1
0
Fork 0

llvm_asm to asm macro

This commit is contained in:
Simon Renblad 2024-07-24 16:00:52 +08:00
parent 85dc1cc258
commit 7c09846855
9 changed files with 63 additions and 60 deletions

View File

@ -1,11 +1,11 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(naked_functions)] #![feature(naked_functions)]
#![feature(asm)]
extern crate alloc; extern crate alloc;
use alloc::collections::BTreeMap; use alloc::collections::BTreeMap;
use core::arch::asm;
use libasync::{ use libasync::{
delay, delay,
smoltcp::{Sockets, TcpStream}, smoltcp::{Sockets, TcpStream},

View File

@ -1,59 +1,60 @@
use core::arch::asm;
/// The classic no-op /// The classic no-op
#[inline] #[inline]
pub fn nop() { pub fn nop() {
unsafe { llvm_asm!("nop" :::: "volatile") } unsafe { asm!("nop") }
} }
/// Wait For Event /// Wait For Event
#[inline] #[inline]
pub fn wfe() { pub fn wfe() {
unsafe { llvm_asm!("wfe" :::: "volatile") } unsafe { asm!("wfe") }
} }
/// Send Event /// Send Event
#[inline] #[inline]
pub fn sev() { pub fn sev() {
unsafe { llvm_asm!("sev" :::: "volatile") } unsafe { asm!("sev") }
} }
/// Data Memory Barrier /// Data Memory Barrier
#[inline] #[inline]
pub fn dmb() { pub fn dmb() {
unsafe { llvm_asm!("dmb" :::: "volatile") } unsafe { asm!("dmb") }
} }
/// Data Synchronization Barrier /// Data Synchronization Barrier
#[inline] #[inline]
pub fn dsb() { pub fn dsb() {
unsafe { llvm_asm!("dsb" :::: "volatile") } unsafe { asm!("dsb") }
} }
/// Instruction Synchronization Barrier /// Instruction Synchronization Barrier
#[inline] #[inline]
pub fn isb() { pub fn isb() {
unsafe { llvm_asm!("isb" :::: "volatile") } unsafe { asm!("isb") }
} }
/// Enable FIQ /// Enable FIQ
#[inline] #[inline]
pub unsafe fn enable_fiq() { pub unsafe fn enable_fiq() {
llvm_asm!("cpsie f":::: "volatile"); asm!("cpsie f");
} }
/// Enable IRQ /// Enable IRQ
#[inline] #[inline]
pub unsafe fn enable_irq() { pub unsafe fn enable_irq() {
llvm_asm!("cpsie i":::: "volatile"); asm!("cpsie i");
} }
/// Disable IRQ, return if IRQ was originally enabled. /// Disable IRQ, return if IRQ was originally enabled.
#[inline] #[inline]
pub unsafe fn enter_critical() -> bool { pub unsafe fn enter_critical() -> bool {
let mut cpsr: u32; let mut cpsr: u32;
llvm_asm!( asm!(
"mrs $0, cpsr "mrs {}, cpsr
cpsid i" cpsid i", out(reg) cpsr);
: "=r"(cpsr) ::: "volatile");
(cpsr & (1 << 7)) == 0 (cpsr & (1 << 7)) == 0
} }
@ -65,18 +66,18 @@ pub unsafe fn exit_critical(enable: bool) {
} else { } else {
0 0
}; };
llvm_asm!( asm!(
"mrs r1, cpsr "mrs r1, cpsr
bic r1, r1, $0 bic r1, r1, {}
msr cpsr_c, r1" msr cpsr_c, r1"
:: "r"(mask) : "r1"); , in(reg) mask);
} }
/// Exiting IRQ /// Exiting IRQ
#[inline] #[inline]
pub unsafe fn exit_irq() { pub unsafe fn exit_irq() {
llvm_asm!(" asm!("
mrs r0, SPSR mrs r0, SPSR
msr CPSR, r0 msr CPSR, r0
" ::: "r0"); ");
} }

View File

@ -1,11 +1,12 @@
use super::asm::{dmb, dsb}; use super::asm::{dmb, dsb};
use super::l2c::*; use super::l2c::*;
use core::arch::asm;
/// Invalidate TLBs /// Invalidate TLBs
#[inline(always)] #[inline(always)]
pub fn tlbiall() { pub fn tlbiall() {
unsafe { 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)] #[inline(always)]
pub fn iciallu() { pub fn iciallu() {
unsafe { 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)] #[inline(always)]
pub fn bpiall() { pub fn bpiall() {
unsafe { 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)] #[inline(always)]
pub fn dccsw(setway: u32) { pub fn dccsw(setway: u32) {
unsafe { 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 // also see example code (for DCCISW, but DCISW will be
// analogous) "Example code for cache maintenance operations" // analogous) "Example code for cache maintenance operations"
// on pages B2-1286 and B2-1287. // 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)] #[inline(always)]
pub fn dccisw(setway: u32) { pub fn dccisw(setway: u32) {
unsafe { 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 // select L1 data cache
unsafe { 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 // Invalidate entire D-Cache by iterating every set and every way
@ -104,7 +105,7 @@ pub fn dcciall_l1() {
// select L1 data cache // select L1 data cache
unsafe { 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 // Invalidate entire D-Cache by iterating every set and every way
@ -156,7 +157,7 @@ fn slice_cache_line_addrs<T>(slice: &[T]) -> impl Iterator<Item = usize> {
#[inline(always)] #[inline(always)]
pub fn dccimvac(addr: usize) { pub fn dccimvac(addr: usize) {
unsafe { 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<T>(slice: &[T]) {
#[inline(always)] #[inline(always)]
pub fn dccmvac(addr: usize) { pub fn dccmvac(addr: usize) {
unsafe { 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. /// Data cache clean for an object.
pub fn dcc<T>(object: &T) { pub fn dcc<T>(object: &T) {
dmb(); dmb();
@ -239,7 +239,7 @@ pub fn dcc_slice<T>(slice: &[T]) {
/// affecting more data than intended. /// affecting more data than intended.
#[inline(always)] #[inline(always)]
pub unsafe fn dcimvac(addr: usize) { 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. /// Data cache clean and invalidate for an object.

View File

@ -1,7 +1,8 @@
use core::arch::asm;
/// Enable FPU in the current core. /// Enable FPU in the current core.
pub fn enable_fpu() { pub fn enable_fpu() {
unsafe { unsafe {
llvm_asm!(" asm!("
mrc p15, 0, r1, c1, c0, 2 mrc p15, 0, r1, c1, c0, 2
orr r1, r1, (0b1111<<20) orr r1, r1, (0b1111<<20)
mcr p15, 0, r1, c1, c0, 2 mcr p15, 0, r1, c1, c0, 2
@ -9,6 +10,6 @@ pub fn enable_fpu() {
vmrs r1, fpexc vmrs r1, fpexc
orr r1, r1, (1<<30) orr r1, r1, (1<<30)
vmsr fpexc, r1 vmsr fpexc, r1
":::"r1"); ");
} }
} }

View File

@ -1,7 +1,5 @@
#![no_std] #![no_std]
#![feature(llvm_asm, global_asm)]
#![feature(never_type)] #![feature(never_type)]
#![feature(const_fn_trait_bound)]
extern crate alloc; extern crate alloc;
@ -17,6 +15,7 @@ pub mod sync_channel;
mod uncached; mod uncached;
pub use fpu::enable_fpu; pub use fpu::enable_fpu;
pub use uncached::UncachedSlice; pub use uncached::UncachedSlice;
use core::arch::global_asm;
global_asm!(include_str!("exceptions.s")); global_asm!(include_str!("exceptions.s"));

View File

@ -2,6 +2,7 @@ use libregister::{
register_bit, register_bits, register_bit, register_bits,
RegisterR, RegisterW, RegisterRW, RegisterR, RegisterW, RegisterRW,
}; };
use core::arch::asm;
macro_rules! def_reg_r { macro_rules! def_reg_r {
($name:tt, $type: ty, $asm_instr:tt) => { ($name:tt, $type: ty, $asm_instr:tt) => {
@ -11,7 +12,7 @@ macro_rules! def_reg_r {
#[inline] #[inline]
fn read(&self) -> Self::R { fn read(&self) -> Self::R {
let mut value: u32; let mut value: u32;
unsafe { llvm_asm!($asm_instr : "=r" (value) ::: "volatile") } unsafe { asm!($asm_instr, out(reg) value) }
value.into() value.into()
} }
} }
@ -26,7 +27,7 @@ macro_rules! def_reg_w {
#[inline] #[inline]
fn write(&mut self, value: Self::W) { fn write(&mut self, value: Self::W) {
let value: u32 = value.into(); let value: u32 = value.into();
unsafe { llvm_asm!($asm_instr :: "r" (value) :: "volatile") } unsafe { asm!($asm_instr, in(reg) value) }
} }
#[inline] #[inline]
@ -71,29 +72,29 @@ macro_rules! wrap_reg {
/// Stack Pointer /// Stack Pointer
pub struct SP; pub struct SP;
def_reg_r!(SP, u32, "mov $0, sp"); def_reg_r!(SP, u32, "mov {}, sp");
def_reg_w!(SP, u32, "mov sp, $0"); def_reg_w!(SP, u32, "mov sp, {}");
/// Link register (function call return address) /// Link register (function call return address)
pub struct LR; pub struct LR;
def_reg_r!(LR, u32, "mov $0, lr"); def_reg_r!(LR, u32, "mov {}, lr");
def_reg_w!(LR, u32, "mov lr, $0"); def_reg_w!(LR, u32, "mov lr, {}");
pub struct VBAR; pub struct VBAR;
def_reg_r!(VBAR, u32, "mrc 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, $0, c12, c0, 0"); def_reg_w!(VBAR, u32, "mcr p15, 0, {}, c12, c0, 0");
pub struct MVBAR; pub struct MVBAR;
def_reg_r!(MVBAR, u32, "mrc 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, $0, c12, c0, 1"); def_reg_w!(MVBAR, u32, "mcr p15, 0, {}, c12, c0, 1");
pub struct HVBAR; pub struct HVBAR;
def_reg_r!(HVBAR, u32, "mrc 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, $0, c12, c0, 0"); def_reg_w!(HVBAR, u32, "mcr p15, 4, {}, c12, c0, 0");
/// Multiprocess Affinity Register /// Multiprocess Affinity Register
pub struct MPIDR; 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); wrap_reg!(mpidr);
register_bits!(mpidr, register_bits!(mpidr,
/// CPU core index /// CPU core index
@ -106,15 +107,15 @@ register_bit!(mpidr,
u, 30); u, 30);
pub struct DFAR; 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; 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; pub struct SCTLR;
wrap_reg!(sctlr); wrap_reg!(sctlr);
def_reg_r!(SCTLR, sctlr::Read, "mrc 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, $0, c1, c0, 0"); def_reg_w!(SCTLR, sctlr::Write, "mcr p15, 0, {}, c1, c0, 0");
register_bit!(sctlr, register_bit!(sctlr,
/// Enables MMU /// Enables MMU
m, 0); m, 0);
@ -147,8 +148,8 @@ register_bit!(sctlr,
/// Auxiliary Control Register /// Auxiliary Control Register
pub struct ACTLR; pub struct ACTLR;
wrap_reg!(actlr); wrap_reg!(actlr);
def_reg_r!(ACTLR, actlr::Read, "mrc 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, $0, c1, c0, 1"); def_reg_w!(ACTLR, actlr::Write, "mcr p15, 0, {}, c1, c0, 1");
// SMP bit // SMP bit
register_bit!(actlr, parity_on, 9); register_bit!(actlr, parity_on, 9);
register_bit!(actlr, alloc_one_way, 8); register_bit!(actlr, alloc_one_way, 8);
@ -183,17 +184,17 @@ impl ACTLR {
/// Domain Access Control Register /// Domain Access Control Register
pub struct DACR; pub struct DACR;
def_reg_r!(DACR, u32, "mrc 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, $0, c3, c0, 0"); def_reg_w!(DACR, u32, "mcr p15, 0, {}, c3, c0, 0");
/// Translation Table Base Register 0 /// Translation Table Base Register 0
pub struct TTBR0; pub struct TTBR0;
/// Translation Table Base Register 1 /// Translation Table Base Register 1
pub struct TTBR1; pub struct TTBR1;
def_reg_r!(TTBR0, ttbr::Read, "mrc p15, 0, $0, c2, c0, 0"); def_reg_r!(TTBR0, ttbr::Read, "mrc p15, 0, {}, c2, c0, 0");
def_reg_w!(TTBR0, ttbr::Write, "mcr p15, 0, $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, $0, c2, c0, 1"); def_reg_r!(TTBR1, ttbr::Read, "mrc p15, 0, {}, c2, c0, 1");
def_reg_w!(TTBR1, ttbr::Write, "mcr p15, 0, $0, c2, c0, 1"); def_reg_w!(TTBR1, ttbr::Write, "mcr p15, 0, {}, c2, c0, 1");
wrap_reg!(ttbr); wrap_reg!(ttbr);
register_bits!(ttbr, table_base, u32, 14, 31); register_bits!(ttbr, table_base, u32, 14, 31);
register_bit!(ttbr, irgn0, 6); register_bit!(ttbr, irgn0, 6);

View File

@ -1,5 +1,6 @@
use r0::zero_bss; use r0::zero_bss;
use core::ptr::write_volatile; use core::ptr::write_volatile;
use core::arch::asm;
use libregister::{ use libregister::{
VolatileCell, VolatileCell,
RegisterR, RegisterRW, RegisterR, RegisterRW,

View File

@ -1,6 +1,7 @@
use libregister::{RegisterR, RegisterW}; use libregister::{RegisterR, RegisterW};
use libcortex_a9::{regs::{DFSR, MPIDR, VBAR}, interrupt_handler}; use libcortex_a9::{regs::{DFSR, MPIDR, VBAR}, interrupt_handler};
use libboard_zynq::{println, stdio}; use libboard_zynq::{println, stdio};
use core::arch::asm;
pub fn set_vector_table(base_addr: u32){ pub fn set_vector_table(base_addr: u32){
VBAR.write(base_addr); VBAR.write(base_addr);

View File

@ -3,7 +3,6 @@
#![feature(alloc_error_handler)] #![feature(alloc_error_handler)]
#![feature(panic_info_message)] #![feature(panic_info_message)]
#![feature(naked_functions)] #![feature(naked_functions)]
#![feature(asm)]
pub extern crate alloc; pub extern crate alloc;
pub extern crate compiler_builtins; pub extern crate compiler_builtins;