diff --git a/.github/workflows/sdk.yaml b/.github/workflows/sdk.yaml index 1f5f7ad2..78a4fdc2 100644 --- a/.github/workflows/sdk.yaml +++ b/.github/workflows/sdk.yaml @@ -34,7 +34,8 @@ jobs: sudo apt install \ cmake pandoc device-tree-compiler ninja-build \ texlive-fonts-recommended texlive-formats-extra libxml2-utils \ - python3.9 python3-pip python3.9-venv musl-tools + python3.9 python3-pip python3.9-venv musl-tools \ + qemu-system-arm \ - name: Install AArch64 GCC toolchain run: | wget -O aarch64-toolchain.tar.gz https://sel4-toolchains.s3.us-east-2.amazonaws.com/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-elf.tar.xz%3Frev%3D28d5199f6db34e5980aae1062e5a6703%26hash%3DF6F5604BC1A2BBAAEAC4F6E98D8DC35B @@ -59,7 +60,7 @@ jobs: ref: microkit path: seL4 - name: Install SDK dependencies - run: brew install pandoc cmake dtc ninja qemu libxml2 python@3.9 coreutils texlive + run: brew install pandoc cmake dtc ninja qemu libxml2 python@3.9 coreutils texlive qemu - name: Install AArch64 GCC toolchain run: | wget -O aarch64-toolchain.tar.gz https://sel4-toolchains.s3.us-east-2.amazonaws.com/arm-gnu-toolchain-12.2.rel1-darwin-x86_64-aarch64-none-elf.tar.xz%3Frev%3D09b11f159fc24fdda01e05bb32695dd5%26hash%3D6AAF4239F28AE17389AB3E611DFFE0A6 diff --git a/README.md b/README.md index 439d2d66..7b9c2db2 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Please file an issue if additional packages are required. * ARM GCC compiler for none-elf; version 12.2.1 20221205 * device tree compiler * xmllint +* qemu-system-aarch64 To build the documentation you also need * pandoc @@ -56,11 +57,12 @@ To build the documentation you also need On a Debian-like system you can do: $ sudo apt install build-essential git cmake ninja-build \ - device-tree-compiler libxml2-utils \ - pandoc texlive-latex-base texlive-latex-recommended \ - texlive-fonts-recommended texlive-fonts-extra \ - python3.9 python3.9-venv \ - musl-dev musl-tools + device-tree-compiler libxml2-utils \ + pandoc texlive-latex-base texlive-latex-recommended \ + texlive-fonts-recommended texlive-fonts-extra \ + python3.9 python3.9-venv \ + musl-dev musl-tools \ + qemu-system-arm If you do not have Python 3.9 available, you can get it via the *deadsnakes* PPA: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa @@ -72,7 +74,7 @@ To use this: On macOS, with the [Homebrew](https://brew.sh) package manager you can do: - $ brew install pandoc cmake dtc ninja qemu libxml2 python@3.9 coreutils texlive + $ brew install pandoc cmake dtc ninja qemu libxml2 python@3.9 coreutils texlive qemu Additonally, a number of Python libraries are needed. These should be installed using `pip`. @@ -173,6 +175,7 @@ The currently supported boards are: * maaxboard * odroidc2 * odroidc4 +* qemu_virt_aarch64 * tqma8xqp1gb * zcu102 diff --git a/build_sdk.py b/build_sdk.py index 9a83fe7b..a7818223 100644 --- a/build_sdk.py +++ b/build_sdk.py @@ -147,6 +147,20 @@ class ConfigInfo: "timer": Path("example/odroidc4/timer") } ), + BoardInfo( + name="qemu_virt_aarch64", + gcc_cpu="cortex-a53", + loader_link_address=0x70000000, + kernel_options={ + "KernelPlatform": "qemu-arm-virt", + "KernelIsMCS": True, + "KernelArmExportPCNTUser": True, + "QEMU_MEMORY": "2048", + }, + examples={ + "hello": Path("example/qemu_virt_aarch64/hello") + } + ), ) SUPPORTED_CONFIGS = ( diff --git a/docs/manual.md b/docs/manual.md index f462e0e6..cce20061 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -615,6 +615,27 @@ Rather than typing these each time you can create a U-Boot script: When debugging is enabled the kernel will use the same UART as U-Boot. +## QEMU virt (AArch64) + +Support is available for the virtual AArch64 QEMU platform. This is a platform that is not based +on any specific SoC or hardware platform and is intended for simulating systems for +development or testing. + +It should be noted that the platform support is configured with 2GB of main memory and a single +Cortex-A53 CPU. + +You can use the following command to simulate a Microkit system: + + $ qemu-system-aarch64 \ + -machine virt \ + -cpu cortex-a53 \ + -nographic \ + -serial mon:stdio \ + -device loader,file=[SYSTEM IMAGE],addr=0x70000000,cpu-num=0 \ + -m size=2G + +You can find more about the QEMU virt platform in the +[QEMU documentation](https://www.qemu.org/docs/master/system/target-arm.html). ## ZCU102 diff --git a/example/qemu_virt_aarch64/hello/Makefile b/example/qemu_virt_aarch64/hello/Makefile new file mode 100644 index 00000000..e7bdffb0 --- /dev/null +++ b/example/qemu_virt_aarch64/hello/Makefile @@ -0,0 +1,55 @@ +# +# Copyright 2021, Breakaway Consulting Pty. Ltd. +# +# SPDX-License-Identifier: BSD-2-Clause +# +ifeq ($(strip $(BUILD_DIR)),) +$(error BUILD_DIR must be specified) +endif + +ifeq ($(strip $(MICROKIT_SDK)),) +$(error MICROKIT_SDK must be specified) +endif + +ifeq ($(strip $(MICROKIT_BOARD)),) +$(error MICROKIT_BOARD must be specified) +endif + +ifeq ($(strip $(MICROKIT_CONFIG)),) +$(error MICROKIT_CONFIG must be specified) +endif + +TOOLCHAIN := aarch64-none-elf + +CPU := cortex-a53 + +CC := $(TOOLCHAIN)-gcc +LD := $(TOOLCHAIN)-ld +AS := $(TOOLCHAIN)-as +MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit + +HELLO_OBJS := hello.o + +BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG) + +IMAGES := hello.elf +CFLAGS := -mcpu=$(CPU) -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include +LDFLAGS := -L$(BOARD_DIR)/lib +LIBS := -lmicrokit -Tmicrokit.ld + +IMAGE_FILE = $(BUILD_DIR)/loader.img +REPORT_FILE = $(BUILD_DIR)/report.txt + +all: $(IMAGE_FILE) + +$(BUILD_DIR)/%.o: %.c Makefile + $(CC) -c $(CFLAGS) $< -o $@ + +$(BUILD_DIR)/%.o: %.s Makefile + $(AS) -g -mcpu=$(CPU) $< -o $@ + +$(BUILD_DIR)/hello.elf: $(addprefix $(BUILD_DIR)/, $(HELLO_OBJS)) + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ + +$(IMAGE_FILE) $(REPORT_FILE): $(addprefix $(BUILD_DIR)/, $(IMAGES)) hello.system + $(MICROKIT_TOOL) hello.system --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE) diff --git a/example/qemu_virt_aarch64/hello/hello.c b/example/qemu_virt_aarch64/hello/hello.c new file mode 100644 index 00000000..493c9574 --- /dev/null +++ b/example/qemu_virt_aarch64/hello/hello.c @@ -0,0 +1,16 @@ +/* + * Copyright 2021, Breakaway Consulting Pty. Ltd. + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#include +#include + +void init(void) +{ + microkit_dbg_puts("hello, world\n"); +} + +void notified(microkit_channel ch) +{ +} diff --git a/example/qemu_virt_aarch64/hello/hello.system b/example/qemu_virt_aarch64/hello/hello.system new file mode 100644 index 00000000..146da4ba --- /dev/null +++ b/example/qemu_virt_aarch64/hello/hello.system @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/loader/Makefile b/loader/Makefile index cbcc261f..d145d164 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -21,7 +21,7 @@ endif TOOLCHAIN := aarch64-none-elf- -CFLAGS := -std=gnu11 -g -O3 -nostdlib -ffreestanding -mcpu=$(GCC_CPU) -DBOARD_$(BOARD) -Wall -Werror +CFLAGS := -std=gnu11 -g -O3 -nostdlib -ffreestanding -mcpu=$(GCC_CPU) -DBOARD_$(BOARD) -Wall -Werror -mgeneral-regs-only PROGS := loader.elf OBJECTS := loader.o crt0.o util64.o diff --git a/loader/src/loader.c b/loader/src/loader.c index 2659df0a..9fa1fd34 100644 --- a/loader/src/loader.c +++ b/loader/src/loader.c @@ -31,6 +31,9 @@ _Static_assert(sizeof(uintptr_t) == 8 || sizeof(uintptr_t) == 4, "Expect uintptr #if defined(BOARD_zcu102) #define GICD_BASE 0x00F9010000UL #define GICC_BASE 0x00F9020000UL +#elif defined(BOARD_qemu_virt_aarch64) +#define GICD_BASE 0x8010000UL +#define GICC_BASE 0x8020000UL #endif #define REGION_TYPE_DATA 1 @@ -179,6 +182,17 @@ static void putc(uint8_t ch) while ((*UART_REG(UART_STATUS) & UART_TX_FULL)); *UART_REG(UART_WFIFO) = ch; } +#elif defined(BOARD_qemu_virt_aarch64) +#define UART_BASE 0x9000000 +#define UARTDR 0x000 +#define UARTFR 0x018 +#define PL011_UARTFR_TXFF (1 << 5) + +static void putc(uint8_t ch) +{ + while ((*UART_REG(UARTFR) & PL011_UARTFR_TXFF) != 0); + *UART_REG(UARTDR) = ch; +} #else #error Board not defined #endif @@ -490,7 +504,7 @@ static void start_kernel(void) ); } -#if defined(BOARD_zcu102) +#if defined(BOARD_zcu102) || defined(BOARD_qemu_virt_aarch64) static void configure_gicv2(void) { /* The ZCU102 start in EL3, and then we drop to EL1(NS). @@ -554,7 +568,7 @@ int main(void) */ copy_data(); -#if defined(BOARD_zcu102) +#if defined(BOARD_zcu102) || defined(BOARD_qemu_virt_aarch64) configure_gicv2(); #endif