470 lines
14 KiB
Plaintext
470 lines
14 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";
|
|
};*/
|
|
};
|
|
|