Go HAL for ASPEED SoC main application processor (AP) cores, targeting bare-metal TamaGo (GOOS=tamago) firmware.
Part of the Kyanite stack.
Status: experimental — expect breaking changes.
The AP cores (Cortex-A7 on AST2600, quad Cortex-A35 on AST2700) run bare-metal Go via TamaGo. They own the management plane: OpenBMC-equivalent services, Redfish, network stack, and user-facing APIs. Auxiliary processor cores run separate firmware:
| Core | ISA | Runtime | Repo |
|---|---|---|---|
| AP (this repo) | ARMv7-A / ARMv8-A | TamaGo (Go) | aspeed-go |
| RoT (AST10x0, BootMCU) | ARMv7E-M / RV32 | Embassy (Rust) | aspeed-mcu-runtime/app-rot |
| Coprocessor SSP/TSP | ARMv7-M / ARMv7E-M | Embassy (Rust) | aspeed-mcu-runtime/app-coprocessor/ssp |
| Coprocessor ColdFire | M68K (ColdFire V1) | async.h (C) | aspeed-mcu-runtime/app-coprocessor/coldfire |
The AP communicates with coprocessors via hardware mailbox IPC and MCTP/PLDM. Sensor data is collected by coprocessor cores and delivered to the AP on request.
- Zero external dependencies —
go.modhas norequireentries. Theregpackage uses onlyunsafefrom the Go standard library. - TamaGo-compatible — direct volatile MMIO via
unsafe.Pointer. No syscalls, no OS, no allocator. Safe from interrupt context. - Generated PAC — register structs in
pac/are generated byaspeed-datavia the chiptool Go backend. Never hand-editpac/.
aspeed-go/
├── reg/ volatile MMIO primitives (Read32/Write32/SetBits32/…)
└── hal/
├── uart/ 16550 UART driver (placeholder — Phase B)
├── gpio/ GPIO driver (placeholder — Phase B)
└── timer/ Hardware timer driver (placeholder — Phase B)
Generated Go PAC register structs live in aspeed-data/aspeed-go-pac/. They are not copied into this repo — import them via Go module:
import "src.kyanite.computer/aspeed-data/aspeed-go-pac/ast2600"go build ./...
go test ./...
go vet ./...
# With Dagger:
dagger call ciimport "src.kyanite.computer/aspeed-go/reg"
// Read the AST2600 SSP control register
v := reg.Read32(0x1E6E2A00)
// Unlock the SCU (same key for AST2600/AST2700)
reg.Write32(0x1E6E2000, 0x1688A8A8)
// Toggle GPIO pin (read-modify-write)
reg.SetBits32(0x1E780000, 1<<4)
reg.ClearBits32(0x1E780000, 1<<4)The generated PAC lives in aspeed-data/aspeed-go-pac/ as a separate Go module (src.kyanite.computer/aspeed-data/aspeed-go-pac). It imports src.kyanite.computer/aspeed-go/reg for register access.
For local development, create a go.work file (gitignored) to redirect the module:
# In aspeed-go/:
cat > go.work << 'EOF'
go 1.24
use .
use ../aspeed-data/aspeed-go-pac
EOFTo regenerate the PAC after YAML changes:
# From aspeed-data repo root:
dagger call generate --chiptool ../chiptool export --path ./The chiptool Go backend generates structs with Base uintptr fields and Read<Reg>()/Write<Reg>() methods that delegate to this reg package.
| Chip | Core | Target | Status |
|---|---|---|---|
| AST2600 | Cortex-A7 (AP) | GOARCH=arm |
PAC generated, HAL planned |
| AST2700 | Cortex-A35 ×4 (AP) | GOARCH=arm64 |
PAC generated, HAL planned |
See the org-wide CONTRIBUTING guide. Contributions are dual-licensed.
See the org-wide SECURITY policy.
Dual-licensed under either of Apache-2.0 (LICENSE-APACHE) or MIT (LICENSE-MIT) at your option.