diff --git a/src/Kernel/KUSB.ZC b/src/Kernel/KUSB.ZC new file mode 100644 index 00000000..1acbd05c --- /dev/null +++ b/src/Kernel/KUSB.ZC @@ -0,0 +1,106 @@ + +#define USBP_CMD 0x00 +#define USBP_STS 0x02 +#define USBP_INTR 0x04 +#define USBP_FRNUM 0x06 +#define USBP_FRBASEADD 0x08 +#define USBP_SOFMOD 0x0C +#define USBP_PORTSC0 0x10 +#define USBP_PORTSC1 0x12 +#define USB_NUM 16 + +//USB Pkt ID's +#define PID_OUT 0xE1 +#define PID_IN 0x69 +#define PID_SOF 0xA5 +#define PID_SETUP 0x2D +#define PID_DATA0 0xC3 +#define PID_DATA1 0x4B +#define PID_DATA2 0x87 +#define PID_MDATA 0x0F +#define PID_ACK 0xD2 +#define PID_NAK 0x5A +#define PID_STALL 0x1E +#define PID_NYET 0x96 +#define PID_PRE 0x3C +#define PID_ERR 0x3C +#define PID_SPLIT 0x78 +#define PID_PING 0xB4 + +//USB Std Rqsts +#define RQ_GET_STAT 0x0 +#define RQ_CLR_FEAT 0x1 +#define RQ_SET_FEAT 0x3 +#define RQ_SET_ADDR 0x5 +#define RQ_SET_DESC 0x7 +#define RQ_GET_CFG 0x8 +#define RQ_SET_CFG 0x9 +#define RQ_GET_INTERFACE 0xA +#define RQ_SET_INTERFACE 0xB +#define RQ_SYNC_FRAME 0xC + +I64 sys_num_usb = 0; +CUSB sys_usb_devs[USB_NUM]; +MemSet(sys_usb_devs, 0, USB_NUM * sizeof(CUSB)); + +U0 USBInitOne(I64 b, I64 d, I64 f) +{ + CUSB *u; + if (sys_num_usb < USB_NUM && PCIReadU16(b, d, f, 0) == 0x8086) + { + u = &sys_usb_devs[sys_num_usb++]; + u->num = sys_num_usb; + u->bus = b; + u->dev = d; + u->fun = f; + u->ports = PCIReadU32(b, d, f, 0x20) & ~0x1F; + } +} + +U0 USBEndAll() +{ + sys_num_usb = 0; +} + +U0 USBInitAll() //This is only valid for my ICH10 dev +{ + if (sys_num_usb) + USBEndAll; + USBInitOne(0, 29, 0); + USBInitOne(0, 29, 1); + USBInitOne(0, 29, 2); + USBInitOne(0, 29, 3); + USBInitOne(0, 26, 0); + USBInitOne(0, 26, 1); + USBInitOne(0, 26, 2); +} + +CUSBTD *USBAllocTD() +{ +// return MAllocAligned(sizeof(CUSBTD), 0x10, dev.uncached_heap); + return MAllocAligned(sizeof(CUSBTD), 0x10, dev.uncached_alias + sys_task->code_heap); +} + +U0 USBFreeTD(CUSBTD *tmptd) +{ + Free(tmptd); +} + +U32 *USBAllocFrameLst(I64 usb_num, I64 size) +{ + //aligned to 0x1000 + CUSB *u; + if (0 <= usb_num < sys_num_usb) + { + u = &sys_usb_devs[usb_num]; + Free(u->frame_lst); +// u->frame_lst = MAllocAligned(size * sizeof(U32), 0x1000, dev.uncached_heap); + u->frame_lst = MAllocAligned(size * sizeof(U32), 0x1000, dev.uncached_alias + sys_task->code_heap); + OutU16(u->ports + USBP_CMD, 0); //Stop + OutU16(u->ports + USBP_FRNUM, 0); + OutU32(u->ports + USBP_FRBASEADD, u->frame_lst); + return u->frame_lst; + } + + return NULL; +} diff --git a/src/Kernel/Kernel.PRJ b/src/Kernel/Kernel.PRJ index 7dda5c80..76dd91a4 100755 --- a/src/Kernel/Kernel.PRJ +++ b/src/Kernel/Kernel.PRJ @@ -52,6 +52,7 @@ #include "Job" #include "PCIBIOS" #include "PCI" +#include "KUSB" // currently too far forward in #includes, doesn't precede keyboard/mouse code #include "MultiProc" #include "EdLite" #include "BlkDev/MakeBlkDev" diff --git a/src/Kernel/KernelA.HH b/src/Kernel/KernelA.HH index d9d731b2..b55d2d21 100755 --- a/src/Kernel/KernelA.HH +++ b/src/Kernel/KernelA.HH @@ -3021,6 +3021,62 @@ class CAtapiModeWriteList #define ATAR0_CMD 7 #define ATAR1_CTRL 2 +#help_index "Devices;USB" +class CUSBTD //Not implemented +{ + U32 td[4]; +}; + +class CUSB //Not implemented +{ + U8 num, //USB dev num + bus, dev, fun; + U16 ports, pad; + U32 *frame_lst; +}; + +#define USBP_CMD 0x00 +#define USBP_STS 0x02 +#define USBP_INTR 0x04 +#define USBP_FRNUM 0x06 +#define USBP_FRBASEADD 0x08 +#define USBP_SOFMOD 0x0C +#define USBP_PORTSC0 0x10 +#define USBP_PORTSC1 0x12 +#define USB_NUM 16 + +//USB Pkt ID's +#define PID_OUT 0xE1 +#define PID_IN 0x69 +#define PID_SOF 0xA5 +#define PID_SETUP 0x2D +#define PID_DATA0 0xC3 +#define PID_DATA1 0x4B +#define PID_DATA2 0x87 +#define PID_MDATA 0x0F +#define PID_ACK 0xD2 +#define PID_NAK 0x5A +#define PID_STALL 0x1E +#define PID_NYET 0x96 +#define PID_PRE 0x3C +#define PID_ERR 0x3C +#define PID_SPLIT 0x78 +#define PID_PING 0xB4 + +//USB Std Rqsts +#define RQ_GET_STAT 0x0 +#define RQ_CLR_FEAT 0x1 +#define RQ_SET_FEAT 0x3 +#define RQ_SET_ADDR 0x5 +#define RQ_SET_DESC 0x7 +#define RQ_GET_CFG 0x8 +#define RQ_SET_CFG 0x9 +#define RQ_GET_INTERFACE 0xA +#define RQ_SET_INTERFACE 0xB +#define RQ_SYNC_FRAME 0xC + + + #help_index "File/FileNames" #define FILEMASK_JIT "*.ZC*;*.HH*" #define FILEMASK_AOT "*.ZC*;*.HH*;*.PRJ*" diff --git a/src/System/USB.ZC b/src/System/USB.ZC new file mode 100644 index 00000000..ac29b4c2 --- /dev/null +++ b/src/System/USB.ZC @@ -0,0 +1,207 @@ + +#help_index "USB" + +extern I64 sys_num_usb; +extern CUSB sys_usb_devs[USB_NUM]; +extern CUSBTD *USBAllocTD(); +extern U0 USBFreeTD(CUSBTD *tmptd); +extern U0 USBEndAll(); +extern U0 USBInitAll(); +extern U32 *USBAllocFrameLst(I64 usb_num, I64 size); + +U8 *StatCB(CDoc *, CDocEntry *doc_e, CTask *mem_task) +{ + //This routine shows the stat of the USB ports + U8 *st = MAlloc(128, mem_task); + U16 w1, w2, w3, w4; + U32 d1; + CUSB *u = doc_e->user_data; + I64 d = u->ports; + w3 = InU16(d + USBP_STS); + w1 = InU16(d + USBP_PORTSC0); + w2 = InU16(d + USBP_PORTSC1); + w4 = InU16(d + USBP_FRNUM); + d1 = InU32(d + USBP_FRBASEADD); + StrPrint(st, "%X:Stat:%04X P0:%04X P1:%04X FRAME:%04X", d1, w3, w1, w2, w4); + return st; +} + +U0 PutStat() +{ + I64 i; + CDocEntry *doc_e; + CUSB *u; + WinMax; + + "$$FG,GREEN$$Dev Stat Bits\n$$FG$$" + " 0:IRQ\n" + " 1:IRQ err\n" + " 2:Resume\n" + " 3:Host Sys Err\n" + " 4:Host Process Err\n" + " 5:Halted\n" + "$$FG,GREEN$$Port Stat Bits\n$$FG$$" + " 0:Connection Stat\n" + " 1:Connection Stat Change\n" + " 2:Port Enabled\n" + " 3:Port Enabled Change\n" + "4-5:Line Stat\n" + " 6:Resume Detect\n" + " 8:Low Speed\n" + " 9:Port Rst\n" + " 10:Overcurrent Active\n" + " 11:Overcurrent Indicator\n" + " 12:Suspend\n\n"; + + for (i = 0; i < sys_num_usb; i++) + { + u = &sys_usb_devs[i]; + "$$FG,LTRED$$Dev%d:%X:", i, u->ports; + doc_e = DocPrint(DocPut, "$$TX+TC,\" \"$$"); + doc_e->user_data = &sys_usb_devs[i]; + doc_e->tag_cb = &StatCB; + "$$FG$$\n"; + } + +// NewLine; + "\n"; +} + +extern U0 PutQH(U32 h); + +U32 *P(U32 d) +{ + return d & ~3; +} + +U0 PutTD(U32 t) +{ + "TD:$$FG,GREEN$$%08X$$FG$$\n", t; + "%08X\n", *P(t); + DocDumpMem(t + 4, 8); + if (*P(t + 12)) + DocDumpMem(*P(t + 12), 16); + // DocDumpMem(*P(t+12), *P(t+4) >> 21 & 0x7FF); + if (!(*P(t) & 1)) + { + if (*P(t) & 2) + PutQH(*P(t)); + else + PutTD(*P(t)); + } +} + +U0 PutQH(U32 h) +{ + "QH:$$FG,RED$$%08X$$FG$$\n", h; + "%08X\n", *P(h); + "%08X\n", *P(h + 4); + + if (!(*P(h) & 1)) + { + if (*P(h) & 2) + PutQH(*P(h)); + else + PutTD(*P(h)); + } + + if (!(*P(h + 4) & 1)) + { + if (*P(h + 4) & 2) + PutQH(*P(h + 4)); + else + PutTD(*P(h + 4)); + } +} + +U0 PutFrame(U32 f) +{ + PutQH(f); +} + +U0 PutFrames() +{ + I64 i, d, f, w1, w2; + CUSB *u; + for (i = 0; i < sys_num_usb; i++) + { + u = &sys_usb_devs[i]; + d = u->ports; + w1 = InU16(d + USBP_PORTSC0); + w2 = InU16(d + USBP_PORTSC1); + if (w1 & 1 || w2 & 1) + { + f = InU32(d + USBP_FRBASEADD); + PutFrame(f); + } + } +} + +U0 Main() +{ + USBInitAll; + PutStat; + PutFrames; + "$$FG,RED$$The BIOS sets-up the USB in PS/2 legacy mode.$$FG$$\n"; +} + +Main; + +///* Not Finished +#define PORT 5 +#define DEV_ADD_INIT 1 +#define DEV_ADD 1 +#define END_PT0 0 +#define END_PT1 1 +#define END_PT2 2 +#define LEN_MAX 8 +#define TERMINATE 1 + +U0 SetUpTD() +{ + CUSB *u = &sys_usb_devs[PORT]; + I64 i, d = u->ports; + U32 *frm = CAllocAligned(0x1000, 0x1000, Fs->code_heap), + *tds = CAllocAligned(256, 16, Fs->code_heap), + *buf = CAlloc(128, Fs->code_heap); + DocDump(buf, 128); + + "<0>\n"; Sleep(100); + OutU16(d + USBP_CMD, 2); //Reset + "<1>\n"; Sleep(100); + OutU16(d + USBP_CMD, 0); + "<2>\n"; Sleep(100); + OutU16(d + USBP_PORTSC0, 4); //Enable + OutU16(d + USBP_PORTSC1, 4); + "<3>\n"; Sleep(100); + + tds[0] = &tds[4](U8 *); + tds[1] = 0; + tds[2] = PID_SETUP + DEV_ADD_INIT << 8 + END_PT0 << 15 + LEN_MAX << 21; + tds[3] = buf; + buf[0] = 0 + RQ_SET_ADDR << 8 + DEV_ADD << 16; + buf[1] = 0 + 0 << 16; + + tds[4] = TERMINATE; + tds[5] = 0; + tds[6] = PID_SETUP + DEV_ADD_INIT << 8 + END_PT0 << 15 + LEN_MAX << 21; + tds[7] = buf(U8 *) + 8; + buf[2] = 0 + RQ_SET_ADDR << 8 + DEV_ADD << 16; + buf[3] = 0 + 0 << 16; + + frm[0] = &tds[0](U8 *); + for (i = 1; i < 0x1000 / 4; i++) + frm[i] = TERMINATE; + + OutU16(d + USBP_FRNUM, frm); + OutU32(d + USBP_FRBASEADD, frm); + "<4>\n"; Sleep(200); + OutU16(d + USBP_CMD,1); + "<5>\n"; Sleep(1000); + OutU16(d + USBP_CMD,0); + "<6>\n"; Sleep(200); +} + +SetUpTD; + +//*/