forked from M-Labs/zynq-rs
Compare commits
16 Commits
df3b94a83a
...
6cfb6fd1fc
| Author | SHA1 | Date | |
|---|---|---|---|
| 6cfb6fd1fc | |||
| 3b5359297c | |||
| 7a4da4df48 | |||
| 6262cb135d | |||
| 354c8a40a2 | |||
| 20975fc812 | |||
| f62bcc5c8a | |||
| 7073d7cc5d | |||
| 71af630a67 | |||
|
|
37263978ba | ||
| fc035d8baf | |||
| 803ecb257f | |||
| 1d71fb3cb7 | |||
| b69de9f37f | |||
| 8ca9f6f4dd | |||
| 45f3173b65 |
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -76,6 +76,7 @@ name = "libasync"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"embedded-hal",
|
||||
"libcortex_a9",
|
||||
"nb 1.0.0",
|
||||
"smoltcp",
|
||||
]
|
||||
@@ -103,6 +104,7 @@ dependencies = [
|
||||
"core_io",
|
||||
"fatfs",
|
||||
"libboard_zynq",
|
||||
"libcortex_a9",
|
||||
"log",
|
||||
]
|
||||
|
||||
|
||||
58
flake.lock
generated
58
flake.lock
generated
@@ -1,17 +1,40 @@
|
||||
{
|
||||
"nodes": {
|
||||
"fenix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"naersk",
|
||||
"nixpkgs"
|
||||
],
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1752475459,
|
||||
"narHash": "sha256-z6QEu4ZFuHiqdOPbYss4/Q8B0BFhacR8ts6jO/F/aOU=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "bf0d6f70f4c9a9cf8845f992105652173f4b617f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"fenix": "fenix",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1745925850,
|
||||
"narHash": "sha256-cyAAMal0aPrlb1NgzMxZqeN1mAJ2pJseDhm2m6Um8T0=",
|
||||
"lastModified": 1768908532,
|
||||
"narHash": "sha256-HIdLXEFaUVE8FiaCPJbCfBMsnF+mVtDub8Jwj2BD+mk=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "38bc60bbc157ae266d4a0c96671c6c742ee17a5f",
|
||||
"rev": "8d97452673640eb7fabe428e8b6a425bc355008b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -22,11 +45,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1749794982,
|
||||
"narHash": "sha256-Kh9K4taXbVuaLC0IL+9HcfvxsSUx8dPB5s5weJcc9pc=",
|
||||
"lastModified": 1769018530,
|
||||
"narHash": "sha256-MJ27Cy2NtBEV5tsK+YraYr2g851f3Fl1LpNHDzDX15c=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ee930f9755f58096ac6e8ca94a1887e0534e2d81",
|
||||
"rev": "88d3861acdd3d2f0e361767018218e51810df8a1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -43,6 +66,23 @@
|
||||
"rust-overlay": "rust-overlay"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1752428706,
|
||||
"narHash": "sha256-EJcdxw3aXfP8Ex1Nm3s0awyH9egQvB2Gu+QEnJn2Sfg=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "591e3b7624be97e4443ea7b5542c191311aa141d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rust-lang",
|
||||
"ref": "nightly",
|
||||
"repo": "rust-analyzer",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@@ -50,11 +90,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1750041667,
|
||||
"narHash": "sha256-/8F9L6T9w/Fx1D6L+BtWIXg5m9F6jwOFg6uhZpKnM/0=",
|
||||
"lastModified": 1769136478,
|
||||
"narHash": "sha256-8UNd5lmGf8phCr/aKxagJ4kNsF0pCHLish2G4ZKCFFY=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "d72bd8c9fda03c9834ea89d7a5a21c7880b79277",
|
||||
"rev": "470ee44393bb19887056b557ea2c03fc5230bd5a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
210
flake.nix
210
flake.nix
@@ -11,21 +11,30 @@
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, rust-overlay, naersk }:
|
||||
let
|
||||
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import rust-overlay) crosspkgs-overlay ]; };
|
||||
|
||||
rust = pkgs.rust-bin.nightly."2025-03-28".default.override {
|
||||
extensions = [ "rust-src" ];
|
||||
targets = [ ];
|
||||
};
|
||||
naerskLib = pkgs.callPackage naersk {
|
||||
rustc = rust;
|
||||
cargo = rust;
|
||||
};
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
rust-overlay,
|
||||
naersk,
|
||||
}: let
|
||||
pkgs = import nixpkgs {
|
||||
system = "x86_64-linux";
|
||||
overlays = [(import rust-overlay) crosspkgs-overlay];
|
||||
};
|
||||
|
||||
crosspkgs-overlay = (self: super: {
|
||||
pkgsCross = super.pkgsCross // {
|
||||
rust = pkgs.rust-bin.nightly."2025-03-28".default.override {
|
||||
extensions = ["rust-src"];
|
||||
targets = [];
|
||||
};
|
||||
naerskLib = pkgs.callPackage naersk {
|
||||
rustc = rust;
|
||||
cargo = rust;
|
||||
};
|
||||
|
||||
crosspkgs-overlay = self: super: {
|
||||
pkgsCross =
|
||||
super.pkgsCross
|
||||
// {
|
||||
zynq-baremetal = import super.path {
|
||||
system = "x86_64-linux";
|
||||
crossSystem = {
|
||||
@@ -36,44 +45,47 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
mkbootimage = pkgs.stdenv.mkDerivation {
|
||||
pname = "mkbootimage";
|
||||
version = "2.3dev";
|
||||
mkbootimage = pkgs.stdenv.mkDerivation {
|
||||
pname = "mkbootimage";
|
||||
version = "2.3dev";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "antmicro";
|
||||
repo = "zynq-mkbootimage";
|
||||
rev = "872363ce32c249f8278cf107bc6d3bdeb38d849f";
|
||||
sha256 = "sha256-5FPyAhUWZDwHbqmp9J2ZXTmjaXPz+dzrJMolaNwADHs=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [ pkgs.libelf pkgs.pcre ];
|
||||
patchPhase =
|
||||
''
|
||||
substituteInPlace Makefile --replace "git rev-parse --short HEAD" "echo nix"
|
||||
'';
|
||||
installPhase =
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
cp mkbootimage $out/bin
|
||||
'';
|
||||
hardeningDisable = [ "fortify" ];
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "antmicro";
|
||||
repo = "zynq-mkbootimage";
|
||||
rev = "872363ce32c249f8278cf107bc6d3bdeb38d849f";
|
||||
sha256 = "sha256-5FPyAhUWZDwHbqmp9J2ZXTmjaXPz+dzrJMolaNwADHs=";
|
||||
};
|
||||
|
||||
fsbl = { board ? "zc706" }: pkgs.stdenv.mkDerivation {
|
||||
propagatedBuildInputs = [pkgs.libelf pkgs.pcre];
|
||||
patchPhase = ''
|
||||
substituteInPlace Makefile --replace "git rev-parse --short HEAD" "echo nix"
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp mkbootimage $out/bin
|
||||
'';
|
||||
hardeningDisable = ["fortify"];
|
||||
};
|
||||
|
||||
fsbl = {board ? "zc706"}:
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "${board}-fsbl";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "Xilinx";
|
||||
repo = "embeddedsw";
|
||||
rev = "xilinx_v2022.2";
|
||||
sha256 = "sha256-UDz9KK/Hw3qM1BAeKif30rE8Bi6C2uvuZlvyvtJCMfw=";
|
||||
rev = "xilinx_v2025.1_update1";
|
||||
sha256 = "sha256-XAwhkox1PDyo/UmxP9kjgKsjuoeWgIVhg8X1qFk+Pdo=";
|
||||
};
|
||||
nativeBuildInputs = [
|
||||
pkgs.pkgsCross.zynq-baremetal.buildPackages.binutils
|
||||
pkgs.pkgsCross.zynq-baremetal.buildPackages.gcc
|
||||
];
|
||||
|
||||
NIX_CFLAGS_COMPILE = "-DFSBL_DEBUG_INFO -g -no-pie";
|
||||
NIX_LDFLAGS = "-no-pie";
|
||||
|
||||
patchPhase = ''
|
||||
patchShebangs lib/sw_apps/zynq_fsbl/misc/copy_bsp.sh
|
||||
|
||||
@@ -84,7 +96,7 @@
|
||||
'';
|
||||
buildPhase = ''
|
||||
cd lib/sw_apps/zynq_fsbl/src
|
||||
make BOARD=${board} "CFLAGS=-DFSBL_DEBUG_INFO -g"
|
||||
make BOARD=${board}
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
@@ -94,18 +106,21 @@
|
||||
dontFixup = true;
|
||||
};
|
||||
|
||||
build-crate = name: crate: features: naerskLib.buildPackage rec {
|
||||
build-crate = name: crate: features:
|
||||
naerskLib.buildPackage rec {
|
||||
name = "${crate}";
|
||||
src = ./.;
|
||||
additionalCargoLock = "${rust}/lib/rustlib/src/rust/library/Cargo.lock";
|
||||
nativeBuildInputs = [ pkgs.llvmPackages_20.clang-unwrapped ];
|
||||
nativeBuildInputs = [pkgs.llvmPackages_20.clang-unwrapped];
|
||||
singleStep = true;
|
||||
release = true;
|
||||
cargoBuildOptions = options: options ++ [
|
||||
"-p ${crate}"
|
||||
"--no-default-features"
|
||||
"--features=${features}"
|
||||
];
|
||||
cargoBuildOptions = options:
|
||||
options
|
||||
++ [
|
||||
"-p ${crate}"
|
||||
"--no-default-features"
|
||||
"--features=${features}"
|
||||
];
|
||||
overrideMain = _: {
|
||||
installPhase = ''
|
||||
mkdir -p $out $out/nix-support
|
||||
@@ -116,59 +131,68 @@
|
||||
};
|
||||
};
|
||||
|
||||
targetCrates = target: {
|
||||
"${target}-experiments" = build-crate "${target}-experiments" "experiments" "target_${target}";
|
||||
"${target}-szl" = build-crate "${target}-szl" "szl" "target_${target}";
|
||||
};
|
||||
targets = ["zc706" "coraz7" "redpitaya" "kasli_soc" "ebaz4205"];
|
||||
allTargetCrates = (builtins.foldl' (results: target:
|
||||
results // targetCrates target
|
||||
) {} targets);
|
||||
|
||||
szl = pkgs.runCommand "szl" {} (builtins.foldl' (commands: target:
|
||||
let
|
||||
targetCrates = target: {
|
||||
"${target}-experiments" = build-crate "${target}-experiments" "experiments" "target_${target}";
|
||||
"${target}-szl" = build-crate "${target}-szl" "szl" "target_${target}";
|
||||
};
|
||||
targets = ["zc706" "coraz7" "redpitaya" "kasli_soc" "ebaz4205"];
|
||||
allTargetCrates =
|
||||
builtins.foldl' (
|
||||
results: target:
|
||||
results // targetCrates target
|
||||
) {}
|
||||
targets;
|
||||
|
||||
szl = pkgs.runCommand "szl" {} (builtins.foldl' (
|
||||
commands: target: let
|
||||
szlResult = builtins.getAttr "${target}-szl" allTargetCrates;
|
||||
in
|
||||
commands + "ln -s ${szlResult}/szl.elf $out/szl-${target}.elf\n"
|
||||
) "mkdir $out\n" targets);
|
||||
) "mkdir $out\n"
|
||||
targets);
|
||||
|
||||
fmt-check = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "fmt-check";
|
||||
fmt-check = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "fmt-check";
|
||||
|
||||
src = ./.;
|
||||
src = ./.;
|
||||
|
||||
nativeBuildInputs = [ rust ];
|
||||
nativeBuildInputs = [rust];
|
||||
|
||||
phases = [ "unpackPhase" "buildPhase" ];
|
||||
phases = ["unpackPhase" "buildPhase"];
|
||||
|
||||
buildPhase =
|
||||
''
|
||||
cargo fmt -- --check
|
||||
touch $out
|
||||
'';
|
||||
};
|
||||
in rec {
|
||||
packages.x86_64-linux = {
|
||||
inherit szl mkbootimage fmt-check;
|
||||
zc706-fsbl = fsbl { board = "zc706"; };
|
||||
} // allTargetCrates ;
|
||||
|
||||
hydraJobs = packages.x86_64-linux;
|
||||
|
||||
inherit rust naerskLib;
|
||||
|
||||
devShell.x86_64-linux = pkgs.mkShell {
|
||||
name = "zynq-rs-dev-shell";
|
||||
buildInputs = [
|
||||
rust
|
||||
pkgs.cargo-xbuild
|
||||
mkbootimage
|
||||
|
||||
pkgs.openocd pkgs.gdb
|
||||
pkgs.openssh pkgs.rsync
|
||||
pkgs.llvmPackages_20.clang-unwrapped
|
||||
(pkgs.python3.withPackages(ps: [ ps.pyftdi ]))
|
||||
];
|
||||
};
|
||||
buildPhase = ''
|
||||
cargo fmt -- --check
|
||||
touch $out
|
||||
'';
|
||||
};
|
||||
in rec {
|
||||
packages.x86_64-linux =
|
||||
{
|
||||
inherit szl mkbootimage fmt-check;
|
||||
zc706-fsbl = fsbl {board = "zc706";};
|
||||
}
|
||||
// allTargetCrates;
|
||||
|
||||
hydraJobs = packages.x86_64-linux;
|
||||
|
||||
inherit rust naerskLib;
|
||||
|
||||
formatter.x86_64-linux = pkgs.alejandra;
|
||||
|
||||
devShell.x86_64-linux = pkgs.mkShell {
|
||||
name = "zynq-rs-dev-shell";
|
||||
buildInputs = [
|
||||
rust
|
||||
pkgs.cargo-xbuild
|
||||
mkbootimage
|
||||
|
||||
pkgs.openocd
|
||||
pkgs.gdb
|
||||
pkgs.openssh
|
||||
pkgs.rsync
|
||||
pkgs.llvmPackages_20.clang-unwrapped
|
||||
(pkgs.python3.withPackages (ps: [ps.pyftdi]))
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
embedded-hal = "0.2"
|
||||
nb = "1.0"
|
||||
libcortex_a9 = { path = "../libcortex_a9" }
|
||||
|
||||
[dependencies.smoltcp]
|
||||
version = "0.7"
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use alloc::vec::Vec;
|
||||
use core::{cell::RefCell, task::Waker};
|
||||
|
||||
use libcortex_a9::once_lock::OnceLock;
|
||||
use smoltcp::{iface::EthernetInterface, phy::Device, socket::SocketSet, time::Instant};
|
||||
|
||||
mod tcp_stream;
|
||||
pub use tcp_stream::TcpStream;
|
||||
|
||||
static mut SOCKETS: Option<Sockets> = None;
|
||||
static SOCKETS: OnceLock<Sockets> = OnceLock::new();
|
||||
|
||||
pub struct Sockets {
|
||||
sockets: RefCell<SocketSet<'static>>,
|
||||
@@ -24,14 +25,11 @@ impl Sockets {
|
||||
let wakers = RefCell::new(Vec::new());
|
||||
|
||||
let instance = Sockets { sockets, wakers };
|
||||
unsafe {
|
||||
SOCKETS = Some(instance);
|
||||
}
|
||||
SOCKETS.set(instance).expect("SOCKETS can only be initialized once");
|
||||
}
|
||||
|
||||
#[allow(static_mut_refs)]
|
||||
pub fn instance() -> &'static Self {
|
||||
unsafe { SOCKETS.as_ref().expect("Sockets") }
|
||||
SOCKETS.get().expect("cannot get instance before it is initialized")
|
||||
}
|
||||
|
||||
pub fn poll<'b, D: for<'d> Device<'d>>(&self, iface: &mut EthernetInterface<'b, D>, instant: Instant) {
|
||||
|
||||
@@ -73,6 +73,7 @@ pub trait ClockSource {
|
||||
.clone();
|
||||
|
||||
debug!("Set {} to {} Hz", Self::name(), target_freq);
|
||||
log::logger().flush();
|
||||
slcr::RegisterBlock::unlocked(|slcr| {
|
||||
let (pll_ctrl, pll_cfg, pll_status) = Self::pll_regs(slcr);
|
||||
|
||||
|
||||
@@ -77,7 +77,5 @@ macro_rules! println {
|
||||
let mut uart = $crate::stdio::get_uart();
|
||||
let _ = write!(uart, $($arg)*);
|
||||
let _ = write!(uart, "\n");
|
||||
// flush after the newline
|
||||
while !uart.tx_idle() {}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
libboard_zynq = { path = "../libboard_zynq" }
|
||||
log = "0.4"
|
||||
libcortex_a9 = { path = "../libcortex_a9" }
|
||||
|
||||
[dependencies.core_io]
|
||||
git = "https://git.m-labs.hk/M-Labs/rs-core_io.git"
|
||||
|
||||
@@ -7,6 +7,7 @@ use core::fmt;
|
||||
|
||||
use core_io::{self as io, BufRead, BufReader, Read, Seek, SeekFrom, Write};
|
||||
use libboard_zynq::sdio;
|
||||
use libcortex_a9::once_lock::OnceLock;
|
||||
|
||||
pub mod bootgen;
|
||||
pub mod net_settings;
|
||||
@@ -66,12 +67,7 @@ fn parse_config(key: &str, buffer: &mut Vec<u8>, file: fatfs::File<sd_reader::Sd
|
||||
}
|
||||
|
||||
type FileSystem = fatfs::FileSystem<sd_reader::SdReader>;
|
||||
static mut FS: Option<FileSystem> = None;
|
||||
|
||||
#[allow(static_mut_refs)]
|
||||
pub fn get_filesystem() -> &'static Option<FileSystem> {
|
||||
unsafe { &FS }
|
||||
}
|
||||
pub static FS: OnceLock<FileSystem> = OnceLock::new();
|
||||
|
||||
const NEWLINE: &[u8] = b"\n";
|
||||
|
||||
@@ -85,18 +81,16 @@ pub fn init() -> Result<()> {
|
||||
|
||||
let fs = reader.mount_fatfs(sd_reader::PartitionEntry::Entry1)?;
|
||||
|
||||
unsafe {
|
||||
FS = Some(fs);
|
||||
}
|
||||
from_fs(fs);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn from_fs(fs: Option<FileSystem>) {
|
||||
unsafe { FS = fs }
|
||||
pub fn from_fs(fs: FileSystem) {
|
||||
FS.set(fs).expect("filesystem can only be initialized once");
|
||||
}
|
||||
|
||||
pub fn read(key: &str) -> Result<Vec<u8>> {
|
||||
if let Some(fs) = get_filesystem() {
|
||||
if let Some(fs) = FS.get() {
|
||||
let root_dir = fs.root_dir();
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
match root_dir.open_file(&["/CONFIG/", key, ".BIN"].concat()) {
|
||||
@@ -117,7 +111,7 @@ pub fn read_str(key: &str) -> Result<String> {
|
||||
}
|
||||
|
||||
pub fn remove(key: &str) -> Result<()> {
|
||||
if let Some(fs) = get_filesystem() {
|
||||
if let Some(fs) = FS.get() {
|
||||
let root_dir = fs.root_dir();
|
||||
match root_dir.remove(&["/CONFIG/", key, ".BIN"].concat()) {
|
||||
Ok(()) => Ok(()),
|
||||
@@ -147,10 +141,10 @@ pub fn remove(key: &str) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn write(key: &str, value: Vec<u8>) -> Result<()> {
|
||||
if get_filesystem().is_none() {
|
||||
if FS.get().is_none() {
|
||||
return Err(Error::NoConfig);
|
||||
}
|
||||
let fs = get_filesystem().as_ref().unwrap();
|
||||
let fs = FS.get().unwrap();
|
||||
let root_dir = fs.root_dir();
|
||||
let is_str = value.len() <= 100 && value.is_ascii() && !value.contains(&b'\n');
|
||||
if key == "boot" {
|
||||
|
||||
@@ -11,6 +11,14 @@ pub fn tlbiall() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Invalidate TLB for given MVA
|
||||
#[inline(always)]
|
||||
pub fn tlbimva(mva: u32) {
|
||||
unsafe {
|
||||
asm!("mcr p15, 0, {}, c8, c7, 1", in(reg) mva);
|
||||
}
|
||||
}
|
||||
|
||||
/// Invalidate I-Cache
|
||||
#[inline(always)]
|
||||
pub fn iciallu() {
|
||||
|
||||
@@ -9,6 +9,7 @@ mod fpu;
|
||||
pub mod l2c;
|
||||
pub mod mmu;
|
||||
pub mod mutex;
|
||||
pub mod once_lock;
|
||||
pub mod regs;
|
||||
pub mod semaphore;
|
||||
pub mod sync_channel;
|
||||
|
||||
@@ -401,6 +401,28 @@ impl L1Table {
|
||||
self.table[index] = L1Entry::from_section(base, section);
|
||||
}
|
||||
|
||||
pub fn remap_section(&mut self, virtual_addr: u32, new_physical_base: u32) {
|
||||
assert!(virtual_addr & 0x000f_ffff == 0);
|
||||
|
||||
let index = (virtual_addr >> 20) as usize;
|
||||
|
||||
let entry = &mut self.table[index];
|
||||
if entry.0 & !0x000f_ffff == new_physical_base {
|
||||
return;
|
||||
}
|
||||
let section = entry.get_section();
|
||||
*entry = L1Entry::from_section(new_physical_base, section);
|
||||
|
||||
// L1 I-cache cache is VIPT and 1MB page sizes guarantee different tags
|
||||
// L1 D-cache and L2 cache is PIPT, unaffected by virtual memory changes
|
||||
// thus flushing caches are unnecessary, we just
|
||||
// invalidate the updated TLB entry and the branch predictor
|
||||
tlbimva(virtual_addr);
|
||||
bpiall();
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
pub fn update<T, F, R>(&mut self, ptr: *const T, f: F) -> R
|
||||
where F: FnOnce(&'_ mut L1Section) -> R {
|
||||
let index = (ptr as usize) >> 20;
|
||||
@@ -413,6 +435,8 @@ impl L1Table {
|
||||
dcciall();
|
||||
// // TODO: L2?
|
||||
|
||||
// Invalidate I-Cache
|
||||
iciallu();
|
||||
// Invalidate TLB
|
||||
tlbiall();
|
||||
// Invalidate all branch predictors
|
||||
@@ -454,3 +478,7 @@ pub fn with_mmu<F: FnMut() -> !>(l1table: &L1Table, mut f: F) -> ! {
|
||||
|
||||
f();
|
||||
}
|
||||
|
||||
pub fn remap_section(virtual_addr: u32, new_physical_base: u32) {
|
||||
L1Table::get().remap_section(virtual_addr, new_physical_base);
|
||||
}
|
||||
|
||||
36
libcortex_a9/src/once_lock.rs
Normal file
36
libcortex_a9/src/once_lock.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use core::{cell::UnsafeCell,
|
||||
sync::atomic::{AtomicBool, Ordering}};
|
||||
|
||||
use crate::asm::{enter_critical, exit_critical};
|
||||
|
||||
pub struct OnceLock<T> {
|
||||
once: AtomicBool,
|
||||
data: UnsafeCell<Option<T>>,
|
||||
}
|
||||
|
||||
impl<T> OnceLock<T> {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
once: AtomicBool::new(false),
|
||||
data: UnsafeCell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&self, data: T) -> Result<(), ()> {
|
||||
let irq = unsafe { enter_critical() };
|
||||
let res = self
|
||||
.once
|
||||
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
|
||||
.map_err(|_| ())
|
||||
.map(|_| unsafe { *self.data.get() = Some(data) });
|
||||
unsafe { exit_critical(irq) };
|
||||
res
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Option<&T> {
|
||||
unsafe { &*self.data.get() }.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T> Sync for OnceLock<T> {}
|
||||
unsafe impl<T> Send for OnceLock<T> {}
|
||||
@@ -107,9 +107,15 @@ register_bit!(mpidr,
|
||||
pub struct DFAR;
|
||||
def_reg_r!(DFAR, u32, "mrc p15, 0, {}, c6, c0, 0");
|
||||
|
||||
pub struct IFAR;
|
||||
def_reg_r!(IFAR, u32, "mrc p15, 0, {}, c6, c0, 2");
|
||||
|
||||
pub struct DFSR;
|
||||
def_reg_r!(DFSR, u32, "mrc p15, 0, {}, c5, c0, 0");
|
||||
|
||||
pub struct IFSR;
|
||||
def_reg_r!(IFSR, u32, "mrc p15, 0, {}, c5, c0, 1");
|
||||
|
||||
pub struct SCTLR;
|
||||
wrap_reg!(sctlr);
|
||||
def_reg_r!(SCTLR, sctlr::Read, "mrc p15, 0, {}, c1, c0, 0");
|
||||
|
||||
@@ -2,7 +2,7 @@ use core::arch::naked_asm;
|
||||
|
||||
use libboard_zynq::{println, stdio};
|
||||
use libcortex_a9::{interrupt_handler,
|
||||
regs::{DFSR, MPIDR, VBAR}};
|
||||
regs::{DFAR, DFSR, IFAR, IFSR, MPIDR, VBAR}};
|
||||
use libregister::{RegisterR, RegisterW};
|
||||
|
||||
pub fn set_vector_table(base_addr: u32) {
|
||||
@@ -35,7 +35,9 @@ interrupt_handler!(
|
||||
|
||||
interrupt_handler!(PrefetchAbort, prefetch_abort, __irq_stack0_start, __irq_stack1_start, {
|
||||
stdio::drop_uart();
|
||||
println!("PrefetchAbort");
|
||||
println!("PrefetchAbort on core {}", MPIDR.read().cpu_id());
|
||||
println!("IFSR: {:03X}", IFSR.read());
|
||||
println!("IFAR: {:08X}", IFAR.read());
|
||||
loop {}
|
||||
});
|
||||
|
||||
@@ -44,6 +46,7 @@ interrupt_handler!(DataAbort, data_abort, __irq_stack0_start, __irq_stack1_start
|
||||
|
||||
println!("DataAbort on core {}", MPIDR.read().cpu_id());
|
||||
println!("DFSR: {:03X}", DFSR.read());
|
||||
println!("DFAR: {:08X}", DFAR.read());
|
||||
|
||||
loop {}
|
||||
});
|
||||
|
||||
@@ -87,21 +87,24 @@ pub fn main_core0() {
|
||||
ram::init_alloc_core0();
|
||||
|
||||
let sdio0 = sdio::Sdio::sdio0(true);
|
||||
let fs = if sdio0.is_card_inserted() {
|
||||
let mut bootgen_file = if sdio0.is_card_inserted() {
|
||||
info!("Card inserted. Mounting file system.");
|
||||
let sd = sdio::sd_card::SdCard::from_sdio(sdio0).unwrap();
|
||||
let reader = sd_reader::SdReader::new(sd);
|
||||
reader.mount_fatfs(sd_reader::PartitionEntry::Entry1).ok()
|
||||
reader
|
||||
.mount_fatfs(sd_reader::PartitionEntry::Entry1)
|
||||
.and_then(|fs| {
|
||||
libconfig::from_fs(fs);
|
||||
let fs_ref = libconfig::FS.get().unwrap();
|
||||
let root_dir = fs_ref.root_dir();
|
||||
root_dir.open_file("/BOOT.BIN")
|
||||
})
|
||||
.ok()
|
||||
} else {
|
||||
info!("No SD card inserted.");
|
||||
None
|
||||
};
|
||||
|
||||
libconfig::from_fs(fs);
|
||||
let fs_ref = libconfig::get_filesystem().as_ref();
|
||||
let root_dir = fs_ref.map(|fs| fs.root_dir());
|
||||
let mut bootgen_file = root_dir.and_then(|root_dir| root_dir.open_file("/BOOT.BIN").ok());
|
||||
|
||||
let max_len = (&raw const __runtime_end).addr() - (&raw const __runtime_start).addr();
|
||||
match slcr::RegisterBlock::unlocked(|slcr| slcr.boot_mode.read().boot_mode_pins()) {
|
||||
slcr::BootModePins::Jtag => netboot::netboot(&mut bootgen_file, (&raw mut __runtime_start).cast(), max_len),
|
||||
|
||||
Reference in New Issue
Block a user