Add hulk.volatile

This commit is contained in:
Josh Holtrop 2024-12-03 00:18:45 -05:00
parent 13b6f39e1a
commit 2d95371aa1
3 changed files with 72 additions and 37 deletions

View File

@ -3,12 +3,12 @@
*/ */
module hulk.time; module hulk.time;
import core.volatile; import hulk.volatile;
struct Time struct Time
{ {
/** System uptime (ms). */ /** System uptime (ms). */
private static __gshared ulong s_uptime; private static __gshared Volatile!ulong s_uptime;
/** /**
* Millisecond ISR. * Millisecond ISR.
@ -23,7 +23,7 @@ struct Time
*/ */
public static @property ulong uptime() public static @property ulong uptime()
{ {
return volatileLoad(&s_uptime); return s_uptime;
} }
/** /**

View File

@ -12,7 +12,7 @@ import hulk.pci;
import hulk.hurl.a1; import hulk.hurl.a1;
import hulk.klog; import hulk.klog;
import hulk.time; import hulk.time;
import core.volatile; import hulk.volatile;
struct XHCI struct XHCI
{ {
@ -27,14 +27,14 @@ struct XHCI
* Offset from beginning of capability registers to beginning of * Offset from beginning of capability registers to beginning of
* operational registers. * operational registers.
*/ */
ubyte capability_length; Volatile!ubyte capability_length;
ubyte _reserved01; ubyte _reserved01;
/** /**
* Interface version number supported (psuedo-BSD). * Interface version number supported (psuedo-BSD).
*/ */
ushort hci_version; Volatile!ushort hci_version;
/** /**
* HCSPARAMS1. * HCSPARAMS1.
@ -43,7 +43,7 @@ struct XHCI
* 23:19 reserved * 23:19 reserved
* 31:24 number of ports (MaxPorts) * 31:24 number of ports (MaxPorts)
*/ */
uint hcs_params1; Volatile!uint hcs_params1;
/** /**
* 3:0 isochronous scheduling threshold (IST) * 3:0 isochronous scheduling threshold (IST)
@ -53,14 +53,14 @@ struct XHCI
* 26 scratchpad restore (SPR) * 26 scratchpad restore (SPR)
* 31:27 max scratchpad buffers (low 5 bits) * 31:27 max scratchpad buffers (low 5 bits)
*/ */
uint hcs_params2; Volatile!uint hcs_params2;
/** /**
* 7:0 U1 device exit latency * 7:0 U1 device exit latency
* 15:8 reserved * 15:8 reserved
* 31:16 U2 device exit latency * 31:16 U2 device exit latency
*/ */
uint hcs_params3; Volatile!uint hcs_params3;
/** /**
* 0 64-bit addressing capability (AC64) * 0 64-bit addressing capability (AC64)
@ -80,7 +80,7 @@ struct XHCI
* offset in 32-bit words from base of capability registers to base * offset in 32-bit words from base of capability registers to base
* of capabilities list * of capabilities list
*/ */
uint hcc_params1; Volatile!uint hcc_params1;
/** /**
* 1:0 reserved * 1:0 reserved
@ -88,13 +88,13 @@ struct XHCI
* offset in 32-bit words from base of capability registers to the * offset in 32-bit words from base of capability registers to the
* doorbell array * doorbell array
*/ */
uint doorbell_offset; Volatile!uint doorbell_offset;
/** /**
* 4:0 reserved * 4:0 reserved
* 31:5 runtime register space offset * 31:5 runtime register space offset
*/ */
uint rts_offset; Volatile!uint rts_offset;
/** /**
* 0 U3 entry capability (U3C) * 0 U3 entry capability (U3C)
@ -109,13 +109,13 @@ struct XHCI
* 9 virtualization based trusted I/O capability (VTC; xHCI v1.2+) * 9 virtualization based trusted I/O capability (VTC; xHCI v1.2+)
* 31:10 reserved * 31:10 reserved
*/ */
uint hcc_params2; Volatile!uint hcc_params2;
/** /**
* 11:0 reserved * 11:0 reserved
* 31:12 VTIO register space offset (xHCI v1.2+) * 31:12 VTIO register space offset (xHCI v1.2+)
*/ */
uint vtios_offset; Volatile!uint vtios_offset;
} }
static assert(CapabilityRegisters.sizeof == 0x24u); static assert(CapabilityRegisters.sizeof == 0x24u);
@ -142,7 +142,7 @@ struct XHCI
* 16 VTIO enable (VTIOE; xHCI v1.2+) * 16 VTIO enable (VTIOE; xHCI v1.2+)
* 31:17 reserved * 31:17 reserved
*/ */
uint usb_command; Volatile!uint usb_command;
/** /**
* 0 HCHalted * 0 HCHalted
@ -158,13 +158,13 @@ struct XHCI
* 12 Host Controller Error (HCE) * 12 Host Controller Error (HCE)
* 31:13 reserved * 31:13 reserved
*/ */
uint usb_status; Volatile!uint usb_status;
/** /**
* 15:0 Page Size (actual page size is 2^(x+12)) * 15:0 Page Size (actual page size is 2^(x+12))
* 31:16 reserved * 31:16 reserved
*/ */
uint page_size; Volatile!uint page_size;
uint[2] _reserved01; uint[2] _reserved01;
@ -172,7 +172,7 @@ struct XHCI
* 15:0 Notification Enable * 15:0 Notification Enable
* 31:16 reserved * 31:16 reserved
*/ */
uint dn_ctrl; Volatile!uint dn_ctrl;
/** /**
* 0 Ring Cycle State (RCS) * 0 Ring Cycle State (RCS)
@ -182,7 +182,7 @@ struct XHCI
* 5:4 reserved * 5:4 reserved
* 63:6 Command Ring Pointer * 63:6 Command Ring Pointer
*/ */
ulong cr_ctrl; Volatile!ulong cr_ctrl;
uint[4] _reserved02; uint[4] _reserved02;
@ -190,7 +190,7 @@ struct XHCI
* 5:0 reserved * 5:0 reserved
* 63:6 Device Context Base Address Array Pointer * 63:6 Device Context Base Address Array Pointer
*/ */
ulong dcbaap; Volatile!ulong dcbaap;
/** /**
* 7:0 Max Device Slots Enabled (MaxSlotsEn) * 7:0 Max Device Slots Enabled (MaxSlotsEn)
@ -198,7 +198,7 @@ struct XHCI
* 9 Configuration Information Enable (CIE; xHCI v1.1+) * 9 Configuration Information Enable (CIE; xHCI v1.1+)
* 31:10 reserved * 31:10 reserved
*/ */
uint config; Volatile!uint config;
uint _reserved03; uint _reserved03;
} }
@ -239,22 +239,22 @@ struct XHCI
* 30 Device Removable * 30 Device Removable
* 31 Warm Port Reset * 31 Warm Port Reset
*/ */
uint portsc; Volatile!uint portsc;
/** /**
* Port Power Management Status and Control * Port Power Management Status and Control
*/ */
uint portpmsc; Volatile!uint portpmsc;
/** /**
* Port Link Info * Port Link Info
*/ */
uint portli; Volatile!uint portli;
/** /**
* Port Hardware LPM Control (xHCI v1.1+) * Port Hardware LPM Control (xHCI v1.1+)
*/ */
uint porthlpmc; Volatile!uint porthlpmc;
} }
static assert(PortRegisters.sizeof == 0x10u); static assert(PortRegisters.sizeof == 0x10u);
@ -266,7 +266,7 @@ struct XHCI
/** /**
* Microframe index. Incremented by controller each microframe. * Microframe index. Incremented by controller each microframe.
*/ */
uint mfindex; Volatile!uint mfindex;
uint[7] _reserved01; uint[7] _reserved01;
@ -289,21 +289,21 @@ struct XHCI
* 1 Interrupt Enable * 1 Interrupt Enable
* 31:2 reserved * 31:2 reserved
*/ */
uint imr; Volatile!uint imr;
/** /**
* Interrupter Moderation. * Interrupter Moderation.
* 15:0 Interrupt Moderation Interval * 15:0 Interrupt Moderation Interval
* 31:16 Interrupt Moderation Counter * 31:16 Interrupt Moderation Counter
*/ */
uint im; Volatile!uint im;
/** /**
* Event Ring Segment Table Size. * Event Ring Segment Table Size.
* 15:0 Event Ring Segment Table Size * 15:0 Event Ring Segment Table Size
* 31:16 reserved * 31:16 reserved
*/ */
uint ersts; Volatile!uint ersts;
uint reserved; uint reserved;
@ -312,7 +312,7 @@ struct XHCI
* 5:0 reserved * 5:0 reserved
* 63:6 Event Ring Segment Table Base Address * 63:6 Event Ring Segment Table Base Address
*/ */
ulong erstba; Volatile!ulong erstba;
/** /**
* Event Ring Dequeue Pointer. * Event Ring Dequeue Pointer.
@ -320,7 +320,7 @@ struct XHCI
* 3 Event Handler Busy * 3 Event Handler Busy
* 63:4 Event Ring Dequeue Pointer * 63:4 Event Ring Dequeue Pointer
*/ */
ulong erdp; Volatile!ulong erdp;
} }
/** /**
@ -331,9 +331,9 @@ struct XHCI
*/ */
struct DoorbellRegister struct DoorbellRegister
{ {
ubyte target; Volatile!ubyte target;
ubyte _reserved01; ubyte _reserved01;
ushort task_id; Volatile!ushort task_id;
} }
static assert(DoorbellRegister.sizeof == 4u); static assert(DoorbellRegister.sizeof == 4u);
@ -361,7 +361,7 @@ struct XHCI
/* TODO: write dcbaap. */ /* TODO: write dcbaap. */
/* TODO: write cr_ctrl. */ /* TODO: write cr_ctrl. */
/+ TODO: /+ TODO:
m_operational_registers.config = volatileLoad(&m_capability_registers.hcs_params1) & 0xFu; m_operational_registers.config = m_capability_registers.hcs_params1 & 0xFu;
m_operational_registers.dn_ctrl = 1u << 1u; m_operational_registers.dn_ctrl = 1u << 1u;
+/ +/
/* TODO: set up interrupt register set. */ /* TODO: set up interrupt register set. */
@ -419,7 +419,7 @@ struct XHCI
{ {
Time.msleep(1u); Time.msleep(1u);
if ((volatileLoad(&m_operational_registers.usb_status) & 1u) != 0u) if ((m_operational_registers.usb_status & 1u) != 0u)
{ {
break; break;
} }
@ -441,8 +441,8 @@ struct XHCI
{ {
Time.msleep(1u); Time.msleep(1u);
if (((volatileLoad(&m_operational_registers.usb_command) & (1u << 1u)) == 0u) && if (((m_operational_registers.usb_command & (1u << 1u)) == 0u) &&
((volatileLoad(&m_operational_registers.usb_status) & (1u << 11u)) == 0u)) ((m_operational_registers.usb_status & (1u << 11u)) == 0u))
{ {
break; break;
} }

35
src/hulk/volatile.d Normal file
View File

@ -0,0 +1,35 @@
module hulk.volatile;
import core.volatile;
struct Volatile(T)
{
private T value;
public @property T read()
{
return volatileLoad(&value);
}
alias read this;
public void opAssign(T value)
{
volatileStore(&this.value, value);
}
public T opUnary(string s)()
{
T v = read();
mixin(s ~ "v;");
volatileStore(&this.value, v);
return v;
}
public T opOpAssign(string s)(T rhs)
{
T v = read();
mixin("v " ~ s ~ "= rhs;");
volatileStore(&this.value, v);
return v;
}
}