1
0
Fork 0

Compare commits

...

20 Commits

Author SHA1 Message Date
Simon Renblad e894f502a4 fixup read_to_end impl 2024-10-31 15:09:14 +08:00
Simon Renblad cd56ef6d48 update Cargo lockfile 2024-10-31 15:09:14 +08:00
Simon Renblad 0a91f883bc up LLVM version, remove LLVM 11 copy 2024-10-31 15:09:14 +08:00
Simon Renblad 3e59dcbc94 remove UB assert in uncached 2024-10-31 15:09:14 +08:00
Simon Renblad 4138a65270 fix xbuild target features 2024-10-31 15:09:14 +08:00
Simon Renblad cb0ec48ef0 up cargo resolver 2024-10-31 15:09:14 +08:00
Simon Renblad 14dffaf49c fix panic message 2024-10-31 15:09:14 +08:00
Simon Renblad bd0c45497e up compiler builtins version 2024-10-31 15:09:14 +08:00
Simon Renblad 6dc831a8f8 up rust-fatfs to 0.4, remove core_io 2024-10-31 15:09:14 +08:00
Simon Renblad aef7dcabae fix const in arr expression 2024-10-31 15:09:09 +08:00
Simon Renblad 49a84da2ce migrate inline asm macro 2024-10-22 12:12:16 +08:00
Simon Renblad b00f297cd0 up rust edition to 2021 2024-10-22 12:10:39 +08:00
Simon Renblad 526e80401a up flake to 2024 nightly 2024-10-22 12:10:39 +08:00
newell cc20478d91 Add i2c support 2024-10-04 23:38:28 -07:00
Sebastien Bourdeauducq 5ef3016554 flake: update dependencies 2024-09-30 14:15:10 +08:00
newell 6a45a0dfd0 ebaz4205 support
Co-authored-by: newell <newell.jensen@gmail.com>
Co-committed-by: newell <newell.jensen@gmail.com>
2024-09-30 14:08:58 +08:00
Sebastien Bourdeauducq b2b3e5c933 flake: update dependencies 2024-07-09 17:03:22 +02:00
Simon Renblad 0efbbe39fe llvm: patch for artiq-zynq release-7 2024-06-06 14:06:56 +08:00
Sebastien Bourdeauducq 51b8111e79 flake: move to nixos 24.05 2024-05-28 17:37:50 +08:00
Simon Renblad 46dc25b89e add LLVM copy from nixpkgs 2024-05-24 10:57:12 +08:00
45 changed files with 547 additions and 293 deletions

View File

@ -1,7 +1,7 @@
[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-feature=+a9,+armv7-a,+neon",
"-C", "target-cpu=cortex-a9", "-C", "target-cpu=cortex-a9",
] ]

50
Cargo.lock generated
View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3
[[package]] [[package]]
name = "bit_field" name = "bit_field"
version = "0.10.1" version = "0.10.1"
@ -12,6 +14,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.4.3" version = "1.4.3"
@ -32,18 +40,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "compiler_builtins" name = "compiler_builtins"
version = "0.1.39" version = "0.1.109"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3748f82c7d366a0b4950257d19db685d4958d2fa27c6d164a3f069fec42b748b" checksum = "f11973008a8cf741fe6d22f339eba21fd0ca81e2760a769ba8243ed6c21edd7e"
[[package]]
name = "core_io"
version = "0.1.20210325"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97f8932064288cc79feb4d343a399d353a6f6f001e586ece47fe518a9e8507df"
dependencies = [
"rustc_version",
]
[[package]] [[package]]
name = "embedded-hal" name = "embedded-hal"
@ -70,13 +69,10 @@ dependencies = [
[[package]] [[package]]
name = "fatfs" name = "fatfs"
version = "0.3.5" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/rafalh/rust-fatfs?rev=85f06e0#85f06e08edbd3368e1b0562f2fc1b6d178bf7b8a"
checksum = "e18f80a87439240dac45d927fd8f8081b6f1e34c03e97271189fa8a8c2e96c8f"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.6.0",
"byteorder",
"core_io",
"log", "log",
] ]
@ -111,7 +107,6 @@ dependencies = [
name = "libconfig" name = "libconfig"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"core_io",
"fatfs", "fatfs",
"libboard_zynq", "libboard_zynq",
"log", "log",
@ -196,28 +191,13 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211" checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211"
[[package]]
name = "rustc_version"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
[[package]] [[package]]
name = "smoltcp" name = "smoltcp"
version = "0.7.5" version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e4a069bef843d170df47e7c0a8bf8d037f217d9f5b325865acc3e466ffe40d3" checksum = "3e4a069bef843d170df47e7c0a8bf8d037f217d9f5b325865acc3e466ffe40d3"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.3.2",
"byteorder", "byteorder",
"managed", "managed",
] ]
@ -227,7 +207,7 @@ name = "szl"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"core_io", "fatfs",
"libboard_zynq", "libboard_zynq",
"libconfig", "libconfig",
"libcortex_a9", "libcortex_a9",

View File

@ -9,6 +9,7 @@ members = [
"experiments", "experiments",
"szl", "szl",
] ]
resolver = "2"
[profile.release] [profile.release]
panic = "abort" panic = "abort"

View File

@ -3,11 +3,12 @@ name = "experiments"
description = "Developing bare-metal Rust on Zynq" description = "Developing bare-metal Rust on Zynq"
version = "0.0.0" version = "0.0.0"
authors = ["M-Labs"] authors = ["M-Labs"]
edition = "2018" edition = "2021"
[features] [features]
target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706"] target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706"]
target_coraz7 = ["libboard_zynq/target_coraz7", "libsupport_zynq/target_coraz7"] target_coraz7 = ["libboard_zynq/target_coraz7", "libsupport_zynq/target_coraz7"]
target_ebaz4205 = ["libboard_zynq/target_ebaz4205", "libsupport_zynq/target_ebaz4205"]
target_redpitaya = ["libboard_zynq/target_redpitaya", "libsupport_zynq/target_redpitaya"] target_redpitaya = ["libboard_zynq/target_redpitaya", "libsupport_zynq/target_redpitaya"]
target_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc"] target_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc"]
default = ["target_zc706"] default = ["target_zc706"]

View File

@ -1,12 +1,11 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(const_in_array_repeat_expressions)]
#![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},
@ -116,6 +115,7 @@ pub fn main_core0() {
#[cfg(any( #[cfg(any(
feature = "target_zc706", feature = "target_zc706",
feature = "target_ebaz4205",
feature = "target_redpitaya", feature = "target_redpitaya",
feature = "target_kasli_soc", feature = "target_kasli_soc",
))] ))]

View File

@ -18,16 +18,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1715087517, "lastModified": 1729181673,
"narHash": "sha256-CLU5Tsg24Ke4+7sH8azHWXKd0CFd4mhLWfhYgUiDBpQ=", "narHash": "sha256-LDiPhQ3l+fBjRATNtnuDZsBS7hqoBtPkKBkhpoBHv3I=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b211b392b8486ee79df6cdfb1157ad2133427a29", "rev": "4eb33fe664af7b41a4c446f87d20c9a0a6321fa3",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-unstable", "ref": "nixos-24.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }

View File

@ -1,7 +1,7 @@
{ {
description = "Bare-metal Rust on Zynq-7000"; description = "Bare-metal Rust on Zynq-7000";
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable; inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-24.05;
inputs.mozilla-overlay = { url = github:mozilla/nixpkgs-mozilla; flake = false; }; inputs.mozilla-overlay = { url = github:mozilla/nixpkgs-mozilla; flake = false; };
outputs = { self, nixpkgs, mozilla-overlay }: outputs = { self, nixpkgs, mozilla-overlay }:
@ -9,8 +9,8 @@
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import mozilla-overlay) crosspkgs-overlay ]; }; pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import mozilla-overlay) crosspkgs-overlay ]; };
rustManifest = pkgs.fetchurl { rustManifest = pkgs.fetchurl {
url = "https://static.rust-lang.org/dist/2021-01-29/channel-rust-nightly.toml"; url = "https://static.rust-lang.org/dist/2024-07-19/channel-rust-nightly.toml";
sha256 = "sha256-EZKgw89AH4vxaJpUHmIMzMW/80wAFQlfcxRoBD9nz0c="; sha256 = "sha256-MM2K43Kg+f83XQXT2lI7W/ZdQjLXhMUvA6eGtD+rqDY=";
}; };
rustTargets = []; rustTargets = [];
rustChannelOfTargets = _channel: _date: targets: rustChannelOfTargets = _channel: _date: targets:
@ -96,9 +96,7 @@
dontFixup = true; dontFixup = true;
}; };
cargo-xbuild = pkgs.cargo-xbuild.overrideAttrs(oa: { cargo-xbuild = pkgs.cargo-xbuild;
postPatch = "substituteInPlace src/sysroot.rs --replace 2021 2018";
});
build-crate = name: crate: features: rustPlatform.buildRustPackage rec { build-crate = name: crate: features: rustPlatform.buildRustPackage rec {
name = "${crate}"; name = "${crate}";
@ -106,9 +104,14 @@
src = builtins.filterSource (path: type: src = builtins.filterSource (path: type:
baseNameOf path != "target" baseNameOf path != "target"
) ./.; ) ./.;
cargoLock = { lockFile = ./Cargo.lock; }; cargoLock = {
lockFile = ./Cargo.lock;
outputHashes = {
"fatfs-0.4.0" = "sha256-P7IgvhwTPXtNhcyv8cFqwO2UdaEcCGJY7UBG6+yBFSg=";
};
};
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_14.clang-unwrapped ]; nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_18.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)
@ -134,7 +137,7 @@
"${target}-experiments" = build-crate "${target}-experiments" "experiments" "target_${target}"; "${target}-experiments" = build-crate "${target}-experiments" "experiments" "target_${target}";
"${target}-szl" = build-crate "${target}-szl" "szl" "target_${target}"; "${target}-szl" = build-crate "${target}-szl" "szl" "target_${target}";
}; };
targets = ["zc706" "coraz7" "redpitaya" "kasli_soc"]; targets = ["zc706" "coraz7" "redpitaya" "kasli_soc" "ebaz4205"];
allTargetCrates = (builtins.foldl' (results: target: allTargetCrates = (builtins.foldl' (results: target:
results // targetCrates target results // targetCrates target
) {} targets); ) {} targets);
@ -164,7 +167,7 @@
pkgs.openocd pkgs.gdb pkgs.openocd pkgs.gdb
pkgs.openssh pkgs.rsync pkgs.openssh pkgs.rsync
pkgs.llvmPackages_14.clang-unwrapped pkgs.llvmPackages_18.clang-unwrapped
(pkgs.python3.withPackages(ps: [ ps.pyftdi ])) (pkgs.python3.withPackages(ps: [ ps.pyftdi ]))
]; ];
}; };

View File

@ -3,7 +3,7 @@ name = "libasync"
description = "low-level async support" description = "low-level async support"
version = "0.0.0" version = "0.0.0"
authors = ["M-Labs"] authors = ["M-Labs"]
edition = "2018" edition = "2021"
[dependencies] [dependencies]
#futures = { version = "0.3", default-features = false } #futures = { version = "0.3", default-features = false }

View File

@ -3,11 +3,12 @@ name = "libboard_zynq"
description = "Drivers for peripherals in the Zynq PS" description = "Drivers for peripherals in the Zynq PS"
version = "0.0.0" version = "0.0.0"
authors = ["M-Labs"] authors = ["M-Labs"]
edition = "2018" edition = "2021"
[features] [features]
target_zc706 = [] target_zc706 = []
target_coraz7 = [] target_coraz7 = []
target_ebaz4205 = []
target_redpitaya = [] target_redpitaya = []
target_kasli_soc = [] target_kasli_soc = []
ipv6 = [ "smoltcp/proto-ipv6" ] ipv6 = [ "smoltcp/proto-ipv6" ]

View File

@ -1,3 +1,5 @@
use core::unimplemented;
use libregister::{RegisterR, RegisterRW}; use libregister::{RegisterR, RegisterRW};
use super::slcr; use super::slcr;
pub use slcr::ArmPllSource; pub use slcr::ArmPllSource;
@ -101,6 +103,8 @@ impl Clocks {
self.ddr, self.ddr,
slcr::PllSource::IoPll => slcr::PllSource::IoPll =>
self.io, self.io,
slcr::PllSource::Emio =>
unimplemented!(),
}; };
pll / u32::from(uart_clk_ctrl.divisor()) pll / u32::from(uart_clk_ctrl.divisor())
} }
@ -115,6 +119,8 @@ impl Clocks {
self.ddr, self.ddr,
slcr::PllSource::IoPll => slcr::PllSource::IoPll =>
self.io, self.io,
slcr::PllSource::Emio =>
unimplemented!(),
}; };
pll / u32::from(sdio_clk_ctrl.divisor()) pll / u32::from(sdio_clk_ctrl.divisor())
} }

View File

@ -6,6 +6,8 @@ use super::slcr;
pub const PS_CLK: u32 = 33_333_333; pub const PS_CLK: u32 = 33_333_333;
#[cfg(feature = "target_coraz7")] #[cfg(feature = "target_coraz7")]
pub const PS_CLK: u32 = 50_000_000; pub const PS_CLK: u32 = 50_000_000;
#[cfg(feature = "target_ebaz4205")]
pub const PS_CLK: u32 = 33_333_333;
#[cfg(feature = "target_redpitaya")] #[cfg(feature = "target_redpitaya")]
pub const PS_CLK: u32 = 33_333_333; pub const PS_CLK: u32 = 33_333_333;
#[cfg(feature = "target_kasli_soc")] #[cfg(feature = "target_kasli_soc")]

View File

@ -16,6 +16,10 @@ const DDR_FREQ: u32 = 666_666_666;
/// Micron MT41K256M16HA-125: 800 MHz DDR3L, max supported 533 MHz /// Micron MT41K256M16HA-125: 800 MHz DDR3L, max supported 533 MHz
const DDR_FREQ: u32 = 525_000_000; const DDR_FREQ: u32 = 525_000_000;
#[cfg(feature = "target_ebaz4205")]
/// EtronTech Memory EM6GD16EWKG-12H: 800 MHz DDR3 at 533 MHz
const DDR_FREQ: u32 = 533_333_333;
#[cfg(feature = "target_redpitaya")] #[cfg(feature = "target_redpitaya")]
/// Alliance Memory AS4C256M16D3B: 800 MHz DDR3 at 533 MHz /// Alliance Memory AS4C256M16D3B: 800 MHz DDR3 at 533 MHz
const DDR_FREQ: u32 = 533_333_333; const DDR_FREQ: u32 = 533_333_333;
@ -147,22 +151,23 @@ impl DdrRam {
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
let data1_config = data0_config.clone(); let data1_config = data0_config.clone();
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))] #[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
let data0_config = slcr::DdriobConfig::zeroed() let data0_config = slcr::DdriobConfig::zeroed()
.inp_type(slcr::DdriobInputType::VrefDifferential) .inp_type(slcr::DdriobInputType::VrefDifferential)
.term_en(true) .term_en(true)
.dci_type(slcr::DdriobDciType::Termination) .dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))] #[cfg(any(
let data1_config = slcr::DdriobConfig::zeroed() feature = "target_coraz7",
.pullup_en(true); feature = "target_ebaz4205",
#[cfg(feature = "target_redpitaya")] feature = "target_redpitaya",
let data0_config = slcr::DdriobConfig::zeroed() feature = "target_kasli_soc",
.inp_type(slcr::DdriobInputType::VrefDifferential) ))]
.term_en(true)
.dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(feature = "target_redpitaya")]
let data1_config = slcr::DdriobConfig::zeroed() let data1_config = slcr::DdriobConfig::zeroed()
.pullup_en(true); .pullup_en(true);
slcr.ddriob_data0.write(data0_config); slcr.ddriob_data0.write(data0_config);
@ -176,22 +181,23 @@ impl DdrRam {
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
let diff1_config = diff0_config.clone(); let diff1_config = diff0_config.clone();
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))] #[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
let diff0_config = slcr::DdriobConfig::zeroed() let diff0_config = slcr::DdriobConfig::zeroed()
.inp_type(slcr::DdriobInputType::Differential) .inp_type(slcr::DdriobInputType::Differential)
.term_en(true) .term_en(true)
.dci_type(slcr::DdriobDciType::Termination) .dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))] #[cfg(any(
let diff1_config = slcr::DdriobConfig::zeroed() feature = "target_coraz7",
.pullup_en(true); feature = "target_ebaz4205",
#[cfg(feature = "target_redpitaya")] feature = "target_redpitaya",
let diff0_config = slcr::DdriobConfig::zeroed() feature = "target_kasli_soc",
.inp_type(slcr::DdriobInputType::Differential) ))]
.term_en(true)
.dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(feature = "target_redpitaya")]
let diff1_config = slcr::DdriobConfig::zeroed() let diff1_config = slcr::DdriobConfig::zeroed()
.pullup_en(true); .pullup_en(true);
slcr.ddriob_diff0.write(diff0_config); slcr.ddriob_diff0.write(diff0_config);
@ -210,7 +216,12 @@ impl DdrRam {
slcr.ddriob_drive_slew_clock.write(0x00F9861C); slcr.ddriob_drive_slew_clock.write(0x00F9861C);
} }
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))] #[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
slcr.ddriob_ddr_ctrl.modify(|_, w| w slcr.ddriob_ddr_ctrl.modify(|_, w| w
.vref_int_en(false) .vref_int_en(false)
.vref_ext_en_lower(true) .vref_ext_en_lower(true)
@ -224,13 +235,6 @@ impl DdrRam {
.vref_ext_en_lower(false) .vref_ext_en_lower(false)
.vref_ext_en_upper(false) .vref_ext_en_upper(false)
); );
#[cfg(feature = "target_redpitaya")]
slcr.ddriob_ddr_ctrl.modify(|_, w| w
.vref_int_en(false)
.vref_ext_en_lower(true)
.vref_ext_en_upper(false)
.refio_en(true)
);
}); });
} }
@ -242,6 +246,13 @@ impl DdrRam {
.t_rfc_min(0x9e) .t_rfc_min(0x9e)
.post_selfref_gap_x32(0x10) .post_selfref_gap_x32(0x10)
); );
#[cfg(feature = "target_ebaz4205")]
self.regs.dram_param0.write(
regs::DramParam0::zeroed()
.t_rc(0x1a)
.t_rfc_min(0x56)
.post_selfref_gap_x32(0x10)
);
#[cfg(feature = "target_redpitaya")] #[cfg(feature = "target_redpitaya")]
self.regs.dram_param0.write( self.regs.dram_param0.write(
regs::DramParam0::zeroed() regs::DramParam0::zeroed()
@ -256,6 +267,12 @@ impl DdrRam {
.t_rfc_min(0x56) .t_rfc_min(0x56)
.post_selfref_gap_x32(0x10) .post_selfref_gap_x32(0x10)
); );
#[cfg(feature = "target_ebaz4205")]
self.regs.dram_param1.modify(
|_, w| w
.t_faw(0x16)
.t_ras_min(0x13)
);
#[cfg(feature = "target_redpitaya")] #[cfg(feature = "target_redpitaya")]
self.regs.dram_param1.modify( self.regs.dram_param1.modify(
|_, w| w |_, w| w
@ -277,6 +294,11 @@ impl DdrRam {
.rd2pre(0x4) .rd2pre(0x4)
.t_rcd(0x7) .t_rcd(0x7)
); );
#[cfg(feature = "target_ebaz4205")]
self.regs.dram_param3.modify(
|_, w| w
.t_rp(7)
);
#[cfg(feature = "target_redpitaya")] #[cfg(feature = "target_redpitaya")]
self.regs.dram_param3.modify( self.regs.dram_param3.modify(
|_, w| w |_, w| w
@ -298,19 +320,21 @@ impl DdrRam {
.emr(0x4) .emr(0x4)
); );
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))] #[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
self.regs.phy_configs[2].modify( self.regs.phy_configs[2].modify(
|_, w| w.data_slice_in_use(false) |_, w| w.data_slice_in_use(false)
); );
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))] #[cfg(any(
self.regs.phy_configs[3].modify( feature = "target_coraz7",
|_, w| w.data_slice_in_use(false) feature = "target_ebaz4205",
); feature = "target_redpitaya",
#[cfg(feature = "target_redpitaya")] feature = "target_kasli_soc",
self.regs.phy_configs[2].modify( ))]
|_, w| w.data_slice_in_use(false)
);
#[cfg(feature = "target_redpitaya")]
self.regs.phy_configs[3].modify( self.regs.phy_configs[3].modify(
|_, w| w.data_slice_in_use(false) |_, w| w.data_slice_in_use(false)
); );
@ -354,7 +378,11 @@ impl DdrRam {
.gatelvl_init_ratio(0xee) .gatelvl_init_ratio(0xee)
); );
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))] #[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_kasli_soc"),
)]
self.regs.reg_64.modify( self.regs.reg_64.modify(
|_, w| w |_, w| w
.phy_ctrl_slave_ratio(0x100) .phy_ctrl_slave_ratio(0x100)
@ -390,9 +418,12 @@ impl DdrRam {
fn reset_ddrc<F: FnMut(&mut Self)>(&mut self, mut f: F) { fn reset_ddrc<F: FnMut(&mut Self)>(&mut self, mut f: F) {
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
let width = regs::DataBusWidth::Width32bit; let width = regs::DataBusWidth::Width32bit;
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))] #[cfg(any(
let width = regs::DataBusWidth::Width16bit; feature = "target_coraz7",
#[cfg(feature = "target_redpitaya")] feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
let width = regs::DataBusWidth::Width16bit; let width = regs::DataBusWidth::Width16bit;
self.regs.ddrc_ctrl.modify(|_, w| w self.regs.ddrc_ctrl.modify(|_, w| w
.soft_rstb(false) .soft_rstb(false)
@ -410,6 +441,7 @@ impl DdrRam {
} }
#[cfg(any( #[cfg(any(
feature = "target_coraz7", feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya", feature = "target_redpitaya",
feature = "target_kasli_soc", feature = "target_kasli_soc",
))] ))]
@ -450,6 +482,8 @@ impl DdrRam {
feature = "target_kasli_soc", feature = "target_kasli_soc",
))] ))]
let megabytes = 512; let megabytes = 512;
#[cfg(feature = "target_ebaz4205")]
let megabytes = 256;
megabytes * 1024 * 1024 megabytes * 1024 * 1024
} }

View File

@ -65,17 +65,31 @@ impl Gem for Gem0 {
slcr.gem0_clk_ctrl.write( slcr.gem0_clk_ctrl.write(
// 0x0050_0801: 8, 5: 100 Mb/s // 0x0050_0801: 8, 5: 100 Mb/s
// ...: 8, 1: 1000 Mb/s // ...: 8, 1: 1000 Mb/s
#[cfg(not(feature = "target_ebaz4205"))]
slcr::GemClkCtrl::zeroed() slcr::GemClkCtrl::zeroed()
.clkact(true) .clkact(true)
.srcsel(slcr::PllSource::IoPll) .srcsel(slcr::PllSource::IoPll)
.divisor(divisor0 as u8) .divisor(divisor0 as u8)
.divisor1(divisor1 as u8),
// ebaz4205 -- EMIO
#[cfg(feature = "target_ebaz4205")]
slcr::GemClkCtrl::zeroed()
.clkact(true)
.srcsel(slcr::PllSource::Emio)
.divisor(divisor0 as u8)
.divisor1(divisor1 as u8) .divisor1(divisor1 as u8)
); );
// Enable gem0 recv clock // Enable gem0 recv clock
slcr.gem0_rclk_ctrl.write( slcr.gem0_rclk_ctrl.write(
// 0x0000_0801 // 0x0000_0801
#[cfg(not(feature = "target_ebaz4205"))]
slcr::RclkCtrl::zeroed()
.clkact(true),
// ebaz4205 -- EMIO
#[cfg(feature = "target_ebaz4205")]
slcr::RclkCtrl::zeroed() slcr::RclkCtrl::zeroed()
.clkact(true) .clkact(true)
.srcsel(true)
); );
}); });
} }
@ -154,6 +168,7 @@ pub struct Eth<GEM: Gem, RX, TX> {
impl Eth<Gem0, (), ()> { impl Eth<Gem0, (), ()> {
pub fn eth0(macaddr: [u8; 6]) -> Self { pub fn eth0(macaddr: [u8; 6]) -> Self {
#[cfg(not(feature = "target_ebaz4205"))]
slcr::RegisterBlock::unlocked(|slcr| { slcr::RegisterBlock::unlocked(|slcr| {
// Manual example: 0x0000_1280 // Manual example: 0x0000_1280
// MDIO // MDIO

View File

@ -83,6 +83,7 @@ pub struct Phy {
const OUI_MARVELL: u32 = 0x005043; const OUI_MARVELL: u32 = 0x005043;
const OUI_REALTEK: u32 = 0x000732; const OUI_REALTEK: u32 = 0x000732;
const OUI_LANTIQ : u32 = 0x355969; const OUI_LANTIQ : u32 = 0x355969;
const OUI_ICPLUS : u32 = 0x0090c3;
//only change pages on Kasli-SoC's Marvel 88E11xx //only change pages on Kasli-SoC's Marvel 88E11xx
#[cfg(feature="target_kasli_soc")] #[cfg(feature="target_kasli_soc")]
@ -117,6 +118,12 @@ impl Phy {
model: 0, model: 0,
.. ..
}) => true, }) => true,
Some(PhyIdentifier {
oui: OUI_ICPLUS,
// IP101G-DS-R01
model: 5,
rev: 4,
}) => true,
_ => false, _ => false,
} }
}).map(|addr| Phy { addr }) }).map(|addr| Phy { addr })

View File

@ -4,6 +4,7 @@ use embedded_hal::timer::CountDown;
pub struct EEPROM<'a> { pub struct EEPROM<'a> {
i2c: &'a mut I2c, i2c: &'a mut I2c,
#[cfg(not(feature = "target_ebaz4205"))]
port: u8, port: u8,
address: u8, address: u8,
page_size: u8, page_size: u8,
@ -46,6 +47,11 @@ impl<'a> EEPROM<'a> {
Ok(()) Ok(())
} }
#[cfg(feature = "target_ebaz4205")]
fn select(&mut self) -> Result<(), &'static str> {
Ok(())
}
/// Random read /// Random read
pub fn read<'r>(&mut self, addr: u8, buf: &'r mut [u8]) -> Result<(), &'static str> { pub fn read<'r>(&mut self, addr: u8, buf: &'r mut [u8]) -> Result<(), &'static str> {
self.select()?; self.select()?;

View File

@ -2,10 +2,13 @@
mod regs; mod regs;
pub mod eeprom; pub mod eeprom;
#[cfg(not(feature = "target_ebaz4205"))]
use super::slcr; use super::slcr;
use super::time::Microseconds; use super::time::Microseconds;
use embedded_hal::timer::CountDown; use embedded_hal::timer::CountDown;
use libregister::{RegisterR, RegisterRW, RegisterW}; use libregister::{RegisterR, RegisterRW};
#[cfg(not(feature = "target_ebaz4205"))]
use libregister::RegisterW;
#[cfg(feature = "target_kasli_soc")] #[cfg(feature = "target_kasli_soc")]
use log::info; use log::info;
@ -22,9 +25,10 @@ pub struct I2c {
} }
impl I2c { impl I2c {
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
pub fn i2c0() -> Self { pub fn i2c0() -> Self {
// Route I2C 0 SCL / SDA Signals to MIO Pins 50 / 51 // Route I2C 0 SCL / SDA Signals to MIO Pins 50 / 51
#[cfg(not(feature = "target_ebaz4205"))]
slcr::RegisterBlock::unlocked(|slcr| { slcr::RegisterBlock::unlocked(|slcr| {
// SCL // SCL
slcr.mio_pin_50.write( slcr.mio_pin_50.write(

View File

@ -21,6 +21,7 @@ use libregister::{
// Current compatibility: // Current compatibility:
// zc706: GPIO 50, 51 == SCL, SDA // zc706: GPIO 50, 51 == SCL, SDA
// kasli_soc: GPIO 50, 51 == SCL, SDA; GPIO 33 == I2C_SW_RESET // kasli_soc: GPIO 50, 51 == SCL, SDA; GPIO 33 == I2C_SW_RESET
// ebaz4205: GPIO (EMIO)
pub struct RegisterBlock { pub struct RegisterBlock {
pub gpio_output_mask: &'static mut GPIOOutputMask, pub gpio_output_mask: &'static mut GPIOOutputMask,
@ -48,17 +49,17 @@ register!(gpio_output_mask,
/// MASK_DATA_1_MSW: /// MASK_DATA_1_MSW:
/// Maskable output data for MIO[53:48] /// Maskable output data for MIO[53:48]
GPIOOutputMask, RW, u32); GPIOOutputMask, RW, u32);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_at!(GPIOOutputMask, 0xE000A00C, new); register_at!(GPIOOutputMask, 0xE000A00C, new);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_bit!(gpio_output_mask, register_bit!(gpio_output_mask,
/// Output for SCL /// Output for SCL
scl_o, 2); scl_o, 2);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_bit!(gpio_output_mask, register_bit!(gpio_output_mask,
/// Output for SDA /// Output for SDA
sda_o, 3); sda_o, 3);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_bits!(gpio_output_mask, register_bits!(gpio_output_mask,
/// Mask for keeping bits except SCL and SDA unchanged /// Mask for keeping bits except SCL and SDA unchanged
mask, u16, 16, 31); mask, u16, 16, 31);
@ -82,13 +83,13 @@ register!(gpio_input,
/// DATA_1_RO: /// DATA_1_RO:
/// Input data for MIO[53:32] /// Input data for MIO[53:32]
GPIOInput, RO, u32); GPIOInput, RO, u32);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_at!(GPIOInput, 0xE000A064, new); register_at!(GPIOInput, 0xE000A064, new);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_bit!(gpio_input, register_bit!(gpio_input,
/// Input for SCL /// Input for SCL
scl, 18); scl, 18);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_bit!(gpio_input, register_bit!(gpio_input,
/// Input for SDA /// Input for SDA
sda, 19); sda, 19);
@ -98,13 +99,13 @@ register!(gpio_direction,
/// DIRM_1: /// DIRM_1:
/// Direction mode for MIO[53:32]; 0/1 = in/out /// Direction mode for MIO[53:32]; 0/1 = in/out
GPIODirection, RW, u32); GPIODirection, RW, u32);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_at!(GPIODirection, 0xE000A244, new); register_at!(GPIODirection, 0xE000A244, new);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_bit!(gpio_direction, register_bit!(gpio_direction,
/// Direction for SCL /// Direction for SCL
scl, 18); scl, 18);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_bit!(gpio_direction, register_bit!(gpio_direction,
/// Direction for SDA /// Direction for SDA
sda, 19); sda, 19);
@ -117,13 +118,13 @@ register!(gpio_output_enable,
/// OEN_1: /// OEN_1:
/// Output enable for MIO[53:32] /// Output enable for MIO[53:32]
GPIOOutputEnable, RW, u32); GPIOOutputEnable, RW, u32);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_at!(GPIOOutputEnable, 0xE000A248, new); register_at!(GPIOOutputEnable, 0xE000A248, new);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_bit!(gpio_output_enable, register_bit!(gpio_output_enable,
/// Output enable for SCL /// Output enable for SCL
scl, 18); scl, 18);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
register_bit!(gpio_output_enable, register_bit!(gpio_output_enable,
/// Output enable for SDA /// Output enable for SDA
sda, 19); sda, 19);

View File

@ -19,7 +19,7 @@ pub mod gic;
pub mod time; pub mod time;
pub mod timer; pub mod timer;
pub mod sdio; pub mod sdio;
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_zc706", feature = "target_kasli_soc", feature = "target_ebaz4205"))]
pub mod i2c; pub mod i2c;
pub mod logger; pub mod logger;
pub mod ps7_init; pub mod ps7_init;

View File

@ -116,8 +116,8 @@ impl Sdio {
.speed(true), .speed(true),
); );
} }
// redpitaya card detect pin // kasli_soc and redpitaya card detect pin
#[cfg(any(feature = "target_redpitaya", feature = "target_kasli_soc"))] #[cfg(any(feature = "target_kasli_soc", feature = "target_redpitaya"))]
{ {
unsafe { unsafe {
slcr.sd0_wp_cd_sel.write(46 << 16); slcr.sd0_wp_cd_sel.write(46 << 16);
@ -128,6 +128,20 @@ impl Sdio {
.speed(true), .speed(true),
); );
} }
// ebaz4205 card detect pin
#[cfg(feature = "target_ebaz4205")]
{
unsafe {
slcr.sd0_wp_cd_sel.write(34 << 16);
}
slcr.mio_pin_34.write(
slcr::MioPin34::zeroed()
.io_type(slcr::IoBufferType::Lvcmos33)
.pullup(true)
.speed(true),
);
}
slcr.sdio_rst_ctrl.reset_sdio0(); slcr.sdio_rst_ctrl.reset_sdio0();
slcr.aper_clk_ctrl.enable_sdio0(); slcr.aper_clk_ctrl.enable_sdio0();
slcr.sdio_clk_ctrl.enable_sdio0(); slcr.sdio_clk_ctrl.enable_sdio0();

View File

@ -9,9 +9,11 @@ use libregister::{
#[repr(u8)] #[repr(u8)]
pub enum PllSource { pub enum PllSource {
IoPll = 0b00, IoPll = 0b000,
ArmPll = 0b10, ArmPll = 0b010,
DdrPll = 0b11, DdrPll = 0b011,
// Ethernet controller 0 EMIO clock
Emio = 0b100,
} }
#[repr(u8)] #[repr(u8)]

View File

@ -47,7 +47,11 @@ impl DerefMut for LazyUart {
LazyUart::Uninitialized => { LazyUart::Uninitialized => {
#[cfg(any(feature = "target_coraz7", feature = "target_redpitaya"))] #[cfg(any(feature = "target_coraz7", feature = "target_redpitaya"))]
let uart = Uart::uart0(UART_RATE); let uart = Uart::uart0(UART_RATE);
#[cfg(any(feature = "target_zc706", feature = "target_kasli_soc"))] #[cfg(any(
feature = "target_zc706",
feature = "target_ebaz4205",
feature = "target_kasli_soc",
))]
let uart = Uart::uart1(UART_RATE); let uart = Uart::uart1(UART_RATE);
*self = LazyUart::Initialized(uart); *self = LazyUart::Initialized(uart);
self self

View File

@ -79,6 +79,39 @@ impl Uart {
self_ self_
} }
#[cfg(feature = "target_ebaz4205")]
pub fn uart1(baudrate: u32) -> Self {
slcr::RegisterBlock::unlocked(|slcr| {
// Route UART 1 RxD/TxD Signals to MIO Pins
// TX pin
slcr.mio_pin_24.write(
slcr::MioPin24::zeroed()
.l3_sel(0b111)
.io_type(slcr::IoBufferType::Lvcmos33)
.pullup(true)
);
// RX pin
slcr.mio_pin_25.write(
slcr::MioPin25::zeroed()
.tri_enable(true)
.l3_sel(0b111)
.io_type(slcr::IoBufferType::Lvcmos33)
.pullup(true)
);
});
slcr::RegisterBlock::unlocked(|slcr| {
slcr.uart_rst_ctrl.reset_uart1();
slcr.aper_clk_ctrl.enable_uart1();
slcr.uart_clk_ctrl.enable_uart1();
});
let mut self_ = Uart {
regs: regs::RegisterBlock::uart1(),
};
self_.configure(baudrate);
self_
}
pub fn write_byte(&mut self, value: u8) { pub fn write_byte(&mut self, value: u8) {
while self.tx_fifo_full() {} while self.tx_fifo_full() {}

View File

@ -2,17 +2,22 @@
name = "libconfig" name = "libconfig"
version = "0.1.0" version = "0.1.0"
authors = ["M-Labs"] authors = ["M-Labs"]
edition = "2018" edition = "2021"
[dependencies] [dependencies]
libboard_zynq = { path = "../libboard_zynq" } libboard_zynq = { path = "../libboard_zynq" }
core_io = { version = "0.1", features = ["collections"] }
fatfs = { version = "0.3", features = ["core_io"], default-features = false }
log = "0.4" log = "0.4"
[dependencies.fatfs]
git = "https://github.com/rafalh/rust-fatfs"
rev = "85f06e0"
default-features = false
features = ["alloc", "lfn"]
[features] [features]
target_zc706 = [] target_zc706 = []
target_coraz7 = [] target_coraz7 = []
target_ebaz4205 = []
target_redpitaya = [] target_redpitaya = []
target_kasli_soc = [] target_kasli_soc = []
ipv6 = [] ipv6 = []

View File

@ -1,8 +1,12 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use core_io::{Error, Read, Seek, SeekFrom}; use fatfs::{self, Read, Seek, SeekFrom};
use libboard_zynq::devc; use libboard_zynq::devc;
use crate::sd_reader;
use crate::File;
use log::debug; use log::debug;
type Error = fatfs::Error<sd_reader::Error>;
#[derive(Debug)] #[derive(Debug)]
pub enum BootgenLoadingError { pub enum BootgenLoadingError {
InvalidBootImageHeader, InvalidBootImageHeader,
@ -58,7 +62,7 @@ struct PartitionHeader {
} }
/// Read a u32 word from the reader. /// Read a u32 word from the reader.
fn read_u32<Reader: Read>(reader: &mut Reader) -> Result<u32, BootgenLoadingError> { fn read_u32<'a>(reader: &mut File<'a>) -> Result<u32, BootgenLoadingError> {
let mut buffer: [u8; 4] = [0; 4]; let mut buffer: [u8; 4] = [0; 4];
reader.read_exact(&mut buffer)?; reader.read_exact(&mut buffer)?;
let mut result: u32 = 0; let mut result: u32 = 0;
@ -69,8 +73,8 @@ fn read_u32<Reader: Read>(reader: &mut Reader) -> Result<u32, BootgenLoadingErro
} }
/// Load PL partition header. /// Load PL partition header.
fn load_pl_header<File: Read + Seek>( fn load_pl_header<'a>(
file: &mut File, file: &mut File<'a>,
) -> Result<Option<PartitionHeader>, BootgenLoadingError> { ) -> Result<Option<PartitionHeader>, BootgenLoadingError> {
let mut buffer: [u8; 0x40] = [0; 0x40]; let mut buffer: [u8; 0x40] = [0; 0x40];
file.read_exact(&mut buffer)?; file.read_exact(&mut buffer)?;
@ -82,8 +86,8 @@ fn load_pl_header<File: Read + Seek>(
} }
} }
fn load_ps_header<File: Read + Seek>( fn load_ps_header<'a>(
file: &mut File, file: &mut File<'a>,
) -> Result<Option<PartitionHeader>, BootgenLoadingError> { ) -> Result<Option<PartitionHeader>, BootgenLoadingError> {
let mut buffer: [u8; 0x40] = [0; 0x40]; let mut buffer: [u8; 0x40] = [0; 0x40];
file.read_exact(&mut buffer)?; file.read_exact(&mut buffer)?;
@ -98,10 +102,10 @@ fn load_ps_header<File: Read + Seek>(
/// Locate the partition from the image, and return the size (in bytes) of the partition if successful. /// Locate the partition from the image, and return the size (in bytes) of the partition if successful.
/// This function would seek the file to the location of the partition. /// This function would seek the file to the location of the partition.
fn locate< fn locate<
File: Read + Seek, 'a,
F: Fn(&mut File) -> Result<Option<PartitionHeader>, BootgenLoadingError>, F: Fn(&mut File<'a>) -> Result<Option<PartitionHeader>, BootgenLoadingError>,
>( >(
file: &mut File, file: &mut File<'a>,
f: F, f: F,
) -> Result<usize, BootgenLoadingError> { ) -> Result<usize, BootgenLoadingError> {
file.seek(SeekFrom::Start(0))?; file.seek(SeekFrom::Start(0))?;
@ -149,7 +153,7 @@ fn locate<
/// Load bitstream from bootgen file. /// Load bitstream from bootgen file.
/// This function parses the file, locate the bitstream and load it through the PCAP driver. /// This function parses the file, locate the bitstream and load it through the PCAP driver.
/// It requires a large buffer, please enable the DDR RAM before using it. /// It requires a large buffer, please enable the DDR RAM before using it.
pub fn load_bitstream<File: Read + Seek>(file: &mut File) -> Result<(), BootgenLoadingError> { pub fn load_bitstream<'a>(file: &mut File<'a>) -> Result<(), BootgenLoadingError> {
let size = locate(file, load_pl_header)?; let size = locate(file, load_pl_header)?;
unsafe { unsafe {
// align to 64 bytes // align to 64 bytes
@ -170,7 +174,7 @@ pub fn load_bitstream<File: Read + Seek>(file: &mut File) -> Result<(), BootgenL
} }
} }
pub fn get_runtime<File: Read + Seek>(file: &mut File) -> Result<Vec<u8>, BootgenLoadingError> { pub fn get_runtime<'a>(file: &mut File<'a>) -> Result<Vec<u8>, BootgenLoadingError> {
let size = locate(file, load_ps_header)?; let size = locate(file, load_ps_header)?;
let mut buffer = Vec::with_capacity(size); let mut buffer = Vec::with_capacity(size);
unsafe { unsafe {

View File

@ -1,19 +1,24 @@
#![no_std] #![no_std]
extern crate alloc; extern crate alloc;
use core::fmt; use alloc::{rc::Rc, string::{FromUtf8Error, String}, vec::Vec};
use alloc::{string::FromUtf8Error, string::String, vec::Vec, rc::Rc}; use sd_reader::SdReader;
use core_io::{self as io, BufRead, BufReader, Read, Write, Seek, SeekFrom}; use core::{cmp, fmt};
use fatfs::{self, Read, Seek, SeekFrom, Write};
use libboard_zynq::sdio; use libboard_zynq::sdio;
pub mod sd_reader;
pub mod net_settings;
pub mod bootgen; pub mod bootgen;
pub mod net_settings;
pub mod sd_reader;
type SdReadError = fatfs::Error<sd_reader::Error>;
pub type File<'a> = fatfs::File<'a, SdReader, fatfs::NullTimeProvider, fatfs::LossyOemCpConverter>;
#[derive(Debug)] #[derive(Debug)]
pub enum Error<'a> { pub enum Error<'a> {
SdError(sdio::sd_card::CardInitializationError), SdError(sdio::sd_card::CardInitializationError),
IoError(io::Error), IoError(SdReadError),
Utf8Error(FromUtf8Error), Utf8Error(FromUtf8Error),
KeyNotFoundError(&'a str), KeyNotFoundError(&'a str),
NoConfig, NoConfig,
@ -39,8 +44,8 @@ impl<'a> From<sdio::sd_card::CardInitializationError> for Error<'a> {
} }
} }
impl<'a> From<io::Error> for Error<'a> { impl<'a> From<SdReadError> for Error<'a> {
fn from(error: io::Error) -> Self { fn from(error: SdReadError) -> Self {
Error::IoError(error) Error::IoError(error)
} }
} }
@ -51,14 +56,60 @@ impl<'a> From<FromUtf8Error> for Error<'a> {
} }
} }
// Simplified replacements to `read_to_end` and `read_to_string` from core_io
fn read_to_end<'a>(file: &mut File<'a>, buffer: &mut Vec<u8>) -> Result<'a, usize> {
const PROBE_SIZE: usize = 32;
const MAX_READ_SIZE: usize = 512; // read max BLOCK_SIZE at a time
let start_len = buffer.len();
let start_cap = buffer.capacity();
fn small_probe_read<'a>(file: &mut File<'a>, buffer: &mut Vec<u8>) -> Result<'a, usize> {
let mut probe = [0u8; PROBE_SIZE];
let n = file.read(&mut probe)?;
buffer.extend_from_slice(&probe[..n]);
Ok(n)
}
if start_cap - start_len < PROBE_SIZE {
let read = small_probe_read(file, buffer)?;
if read == 0 {
return Ok(0);
}
}
loop {
if buffer.len() == buffer.capacity() && buffer.capacity() == start_cap {
let read = small_probe_read(file, buffer)?;
if read == 0 {
return Ok(buffer.len() - start_len);
}
}
if buffer.len() == buffer.capacity() {
buffer.try_reserve(PROBE_SIZE).unwrap();
}
let mut read_buf = [0u8; MAX_READ_SIZE];
let buf_len = cmp::min(MAX_READ_SIZE, buffer.capacity() - buffer.len());
let mut read_buf_mut = &mut read_buf[..buf_len];
let bytes_read = file.read(&mut read_buf_mut)?;
if bytes_read == 0 {
return Ok(buffer.len() - start_len);
}
buffer.extend_from_slice(&read_buf_mut[..bytes_read]);
}
}
fn read_to_string<'a>(file: &mut File<'a>) -> Result<'a, String> {
let mut buffer: Vec<u8> = Vec::new();
read_to_end(file, &mut buffer).map(|_| ())?;
Ok(String::from_utf8(buffer)?)
}
fn parse_config<'a>( fn parse_config<'a>(
key: &'a str, key: &'a str,
buffer: &mut Vec<u8>, buffer: &mut Vec<u8>,
file: fatfs::File<sd_reader::SdReader>, mut file: File<'a>,
) -> Result<'a, ()> { ) -> Result<'a, ()> {
let prefix = [key, "="].concat().to_ascii_lowercase(); let prefix = [key, "="].concat().to_ascii_lowercase();
for line in BufReader::new(file).lines() { let read_buffer = read_to_string(&mut file)?;
let line = line?.to_ascii_lowercase(); for line in read_buffer.lines() {
let line = line.to_ascii_lowercase();
if line.starts_with(&prefix) { if line.starts_with(&prefix) {
buffer.extend(line[prefix.len()..].as_bytes()); buffer.extend(line[prefix.len()..].as_bytes());
return Ok(()); return Ok(());
@ -83,7 +134,9 @@ impl Config {
let reader = sd_reader::SdReader::new(sd); let reader = sd_reader::SdReader::new(sd);
let fs = reader.mount_fatfs(sd_reader::PartitionEntry::Entry1)?; let fs = reader.mount_fatfs(sd_reader::PartitionEntry::Entry1)?;
Ok(Config { fs: Some(Rc::new(fs)) }) Ok(Config {
fs: Some(Rc::new(fs)),
})
} }
pub fn from_fs(fs: Option<Rc<fatfs::FileSystem<sd_reader::SdReader>>>) -> Self { pub fn from_fs(fs: Option<Rc<fatfs::FileSystem<sd_reader::SdReader>>>) -> Self {
@ -94,12 +147,12 @@ impl Config {
Config { fs: None } Config { fs: None }
} }
pub fn read<'b>(&self, key: &'b str) -> Result<'b, Vec<u8>> { pub fn read<'b>(&'b self, key: &'b str) -> Result<'b, Vec<u8>> {
if let Some(fs) = &self.fs { if let Some(fs) = &self.fs {
let root_dir = fs.root_dir(); let root_dir = fs.root_dir();
let mut buffer: Vec<u8> = Vec::new(); let mut buffer: Vec<u8> = Vec::new();
match root_dir.open_file(&["/CONFIG/", key, ".BIN"].concat()) { match root_dir.open_file(&["/CONFIG/", key, ".BIN"].concat()) {
Ok(mut f) => f.read_to_end(&mut buffer).map(|_| ())?, Ok(mut f) => read_to_end( &mut f, &mut buffer).map(|_| ())?,
Err(_) => match root_dir.open_file("/CONFIG.TXT") { Err(_) => match root_dir.open_file("/CONFIG.TXT") {
Ok(f) => parse_config(key, &mut buffer, f)?, Ok(f) => parse_config(key, &mut buffer, f)?,
Err(_) => return Err(Error::KeyNotFoundError(key)), Err(_) => return Err(Error::KeyNotFoundError(key)),
@ -111,11 +164,11 @@ impl Config {
} }
} }
pub fn read_str<'b>(&self, key: &'b str) -> Result<'b, String> { pub fn read_str<'b>(&'b self, key: &'b str) -> Result<'b, String> {
Ok(String::from_utf8(self.read(key)?)?) Ok(String::from_utf8(self.read(key)?)?)
} }
pub fn remove<'b>(&self, key: &'b str) -> Result<'b, ()> { pub fn remove<'b>(&'b self, key: &'b str) -> Result<'b, ()> {
if let Some(fs) = &self.fs { if let Some(fs) = &self.fs {
let root_dir = fs.root_dir(); let root_dir = fs.root_dir();
match root_dir.remove(&["/CONFIG/", key, ".BIN"].concat()) { match root_dir.remove(&["/CONFIG/", key, ".BIN"].concat()) {
@ -124,19 +177,19 @@ impl Config {
let prefix = [key, "="].concat().to_ascii_lowercase(); let prefix = [key, "="].concat().to_ascii_lowercase();
match root_dir.create_file("/CONFIG.TXT") { match root_dir.create_file("/CONFIG.TXT") {
Ok(mut f) => { Ok(mut f) => {
let mut buffer = String::new(); let buffer = read_to_string(&mut f)?;
f.read_to_string(&mut buffer)?;
f.seek(SeekFrom::Start(0))?; f.seek(SeekFrom::Start(0))?;
f.truncate()?; f.truncate()?;
for line in buffer.lines() { for line in buffer.lines() {
if line.len() > 0 && !line.to_ascii_lowercase().starts_with(&prefix) { if line.len() > 0 && !line.to_ascii_lowercase().starts_with(&prefix)
{
f.write(line.as_bytes())?; f.write(line.as_bytes())?;
f.write(NEWLINE)?; f.write(NEWLINE)?;
} }
} }
Ok(()) Ok(())
}, }
Err(_) => Err(Error::KeyNotFoundError(key)) Err(_) => Err(Error::KeyNotFoundError(key)),
} }
} }
} }
@ -162,7 +215,10 @@ impl Config {
if is_str { if is_str {
let mut f = root_dir.create_file("/CONFIG.TXT")?; let mut f = root_dir.create_file("/CONFIG.TXT")?;
f.seek(SeekFrom::End(0))?; f.seek(SeekFrom::End(0))?;
write!(f, "{}={}\n", key, String::from_utf8(value).unwrap())?; f.write(key.as_bytes())?;
f.write("=".as_bytes())?;
f.write(value.as_slice())?;
f.write(NEWLINE)?;
} else { } else {
let dir = root_dir.create_dir("/CONFIG")?; let dir = root_dir.create_dir("/CONFIG")?;
let mut f = dir.create_file(&[key, ".BIN"].concat())?; let mut f = dir.create_file(&[key, ".BIN"].concat())?;

View File

@ -59,6 +59,10 @@ pub fn get_addresses(cfg: &Config) -> NetAddresses {
let mut hardware_addr = get_address_from_eeprom(); let mut hardware_addr = get_address_from_eeprom();
#[cfg(feature = "target_kasli_soc")] #[cfg(feature = "target_kasli_soc")]
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 56); let mut ipv4_addr = IpAddress::v4(192, 168, 1, 56);
#[cfg(feature = "target_ebaz4205")]
let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x57]);
#[cfg(feature = "target_ebaz4205")]
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 57);
if let Ok(Ok(addr)) = cfg.read_str("mac").map(|s| s.parse()) { if let Ok(Ok(addr)) = cfg.read_str("mac").map(|s| s.parse()) {
hardware_addr = addr; hardware_addr = addr;

View File

@ -1,8 +1,8 @@
use core_io::{BufRead, Error, ErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write}; use alloc::vec::Vec;
use fatfs; use core::fmt;
use fatfs::{self, IoBase, IoError, Read, Seek, SeekFrom, Write};
use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError}; use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError};
use log::debug; use log::debug;
use alloc::vec::Vec;
const MBR_SIGNATURE: [u8; 2] = [0x55, 0xAA]; const MBR_SIGNATURE: [u8; 2] = [0x55, 0xAA];
const PARTID_FAT12: u8 = 0x01; const PARTID_FAT12: u8 = 0x01;
@ -12,13 +12,46 @@ const PARTID_FAT32: u8 = 0x0B;
const PARTID_FAT32_LBA: u8 = 0x0C; const PARTID_FAT32_LBA: u8 = 0x0C;
const PARTID_FAT16_LBA: u8 = 0x0E; const PARTID_FAT16_LBA: u8 = 0x0E;
fn cmd_error_to_io_error(_: CmdTransferError) -> Error {
Error::new(ErrorKind::Other, "Command transfer error")
}
const BLOCK_SIZE: usize = 512; const BLOCK_SIZE: usize = 512;
/// SdReader struct implementing `Read + BufRead + Write + Seek` traits for `core_io`. #[derive(Debug)]
pub struct Error {
message: &'static str,
}
impl Error {
pub fn new(message: &'static str) -> Self {
Self { message: message }
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl IoError for Error {
fn is_interrupted(&self) -> bool {
false
}
fn new_unexpected_eof_error() -> Self {
Error::new("Unexpected end of file error")
}
fn new_write_zero_error() -> Self {
Error::new("Write zero error")
}
}
impl From<CmdTransferError> for Error {
fn from(_: CmdTransferError) -> Self {
Error::new("Command transfer error")
}
}
/// SdReader struct implementing `Read + Write + Seek` traits for `core_io`.
/// Used as an adaptor for fatfs crate, but could be used directly for raw data access. /// Used as an adaptor for fatfs crate, but could be used directly for raw data access.
/// ///
/// Implementation: all read/writes would be split into unaligned and block-aligned parts, /// Implementation: all read/writes would be split into unaligned and block-aligned parts,
@ -43,6 +76,10 @@ pub struct SdReader {
offset: u32, offset: u32,
} }
impl IoBase for SdReader {
type Error = Error;
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[allow(unused)] #[allow(unused)]
// Partition entry enum, normally we would use entry1. // Partition entry enum, normally we would use entry1.
@ -72,7 +109,7 @@ impl SdReader {
/// Internal read function for unaligned read. /// Internal read function for unaligned read.
/// The read must not cross block boundary. /// The read must not cross block boundary.
fn read_unaligned(&mut self, buf: &mut [u8]) -> IoResult<usize> { fn read_unaligned(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
if buf.len() == 0 { if buf.len() == 0 {
return Ok(0); return Ok(0);
} }
@ -86,7 +123,7 @@ impl SdReader {
/// Internal write function for unaligned write. /// Internal write function for unaligned write.
/// The write must not cross block boundary. /// The write must not cross block boundary.
fn write_unaligned(&mut self, buf: &[u8]) -> IoResult<usize> { fn write_unaligned(&mut self, buf: &[u8]) -> Result<usize, Error> {
if buf.len() == 0 { if buf.len() == 0 {
return Ok(0); return Ok(0);
} }
@ -137,7 +174,7 @@ impl SdReader {
} }
/// Set the base offset of the SD card, to transform from physical address to logical address. /// Set the base offset of the SD card, to transform from physical address to logical address.
fn set_base_offset(&mut self, offset: u32) -> IoResult<u64> { fn set_base_offset(&mut self, offset: u32) -> Result<u64, Error> {
self.offset = offset; self.offset = offset;
self.seek(SeekFrom::Start(0)) self.seek(SeekFrom::Start(0))
} }
@ -145,29 +182,28 @@ impl SdReader {
/// Mount fatfs from partition entry, and return the fatfs object if success. /// Mount fatfs from partition entry, and return the fatfs object if success.
/// This takes the ownership of self, so currently there is no way to recover from an error, /// This takes the ownership of self, so currently there is no way to recover from an error,
/// except creating a new SD card instance. /// except creating a new SD card instance.
pub fn mount_fatfs(mut self, entry: PartitionEntry) -> IoResult<fatfs::FileSystem<Self>> { pub fn mount_fatfs(
mut self,
entry: PartitionEntry,
) -> Result<fatfs::FileSystem<Self>, fatfs::Error<Error>> {
let mut buffer: [u8; 4] = [0; 4]; let mut buffer: [u8; 4] = [0; 4];
self.seek(SeekFrom::Start(0x1FE))?; self.seek(SeekFrom::Start(0x1FE))?;
self.read_exact(&mut buffer[..2])?; self.read_exact(&mut buffer[..2])?;
// check MBR signature // check MBR signature
if buffer[..2] != MBR_SIGNATURE { if buffer[..2] != MBR_SIGNATURE {
return Err(Error::new( return Err(fatfs::Error::Io(Error::new("Incorrect signature for MBR sector.")));
ErrorKind::InvalidData,
"Incorrect signature for MBR sector.",
));
} }
// Read partition ID. // Read partition ID.
self.seek(SeekFrom::Start(entry as u64 + 0x4))?; self.seek(SeekFrom::Start(entry as u64 + 0x4))?;
self.read_exact(&mut buffer[..1])?; self.read_exact(&mut buffer[..1])?;
debug!("Partition ID: {:0X}", buffer[0]); debug!("Partition ID: {:0X}", buffer[0]);
match buffer[0] { match buffer[0] {
PARTID_FAT12 | PARTID_FAT16_LESS32M | PARTID_FAT16 | PARTID_FAT12 | PARTID_FAT16_LESS32M | PARTID_FAT16 | PARTID_FAT16_LBA
PARTID_FAT16_LBA | PARTID_FAT32 | PARTID_FAT32_LBA => {} | PARTID_FAT32 | PARTID_FAT32_LBA => {}
_ => { _ => {
return Err(Error::new( return Err(fatfs::Error::Io(Error::new(
ErrorKind::InvalidData,
"No FAT partition found for the specified entry.", "No FAT partition found for the specified entry.",
)); )));
} }
} }
// Read LBA // Read LBA
@ -183,10 +219,29 @@ impl SdReader {
// setup fatfs // setup fatfs
fatfs::FileSystem::new(self, fatfs::FsOptions::new()) fatfs::FileSystem::new(self, fatfs::FsOptions::new())
} }
fn fill_buf(&mut self) -> Result<&[u8], Error> {
if self.index == BLOCK_SIZE {
// flush the buffer if it is dirty before overwriting it with new data
if self.dirty {
self.flush()?;
}
// reload buffer
self.sd
.read_block(self.byte_addr / (BLOCK_SIZE as u32), 1, &mut self.buffer)?;
self.index = (self.byte_addr as usize) % BLOCK_SIZE;
}
Ok(&self.buffer[self.index..])
}
fn consume(&mut self, amt: usize) {
self.index += amt;
self.byte_addr += amt as u32;
}
} }
impl Read for SdReader { impl Read for SdReader {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
let total_length = buf.len(); let total_length = buf.len();
let (a, b, c) = self.block_align_mut(buf); let (a, b, c) = self.block_align_mut(buf);
self.read_unaligned(a)?; self.read_unaligned(a)?;
@ -211,30 +266,8 @@ impl Read for SdReader {
} }
} }
impl BufRead for SdReader {
fn fill_buf(&mut self) -> IoResult<&[u8]> {
if self.index == BLOCK_SIZE {
// flush the buffer if it is dirty before overwriting it with new data
if self.dirty {
self.flush()?;
}
// reload buffer
self.sd
.read_block(self.byte_addr / (BLOCK_SIZE as u32), 1, &mut self.buffer)
.map_err(cmd_error_to_io_error)?;
self.index = (self.byte_addr as usize) % BLOCK_SIZE;
}
Ok(&self.buffer[self.index..])
}
fn consume(&mut self, amt: usize) {
self.index += amt;
self.byte_addr += amt as u32;
}
}
impl Write for SdReader { impl Write for SdReader {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> { fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
let (a, b, c) = self.block_align(buf); let (a, b, c) = self.block_align(buf);
self.write_unaligned(a)?; self.write_unaligned(a)?;
if b.len() > 0 { if b.len() > 0 {
@ -255,12 +288,10 @@ impl Write for SdReader {
Ok(buf.len()) Ok(buf.len())
} }
fn flush(&mut self) -> IoResult<()> { fn flush(&mut self) -> Result<(), Error> {
if self.dirty { if self.dirty {
let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32); let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32);
self.sd self.sd.write_block(block_addr, 1, &self.buffer)?;
.write_block(block_addr, 1, &self.buffer)
.map_err(cmd_error_to_io_error)?;
self.dirty = false; self.dirty = false;
} }
Ok(()) Ok(())
@ -268,14 +299,14 @@ impl Write for SdReader {
} }
impl Seek for SdReader { impl Seek for SdReader {
fn seek(&mut self, pos: SeekFrom) -> IoResult<u64> { fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error> {
let raw_target = match pos { let raw_target = match pos {
SeekFrom::Start(x) => self.offset as i64 + x as i64, SeekFrom::Start(x) => self.offset as i64 + x as i64,
SeekFrom::Current(x) => self.byte_addr as i64 + x, SeekFrom::Current(x) => self.byte_addr as i64 + x,
SeekFrom::End(_) => panic!("SD card does not support seek from end"), SeekFrom::End(_) => panic!("SD card does not support seek from end"),
}; };
if raw_target < self.offset as i64 || raw_target > core::u32::MAX as i64 { if raw_target < self.offset as i64 || raw_target > core::u32::MAX as i64 {
return Err(Error::new(ErrorKind::InvalidInput, "Invalid address")); return Err(Error::new("Invalid address"));
} }
let target_byte_addr = raw_target as u32; let target_byte_addr = raw_target as u32;
let address_same_block = let address_same_block =

View File

@ -2,7 +2,7 @@
name = "libcortex_a9" name = "libcortex_a9"
version = "0.0.0" version = "0.0.0"
authors = ["M-Labs"] authors = ["M-Labs"]
edition = "2018" edition = "2021"
[features] [features]
power_saving = [] power_saving = []

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", lateout(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, out("r1") _);
} }
/// 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"); ", out("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"); ", out("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)]
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, lateout(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

@ -172,13 +172,12 @@ impl<'a, T> Iterator for Receiver<'a, T> where T: Clone {
#[macro_export] #[macro_export]
/// Macro for initializing the sync_channel with static buffer and indexes. /// Macro for initializing the sync_channel with static buffer and indexes.
/// Note that this requires `#![feature(const_in_array_repeat_expressions)]`
macro_rules! sync_channel { macro_rules! sync_channel {
($t: ty, $cap: expr) => { ($t: ty, $cap: expr) => {
{ {
use core::sync::atomic::{AtomicUsize, AtomicPtr}; use core::sync::atomic::{AtomicUsize, AtomicPtr};
use $crate::sync_channel::{Sender, Receiver}; use $crate::sync_channel::{Sender, Receiver};
static LIST: [AtomicPtr<$t>; $cap + 1] = [AtomicPtr::new(core::ptr::null_mut()); $cap + 1]; static LIST: [AtomicPtr<$t>; $cap + 1] = [const { AtomicPtr::new(core::ptr::null_mut()) }; $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))

View File

@ -33,8 +33,6 @@ impl<T> UncachedSlice<T> {
} }
let slice = unsafe { core::slice::from_raw_parts_mut(ptr, len) }; let slice = unsafe { core::slice::from_raw_parts_mut(ptr, len) };
// verify size
assert!(unsafe { slice.get_unchecked(len) } as *const _ as usize <= start + size);
// initialize // initialize
for e in slice.iter_mut() { for e in slice.iter_mut() {
*e = default(); *e = default();

View File

@ -2,7 +2,7 @@
name = "libregister" name = "libregister"
version = "0.0.0" version = "0.0.0"
authors = ["M-Labs"] authors = ["M-Labs"]
edition = "2018" edition = "2021"
[dependencies] [dependencies]
vcell = "0.1" vcell = "0.1"

View File

@ -3,11 +3,12 @@ name = "libsupport_zynq"
description = "Software support for running in the Zynq PS" description = "Software support for running in the Zynq PS"
version = "0.0.0" version = "0.0.0"
authors = ["M-Labs"] authors = ["M-Labs"]
edition = "2018" edition = "2021"
[features] [features]
target_zc706 = ["libboard_zynq/target_zc706"] target_zc706 = ["libboard_zynq/target_zc706"]
target_coraz7 = ["libboard_zynq/target_coraz7"] target_coraz7 = ["libboard_zynq/target_coraz7"]
target_ebaz4205 = ["libboard_zynq/target_ebaz4205"]
target_redpitaya = ["libboard_zynq/target_redpitaya"] target_redpitaya = ["libboard_zynq/target_redpitaya"]
target_kasli_soc = ["libboard_zynq/target_kasli_soc"] target_kasli_soc = ["libboard_zynq/target_kasli_soc"]
panic_handler = [] panic_handler = []
@ -19,7 +20,7 @@ default = ["panic_handler", "dummy_irq_handler", "dummy_fiq_handler"]
[dependencies] [dependencies]
r0 = "1" r0 = "1"
compiler_builtins = "=0.1.39" compiler_builtins = "=0.1.109"
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" }

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

@ -1,9 +1,7 @@
#![no_std] #![no_std]
#![feature(alloc_error_handler)] #![feature(alloc_error_handler)]
#![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;

View File

@ -10,7 +10,7 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
} else { } else {
print!("unknown location"); print!("unknown location");
} }
if let Some(message) = info.message() { if let Some(message) = info.message().as_str() {
println!(": {}", message); println!(": {}", message);
} else { } else {
println!(""); println!("");

33
openocd/ebaz4205.cfg Normal file
View File

@ -0,0 +1,33 @@
# The contents of this file are partially dependend on
# the adapter that you have. Please modify accordingly.
adapter driver ftdi
ftdi vid_pid 0x0403 0x6010
ftdi channel 0
# Every pin set as high impedance except TCK, TDI, TDO and TMS
ftdi layout_init 0x0088 0x008b
# nSRST defined on pin CN2-13 of the MiniModule (pin ADBUS5 [AD5] on the FT2232H chip)
# This choice is arbitrary. Use other GPIO pin if desired.
ftdi layout_signal nSRST -data 0x0020 -oe 0x0020
transport select jtag
adapter speed 10000
set PL_TAPID 0x13722093
set SMP 1
source ./zynq-7000.cfg
reset_config srst_only srst_open_drain
adapter srst pulse_width 250
adapter srst delay 400
source ./common.cfg
reset halt
# Disable MMU
targets $_TARGETNAME_1
arm mcr 15 0 1 0 0 [expr { [arm mrc 15 0 1 0 0] & ~0xd }]
targets $_TARGETNAME_0
arm mcr 15 0 1 0 0 [expr { [arm mrc 15 0 1 0 0] & ~0xd }]

View File

@ -3,11 +3,12 @@ name = "szl"
description = "Simple Zynq Loader" description = "Simple Zynq Loader"
version = "0.1.0" version = "0.1.0"
authors = ["M-Labs"] authors = ["M-Labs"]
edition = "2018" edition = "2021"
[features] [features]
target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706", "libconfig/target_zc706"] target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706", "libconfig/target_zc706"]
target_coraz7 = ["libboard_zynq/target_coraz7", "libsupport_zynq/target_coraz7", "libconfig/target_coraz7"] target_coraz7 = ["libboard_zynq/target_coraz7", "libsupport_zynq/target_coraz7", "libconfig/target_coraz7"]
target_ebaz4205 = ["libboard_zynq/target_ebaz4205", "libsupport_zynq/target_ebaz4205", "libconfig/target_ebaz4205"]
target_redpitaya = ["libboard_zynq/target_redpitaya", "libsupport_zynq/target_redpitaya", "libconfig/target_redpitaya"] target_redpitaya = ["libboard_zynq/target_redpitaya", "libsupport_zynq/target_redpitaya", "libconfig/target_redpitaya"]
target_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc", "libconfig/target_kasli_soc"] target_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc", "libconfig/target_kasli_soc"]
default = ["target_zc706"] default = ["target_zc706"]
@ -15,10 +16,15 @@ default = ["target_zc706"]
[dependencies] [dependencies]
log = "0.4" log = "0.4"
byteorder = { version = "1.3", default-features = false } byteorder = { version = "1.3", default-features = false }
core_io = { version = "0.1", features = ["collections"] }
libboard_zynq = { path = "../libboard_zynq" } libboard_zynq = { path = "../libboard_zynq" }
libsupport_zynq = { path = "../libsupport_zynq" } libsupport_zynq = { path = "../libsupport_zynq" }
libcortex_a9 = { path = "../libcortex_a9" } libcortex_a9 = { path = "../libcortex_a9" }
libregister = { path = "../libregister" } libregister = { path = "../libregister" }
libconfig = { path = "../libconfig" } libconfig = { path = "../libconfig" }
[dependencies.fatfs]
git = "https://github.com/rafalh/rust-fatfs"
rev = "85f06e0"
default-features = false
features = ["alloc", "lfn"]

View File

@ -8,7 +8,6 @@ mod netboot;
use alloc::rc::Rc; use alloc::rc::Rc;
use core::mem; use core::mem;
use core_io::{Read, Seek};
use libboard_zynq::{ use libboard_zynq::{
self as zynq, self as zynq,
clocks::source::{ArmPll, ClockSource, IoPll}, clocks::source::{ArmPll, ClockSource, IoPll},
@ -16,7 +15,7 @@ use libboard_zynq::{
logger, println, sdio, slcr, logger, println, sdio, slcr,
timer::GlobalTimer, timer::GlobalTimer,
}; };
use libconfig::{bootgen, sd_reader, Config}; use libconfig::{bootgen, sd_reader, Config, File};
use libcortex_a9::{ use libcortex_a9::{
asm::{dsb, isb}, asm::{dsb, isb},
cache::{bpiall, dcciall, iciallu}, cache::{bpiall, dcciall, iciallu},
@ -30,8 +29,8 @@ extern "C" {
static mut __runtime_end: usize; static mut __runtime_end: usize;
} }
fn boot_sd<File: Read + Seek>( fn boot_sd<'a>(
file: &mut Option<File>, file: &mut Option<File<'a>>,
runtime_start: *mut u8, runtime_start: *mut u8,
runtime_max: usize, runtime_max: usize,
) -> Result<(), ()> { ) -> Result<(), ()> {
@ -80,12 +79,15 @@ pub fn main_core0() {
); );
info!("Simple Zynq Loader starting..."); info!("Simple Zynq Loader starting...");
#[cfg(not(feature = "target_kasli_soc"))] #[cfg(not(any(feature = "target_kasli_soc", feature = "target_ebaz4205")))]
const CPU_FREQ: u32 = 800_000_000; const CPU_FREQ: u32 = 800_000_000;
#[cfg(feature = "target_kasli_soc")] #[cfg(feature = "target_kasli_soc")]
const CPU_FREQ: u32 = 1_000_000_000; const CPU_FREQ: u32 = 1_000_000_000;
#[cfg(feature = "target_ebaz4205")]
const CPU_FREQ: u32 = 666_666_666;
ArmPll::setup(2 * CPU_FREQ); ArmPll::setup(2 * CPU_FREQ);
Clocks::set_cpu_freq(CPU_FREQ); Clocks::set_cpu_freq(CPU_FREQ);
IoPll::setup(1_000_000_000); IoPll::setup(1_000_000_000);

View File

@ -1,7 +1,6 @@
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
use byteorder::{ByteOrder, NetworkEndian}; use byteorder::{ByteOrder, NetworkEndian};
use core_io::{Read, Seek};
use libboard_zynq::{ use libboard_zynq::{
devc, devc,
eth::Eth, eth::Eth,
@ -13,7 +12,7 @@ use libboard_zynq::{
}, },
timer::GlobalTimer, timer::GlobalTimer,
}; };
use libconfig::{bootgen, net_settings, Config}; use libconfig::{bootgen, net_settings, Config, File};
enum NetConnState { enum NetConnState {
WaitCommand, WaitCommand,
@ -48,7 +47,7 @@ impl NetConn {
self.gateware_downloaded = false; self.gateware_downloaded = false;
} }
fn input_partial<File: Read + Seek>( fn input_partial(
&mut self, &mut self,
bootgen_file: &mut Option<File>, bootgen_file: &mut Option<File>,
runtime_start: *mut u8, runtime_start: *mut u8,
@ -284,9 +283,9 @@ impl NetConn {
} }
} }
fn input<File: Read + Seek>( fn input<'a>(
&mut self, &mut self,
bootgen_file: &mut Option<File>, bootgen_file: &mut Option<File<'a>>,
runtime_start: *mut u8, runtime_start: *mut u8,
runtime_max_len: usize, runtime_max_len: usize,
buf: &[u8], buf: &[u8],
@ -309,8 +308,8 @@ impl NetConn {
} }
} }
pub fn netboot<File: Read + Seek>( pub fn netboot<'a>(
bootgen_file: &mut Option<File>, bootgen_file: &mut Option<File<'a>>,
cfg: Config, cfg: Config,
runtime_start: *mut u8, runtime_start: *mut u8,
runtime_max_len: usize, runtime_max_len: usize,