Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

21 changed files with 132 additions and 140 deletions

View File

@ -1,6 +1,7 @@
[target.armv7-none-eabihf]
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "target-feature=a9,armv7-a,neon",
"-C", "target-cpu=cortex-a9",
]

11
Cargo.lock generated
View File

@ -34,9 +34,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "compiler_builtins"
version = "0.1.108"
version = "0.1.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68bc55329711cd719c2687bb147bc06211b0521f97ef398280108ccb23227e9"
checksum = "20b1438ef42c655665a8ab2c1c6d605a305f031d38d9be689ddfef41a20f3aa2"
[[package]]
name = "core_io"
@ -84,6 +84,7 @@ dependencies = [
"embedded-hal",
"libcortex_a9",
"nb 1.0.0",
"pin-utils",
"smoltcp",
]
@ -180,6 +181,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "r0"
version = "1.0.0"

View File

@ -4,7 +4,7 @@
"emit-debug-gdb-scripts": false,
"env": "",
"executables": true,
"features": "+v7,+vfp3,-d32,+thumb2,+neon,+a9,+armv7-a",
"features": "+v7,+vfp3,-d32,+thumb2,-neon",
"is-builtin": false,
"linker": "rust-lld",
"linker-flavor": "ld.lld",

View File

@ -1,9 +1,9 @@
#![no_std]
#![no_main]
#![allow(incomplete_features)]
#![feature(naked_functions)]
#![feature(asm)]
#![feature(inline_const)]
#![feature(strict_provenance)]
#![feature(raw_ref_op)]
extern crate alloc;
@ -73,7 +73,7 @@ interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, {
if id.0 == 0 {
gic.end_interrupt(id);
asm::exit_irq();
SP.write((&raw mut __stack1_start).addr() as u32);
SP.write(&mut __stack1_start as *mut _ as u32);
asm::enable_irq();
CORE1_RESTART.store(false, Ordering::Relaxed);
notify_spin_lock();

6
flake.lock generated
View File

@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1739206421,
"narHash": "sha256-PwQASeL2cGVmrtQYlrBur0U20Xy07uSWVnFup2PHnDs=",
"lastModified": 1736867362,
"narHash": "sha256-i/UJ5I7HoqmFMwZEH6vAvBxOrjjOJNU739lnZnhUln8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "44534bc021b85c8d78e465021e21f33b856e2540",
"rev": "9c6b49aeac36e2ed73a8c472f1546f6d9cf1addc",
"type": "github"
},
"original": {

View File

@ -11,7 +11,7 @@
let
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import rust-overlay) crosspkgs-overlay ]; };
rust = pkgs.rust-bin.nightly."2024-04-06".default.override {
rust = pkgs.rust-bin.nightly."2021-09-01".default.override {
extensions = [ "rust-src" ];
targets = [ ];
};
@ -95,6 +95,10 @@
dontFixup = true;
};
cargo-xbuild = pkgs.cargo-xbuild.overrideAttrs(oa: {
postPatch = "substituteInPlace src/sysroot.rs --replace 2021 2018";
});
build-crate = name: crate: features: rustPlatform.buildRustPackage rec {
name = "${crate}";
@ -109,8 +113,7 @@
};
};
nativeBuildInputs = [ pkgs.cargo-xbuild pkgs.llvmPackages_18.clang-unwrapped ];
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_13.clang-unwrapped ];
buildPhase = ''
export XARGO_RUST_SRC="${rust}/lib/rustlib/src/rust/library"
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
@ -149,7 +152,7 @@
) "mkdir $out\n" targets);
in rec {
packages.x86_64-linux = {
inherit szl mkbootimage;
inherit cargo-xbuild szl mkbootimage;
zc706-fsbl = fsbl { board = "zc706"; };
} // allTargetCrates ;
@ -161,12 +164,12 @@
name = "zynq-rs-dev-shell";
buildInputs = [
rust
pkgs.cargo-xbuild
cargo-xbuild
mkbootimage
pkgs.openocd pkgs.gdb
pkgs.openssh pkgs.rsync
pkgs.llvmPackages_18.clang-unwrapped
pkgs.llvmPackages_13.clang-unwrapped
(pkgs.python3.withPackages(ps: [ ps.pyftdi ]))
];
};

View File

@ -7,6 +7,7 @@ edition = "2018"
[dependencies]
#futures = { version = "0.3", default-features = false }
pin-utils = "0.1.0-alpha.4"
embedded-hal = "0.2"
nb = "1.0"
libcortex_a9 = { path = "../libcortex_a9" }

View File

@ -1,12 +1,14 @@
use alloc::{boxed::Box, vec::Vec};
use core::{
cell::{RefCell, Cell},
cell::{RefCell, UnsafeCell},
future::Future,
mem::MaybeUninit,
pin::{pin, Pin},
pin::Pin,
sync::atomic::{AtomicBool, Ordering},
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};
use alloc::{boxed::Box, vec::Vec};
//use futures::future::FutureExt;
use pin_utils::pin_mut;
// NOTE `*const ()` is &AtomicBool
static VTABLE: RawWakerVTable = {
@ -37,7 +39,7 @@ fn wrap_waker(ready: &AtomicBool) -> Waker {
/// This is a singleton
pub struct Executor {
// Entered block_on() already?
in_block_on: Cell<bool>,
in_block_on: RefCell<bool>,
/// Tasks reside on the heap, so that we just queue pointers. They
/// must also be pinned in memory because our RawWaker is a pointer
@ -49,7 +51,7 @@ impl Executor {
/// Creates a new instance of the executor
pub fn new() -> Self {
Self {
in_block_on: Cell::new(false),
in_block_on: RefCell::new(false),
tasks: RefCell::new(Vec::new()),
}
}
@ -59,12 +61,15 @@ impl Executor {
// below has to become more complex. It's also likely that the
// application will only call `block_on` once on an infinite task
// (`Future<Output = !>`)
if self.in_block_on.get() {
panic!("nested `block_on`");
{
let mut in_block_on = self.in_block_on.borrow_mut();
if *in_block_on {
panic!("nested `block_on`");
}
*in_block_on = true;
}
self.in_block_on.replace(true);
let mut pinned_f = pin!(f);
pin_mut!(f);
let ready = AtomicBool::new(true);
let waker = wrap_waker(&ready);
let mut backup = Vec::new();
@ -72,10 +77,13 @@ impl Executor {
// advance the main task
if ready.load(Ordering::Relaxed) {
ready.store(false, Ordering::Relaxed);
// println!("run block_on");
let mut cx = Context::from_waker(&waker);
if let Poll::Ready(val) = pinned_f.as_mut().poll(&mut cx) {
if let Poll::Ready(val) = f.as_mut().poll(&mut cx) {
break val;
}
// println!("ran block_on");
}
// advance all tasks
@ -100,12 +108,16 @@ impl Executor {
// Requeue
self.tasks.borrow_mut().push(task);
}
// // try to sleep; this will be a no-op if any of the previous tasks generated a SEV or an
// // interrupt ran (regardless of whether it generated a wake-up or not)
// asm::wfe();
};
self.in_block_on.replace(false);
val
}
pub fn spawn(&self, f: impl Future<Output = ()> + 'static) {
pub fn spawn(&self, f: impl Future + 'static) {
let task = Box::pin(Task::new(f));
self.tasks.borrow_mut().push(task);
}
@ -117,10 +129,10 @@ pub struct Task {
}
impl Task {
fn new(f: impl Future<Output = ()> + 'static) -> Self {
fn new(f: impl Future + 'static) -> Self {
Task {
ready: AtomicBool::new(true),
f: Box::pin(f),
f: Box::pin(async { f.await; }),
}
}
}
@ -130,15 +142,16 @@ impl Task {
/// This lazily initializes the executor and allocator when first called
pub(crate) fn current() -> &'static Executor {
static INIT: AtomicBool = AtomicBool::new(false);
static mut EXECUTOR: MaybeUninit<Executor> = MaybeUninit::uninit();
static mut EXECUTOR: UnsafeCell<MaybeUninit<Executor>> = UnsafeCell::new(MaybeUninit::uninit());
if INIT.load(Ordering::Relaxed) {
unsafe { EXECUTOR.assume_init_ref() }
unsafe { &*(EXECUTOR.get() as *const Executor) }
} else {
unsafe {
let executor = EXECUTOR.write(Executor::new());
let executorp = EXECUTOR.get() as *mut Executor;
executorp.write(Executor::new());
INIT.store(true, Ordering::Relaxed);
&*executor
&*executorp
}
}
}

View File

@ -17,7 +17,7 @@ pub fn block_on<T>(f: impl Future<Output = T>) -> T {
/// Spawns a task onto the executor
///
/// The spawned task will not make any progress until `block_on` is called.
pub fn spawn(f: impl Future<Output = ()> + 'static) {
pub fn spawn(f: impl Future + 'static) {
executor::current().spawn(f)
}

View File

@ -1,4 +1,4 @@
use super::{I2c, Error};
use super::I2c;
use crate::time::Milliseconds;
use embedded_hal::timer::CountDown;
@ -35,25 +35,25 @@ impl<'a> EEPROM<'a> {
}
#[cfg(feature = "target_zc706")]
fn select(&mut self) -> Result<(), Error> {
fn select(&mut self) -> Result<(), &'static str> {
self.i2c.pca954x_select(0b1110100, Some(self.port))?;
Ok(())
}
#[cfg(feature = "target_kasli_soc")]
fn select(&mut self) -> Result<(), Error> {
fn select(&mut self) -> Result<(), &'static str> {
// tca9548 is compatible with pca9548
self.i2c.pca954x_select(0b1110001, Some(self.port))?;
Ok(())
}
#[cfg(feature = "target_ebaz4205")]
fn select(&mut self) -> Result<(), Error> {
fn select(&mut self) -> Result<(), &'static str> {
Ok(())
}
/// Random read
pub fn read<'r>(&mut self, addr: u8, buf: &'r mut [u8]) -> Result<(), Error> {
pub fn read<'r>(&mut self, addr: u8, buf: &'r mut [u8]) -> Result<(), &'static str> {
self.select()?;
self.i2c.start()?;
@ -78,7 +78,7 @@ impl<'a> EEPROM<'a> {
/// (i.e. `addr+buf.len()` < `addr/self.page_size+1`); otherwise, a roll-oever occurs,
/// where bytes beyond the page end. This smart function takes care of the scenario to avoid
/// any roll-over when writing ambiguous memory regions.
pub fn write(&mut self, addr: u8, buf: &[u8]) -> Result<(), Error> {
pub fn write(&mut self, addr: u8, buf: &[u8]) -> Result<(), &'static str> {
self.select()?;
let buf_len = buf.len();
@ -103,28 +103,26 @@ impl<'a> EEPROM<'a> {
}
/// Poll
pub fn poll(&mut self, timeout_ms: u64) -> Result<(), Error> {
pub fn poll(&mut self, timeout_ms: u64) -> Result<(), &'static str> {
self.select()?;
self.count_down.start(Milliseconds(timeout_ms));
loop {
self.i2c.start()?;
let res = self.i2c.write(self.address << 1);
let ack = self.i2c.write(self.address << 1)?;
self.i2c.stop()?;
match res {
Ok(()) => break,
Err(Error::Nack) => (),
Err(e) => return Err(e)
}
if ack {
break
};
if !self.count_down.waiting() {
return Err(Error::PollingTimeout)
return Err("I2C polling timeout")
}
}
Ok(())
}
pub fn read_eui48<'r>(&mut self) -> Result<[u8; 6], Error> {
pub fn read_eui48<'r>(&mut self) -> Result<[u8; 6], &'static str> {
let mut buffer = [0u8; 6];
self.read(0xFA, &mut buffer)?;
Ok(buffer)

View File

@ -11,7 +11,6 @@ use libregister::{RegisterR, RegisterRW};
use libregister::RegisterW;
#[cfg(feature = "target_kasli_soc")]
use log::info;
use log::error;
pub enum I2cMultiplexer {
PCA9548 = 0,
@ -19,31 +18,6 @@ pub enum I2cMultiplexer {
PCA9547 = 1,
}
#[derive(Debug)]
pub enum Error {
Nack,
SCLLow,
SDALow,
ArbitrationLost,
UnknownSwitch,
PollingTimeout,
OtherError,
}
impl From<Error> for &str {
fn from(err: Error) -> &'static str {
match err {
Error::Nack => "I2C write was not ACKed",
Error::SCLLow => "SCL stuck low",
Error::SDALow => "SDA stuck low",
Error::ArbitrationLost => "SDA arbitration lost",
Error::UnknownSwitch => "Unknown response for PCA954X autodetect",
Error::PollingTimeout => "I2C polling timeout",
Error::OtherError => "other error",
}
}
}
pub struct I2c {
regs: regs::RegisterBlock,
count_down: super::timer::global::CountDown<Microseconds>,
@ -174,7 +148,7 @@ impl I2c {
}
#[cfg(feature = "target_kasli_soc")]
fn pca_autodetect(&mut self) -> Result<I2cMultiplexer, Error> {
fn pca_autodetect(&mut self) -> Result<I2cMultiplexer, &'static str> {
// start with resetting the PCA954X
// SDA must be clear (before start)
// reset time is 500ns, unit_delay (100us) to account for propagation
@ -187,26 +161,21 @@ impl I2c {
self.start()?;
// read the config register
self.write(pca954x_read_addr).map_err(|err| {
match err {
Error::Nack => error!("PCA954X failed to ack read address"),
_ => ()
}
err
}
)?;
if !self.write(pca954x_read_addr)? {
return Err("PCA954X failed to ack read address");
}
let config = self.read(false)?;
let pca = match config {
0x00 => { info!("PCA9548 detected"); I2cMultiplexer::PCA9548 },
0x08 => { info!("PCA9547 detected"); I2cMultiplexer::PCA9547 },
_ => { return Err(Error::UnknownSwitch)},
_ => { return Err("Unknown response for PCA954X autodetect")},
};
self.stop()?;
Ok(pca)
}
pub fn init(&mut self) -> Result<(), Error> {
pub fn init(&mut self) -> Result<(), &'static str> {
self.scl_oe(false);
self.sda_oe(false);
self.scl_o(false);
@ -226,10 +195,10 @@ impl I2c {
}
if !self.sda_i() {
return Err(Error::SDALow);
return Err("SDA is stuck low and doesn't get unstuck");
}
if !self.scl_i() {
return Err(Error::SCLLow);
return Err("SCL is stuck low");
}
// postcondition: SCL and SDA high
@ -242,13 +211,13 @@ impl I2c {
Ok(())
}
pub fn start(&mut self) -> Result<(), Error> {
pub fn start(&mut self) -> Result<(), &'static str> {
// precondition: SCL and SDA high
if !self.scl_i() {
return Err(Error::SCLLow);
return Err("SCL is stuck low");
}
if !self.sda_i() {
return Err(Error::ArbitrationLost);
return Err("SDA arbitration lost");
}
self.sda_oe(true);
self.unit_delay();
@ -258,7 +227,7 @@ impl I2c {
Ok(())
}
pub fn restart(&mut self) -> Result<(), Error> {
pub fn restart(&mut self) -> Result<(), &'static str> {
// precondition SCL and SDA low
self.sda_oe(false);
self.unit_delay();
@ -269,7 +238,7 @@ impl I2c {
Ok(())
}
pub fn stop(&mut self) -> Result<(), Error> {
pub fn stop(&mut self) -> Result<(), &'static str> {
// precondition: SCL and SDA low
self.unit_delay();
self.scl_oe(false);
@ -277,13 +246,13 @@ impl I2c {
self.sda_oe(false);
self.unit_delay();
if !self.sda_i() {
return Err(Error::ArbitrationLost);
return Err("SDA arbitration lost");
}
// postcondition: SCL and SDA high
Ok(())
}
pub fn write(&mut self, data: u8) -> Result<(), Error> {
pub fn write(&mut self, data: u8) -> Result<bool, &'static str> {
// precondition: SCL and SDA low
// MSB first
for bit in (0..8).rev() {
@ -305,10 +274,10 @@ impl I2c {
self.sda_oe(true);
// postcondition: SCL and SDA low
if ack { Ok(()) } else { Err(Error::Nack) }
Ok(ack)
}
pub fn read(&mut self, ack: bool) -> Result<u8, Error> {
pub fn read(&mut self, ack: bool) -> Result<u8, &'static str> {
// precondition: SCL and SDA low
self.sda_oe(false);
@ -334,7 +303,7 @@ impl I2c {
Ok(data)
}
pub fn pca954x_select(&mut self, address: u8, channel: Option<u8>) -> Result<(), Error> {
pub fn pca954x_select(&mut self, address: u8, channel: Option<u8>) -> Result<(), &'static str> {
self.start()?;
// PCA9547 supports only one channel at a time
// for compatibility, PCA9548 is treated as such too
@ -355,16 +324,13 @@ impl I2c {
}
};
let write_res = self.write(address << 1).or_else( |err| {
error!("PCA954X write address fail: {:?}", err);
Err(err)
}).and_then(|_| self.write(setting).or_else(|err| {
error!("PCA954X control word fail: {:?}", err);
Err(err)
})
);
let stop_res = self.stop();
write_res.and(stop_res)
if !self.write(address << 1)? {
return Err("PCA954X failed to ack write address")
}
if !self.write(setting)? {
return Err("PCA954X failed to ack control word")
}
self.stop()?;
Ok(())
}
}

View File

@ -9,6 +9,7 @@ use super::time::Milliseconds;
use embedded_hal::timer::CountDown;
use libregister::{RegisterR, RegisterRW, RegisterW};
use log::{trace, debug};
use nb;
/// Basic SDIO Struct with common low-level functions.
pub struct Sdio {

View File

@ -1,4 +1,5 @@
use core_io::{BufRead, Error, ErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write};
use fatfs;
use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError};
use log::debug;
use alloc::vec::Vec;

View File

@ -137,15 +137,15 @@ fn cache_line_addrs(first_addr: usize, beyond_addr: usize) -> impl Iterator<Item
(first_addr..beyond_addr).step_by(CACHE_LINE)
}
fn object_cache_line_addrs<T>(object: *const T) -> impl Iterator<Item = usize> {
let first_addr = object.addr();
let beyond_addr = object.addr() + core::mem::size_of::<T>();
fn object_cache_line_addrs<T>(object: &T) -> impl Iterator<Item = usize> {
let first_addr = object as *const _ as usize;
let beyond_addr = (object as *const _ as usize) + core::mem::size_of_val(object);
cache_line_addrs(first_addr, beyond_addr)
}
fn slice_cache_line_addrs<T>(slice: &[T]) -> impl Iterator<Item = usize> {
let first_addr = (&raw const slice[0]).addr();
let beyond_addr = (&raw const slice[slice.len() - 1]).addr() +
let first_addr = &slice[0] as *const _ as usize;
let beyond_addr = (&slice[slice.len() - 1] as *const _ as usize) +
core::mem::size_of_val(&slice[slice.len() - 1]);
cache_line_addrs(first_addr, beyond_addr)
}
@ -162,7 +162,7 @@ pub fn dccimvac(addr: usize) {
}
/// Data cache clean and invalidate for an object.
pub fn dcci<T>(object: *const T) {
pub fn dcci<T>(object: &T) {
// ref: L2C310 TRM 3.3.10
dmb();
for addr in object_cache_line_addrs(object) {
@ -203,7 +203,7 @@ pub fn dccmvac(addr: usize) {
}
}
/// Data cache clean for an object.
pub fn dcc<T>(object: *const T) {
pub fn dcc<T>(object: &T) {
dmb();
for addr in object_cache_line_addrs(object) {
dccmvac(addr);

View File

@ -1,8 +1,10 @@
#![no_std]
#![feature(never_type)]
#![feature(global_asm)]
#![feature(asm)]
#![allow(incomplete_features)]
#![feature(inline_const)]
#![feature(strict_provenance)]
#![feature(raw_ref_op)]
#![feature(const_fn_trait_bound)]
extern crate alloc;

View File

@ -1,4 +1,3 @@
use core::cell::UnsafeCell;
use bit_field::BitField;
use super::{regs::*, asm::*, cache::*};
use libregister::RegisterW;
@ -125,9 +124,9 @@ impl L1Entry {
}
const L1_TABLE_SIZE: usize = 4096;
static mut L1_TABLE: UnsafeCell<L1Table> = UnsafeCell::new(L1Table {
static mut L1_TABLE: L1Table = L1Table {
table: [L1Entry(0); L1_TABLE_SIZE]
});
};
#[repr(C, align(16384))]
pub struct L1Table {
@ -136,7 +135,9 @@ pub struct L1Table {
impl L1Table {
pub fn get() -> &'static mut Self {
unsafe { L1_TABLE.get_mut() }
unsafe {
&mut L1_TABLE
}
}
pub fn setup_flat_layout(&mut self) -> &Self {

View File

@ -37,7 +37,7 @@ impl<'a, T> Sender<'a, T> where T: Clone {
notify_spin_lock();
if !prev.is_null() {
unsafe {
let _ = Box::from_raw(prev);
Box::from_raw(prev);
}
}
Ok(())
@ -91,7 +91,7 @@ impl<'a, T> Sender<'a, T> where T: Clone {
for v in self.list.iter() {
let original = v.swap(core::ptr::null_mut(), Ordering::Relaxed);
if !original.is_null() {
let _ = Box::from_raw(original);
Box::from_raw(original);
}
}
}
@ -177,7 +177,10 @@ macro_rules! sync_channel {
{
use core::sync::atomic::{AtomicUsize, AtomicPtr};
use $crate::sync_channel::{Sender, Receiver};
static LIST: [AtomicPtr<$t>; $cap + 1] = [const { AtomicPtr::new(core::ptr::null_mut()) }; $cap + 1];
const fn new_atomic() -> AtomicPtr<$t> {
AtomicPtr::new(core::ptr::null_mut())
}
static LIST: [AtomicPtr<$t>; $cap + 1] = [const { new_atomic() }; $cap + 1];
static WRITE: AtomicUsize = AtomicUsize::new(0);
static READ: AtomicUsize = AtomicUsize::new(0);
(Sender::new(&LIST, &WRITE, &READ), Receiver::new(&LIST, &WRITE, &READ))

View File

@ -20,7 +20,7 @@ default = ["panic_handler", "dummy_irq_handler", "dummy_fiq_handler"]
[dependencies]
r0 = "1"
compiler_builtins = "=0.1.108"
compiler_builtins = "=0.1.49"
linked_list_allocator = { version = "0.8", default-features = false, features = ["const_mut_refs"] }
libregister = { path = "../libregister" }
libcortex_a9 = { path = "../libcortex_a9" }

View File

@ -43,11 +43,10 @@ unsafe extern "C" fn boot_core0() -> ! {
let mpcore = mpcore::RegisterBlock::mpcore();
mpcore.scu_invalidate.invalidate_all_cores();
zero_bss(&raw mut __bss_start, &raw mut __bss_end);
zero_bss(&mut __bss_start, &mut __bss_end);
let mmu_table = mmu::L1Table::get()
.setup_flat_layout();
cache::dcc(mmu_table);
mmu::with_mmu(mmu_table, || {
mpcore.scu_control.start();
ACTLR.enable_smp();
@ -67,7 +66,6 @@ unsafe extern "C" fn boot_core0() -> ! {
unsafe extern "C" fn boot_core1() -> ! {
l1_cache_init();
enable_fpu();
let mpcore = mpcore::RegisterBlock::mpcore();
mpcore.scu_invalidate.invalidate_core1();
@ -134,7 +132,7 @@ impl Core1 {
CORE1_ENABLED.set(true);
}
// Flush cache-line
cache::dcc(unsafe { &raw const CORE1_ENABLED });
cache::dcc(unsafe { &CORE1_ENABLED });
if sdram {
cache::dccmvac(0);
asm::dsb();
@ -155,7 +153,7 @@ impl Core1 {
pub fn disable(&self) {
unsafe {
CORE1_ENABLED.set(false);
cache::dccmvac((&raw const CORE1_ENABLED).addr());
cache::dccmvac(&CORE1_ENABLED as *const _ as usize);
asm::dsb();
}
self.restart();

View File

@ -3,8 +3,8 @@
#![feature(alloc_error_handler)]
#![feature(panic_info_message)]
#![feature(naked_functions)]
#![feature(strict_provenance)]
#![feature(raw_ref_op)]
#![feature(global_asm)]
#![feature(asm)]
pub extern crate alloc;
pub extern crate compiler_builtins;

View File

@ -1,9 +1,6 @@
#![no_std]
#![no_main]
#![feature(strict_provenance)]
#![feature(raw_ref_op)]
extern crate alloc;
extern crate log;
@ -119,18 +116,18 @@ pub fn main_core0() {
unsafe {
let max_len =
(&raw const __runtime_end).addr() - (&raw const __runtime_start).addr();
&__runtime_end as *const usize as usize - &__runtime_start as *const usize as usize;
match slcr::RegisterBlock::unlocked(|slcr| slcr.boot_mode.read().boot_mode_pins()) {
slcr::BootModePins::Jtag => netboot::netboot(
&mut bootgen_file,
config,
(&raw mut __runtime_start).cast(),
&mut __runtime_start as *mut usize as *mut u8,
max_len,
),
slcr::BootModePins::SdCard => {
if boot_sd(
&mut bootgen_file,
(&raw mut __runtime_start).cast(),
&mut __runtime_start as *mut usize as *mut u8,
max_len,
)
.is_err()
@ -140,7 +137,7 @@ pub fn main_core0() {
netboot::netboot(
&mut bootgen_file,
config,
(&raw mut __runtime_start).cast(),
&mut __runtime_start as *mut usize as *mut u8,
max_len,
)
}
@ -151,7 +148,7 @@ pub fn main_core0() {
netboot::netboot(
&mut bootgen_file,
config,
(&raw mut __runtime_start).cast(),
&mut __runtime_start as *mut usize as *mut u8,
max_len,
)
}