Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add USB support #87

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
106 changes: 106 additions & 0 deletions src/Kernel/KUSB.ZC
Original file line number Diff line number Diff line change
@@ -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;
}
1 change: 1 addition & 0 deletions src/Kernel/Kernel.PRJ
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
56 changes: 56 additions & 0 deletions src/Kernel/KernelA.HH
Original file line number Diff line number Diff line change
Expand Up @@ -3016,6 +3016,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*"
Expand Down
207 changes: 207 additions & 0 deletions src/System/USB.ZC
Original file line number Diff line number Diff line change
@@ -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;

//*/