forked from M-Labs/zynq-rs
Compare commits
11 Commits
fix_uncach
...
master
Author | SHA1 | Date | |
---|---|---|---|
1c3912e34e | |||
b01db024f2 | |||
86af810f02 | |||
7412291b16 | |||
ac33c09578 | |||
9e41aed178 | |||
ce57ae40de | |||
aecce03dc8 | |||
74436691ec | |||
0ed235475a | |||
c6f6bd292d |
@ -1,7 +1,6 @@
|
|||||||
[target.armv7-none-eabihf]
|
[target.armv7-none-eabihf]
|
||||||
rustflags = [
|
rustflags = [
|
||||||
"-C", "link-arg=-Tlink.x",
|
"-C", "link-arg=-Tlink.x",
|
||||||
"-C", "target-feature=a9,armv7-a,neon",
|
|
||||||
"-C", "target-cpu=cortex-a9",
|
"-C", "target-cpu=cortex-a9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -34,9 +34,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.49"
|
version = "0.1.70"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20b1438ef42c655665a8ab2c1c6d605a305f031d38d9be689ddfef41a20f3aa2"
|
checksum = "80873f979f0a344a4ade87c2f70d9ccf5720b83b10c97ec7cd745895d021e85a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core_io"
|
name = "core_io"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"emit-debug-gdb-scripts": false,
|
"emit-debug-gdb-scripts": false,
|
||||||
"env": "",
|
"env": "",
|
||||||
"executables": true,
|
"executables": true,
|
||||||
"features": "+v7,+vfp3,-d32,+thumb2,-neon",
|
"features": "+v7,+vfp3,-d32,+thumb2,+neon,+a9,+armv7-a",
|
||||||
"is-builtin": false,
|
"is-builtin": false,
|
||||||
"linker": "rust-lld",
|
"linker": "rust-lld",
|
||||||
"linker-flavor": "ld.lld",
|
"linker-flavor": "ld.lld",
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![feature(asm)]
|
|
||||||
#![feature(inline_const)]
|
#![feature(inline_const)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
6
flake.lock
generated
6
flake.lock
generated
@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1736867362,
|
"lastModified": 1739206421,
|
||||||
"narHash": "sha256-i/UJ5I7HoqmFMwZEH6vAvBxOrjjOJNU739lnZnhUln8=",
|
"narHash": "sha256-PwQASeL2cGVmrtQYlrBur0U20Xy07uSWVnFup2PHnDs=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9c6b49aeac36e2ed73a8c472f1546f6d9cf1addc",
|
"rev": "44534bc021b85c8d78e465021e21f33b856e2540",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
let
|
let
|
||||||
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import rust-overlay) crosspkgs-overlay ]; };
|
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import rust-overlay) crosspkgs-overlay ]; };
|
||||||
|
|
||||||
rust = pkgs.rust-bin.nightly."2021-09-01".default.override {
|
rust = pkgs.rust-bin.nightly."2022-04-01".default.override {
|
||||||
extensions = [ "rust-src" ];
|
extensions = [ "rust-src" ];
|
||||||
targets = [ ];
|
targets = [ ];
|
||||||
};
|
};
|
||||||
@ -113,7 +113,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_13.clang-unwrapped ];
|
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_14.clang-unwrapped ];
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
export XARGO_RUST_SRC="${rust}/lib/rustlib/src/rust/library"
|
export XARGO_RUST_SRC="${rust}/lib/rustlib/src/rust/library"
|
||||||
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
|
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
|
||||||
@ -169,7 +169,7 @@
|
|||||||
|
|
||||||
pkgs.openocd pkgs.gdb
|
pkgs.openocd pkgs.gdb
|
||||||
pkgs.openssh pkgs.rsync
|
pkgs.openssh pkgs.rsync
|
||||||
pkgs.llvmPackages_13.clang-unwrapped
|
pkgs.llvmPackages_14.clang-unwrapped
|
||||||
(pkgs.python3.withPackages(ps: [ ps.pyftdi ]))
|
(pkgs.python3.withPackages(ps: [ ps.pyftdi ]))
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
use core::{
|
use core::{
|
||||||
cell::{RefCell, UnsafeCell},
|
cell::UnsafeCell,
|
||||||
future::Future,
|
future::Future,
|
||||||
mem::MaybeUninit,
|
mem::MaybeUninit,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||||
};
|
};
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
|
||||||
//use futures::future::FutureExt;
|
|
||||||
use pin_utils::pin_mut;
|
use pin_utils::pin_mut;
|
||||||
|
|
||||||
// NOTE `*const ()` is &AtomicBool
|
// NOTE `*const ()` is &AtomicBool
|
||||||
@ -39,35 +38,32 @@ fn wrap_waker(ready: &AtomicBool) -> Waker {
|
|||||||
/// This is a singleton
|
/// This is a singleton
|
||||||
pub struct Executor {
|
pub struct Executor {
|
||||||
// Entered block_on() already?
|
// Entered block_on() already?
|
||||||
in_block_on: RefCell<bool>,
|
in_block_on: bool,
|
||||||
|
|
||||||
/// Tasks reside on the heap, so that we just queue pointers. They
|
/// Tasks reside on the heap, so that we just queue pointers. They
|
||||||
/// must also be pinned in memory because our RawWaker is a pointer
|
/// must also be pinned in memory because our RawWaker is a pointer
|
||||||
/// to their `ready` field.
|
/// to their `ready` field.
|
||||||
tasks: RefCell<Vec<Pin<Box<Task>>>>,
|
tasks: Vec<Pin<Box<Task>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Executor {
|
impl Executor {
|
||||||
/// Creates a new instance of the executor
|
/// Creates a new instance of the executor
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
in_block_on: RefCell::new(false),
|
in_block_on: false,
|
||||||
tasks: RefCell::new(Vec::new()),
|
tasks: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn block_on<T>(&self, f: impl Future<Output = T>) -> T {
|
pub fn block_on<T>(&mut self, f: impl Future<Output = T>) -> T {
|
||||||
// we want to avoid reentering `block_on` because then all the code
|
// we want to avoid reentering `block_on` because then all the code
|
||||||
// below has to become more complex. It's also likely that the
|
// below has to become more complex. It's also likely that the
|
||||||
// application will only call `block_on` once on an infinite task
|
// application will only call `block_on` once on an infinite task
|
||||||
// (`Future<Output = !>`)
|
// (`Future<Output = !>`)
|
||||||
{
|
if self.in_block_on {
|
||||||
let mut in_block_on = self.in_block_on.borrow_mut();
|
|
||||||
if *in_block_on {
|
|
||||||
panic!("nested `block_on`");
|
panic!("nested `block_on`");
|
||||||
}
|
}
|
||||||
*in_block_on = true;
|
self.in_block_on = true;
|
||||||
}
|
|
||||||
|
|
||||||
pin_mut!(f);
|
pin_mut!(f);
|
||||||
let ready = AtomicBool::new(true);
|
let ready = AtomicBool::new(true);
|
||||||
@ -77,17 +73,14 @@ impl Executor {
|
|||||||
// advance the main task
|
// advance the main task
|
||||||
if ready.load(Ordering::Relaxed) {
|
if ready.load(Ordering::Relaxed) {
|
||||||
ready.store(false, Ordering::Relaxed);
|
ready.store(false, Ordering::Relaxed);
|
||||||
|
|
||||||
// println!("run block_on");
|
|
||||||
let mut cx = Context::from_waker(&waker);
|
let mut cx = Context::from_waker(&waker);
|
||||||
if let Poll::Ready(val) = f.as_mut().poll(&mut cx) {
|
if let Poll::Ready(val) = f.as_mut().poll(&mut cx) {
|
||||||
break val;
|
break val;
|
||||||
}
|
}
|
||||||
// println!("ran block_on");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// advance all tasks
|
// advance all tasks
|
||||||
core::mem::swap(&mut *self.tasks.borrow_mut(), &mut backup);
|
core::mem::swap(&mut self.tasks, &mut backup);
|
||||||
for mut task in backup.drain(..) {
|
for mut task in backup.drain(..) {
|
||||||
// NOTE we don't need a CAS operation here because `wake` invocations that come from
|
// NOTE we don't need a CAS operation here because `wake` invocations that come from
|
||||||
// interrupt handlers (the only source of 'race conditions' (!= data races)) are
|
// interrupt handlers (the only source of 'race conditions' (!= data races)) are
|
||||||
@ -106,20 +99,16 @@ impl Executor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Requeue
|
// Requeue
|
||||||
self.tasks.borrow_mut().push(task);
|
self.tasks.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);
|
self.in_block_on = false;
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(&self, f: impl Future + 'static) {
|
pub fn spawn(&mut self, f: impl Future<Output = ()> + 'static) {
|
||||||
let task = Box::pin(Task::new(f));
|
let task = Box::pin(Task::new(f));
|
||||||
self.tasks.borrow_mut().push(task);
|
self.tasks.push(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,10 +118,10 @@ pub struct Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Task {
|
impl Task {
|
||||||
fn new(f: impl Future + 'static) -> Self {
|
fn new(f: impl Future<Output = ()> + 'static) -> Self {
|
||||||
Task {
|
Task {
|
||||||
ready: AtomicBool::new(true),
|
ready: AtomicBool::new(true),
|
||||||
f: Box::pin(async { f.await; }),
|
f: Box::pin(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,18 +129,17 @@ impl Task {
|
|||||||
/// Returns a handle to the executor singleton
|
/// Returns a handle to the executor singleton
|
||||||
///
|
///
|
||||||
/// This lazily initializes the executor and allocator when first called
|
/// This lazily initializes the executor and allocator when first called
|
||||||
pub(crate) fn current() -> &'static Executor {
|
pub(crate) fn current() -> &'static mut Executor {
|
||||||
static INIT: AtomicBool = AtomicBool::new(false);
|
static INIT: AtomicBool = AtomicBool::new(false);
|
||||||
static mut EXECUTOR: UnsafeCell<MaybeUninit<Executor>> = UnsafeCell::new(MaybeUninit::uninit());
|
static mut EXECUTOR: UnsafeCell<MaybeUninit<Executor>> = UnsafeCell::new(MaybeUninit::uninit());
|
||||||
|
|
||||||
if INIT.load(Ordering::Relaxed) {
|
if INIT.load(Ordering::Relaxed) {
|
||||||
unsafe { &*(EXECUTOR.get() as *const Executor) }
|
unsafe { EXECUTOR.get_mut().assume_init_mut() }
|
||||||
} else {
|
} else {
|
||||||
unsafe {
|
unsafe {
|
||||||
let executorp = EXECUTOR.get() as *mut Executor;
|
let executor = EXECUTOR.get_mut().write(Executor::new());
|
||||||
executorp.write(Executor::new());
|
|
||||||
INIT.store(true, Ordering::Relaxed);
|
INIT.store(true, Ordering::Relaxed);
|
||||||
&*executorp
|
executor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ pub fn block_on<T>(f: impl Future<Output = T>) -> T {
|
|||||||
/// Spawns a task onto the executor
|
/// Spawns a task onto the executor
|
||||||
///
|
///
|
||||||
/// The spawned task will not make any progress until `block_on` is called.
|
/// The spawned task will not make any progress until `block_on` is called.
|
||||||
pub fn spawn(f: impl Future + 'static) {
|
pub fn spawn(f: impl Future<Output = ()> + 'static) {
|
||||||
executor::current().spawn(f)
|
executor::current().spawn(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(global_asm)]
|
|
||||||
#![feature(asm)]
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(inline_const)]
|
#![feature(inline_const)]
|
||||||
#![feature(const_fn_trait_bound)]
|
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
@ -177,10 +177,7 @@ macro_rules! sync_channel {
|
|||||||
{
|
{
|
||||||
use core::sync::atomic::{AtomicUsize, AtomicPtr};
|
use core::sync::atomic::{AtomicUsize, AtomicPtr};
|
||||||
use $crate::sync_channel::{Sender, Receiver};
|
use $crate::sync_channel::{Sender, Receiver};
|
||||||
const fn new_atomic() -> AtomicPtr<$t> {
|
static LIST: [AtomicPtr<$t>; $cap + 1] = [const { AtomicPtr::new(core::ptr::null_mut()) }; $cap + 1];
|
||||||
AtomicPtr::new(core::ptr::null_mut())
|
|
||||||
}
|
|
||||||
static LIST: [AtomicPtr<$t>; $cap + 1] = [const { new_atomic() }; $cap + 1];
|
|
||||||
static WRITE: AtomicUsize = AtomicUsize::new(0);
|
static WRITE: AtomicUsize = AtomicUsize::new(0);
|
||||||
static READ: AtomicUsize = AtomicUsize::new(0);
|
static READ: AtomicUsize = AtomicUsize::new(0);
|
||||||
(Sender::new(&LIST, &WRITE, &READ), Receiver::new(&LIST, &WRITE, &READ))
|
(Sender::new(&LIST, &WRITE, &READ), Receiver::new(&LIST, &WRITE, &READ))
|
||||||
|
@ -20,7 +20,7 @@ default = ["panic_handler", "dummy_irq_handler", "dummy_fiq_handler"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
r0 = "1"
|
r0 = "1"
|
||||||
compiler_builtins = "=0.1.49"
|
compiler_builtins = "=0.1.70"
|
||||||
linked_list_allocator = { version = "0.8", default-features = false, features = ["const_mut_refs"] }
|
linked_list_allocator = { version = "0.8", default-features = false, features = ["const_mut_refs"] }
|
||||||
libregister = { path = "../libregister" }
|
libregister = { path = "../libregister" }
|
||||||
libcortex_a9 = { path = "../libcortex_a9" }
|
libcortex_a9 = { path = "../libcortex_a9" }
|
||||||
|
@ -66,6 +66,7 @@ unsafe extern "C" fn boot_core0() -> ! {
|
|||||||
unsafe extern "C" fn boot_core1() -> ! {
|
unsafe extern "C" fn boot_core1() -> ! {
|
||||||
l1_cache_init();
|
l1_cache_init();
|
||||||
|
|
||||||
|
enable_fpu();
|
||||||
let mpcore = mpcore::RegisterBlock::mpcore();
|
let mpcore = mpcore::RegisterBlock::mpcore();
|
||||||
mpcore.scu_invalidate.invalidate_core1();
|
mpcore.scu_invalidate.invalidate_core1();
|
||||||
|
|
||||||
|
@ -3,8 +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(global_asm)]
|
|
||||||
#![feature(asm)]
|
|
||||||
|
|
||||||
pub extern crate alloc;
|
pub extern crate alloc;
|
||||||
pub extern crate compiler_builtins;
|
pub extern crate compiler_builtins;
|
||||||
|
Loading…
Reference in New Issue
Block a user