diff --git a/criticalup.toml b/criticalup.toml index 79c8c62..46cba1a 100644 --- a/criticalup.toml +++ b/criticalup.toml @@ -4,7 +4,7 @@ manifest-version = 1 [products.ferrocene] -release = "pre-rolling-2024-05-24" +release = "beta-25.02-2025-01-25" packages = [ "rustc-${rustc-host}", "rust-std-${rustc-host}", diff --git a/qemu-cortex-r5-app/.cargo/config.toml b/qemu-cortex-r5-app/.cargo/config.toml index 29a7196..4446f4a 100644 --- a/qemu-cortex-r5-app/.cargo/config.toml +++ b/qemu-cortex-r5-app/.cargo/config.toml @@ -2,10 +2,6 @@ # SPDX-License-Identifier: MIT OR Apache-2.0 [target.armv7r-none-eabihf] -rustflags = [ - "-Clink-arg=-Tlinker.ld", - "-Ctarget-cpu=cortex-r5", -] runner = "qemu-system-arm -machine versatileab -cpu cortex-r5f -semihosting -nographic -kernel" [build] diff --git a/qemu-cortex-r5-app/Cargo.lock b/qemu-cortex-r5-app/Cargo.lock index 5c776cc..682054e 100644 --- a/qemu-cortex-r5-app/Cargo.lock +++ b/qemu-cortex-r5-app/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -11,11 +11,22 @@ dependencies = [ "memchr", ] +[[package]] +name = "arbitrary-int" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825297538d77367557b912770ca3083f778a196054b3ee63b22673c4a3cae0a5" + +[[package]] +name = "arm-targets" +version = "0.1.0" +source = "git+http://github.com/ferrous-systems/cortex-r#132e8c921da9d0f96562f8025062e278d5959570" + [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -34,11 +45,23 @@ dependencies = [ "which", ] +[[package]] +name = "bitbybit" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d317eeca82e7d88d606419a430590d83552bdceb899cb29904f63d694344b7fc" +dependencies = [ + "arbitrary-int", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "bitflags" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "byte-strings" @@ -62,9 +85,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.6" +version = "1.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "755717a7de9ec452bf7f3f1a3099085deabd7f2962b861dae91ecd7a365903d2" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -92,11 +118,31 @@ dependencies = [ "libloading", ] +[[package]] +name = "cortex-r" +version = "0.1.0" +source = "git+http://github.com/ferrous-systems/cortex-r#132e8c921da9d0f96562f8025062e278d5959570" +dependencies = [ + "arbitrary-int", + "arm-targets", + "bitbybit", +] + +[[package]] +name = "cortex-r-rt" +version = "0.1.0" +source = "git+http://github.com/ferrous-systems/cortex-r#132e8c921da9d0f96562f8025062e278d5959570" +dependencies = [ + "arm-targets", + "cortex-r", + "semihosting", +] + [[package]] name = "critical-section" -version = "1.1.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "either" @@ -116,9 +162,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", "windows-sys", @@ -126,15 +172,15 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ "windows-sys", ] @@ -162,15 +208,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets", @@ -184,15 +230,15 @@ checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "log" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "memchr" @@ -218,21 +264,21 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "portable-atomic" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "prettyplease" -version = "0.2.20" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" dependencies = [ "proc-macro2", "syn", @@ -240,9 +286,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -251,8 +297,11 @@ dependencies = [ name = "qemu-cortex-r5-app" version = "0.1.0" dependencies = [ + "arm-targets", "byte-strings", "cc", + "cortex-r", + "cortex-r-rt", "embedded-alloc", "static_cell", "threadx-sys", @@ -260,18 +309,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -281,9 +330,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -292,9 +341,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc-hash" @@ -304,9 +353,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags", "errno", @@ -315,6 +364,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "semihosting" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d00d0037a88d97379cc27d815a471350923a1dc5880d5325c49695edcdc0d37" + [[package]] name = "shlex" version = "1.3.0" @@ -332,9 +387,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -350,9 +405,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" [[package]] name = "which" @@ -368,9 +423,9 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] diff --git a/qemu-cortex-r5-app/Cargo.toml b/qemu-cortex-r5-app/Cargo.toml index 766c864..3a2fb04 100644 --- a/qemu-cortex-r5-app/Cargo.toml +++ b/qemu-cortex-r5-app/Cargo.toml @@ -14,9 +14,12 @@ embedded-alloc = "0.5.1" static_cell = "2.1.0" threadx-sys = { path = "../threadx-sys" } byte-strings = "0.3.1" +cortex-r-rt = { git = "http://github.com/ferrous-systems/cortex-r", version = "0.1.0" } +cortex-r = { git = "http://github.com/ferrous-systems/cortex-r", version = "0.1.0" } [build-dependencies] cc = "1.1.6" +arm-targets = { git = "http://github.com/ferrous-systems/cortex-r", version = "0.1.0" } [profile.release] codegen-units = 1 diff --git a/qemu-cortex-r5-app/build.rs b/qemu-cortex-r5-app/build.rs index ac2585d..fde0d70 100644 --- a/qemu-cortex-r5-app/build.rs +++ b/qemu-cortex-r5-app/build.rs @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2023 Ferrous Systems // SPDX-License-Identifier: MIT OR Apache-2.0 -use std::{env, error::Error, fs, path::PathBuf}; +use std::{env, error::Error, io::Write, path::PathBuf}; static TX_PORT_FILES: &[&str] = &[ "tx_thread_context_restore.S", @@ -212,13 +212,20 @@ static TX_COMMON_FILES: &[&str] = &[ ]; fn main() -> Result<(), Box> { - let out_dir = PathBuf::from(env::var("OUT_DIR")?); let crate_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?); - // put memory layout (linker script) in the linker search path - fs::copy("linker.ld", out_dir.join("linker.ld"))?; - println!("cargo:rustc-link-search={}", out_dir.display()); - println!("cargo:rerun-if-changed=linker.ld"); + arm_targets::process(); + + match std::env::var("TARGET").expect("TARGET not set").as_str() { + "armv8r-none-eabihf" => { + write("memory.x", include_bytes!("mps3-an536.ld")); + } + _ => { + write("memory.x", include_bytes!("versatileab.ld")); + } + } + // Use the cortex-m-rt linker script + println!("cargo:rustc-link-arg=-Tlink.x"); // Build our ThreadX static library let tx_common_dir = crate_dir.join("../threadx/common/src"); @@ -234,12 +241,17 @@ fn main() -> Result<(), Box> { .files(TX_COMMON_FILES.iter().map(|&s| tx_common_dir.join(s))) .compile("threadx"); - cc::Build::new() - .include(&tx_common_inc) - .include(&tx_port_inc) - .flag("-g") - .file("src/tx_initialize_low_level.S") - .compile("startup"); - Ok(()) } + +fn write(file: &str, contents: &[u8]) { + // Put linker file in our output directory and ensure it's on the + // linker search path. + let out = &std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap()); + std::fs::File::create(out.join(file)) + .unwrap() + .write_all(contents) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + println!("cargo:rerun-if-changed={}", file); +} diff --git a/qemu-cortex-r5-app/linker.ld b/qemu-cortex-r5-app/linker.ld deleted file mode 100644 index f7fa5ac..0000000 --- a/qemu-cortex-r5-app/linker.ld +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Linker script for running ThreadX/Rust on QEMU's Versatile AB with a Cortex-R5 - * - * SPDX-FileCopyrightText: Copyright (c) 2024 Ferrous Systems - * SPDX-License-Identifier: MIT OR Apache-2.0 -*/ - -MEMORY { - RAM : ORIGIN = 0, LENGTH = 0x1000000 -} - -ENTRY(_start) -SECTIONS { - .startup ORIGIN(RAM) : { - *(.text.startup) - } > RAM - .text : { *(.text .text*) } > RAM - .rodata : { *(.rodata .rodata*) } > RAM - .data : { *(.data .data*) } > RAM - .bss : { *(.bss .bss* COMMON) } > RAM - /DISCARD/ : { - *(.note .note*) - } - - . = ALIGN(16); - .stack : { - _stack_bottom = ABSOLUTE(.) ; - /* Allocate room for stack. This must be big enough for the IRQ, FIQ, and - SYS stack if nested interrupts are enabled. */ - . = ALIGN(8) ; - . += 0x100000; - _sp = . - 16 ; - _stack_top = ABSOLUTE(.) ; - } > RAM - - _end = .; __end__ = . ; -} diff --git a/qemu-cortex-r5-app/mps3-an536.ld b/qemu-cortex-r5-app/mps3-an536.ld new file mode 100644 index 0000000..3d16e04 --- /dev/null +++ b/qemu-cortex-r5-app/mps3-an536.ld @@ -0,0 +1,18 @@ +/* +Memory configuration for the MPS3-AN536 machine. + +See https://github.com/qemu/qemu/blob/master/hw/arm/mps3r.c + +SPDX-FileCopyrightText: Copyright (c) 2025 Ferrous Systems +SPDX-License-Identifier: MIT OR Apache-2.0 +*/ + +MEMORY { + QSPI : ORIGIN = 0x08000000, LENGTH = 8M + DDR : ORIGIN = 0x20000000, LENGTH = 128M +} + +REGION_ALIAS("CODE", QSPI); +REGION_ALIAS("DATA", DDR); + +PROVIDE(_end = __euninit); diff --git a/qemu-cortex-r5-app/src/lib.rs b/qemu-cortex-r5-app/src/lib.rs index 4bccf1c..7229524 100644 --- a/qemu-cortex-r5-app/src/lib.rs +++ b/qemu-cortex-r5-app/src/lib.rs @@ -1,6 +1,6 @@ //! Common code for the ThreadX/Rust on Cortex-R5 demo -// SPDX-FileCopyrightText: Copyright (c) 2024 Ferrous Systems +// SPDX-FileCopyrightText: Copyright (c) 2025 Ferrous Systems // SPDX-License-Identifier: MIT OR Apache-2.0 #![no_std] @@ -9,62 +9,43 @@ pub mod pl011_uart; pub mod pl190_vic; pub mod sp804_timer; +use cortex_r_rt as _; + core::arch::global_asm!( r#" - -.section .text.startup -.global _start -.global _vectors -.code 32 -.align 0 -// Work around https://github.com/rust-lang/rust/issues/127269 -.fpu vfp3-d16 - -_vectors: - LDR pc, STARTUP @ Reset goes to startup function 0x00 - LDR pc, UNDEFINED @ Undefined handler 0x04 - LDR pc, SWI @ Software interrupt handler 0x08 - LDR pc, PREFETCH @ Prefetch exception handler 0x0C - LDR pc, ABORT @ Abort exception handler 0x10 - LDR pc, RESERVED @ Reserved exception handler 0x14 - LDR pc, IRQ @ IRQ interrupt handler 0x18 - LDR pc, FIQ @ FIQ interrupt handler 0x1C - -STARTUP: - .word _start @ Reset goes to C startup function -UNDEFINED: - .word __tx_undefined @ Undefined handler -SWI: - .word __tx_swi_interrupt @ Software interrupt handler -PREFETCH: - .word __tx_prefetch_handler @ Prefetch exception handler -ABORT: - .word __tx_abort_handler @ Abort exception handler -RESERVED: - .word __tx_reserved_handler @ Reserved exception handler -IRQ: - .word __tx_irq_handler @ IRQ interrupt handler -FIQ: - .word __tx_fiq_handler @ FIQ interrupt handler - -_start: - // Set stack pointer - ldr sp, =_stack_top - - // Allow VFP coprocessor access - mrc p15, 0, r0, c1, c0, 2 - orr r0, r0, #0xF00000 - mcr p15, 0, r0, c1, c0, 2 - - // Enable VFP - mov r0, #0x40000000 - vmsr fpexc, r0 - - // Jump to application - bl kmain - - // In case the application returns, loop forever - b . - -"# +.global kmain + +SVC_MODE = 0xD3 @ Disable IRQ/FIQ SVC mode + +kmain: +@ +@ /* Switch to SVC mode, which is what ThreadX expects us to be in (cortex-m-rt leaves us in SYS, not SVC) */ +@ + MOV r0, #SVC_MODE @ Build SVC mode CPSR + MSR CPSR, r0 @ Enter SVC mode + MOV r1, sp @ Get pointer to stack area +@ +@ /* Save the system stack pointer. */ +@ _tx_thread_system_stack_ptr = (VOID_PTR) (sp); +@ + LDR r2, =_tx_thread_system_stack_ptr @ Pickup stack pointer + STR r1, [r2] @ Save the system stack +@ +@ /* Save the first available memory address. */ +@ _tx_initialize_unused_memory = (VOID_PTR) _end; +@ + LDR r1, =_end @ Get end of non-initialized RAM area + LDR r2, =_tx_initialize_unused_memory @ Pickup unused memory ptr address + ADD r1, r1, #8 @ Increment to next free word + STR r1, [r2] @ Save first free memory address +@ + bl rust_main + B . + +.global _tx_initialize_low_level + +_tx_initialize_low_level: + bx lr + + "# ); diff --git a/qemu-cortex-r5-app/src/main.rs b/qemu-cortex-r5-app/src/main.rs index 416f21f..e70dcc9 100644 --- a/qemu-cortex-r5-app/src/main.rs +++ b/qemu-cortex-r5-app/src/main.rs @@ -234,7 +234,7 @@ extern "C" fn my_thread(value: u32) { /// /// It is called by the start-up code in `lib.rs`. #[no_mangle] -pub extern "C" fn kmain() { +pub extern "C" fn rust_main() { // Create a UART let mut uart0 = unsafe { Uart::new_uart0() }; _ = writeln!( @@ -268,9 +268,9 @@ pub extern "C" fn kmain() { panic!("Kernel exited"); } -/// Called from the main interrupt handler +/// Called from the asm interrupt handler in cortex-r-rt #[no_mangle] -unsafe extern "C" fn handle_interrupt() { +unsafe extern "C" fn _irq_handler() { extern "C" { fn _tx_timer_interrupt(); } diff --git a/qemu-cortex-r5-app/src/tx_initialize_low_level.S b/qemu-cortex-r5-app/src/tx_initialize_low_level.S deleted file mode 100644 index ca36af6..0000000 --- a/qemu-cortex-r5-app/src/tx_initialize_low_level.S +++ /dev/null @@ -1,343 +0,0 @@ -@/*************************************************************************** -@ * Copyright (c) 2024 Microsoft Corporation -@ * -@ * This program and the accompanying materials are made available under the -@ * terms of the MIT License which is available at -@ * https://opensource.org/licenses/MIT. -@ * -@ * SPDX-License-Identifier: MIT -@ **************************************************************************/ -@ -@ -@/**************************************************************************/ -@/**************************************************************************/ -@/** */ -@/** ThreadX Component */ -@/** */ -@/** Initialize */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ -@#define TX_SOURCE_CODE -@ -@ -@/* Include necessary system files. */ -@ -@#include "tx_api.h" -@#include "tx_initialize.h" -@#include "tx_thread.h" -@#include "tx_timer.h" - - .arm - -SVC_MODE = 0xD3 @ Disable IRQ/FIQ SVC mode -IRQ_MODE = 0xD2 @ Disable IRQ/FIQ IRQ mode -FIQ_MODE = 0xD1 @ Disable IRQ/FIQ FIQ mode -SYS_MODE = 0xDF @ Disable IRQ/FIQ SYS mode -FIQ_STACK_SIZE = 512 @ FIQ stack size -IRQ_STACK_SIZE = 1024 @ IRQ stack size -SYS_STACK_SIZE = 1024 @ System stack size -@ -@ - .global _tx_thread_system_stack_ptr - .global _tx_initialize_unused_memory - .global _tx_thread_context_save - .global _tx_thread_context_restore - .global _tx_timer_interrupt - .global _end - .global _sp - .global _stack_bottom - -@ -@ -@/* Define the 16-bit Thumb mode veneer for _tx_initialize_low_level for -@ applications calling this function from to 16-bit Thumb mode. */ -@ - .text - .align 2 - .thumb - .global $_tx_initialize_low_level - .type $_tx_initialize_low_level,function -$_tx_initialize_low_level: - BX pc @ Switch to 32-bit mode - NOP @ - .arm - STMFD sp!, {lr} @ Save return address - BL _tx_initialize_low_level @ Call _tx_initialize_low_level function - LDMFD sp!, {lr} @ Recover saved return address - BX lr @ Return to 16-bit caller -@ -@ - .text - .align 2 -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_initialize_low_level Cortex-R5/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is responsible for any low-level processor */ -@/* initialization, including setting up interrupt vectors, setting */ -@/* up a periodic timer interrupt source, saving the system stack */ -@/* pointer for use in ISR processing later, and finding the first */ -@/* available RAM memory address for tx_application_define. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* None */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* _tx_initialize_kernel_enter ThreadX entry function */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_initialize_low_level(VOID) -@{ - .global _tx_initialize_low_level - .type _tx_initialize_low_level,function -_tx_initialize_low_level: -@ -@ /* We must be in SVC mode at this point! */ -@ -@ /* Setup various stack pointers. */ -@ - LDR r1, =_sp @ Get pointer to stack area - -#ifdef TX_ENABLE_IRQ_NESTING -@ -@ /* Setup the system mode stack for nested interrupt support */ -@ - LDR r2, =SYS_STACK_SIZE @ Pickup stack size - MOV r3, #SYS_MODE @ Build SYS mode CPSR - MSR CPSR_c, r3 @ Enter SYS mode - SUB r1, r1, #1 @ Backup 1 byte - BIC r1, r1, #7 @ Ensure 8-byte alignment - MOV sp, r1 @ Setup SYS stack pointer - SUB r1, r1, r2 @ Calculate start of next stack -#endif - - LDR r2, =FIQ_STACK_SIZE @ Pickup stack size - MOV r0, #FIQ_MODE @ Build FIQ mode CPSR - MSR CPSR, r0 @ Enter FIQ mode - SUB r1, r1, #1 @ Backup 1 byte - BIC r1, r1, #7 @ Ensure 8-byte alignment - MOV sp, r1 @ Setup FIQ stack pointer - SUB r1, r1, r2 @ Calculate start of next stack - LDR r2, =IRQ_STACK_SIZE @ Pickup IRQ stack size - MOV r0, #IRQ_MODE @ Build IRQ mode CPSR - MSR CPSR, r0 @ Enter IRQ mode - SUB r1, r1, #1 @ Backup 1 byte - BIC r1, r1, #7 @ Ensure 8-byte alignment - MOV sp, r1 @ Setup IRQ stack pointer - SUB r3, r1, r2 @ Calculate end of IRQ stack - MOV r0, #SVC_MODE @ Build SVC mode CPSR - MSR CPSR, r0 @ Enter SVC mode - LDR r2, =_stack_bottom @ Pickup stack bottom - CMP r3, r2 @ Compare the current stack end with the bottom -_stack_error_loop: - BLT _stack_error_loop @ If the IRQ stack exceeds the stack bottom, just sit here! -@ -@ /* Save the system stack pointer. */ -@ _tx_thread_system_stack_ptr = (VOID_PTR) (sp); -@ - LDR r2, =_tx_thread_system_stack_ptr @ Pickup stack pointer - STR r1, [r2] @ Save the system stack -@ -@ /* Save the first available memory address. */ -@ _tx_initialize_unused_memory = (VOID_PTR) _end; -@ - LDR r1, =_end @ Get end of non-initialized RAM area - LDR r2, =_tx_initialize_unused_memory @ Pickup unused memory ptr address - ADD r1, r1, #8 @ Increment to next free word - STR r1, [r2] @ Save first free memory address -@ -@ /* Setup Timer for periodic interrupts. */ -@ -@ /* Done, return to caller. */ -@ -#ifdef __THUMB_INTERWORK - BX lr @ Return to caller -#else - MOV pc, lr @ Return to caller -#endif -@} -@ -@ -@/* Define shells for each of the interrupt vectors. */ -@ - .global __tx_undefined -__tx_undefined: - B __tx_undefined @ Undefined handler -@ - .global __tx_swi_interrupt -__tx_swi_interrupt: - B __tx_swi_interrupt @ Software interrupt handler -@ - .global __tx_prefetch_handler -__tx_prefetch_handler: - B __tx_prefetch_handler @ Prefetch exception handler -@ - .global __tx_abort_handler -__tx_abort_handler: - B __tx_abort_handler @ Abort exception handler -@ - .global __tx_reserved_handler -__tx_reserved_handler: - B __tx_reserved_handler @ Reserved exception handler -@ - .global __tx_irq_handler - .global __tx_irq_processing_return -__tx_irq_handler: -@ -@ /* Jump to context save to save system context. */ - B _tx_thread_context_save -__tx_irq_processing_return: -@ -@ /* At this point execution is still in the IRQ mode. The CPSR, point of -@ interrupt, and all C scratch registers are available for use. In -@ addition, IRQ interrupts may be re-enabled - with certain restrictions - -@ if nested IRQ interrupts are desired. Interrupts may be re-enabled over -@ small code sequences where lr is saved before enabling interrupts and -@ restored after interrupts are again disabled. */ -@ -@ /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start -@ from IRQ mode with interrupts disabled. This routine switches to the -@ system mode and returns with IRQ interrupts enabled. -@ -@ NOTE: It is very important to ensure all IRQ interrupts are cleared -@ prior to enabling nested IRQ interrupts. */ -#ifdef TX_ENABLE_IRQ_NESTING - BL _tx_thread_irq_nesting_start -#endif -@ - /* Use Rust to handle the interrupt */ - BL handle_interrupt -@ -@ -@ /* If interrupt nesting was started earlier, the end of interrupt nesting -@ service must be called before returning to _tx_thread_context_restore. -@ This routine returns in processing in IRQ mode with interrupts disabled. */ -#ifdef TX_ENABLE_IRQ_NESTING - BL _tx_thread_irq_nesting_end -#endif -@ -@ /* Jump to context restore to restore system context. */ - B _tx_thread_context_restore -@ -@ -@ /* This is an example of a vectored IRQ handler. */ -@ -@ .global __tx_example_vectored_irq_handler -@__tx_example_vectored_irq_handler: -@ -@ -@ /* Save initial context and call context save to prepare for -@ vectored ISR execution. */ -@ -@ STMDB sp!, {r0-r3} @ Save some scratch registers -@ MRS r0, SPSR @ Pickup saved SPSR -@ SUB lr, lr, #4 @ Adjust point of interrupt -@ STMDB sp!, {r0, r10, r12, lr} @ Store other scratch registers -@ BL _tx_thread_vectored_context_save @ Vectored context save -@ -@ /* At this point execution is still in the IRQ mode. The CPSR, point of -@ interrupt, and all C scratch registers are available for use. In -@ addition, IRQ interrupts may be re-enabled - with certain restrictions - -@ if nested IRQ interrupts are desired. Interrupts may be re-enabled over -@ small code sequences where lr is saved before enabling interrupts and -@ restored after interrupts are again disabled. */ -@ -@ -@ /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start -@ from IRQ mode with interrupts disabled. This routine switches to the -@ system mode and returns with IRQ interrupts enabled. -@ -@ NOTE: It is very important to ensure all IRQ interrupts are cleared -@ prior to enabling nested IRQ interrupts. */ -@#ifdef TX_ENABLE_IRQ_NESTING -@ BL _tx_thread_irq_nesting_start -@#endif -@ -@ /* Application IRQ handlers can be called here! */ -@ -@ /* If interrupt nesting was started earlier, the end of interrupt nesting -@ service must be called before returning to _tx_thread_context_restore. -@ This routine returns in processing in IRQ mode with interrupts disabled. */ -@#ifdef TX_ENABLE_IRQ_NESTING -@ BL _tx_thread_irq_nesting_end -@#endif -@ -@ /* Jump to context restore to restore system context. */ -@ B _tx_thread_context_restore -@ -@ -#ifdef TX_ENABLE_FIQ_SUPPORT - .global __tx_fiq_handler - .global __tx_fiq_processing_return -__tx_fiq_handler: -@ -@ /* Jump to fiq context save to save system context. */ - B _tx_thread_fiq_context_save -__tx_fiq_processing_return: -@ -@ /* At this point execution is still in the FIQ mode. The CPSR, point of -@ interrupt, and all C scratch registers are available for use. */ -@ -@ /* Interrupt nesting is allowed after calling _tx_thread_fiq_nesting_start -@ from FIQ mode with interrupts disabled. This routine switches to the -@ system mode and returns with FIQ interrupts enabled. -@ -@ NOTE: It is very important to ensure all FIQ interrupts are cleared -@ prior to enabling nested FIQ interrupts. */ -#ifdef TX_ENABLE_FIQ_NESTING - BL _tx_thread_fiq_nesting_start -#endif -@ -@ /* Application FIQ handlers can be called here! */ -@ -@ /* If interrupt nesting was started earlier, the end of interrupt nesting -@ service must be called before returning to _tx_thread_fiq_context_restore. */ -#ifdef TX_ENABLE_FIQ_NESTING - BL _tx_thread_fiq_nesting_end -#endif -@ -@ /* Jump to fiq context restore to restore system context. */ - B _tx_thread_fiq_context_restore -@ -@ -#else - .global __tx_fiq_handler -__tx_fiq_handler: - B __tx_fiq_handler @ FIQ interrupt handler -#endif -@ -@ -BUILD_OPTIONS: - .word _tx_build_options @ Reference to bring in -VERSION_ID: - .word _tx_version_id @ Reference to bring in - - - diff --git a/qemu-cortex-r5-app/versatileab.ld b/qemu-cortex-r5-app/versatileab.ld new file mode 100644 index 0000000..5a685fe --- /dev/null +++ b/qemu-cortex-r5-app/versatileab.ld @@ -0,0 +1,18 @@ +/* +Memory configuration for the Arm Versatile Peripheral Board. + +See https://github.com/qemu/qemu/blob/master/hw/arm/versatilepb.c + +SPDX-FileCopyrightText: Copyright (c) 2025 Ferrous Systems +SPDX-License-Identifier: MIT OR Apache-2.0 + +*/ + +MEMORY { + SDRAM : ORIGIN = 0, LENGTH = 128M +} + +REGION_ALIAS("CODE", SDRAM); +REGION_ALIAS("DATA", SDRAM); + +PROVIDE(_end = __euninit);