GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / usb / usbhack.c
blob647f213aa548ebab23d69165f2fa37d07d6984bd
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 (mpl@broadcom.com)
12 *********************************************************************
14 * Copyright 2000,2001,2002,2003
15 * Broadcom Corporation. All rights reserved.
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.
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.
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.
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 ********************************************************************* */
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>
61 #include "lib_malloc.h"
62 #include "lib_queue.h"
63 #include "usbchap9.h"
64 #include "usbd.h"
65 #include "ohci.h"
67 /* *********************************************************************
68 * Macros
69 ********************************************************************* */
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))))
76 /* *********************************************************************
77 * Externs
78 ********************************************************************* */
80 extern int usb_noisy;
81 extern int ohcidebug;
83 extern usbdev_t *usbmass_dev;
84 extern int usbmass_read_sector(usbdev_t *dev,uint32_t sectornum,uint32_t seccnt,
85 uint8_t *buffer);
88 /* *********************************************************************
89 * Play Area definitions
91 * We use /dev/mem to map two areas - the "play" area and the
92 * "device" area.
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:
99 * append="mem=255M"
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.
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:
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].
118 * The 0xd9100000 will probably be different on your system.
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.
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.
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 ********************************************************************* */
138 #define PLAY_AREA_ADDR (255*1024*1024) /* EDIT ME */
139 #define PLAY_AREA_SIZE (1024*1024)
140 int play_fd = -1;
141 uint8_t *play_area = MAP_FAILED;
143 #define DEVICE_AREA_ADDR 0xd9100000 /* EDIT ME */
144 #define DEVICE_AREA_SIZE 4096
145 int dev_fd = -1;
146 uint8_t *device_area = MAP_FAILED;
148 /* *********************************************************************
149 * Globals
150 ********************************************************************* */
153 usbbus_t *bus = NULL;
154 ohci_softc_t *ohci = NULL;
155 int running = 1;
157 /* *********************************************************************
158 * vtop(v)
160 * Given a virtual address in the play area, return its physical
161 * address.
163 * Input parameters:
164 * v - virtual address
166 * Return value:
167 * physical address
168 ********************************************************************* */
171 uint32_t vtop(void *v)
173 uint32_t p = (uint32_t) v;
175 if (v == 0) return 0;
177 p -= (uint32_t) play_area;
178 p += PLAY_AREA_ADDR;
180 return p;
183 /* *********************************************************************
184 * ptov(v)
186 * Given a phyiscal address in the play area, return the virtual
187 * address.
189 * Input parameters:
190 * p - physical address
193 * Return value:
194 * virtual address (void pointer)
195 ********************************************************************* */
197 void *ptov(uint32_t p)
199 if (p == 0) return 0;
201 p -= PLAY_AREA_ADDR;
202 p += (uint32_t) play_area;
204 return (void *) p;
207 /* *********************************************************************
208 * mydelay(x)
210 * delay for 'x' milliseconds.
212 * Input parameters:
213 * x - milliseconds
215 * Return value:
216 * nothing
217 ********************************************************************* */
219 void mydelay(int x)
221 struct timespec ts;
223 ts.tv_sec = 0;
224 ts.tv_nsec = x * 1000000; /* milliseconds */
225 nanosleep(&ts,NULL);
228 /* *********************************************************************
229 * console_log(tmplt,...)
231 * Display a console log message - this is a CFE function
232 * transplanted here.
234 * Input parameters:
235 * tmplt - printf string args...
237 * Return value:
238 * nothing
239 ********************************************************************* */
241 void console_log(const char *tmplt,...)
243 char buffer[256];
244 va_list marker;
246 va_start(marker,tmplt);
247 vsprintf(buffer,tmplt,marker);
248 va_end(marker);
249 printf("%s\n",buffer);
252 /* *********************************************************************
253 * init_devaccess()
255 * Open /dev/mem and create the play area
257 * Input parameters:
258 * nothing
260 * Return value:
261 * 0 if ok, else error
262 ********************************************************************* */
264 int init_devaccess(void)
266 int idx;
268 play_fd = open("/dev/mem",O_RDWR);
270 if (play_fd < 0) {
271 perror("open");
272 return -1;
275 dev_fd = open("/dev/mem",O_RDWR | O_SYNC);
277 if (dev_fd < 0) {
278 perror("open");
279 close(play_fd);
280 play_fd = -1;
281 return -1;
284 play_area = mmap(NULL,
285 PLAY_AREA_SIZE,
286 PROT_READ|PROT_WRITE,MAP_SHARED,
287 play_fd,
288 PLAY_AREA_ADDR);
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);
301 else {
302 perror("mmap");
303 close(play_fd);
304 close(dev_fd);
305 play_fd = -1;
306 dev_fd = -1;
307 return -1;
310 device_area = mmap(NULL,
311 DEVICE_AREA_SIZE,
312 PROT_READ|PROT_WRITE,MAP_SHARED,
313 dev_fd,
314 DEVICE_AREA_ADDR);
316 if (device_area != MAP_FAILED) {
317 printf("Device area mapped ok at address %p\n",device_area);
319 else {
320 perror("mmap");
321 munmap(play_area,PLAY_AREA_SIZE);
322 play_area = MAP_FAILED;
323 close(play_fd);
324 close(dev_fd);
325 play_fd = -1;
326 dev_fd = -1;
327 return -1;
330 return 0;
334 /* *********************************************************************
335 * uninit_devaccess()
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.
341 * Input parameters:
342 * nothing
344 * Return value:
345 * nothing
346 ********************************************************************* */
348 void uninit_devaccess(void)
350 if (ohci->ohci_regs) {
351 OHCI_WRITECSR(ohci,R_OHCI_CONTROL,V_OHCI_CONTROL_HCFS(K_OHCI_HCFS_RESET));
354 if (play_area != MAP_FAILED) munmap(play_area,PLAY_AREA_SIZE);
355 if (device_area != MAP_FAILED) munmap(device_area,DEVICE_AREA_SIZE);
357 if (play_fd > 0) close(play_fd);
358 if (dev_fd > 0) close(dev_fd);
360 device_area = MAP_FAILED;
361 play_area = MAP_FAILED;
363 dev_fd = -1;
364 play_fd = -1;
367 /* *********************************************************************
368 * sighandler()
370 * ^C handler - switch off OHCI controller
372 * Input parameters:
373 * sig - signal
375 * Return value:
376 * nothing
377 ********************************************************************* */
379 void sighandler(int sig)
381 signal(SIGINT,SIG_DFL);
382 printf("Interrupted, controller reset\n");
383 if (ohci->ohci_regs) {
384 OHCI_WRITECSR(ohci,R_OHCI_CONTROL,V_OHCI_CONTROL_HCFS(K_OHCI_HCFS_RESET));
386 running = 0;
390 extern usb_hcdrv_t ohci_driver;
392 /* *********************************************************************
393 * xprintf(str)
395 * Called by lib_malloc, we need to supply it.
397 * Input parameters:
398 * str - string
400 * Return value:
402 ********************************************************************* */
404 int xprintf(char *str)
406 printf("%s",str);
407 return 0;
410 /* *********************************************************************
411 * main(argc,argv)
413 * Main test program
415 * Input parameters:
416 * argc,argv - guess.
418 * Return value:
419 * nothing
420 ********************************************************************* */
423 int main(int argc,char *argv[])
425 int res;
426 memstats_t stats;
427 uint8_t *buffer;
430 * Parse command line args
433 for (res = 1; res < argc; res++) {
434 if (strcmp(argv[res],"-o") == 0) ohcidebug++;
435 if (strcmp(argv[res],"-u") == 0) usb_noisy++;
439 * Open the play area.
442 if (init_devaccess() < 0) {
443 printf("Could not map USB controller\n");
447 * Establish signal and exit handlers
450 signal(SIGINT,sighandler);
451 atexit(uninit_devaccess);
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.
460 KMEMINIT(play_area,PLAY_AREA_SIZE);
462 buffer = KMALLOC(512,32);
464 printf("-------------------------------------------\n\n");
467 * Create the OHCI driver instance.
471 bus = UBCREATE(&ohci_driver,(void *) device_area);
474 * Hack: retrieve copy of softc for our exception handler
477 ohci = (ohci_softc_t *) bus->ub_hwsoftc;
480 * Start the controller.
483 res = UBSTART(bus);
485 if (res != 0) {
486 printf("Could not init hardware\n");
487 UBSTOP(bus);
488 exit(1);
492 * Init the root hub
495 usb_initroot(bus);
498 * Main loop - just call interrupt routine to poll
501 while (usbmass_dev== NULL) {
502 usb_poll(bus);
503 usb_daemon(bus);
506 for (res = 0; res < 1000; res++) {
507 usbmass_read_sector(usbmass_dev,0,1,buffer);
510 printf("----- finished reading all sectors ----\n");
512 while (running) {
513 usb_poll(bus);
514 usb_daemon(bus);
518 * Clean up - get heap statistics to see if we
519 * screwed up.
522 res = KMEMSTATS(&stats);
523 if (res < 0) printf("Warning: heap is not consistent\n");
524 else printf("Heap is ok\n");
526 exit(0);