Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
959f432
(wip) Timer and i2c acacia adaptation
omeh-a Jun 25, 2026
a55c47c
Updated ina219 and bus scan i2c examples to use acacia
omeh-a Jul 2, 2026
013449b
Lint Python with Acacia additions
omeh-a Jul 3, 2026
6d06dfb
Update signatures to put SDF first for Acacia
omeh-a Jul 12, 2026
de0f706
Extract per-board / x86 metaprogram hacks to class.py
omeh-a Jul 13, 2026
55b8d7b
Add I2CAddress type and I2C address decoding for I2C class
omeh-a Jul 14, 2026
0659674
Add IMX i2c driver Co-authored-by: mt-fns <michaeltanto0909@gmail.com>
omeh-a Jul 3, 2026
55d99cb
Updated ina219 and bus scan i2c examples to use acacia
omeh-a Jul 2, 2026
70f7742
Added CI test for imx I2C on the Maaxboard, add Acacia support
omeh-a Jul 2, 2026
b936dc6
Lint Python with Acacia additions
omeh-a Jul 3, 2026
305fa5d
Fix licencing
omeh-a Jul 3, 2026
677fcfe
Replace bit shift bits with BIT macro
omeh-a Jul 3, 2026
6a2be35
add imx i2c driver
mt-fns Feb 13, 2026
79684a3
Rework imx i2c to properly implement state machine
omeh-a Mar 4, 2026
ba73364
Working I2C driver for maaxboard. Only works on bus 1 however, unclea…
omeh-a Mar 6, 2026
d43a147
Clean up build files and fix board.py
omeh-a Mar 10, 2026
dcc0b5a
Added no-coroutine build mode for libi2c
omeh-a Mar 10, 2026
2d89eda
Added PMIC driver class and stub driver for Maaxboard. Currently supp…
omeh-a Mar 10, 2026
a3bf6e2
PMIC class (wip)
omeh-a Jul 14, 2026
0fdda3b
Add acacia support for pmic, add config to pmic
omeh-a Jul 14, 2026
f8d4f82
Add dev docs for PMIC
omeh-a Jul 14, 2026
d7bfbd2
design doc: add Power/Thermal/Clock section
omeh-a Jul 14, 2026
a04f760
Draft pmic design doc section based on NCSC reporting
omeh-a Jul 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions acacia_sddf/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright 2026, UNSW
# SPDX-License-Identifier: BSD-2-Clause

from .i2c import sDDFI2C
from .timer import sDDFTimer
from .serial import sDDFSerial
from .sddf import sDDFDriverClass, sDDFDriverConfig, sDDFDriverManifest
from .board import BOARDS, Board
from .pmic import sDDFPMIC
192 changes: 192 additions & 0 deletions acacia_sddf/board.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# Copyright 2025, UNSW
# SPDX-License-Identifier: BSD-2-Clause
from dataclasses import dataclass
from typing import List, Optional, Tuple
from acacia import System, ProtectionDomain, aarch64, riscv64, x86_64, Arch
from importlib.metadata import version


@dataclass(frozen=True)
class DriverDouble:
compatible: str
node_path: str


@dataclass
class Board:
name: str
arch: Arch
paddr_top: int
# Driver mappings -> (compatible, preferred_node) tuples
serial: Optional[DriverDouble] = DriverDouble(None, None)
ethernet: Optional[DriverDouble] = DriverDouble(None, None)
timer: Optional[DriverDouble] = DriverDouble(None, None)
i2c: Optional[DriverDouble] = DriverDouble(None, None)
blk: Optional[DriverDouble] = DriverDouble(None, None)
pmic: Optional[DriverDouble] = DriverDouble(None, None)
partition: int = 0
baud_rate: Optional[int] = None


# Keep this list in alphabetical order by board name
# TODO: convert to Dictionary
BOARDS: List[Board] = [
Board(
name="cheshire",
arch=riscv64,
paddr_top=0x90000000,
serial=DriverDouble("ns16550a", "soc/serial@3002000"),
i2c=DriverDouble("eth,i2c", "soc/i2c@3003000"),
),
Board(
name="hifive_p550",
arch=riscv64,
paddr_top=0xA0000000,
serial=DriverDouble("snps,dw-apb-uart", "soc/serial@0x50900000"),
),
Board(
name="imx8mm_evk",
arch=aarch64,
paddr_top=0x70000000,
serial=DriverDouble(
"fsl,imx8mm-uart", "soc@0/bus@30800000/spba-bus@30800000/serial@30890000"
),
timer=DriverDouble("fsl,imx8mm-gpt", "soc@0/bus@30000000/timer@302d0000"),
ethernet=DriverDouble("", "soc@0/bus@30800000/ethernet@30be0000"),
),
Board(
name="imx8mp_evk",
arch=aarch64,
paddr_top=0x70000000,
serial=DriverDouble(
"fsl,imx8mp-uart", "soc@0/bus@30800000/spba-bus@30800000/serial@30890000"
),
timer=DriverDouble("fsl,imx8mp-gpt", "soc@0/bus@30000000/timer@302d0000"),
ethernet=DriverDouble("", "soc@0/bus@30800000/ethernet@30bf0000"),
),
Board(
name="imx8mp_iotgate",
arch=aarch64,
paddr_top=0x70000000,
serial=DriverDouble("fsl,imx8mp-uart", "soc@0/bus@30800000/serial@30890000"),
timer=DriverDouble("fsl,imx8mp-gpt", "soc@0/bus@30000000/timer@302d0000"),
ethernet=DriverDouble("", "soc@0/bus@30800000/ethernet@30bf0000"),
),
Board(
name="imx8mq_evk",
arch=aarch64,
paddr_top=0x70000000,
serial=DriverDouble("fsl,imx8mq-uart", "soc@0/bus@30800000/serial@30860000"),
timer=DriverDouble("fsl,imx8mq-gpt", "soc@0/bus@30000000/timer@302d0000"),
ethernet=DriverDouble("", "soc@0/bus@30800000/ethernet@30be0000"),
),
Board(
name="kria_k26",
arch=aarch64,
paddr_top=0x70000000,
timer=DriverDouble("cdns,ttc", "axi/timer@ff140000"),
serial=DriverDouble("xlnx,zynqmp-uart", "axi/serial@ff010000"),
),
Board(
name="maaxboard",
arch=aarch64,
paddr_top=0x70000000,
serial=DriverDouble("fsl,imx8mq-uart", "soc@0/bus@30800000/serial@30860000"),
timer=DriverDouble("fsl,imx8mq-gpt", "soc@0/bus@30000000/timer@302d0000"),
ethernet=DriverDouble("", "soc@0/bus@30800000/ethernet@30be0000"),
blk=DriverDouble("", "soc@0/bus@30800000/mmc@30b40000"),
i2c=DriverDouble("fsl,imx8mq-i2c", "soc@0/bus@30800000/i2c@30a20000"),
pmic=DriverDouble("rohm,bd71837", "soc@0/bus@30800000/i2c@30a20000/pmic@4b"),
partition=2,
),
Board(
name="odroidc2",
arch=aarch64,
paddr_top=0x60000000,
serial=DriverDouble("amlogic,meson-gx-uart", "soc/bus@c8100000/serial@4c0"),
timer=DriverDouble("amlogic,meson-gxbb-wdt", "soc/bus@c1100000/watchdog@98d0"),
ethernet=DriverDouble("", "soc/ethernet@c9410000"),
baud_rate=115200,
),
Board(
name="odroidc4",
arch=aarch64,
paddr_top=0x60000000,
i2c=DriverDouble("amlogic,meson-axg-i2c", "soc/bus@ffd00000/i2c@1d000"),
serial=DriverDouble("amlogic,meson-gx-uart", "soc/bus@ff800000/serial@3000"),
timer=DriverDouble("amlogic,meson-gxbb-wdt", "soc/bus@ffd00000/watchdog@f0d0"),
ethernet=DriverDouble("amlogic,meson-gx-uart", "soc/ethernet@ff3f0000"),
baud_rate=115200,
),
Board(
name="qemu_virt_aarch64",
arch=aarch64,
paddr_top=0x6_0000_000,
serial=DriverDouble("arm,pl011", "pl011@9000000"),
timer=DriverDouble("arm,armv8-timer", "timer"),
blk=DriverDouble("", "virtio_mmio@a000200"),
ethernet=DriverDouble("", "virtio_mmio@a000000"),
i2c=None,
),
Board(
name="qemu_virt_riscv64",
arch=riscv64,
paddr_top=0xA_0000_000,
serial=DriverDouble("ns16550a", "soc/serial@10000000"),
timer=DriverDouble("google,goldfish-rtc", "soc/rtc@101000"),
ethernet=DriverDouble("", "soc/virtio_mmio@10001000"),
blk=DriverDouble("", "soc/virtio_mmio@10002000"),
partition=0,
i2c=None,
),
Board(
name="rock3b",
arch=aarch64,
paddr_top=0xEC000000,
serial=DriverDouble("snps,dw-apb-uart", "serial@fe660000"),
timer=DriverDouble("rockchip,rk3568-timer", "rktimer@fe5f0000"),
ethernet=DriverDouble("", "ethernet@fe2a0000"),
baud_rate=1500000,
),
Board(
name="rpi4b_1gb",
arch=aarch64,
paddr_top=0x2_000_000,
serial=DriverDouble("brcm,bcm2835-aux-uart", "soc/serial@7e215040"),
timer=DriverDouble("brcm,bcm2835-system-timer", "soc/timer@7e003000"),
ethernet=DriverDouble("", "scb/ethernet@7d580000"),
),
Board(
name="serengeti",
arch=riscv64,
paddr_top=0x90000000,
serial=DriverDouble("ns16550a", "soc/serial@3002000"),
i2c=DriverDouble("eth,i2c", "soc/i2c@3003000"),
timer=DriverDouble("pulp,apb_timer", "soc/timer@300B000"),
),
Board(
name="star64",
arch=riscv64,
paddr_top=0x100000000,
serial=DriverDouble("starfive,jh7110-uart", "soc/serial@10000000"),
timer=DriverDouble("starfive,jh7110-timer", "soc/timer@13050000"),
ethernet=DriverDouble("", "soc/ethernet@16030000"),
),
Board(
name="zcu102",
arch=aarch64,
paddr_top=0x80000000,
timer=DriverDouble("cdns,ttc", "axi/timer@ff140000"),
serial=DriverDouble("xlnx,zynqmp-uart", "axi/serial@ff000000"),
),
Board(
name="x86_64_generic",
arch=x86_64,
paddr_top=0x7FFDF000,
),
Board(
name="x86_64_generic_vtx",
arch=x86_64,
paddr_top=0x7FFDF000,
),
]
92 changes: 92 additions & 0 deletions acacia_sddf/driver_manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Copyright 2026, UNSW
# SPDX-License-Identifier: BSD-2-Clause

from dataclasses import dataclass
from typing import List, Dict, Type, Union, Optional
from collections import defaultdict


@dataclass
class DTSRegion:
name: str
perms: str = None
size: int = None
dt_idx: int = None


@dataclass
class DTSIRQ:
dt_index: int


@dataclass
class sDDFDriverConfig:
"""
Encapsulation of device tree fields describing an instance
of a driver.

WARNING: the order of regions and irqs affects the order they are
mapped into the driver in config structs! We REALLY shouldn't have
this be the case. This is a hangover from `config.json` and sdfgen.

TODO: make this better in future
"""

compatible: Union[List[str], str]
regions: List[DTSRegion]
irqs: List[DTSIRQ]

def __post_init__(self):
if type(self.compatible) is str:
self.compatible = [self.compatible]
assert type(self.regions) is list
assert type(self.irqs) is list


class __sDDFDriverManifest:
"""
Wrapper class encapsulating sDDF driver manifest. This is a
mapping of driver subsystem type -> list of driver names ->
DTS fields. I.e. this encodes:
* Which drivers are compatible with what devices, according to the
device tree,
* What drivers are available in each driver class,
* Which driver subsystem types in sdfgen map to which drivers.

You should NOT make a new instance of this class! Use the
`sDDFDriverManifest()` function to get the global instance.
"""

def __init__(self):
self.map: Dict[Type[sDDFDeviceClass], Dict[str, sDDFDriverConfig]] = (
defaultdict(dict)
)

def add_driver_config(
self,
subsystem_type: Type[sDDFDriverConfig],
driver_name: str,
config: sDDFDriverConfig,
):
# Refuse namespace collisions
if driver_name in self.map[subsystem_type]:
raise ValueError(
f"Driver named {driver_name} already exists for " f"{subsystem_type}!"
)
self.map[subsystem_type][driver_name] = config

def __getitem__(self, item):
# Allow array syntax for indexing into dict of driver names per class type
return self.map[item]

def get_configs_matching_compatible(
self, subsystem_type: Type[sDDFDriverConfig], compat: str
) -> List[sDDFDriverConfig]:
return [c for c in self.map[subsystem_type].values() if compat in c.compatible]


module_manifest = __sDDFDriverManifest()


def sDDFDriverManifest():
return module_manifest
Loading
Loading