diff --git a/experiments/src/main.rs b/experiments/src/main.rs index 0f62d2f..6e57391 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -1,12 +1,12 @@ #![no_std] #![no_main] -#![feature(const_in_array_repeat_expressions)] #![feature(naked_functions)] #![feature(asm)] extern crate alloc; use alloc::collections::BTreeMap; +use core::arch::asm; use libasync::{ delay, smoltcp::{Sockets, TcpStream}, diff --git a/libcortex_a9/src/asm.rs b/libcortex_a9/src/asm.rs index 2243c9e..1541894 100644 --- a/libcortex_a9/src/asm.rs +++ b/libcortex_a9/src/asm.rs @@ -1,59 +1,60 @@ +use core::arch::asm; + /// The classic no-op #[inline] pub fn nop() { - unsafe { llvm_asm!("nop" :::: "volatile") } + unsafe { asm!("nop") } } /// Wait For Event #[inline] pub fn wfe() { - unsafe { llvm_asm!("wfe" :::: "volatile") } + unsafe { asm!("wfe") } } /// Send Event #[inline] pub fn sev() { - unsafe { llvm_asm!("sev" :::: "volatile") } + unsafe { asm!("sev") } } /// Data Memory Barrier #[inline] pub fn dmb() { - unsafe { llvm_asm!("dmb" :::: "volatile") } + unsafe { asm!("dmb") } } /// Data Synchronization Barrier #[inline] pub fn dsb() { - unsafe { llvm_asm!("dsb" :::: "volatile") } + unsafe { asm!("dsb") } } /// Instruction Synchronization Barrier #[inline] pub fn isb() { - unsafe { llvm_asm!("isb" :::: "volatile") } + unsafe { asm!("isb") } } /// Enable FIQ #[inline] pub unsafe fn enable_fiq() { - llvm_asm!("cpsie f":::: "volatile"); + asm!("cpsie f"); } /// Enable IRQ #[inline] pub unsafe fn enable_irq() { - llvm_asm!("cpsie i":::: "volatile"); + asm!("cpsie i"); } /// Disable IRQ, return if IRQ was originally enabled. #[inline] pub unsafe fn enter_critical() -> bool { let mut cpsr: u32; - llvm_asm!( - "mrs $0, cpsr - cpsid i" - : "=r"(cpsr) ::: "volatile"); + asm!( + "mrs {}, cpsr + cpsid i", out(reg) cpsr); (cpsr & (1 << 7)) == 0 } @@ -65,18 +66,18 @@ pub unsafe fn exit_critical(enable: bool) { } else { 0 }; - llvm_asm!( + asm!( "mrs r1, cpsr - bic r1, r1, $0 + bic r1, r1, {} msr cpsr_c, r1" - :: "r"(mask) : "r1"); + , in(reg) mask); } /// Exiting IRQ #[inline] pub unsafe fn exit_irq() { - llvm_asm!(" + asm!(" mrs r0, SPSR msr CPSR, r0 - " ::: "r0"); + "); } diff --git a/libcortex_a9/src/cache.rs b/libcortex_a9/src/cache.rs index 054e2d1..24531e3 100644 --- a/libcortex_a9/src/cache.rs +++ b/libcortex_a9/src/cache.rs @@ -1,11 +1,12 @@ use super::asm::{dmb, dsb}; use super::l2c::*; +use core::arch::asm; /// Invalidate TLBs #[inline(always)] pub fn tlbiall() { unsafe { - llvm_asm!("mcr p15, 0, $0, c8, c7, 0" :: "r" (0) :: "volatile"); + asm!("mcr p15, 0, {}, c8, c7, 0", in(reg) 0); } } @@ -13,7 +14,7 @@ pub fn tlbiall() { #[inline(always)] pub fn iciallu() { unsafe { - llvm_asm!("mcr p15, 0, $0, c7, c5, 0" :: "r" (0) :: "volatile"); + asm!("mcr p15, 0, {}, c7, c5, 0", in(reg) 0); } } @@ -21,7 +22,7 @@ pub fn iciallu() { #[inline(always)] pub fn bpiall() { unsafe { - llvm_asm!("mcr p15, 0, $0, c7, c5, 6" :: "r" (0) :: "volatile"); + asm!("mcr p15, 0, {}, c7, c5, 6", in(reg) 0); } } @@ -29,7 +30,7 @@ pub fn bpiall() { #[inline(always)] pub fn dccsw(setway: u32) { unsafe { - llvm_asm!("mcr p15, 0, $0, c7, c10, 2" :: "r" (setway) :: "volatile"); + asm!("mcr p15, 0, {}, c7, c10, 2", in(reg) setway); } } @@ -41,7 +42,7 @@ pub fn dcisw(setway: u32) { // also see example code (for DCCISW, but DCISW will be // analogous) "Example code for cache maintenance operations" // on pages B2-1286 and B2-1287. - llvm_asm!("mcr p15, 0, $0, c7, c6, 2" :: "r" (setway) :: "volatile"); + asm!("mcr p15, 0, {}, c7, c6, 2", in(reg) setway); } } @@ -49,7 +50,7 @@ pub fn dcisw(setway: u32) { #[inline(always)] pub fn dccisw(setway: u32) { unsafe { - llvm_asm!("mcr p15, 0, $0, c7, c14, 2" :: "r" (setway) :: "volatile"); + asm!("mcr p15, 0, {}, c7, c14, 2", in(reg) setway); } } @@ -69,7 +70,7 @@ pub fn dciall_l1() { // select L1 data cache unsafe { - llvm_asm!("mcr p15, 2, $0, c0, c0, 0" :: "r" (0) :: "volatile"); + asm!("mcr p15, 2, {}, c0, c0, 0", in(reg) 0); } // Invalidate entire D-Cache by iterating every set and every way @@ -104,7 +105,7 @@ pub fn dcciall_l1() { // select L1 data cache unsafe { - llvm_asm!("mcr p15, 2, $0, c0, c0, 0" :: "r" (0) :: "volatile"); + asm!("mcr p15, 2, {}, c0, c0, 0", in(reg) 0); } // Invalidate entire D-Cache by iterating every set and every way @@ -156,7 +157,7 @@ fn slice_cache_line_addrs(slice: &[T]) -> impl Iterator { #[inline(always)] pub fn dccimvac(addr: usize) { unsafe { - llvm_asm!("mcr p15, 0, $0, c7, c14, 1" :: "r" (addr) :: "volatile"); + asm!("mcr p15, 0, {}, c7, c14, 1", in(reg) addr); } } @@ -198,10 +199,9 @@ pub fn dcci_slice(slice: &[T]) { #[inline(always)] pub fn dccmvac(addr: usize) { unsafe { - llvm_asm!("mcr p15, 0, $0, c7, c10, 1" :: "r" (addr) :: "volatile"); + asm!("mcr p15, 0, {}, c7, c10, 1", in(reg) addr); } } - /// Data cache clean for an object. pub fn dcc(object: &T) { dmb(); @@ -239,7 +239,7 @@ pub fn dcc_slice(slice: &[T]) { /// affecting more data than intended. #[inline(always)] pub unsafe fn dcimvac(addr: usize) { - llvm_asm!("mcr p15, 0, $0, c7, c6, 1" :: "r" (addr) :: "volatile"); + asm!("mcr p15, 0, {}, c7, c6, 1", in(reg) addr); } /// Data cache clean and invalidate for an object. diff --git a/libcortex_a9/src/fpu.rs b/libcortex_a9/src/fpu.rs index 2a987be..c36d07c 100644 --- a/libcortex_a9/src/fpu.rs +++ b/libcortex_a9/src/fpu.rs @@ -1,7 +1,8 @@ +use core::arch::asm; /// Enable FPU in the current core. pub fn enable_fpu() { unsafe { - llvm_asm!(" + asm!(" mrc p15, 0, r1, c1, c0, 2 orr r1, r1, (0b1111<<20) mcr p15, 0, r1, c1, c0, 2 @@ -9,6 +10,6 @@ pub fn enable_fpu() { vmrs r1, fpexc orr r1, r1, (1<<30) vmsr fpexc, r1 - ":::"r1"); + "); } } diff --git a/libcortex_a9/src/lib.rs b/libcortex_a9/src/lib.rs index 2f341d3..646aa1a 100644 --- a/libcortex_a9/src/lib.rs +++ b/libcortex_a9/src/lib.rs @@ -1,7 +1,7 @@ #![no_std] -#![feature(llvm_asm, global_asm)] #![feature(never_type)] -#![feature(const_fn)] +#![feature(asm, global_asm)] +#![feature(const_fn_trait_bound)] extern crate alloc; @@ -17,6 +17,7 @@ pub mod sync_channel; mod uncached; pub use fpu::enable_fpu; pub use uncached::UncachedSlice; +use core::arch::global_asm; global_asm!(include_str!("exceptions.s")); diff --git a/libcortex_a9/src/regs.rs b/libcortex_a9/src/regs.rs index 2b73cfe..87becf5 100644 --- a/libcortex_a9/src/regs.rs +++ b/libcortex_a9/src/regs.rs @@ -2,6 +2,7 @@ use libregister::{ register_bit, register_bits, RegisterR, RegisterW, RegisterRW, }; +use core::arch::asm; macro_rules! def_reg_r { ($name:tt, $type: ty, $asm_instr:tt) => { @@ -11,7 +12,7 @@ macro_rules! def_reg_r { #[inline] fn read(&self) -> Self::R { let mut value: u32; - unsafe { llvm_asm!($asm_instr : "=r" (value) ::: "volatile") } + unsafe { asm!($asm_instr, out(reg) value) } value.into() } } @@ -26,7 +27,7 @@ macro_rules! def_reg_w { #[inline] fn write(&mut self, value: Self::W) { let value: u32 = value.into(); - unsafe { llvm_asm!($asm_instr :: "r" (value) :: "volatile") } + unsafe { asm!($asm_instr, in(reg) value) } } #[inline] @@ -71,29 +72,29 @@ macro_rules! wrap_reg { /// Stack Pointer pub struct SP; -def_reg_r!(SP, u32, "mov $0, sp"); -def_reg_w!(SP, u32, "mov sp, $0"); +def_reg_r!(SP, u32, "mov {}, sp"); +def_reg_w!(SP, u32, "mov sp, {}"); /// Link register (function call return address) pub struct LR; -def_reg_r!(LR, u32, "mov $0, lr"); -def_reg_w!(LR, u32, "mov lr, $0"); +def_reg_r!(LR, u32, "mov {}, lr"); +def_reg_w!(LR, u32, "mov lr, {}"); pub struct VBAR; -def_reg_r!(VBAR, u32, "mrc p15, 0, $0, c12, c0, 0"); -def_reg_w!(VBAR, u32, "mcr p15, 0, $0, c12, c0, 0"); +def_reg_r!(VBAR, u32, "mrc p15, 0, {}, c12, c0, 0"); +def_reg_w!(VBAR, u32, "mcr p15, 0, {}, c12, c0, 0"); pub struct MVBAR; -def_reg_r!(MVBAR, u32, "mrc p15, 0, $0, c12, c0, 1"); -def_reg_w!(MVBAR, u32, "mcr p15, 0, $0, c12, c0, 1"); +def_reg_r!(MVBAR, u32, "mrc p15, 0, {}, c12, c0, 1"); +def_reg_w!(MVBAR, u32, "mcr p15, 0, {}, c12, c0, 1"); pub struct HVBAR; -def_reg_r!(HVBAR, u32, "mrc p15, 4, $0, c12, c0, 0"); -def_reg_w!(HVBAR, u32, "mcr p15, 4, $0, c12, c0, 0"); +def_reg_r!(HVBAR, u32, "mrc p15, 4, {}, c12, c0, 0"); +def_reg_w!(HVBAR, u32, "mcr p15, 4, {}, c12, c0, 0"); /// Multiprocess Affinity Register pub struct MPIDR; -def_reg_r!(MPIDR, mpidr::Read, "mrc p15, 0, $0, c0, c0, 5"); +def_reg_r!(MPIDR, mpidr::Read, "mrc p15, 0, {}, c0, c0, 5"); wrap_reg!(mpidr); register_bits!(mpidr, /// CPU core index @@ -106,15 +107,15 @@ register_bit!(mpidr, u, 30); pub struct DFAR; -def_reg_r!(DFAR, u32, "mrc p15, 0, $0, c6, c0, 0"); +def_reg_r!(DFAR, u32, "mrc p15, 0, {}, c6, c0, 0"); pub struct DFSR; -def_reg_r!(DFSR, u32, "mrc p15, 0, $0, c5, c0, 0"); +def_reg_r!(DFSR, u32, "mrc p15, 0, {}, c5, c0, 0"); pub struct SCTLR; wrap_reg!(sctlr); -def_reg_r!(SCTLR, sctlr::Read, "mrc p15, 0, $0, c1, c0, 0"); -def_reg_w!(SCTLR, sctlr::Write, "mcr p15, 0, $0, c1, c0, 0"); +def_reg_r!(SCTLR, sctlr::Read, "mrc p15, 0, {}, c1, c0, 0"); +def_reg_w!(SCTLR, sctlr::Write, "mcr p15, 0, {}, c1, c0, 0"); register_bit!(sctlr, /// Enables MMU m, 0); @@ -147,8 +148,8 @@ register_bit!(sctlr, /// Auxiliary Control Register pub struct ACTLR; wrap_reg!(actlr); -def_reg_r!(ACTLR, actlr::Read, "mrc p15, 0, $0, c1, c0, 1"); -def_reg_w!(ACTLR, actlr::Write, "mcr p15, 0, $0, c1, c0, 1"); +def_reg_r!(ACTLR, actlr::Read, "mrc p15, 0, {}, c1, c0, 1"); +def_reg_w!(ACTLR, actlr::Write, "mcr p15, 0, {}, c1, c0, 1"); // SMP bit register_bit!(actlr, parity_on, 9); register_bit!(actlr, alloc_one_way, 8); @@ -183,17 +184,17 @@ impl ACTLR { /// Domain Access Control Register pub struct DACR; -def_reg_r!(DACR, u32, "mrc p15, 0, $0, c3, c0, 0"); -def_reg_w!(DACR, u32, "mcr p15, 0, $0, c3, c0, 0"); +def_reg_r!(DACR, u32, "mrc p15, 0, {}, c3, c0, 0"); +def_reg_w!(DACR, u32, "mcr p15, 0, {}, c3, c0, 0"); /// Translation Table Base Register 0 pub struct TTBR0; /// Translation Table Base Register 1 pub struct TTBR1; -def_reg_r!(TTBR0, ttbr::Read, "mrc p15, 0, $0, c2, c0, 0"); -def_reg_w!(TTBR0, ttbr::Write, "mcr p15, 0, $0, c2, c0, 0"); -def_reg_r!(TTBR1, ttbr::Read, "mrc p15, 0, $0, c2, c0, 1"); -def_reg_w!(TTBR1, ttbr::Write, "mcr p15, 0, $0, c2, c0, 1"); +def_reg_r!(TTBR0, ttbr::Read, "mrc p15, 0, {}, c2, c0, 0"); +def_reg_w!(TTBR0, ttbr::Write, "mcr p15, 0, {}, c2, c0, 0"); +def_reg_r!(TTBR1, ttbr::Read, "mrc p15, 0, {}, c2, c0, 1"); +def_reg_w!(TTBR1, ttbr::Write, "mcr p15, 0, {}, c2, c0, 1"); wrap_reg!(ttbr); register_bits!(ttbr, table_base, u32, 14, 31); register_bit!(ttbr, irgn0, 6); diff --git a/libcortex_a9/src/sync_channel.rs b/libcortex_a9/src/sync_channel.rs index e21df16..a672f6e 100644 --- a/libcortex_a9/src/sync_channel.rs +++ b/libcortex_a9/src/sync_channel.rs @@ -178,7 +178,8 @@ macro_rules! sync_channel { { use core::sync::atomic::{AtomicUsize, AtomicPtr}; use $crate::sync_channel::{Sender, Receiver}; - static LIST: [AtomicPtr<$t>; $cap + 1] = [AtomicPtr::new(core::ptr::null_mut()); $cap + 1]; + const cnst_ptr: AtomicPtr<$t> = AtomicPtr::new(core::ptr::null_mut()); + static LIST: [AtomicPtr<$t>; $cap + 1] = [cnst_ptr; $cap + 1]; static WRITE: AtomicUsize = AtomicUsize::new(0); static READ: AtomicUsize = AtomicUsize::new(0); (Sender::new(&LIST, &WRITE, &READ), Receiver::new(&LIST, &WRITE, &READ)) diff --git a/libsupport_zynq/src/boot.rs b/libsupport_zynq/src/boot.rs index f542c89..3b52934 100644 --- a/libsupport_zynq/src/boot.rs +++ b/libsupport_zynq/src/boot.rs @@ -1,5 +1,6 @@ use r0::zero_bss; use core::ptr::write_volatile; +use core::arch::asm; use libregister::{ VolatileCell, RegisterR, RegisterRW, diff --git a/libsupport_zynq/src/exception_vectors.rs b/libsupport_zynq/src/exception_vectors.rs index f4e94d5..57d8fbd 100644 --- a/libsupport_zynq/src/exception_vectors.rs +++ b/libsupport_zynq/src/exception_vectors.rs @@ -1,6 +1,7 @@ use libregister::{RegisterR, RegisterW}; use libcortex_a9::{regs::{DFSR, MPIDR, VBAR}, interrupt_handler}; use libboard_zynq::{println, stdio}; +use core::arch::asm; pub fn set_vector_table(base_addr: u32){ VBAR.write(base_addr);