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

341 lines
8.7 KiB
Plaintext

/*
* Copyright (c) 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, Universitaestr. 6, CH-8092 Zurich. Attn: Systems Group.
*/
/*
* ohci.dev
*
* DESCRIPTION: Open Host Controller Interface (OHCI) description
*
* Archaic USB interface, but still found on e.g. ATI and NVidia
* chipsets.
*
* Numbers in comments refer to the OpenHCI Open Host Controller
* Interface Specification for USB, by Compaq, Microsoft, and National
* Semiconductor, 09/14/99 2:33 PM, Release: 1.0a
*/
device ohci lsbfirst ( io base ) "OHCI USB controller" {
/*
//
// Data structures
//
// 4.2.1
constants direction width(2) "Data flow direction" {
dir_td = 0b00 "Get direction from TD";
dir_out = 0b01 "Out";
dir_in = 0b10 "In";
dir_td1 = 0b11 "Get direction from TD (alt)";
};
datatype epdesc lsbfirst(32) "Endpoint descriptor" {
fa 7 "Function address";
en 4 "Endpoint number";
d 2 type(direction) "Direction";
s 1 "Speed (1=low, 0=full)";
k 1 "Skip";
f 1 "Format (1=isochronous, 0=general)";
mps 11 "Maximum packet size";
_ 5;
_ 4;
tailp 28 "TD queue tail pointer";
h 1 "Halted";
c 1 "Toggle carry";
_ 2 mbz;
headp 28 "TD queue head pointer";
_ 4;
nexted 28 "Next endpoint descriptor";
};
// 4.3.1
constants pid width(2) "Direction / PID for token" {
pid_setup = 0b00 "Setup (to endpoint)";
pid_out = 0b01 "To endpoint";
pid_in = 0b10 "From endpoint";
};
datatype gentd lsbfirst(32) "General transfer descriptor" {
_ 18;
r 1 "Buffer rounding";
dp 2 type(pid) "Direction or PID";
di 3 "Delay interrupt frames";
t 2 "Data toggle";
ec 2 "Error count";
cc 4 type(ccode) "Condition code for last attempted transaction";
cbp 32 "Current buffer pointer";
_ 4 mbz;
nexttd 28 "Next transfer descriptor";
be 32 "Buffer end";
};
// 4.3.2
datatype isotd lsbfirst(32) "Isochronous transfer descriptor" {
sf 16 "Starting frame";
_ 5;
di 3 "Delay interrupt frames";
fc 3 "Frame count";
_ 1;
cc 4 type(ccode) "Condition code for last attempted transaction";
_ 12;
bp0 20 "Buffer page 0";
_ 5 mbz;
nexttd 27 "Next transfer descriptor";
be 32 "Buffer end";
ofpsw0 16 "Offset / packet status word 0";
ofpsw1 16 "Offset / packet status word 1";
ofpsw2 16 "Offset / packet status word 2";
ofpsw3 16 "Offset / packet status word 4";
ofpsw4 16 "Offset / packet status word 3";
ofpsw5 16 "Offset / packet status word 5";
ofpsw6 16 "Offset / packet status word 6";
ofpsw7 16 "Offset / packet status word 7";
};
datatype psw lsbfirst(16) "Packet status word" {
size 11 "Size of packet";
_ 1 mbz;
cc 4 type(ccode) "Condition code";
};
/// 4.3.3
constants ccode width(4) "Completion codes" {
cc_ne = 0b0000 "No error";
cc_crc = 0b0001 "CRC error";
cc_bs = 0b0010 "Bitstuffing violation";
cc_dtm = 0b0011 "Data toggle PID mismatch";
cc_stl = 0b0100 "EP returned stall PID";
cc_dnr = 0b0101 "Device not responding";
cc_pcf = 0b0110 "PID check failure";
cc_uxp = 0b0111 "Unexpected PID";
cc_dor = 0b1000 "Data overrun";
cc_dur = 0b1001 "Data underrun";
cc_bor = 0b1100 "Buffer overrun";
cc_bur = 0b1101 "Buffer underrun";
cc_nac = 0b1110 "Not accessed";
cc_nac_ = 0b1111 "Not accessed (alternate)";
};
*/
//
// Registers
//
// 7.1 Control and status partition
//
// 7.1.1 Interface revision
/// Initially 0x10.
register revision ro io(base, 0x00) "Revision" {
rev 8 "BCD rep. of interface version";
_ 24;
};
// 7.1.2 Control register
constants state "Functional state" {
st_reset = 0b00 "Reset (after h/w reset)";
st_resume = 0b01 "Resume from downstream port";
st_operational = 0b10 "Operational (running)";
st_suspend = 0b11 "Suspend (after s/w reset)";
};
// Initially 0x00
register control rw io(base, 0x04) "Control" {
cbsr 2 "Control/bulk service ratio";
pe 1 "Periodic list enable";
ie 1 "Isochronous enable";
cle 1 "Control list enable";
ble 1 "Bulk list enable";
hcfs 2 type(state) "Host controller functional state";
ir 1 "Interrupt routing";
rwc 1 "Remote wakeup connected";
rwe 1 "Remote wakeup enabled";
_ 21;
};
// 7.1.3 Command and Status
// Initially 0x00
register cmdstatus rw io(base, 0x08) "08 CommandStatus" {
hcr 1 "Host controller reset";
clf 1 "Control list filled";
blf 1 "Bulk list filled";
ocr 1 "Ownership change request";
_ 12;
soc 2 ro "Scheduling overrun count";
_ 14;
};
// 7.1.4-6: Interrupt registers
regtype interrupt "Interrupts" {
so 1 "Scheduling overrun";
wdh 1 "Writeback done head";
sf 1 "Start of frame";
rd 1 "Resume detected";
ue 1 "Unrecoverable error";
fno 1 "Frame number overflow";
rhsc 1 "Root hub status change";
_ 23;
oc 1 "Ownership change";
mie 1 "Master interrupt enable";
};
register intstatus rw io(base, 0x0C) "Interrupt status"
type(interrupt);
register intenable rw io(base, 0x10) "Interrupt enable"
type(interrupt);
register intdisable rw io(base, 0x14) "Interrupt disable"
type(interrupt);
//
// 7.2 Memory pointer partition
//
// 7.2.1
register hcca rw io(base, 0x18) "Host controller communication area" {
_ 8 mbz;
hcca 24 "Physical address";
};
regtype physptr "Physical address pointer" {
_ 4 mbz;
addr 28 "Address";
};
// 7.2.2.
register period_cur ro io(base, 0x1C) "Cur. isochronous or int. ED"
type(physptr);
// 7.2.3
register ctrl_head rw io(base, 0x20) "First ED of control list"
type(physptr);
// 7.2.4
register ctrl_cur rw io(base, 0x24) "Current ED of control list"
type(physptr);
// 7.2.5
register bulk_head rw io(base, 0x28) "First ED of bulk list"
type(physptr);
// 7.2.6
register bulk_cur rw io(base, 0x2C) "Current ED of bulk list"
type(physptr);
// 7.2.7
register done_head ro io(base, 0x30) "Done head pointer"
type(physptr);
//
// 7.3 Frame counter partition
//
// 7.3.1
register fm_interval rw io(base, 0x34) "Frame interval" {
fi 14 "Frame interval (dflt 0x2edf)";
_ 2;
fsmps 15 "FS largest data packet";
fit 1 "Frame interval toggle";
};
// 7.3.2
register fm_remain ro io(base, 0x38) "Frame remaining" {
fr 14 "Bit time remaining in current frame";
_ 17;
frt 1 "Frame remaining toggle";
};
// 7.3.3
register fm_num ro io(base, 0x3C) "Frame number" {
fn 16 "Frame number (16-bit counter)";
_ 16;
};
// 7.3.4
register period_start rw io(base, 0x40) "Period start" {
ps 14 "Start time for processing periodic list";
_ 18;
};
// 7.3.5
register hclsthreshold rw io(base, 0x44) "LS threshold" {
lst 11 "Low-speed threshold (should be 0x0628)";
_ 21;
};
//
// 7.4 Root Hub partition
//
// 7.4.1
register rh_descra rw io(base, 0x48) "Root hub descriptor a" {
ndp 8 ro "Number of downstream ports";
psm 1 "Power switching mode";
nps 1 "No power switching";
dt 1 ro "Device type";
ocpm 1 "Overcurrent protection mode";
nocp 1 "No overcurrent protection";
_ 11;
potpgt 8 "Power-on to power-good time (* 2ms)";
};
// 7.4.2
register rh_descrb rw io(base, 0x4C) "Root hub descriptor b" {
dr 16 "Device removal";
ppcm 16 "Port power control mask";
};
// 7.4.3
register rh_status rw io(base, 0x50) "Root hub status" {
lps 1 wo "Clear global power";
oci 1 ro "Overcurrent indicator";
_ 13;
drwe 1 rw1c "Device remote wakeup enable";
lpsc 1 wo "Set globl power";
ocic 1 rw1c "Overcurrent indicator change";
_ 13;
crwe 1 wo "Clear remote wakeup enable";
};
// 7.4.4
// Assume 256 ports at this stage; it's actually given by
// rh_descra->ndp.
regarray rh_portstat ro io(base, 0x54)[256] "Root hub port status" {
ccs 1 "Current connection status";
pes 1 "Port enable status";
pss 1 "Port suspend status";
poci 1 "Port overcurrent indicator";
prs 1 "Port reset status";
_ 3;
pps 1 "Port power status";
lsda 1 "Low-speed device attached";
_ 6;
csc 1 "Connect status change";
pesc 1 "Port enable status change";
pssc 1 "Port suspend status change";
ocic 1 "Port overcurrent indicator change";
prsc 1 "Port reset status change";
_ 11;
};
regarray rh_portctrl wo also io(base, 0x54)[256] "Root hub port control" {
cpe 1 "Clear port enable";
spe 1 "Set port enable";
sps 1 "Set port suspend";
css 1 "Clear suspend status";
spr 1 "Set port reset";
_ 3;
spp 1 "Set port power";
cpp 1 "Clear port power";
_ 6;
csc 1 "Clear connect status change";
pesc 1 "Clear port enable status change";
pssc 1 "Clear port suspend status change";
ocic 1 "Clear port overcurrent indicator change";
prsc 1 "Clear port reset status change";
_ 11;
};
};