diff --git a/packages/harbor/lib/harbor.dart b/packages/harbor/lib/harbor.dart index 0eb5e87..b7600bc 100644 --- a/packages/harbor/lib/harbor.dart +++ b/packages/harbor/lib/harbor.dart @@ -47,7 +47,9 @@ export 'src/clock/clock_domain.dart'; export 'src/clock/clock_gate.dart'; // SoC +export 'src/soc/acpi.dart'; export 'src/soc/boot_sequencer.dart'; +export 'src/soc/cpu.dart'; export 'src/soc/device_tree.dart'; export 'src/soc/graph.dart'; export 'src/soc/harbor_soc.dart'; diff --git a/packages/harbor/lib/src/debug/debug_module.dart b/packages/harbor/lib/src/debug/debug_module.dart index 0dae635..beab43c 100644 --- a/packages/harbor/lib/src/debug/debug_module.dart +++ b/packages/harbor/lib/src/debug/debug_module.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// RISC-V Debug Module (DM) per the RISC-V Debug Specification 1.0. @@ -22,7 +23,8 @@ import '../soc/device_tree.dart'; /// - 0x12: haltsum1 0x16: abstracts 0x17: command /// - 0x18: abstractauto 0x20-0x2F: progbuf 0x38: sbcs /// - 0x39: sbaddress0 0x3C: sbdata0 -class HarborDebugModule extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborDebugModule extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address for the debug module's memory-mapped registers. final int baseAddress; @@ -239,4 +241,16 @@ class HarborDebugModule extends BridgeModule with HarborDeviceTreeNodeProvider { reg: BusAddressRange(baseAddress, 0x1000), properties: {'num-harts': numHarts, 'progbuf-size': progBufSize}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,debug-module', 'riscv,debug-013'], + 'num-harts': numHarts, + 'progbuf-size': progBufSize, + }, + ); } diff --git a/packages/harbor/lib/src/debug/trace.dart b/packages/harbor/lib/src/debug/trace.dart index a8cb25e..ecdd5f0 100644 --- a/packages/harbor/lib/src/debug/trace.dart +++ b/packages/harbor/lib/src/debug/trace.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// Trace packet type. @@ -45,7 +46,7 @@ enum HarborTracePacketType { /// - 0x18: BUF_WR (current write pointer, read-only) /// - 0x1C: SYNC_CNT (sync packet interval in branches) class HarborTraceEncoder extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address for trace registers. final int baseAddress; @@ -245,4 +246,16 @@ class HarborTraceEncoder extends BridgeModule reg: BusAddressRange(baseAddress, 0x1000), properties: {'buffer-size': bufferSize, 'sync-interval': syncInterval}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['riscv,trace'], + 'buffer-size': bufferSize, + 'sync-interval': syncInterval, + }, + ); } diff --git a/packages/harbor/lib/src/media/audio.dart b/packages/harbor/lib/src/media/audio.dart index dd484c7..7485d95 100644 --- a/packages/harbor/lib/src/media/audio.dart +++ b/packages/harbor/lib/src/media/audio.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// Audio sample format. @@ -109,7 +110,7 @@ enum HarborAudioCodecFormat { /// - 0x84: CODEC_STATUS (codec busy/done/error) /// - 0x88: CODEC_CAPS (supported codecs bitmask, read-only) class HarborAudioController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address in the SoC memory map. final int baseAddress; @@ -516,4 +517,24 @@ class HarborAudioController extends BridgeModule 'harbor,rx-fifo-depth': rxFifoDepth, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,audio'], + '#sound-dai-cells': 0, + 'harbor,interfaces': audioInterfaces.map((i) => i.name).join(', '), + 'harbor,max-channels': maxChannels, + 'harbor,sample-rates': sampleRates.map((r) => '$r').join(', '), + 'harbor,formats': formats.map((f) => f.name).join(', '), + if (hwCodecs.isNotEmpty) + 'harbor,codecs': hwCodecs.map((c) => c.displayName).join(', '), + if (hasSrc) 'harbor,has-src': true, + 'harbor,tx-fifo-depth': txFifoDepth, + 'harbor,rx-fifo-depth': rxFifoDepth, + }, + ); } diff --git a/packages/harbor/lib/src/media/media_engine.dart b/packages/harbor/lib/src/media/media_engine.dart index fb97c58..d7b845d 100644 --- a/packages/harbor/lib/src/media/media_engine.dart +++ b/packages/harbor/lib/src/media/media_engine.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import 'codec.dart'; @@ -52,7 +53,8 @@ import 'codec.dart'; /// - +0x44: SESS_LEVEL (codec level) /// - +0x48: SESS_BYTES_DONE (bytes processed, read-only) /// - +0x4C: SESS_FRAMES_DONE (frames processed, read-only) -class HarborMediaEngine extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborMediaEngine extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address in the SoC memory map. final int baseAddress; @@ -329,4 +331,24 @@ class HarborMediaEngine extends BridgeModule with HarborDeviceTreeNodeProvider { ), }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,media-engine'], + 'max-sessions': maxSessions, + 'harbor,codecs': codecs.map((c) => c.format.displayName).join(', '), + 'harbor,max-width': codecs.fold( + 0, + (max, c) => c.maxWidth > max ? c.maxWidth : max, + ), + 'harbor,max-height': codecs.fold( + 0, + (max, c) => c.maxHeight > max ? c.maxHeight : max, + ), + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/aplic.dart b/packages/harbor/lib/src/peripherals/aplic.dart index 531391a..0dd969e 100644 --- a/packages/harbor/lib/src/peripherals/aplic.dart +++ b/packages/harbor/lib/src/peripherals/aplic.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// RISC-V Advanced Platform-Level Interrupt Controller (APLIC). @@ -20,7 +21,8 @@ import '../soc/device_tree.dart'; /// - `target[i]`: 0x3004 + (i-1)*4 /// - IDC per hart: 0x4000 + hart*32 /// - `idelivery` +0x00, `iforce` +0x04, `ithreshold` +0x08, `claimi` +0x1C -class HarborAplic extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborAplic extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { final int sources; final int harts; final int priorityBits; @@ -318,4 +320,17 @@ class HarborAplic extends BridgeModule with HarborDeviceTreeNodeProvider { interruptCells: 2, properties: {'riscv,num-sources': sources}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x8000)], + properties: { + 'compatible': ['riscv,aplic'], + 'riscv,num-sources': sources, + 'interrupt-controller': true, + '#interrupt-cells': 2, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/clint.dart b/packages/harbor/lib/src/peripherals/clint.dart index 95c73b8..2872ca5 100644 --- a/packages/harbor/lib/src/peripherals/clint.dart +++ b/packages/harbor/lib/src/peripherals/clint.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// RISC-V Core Local Interruptor (CLINT), SiFive-compatible. @@ -16,7 +17,8 @@ import '../soc/device_tree.dart'; /// - `mtime`: 0xBFF8 (8 bytes, machine timer) /// /// Address space: 64 KB (0x10000). -class HarborClint extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborClint extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { final int? busDataWidth; /// Number of harts this CLINT serves. @@ -168,4 +170,15 @@ class HarborClint extends BridgeModule with HarborDeviceTreeNodeProvider { reg: BusAddressRange(baseAddress, 0x10000), properties: {'reg-names': 'control'}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x10000)], + properties: { + 'compatible': ['riscv,clint0'], + 'reg-names': 'control', + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/ddr.dart b/packages/harbor/lib/src/peripherals/ddr.dart index baeb29e..f45a0db 100644 --- a/packages/harbor/lib/src/peripherals/ddr.dart +++ b/packages/harbor/lib/src/peripherals/ddr.dart @@ -5,6 +5,7 @@ import '../bus/bus.dart'; import 'ddr_phy_ecp5.dart'; import 'ddr_sequencer.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/pretty_string.dart'; @@ -164,7 +165,7 @@ class HarborDdrConfig with HarborPrettyString { /// unimplemented shells until their PHYs exist; a Xilinx 7-series PHY for /// the Arty S7 reuses the sequencer. class HarborDdrController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { final int? busDataWidth; /// Memory configuration. @@ -391,4 +392,23 @@ class HarborDdrController extends BridgeModule 'clock-frequency': config.frequency, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, config.size)], + properties: { + 'compatible': [ + 'harbor,sdram-controller', + if (config.isSdr) 'harbor,sdr-sdram', + if (config.type == HarborDdrType.ddr3 || + config.type == HarborDdrType.ddr3l) + 'harbor,ddr3-sdram', + ], + 'sdram-type': config.type.name, + 'data-width': config.dataWidth, + 'clock-frequency': config.frequency, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/display.dart b/packages/harbor/lib/src/peripherals/display.dart index e145944..d5f4654 100644 --- a/packages/harbor/lib/src/peripherals/display.dart +++ b/packages/harbor/lib/src/peripherals/display.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/pretty_string.dart'; @@ -226,7 +227,7 @@ class HarborDisplayConfig with HarborPrettyString { /// - 0x20: INT_STATUS (W1C: vblank, underrun) /// - 0x24: INT_ENABLE class HarborDisplayController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Display configuration. final HarborDisplayConfig config; @@ -487,4 +488,17 @@ class HarborDisplayController extends BridgeModule 'max-height': config.maxHeight, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,display'], + 'output-interface': config.interface_.name, + 'max-width': config.maxWidth, + 'max-height': config.maxHeight, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/dma.dart b/packages/harbor/lib/src/peripherals/dma.dart index a7812f2..0042c8b 100644 --- a/packages/harbor/lib/src/peripherals/dma.dart +++ b/packages/harbor/lib/src/peripherals/dma.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/pretty_string.dart'; @@ -81,7 +82,7 @@ class HarborDmaChannelConfig with HarborPrettyString { /// - 0x004: INT_STATUS (per-channel interrupt status, W1C) /// - 0x008: INT_ENABLE (per-channel interrupt enable) class HarborDmaController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Number of DMA channels. final int channels; @@ -343,4 +344,16 @@ class HarborDmaController extends BridgeModule reg: BusAddressRange(baseAddress, 0x1000), properties: {'dma-channels': channels, '#dma-cells': 1}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,dma'], + 'dma-channels': channels, + '#dma-cells': 1, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/efuse.dart b/packages/harbor/lib/src/peripherals/efuse.dart index c835978..5ae08f4 100644 --- a/packages/harbor/lib/src/peripherals/efuse.dart +++ b/packages/harbor/lib/src/peripherals/efuse.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// eFuse bank configuration. @@ -189,7 +190,8 @@ class HarborEfuseBlock extends BridgeModule { /// - 0x14: LOCK (per-region lock bits, write-1-to-lock) /// - 0x18: TIMING (program pulse width in clock cycles) /// - 0x1C: KEY (write 0x4F545021 to unlock programming) -class HarborEfuseDevice extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborEfuseDevice extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address in the SoC memory map. final int baseAddress; @@ -446,4 +448,20 @@ class HarborEfuseDevice extends BridgeModule with HarborDeviceTreeNodeProvider { '#size-cells': 1, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,efuse', 'harbor,otp'], + 'harbor,total-bits': config.totalBits, + 'harbor,bits-per-word': config.bitsPerWord, + 'harbor,regions': config.regions, + 'harbor,unlock-key': programUnlockKey, + '#address-cells': 1, + '#size-cells': 1, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/ethernet.dart b/packages/harbor/lib/src/peripherals/ethernet.dart index 04f2129..f1098b8 100644 --- a/packages/harbor/lib/src/peripherals/ethernet.dart +++ b/packages/harbor/lib/src/peripherals/ethernet.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/pretty_string.dart'; @@ -110,7 +111,8 @@ class HarborEthernetConfig with HarborPrettyString { /// - 0x038: RX_DESC_BASE (RX descriptor ring base address) /// - 0x040: MDIO_CTRL (PHY management: addr, reg, write, busy) /// - 0x044: MDIO_DATA (PHY management data) -class HarborEthernetMac extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborEthernetMac extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// MAC configuration. final HarborEthernetConfig config; @@ -345,4 +347,16 @@ class HarborEthernetMac extends BridgeModule with HarborDeviceTreeNodeProvider { 'max-speed': config.maxSpeed.mbps, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,ethernet'], + 'phy-mode': config.phyInterface.name, + 'max-speed': config.maxSpeed.mbps, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/flash.dart b/packages/harbor/lib/src/peripherals/flash.dart index 1305be5..f471b18 100644 --- a/packages/harbor/lib/src/peripherals/flash.dart +++ b/packages/harbor/lib/src/peripherals/flash.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// Read-only flash/ROM memory module. @@ -11,7 +12,8 @@ import '../soc/device_tree.dart'; /// interface. Write requests are silently ignored. /// /// Used for boot ROM, firmware storage, etc. -class HarborFlash extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborFlash extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Memory size in bytes. final int size; @@ -70,4 +72,15 @@ class HarborFlash extends BridgeModule with HarborDeviceTreeNodeProvider { reg: BusAddressRange(baseAddress, size), properties: {'data-width': dataWidth}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, size)], + properties: { + 'compatible': ['harbor,flash', 'mtd-rom'], + 'data-width': dataWidth, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/gpio.dart b/packages/harbor/lib/src/peripherals/gpio.dart index 784f2b4..c5a3e76 100644 --- a/packages/harbor/lib/src/peripherals/gpio.dart +++ b/packages/harbor/lib/src/peripherals/gpio.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// General-Purpose I/O (GPIO) peripheral. @@ -17,7 +18,8 @@ import '../soc/device_tree.dart'; /// - 0x0C: IRQ_EN (read/write, interrupt enable per pin) /// - 0x10: IRQ_STATUS (read/write-1-to-clear, interrupt status) /// - 0x14: IRQ_EDGE (read/write, 0=level, 1=edge triggered) -class HarborGpio extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborGpio extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Number of GPIO pins. final int pinCount; @@ -172,4 +174,17 @@ class HarborGpio extends BridgeModule with HarborDeviceTreeNodeProvider { reg: BusAddressRange(baseAddress, 0x1000), properties: {'ngpios': pinCount, '#gpio-cells': 2, 'gpio-controller': true}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,gpio', 'sifive,gpio0'], + 'ngpios': pinCount, + '#gpio-cells': 2, + 'gpio-controller': true, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/i2c.dart b/packages/harbor/lib/src/peripherals/i2c.dart index 74fb847..0483de8 100644 --- a/packages/harbor/lib/src/peripherals/i2c.dart +++ b/packages/harbor/lib/src/peripherals/i2c.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// I2C master/slave controller. @@ -17,7 +18,7 @@ import '../soc/device_tree.dart'; /// /// Supports standard (100 kHz), fast (400 kHz), and fast-plus (1 MHz). class HarborI2cController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address in the SoC memory map. final int baseAddress; @@ -249,4 +250,16 @@ class HarborI2cController extends BridgeModule reg: BusAddressRange(baseAddress, 0x1000), properties: {'#address-cells': 1, '#size-cells': 0}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,i2c', 'opencores,i2c-ocores'], + '#address-cells': 1, + '#size-cells': 0, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/imsic.dart b/packages/harbor/lib/src/peripherals/imsic.dart index ab0a27f..8311366 100644 --- a/packages/harbor/lib/src/peripherals/imsic.dart +++ b/packages/harbor/lib/src/peripherals/imsic.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// RISC-V Incoming MSI Controller (IMSIC). @@ -26,7 +27,8 @@ import '../soc/device_tree.dart'; /// The IMSIC address for each hart is used as the MSI target address /// by devices. Writing an interrupt identity to seteipnum sets the /// corresponding pending bit. -class HarborImsic extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborImsic extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address for this hart's IMSIC. final int baseAddress; @@ -178,4 +180,19 @@ class HarborImsic extends BridgeModule with HarborDeviceTreeNodeProvider { 'msi-controller': true, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['riscv,imsics'], + 'riscv,num-ids': numIds, + if (numGuests > 0) 'riscv,num-guest-ids': numIds, + '#interrupt-cells': 0, + 'interrupt-controller': true, + 'msi-controller': true, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/iommu.dart b/packages/harbor/lib/src/peripherals/iommu.dart index 9ec700c..36e00fc 100644 --- a/packages/harbor/lib/src/peripherals/iommu.dart +++ b/packages/harbor/lib/src/peripherals/iommu.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// RISC-V IOMMU translation mode. @@ -45,7 +46,8 @@ enum HarborIommuMode { /// - 0x058: cqcsr 0x05C: fqcsr 0x060: pqcsr /// - 0x064: ipsr 0x100: iohpmcycles /// - 0x108-0x1F8: iohpmctr/iohpmevt -class HarborIommu extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborIommu extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address for IOMMU registers. final int baseAddress; @@ -209,4 +211,17 @@ class HarborIommu extends BridgeModule with HarborDeviceTreeNodeProvider { 'riscv,max-mode': maxMode.name, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['riscv,iommu'], + '#iommu-cells': 1, + 'riscv,iotlb-entries': iotlbEntries, + 'riscv,max-mode': maxMode.name, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/maskrom.dart b/packages/harbor/lib/src/peripherals/maskrom.dart index 85ccd0b..c1f841e 100644 --- a/packages/harbor/lib/src/peripherals/maskrom.dart +++ b/packages/harbor/lib/src/peripherals/maskrom.dart @@ -6,6 +6,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/elf_loader.dart'; @@ -31,7 +32,8 @@ import '../util/elf_loader.dart'; /// ], /// ); /// ``` -class HarborMaskRom extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborMaskRom extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { final int? busDataWidth; /// Base address in the SoC memory map. @@ -275,4 +277,16 @@ class HarborMaskRom extends BridgeModule with HarborDeviceTreeNodeProvider { reg: BusAddressRange(baseAddress, size), properties: {'data-width': dataWidth, 'depth': initialData.length}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, size)], + properties: { + 'compatible': ['harbor,maskrom'], + 'data-width': dataWidth, + 'depth': initialData.length, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/pcie.dart b/packages/harbor/lib/src/peripherals/pcie.dart index 26d087b..787b77b 100644 --- a/packages/harbor/lib/src/peripherals/pcie.dart +++ b/packages/harbor/lib/src/peripherals/pcie.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/pretty_string.dart'; @@ -148,7 +149,7 @@ class HarborPcieConfig with HarborPrettyString { /// /// ECAM space is mapped at a separate memory region for config access. class HarborPcieController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// PCIe configuration. final HarborPcieConfig config; @@ -391,4 +392,23 @@ class HarborPcieController extends BridgeModule 'bus-range': [0, 255], }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': config.role == HarborPcieRole.rootComplex + ? ['harbor,pcie-host', 'pci-host-ecam-generic'] + : ['harbor,pcie-ep'], + 'device_type': 'pci', + '#address-cells': 3, + '#size-cells': 2, + 'max-link-speed': config.maxGen.gen, + 'num-lanes': config.maxLanes.count, + 'msi-parent': true, + 'bus-range': [0, 255], + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/plic.dart b/packages/harbor/lib/src/peripherals/plic.dart index b9f2ca9..111b224 100644 --- a/packages/harbor/lib/src/peripherals/plic.dart +++ b/packages/harbor/lib/src/peripherals/plic.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// RISC-V Platform-Level Interrupt Controller (PLIC), SiFive-compatible. @@ -15,7 +16,8 @@ import '../soc/device_tree.dart'; /// - Claim/Complete: 0x200004 + ctx*0x1000 (4 bytes per context) /// /// Address space: 64 MB (0x4000000). -class HarborPlic extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborPlic extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { final int? busDataWidth; final int sources; final int contexts; @@ -233,4 +235,17 @@ class HarborPlic extends BridgeModule with HarborDeviceTreeNodeProvider { interruptCells: 1, properties: {'riscv,ndev': sources}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x4000000)], + properties: { + 'compatible': ['sifive,plic-1.0.0'], + 'riscv,ndev': sources, + 'interrupt-controller': true, + '#interrupt-cells': 1, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/pmu.dart b/packages/harbor/lib/src/peripherals/pmu.dart index 254e05d..8d367bb 100644 --- a/packages/harbor/lib/src/peripherals/pmu.dart +++ b/packages/harbor/lib/src/peripherals/pmu.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/pretty_string.dart'; @@ -84,7 +85,7 @@ class HarborPmuConfig with HarborPrettyString { /// - +0x04: DOM_STATUS (current state, transition busy) /// - +0x08: DOM_ISO (isolation control) class HarborPowerManagementUnit extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// PMU configuration. final HarborPmuConfig config; @@ -273,4 +274,16 @@ class HarborPowerManagementUnit extends BridgeModule 'num-domains': config.domains.length, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,pmu'], + '#power-domain-cells': 1, + 'num-domains': config.domains.length, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/pwm_timer.dart b/packages/harbor/lib/src/peripherals/pwm_timer.dart index 913eff1..365f659 100644 --- a/packages/harbor/lib/src/peripherals/pwm_timer.dart +++ b/packages/harbor/lib/src/peripherals/pwm_timer.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// PWM/Timer peripheral. @@ -20,7 +21,8 @@ import '../soc/device_tree.dart'; /// Global registers: /// - 0x00: GLOBAL_CTRL (global enable) /// - 0x04: INT_STATUS (per-channel interrupt status, W1C) -class HarborPwmTimer extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborPwmTimer extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Number of timer/PWM channels. final int channels; @@ -263,4 +265,16 @@ class HarborPwmTimer extends BridgeModule with HarborDeviceTreeNodeProvider { reg: BusAddressRange(baseAddress, 0x1000), properties: {'#pwm-cells': 3, 'num-channels': channels}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,pwm-timer'], + '#pwm-cells': 3, + 'num-channels': channels, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/reset_controller.dart b/packages/harbor/lib/src/peripherals/reset_controller.dart index ed58a3b..9576805 100644 --- a/packages/harbor/lib/src/peripherals/reset_controller.dart +++ b/packages/harbor/lib/src/peripherals/reset_controller.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// Reset source that can trigger a system reset. @@ -38,7 +39,7 @@ enum HarborResetSource { /// - 0x14: WDOG_RST_EN (enable watchdog as reset source) /// - 0x18: SW_RST_KEY (write 0xDEAD to trigger software reset) class HarborResetController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address in the SoC memory map. final int baseAddress; @@ -233,4 +234,16 @@ class HarborResetController extends BridgeModule reg: BusAddressRange(baseAddress, 0x1000), properties: {'#reset-cells': 1, 'num-domains': domainCount}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,reset-controller'], + '#reset-cells': 1, + 'num-domains': domainCount, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/sdio.dart b/packages/harbor/lib/src/peripherals/sdio.dart index 3985533..6a04705 100644 --- a/packages/harbor/lib/src/peripherals/sdio.dart +++ b/packages/harbor/lib/src/peripherals/sdio.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/pretty_string.dart'; @@ -170,7 +171,7 @@ class HarborSdioConfig with HarborPrettyString { /// - 0x30: INT_STATUS (interrupt status, write-1-to-clear) /// - 0x34: INT_ENABLE (interrupt enable) class HarborSdioController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Controller configuration. final HarborSdioConfig config; @@ -395,4 +396,25 @@ class HarborSdioController extends BridgeModule if (config.supportsEmmc) 'non-removable': true, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': config.supportsEmmc + ? ['harbor,sdhci-emmc'] + : ['harbor,sdhci'], + 'bus-width': config.maxBusWidth.width, + 'max-frequency': config.maxFrequency, + if (config.supports1v8) 'sd-uhs-sdr12': true, + if (config.supports1v8) 'sd-uhs-sdr25': true, + if (config.maxSpeed.index >= HarborSdioSpeed.sdr50.index) + 'sd-uhs-sdr50': true, + if (config.maxSpeed.index >= HarborSdioSpeed.sdr104.index) + 'sd-uhs-sdr104': true, + if (config.supportsEmmc) 'non-removable': true, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/spi.dart b/packages/harbor/lib/src/peripherals/spi.dart index 27a103f..f2491b8 100644 --- a/packages/harbor/lib/src/peripherals/spi.dart +++ b/packages/harbor/lib/src/peripherals/spi.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// SPI master/slave controller. @@ -16,7 +17,7 @@ import '../soc/device_tree.dart'; /// /// Supports both master and slave mode. CPOL/CPHA configurable. class HarborSpiController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address in the SoC memory map. final int baseAddress; @@ -237,4 +238,17 @@ class HarborSpiController extends BridgeModule reg: BusAddressRange(baseAddress, 0x1000), properties: {'num-cs': csCount, '#address-cells': 1, '#size-cells': 0}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,spi', 'opencores,spi-oc'], + 'num-cs': csCount, + '#address-cells': 1, + '#size-cells': 0, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/spi_flash.dart b/packages/harbor/lib/src/peripherals/spi_flash.dart index 046c290..e12a26a 100644 --- a/packages/harbor/lib/src/peripherals/spi_flash.dart +++ b/packages/harbor/lib/src/peripherals/spi_flash.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/pretty_string.dart'; @@ -126,7 +127,7 @@ class HarborSpiFlashConfig with HarborPrettyString { /// Supports XIP (Execute In Place) - the CPU can fetch instructions /// directly from the SPI flash. class HarborSpiFlashController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// HarborFlash configuration. final HarborSpiFlashConfig config; @@ -344,4 +345,17 @@ class HarborSpiFlashController extends BridgeModule if (config.mode == HarborSpiFlashMode.dual) 'spi-tx-bus-width': 2, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, config.size)], + properties: { + 'compatible': ['jedec,spi-nor'], + 'spi-max-frequency': config.spiFrequency, + if (config.mode == HarborSpiFlashMode.quad) 'spi-tx-bus-width': 4, + if (config.mode == HarborSpiFlashMode.dual) 'spi-tx-bus-width': 2, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/sram.dart b/packages/harbor/lib/src/peripherals/sram.dart index be71a63..691fd37 100644 --- a/packages/harbor/lib/src/peripherals/sram.dart +++ b/packages/harbor/lib/src/peripherals/sram.dart @@ -5,6 +5,7 @@ import '../blackbox/ecp5/ecp5.dart'; import '../blackbox/ice40/ice40.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../soc/target.dart'; @@ -18,7 +19,8 @@ import '../soc/target.dart'; /// The ASIC and simulation builders still write whole words, so sub-word /// stores clobber their neighbors there until they grow the same masking /// (a known follow-up). -class HarborSram extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborSram extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { final int? busDataWidth; final int size; final int baseAddress; @@ -439,6 +441,17 @@ class HarborSram extends BridgeModule with HarborDeviceTreeNodeProvider { reg: BusAddressRange(baseAddress, size), properties: {'data-width': dataWidth}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, size)], + properties: { + 'compatible': ['harbor,sram', 'mmio-sram'], + 'data-width': dataWidth, + }, + ); } /// PDK SRAM macro instantiated as a blackbox leaf. diff --git a/packages/harbor/lib/src/peripherals/temperature_sensor.dart b/packages/harbor/lib/src/peripherals/temperature_sensor.dart index f97d36e..a23caa5 100644 --- a/packages/harbor/lib/src/peripherals/temperature_sensor.dart +++ b/packages/harbor/lib/src/peripherals/temperature_sensor.dart @@ -6,6 +6,7 @@ import '../blackbox/xilinx/xilinx.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; import '../pdk/pdk_provider.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../soc/target.dart'; @@ -49,7 +50,7 @@ enum HarborTemperatureSource { /// - 0x18: INT_STATUS (read/write-1-to-clear) /// - 0x1C: INT_ENABLE (read/write, interrupt enable mask) class HarborTemperatureSensor extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address in the SoC memory map. final int baseAddress; @@ -325,4 +326,16 @@ class HarborTemperatureSensor extends BridgeModule reg: BusAddressRange(baseAddress, 0x1000), properties: {'#thermal-sensor-cells': 0, 'harbor,source': source.name}, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,temp-sensor'], + '#thermal-sensor-cells': 0, + 'harbor,source': source.name, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/uart.dart b/packages/harbor/lib/src/peripherals/uart.dart index 8218349..2e4dcae 100644 --- a/packages/harbor/lib/src/peripherals/uart.dart +++ b/packages/harbor/lib/src/peripherals/uart.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// 16550-compatible UART peripheral. @@ -25,7 +26,8 @@ import '../soc/device_tree.dart'; /// pick their register through the byte-lane selects, and reads return the /// whole addressed word with every register in its lane, so masters that /// issue word-aligned loads extract the byte they want. -class HarborUart extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborUart extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { final int? busDataWidth; final int baseAddress; final int clockFrequency; @@ -415,4 +417,18 @@ class HarborUart extends BridgeModule with HarborDeviceTreeNodeProvider { if (clockFrequency > 0) 'clock-frequency': clockFrequency, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PNP0501', + cid: ['PNP0501'], + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['ns16550a'], + 'reg-shift': 0, + 'reg-io-width': 1, + if (clockFrequency > 0) 'clock-frequency': clockFrequency, + }, + ); } diff --git a/packages/harbor/lib/src/peripherals/usb.dart b/packages/harbor/lib/src/peripherals/usb.dart index 2d2bf54..f73c346 100644 --- a/packages/harbor/lib/src/peripherals/usb.dart +++ b/packages/harbor/lib/src/peripherals/usb.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; import '../util/pretty_string.dart'; @@ -143,7 +144,7 @@ class HarborUsbConfig with HarborPrettyString { /// - +0x14: EP_TXLEN (TX packet length) /// - +0x18: EP_RXLEN (RX packet length, read-only) class HarborUsbController extends BridgeModule - with HarborDeviceTreeNodeProvider { + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// USB configuration. final HarborUsbConfig config; @@ -310,6 +311,19 @@ class HarborUsbController extends BridgeModule 'num-endpoints': config.endpointCount, }, ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,usb'], + 'maximum-speed': _dtSpeedString(config.maxSpeed), + 'dr_mode': config.role == HarborUsbRole.otg ? 'otg' : config.role.name, + 'num-endpoints': config.endpointCount, + }, + ); } /// Maps HarborUsbSpeed to the Linux DT `maximum-speed` string. diff --git a/packages/harbor/lib/src/peripherals/watchdog.dart b/packages/harbor/lib/src/peripherals/watchdog.dart index 86f7f48..1e60bd1 100644 --- a/packages/harbor/lib/src/peripherals/watchdog.dart +++ b/packages/harbor/lib/src/peripherals/watchdog.dart @@ -3,6 +3,7 @@ import 'package:rohd_bridge/rohd_bridge.dart'; import '../bus/bus.dart'; import '../bus/bus_slave_port.dart'; +import '../soc/acpi.dart'; import '../soc/device_tree.dart'; /// HarborWatchdog timer peripheral. @@ -20,7 +21,8 @@ import '../soc/device_tree.dart'; /// - 0x14: COUNT (current counter value, read-only) /// /// Magic kick value prevents accidental kicks from stray writes. -class HarborWatchdog extends BridgeModule with HarborDeviceTreeNodeProvider { +class HarborWatchdog extends BridgeModule + with HarborDeviceTreeNodeProvider, HarborAcpiDeviceProvider { /// Base address in the SoC memory map. final int baseAddress; @@ -197,4 +199,14 @@ class HarborWatchdog extends BridgeModule with HarborDeviceTreeNodeProvider { compatible: ['harbor,watchdog'], reg: BusAddressRange(baseAddress, 0x1000), ); + + @override + HarborAcpiDevice get acpiDevice => HarborAcpiDevice( + hid: 'PRP0001', + uid: 0, + memory: [BusAddressRange(baseAddress, 0x1000)], + properties: { + 'compatible': ['harbor,watchdog'], + }, + ); } diff --git a/packages/harbor/lib/src/soc/acpi.dart b/packages/harbor/lib/src/soc/acpi.dart new file mode 100644 index 0000000..1a21b1d --- /dev/null +++ b/packages/harbor/lib/src/soc/acpi.dart @@ -0,0 +1,262 @@ +import '../bus/bus.dart'; +import 'cpu.dart'; + +class HarborAcpiDevice { + /// ACPI Hardware ID + final String hid; + + /// Optional compatible IDs + final List cid; + + /// Unique device ID + final int uid; + + /// MMIO regions + final List memory; + + /// Interrupts + final List interrupts; + + /// Device properties emitted as an ACPI `_DSD` device-properties package. + /// + /// This is the standard mechanism for attaching arbitrary key/value data to + /// a device. Pairing a `compatible` property here with [hid] `"PRP0001"` + /// lets an OS reuse its device tree driver for a device that has no native + /// ACPI hardware ID. + /// + /// Values may be [String], [int], [bool], [List] or [List]. + final Map properties; + + /// Additional raw ACPI names emitted as `Name (KEY, value)` entries. + final Map names; + + const HarborAcpiDevice({ + required this.hid, + this.cid = const [], + this.uid = 0, + this.memory = const [], + this.interrupts = const [], + this.properties = const {}, + this.names = const {}, + }); +} + +mixin HarborAcpiDeviceProvider { + HarborAcpiDevice get acpiDevice; +} + +class HarborAcpiGenerator { + /// OEM ID (6 chars max) + final String oemId; + + /// OEM Table ID (8 chars max) + final String oemTableId; + + /// CPU entries. + final List cpus; + + /// Peripheral nodes implementing [HarborAcpiDeviceProvider]. + final List peripherals; + + const HarborAcpiGenerator({ + required this.oemId, + required this.oemTableId, + this.cpus = const [], + this.peripherals = const [], + }); + + /// ACPI device nodes from the peripherals. + List get devices => + peripherals.map((p) => p.acpiDevice).toList(); + + /// Generates the DSDT ASL source as a string. + /// + /// The output is intended to be fed to an ASL compiler such as `iasl`. + String generate() { + final buf = StringBuffer(); + + buf.writeln( + 'DefinitionBlock ("", "DSDT", 2, "$oemId", "$oemTableId", 0x00000001)', + ); + buf.writeln('{'); + buf.writeln(' Scope (\\_SB)'); + buf.writeln(' {'); + + for (var i = 0; i < cpus.length; i++) { + if (i > 0) buf.writeln(); + _writeCpu(buf, cpus[i]); + } + + if (cpus.isNotEmpty && peripherals.isNotEmpty) buf.writeln(); + + final devs = devices; + for (var i = 0; i < devs.length; i++) { + if (i > 0) buf.writeln(); + _writeDevice(buf, devs[i], i); + } + + buf.writeln(' }'); + buf.writeln('}'); + return buf.toString(); + } + + void _writeCpu(StringBuffer buf, HarborCpu cpu) { + final name = _nameSeg('C', cpu.hartId); + buf.writeln(' Device ($name)'); + buf.writeln(' {'); + buf.writeln(' Name (_HID, "ACPI0007")'); + buf.writeln(' Name (_UID, ${_hex(cpu.hartId)})'); + buf.writeln(' Name (_STA, 0x0F)'); + + final props = >[ + MapEntry('riscv,isa', cpu.isa), + if (cpu.mmu != null) MapEntry('mmu-type', cpu.mmu!), + if (cpu.clockFrequency != null) + MapEntry('clock-frequency', cpu.clockFrequency!), + ]; + _writeDsd(buf, props, indent: ' '); + + buf.writeln(' }'); + } + + void _writeDevice(StringBuffer buf, HarborAcpiDevice dev, int index) { + final name = _nameSeg('D', index); + buf.writeln(' Device ($name)'); + buf.writeln(' {'); + buf.writeln(' Name (_HID, "${dev.hid}")'); + + if (dev.cid.length == 1) { + buf.writeln(' Name (_CID, "${dev.cid.first}")'); + } else if (dev.cid.length > 1) { + final list = dev.cid.map((c) => '"$c"').join(', '); + buf.writeln(' Name (_CID, Package () { $list })'); + } + + buf.writeln(' Name (_UID, ${_hex(dev.uid)})'); + buf.writeln(' Name (_STA, 0x0F)'); + + if (dev.memory.isNotEmpty || dev.interrupts.isNotEmpty) { + buf.writeln(' Name (_CRS, ResourceTemplate ()'); + buf.writeln(' {'); + for (final region in dev.memory) { + _writeMemory(buf, region); + } + if (dev.interrupts.isNotEmpty) { + final irqs = dev.interrupts.map(_hex).join(', '); + buf.writeln( + ' Interrupt (ResourceConsumer, Level, ActiveHigh, ' + 'Exclusive)', + ); + buf.writeln(' {'); + buf.writeln(' $irqs'); + buf.writeln(' }'); + } + buf.writeln(' })'); + } + + _writeDsd(buf, dev.properties.entries.toList(), indent: ' '); + + for (final entry in dev.names.entries) { + buf.writeln( + ' Name (${_nameSegFromKey(entry.key)}, ' + '${_formatValue(entry.value)})', + ); + } + + buf.writeln(' }'); + } + + void _writeMemory(StringBuffer buf, BusAddressRange region) { + // Use the compact 32-bit descriptor when the whole range fits, otherwise + // fall back to the 64-bit QWord descriptor. + if (region.end <= 0x100000000) { + buf.writeln( + ' Memory32Fixed (ReadWrite, ' + '${_hex32(region.start)}, ${_hex32(region.size)})', + ); + return; + } + + buf.writeln( + ' QWordMemory (ResourceConsumer, PosDecode, MinFixed, ' + 'MaxFixed, NonCacheable, ReadWrite,', + ); + buf.writeln(' 0x0000000000000000, // Granularity'); + buf.writeln( + ' ${_hex64(region.start)}, // Range Minimum', + ); + buf.writeln( + ' ${_hex64(region.end - 1)}, // Range Maximum', + ); + buf.writeln( + ' 0x0000000000000000, // Translation Offset', + ); + buf.writeln(' ${_hex64(region.size)}, // Length'); + buf.writeln(' )'); + } + + void _writeDsd( + StringBuffer buf, + List> props, { + required String indent, + }) { + if (props.isEmpty) return; + // Standard ACPI device-properties UUID for _DSD. + buf.writeln('${indent}Name (_DSD, Package ()'); + buf.writeln('$indent{'); + buf.writeln('$indent ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),'); + buf.writeln('$indent Package ()'); + buf.writeln('$indent {'); + for (final p in props) { + buf.writeln( + '$indent Package () { "${p.key}", ${_formatValue(p.value)} },', + ); + } + buf.writeln('$indent }'); + buf.writeln('$indent})'); + } + + /// Builds a 4-character ACPI NameSeg from a [prefix] and numeric [index]. + String _nameSeg(String prefix, int index) { + final hex = index.toRadixString(16).toUpperCase(); + final room = 4 - prefix.length; + final tail = hex.length >= room + ? hex.substring(hex.length - room) + : hex.padLeft(room, '0'); + return '$prefix$tail'; + } + + /// Sanitizes an arbitrary [key] into a valid 4-character ACPI NameSeg. + String _nameSegFromKey(String key) { + var s = key.toUpperCase().replaceAll(RegExp(r'[^A-Z0-9_]'), '_'); + if (s.isEmpty) s = '_'; + if (RegExp(r'[0-9]').hasMatch(s[0])) s = '_$s'; + if (s.length > 4) s = s.substring(0, 4); + return s.padRight(4, '_'); + } + + String _hex(int v) => '0x${v.toRadixString(16).toUpperCase()}'; + + String _hex32(int v) => + '0x${v.toRadixString(16).toUpperCase().padLeft(8, '0')}'; + + String _hex64(int v) => + '0x${v.toRadixString(16).toUpperCase().padLeft(16, '0')}'; + + String _formatValue(Object value) { + if (value is String) return '"$value"'; + if (value is bool) return value ? 'One' : 'Zero'; + if (value is int) return _hex(value); + if (value is List) { + return 'Package () { ${value.map(_hex).join(', ')} }'; + } + if (value is List) { + return 'Package () { ${value.map((s) => '"$s"').join(', ')} }'; + } + if (value is List) { + return 'Package () { ' + '${value.map((e) => _formatValue(e as Object)).join(', ')} }'; + } + return '"$value"'; + } +} diff --git a/packages/harbor/lib/src/soc/cpu.dart b/packages/harbor/lib/src/soc/cpu.dart new file mode 100644 index 0000000..a441103 --- /dev/null +++ b/packages/harbor/lib/src/soc/cpu.dart @@ -0,0 +1,47 @@ +import '../util/pretty_string.dart'; + +/// A CPU hart description shared across all SoC generators. +/// +/// This is the single source of truth consumed by the device tree, ACPI and +/// topology graph generators. Generators read these fields and emit them in +/// their own format - there is no conversion between generator-specific CPU +/// types. +class HarborCpu with HarborPrettyString { + /// Hart ID. + final int hartId; + + /// ISA string, e.g. `"rv64imac"`. + final String isa; + + /// MMU type, e.g. `"riscv,sv39"` (optional). + final String? mmu; + + /// Clock frequency in Hz (optional). + final int? clockFrequency; + + const HarborCpu({ + required this.hartId, + required this.isa, + this.mmu, + this.clockFrequency, + }); + + @override + String toString() => 'HarborCpu(hart$hartId, $isa)'; + + @override + String toPrettyString([ + HarborPrettyStringOptions options = const HarborPrettyStringOptions(), + ]) { + final p = options.prefix; + final c = options.childPrefix; + final buf = StringBuffer('${p}HarborCpu(\n'); + buf.writeln('${c}hartId: $hartId,'); + buf.writeln('${c}isa: $isa,'); + if (mmu != null) buf.writeln('${c}mmu: $mmu,'); + if (clockFrequency != null) + buf.writeln('${c}clockFrequency: $clockFrequency,'); + buf.write('$p)'); + return buf.toString(); + } +} diff --git a/packages/harbor/lib/src/soc/device_tree.dart b/packages/harbor/lib/src/soc/device_tree.dart index b012d3c..6a4802f 100644 --- a/packages/harbor/lib/src/soc/device_tree.dart +++ b/packages/harbor/lib/src/soc/device_tree.dart @@ -1,5 +1,6 @@ import '../bus/bus.dart'; import '../util/pretty_string.dart'; +import 'cpu.dart'; /// A device tree node - an immutable value object describing a device's /// presence in the device tree. @@ -112,55 +113,14 @@ mixin HarborDeviceTreeNodeProvider { HarborDeviceTreeNode get dtNode; } -/// Configuration for CPU entries in the device tree. -class HarborDeviceTreeCpu with HarborPrettyString { - /// Hart ID. - final int hartId; - - /// ISA string, e.g. `"rv64imac"`. - final String isa; - - /// Clock frequency in Hz (optional). - final int? clockFrequency; - - /// MMU type, e.g. `"riscv,sv39"` (optional). - final String? mmu; - - const HarborDeviceTreeCpu({ - required this.hartId, - required this.isa, - this.clockFrequency, - this.mmu, - }); - - @override - String toString() => 'HarborDeviceTreeCpu(hart$hartId, $isa)'; - - @override - String toPrettyString([ - HarborPrettyStringOptions options = const HarborPrettyStringOptions(), - ]) { - final p = options.prefix; - final c = options.childPrefix; - final buf = StringBuffer('${p}HarborDeviceTreeCpu(\n'); - buf.writeln('${c}hartId: $hartId,'); - buf.writeln('${c}isa: $isa,'); - if (mmu != null) buf.writeln('${c}mmu: $mmu,'); - if (clockFrequency != null) - buf.writeln('${c}clockFrequency: $clockFrequency,'); - buf.write('$p)'); - return buf.toString(); - } -} - /// Generates a Linux/U-Boot compatible `.dts` file from a list of -/// [HarborDeviceTreeNodeProvider] peripherals and [HarborDeviceTreeCpu] entries. +/// [HarborDeviceTreeNodeProvider] peripherals and [HarborCpu] entries. /// /// ```dart /// final dts = HarborDeviceTreeGenerator( /// model: 'Midstall Creek V1', /// compatible: 'midstall,creek-v1', -/// cpus: [HarborDeviceTreeCpu(hartId: 0, isa: 'rv64imac')], +/// cpus: [HarborCpu(hartId: 0, isa: 'rv64imac')], /// peripherals: [clint, plic, uart], /// ).generate(); /// ``` @@ -178,7 +138,7 @@ class HarborDeviceTreeGenerator { final int sizeCells; /// CPU entries. - final List cpus; + final List cpus; /// Peripheral nodes implementing [HarborDeviceTreeNodeProvider]. final List peripherals; diff --git a/packages/harbor/lib/src/soc/graph.dart b/packages/harbor/lib/src/soc/graph.dart index f573404..773cf7d 100644 --- a/packages/harbor/lib/src/soc/graph.dart +++ b/packages/harbor/lib/src/soc/graph.dart @@ -1,3 +1,4 @@ +import 'cpu.dart'; import 'device_tree.dart'; /// Generates Mermaid and Graphviz DOT diagrams of a SoC's bus fabric @@ -6,7 +7,7 @@ import 'device_tree.dart'; /// ```dart /// final graph = HarborSoCGraphGenerator( /// name: 'Creek V1', -/// cpus: [HarborDeviceTreeCpu(hartId: 0, isa: 'rv64imac')], +/// cpus: [HarborCpu(hartId: 0, isa: 'rv64imac')], /// peripherals: [clint, plic, uart, sram], /// ); /// @@ -18,7 +19,7 @@ class HarborSoCGraphGenerator { final String name; /// CPU entries. - final List cpus; + final List cpus; /// Peripheral nodes. final List peripherals; diff --git a/packages/harbor/lib/src/soc/harbor_soc.dart b/packages/harbor/lib/src/soc/harbor_soc.dart index 7637518..74c293b 100644 --- a/packages/harbor/lib/src/soc/harbor_soc.dart +++ b/packages/harbor/lib/src/soc/harbor_soc.dart @@ -8,6 +8,8 @@ import '../bus/wishbone/wishbone_decoder.dart'; import '../bus/wishbone/wishbone_interface.dart'; import '../clock/clock_domain.dart'; import '../pdk/klayout.dart'; +import 'acpi.dart'; +import 'cpu.dart'; import 'device_tree.dart'; import 'graph.dart'; import 'target.dart'; @@ -55,7 +57,7 @@ class HarborSoC extends BridgeModule { final Object busConfig; /// CPU information for the device tree. - final List cpus; + final List cpus; /// Build target (FPGA or ASIC). Controls what scripts are generated. final HarborDeviceTarget? target; @@ -66,6 +68,9 @@ class HarborSoC extends BridgeModule { late final HarborClockGenerator _clockGen; final Map _clockDomains = {}; + final String acpiOemId; + final String acpiOemTableId; + /// Creates a new SoC. /// /// Accepts an optional list of [clocks] to generate PLL-derived @@ -74,6 +79,8 @@ class HarborSoC extends BridgeModule { required String name, required this.compatible, required this.busConfig, + this.acpiOemId = 'MIDSTL', + this.acpiOemTableId = 'HARBOR', this.cpus = const [], this.target, List clocks = const [], @@ -298,6 +305,19 @@ class HarborSoC extends BridgeModule { } } + /// Generates a ACPICA compatible `.asl` file. + String generateAcpi() { + return HarborAcpiGenerator( + oemId: acpiOemId, + oemTableId: acpiOemTableId, + cpus: cpus, + peripherals: _peripherals + .map((e) => e.module) + .whereType() + .toList(), + ).generate(); + } + /// Generates a Linux/U-Boot compatible `.dts` file. String generateDts() { return HarborDeviceTreeGenerator( @@ -358,6 +378,9 @@ class HarborSoC extends BridgeModule { File('$path/blackboxes.v').writeAsStringSync(blackboxStubs); } + // ACPI + File('$path/$name.asl').writeAsStringSync(generateAcpi()); + // Device tree File('$path/$name.dts').writeAsStringSync(generateDts()); diff --git a/packages/harbor/test/soc/acpi_test.dart b/packages/harbor/test/soc/acpi_test.dart new file mode 100644 index 0000000..393b1df --- /dev/null +++ b/packages/harbor/test/soc/acpi_test.dart @@ -0,0 +1,175 @@ +import 'package:harbor/harbor.dart'; +import 'package:test/test.dart'; + +class _MockAcpiDevice with HarborAcpiDeviceProvider { + @override + final HarborAcpiDevice acpiDevice; + _MockAcpiDevice(this.acpiDevice); +} + +void main() { + group('HarborAcpiGenerator', () { + test('generates a DSDT with CPUs and peripherals', () { + final uart = _MockAcpiDevice( + const HarborAcpiDevice( + hid: 'HISI0031', + cid: ['PNP0501'], + uid: 0, + memory: [BusAddressRange(0x10000000, 0x1000)], + interrupts: [10], + names: {'clock-frequency': 48000000}, + ), + ); + + final asl = HarborAcpiGenerator( + oemId: 'MDSTLL', + oemTableId: 'CREEKV1', + cpus: [HarborCpu(hartId: 0, isa: 'rv64imac', mmu: 'riscv,sv39')], + peripherals: [uart], + ).generate(); + + expect(asl, contains('DefinitionBlock')); + expect(asl, contains('"DSDT"')); + expect(asl, contains('"MDSTLL"')); + expect(asl, contains('"CREEKV1"')); + expect(asl, contains('Scope (\\_SB)')); + + // CPU as ACPI0007 processor device. + expect(asl, contains('Device (C000)')); + expect(asl, contains('Name (_HID, "ACPI0007")')); + expect(asl, contains('"riscv,isa", "rv64imac"')); + expect(asl, contains('"mmu-type", "riscv,sv39"')); + expect(asl, contains('ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")')); + + // Peripheral device. + expect(asl, contains('Device (D000)')); + expect(asl, contains('Name (_HID, "HISI0031")')); + expect(asl, contains('Name (_CID, "PNP0501")')); + expect( + asl, + contains('Memory32Fixed (ReadWrite, 0x10000000, 0x00001000)'), + ); + expect(asl, contains('Interrupt (ResourceConsumer, Level, ActiveHigh')); + expect(asl, contains('0xA')); + expect(asl, contains('Name (CLOC, 0x2DC6C00)')); + }); + + test('uses QWordMemory for 64-bit ranges', () { + final dev = _MockAcpiDevice( + const HarborAcpiDevice( + hid: 'MEMS0001', + memory: [BusAddressRange(0x100000000, 0x40000000)], + ), + ); + + final asl = HarborAcpiGenerator( + oemId: 'MDSTLL', + oemTableId: 'CREEKV1', + peripherals: [dev], + ).generate(); + + expect(asl, contains('QWordMemory')); + expect(asl, contains('0x0000000100000000, // Range Minimum')); + expect(asl, contains('0x000000013FFFFFFF, // Range Maximum')); + expect(asl, contains('0x0000000040000000, // Length')); + expect(asl, isNot(contains('Memory32Fixed'))); + }); + + test('emits multiple compatible IDs as a Package', () { + final dev = _MockAcpiDevice( + const HarborAcpiDevice(hid: 'ABCD0001', cid: ['PNP0501', 'PNP0500']), + ); + + final asl = HarborAcpiGenerator( + oemId: 'MDSTLL', + oemTableId: 'CREEKV1', + peripherals: [dev], + ).generate(); + + expect(asl, contains('Name (_CID, Package () { "PNP0501", "PNP0500" })')); + }); + + test('generates a minimal table with no CPUs or peripherals', () { + final asl = HarborAcpiGenerator( + oemId: 'MDSTLL', + oemTableId: 'CREEKV1', + ).generate(); + + expect(asl, contains('DefinitionBlock')); + expect(asl, contains('Scope (\\_SB)')); + expect(asl, isNot(contains('Device ('))); + }); + + test('handles multi-hart setups', () { + final asl = HarborAcpiGenerator( + oemId: 'MDSTLL', + oemTableId: 'CREEKV1', + cpus: [ + HarborCpu(hartId: 0, isa: 'rv64imac'), + HarborCpu(hartId: 1, isa: 'rv64imac'), + ], + ).generate(); + + expect(asl, contains('Device (C000)')); + expect(asl, contains('Device (C001)')); + }); + + test('emits device properties as a _DSD package', () { + final dev = _MockAcpiDevice( + const HarborAcpiDevice( + hid: 'PRP0001', + memory: [BusAddressRange(0x10000000, 0x1000)], + properties: { + 'compatible': ['harbor,gpio', 'sifive,gpio0'], + 'ngpios': 32, + 'gpio-controller': true, + }, + ), + ); + + final asl = HarborAcpiGenerator( + oemId: 'MDSTLL', + oemTableId: 'CREEKV1', + peripherals: [dev], + ).generate(); + + expect(asl, contains('Name (_HID, "PRP0001")')); + expect(asl, contains('ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")')); + expect( + asl, + contains( + 'Package () { "compatible", Package () { "harbor,gpio", ' + '"sifive,gpio0" } }', + ), + ); + expect(asl, contains('Package () { "ngpios", 0x20 }')); + expect(asl, contains('Package () { "gpio-controller", One }')); + }); + }); + + group('HarborAcpiDeviceProvider peripherals', () { + test('UART exposes a native ACPI HID', () { + final uart = HarborUart( + baseAddress: 0x10000000, + clockFrequency: 48000000, + ); + final dev = uart.acpiDevice; + expect(dev.hid, equals('PNP0501')); + expect(dev.cid, contains('PNP0501')); + expect(dev.memory.single.start, equals(0x10000000)); + }); + + test('SRAM flows through the generator', () { + final sram = HarborSram(baseAddress: 0x80000000, size: 0x10000); + final asl = HarborAcpiGenerator( + oemId: 'MDSTLL', + oemTableId: 'CREEKV1', + peripherals: [sram], + ).generate(); + + expect(asl, contains('Name (_HID, "PRP0001")')); + expect(asl, contains('"compatible"')); + expect(asl, contains('"harbor,sram"')); + }); + }); +} diff --git a/packages/harbor/test/soc/device_tree_test.dart b/packages/harbor/test/soc/device_tree_test.dart index f3e3163..907afdb 100644 --- a/packages/harbor/test/soc/device_tree_test.dart +++ b/packages/harbor/test/soc/device_tree_test.dart @@ -14,9 +14,7 @@ void main() { final dts = HarborDeviceTreeGenerator( model: 'Test SoC', compatible: 'test,soc-v1', - cpus: [ - HarborDeviceTreeCpu(hartId: 0, isa: 'rv64imac', mmu: 'riscv,sv39'), - ], + cpus: [HarborCpu(hartId: 0, isa: 'rv64imac', mmu: 'riscv,sv39')], peripherals: [clint, plic, uart], ).generate(); @@ -61,8 +59,8 @@ void main() { model: 'Multi', compatible: 'test,multi', cpus: [ - HarborDeviceTreeCpu(hartId: 0, isa: 'rv32imac'), - HarborDeviceTreeCpu(hartId: 1, isa: 'rv32imac'), + HarborCpu(hartId: 0, isa: 'rv32imac'), + HarborCpu(hartId: 1, isa: 'rv32imac'), ], ).generate(); diff --git a/packages/harbor/test/soc/graph_test.dart b/packages/harbor/test/soc/graph_test.dart index 6ea1354..f1cac9f 100644 --- a/packages/harbor/test/soc/graph_test.dart +++ b/packages/harbor/test/soc/graph_test.dart @@ -2,15 +2,15 @@ import 'package:harbor/harbor.dart'; import 'package:test/test.dart'; void main() { - late List cpus; + late List cpus; late HarborClint clint; late HarborPlic plic; late HarborUart uart; setUp(() { cpus = [ - HarborDeviceTreeCpu(hartId: 0, isa: 'rv64imac'), - HarborDeviceTreeCpu(hartId: 1, isa: 'rv64imac'), + HarborCpu(hartId: 0, isa: 'rv64imac'), + HarborCpu(hartId: 1, isa: 'rv64imac'), ]; clint = HarborClint(baseAddress: 0x02000000, hartCount: 2); plic = HarborPlic(baseAddress: 0x0C000000, sources: 32, contexts: 2); diff --git a/packages/harbor/test/soc/harbor_soc_test.dart b/packages/harbor/test/soc/harbor_soc_test.dart index 7483e42..701fe2c 100644 --- a/packages/harbor/test/soc/harbor_soc_test.dart +++ b/packages/harbor/test/soc/harbor_soc_test.dart @@ -39,7 +39,7 @@ void main() { name: 'TestSoC', compatible: 'test,soc-v1', busConfig: const WishboneConfig(addressWidth: 32, dataWidth: 32), - cpus: [HarborDeviceTreeCpu(hartId: 0, isa: 'rv64imac')], + cpus: [HarborCpu(hartId: 0, isa: 'rv64imac')], ); soc.addPeripheral(HarborClint(baseAddress: 0x02000000)); diff --git a/packages/harbor/test/util/pretty_string_test.dart b/packages/harbor/test/util/pretty_string_test.dart index a283c85..4fc88ca 100644 --- a/packages/harbor/test/util/pretty_string_test.dart +++ b/packages/harbor/test/util/pretty_string_test.dart @@ -48,8 +48,8 @@ void main() { expect(pretty, contains(' compatible:')); }); - test('HarborDeviceTreeCpu toPrettyString', () { - const cpu = HarborDeviceTreeCpu( + test('HarborCpu toPrettyString', () { + const cpu = HarborCpu( hartId: 0, isa: 'rv64imac', mmu: 'riscv,sv39',