tree: 56cb79077e60af15f99969e3ca9290ca5b713fb6
  1. harness/
  2. i2c/
  3. i2c-slave/
  4. ipc/
  5. mctp/
  6. threads/
  7. BUILD.bazel
  8. config.rs
  9. console_backend.rs
  10. defs.bzl
  11. entry.rs
  12. README.md
  13. target.ld.tmpl
target/ast1060-evb/README.md

AST1060 Target Guide

This document explains the out-of-tree Pigweed kernel targets for AST1060.

Overview

There are two AST1060 targets in this workspace:

TargetPurposeConsoleUse Case
ast1060QEMU emulationSemihostingDevelopment, CI testing
ast1060-evbPhysical hardwareUARTReal board testing

Architecture

bazel-stuff/
├── target/
│   ├── ast1060/              # QEMU target
│   │   ├── BUILD.bazel       # Platform + rust_library targets
│   │   ├── defs.bzl          # TARGET_COMPATIBLE_WITH constraint
│   │   ├── config.rs         # KernelConfig (SysTick, MPU regions)
│   │   ├── entry.rs          # Reset handler + boot sequence
│   │   ├── target.ld.tmpl    # Linker script template
│   │   └── threads/kernel/   # Threads test application
│   │       ├── BUILD.bazel
│   │       ├── system.json5  # Memory layout
│   │       └── target.rs     # Application entry point
│   │
│   └── ast1060-evb/          # Physical board target
│       ├── BUILD.bazel
│       ├── defs.bzl
│       ├── config.rs
│       ├── entry.rs          # Initializes UART before kernel
│       ├── console_backend.rs # UART driver via aspeed-ddk
│       ├── target.ld.tmpl
│       └── threads/kernel/
│           ├── BUILD.bazel
│           ├── system.json5
│           └── target.rs

How It Works

1. Platform Definition (BUILD.bazel)

Each target defines a Bazel platform with CPU and OS constraints:

platform(
    name = "ast1060",
    constraint_values = [
        "@platforms//cpu:armv7-m",
        "@platforms//os:none",
        "@pigweed//pw_kernel:os_freestanding",
        "//platform:ast1060",          # Custom constraint
    ],
)

The platform tells Bazel which toolchain to use (ARM Cortex-M cross-compiler).

2. Kernel Configuration (config.rs)

Provides hardware-specific settings to the kernel:

impl KernelConfig for Config {
    const SYSTICK_HZ: u32 = 12_000_000;  // 12 MHz clock
    const ARM_V7_MPU_REGIONS: usize = 8; // MPU region count
}

3. Boot Entry (entry.rs)

The reset handler that runs at power-on:

#[cortex_m_rt::entry]
fn main() -> ! {
    // For ast1060-evb: Initialize UART here
    uart_init();
    
    // Jump to kernel target
    target_common::enter_kernel_main()
}

4. Console Backend

QEMU (ast1060): Uses ARM semihosting - debug output goes through QEMU to host terminal.

Physical Board (ast1060-evb): Uses UART via aspeed-ddk driver:

// console_backend.rs
static UART: Mutex<RefCell<Option<Uart>>> = ...;

pub fn uart_write(data: &[u8]) {
    critical_section::with(|cs| {
        if let Some(ref mut uart) = *UART.borrow_ref_mut(cs) {
            for byte in data {
                uart.write_byte(*byte);
            }
        }
    });
}

5. Memory Layout (system.json5)

Defines memory regions for the linker:

{
    memory: {
        vector_table: { start: 0x00000000, size: 0x400 },
        flash:        { start: 0x00000400, size: 0x000ffc00 },
        ram:          { start: 0x80000000, size: 0x00100000 },
    }
}

6. Linker Script (target.ld.tmpl)

Template processed by Bazel to generate final linker script with memory addresses from system.json5.

Build Commands

QEMU Target

# Build
bazelisk build //target/ast1060/threads/kernel:threads --config=k_qemu_ast1060

# Run in QEMU
bazelisk run //target/ast1060/threads/kernel:threads --config=k_qemu_ast1060

Physical Board Target

# Build
bazelisk build //target/ast1060-evb/threads/kernel:threads --config=k_ast1060_evb

# The output binary is at:
# bazel-bin/target/ast1060-evb/threads/kernel/threads.bin

Output Files

FileHeaderUse Case
threads.binNoOpenOCD/JTAG flashing, direct memory load
threads_uart.binYes (4-byte size)UART bootloader upload

Generate UART Boot Image

The AST1060 UART bootloader requires a special header format:

  • 4 bytes: image size (little-endian, 4-byte aligned)
  • N bytes: binary image data
  • 0-3 bytes: zero padding to 4-byte alignment

This is automated via the uart_boot_image Bazel rule:

# Build the UART-bootable image
bazelisk build //target/ast1060-evb/threads/kernel:threads_uart --config=k_ast1060_evb

# Output file:
# bazel-bin/target/ast1060-evb/threads/kernel/threads_uart.bin

The rule is defined in //target:uart_boot_image.bzl and used in BUILD.bazel:

load("//target:uart_boot_image.bzl", "uart_boot_image")

uart_boot_image(
    name = "threads_uart",
    src = ":threads",  # system_image target
    out = "threads_uart.bin",
)

Flashing to Hardware

After building the ast1060-evb target:

# Using the UART boot image (with header)
# Upload via serial bootloader tool
uart_upload /dev/ttyUSB0 bazel-bin/target/ast1060-evb/threads/kernel/threads_uart.bin

# Or using OpenOCD with raw binary (no header needed)
openocd -f interface/cmsis-dap.cfg -f target/aspeed_ast1060.cfg \
  -c "program bazel-bin/target/ast1060-evb/threads/kernel/threads.bin verify reset exit"

Serial Console

Connect to the AST1060-EVB serial port:

# Find the USB-UART device
ls /dev/ttyUSB*

# Connect at 115200 baud
screen /dev/ttyUSB2 115200
# or
picocom -b 115200 /dev/ttyUSB2

Expected output:

Hello from AST1060-EVB!
=== pw_kernel ===
...

Key Dependencies

CratePurpose
@ast1060_pacAST1060 Peripheral Access Crate (register definitions)
aspeed-ddkASPEED device driver kit (UART driver)
cortex-m-rtCortex-M runtime (reset handler, vector table)
cortex-m-semihostingARM semihosting support

Configuration Files

.bazelrc Configs

# QEMU config
common:k_qemu_ast1060 --config=k_common
common:k_qemu_ast1060 --platforms=//target/ast1060
run:k_qemu_ast1060 --run_under="@pigweed//pw_kernel/tooling:qemu ..."

# Physical board config
common:k_ast1060_evb --config=k_common
common:k_ast1060_evb --platforms=//target/ast1060-evb

MODULE.bazel Dependencies

The AST1060 PAC is fetched via git:

ast1060_pac = use_extension("//third_party:ast1060_pac.bzl", "ast1060_pac")
use_repo(ast1060_pac, "ast1060_pac")

Differences: QEMU vs Physical Board

Aspectast1060 (QEMU)ast1060-evb (Physical)
ConsoleSemihostingUART @ 115200
Exitsemihosting::exit()Loop or reset
ClockEmulatedReal 12 MHz
DebugGDB via QEMUJTAG/SWD
Build configk_qemu_ast1060k_ast1060_evb

Troubleshooting

Build Errors

“No matching toolchains found”

  • Ensure --platforms=//target/ast1060 is specified
  • Check that ARM toolchain is configured in MODULE.bazel

“unresolved import ast1060_pac

  • Run cargo generate-lockfile in third_party/crates_io/
  • Verify Cargo.toml has the ast1060-pac dependency

Runtime Issues

No UART output on physical board

  • Check baud rate (115200)
  • Verify TX/RX pin connections
  • Ensure UART is initialized before any print calls

QEMU hangs

  • Check CPU type matches (cortex-m4 for ast1030-evb machine)
  • Verify semihosting is enabled in run_under config