LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
usbhack.c
Go to the documentation of this file.
1/* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * Main Module File: usbhack.c
5 *
6 * A crude test program to let us tinker with a USB controller
7 * installed in an X86 Linux PC. Eventually we'll clean up
8 * this stuff and incorporate it into CFE.
9 *
10 * Author: Mitch Lichtenberg
11 *
12 *********************************************************************
13 *
14 * Copyright 2000,2001,2002,2003
15 * Broadcom Corporation. All rights reserved.
16 *
17 * This software is furnished under license and may be used and
18 * copied only in accordance with the following terms and
19 * conditions. Subject to these conditions, you may download,
20 * copy, install, use, modify and distribute modified or unmodified
21 * copies of this software in source and/or binary form. No title
22 * or ownership is transferred hereby.
23 *
24 * 1) Any source code used, modified or distributed must reproduce
25 * and retain this copyright notice and list of conditions
26 * as they appear in the source file.
27 *
28 * 2) No right is granted to use any trade name, trademark, or
29 * logo of Broadcom Corporation. The "Broadcom Corporation"
30 * name may not be used to endorse or promote products derived
31 * from this software without the prior written permission of
32 * Broadcom Corporation.
33 *
34 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
35 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
36 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
38 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
39 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
40 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
45 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
46 * THE POSSIBILITY OF SUCH DAMAGE.
47 ********************************************************************* */
48
49
50#include <stdio.h>
51#include <unistd.h>
52#include <stdlib.h>
53#include <stdint.h>
54#include <stdarg.h>
55#include <sys/mman.h>
56#include <sys/fcntl.h>
57#include <signal.h>
58#include <memory.h>
59#include <time.h>
60
61#include "lib_malloc.h"
62#include "lib_queue.h"
63#include "usbchap9.h"
64#include "usbd.h"
65#include "ohci.h"
66
67/* *********************************************************************
68 * Macros
69 ********************************************************************* */
70
71#define OHCI_WRITECSR(softc,x,y) \
72 *((volatile uint32_t *) ((softc)->ohci_regs + ((x)/sizeof(uint32_t)))) = (y)
73#define OHCI_READCSR(softc,x) \
74 *((volatile uint32_t *) ((softc)->ohci_regs + ((x)/sizeof(uint32_t))))
75
76/* *********************************************************************
77 * Externs
78 ********************************************************************* */
79
80extern int usb_noisy;
81extern int ohcidebug;
82
83extern usbdev_t *usbmass_dev;
84extern int usbmass_read_sector(usbdev_t *dev,uint32_t sectornum,uint32_t seccnt,
85 uint8_t *buffer);
86
87
88/* *********************************************************************
89 * Play Area definitions
90 *
91 * We use /dev/mem to map two areas - the "play" area and the
92 * "device" area.
93 *
94 * The "play" area maps to the upper 1MB of physical memory.
95 * You need to calculate this address yourself based on your system
96 * setup. If you have 256MB of memory, in your lilo.conf file put
97 * the following line:
98 *
99 * append="mem=255M"
100 *
101 * where '255' is one less than your system memory size. this
102 * leaves 1MB out of Linux's physical memory map and therefore
103 * leaves it to you to play with. /dev/mem will map this
104 * uncached using the Pentium MTRR registers, but for playing
105 * around this will be fine.
106 *
107 * the second area is the "device area" - this is the address
108 * the PCI USB controller's BARs were mapped to. You can find
109 * this by looking through /proc/pci until you find:
110 *
111 * Bus 0, device 8, function 0:
112 * USB Controller: OPTi Unknown device (rev 16).
113 * Vendor id=1045. Device id=c861.
114 * Medium devsel. Fast back-to-back capable. IRQ 3.
115 * Master Capable. Latency=32.
116 * Non-prefetchable 32 bit memory at 0xd9100000 [0xd9100000].
117 *
118 * The 0xd9100000 will probably be different on your system.
119 *
120 * Of course, to make this work you'll need to rebuild the kernel
121 * without USB support, if you're running a recent kernel.
122 * Fortunately(?), I've been using RH 6.2, no USB support there
123 * in the old 2.2 kernels.
124 *
125 * Finally, you'll need to run this program as root. Even if
126 * you mess with the permissions on /dev/mem, there are additional
127 * checks in the kernel, so you will lose.
128 *
129 * But, the good news is that it works well - I've never crashed
130 * my Linux box, and I can use gdb to debug programs.
131 * You will NOT be able to use GDB to display things in the
132 * play area - I believe GDB doesn't know how to deal with
133 * the uncached nature of the memory there. You can see stuff
134 * in the area by tracing through instructions that read the play
135 * area, and viewing the register contents.
136 ********************************************************************* */
137
138#define PLAY_AREA_ADDR (255*1024*1024) /* EDIT ME */
139#define PLAY_AREA_SIZE (1024*1024)
140int play_fd = -1;
141uint8_t *play_area = MAP_FAILED;
142
143#define DEVICE_AREA_ADDR 0xd9100000 /* EDIT ME */
144#define DEVICE_AREA_SIZE 4096
145int dev_fd = -1;
146uint8_t *device_area = MAP_FAILED;
147
148/* *********************************************************************
149 * Globals
150 ********************************************************************* */
151
152
155int running = 1;
156
157/* *********************************************************************
158 * vtop(v)
159 *
160 * Given a virtual address in the play area, return its physical
161 * address.
162 *
163 * Input parameters:
164 * v - virtual address
165 *
166 * Return value:
167 * physical address
168 ********************************************************************* */
169
170
172{
173 uint32_t p = (uint32_t) v;
174
175 if (v == 0) return 0;
176
177 p -= (uint32_t) play_area;
178 p += PLAY_AREA_ADDR;
179
180 return p;
181}
182
183/* *********************************************************************
184 * ptov(v)
185 *
186 * Given a phyiscal address in the play area, return the virtual
187 * address.
188 *
189 * Input parameters:
190 * p - physical address
191 *
192 *
193 * Return value:
194 * virtual address (void pointer)
195 ********************************************************************* */
196
198{
199 if (p == 0) return 0;
200
201 p -= PLAY_AREA_ADDR;
202 p += (uint32_t) play_area;
203
204 return (void *) p;
205}
206
207/* *********************************************************************
208 * mydelay(x)
209 *
210 * delay for 'x' milliseconds.
211 *
212 * Input parameters:
213 * x - milliseconds
214 *
215 * Return value:
216 * nothing
217 ********************************************************************* */
218
219void mydelay(int x)
220{
221 struct timespec ts;
222
223 ts.tv_sec = 0;
224 ts.tv_nsec = x * 1000000; /* milliseconds */
225 nanosleep(&ts,NULL);
226}
227
228/* *********************************************************************
229 * console_log(tmplt,...)
230 *
231 * Display a console log message - this is a CFE function
232 * transplanted here.
233 *
234 * Input parameters:
235 * tmplt - printf string args...
236 *
237 * Return value:
238 * nothing
239 ********************************************************************* */
240
241void console_log(const char *tmplt,...)
242{
243 char buffer[256];
244 va_list marker;
245
246 va_start(marker,tmplt);
247 vsprintf(buffer,tmplt,marker);
248 va_end(marker);
249 printf("%s\n",buffer);
250}
251
252/* *********************************************************************
253 * init_devaccess()
254 *
255 * Open /dev/mem and create the play area
256 *
257 * Input parameters:
258 * nothing
259 *
260 * Return value:
261 * 0 if ok, else error
262 ********************************************************************* */
263
265{
266 int idx;
267
268 play_fd = open("/dev/mem",O_RDWR);
269
270 if (play_fd < 0) {
271 perror("open");
272 return -1;
273 }
274
275 dev_fd = open("/dev/mem",O_RDWR | O_SYNC);
276
277 if (dev_fd < 0) {
278 perror("open");
279 close(play_fd);
280 play_fd = -1;
281 return -1;
282 }
283
284 play_area = mmap(NULL,
286 PROT_READ|PROT_WRITE,MAP_SHARED,
287 play_fd,
289
290 if (play_area != MAP_FAILED) {
291 printf("Play area mapped ok at address %p to %p\n",play_area,play_area+PLAY_AREA_SIZE-1);
292 for (idx = 0; idx < PLAY_AREA_SIZE; idx++) {
293 play_area[idx] = 0x55;
294 if (play_area[idx] != 0x55) printf("Offset %x doesn't work\n",idx);
295 play_area[idx] = 0xaa;
296 if (play_area[idx] != 0xaa) printf("Offset %x doesn't work\n",idx);
297 play_area[idx] = 0x0;
298 if (play_area[idx] != 0x0) printf("Offset %x doesn't work\n",idx);
299 }
300 }
301 else {
302 perror("mmap");
303 close(play_fd);
304 close(dev_fd);
305 play_fd = -1;
306 dev_fd = -1;
307 return -1;
308 }
309
310 device_area = mmap(NULL,
312 PROT_READ|PROT_WRITE,MAP_SHARED,
313 dev_fd,
315
316 if (device_area != MAP_FAILED) {
317 printf("Device area mapped ok at address %p\n",device_area);
318 }
319 else {
320 perror("mmap");
322 play_area = MAP_FAILED;
323 close(play_fd);
324 close(dev_fd);
325 play_fd = -1;
326 dev_fd = -1;
327 return -1;
328 }
329
330 return 0;
331}
332
333
334/* *********************************************************************
335 * uninit_devaccess()
336 *
337 * Turn off access to the /dev/mem area. this will also
338 * set the OHCI controller's state to reset if we were playing
339 * with it.
340 *
341 * Input parameters:
342 * nothing
343 *
344 * Return value:
345 * nothing
346 ********************************************************************* */
347
349{
350 if (ohci->ohci_regs) {
352 }
353
354 if (play_area != MAP_FAILED) munmap(play_area,PLAY_AREA_SIZE);
355 if (device_area != MAP_FAILED) munmap(device_area,DEVICE_AREA_SIZE);
356
357 if (play_fd > 0) close(play_fd);
358 if (dev_fd > 0) close(dev_fd);
359
360 device_area = MAP_FAILED;
361 play_area = MAP_FAILED;
362
363 dev_fd = -1;
364 play_fd = -1;
365}
366
367/* *********************************************************************
368 * sighandler()
369 *
370 * ^C handler - switch off OHCI controller
371 *
372 * Input parameters:
373 * sig - signal
374 *
375 * Return value:
376 * nothing
377 ********************************************************************* */
378
379void sighandler(int sig)
380{
381 signal(SIGINT,SIG_DFL);
382 printf("Interrupted, controller reset\n");
383 if (ohci->ohci_regs) {
385 }
386 running = 0;
387}
388
389
391
392/* *********************************************************************
393 * xprintf(str)
394 *
395 * Called by lib_malloc, we need to supply it.
396 *
397 * Input parameters:
398 * str - string
399 *
400 * Return value:
401 * 0
402 ********************************************************************* */
403
404int xprintf(char *str)
405{
406 printf("%s",str);
407 return 0;
408}
409
410/* *********************************************************************
411 * main(argc,argv)
412 *
413 * Main test program
414 *
415 * Input parameters:
416 * argc,argv - guess.
417 *
418 * Return value:
419 * nothing
420 ********************************************************************* */
421
422
423int main(int argc,char *argv[])
424{
425 int res;
426 memstats_t stats;
427 uint8_t *buffer;
428
429 /*
430 * Parse command line args
431 */
432
433 for (res = 1; res < argc; res++) {
434 if (strcmp(argv[res],"-o") == 0) ohcidebug++;
435 if (strcmp(argv[res],"-u") == 0) usb_noisy++;
436 }
437
438 /*
439 * Open the play area.
440 */
441
442 if (init_devaccess() < 0) {
443 printf("Could not map USB controller\n");
444 }
445
446 /*
447 * Establish signal and exit handlers
448 */
449
450 signal(SIGINT,sighandler);
451 atexit(uninit_devaccess);
452
453 /*
454 * Initialize a buffer pool to point at the play area.
455 * the 'malloc' calls inside our driver will therefore
456 * allocate memory suitable for DMA, just like on real
457 * hardware.
458 */
459
461
462 buffer = KMALLOC(512,32);
463
464 printf("-------------------------------------------\n\n");
465
466 /*
467 * Create the OHCI driver instance.
468 */
469
470
471 bus = UBCREATE(&ohci_driver,(void *) device_area);
472
473 /*
474 * Hack: retrieve copy of softc for our exception handler
475 */
476
478
479 /*
480 * Start the controller.
481 */
482
483 res = UBSTART(bus);
484
485 if (res != 0) {
486 printf("Could not init hardware\n");
487 UBSTOP(bus);
488 exit(1);
489 }
490
491 /*
492 * Init the root hub
493 */
494
496
497 /*
498 * Main loop - just call interrupt routine to poll
499 */
500
501 while (usbmass_dev== NULL) {
502 usb_poll(bus);
504 }
505
506 for (res = 0; res < 1000; res++) {
508 }
509
510 printf("----- finished reading all sectors ----\n");
511
512 while (running) {
513 usb_poll(bus);
515 }
516
517 /*
518 * Clean up - get heap statistics to see if we
519 * screwed up.
520 */
521
522 res = KMEMSTATS(&stats);
523 if (res < 0) printf("Warning: heap is not consistent\n");
524 else printf("Heap is ok\n");
525
526 exit(0);
527
528}
#define console_log(fmt, x...)
Definition: cfe.h:18
#define NULL
Definition: def.h:47
#define KMEMSTATS(s)
Definition: lib_malloc.h:94
#define KMEMINIT(buffer, length)
Definition: lib_malloc.h:89
#define KMALLOC(size, align)
Definition: lib_malloc.h:92
u32 uint32_t
Definition: libfdt_env.h:11
u8 uint8_t
Definition: libfdt_env.h:9
int close(int fileDesc)
Definition: newlib.c:829
int open(const char *file, int flags, int mode)
Definition: newlib.c:522
#define R_OHCI_CONTROL
Definition: ohci.h:227
#define V_OHCI_CONTROL_HCFS(x)
Definition: ohci.h:281
#define K_OHCI_HCFS_RESET
Definition: ohci.h:284
volatile uint32_t * ohci_regs
Definition: ohci.h:467
Definition: usbd.h:92
usb_hc_t * ub_hwsoftc
Definition: usbd.h:94
Definition: usbd.h:141
void usb_daemon(usbbus_t *bus)
Definition: usbd.c:410
void usb_poll(usbbus_t *bus)
Definition: usbd.c:392
void usb_initroot(usbbus_t *bus)
Definition: usbd.c:1128
#define UBSTOP(bus)
Definition: usbd.h:274
#define UBCREATE(driver, addr)
Definition: usbd.h:271
#define UBSTART(bus)
Definition: usbd.h:273
int xprintf(char *str)
Definition: usbhack.c:404
int play_fd
Definition: usbhack.c:140
int main(int argc, char *argv[])
Definition: usbhack.c:423
uint8_t * play_area
Definition: usbhack.c:141
usb_hcdrv_t ohci_driver
Definition: ohci.c:1717
uint8_t * device_area
Definition: usbhack.c:146
usbdev_t * usbmass_dev
int ohcidebug
Definition: ohci.c:199
int running
Definition: usbhack.c:155
int usbmass_read_sector(usbdev_t *dev, uint32_t sectornum, uint32_t seccnt, uint8_t *buffer)
int usb_noisy
Definition: usbd.c:68
void mydelay(int x)
Definition: usbhack.c:219
int dev_fd
Definition: usbhack.c:145
#define PLAY_AREA_SIZE
Definition: usbhack.c:139
void * ptov(uint32_t p)
Definition: usbhack.c:197
#define PLAY_AREA_ADDR
Definition: usbhack.c:138
uint32_t vtop(void *v)
Definition: usbhack.c:171
void uninit_devaccess(void)
Definition: usbhack.c:348
int init_devaccess(void)
Definition: usbhack.c:264
#define DEVICE_AREA_ADDR
Definition: usbhack.c:143
#define DEVICE_AREA_SIZE
Definition: usbhack.c:144
#define OHCI_WRITECSR(softc, x, y)
Definition: usbhack.c:71
usbbus_t * bus
Definition: usbhack.c:153
void sighandler(int sig)
Definition: usbhack.c:379
ohci_softc_t * ohci
Definition: usbhack.c:154
u8 str[13]
Definition: xenos_edid.h:0