aos/devices/ehci.dev
Daniel Schwyn 6d444bf552 Main handout
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
2022-03-03 14:57:51 +01:00

470 lines
16 KiB
Plaintext

/*
* Copyright (c) 2009, 2012, ETH Zurich. All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
* ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
*/
/*
* ehci.dev
*
* DESCRIPTION: Enhanced Host Controller Interface description
*
* Numbers in comments refer to the Intel Enhanced Host Controller
* Interface Specification for Universal Serial Bus, March 12, 2002,
* Revision: 1.0
*/
device ehci msbfirst (addr cap, addr op) "EHCI USB Controller" {
/*
* Section 2.2
* Host controller capabilty registers
*/
// 2.2.1
// The correct value for 'op' is actually 'cap' plus this number.
register caplength ro addr(cap, 0x00) "Capability Registers Length"
type(uint8);
// 2.2.2
register hciversion ro addr(cap, 0x02) "Host Controller Interface Version Number"
type(uint16);
// 2.2.3
register hcsparams ro addr(cap, 0x04) "Structural parameters" {
_ 8;
dpn 4 "Debug port number";
_ 3;
p_indicator 1 "Port indicator";
n_cc 4 "Number of campanion controller";
n_pcc 4 "Number of ports per companion controller";
prr 1 "Port routing rules";
_ 2;
ppc 1 "Port power control";
n_ports 4 "Num. physical downstream ports on this controller";
};
// 2.2.4
register hccparams ro addr(cap, 0x08) "Capability parameters" {
_ 16;
eecp 8 "EHCI extended capabilities pointer";
ist 4 "Isochronous scheduling threshold";
_ 1;
aspc 1 "Asynchronous sechedule park capability";
pflf 1 "Programmable frame list flag";
bit64ac 1 "Extended 64 bit addressing capability";
};
// section 2.2.5 Companion port route descriptor
register hcspportroute ro addr(cap, 0x0C) "Companion port route descr." {
attr 60 "Port array";
_ 4;
};
/*
* Section 2.3
* Host controller operational registers
*/
constants itc_val "Interrupt threshold control" {
itc_val_rsvd = 0x00 "Reserved";
uframe_1 = 0x01 "1 Micro frame";
uframes_2 = 0x02 "2 Micro frames";
uframes_4 = 0x04 "4 Micro frames";
uframes_8 = 0x08 "8 Micro frames (default, equates to 1 ms)";
uframes_16 = 0x10 "16 Micro frames (2 ms)";
uframes_32 = 0x20 "32 Micro frames (4 ms)";
uframes_64 = 0x40 "64 Micro frames (8 ms)";
};
constants frame_val "Frame list size" {
elem_1024 = 0b00 "1024 Elements (4096 bytes, default)";
elem_512 = 0b01 "512 Elements (2048 bytes)";
elem_256 = 0b10 "256 Elements (1024 bytes)";
frame_rsvd = 0b11 "Reserved";
};
// 2.3.1
register usbcmd rw addr(op, 0x00) "USB command" {
_ 8 mbz;
itc 8 type(itc_val) "Interrupt threshold control";
_ 4 mbz;
aspme 1 rw "Asynchronous schedule park mode enable";
_ 1 mbz;
aspmc 2 rw "Asynchronous schedule park mode count";
lhcr 1 rw "Light host controller reset";
iaad 1 rw "Interrupt on async advance doorbell";
ase 1 rw "Asynchronous schedule enable";
pse 1 rw "Periodic schedule enable";
fls 2 type(frame_val) "Frame list size";
hcr 1 rw "Host controller reset";
rs 1 rw "Run stop for scheduling";
};
// 2.3.2
register usbsts rw addr(op, 0x04) "USB status" {
_ 16 mbz;
ass 1 ro "Asynchronous schedule status";
pss 1 ro "Periodic schedule status";
rec 1 ro "Reclamation";
hch 1 ro "Host controller halted see Run/Stop";
_ 6 mbz;
iaa 1 rwc "Interrupt on Async advance";
hse 1 rwc "Host system error";
flr 1 rwc "Frame list rollover";
pcd 1 rwc "Port change detect";
usbei 1 rwc "USB error interrupt";
usbi 1 rwc "USB interrupt";
};
// 2.3.3
register usbintr rw addr(op, 0x08) "USB interrupt enable" {
_ 26 mbz;
iaae 1 "Interrupt on async advance enable";
hsee 1 "Host system error enable";
flre 1 "Frame list rollover enable";
pcie 1 "Port change interrupt enable";
usbeie 1 "USB error interrupt enable";
usbie 1 "USB interrupt enable";
};
// 2.3.4
register frindex rw addr(op, 0x0C) "Frame index" {
_ 18 mbz;
fi 14 "Frame index";
};
// 2.3.5
// NOTE: Only enabled if 64 bit address capability is enabled
register ctrldssegment rw addr(op, 0x10) "Control data structure segment" {
data 32 rw "MSB [63:32] bits of EHCI data strctures";
};
// 2.3.6
register periodiclistbase rw addr(op, 0x14) "Periodic frame list base addr" {
addr 20 rw "Base address (must be 4k aligned)";
_ 12 mbz;
};
// 2.3.7
register asynclistaddr rw addr(op, 0x18) "Current async. list addr." {
lpl 27 rw "Link pointer low";
_ 5 mbz;
};
// 2.3.8
register configflag rw addr(op, 0x40) "Configure flag" {
_ 31 mbz;
cf 1 rw "Configure flag";
};
// 2.3.9
constants test_mode_val "Test modes" {
disabled = 0b0000 "Test mode not enabled";
test_j_st = 0b0001 "Test J_STATE";
test_k_st = 0b0010 "Test K_STATE";
se0_nak = 0b0011 "Test SE0_NAK";
test_pack = 0b0100 "Test packet";
force_ena = 0b0101 "Force enable";
};
constants indi_val "Port indicator values" {
off = 0b00 "Port indicators are off";
amber = 0b01 "Amber";
green = 0b10 "Green";
indi_val_undef = 0b11 "Undefined";
};
constants lstatus_val "USB line status" {
se0 = 0b00 "Not low speed device, perform EHCI reset";
j_state = 0b10 "Not low speed device, perform EHCI reset";
k_state = 0b01 "Low speed device, release ownership of port";
lstatus_undef = 0b11 "Not low speed device, perform EHCI reset";
};
regarray portsc rw addr(op, 0x44)[16] "Port status and control" {
_ 9 mbz;
wkoc_e 1 "Wake on over-current enable";
wkdscnnt_e 1 "Wake on disconnect enable";
wkcnnt_e 1 "Wake on connect enable";
ptc 4 type(test_mode_val) "Port test control";
pic 2 type(indi_val) "Port indicator control";
po 1 "Port owner";
pp 1 "Port power";
ls 2 type(lstatus_val) "Line status value";
_ 1 mbz;
pr 1 "Port reset";
sus 1 "Port suspend";
fpr 1 "Force port resume";
occ 1 rwc "Over current change";
oca 1 ro "Over current active";
pec 1 rwc "Port enable/disbale change";
ped 1 "Port enabled/disabled";
csc 1 rwc "Connect status change";
ccs 1 ro "Current connect status";
};
/*
//
// In-memory data structures
//
// 3.1
constants lptype width(2) "Link pointer type" {
lp_itd = 0b00 "Isochronous transfer descriptor";
lp_qh = 0b01 "Queue head";
lp_sitd = 0b10 "Split transaction isochronous trans. desc.";
lp_fstn = 0b11 "Frame span traversal node";
};
datatype lp msbfirst(32) "Link pointer" {
p 27 "Frame list link pointer";
_ 2 mbz;
typ 2 type(lptype) "Pointer type";
t 1 "Pointer value invalid";
};
// 3.3
datatype itd msbfirst(32) "Isochronous transfer descriptor" {
next 32 type(lp) "Next descriptor";
sc0 32 type(itsc) "Transaction 0 Status/control";
sc1 32 type(itsc) "Transaction 1 Status/control";
sc2 32 type(itsc) "Transaction 2 Status/control";
sc3 32 type(itsc) "Transaction 3 Status/control";
sc4 32 type(itsc) "Transaction 4 Status/control";
sc5 32 type(itsc) "Transaction 5 Status/control";
sc6 32 type(itsc) "Transaction 6 Status/control";
sc7 32 type(itsc) "Transaction 7 Status/control";
bp0 32 type(itbp0) "Buffer pointer 0";
bp1 32 type(itbp1) "Buffer pointer 1";
bp2 32 type(itbp2) "Buffer pointer 2";
bp3 32 type(itbp3) "Buffer pointer 3";
bp4 32 type(itbp3) "Buffer pointer 4";
bp5 32 type(itbp3) "Buffer pointer 5";
bp6 32 type(itbp3) "Buffer pointer 6";
};
// 3.3.2
datatype itsc msbfirst(32) "Isochronous transaction status/control" {
// Status
active 1 "Active";
dbe 1 "Data buffer error";
bd 1 "Babble detected";
xacterr 1 "Transaction error";
// Control
length 12 "Transaction length";
ioc 1 "Interrupt on complete";
pg 3 "Page select (0-6)";
offset 12 "Offset from state of buffer";
};
// 3.3.3
datatype itbp0 msbfirst(32) "iTD buffer pointer page 0" {
p 20 "Buffer pointer (4k aligned)";
epn 4 "Endpoint number";
_ 1 mbz;
da 7 "Device address";
};
datatype itdp1 msbfirst(32) "iTD buffer pointer page 1" {
p 20 "Buffer pointer (4k aligned)";
dir 1 "In (1) or out (0) PID";
mps 11 "Maximum packet size";
};
datatype itdp2 msbfirst(32) "iTD buffer pointer page 2" {
p 20 "Buffer pointer (4k aligned)";
_ 10 mbz;
multi 2 "Num. transactions/micro-frame + 1 (0=rsvd)";
};
datatype itdp3 msbfirst(32) "iTD buffer pointer page 3" {
p 20 "Buffer pointer (4k aligned)";
_ 12 mbz;
};
// 3.4
datatype sitd msbfirst(32) "Split isochronous transfer descriptor" {
next 32 type(lp) "Next descriptor";
cap 32 type(sitcap) "Endpoint capabilities/characteristics";
msc 32 type(sitmsc) "Micro-frame schedule control";
tsc 32 type(sittsc) "Transfer status and control";
bpl0 32 type(sitbpl0) "Buffer page pointer 0";
bpl1 32 type(sitbpl1) "Buffer page pointer 1";
bp 32 type(sitblp) "Back link";
};
// 3.4.2
datatype sitcap msbfirst(32) "siTD endpoint capabilities/characteristics" {
dir 1 "In (1) or out (0) PID";
port 7 "Port number";
_ 1 mbz;
hub 7 "Hub address";
_ 4 mbz;
epn 4 "Endpoint number";
_ 1 mbz;
da 7 "Device address";
};
datatype sitmsc msbfirst(32) "siTD micro-frame schedule control" {
_ 16 mbz;
scm 8 "Split completion mask";
ssm 8 "Split start mask";
};
// 3.4.3
datatype sittsc msbfirst(32) "siTD transfer status and control" {
ioc 1 "Interrupt on complete";
p 1 "Page select";
_ 4 mbz;
total 10 "Total bytes to transfer";
cpm 8 "Microframe complete-split progress mask";
active 1 "Status active";
err 1 "ERR response rcvd from transaction translator";
dbe 1 "Data buffer error";
babble 1 "Babble detected";
xacterr 1 "Transaction error";
mmf 1 "Missed micro-frame";
sts 1 "Split transaction state";
_ 1 mbz;
};
// 3.4.4
constants xpos width(2) "Transaction position" {
tp_all = 0b00 "Entire payload";
tp_begin = 0b01 "First data payload";
tp_mid = 0b10 "Middle payload";
tp_end = 0b11 "Final payload";
};
datatype sitbpl0 msbfirst(32) "siTD buffer page pointer list page 0" {
p 20 "Buffer pointer (4k aligned)";
offset 12 "Current offset";
};
datatype sitbpl1 msbfirst(32) "siTD buffer page pointer list page 1" {
p 20 "Buffer pointer (4k aligned)";
_ 7 mbz;
tp 2 type(xpos) "Transaction position";
tc 3 "Transaction count";
};
// 3.4.5
datatype sitblp msbfirst(32) "siTD back link pointer" {
bp 27 "Back pointer";
_ 4 mbz;
t 1 "Terminate (0 -> bp is valid)";
};
// 3.5
datatype qtd msbfirst(32) "Queue element transfer descriptor" {
next 32 type(lp) "Next element";
altnext 32 type(lp) "Alternate next pointer";
token 32 type(qttok) "Token";
bp0 32 type(qtbp0) "Buffer pointer 0";
bp1 32 type(qtbp1) "Buffer pointer 1";
bp2 32 type(qtbp1) "Buffer pointer 2";
bp3 32 type(qtbp1) "Buffer pointer 3";
bp4 32 type(qtbp1) "Buffer pointer 4";
};
// 3.5.3
constants pid "PID token encoding" {
pid_out = 0b00 "Generates OUT token (E1H)";
pid_in = 0b01 "Generates IN token (69H)";
pid_setup = 0b10 "Generates SETUP token (2DH)";
pid_rsvd = 0b11 "Reserved";
};
datatype qttok msbfirst(32) "qTD Token" {
toggle 1 "Data toggle";
tbt 15 "Total bytes to transfer";
ioc 1 "Interrupt on complete";
cp 3 "Current page";
cerr 2 "Error counter";
pidc 2 type(pid) "PID code token";
active 1 "Status active";
halted 1 "Serious error at endpoint";
dbe 1 "Data buffer error";
babble 1 "Babble detected";
xacterr 1 "Transaction error";
mmf 1 "Missed micro-frame";
sts 1 "Split transaction state";
ping 1 "Ping state";
};
// 3.5.4
datatype qtbp0 msbfirst(32) "Queue element buffer pointer page 0" {
p 20 "Buffer pointer (4k aligned)";
offset 12 "Current offset";
};
datatype qtbp1 msbfirst(32) "Queue element buffer pointer page 1" {
p 20 "Buffer pointer (4k aligned)";
_ 12 mbz;
};
// 3.6
datatype qh msbfirst(32) "Queue head" {
hlp 32 type(lp) "Horizontal link pointer";
cap1 32 type(qhcap1) "Endpoint capabilities/characteristics 1";
cap2 32 type(qhcap2) "Endpoint capabilities/characteristics 2";
current 32 type(lp) "Current element";
next 32 type(lp) "Next element";
altnext 32 type(qhlp) "Alternate next pointer";
token 32 type(qttok) "Token";
bp0 32 type(qtbp0) "Buffer pointer 0";
bp1 32 type(qhbp1) "Buffer pointer 1";
bp2 32 type(qhbp2) "Buffer pointer 2";
bp3 32 type(qtbp1) "Buffer pointer 3";
bp4 32 type(qtbp1) "Buffer pointer 4";
};
// 3.6.2
constants speed width(2) "Endpoint speed" {
fullspeed = 0b00 "Full-speed (12Mbs)";
lowspeed = 0b01 "Low-speed (1.5Mbs)";
highspeed = 0b10 "High-speed (480 Mb/s)";
};
datatype qhcap1 msbfirst(32) "Endpoint capabilities: queue head word 1"{
rl 4 "NAK count reload";
c 1 "Control endpoint flag";
mpl 11 "Maximum packet length";
h 1 "Head of reclamation list flag";
dtc 1 "Data toggle control";
eps 2 type(speed) "Endpoint speed";
epn 4 "Endpoint number";
i 1 "Inactivate on next transaction";
da 7 "Device address";
};
datatype qhcap2 msbfirst(32) "Endpoint capabilities: queue head word 2"{
mult 2 "High-bandwidth pipe multiplier";
port 7 "Port number";
hub 7 "Hub address";
scm 8 "Split completion mask";
ism 8 "Interrupt schedule mask";
};
// 3.6.3
datatype qhlpa msbfirst(32) "Alternate queue head link pointer" {
p 27 "Frame list link pointer";
nakcnt 4 "NACK counter";
t 1 "Pointer value invalid";
};
datatype qhbp1 msbfirst(32) "Queue head buffer pointer page 1" {
p 20 "Buffer pointer (4k aligned)";
_ 4 mbz;
cpm 8 "Split-transaction complete-split progress";
};
datatype qhbp2 msbfirst(32) "Queue head buffer pointer page 2" {
p 20 "Buffer pointer (4k aligned)";
sb 7 "S-bytes";
ft 5 "Split-transaction frame tag";
};
// 3.7
datatype fstm msbfirst(32) "Periodic Frame Span Traversal Node" {
normal 32 type(lp) "Normal path link pointer";
back 32 type(lp) "Back path link pointer";
};*/
};