forked from M-Labs/zynq-rs
llvm_asm -> asm
This commit is contained in:
parent
5ef3016554
commit
2c70fdbeab
|
@ -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},
|
||||
|
|
|
@ -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", lateout(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, out("r1") _);
|
||||
}
|
||||
|
||||
/// Exiting IRQ
|
||||
#[inline]
|
||||
pub unsafe fn exit_irq() {
|
||||
llvm_asm!("
|
||||
asm!("
|
||||
mrs r0, SPSR
|
||||
msr CPSR, r0
|
||||
" ::: "r0");
|
||||
", out("r0") _);
|
||||
}
|
||||
|
|
|
@ -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<T>(slice: &[T]) -> impl Iterator<Item = usize> {
|
|||
#[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<T>(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<T>(object: &T) {
|
||||
dmb();
|
||||
|
@ -239,7 +239,7 @@ pub fn dcc_slice<T>(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.
|
||||
|
|
|
@ -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");
|
||||
", out("r1") _);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
||||
|
|
|
@ -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, lateout(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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use r0::zero_bss;
|
||||
use core::ptr::write_volatile;
|
||||
use core::arch::asm;
|
||||
use libregister::{
|
||||
VolatileCell,
|
||||
RegisterR, RegisterRW,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue