| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 0414173 commit 11bc11b
105 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -74,3 +74,17 @@ jobs: | |||
| 74 | 74 | - name: Print failures | |
| 75 | 75 | if: failure() | |
| 76 | 76 | run: tests/run-tests.py --print-failures | |
| 77 | + | ||
| 78 | + build_and_test_aarch64: | ||
| 79 | + runs-on: ubuntu-latest | ||
| 80 | + steps: | ||
| 81 | + - uses: actions/checkout@v7 | ||
| 82 | + - name: Install packages | ||
| 83 | + run: tools/ci.sh qemu_setup_aarch64 | ||
| 84 | + - name: Add toolchain to PATH | ||
| 85 | + run: echo "$(tools/ci.sh qemu_aarch64_path)" >> $GITHUB_PATH | ||
| 86 | + - name: Build and run test suite | ||
| 87 | + run: tools/ci.sh qemu_build_aarch64 | ||
| 88 | + - name: Print failures | ||
| 89 | + if: failure() | ||
| 90 | + run: tests/run-tests.py --print-failures | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -409,6 +409,27 @@ jobs: | |||
| 409 | 409 | if: failure() | |
| 410 | 410 | run: tests/run-tests.py --print-failures | |
| 411 | 411 | ||
| 412 | + qemu_aarch64: | ||
| 413 | + runs-on: ubuntu-latest | ||
| 414 | + steps: | ||
| 415 | + - uses: actions/checkout@v7 | ||
| 416 | + - uses: actions/setup-python@v7 | ||
| 417 | + # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests. | ||
| 418 | + # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default. | ||
| 419 | + with: | ||
| 420 | + python-version: '3.11' | ||
| 421 | + - name: Install packages | ||
| 422 | + run: tools/ci.sh unix_qemu_aarch64_setup | ||
| 423 | + - name: Build | ||
| 424 | + run: tools/ci.sh unix_qemu_aarch64_build | ||
| 425 | + - name: Run main test suite | ||
| 426 | + run: tools/ci.sh unix_qemu_aarch64_run_tests | ||
| 427 | + - name: Run gcov coverage analysis | ||
| 428 | + run: tools/ci.sh unix_qemu_aarch64_run_coverage | ||
| 429 | + - name: Print failures | ||
| 430 | + if: failure() | ||
| 431 | + run: tests/run-tests.py --print-failures | ||
| 432 | + | ||
| 412 | 433 | sanitize_address: | |
| 413 | 434 | runs-on: ubuntu-latest | |
| 414 | 435 | steps: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -200,7 +200,7 @@ primarily for maintenance, development and testing: | |||
| 200 | 200 | to another microcontroller. | |
| 201 | 201 | ||
| 202 | 202 | - The [qemu](ports/qemu) port is a QEMU-based emulated target for Cortex-A, | |
| 203 | - Cortex-M, RISC-V 32-bit, RISC-V 64-bit, and PowerPC 64-bit architectures. | ||
| 203 | + Cortex-M, RISC-V 32-bit, RISC-V 64-bit, PowerPC 64-bit and AArch64 architectures. | ||
| 204 | 204 | ||
| 205 | 205 | The MicroPython cross-compiler, mpy-cross | |
| 206 | 206 | ----------------------------------------- | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,171 @@ | |||
| 1 | + .. _asm_aarch64: | ||
| 2 | + | ||
| 3 | + Inline assembler for AArch64 | ||
| 4 | + ============================ | ||
| 5 | + | ||
| 6 | + This document assumes some familiarity with assembly language programming | ||
| 7 | + and with the ARM 64-bit (AArch64/ARMv8-A) instruction set. For a detailed | ||
| 8 | + description of the instruction set consult the *Arm Architecture Reference | ||
| 9 | + Manual for A-profile architecture*. | ||
| 10 | + | ||
| 11 | + The inline assembler is enabled on AArch64 targets (for example the unix | ||
| 12 | + port running on a 64-bit ARM system, or the ``VIRT_AARCH64`` boards of the | ||
| 13 | + ``ports/qemu`` port) and is used via the ``@micropython.asm_aarch64`` | ||
| 14 | + decorator:: | ||
| 15 | + | ||
| 16 | + @micropython.asm_aarch64 | ||
| 17 | + def add1(x0) -> int: | ||
| 18 | + add(x0, x0, 1) | ||
| 19 | + | ||
| 20 | + print(add1(1)) # prints 2 | ||
| 21 | + | ||
| 22 | + Instructions are written as Python function calls; operands are passed as | ||
| 23 | + arguments. The syntax tries to be as close as possible to that defined in | ||
| 24 | + the ARM manual, converted to Python function calls. Because ``and`` is a | ||
| 25 | + Python keyword, the AND instruction is spelled ``and_``. | ||
| 26 | + | ||
| 27 | + Registers and calling convention | ||
| 28 | + -------------------------------- | ||
| 29 | + | ||
| 30 | + All 31 general purpose registers are available as ``x0``-``x30``, plus | ||
| 31 | + ``sp`` and ``lr`` (an alias for ``x30``). All instructions operate on 64-bit | ||
| 32 | + values (the ``x`` registers); the 32-bit ``w`` registers are not accessible | ||
| 33 | + from the inline assembler. | ||
| 34 | + | ||
| 35 | + A function may take up to four parameters, which must be named ``x0``, | ||
| 36 | + ``x1``, ``x2``, ``x3`` in sequence; the arguments passed by the caller are | ||
| 37 | + available in those registers. Unless another return type is annotated, the | ||
| 38 | + value in ``x0`` when control reaches the end of the function body is treated | ||
| 39 | + as a signed integer result. | ||
| 40 | + | ||
| 41 | + ``sp`` is only accepted as an operand of ``push`` and ``pop``; every other | ||
| 42 | + instruction expects ``x0``-``x30`` (or ``lr``). Adjust the stack with those | ||
| 43 | + two operations rather than with ``add``/``sub``. | ||
| 44 | + | ||
| 45 | + .. warning:: | ||
| 46 | + | ||
| 47 | + Do not use ``ret()`` to return from the assembly function itself. Leave | ||
| 48 | + the value in ``x0`` and let control fall off the end of the body, so that | ||
| 49 | + the automatically generated epilogue runs. A ``ret()`` at the top level | ||
| 50 | + skips that epilogue, which leaves the stack pointer 96 bytes too low and | ||
| 51 | + ``x19``-``x28`` unrestored, corrupting the caller. ``ret()`` is only for | ||
| 52 | + returning from a subroutine reached with ``bl()``, as in the example | ||
| 53 | + below. | ||
| 54 | + | ||
| 55 | + The function wrapper saves and restores all callee-saved registers | ||
| 56 | + (``x19``-``x28``) as well as the frame pointer and link register, so user | ||
| 57 | + assembly code may freely use any register. Note that the compiler may use | ||
| 58 | + ``x9``/``x10`` as scratch registers when materialising a large immediate | ||
| 59 | + for ``and_``/``eor``/``orr`` that cannot be encoded directly (see below); | ||
| 60 | + this never affects the operands of the instruction being assembled. | ||
| 61 | + | ||
| 62 | + Instructions | ||
| 63 | + ------------ | ||
| 64 | + | ||
| 65 | + The following subset of the AArch64 instruction set is supported. | ||
| 66 | + | ||
| 67 | + Arithmetic and logical | ||
| 68 | + ~~~~~~~~~~~~~~~~~~~~~~ | ||
| 69 | + | ||
| 70 | + * ``add(Rd, Rn, Rm)`` / ``add(Rd, Rn, imm)`` — ``Rd = Rn + Rm`` or ``Rd = Rn + imm`` | ||
| 71 | + * ``sub(Rd, Rn, Rm)`` / ``sub(Rd, Rn, imm)`` — ``Rd = Rn - Rm`` or ``Rd = Rn - imm`` | ||
| 72 | + * ``mul(Rd, Rn, Rm)`` — ``Rd = Rn * Rm`` (signed and unsigned, low 64 bits) | ||
| 73 | + * ``and_(Rd, Rn, Rm)`` / ``and_(Rd, Rn, imm)`` — bitwise AND | ||
| 74 | + * ``orr(Rd, Rn, Rm)`` / ``orr(Rd, Rn, imm)`` — bitwise OR | ||
| 75 | + * ``eor(Rd, Rn, Rm)`` / ``eor(Rd, Rn, imm)`` — bitwise exclusive OR | ||
| 76 | + * ``mvn(Rd, Rm)`` — bitwise NOT | ||
| 77 | + * ``cmp(Rn, Rm)`` / ``cmp(Rn, imm)`` — compare (sets the condition flags) | ||
| 78 | + * ``mov(Rd, Rn)`` / ``mov(Rd, imm)`` — move register or 64-bit immediate | ||
| 79 | + | ||
| 80 | + For ``add``/``sub``/``cmp`` the immediate must be a 12-bit value | ||
| 81 | + (``0``-``0xfff``), optionally shifted left by 12 bits (i.e. a multiple of | ||
| 82 | + 4096 up to ``0xfff000``). | ||
| 83 | + | ||
| 84 | + For ``and_``/``eor``/``orr`` any 64-bit immediate is accepted. Immediates | ||
| 85 | + that match the ARM "bitmask immediate" encoding (a rotated run of one bits | ||
| 86 | + replicated across the register, e.g. ``0xff``, ``0xf0``, ``0xffffffff``, | ||
| 87 | + ``~0xf``) are emitted as a single instruction; other values are | ||
| 88 | + materialised in a scratch register first. | ||
| 89 | + | ||
| 90 | + For ``mov`` any 64-bit immediate is accepted; the shortest ``MOVZ``/``MOVN``/ | ||
| 91 | + ``MOVK`` sequence is generated. | ||
| 92 | + | ||
| 93 | + Shifts | ||
| 94 | + ~~~~~~ | ||
| 95 | + | ||
| 96 | + * ``lsl(Rd, Rn, Rm)`` / ``lsl(Rd, Rn, imm)`` — logical shift left | ||
| 97 | + * ``lsr(Rd, Rn, Rm)`` / ``lsr(Rd, Rn, imm)`` — logical shift right | ||
| 98 | + * ``asr(Rd, Rn, Rm)`` / ``asr(Rd, Rn, imm)`` — arithmetic shift right | ||
| 99 | + | ||
| 100 | + The immediate shift amount must be in the range 0-63. | ||
| 101 | + | ||
| 102 | + Load and store | ||
| 103 | + ~~~~~~~~~~~~~~ | ||
| 104 | + | ||
| 105 | + * ``ldr(Rt, [Rn, off])`` — load 64-bit word; ``off`` must be a multiple of 8, in 0-32760 | ||
| 106 | + * ``ldrh(Rt, [Rn, off])`` — load 16-bit halfword (zero extend); ``off`` must be a multiple of 2, in 0-8190 | ||
| 107 | + * ``ldrb(Rt, [Rn, off])`` — load byte (zero extend); ``off`` in 0-4095 | ||
| 108 | + * ``str(Rt, [Rn, off])`` / ``strh(Rt, [Rn, off])`` / ``strb(Rt, [Rn, off])`` — the store equivalents | ||
| 109 | + | ||
| 110 | + The offset is a constant in bytes; unaligned offsets for ``ldr``/``str``/ | ||
| 111 | + ``ldrh``/``strh`` are a compile-time error. | ||
| 112 | + | ||
| 113 | + Branches and labels | ||
| 114 | + ~~~~~~~~~~~~~~~~~~~ | ||
| 115 | + | ||
| 116 | + * ``label(NAME)`` — define a label | ||
| 117 | + * ``b(label)`` — unconditional branch | ||
| 118 | + * ``bl(label)`` — branch with link (call); return with ``ret(lr)`` | ||
| 119 | + * ``b<cc>(label)`` — conditional branch, where ``<cc>`` is one of: | ||
| 120 | + ``eq``, ``ne``, ``cs``, ``cc``, ``mi``, ``pl``, ``vs``, ``vc``, ``hi``, | ||
| 121 | + ``ls``, ``ge``, ``lt``, ``gt``, ``le``. ``bhs`` and ``blo`` are accepted as | ||
| 122 | + aliases for ``bcs`` and ``bcc``. The condition code is written directly | ||
| 123 | + after the ``b`` with no separator, because ``b.eq`` is not a valid Python | ||
| 124 | + identifier. | ||
| 125 | + * ``ret(Rn)`` — return to the address in ``Rn`` (usually ``lr``) | ||
| 126 | + * ``nop()``, ``wfi()``, ``bkpt()`` — no operation, wait for interrupt, | ||
| 127 | + breakpoint (``BRK #0``) | ||
| 128 | + | ||
| 129 | + ``b`` and ``bl`` have a native range of ±128MB and are always a single | ||
| 130 | + instruction. ``b<cc>`` has a native range of only ±1MB, so a conditional | ||
| 131 | + branch that is forwards, or backwards beyond ±1MB, is relaxed automatically to | ||
| 132 | + a two-instruction sequence (an inverted ``b<cc>`` over an unconditional ``b``), | ||
| 133 | + which also gives it a ±128MB range. Because the relaxation is decided from | ||
| 134 | + the branch direction rather than from whether the label is known yet, the | ||
| 135 | + generated code has the same size in every compiler pass. | ||
| 136 | + | ||
| 137 | + Stack operations | ||
| 138 | + ~~~~~~~~~~~~~~~~ | ||
| 139 | + | ||
| 140 | + * ``push({Ra, Rb, ...})`` — store the listed registers on the stack | ||
| 141 | + (decrementing ``sp``; an odd number of registers is padded with a dummy | ||
| 142 | + slot to keep ``sp`` 16-byte aligned) | ||
| 143 | + * ``pop({Ra, Rb, ...})`` — the inverse of ``push`` | ||
| 144 | + | ||
| 145 | + Example:: | ||
| 146 | + | ||
| 147 | + @micropython.asm_aarch64 | ||
| 148 | + def call_helper(x0) -> int: | ||
| 149 | + push({lr}) | ||
| 150 | + bl(double) | ||
| 151 | + pop({lr}) | ||
| 152 | + ret(lr) | ||
| 153 | + label(double) | ||
| 154 | + add(x0, x0, x0) | ||
| 155 | + ret(lr) | ||
| 156 | + | ||
| 157 | + Limitations | ||
| 158 | + ----------- | ||
| 159 | + | ||
| 160 | + - Register-offset addressing (e.g. ``ldr(x0, [x1, x2])``) is not | ||
| 161 | + supported; only constant offsets. Pre-indexed (``[x1, #8]!``) and | ||
| 162 | + post-indexed (``[x1], #8``) forms cannot be written in Python at all. | ||
| 163 | + - ``push`` and ``pop`` round an odd number of registers up to an even number of | ||
| 164 | + stack slots, to keep ``sp`` 16-byte aligned. The padding slot is written | ||
| 165 | + with, and read back into, the zero register, so it never disturbs ``sp``. | ||
| 166 | + Matching ``push``/``pop`` lists therefore keep the stack balanced as long as | ||
| 167 | + they round to the same number of slots. | ||
| 168 | + - Floating point (SIMD/FP) registers and instructions are not supported. | ||
| 169 | + - There is currently no ``.mpy`` architecture ID for AArch64, so inline | ||
| 170 | + assembler functions cannot be frozen into ``.mpy`` files or loaded from | ||
| 171 | + them; they are compiled at runtime only. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,6 +30,7 @@ implementation and the best practices to use them. | |||
| 30 | 30 | manifest.rst | |
| 31 | 31 | packages.rst | |
| 32 | 32 | asm_thumb2_index.rst | |
| 33 | + asm_aarch64.rst | ||
| 33 | 34 | filesystem.rst | |
| 34 | 35 | romfs.rst | |
| 35 | 36 | unicode_support.rst | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,12 @@ | |||
| 1 | + // An implementation of sqrtf for AArch64 using hardware fsqrt instruction. | ||
| 2 | + | ||
| 3 | + #include <math.h> | ||
| 4 | + | ||
| 5 | + float sqrtf(float x) { | ||
| 6 | + float ret; | ||
| 7 | + __asm__ volatile ( | ||
| 8 | + "fsqrt %s0, %s1\n" | ||
| 9 | + : "=w" (ret) | ||
| 10 | + : "w" (x)); | ||
| 11 | + return ret; | ||
| 12 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,10 @@ | |||
| 1 | + // An implementation of sqrt for AArch64 using hardware fsqrt instruction. | ||
| 2 | + | ||
| 3 | + double sqrt(double x) { | ||
| 4 | + double ret; | ||
| 5 | + __asm__ volatile ( | ||
| 6 | + "fsqrt %d0, %d1\n" | ||
| 7 | + : "=w" (ret) | ||
| 8 | + : "w" (x)); | ||
| 9 | + return ret; | ||
| 10 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -47,6 +47,11 @@ MICROPY_HEAP_SIZE ?= 204800 | |||
| 47 | 47 | MICROPY_STACK_SIZE ?= 20480 | |
| 48 | 48 | FROZEN_MANIFEST ?= "require('unittest'); freeze('test-frzmpy', ('frozen_const.py',))" | |
| 49 | 49 | endif | |
| 50 | + ifeq ($(QEMU_ARCH),aarch64) | ||
| 51 | + MICROPY_HEAP_SIZE ?= 1048576 | ||
| 52 | + MICROPY_STACK_SIZE ?= 20480 | ||
| 53 | + FROZEN_MANIFEST ?= "require('unittest'); freeze('test-frzmpy', ('frozen_const.py',))" | ||
| 54 | + endif | ||
| 50 | 55 | ||
| 51 | 56 | MICROPY_FLOAT_IMPL ?= float | |
| 52 | 57 | ||
@@ -195,6 +200,31 @@ SRC_BOARD_O += mcu/ppc64/head.o | |||
| 195 | 200 | ||
| 196 | 201 | endif | |
| 197 | 202 | ||
| 203 | + ################################################################################ | ||
| 204 | + # AArch64 specific settings | ||
| 205 | + | ||
| 206 | + ifeq ($(QEMU_ARCH),aarch64) | ||
| 207 | + | ||
| 208 | + CROSS_COMPILE ?= aarch64-none-elf- | ||
| 209 | + | ||
| 210 | + LDFLAGS += -nostdlib | ||
| 211 | + LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) | ||
| 212 | + | ||
| 213 | + QEMU_ARGS += -cpu max -semihosting | ||
| 214 | + | ||
| 215 | + AFLAGS += -march=armv8-a | ||
| 216 | + CFLAGS += $(AFLAGS) -mstrict-align -fno-stack-protector -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 | ||
| 217 | + | ||
| 218 | + SRC_C += \ | ||
| 219 | + mcu/aarch64/errorhandler.c \ | ||
| 220 | + mcu/aarch64/startup.c \ | ||
| 221 | + mcu/aarch64/ticks.c \ | ||
| 222 | + shared/runtime/semihosting_aarch64.c \ | ||
| 223 | + | ||
| 224 | + SRC_BOARD_O += mcu/aarch64/entrypoint.o | ||
| 225 | + | ||
| 226 | + endif | ||
| 227 | + | ||
| 198 | 228 | ################################################################################ | |
| 199 | 229 | # Project specific settings and compiler/linker flags | |
| 200 | 230 | ||
@@ -300,15 +330,23 @@ SRC_C += \ | |||
| 300 | 330 | ifeq ($(MICROPY_FLOAT_IMPL),double) | |
| 301 | 331 | LIBM_SRC_C += $(SRC_LIB_LIBM_DBL_C) | |
| 302 | 332 | ifeq ($(SUPPORTS_HARDWARE_FP_DOUBLE),1) | |
| 333 | + ifeq ($(QEMU_ARCH),aarch64) | ||
| 334 | + LIBM_SRC_C += lib/libm_dbl/aarch64_sqrt.c | ||
| 335 | + else | ||
| 303 | 336 | LIBM_SRC_C += $(SRC_LIB_LIBM_DBL_SQRT_HW_C) | |
| 337 | + endif | ||
| 304 | 338 | else | |
| 305 | 339 | LIBM_SRC_C += $(SRC_LIB_LIBM_DBL_SQRT_SW_C) | |
| 306 | 340 | endif | |
| 307 | 341 | else | |
| 308 | 342 | ifeq ($(MICROPY_FLOAT_IMPL),float) | |
| 309 | 343 | LIBM_SRC_C += $(SRC_LIB_LIBM_C) | |
| 310 | 344 | ifeq ($(SUPPORTS_HARDWARE_FP_SINGLE),1) | |
| 345 | + ifeq ($(QEMU_ARCH),aarch64) | ||
| 346 | + LIBM_SRC_C += lib/libm/aarch64_sqrtf.c | ||
| 347 | + else | ||
| 311 | 348 | LIBM_SRC_C += $(SRC_LIB_LIBM_SQRT_HW_C) | |
| 349 | + endif | ||
| 312 | 350 | else | |
| 313 | 351 | LIBM_SRC_C += $(SRC_LIB_LIBM_SQRT_SW_C) | |
| 314 | 352 | endif | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,8 @@ | |||
| 1 | 1 | MicroPython port to qemu | |
| 2 | 2 | ======================== | |
| 3 | 3 | ||
| 4 | - This is experimental, community-supported port for Cortex-M and RISC-V | ||
| 5 | - RV32IMC/RV64IMC emulation as provided by QEMU (http://qemu.org). | ||
| 4 | + This is experimental, community-supported port for Cortex-M, RISC-V | ||
| 5 | + RV32IMC/RV64IMC, and AArch64 emulation as provided by QEMU (http://qemu.org). | ||
| 6 | 6 | ||
| 7 | 7 | The purposes of this port are to enable: | |
| 8 | 8 | ||
@@ -26,6 +26,13 @@ Dependencies | |||
| 26 | 26 | For ARM-based boards the build requires a bare-metal ARM toolchain, such as | |
| 27 | 27 | `arm-none-eabi-gcc`. | |
| 28 | 28 | ||
| 29 | + ### AArch64 | ||
| 30 | + | ||
| 31 | + For AArch64-based boards the build requires a bare-metal AArch64 toolchain, such as | ||
| 32 | + `aarch64-none-elf-gcc`. The QEMU `virt` machine is used with `-cpu max`, which | ||
| 33 | + enables all CPU features supported by the version of QEMU being used; the | ||
| 34 | + firmware itself is built for the base ARMv8-A instruction set. | ||
| 35 | + | ||
| 29 | 36 | ### RISC-V 32 | |
| 30 | 37 | ||
| 31 | 38 | For RV32-based boards the build requires a bare metal RISC-V toolchain with GCC 10 | |
@@ -101,16 +108,18 @@ different board pass the `BOARD` argument to `make`, for example: | |||
| 101 | 108 | ||
| 102 | 109 | Available boards are: | |
| 103 | 110 | ||
| 104 | - | Name for `BOARD=` | Architecture | Corresponding qemu board | | ||
| 105 | - | ----------------- | ------------ | ------------------------ | | ||
| 106 | - | `MICROBIT` | `arm` | `microbit` | | ||
| 107 | - | `MPS2_AN385` | `arm` | `mps2-an385` | | ||
| 108 | - | `MPS2_AN500` | `arm` | `mps2-an500` | | ||
| 109 | - | `NETDUINO2` | `arm` | `netduino2` | | ||
| 110 | - | `POWERNV9` | `ppc64` | `powernv9` | | ||
| 111 | - | `SABRELITE` | `arm` | `sabrelite` | | ||
| 112 | - | `VIRT_RV32` | `riscv32` | `virt` | | ||
| 113 | - | `VIRT_RV64` | `riscv64` | `virt` | | ||
| 111 | + | Name for `BOARD=` | Architecture | Corresponding qemu board | | ||
| 112 | + | -------------------- | ------------ | ------------------------ | | ||
| 113 | + | `MICROBIT` | `arm` | `microbit` | | ||
| 114 | + | `MPS2_AN385` | `arm` | `mps2-an385` | | ||
| 115 | + | `MPS2_AN500` | `arm` | `mps2-an500` | | ||
| 116 | + | `NETDUINO2` | `arm` | `netduino2` | | ||
| 117 | + | `POWERNV9` | `ppc64` | `powernv9` | | ||
| 118 | + | `SABRELITE` | `arm` | `sabrelite` | | ||
| 119 | + | `VIRT_AARCH64` | `aarch64` | `virt` | | ||
| 120 | + | `VIRT_AARCH64_FLOAT` | `aarch64` | `virt` | | ||
| 121 | + | `VIRT_RV32` | `riscv32` | `virt` | | ||
| 122 | + | `VIRT_RV64` | `riscv64` | `virt` | | ||
| 114 | 123 | ||
| 115 | 124 | Running | |
| 116 | 125 | ------- | |
@@ -120,7 +129,8 @@ To access the REPL directly use: | |||
| 120 | 129 | ||
| 121 | 130 | $ make repl | |
| 122 | 131 | ||
| 123 | - This will start `qemu-system-arm` (or `qemu-system-riscv32`) with the UART | ||
| 132 | + This will start `qemu-system-arm` (or `qemu-system-riscv32`, or | ||
| 133 | + `qemu-system-aarch64`) with the UART | ||
| 124 | 134 | redirected to stdio. It's also possible to redirect the UART to a pty device | |
| 125 | 135 | using: | |
| 126 | 136 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments