usbrdb.c 3.79 KB
#include "ultra64.h"
#include "os_internal.h"
#include "os_usb.h"
#include "PR/bcp.h"

#include "usbrdb.h"

#ifdef _FINALROM
#define PRINTF		dramPrintf
extern int dramPrintf(char *, ...);
extern void __usbSkidMark(int);
#else
#define PRINTF		osSyncPrintf
#define __usbSkidMark(x)
#endif

/*
 * Thread and stack structures
 */
char   bootStack[STACKSIZE] __attribute__ ((aligned (8)));

static OSThread idleThread;
static char     idleThreadStack[STACKSIZE] __attribute__ ((aligned (8)));

static OSThread mainThread;
static char     mainThreadStack[STACKSIZE] __attribute__ ((aligned (8)));

/*
 * USB specific data structures
 */
#define	MAX_USB_DEVICES	4

static OSUsbInfo UsbInfo[MAX_USB_DEVICES];

/*
 * Local variables and routines
 */

static void		idleproc(char *);
static void		mainproc(char *);

void
boot(void)
{
	__usbSkidMark(0xdead0000);

	PRINTF("ROM Start ...\n");
    osInitialize();
    osCreateThread(&idleThread, 1, (void(*)(void *))idleproc, (void *)0,
                   idleThreadStack+STACKSIZE, 8);
    osStartThread(&idleThread);
}


static void
idleproc(char *arg)		/* priority 8 */
{
    s32 nctlr;

    /*
     * Initialize USB and start manager threads for both controllers
     */
    __usbSkidMark(0xdead0001);
    PRINTF("Calling osUsbInit ...\n");
    nctlr = osUsbInit();
    if (nctlr == 0) {
    	PRINTF("osUsbInit returns 0 ...\n");
	PRINTF("No USB controllers present\n");
    } else if (nctlr > OS_USB_MAX_CONTROLLERS) {
	PRINTF("More USB controllers than possible (%d)\n", nctlr);
    }	
    __usbSkidMark(0xdead0002);

    /*
     * The main thread's priority must be the same or lower than the original
     * idle's thread priority. This allows the idle thread to change its
     * priority to 0 before the main thread starts execution.
     */
    osCreateThread(&mainThread, 3, (void(*)(void *))mainproc, arg,
           mainThreadStack+STACKSIZE, (OSPri)7);
    osStartThread(&mainThread);

    osSetThreadPri(0, OS_PRIORITY_IDLE);
    for(;;);                                    /* idle thread */
}

#include "rdb.h"

void
do_rdb_test(s32 which, OSUsbHandle handle)
{
    unsigned char data[4];
    unsigned char in[64];
    int i, rv;

    __usbSkidMark(0xdead0010);
    PRINTF("USB0: test RDB device in loopback mode\n");

    data[0] = RDB_TYPE_HtoG_DATA << 2 | 3;
    data[1] = 0xa1;
    data[2] = 0xb2;
    data[3] = 0xc3;

    rv = osUsbDevWrite(handle, data, 4, 0);
    PRINTF("USB0: DevWrite 4 to RDB wrote %d\n", rv);

    bzero((void *)in, sizeof in);
    rv = osUsbDevRead(handle, in, sizeof in, 0);
    PRINTF("USB0: DevRead from RDB got %d\nRet data: ", rv);

    for (i = 0; i < rv; i++)
	PRINTF("%02x ", in[i]);
    
    PRINTF("\n");
    return;
}

static void 
mainproc(char *arg)			/* priority of 7 */
{
    s32 ndevs;
    OSUsbHandle handle;
	
    __usbSkidMark(0xdead0003);
    PRINTF("\n=> mainproc...\n");

    /*
     * Call USB device query for each controller
     */
    ndevs = osUsbDevQuery(0, &UsbInfo[0], MAX_USB_DEVICES);
    __usbSkidMark(0xdead0004);
    PRINTF("USB Controller 0 has %d devices\n", ndevs);

    if (ndevs > 0) {
	PRINTF("USB0: found device vend 0x%x, prod 0x%x, class 0x%x\n",
	    UsbInfo[0].ua_vendor,
	    UsbInfo[0].ua_product,
	    UsbInfo[0].ua_class);
    }
   
    handle = NULL;
    if (osUsbDevGetHandle(0, &UsbInfo[0], &handle)) {
	    PRINTF("USB0: GetHandle fails\n");
    }
    PRINTF("USB0: GetHandle returns 0x%x\n", handle);
    __usbSkidMark(0xdead0005);

    /*
     * Check for RDB device
     */
    if (UsbInfo[0].ua_vendor == 0x3dbb &&
        UsbInfo[0].ua_product == 0xdbbb) {
       do_rdb_test(0, handle);
    }

    PRINTF("=> done\n");

    { char *cp = (char *)PHYS_TO_K1(0x300000);
      int *ip = (int *)PHYS_TO_K1(0x300010);
      int i = 0;

	bcopy("deadbeat", cp, 9); 
        osSetThreadPri(0, 1);
        for(;;) {
	    *ip = i++;
        }
    }
}