Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ jobs:
- name: Run Clippy
# Make sure CI fails on all warnings, including Clippy lints
run: nix develop --ignore-environment -c bash -c "cd tool/microkit && cargo-clippy --all-targets --all-features -- -D warnings -Wclippy::get_unwrap"
- name: Run Clippy (Loader)
run: nix develop --ignore-environment -c bash -c 'make -C loader clippy CLIPPYFLAGS="-D warnings -Wclippy::get_unwrap" BUILD_DIR=$(mktemp -d) ARCH=dummy BOARD=dummy SEL4_SDK=dummy TARGET_TRIPLE=dummy LLVM=False LINK_ADDRESS=0'

rustfmt_check:
runs-on: [self-hosted, macos, ARM64]
Expand Down
22 changes: 22 additions & 0 deletions build_sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,26 @@ def build_sel4(
json_dst.chmod(0o744)


def test_loader(build_dir: Path) -> None:
build_dir = build_dir / "loader"
build_dir.mkdir(exist_ok=True, parents=True)

make_args = f"BUILD_DIR={build_dir.absolute()} ARCH=dummy BOARD=dummy SEL4_SDK=dummy TARGET_TRIPLE=dummy LLVM=False LINK_ADDRESS=0"

r = system(
f"make -C loader tests {make_args}"
)
if r != 0:
raise Exception(f"Tests failed: loader")

# We don't pass CLIPPYARGS, so this is warning-only
r = system(
f"make -C loader clippy {make_args}"
)
if r != 0:
raise Exception(f"Clippy failed: loader")


def build_elf_component(
component_name: str,
sdk_dir: Path,
Expand Down Expand Up @@ -1094,6 +1114,8 @@ def main() -> None:

if not args.skip_run_time:
build_dir = Path("build")
test_loader(build_dir)

for (board, configs) in build_goals:
for config in configs:
if not args.skip_sel4:
Expand Down
54 changes: 51 additions & 3 deletions loader/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,34 @@ else
LD = $(TARGET_TRIPLE)-ld
endif

RUSTC := rustc
CLIPPY := clippy-driver

ifeq ($(ARCH),aarch64)
CFLAGS_AARCH64 := -mcpu=$(GCC_CPU) -mgeneral-regs-only -mstrict-align -mno-outline-atomics
CFLAGS_ARCH := $(CFLAGS_AARCH64) -DARCH_aarch64
ASM_FLAGS_ARCH := -mcpu=$(GCC_CPU)
ARCH_DIR := aarch64
RUST_TARGET_TRIPLE := aarch64-unknown-none
else ifeq ($(ARCH),riscv64)
CFLAGS_RISCV64 := -mcmodel=medany -march=rv64imac_zicsr_zifencei -mabi=lp64
CFLAGS_ARCH := $(CFLAGS_RISCV64) -DARCH_riscv64
ASM_FLAGS_ARCH := -march=rv64imac_zicsr_zifencei -mabi=lp64
RUST_TARGET_TRIPLE := riscv64gc-unknown-none-elf
ARCH_DIR := riscv
endif

CFLAGS := -std=gnu11 -g -O3 -nostdlib -ffreestanding \
-MP -MD $(CFLAGS_ARCH) -DBOARD_$(BOARD) -I$(SEL4_SDK)/include \
-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \
-Wundef -Wno-nonnull -Wnested-externs
-Wundef -Wno-nonnull -Wnested-externs -ffunction-sections -fdata-sections

ASM_FLAGS := $(ASM_FLAGS_ARCH) -g -MP -MD -I$(SEL4_SDK)/include

RUSTFLAGS := --edition 2024 -g -C opt-level=2

PROGS := loader.elf
OBJECTS := loader.o crt0.o uart.o cutil.o
OBJECTS := loader.o crt0.o uart.o cutil.o libpage_tables.a

ifeq ($(ARCH),aarch64)
OBJECTS += util64.o el.o exceptions.o init.o mmu.o cpus.o
Expand All @@ -80,6 +87,18 @@ $(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.c
$(BUILD_DIR)/%.o : src/%.c
$(CC) -c $(CFLAGS) $< -o $@

# Note: having multiple libs with staticlib will give duplicate linker symbol
# issues. Use "--crate-type rlib" instead, but then we need to link a single
# copy of the rust corelibs. For now this is fine.
$(BUILD_DIR)/lib%.a : src/%.rs
$(RUSTC) $(RUSTFLAGS) \
--emit dep-info,metadata,link \
--out-dir $(BUILD_DIR) -L dependency=$(BUILD_DIR) \
--target $(RUST_TARGET_TRIPLE) \
--crate-type staticlib \
--crate-name $(patsubst lib%.a,%,$(notdir $@)) \
$<

-include $(BUILD_DIR)/*.d

OBJPROG = $(addprefix $(BUILD_DIR)/, $(PROGS))
Expand All @@ -89,5 +108,34 @@ all: $(OBJPROG)
$(LINKSCRIPT): $(LINKSCRIPT_INPUT)
$(CPP) -DLINK_ADDRESS=$(LINK_ADDRESS) $< | grep -v "^#" > $@

LDFLAGS := -T$(LINKSCRIPT) --gc-sections

$(OBJPROG): $(addprefix $(BUILD_DIR)/, $(OBJECTS)) $(LINKSCRIPT)
$(LD) -T$(LINKSCRIPT) $(addprefix $(BUILD_DIR)/, $(OBJECTS)) -o $@
$(LD) $(LDFLAGS) --start-group $(addprefix $(BUILD_DIR)/, $(OBJECTS)) --end-group -o $@

rusttest_%: src/%.rs
$(RUSTC) $(RUSTFLAGS) \
--emit dep-info,metadata,link \
--out-dir $(BUILD_DIR) -L dependency=$(BUILD_DIR) \
-Awarnings \
--test \
--crate-name "$@" \
$<

tests: rusttest_page_tables
$(BUILD_DIR)/rusttest_page_tables


CLIPPYFLAGS ?=

rustclippy_%: src/%.rs
$(CLIPPY) $(RUSTFLAGS) \
--emit dep-info,metadata,link \
--out-dir $(BUILD_DIR) -L dependency=$(BUILD_DIR) \
$(CLIPPYFLAGS) \
-Cpanic=abort \
--crate-type staticlib \
--crate-name "$@" \
$<

clippy: rustclippy_page_tables
27 changes: 23 additions & 4 deletions loader/aarch64.ld
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ PHDRS
all PT_LOAD AT (LINK_ADDRESS);
}


// text PT_LOAD FLAGS(5); /* RX */
// rodata PT_LOAD FLAGS(4); /* RO */
// data PT_LOAD FLAGS(6); /* RW */
// bss PT_LOAD FLAGS(6); /* RW */

SECTIONS
{
. = LINK_ADDRESS;
Expand All @@ -17,27 +23,40 @@ SECTIONS
.text :
{
_text = .;
*(.text.start)
*(.text*)
*(.rodata)

KEEP(*(.text.start))
*(.text .text.*)

_text_end = .;
} :all

.rodata :
{
*(.rodata .rodata.* .rodata..Lanon.*)
} :all

.data :
{
_data = .;
*(.data)
*(.data .data.*)
*(.data.*)

KEEP(*(.data.uart_addr))

_data_end = .;
} :all

.bss :
{
_bss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
_bss_end = .;
} :all



_loader_end = .;
}
13 changes: 9 additions & 4 deletions loader/riscv64.ld
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,32 @@ SECTIONS
.text :
{
_text = .;
*(.text.start)
KEEP(*(.text.start))
*(.text*)
*(.text.*)
*(.rodata)
*(.rodata.*)
_text_end = .;
} :all

.data :
{
_data = .;
*(.data)
*(.data.*)
__global_pointer$ = . + 0x800;
*(.srodata)
*(.sdata)
*(.srodata)
*(.sdata)
KEEP(*(.data.uart_addr))
_data_end = .;
} :all

.bss :
{
_bss = .;
*(.sbss)
*(.sbss)
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
_bss_end = .;
Expand Down
53 changes: 41 additions & 12 deletions loader/src/aarch64/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,56 @@
*/

#include <stdint.h>
#include <stdbool.h>

#include "el.h"
#include "../arch.h"
#include "../cutil.h"
#include "../uart.h"

void el1_mmu_enable(void);
void el2_mmu_enable(void);
void el1_mmu_enable(uint64_t ttbr0_el1, uint64_t ttbr1_el1);
void el2_mmu_enable(uint64_t ttbr0_el2);

/* Paging structures for kernel mapping */
uint64_t boot_lvl0_upper[1 << 9] ALIGN(1 << 12);
uint64_t boot_lvl1_upper[1 << 9] ALIGN(1 << 12);
uint64_t boot_lvl2_upper[1 << 9] ALIGN(1 << 12);
struct AArch64ReturnValue {
uintptr_t ttbr0_el2;
uintptr_t ttbr0_el1;
uintptr_t ttbr1_el1;
};

/* Paging structures for identity mapping */
uint64_t boot_lvl0_lower[1 << 9] ALIGN(1 << 12);
uint64_t boot_lvl1_lower[1 << 9] ALIGN(1 << 12);
uint64_t boot_lvl2_lower[1 << 9] ALIGN(1 << 12);
union RegionArchAttrs {
bool is_ram;
uint64_t raw;
};

struct Region {
uint64_t start;
uint64_t end;
union RegionArchAttrs arch_attrs;
};

struct Region regions[] = {
{ .start = 0x60000000, .end = 0xc0000000, .arch_attrs.is_ram = true },
{ .start = 0x9000000, .end = 0x9000000 + 4096, .arch_attrs.is_ram = false },
};

#define PAGE_TABLE_SIZE 4096
#define MAX_NUM_PAGE_TABLES 64

uint8_t page_table_bytes[PAGE_TABLE_SIZE][MAX_NUM_PAGE_TABLES] ALIGN(4096);

extern struct AArch64ReturnValue aarch64_setup_pagetables(
uint64_t kernel_first_vaddr, uint64_t kernel_first_paddr,
void *regions_ptr, uintptr_t regions_len,
uint8_t page_table_bytes[4096][64]);

int arch_mmu_enable(int logical_cpu)
{
struct AArch64ReturnValue pt = aarch64_setup_pagetables(
0x8060000000, 0x60000000,
&regions, ARRAY_SIZE(regions),
page_table_bytes
);

int r;
enum el el;
r = ensure_correct_el(logical_cpu);
Expand All @@ -37,9 +66,9 @@ int arch_mmu_enable(int logical_cpu)
LDR_PRINT("INFO", logical_cpu, "enabling MMU\n");
el = current_el();
if (el == EL1) {
el1_mmu_enable();
el1_mmu_enable(pt.ttbr0_el1, pt.ttbr1_el1);
} else if (el == EL2) {
el2_mmu_enable();
el2_mmu_enable(pt.ttbr0_el2);
} else {
LDR_PRINT("ERROR", logical_cpu, "unknown EL for MMU enable\n");
}
Expand Down
26 changes: 16 additions & 10 deletions loader/src/aarch64/util64.S
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,6 @@ END_FUNC(el1_mmu_disable)

BEGIN_FUNC(el2_mmu_disable)
stp x29, x30, [sp, #-16]!
stp x27, x28, [sp, #-16]!
mov x29, sp

/* Disable caches */
Expand All @@ -323,14 +322,18 @@ BEGIN_FUNC(el2_mmu_disable)
*/
bl invalidate_icache

ldp x27, x28, [sp], #16
ldp x29, x30, [sp], #16
ret
END_FUNC(el2_mmu_disable)

/*
* Enables the MMU for EL2.
* Takes two arguments the physical address for TTBR0_EL1 (x0) and TTBR1_EL1 (x1).
*/
BEGIN_FUNC(el1_mmu_enable)
stp x29, x30, [sp, #-16]!
stp x27, x28, [sp, #-16]!
/* move caller-saved to callee-saved registers */
mov x29, sp
mov x27, x0
mov x28, x1
Expand Down Expand Up @@ -358,10 +361,8 @@ BEGIN_FUNC(el1_mmu_enable)
msr tcr_el1, x10

/* Setup page tables */
adrp x8, boot_lvl0_lower
msr ttbr0_el1, x8
adrp x8, boot_lvl0_upper
msr ttbr1_el1, x8
msr ttbr0_el1, x27 /* argument 0 */
msr ttbr1_el1, x28 /* argument 1 */
isb

/* invalidate all TLB entries for EL1 */
Expand All @@ -374,12 +375,18 @@ BEGIN_FUNC(el1_mmu_enable)
ldp x27, x28, [sp], #16
ldp x29, x30, [sp], #16
ret

END_FUNC(el1_mmu_enable)

/*
* Enables the MMU for EL2.
* Takes one argument, the physical address for TTBR0_EL2 (x0).
*/
BEGIN_FUNC(el2_mmu_enable)
stp x29, x30, [sp, #-16]!
stp x27, x28, [sp, #-16]!
/* move caller-saved to callee-saved registers */
mov x29, sp
mov x28, x0

/* Disable the MMU */
bl el2_mmu_disable
Expand All @@ -403,8 +410,7 @@ BEGIN_FUNC(el2_mmu_enable)
isb

/* Setup page tables */
adrp x8, boot_lvl0_lower
msr ttbr0_el2, x8
msr ttbr0_el2, x28 /* argument 0 */
isb

/* invalidate all TLB entries for EL2 */
Expand All @@ -423,9 +429,9 @@ BEGIN_FUNC(el2_mmu_enable)
dsb ish
isb

ldp x27, x28, [sp], #16
ldp x29, x30, [sp], #16
ret

END_FUNC(el2_mmu_enable)

.extern arm_secondary_cpu_c_entry
Expand Down
Loading
Loading