-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #86 from doodayev/master
Adding in USB from the TempleOS supplemental discs
- Loading branch information
Showing
2 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
|
||
#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 | ||
|
||
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; | ||
}; | ||
|
||
//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); | ||
} | ||
|
||
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); | ||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
/* | ||
You can play with this if you are | ||
interested in USB.I'm not planning | ||
on doing USB unless the legacy PS2 | ||
keyboard/mouse mode disappears. | ||
There EHCI UHCI in various ICH chips and | ||
others and God knows how many custom packet | ||
formats for different keyboards and mice.Okay, | ||
I suppose if BIOS can make a universal | ||
packet, it is done just one way for | ||
different mice.PS2 is more compatible. | ||
*/ | ||
#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; | ||
} | ||
|
||
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); | ||
DocDm(t + 4, 8); | ||
if (*P(t + 12)) | ||
DocDm(*P(t + 12), 16); | ||
// DocDm(*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); | ||
DocD(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; | ||
*/ |