1
0
Fork 0

Compare commits

..

7 Commits

Author SHA1 Message Date
Sebastien Bourdeauducq 12975de2e1 flake: add missing attributes on rustc (for nixpkgs-unstable compat) 2024-11-16 17:31:34 +08:00
Sebastien Bourdeauducq 8c404829ef flake: update nixpkgs 2024-11-16 17:15:03 +08:00
Sebastien Bourdeauducq 8f041b017c switch to oxalica rust overlay 2024-11-16 17:14:37 +08:00
newell 5815baf88b Reorder Status.get_link to check for higher speeds before slower. 2024-11-15 13:09:17 -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
38 changed files with 463 additions and 318 deletions

86
Cargo.lock generated
View File

@ -1,12 +1,10 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bit_field"
version = "0.10.2"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
[[package]]
name = "bitflags"
@ -14,29 +12,38 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "byteorder"
version = "1.5.0"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.1.7"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "compiler_builtins"
version = "0.1.114"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb58b199190fcfe0846f55a3b545cd6b07a34bdd5930a476ff856f3ebcc5558a"
checksum = "3748f82c7d366a0b4950257d19db685d4958d2fa27c6d164a3f069fec42b748b"
[[package]]
name = "core_io"
version = "0.1.20210325"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97f8932064288cc79feb4d343a399d353a6f6f001e586ece47fe518a9e8507df"
dependencies = [
"rustc_version",
]
[[package]]
name = "embedded-hal"
@ -63,10 +70,13 @@ dependencies = [
[[package]]
name = "fatfs"
version = "0.4.0"
source = "git+https://github.com/rafalh/rust-fatfs#85f06e08edbd3368e1b0562f2fc1b6d178bf7b8a"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e18f80a87439240dac45d927fd8f8081b6f1e34c03e97271189fa8a8c2e96c8f"
dependencies = [
"bitflags 2.6.0",
"bitflags",
"byteorder",
"core_io",
"log",
]
@ -76,7 +86,7 @@ version = "0.0.0"
dependencies = [
"embedded-hal",
"libcortex_a9",
"nb 1.1.0",
"nb 1.0.0",
"pin-utils",
"smoltcp",
]
@ -101,6 +111,7 @@ dependencies = [
name = "libconfig"
version = "0.1.0"
dependencies = [
"core_io",
"fatfs",
"libboard_zynq",
"log",
@ -145,9 +156,12 @@ checksum = "822add9edb1860698b79522510da17bef885171f75aa395cff099d770c609c24"
[[package]]
name = "log"
version = "0.4.22"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "managed"
@ -161,14 +175,14 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
"nb 1.1.0",
"nb 1.0.0",
]
[[package]]
name = "nb"
version = "1.1.0"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
[[package]]
name = "pin-utils"
@ -182,13 +196,28 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "smoltcp"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e4a069bef843d170df47e7c0a8bf8d037f217d9f5b325865acc3e466ffe40d3"
dependencies = [
"bitflags 1.3.2",
"bitflags",
"byteorder",
"managed",
]
@ -198,6 +227,7 @@ name = "szl"
version = "0.1.0"
dependencies = [
"byteorder",
"core_io",
"libboard_zynq",
"libconfig",
"libcortex_a9",
@ -220,9 +250,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "volatile-register"
version = "0.2.2"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc"
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
dependencies = [
"vcell",
]

View File

@ -8,6 +8,7 @@ edition = "2018"
[features]
target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706"]
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_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc"]
default = ["target_zc706"]

View File

@ -1,11 +1,12 @@
#![no_std]
#![no_main]
#![feature(const_in_array_repeat_expressions)]
#![feature(naked_functions)]
#![feature(asm)]
extern crate alloc;
use alloc::collections::BTreeMap;
use core::arch::asm;
use libasync::{
delay,
smoltcp::{Sockets, TcpStream},
@ -115,6 +116,7 @@ pub fn main_core0() {
#[cfg(any(
feature = "target_zc706",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]

View File

@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1721548954,
"narHash": "sha256-7cCC8+Tdq1+3OPyc3+gVo9dzUNkNIQfwSDJ2HSi2u3o=",
"lastModified": 1731652201,
"narHash": "sha256-XUO0JKP1hlww0d7mm3kpmIr4hhtR4zicg5Wwes9cPMg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "63d37ccd2d178d54e7fb691d7ec76000740ea24a",
"rev": "c21b77913ea840f8bcf9adf4c41cecc2abffd38d",
"type": "github"
},
"original": {
@ -29,15 +29,16 @@
]
},
"locked": {
"lastModified": 1721701191,
"narHash": "sha256-nM4szL90VeZHZEC5rFfaiiPNTVOmsihdtk2QSP1l37I=",
"lastModified": 1719454714,
"narHash": "sha256-MojqG0lyUINkEk0b3kM2drsU5vyaF8DFZe/FAlZVOGs=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "4674ff2c2e5423a0cebe16e61aa874c359306af4",
"rev": "d1c527659cf076ecc4b96a91c702d080b213801e",
"type": "github"
},
"original": {
"owner": "oxalica",
"ref": "snapshot/2024-08-01",
"repo": "rust-overlay",
"type": "github"
}

View File

@ -2,9 +2,8 @@
description = "Bare-metal Rust on Zynq-7000";
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-24.05;
#inputs.mozilla-overlay = { url = github:mozilla/nixpkgs-mozilla; flake = false; };
inputs.rust-overlay = {
url = "github:oxalica/rust-overlay";
url = "github:oxalica/rust-overlay?ref=snapshot/2024-08-01";
inputs.nixpkgs.follows = "nixpkgs";
};
@ -12,37 +11,27 @@
let
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import rust-overlay) crosspkgs-overlay ]; };
# rustManifest = pkgs.fetchurl {
# url = "https://static.rust-lang.org/dist/2021-01-29/channel-rust-nightly.toml";
# sha256 = "sha256-EZKgw89AH4vxaJpUHmIMzMW/80wAFQlfcxRoBD9nz0c=";
# };
# rustTargets = [];
# rustChannelOfTargets = _channel: _date: targets:
# (pkgs.lib.rustLib.fromManifestFile rustManifest {
# inherit (pkgs) stdenv lib fetchurl patchelf;
# }).rust.override {
# inherit targets;
# extensions = ["rust-src"];
# };
# rust = rustChannelOfTargets "nightly" null rustTargets;
# rustc version needs to match LLVM version, else ABI bugs
# https://doc.rust-lang.org/rustc/linker-plugin-lto.html#toolchain-compatibility
rust = pkgs.rust-bin.nightly."2023-04-20".default.override {
rust = pkgs.rust-bin.nightly."2021-01-28".default.override {
extensions = [ "rust-src" ];
targets = [ ];
};
rustPlatform = pkgs.recurseIntoAttrs (pkgs.makeRustPlatform {
rustc = rust;
rustPlatform = pkgs.makeRustPlatform {
rustc = rust // {
# https://github.com/oxalica/rust-overlay/commit/c48c2d76b68dd9ede0815fec53479375c61af857
targetPlatforms = pkgs.lib.platforms.all;
tier1TargetPlatforms = pkgs.lib.platforms.all;
badTargetPlatforms = [ ];
};
cargo = rust;
});
## https://doc.rust-lang.org/rustc/linker-plugin-lto.html#toolchain-compatibility
#llvmPackages_11 = pkgs.recurseIntoAttrs (pkgs.callPackage (import ./llvm/11) ({
# inherit (pkgs.stdenvAdapters) overrideCC;
# buildLlvmTools = null;
# targetLlvmLibraries = null;
# targetLlvm = null;
#}));
};
# https://doc.rust-lang.org/rustc/linker-plugin-lto.html#toolchain-compatibility
llvmPackages_11 = pkgs.recurseIntoAttrs (pkgs.callPackage (import ./llvm/11) ({
inherit (pkgs.stdenvAdapters) overrideCC;
buildLlvmTools = null;
targetLlvmLibraries = null;
targetLlvm = null;
}));
crosspkgs-overlay = (self: super: {
pkgsCross = super.pkgsCross // {
@ -114,13 +103,9 @@
dontFixup = true;
};
cargo-xbuild = pkgs.cargo-xbuild;
#cargo-xbuild = pkgs.cargo-xbuild.overrideAttrs(oa: {
# postPatch = "substituteInPlace src/sysroot.rs --replace 2021 2018";
#});
#cargo-xbuild = pkgs.cargo-xbuild.overrideAttrs(oa: {
# postPatch = "substituteInPlace src/sysroot.rs --replace 2023 2018";
#});
cargo-xbuild = pkgs.cargo-xbuild.overrideAttrs(oa: {
postPatch = "substituteInPlace src/sysroot.rs --replace 2021 2018";
});
build-crate = name: crate: features: rustPlatform.buildRustPackage rec {
name = "${crate}";
@ -130,7 +115,7 @@
) ./.;
cargoLock = { lockFile = ./Cargo.lock; };
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_16.clang-unwrapped ];
nativeBuildInputs = [ cargo-xbuild llvmPackages_11.clang-unwrapped ];
buildPhase = ''
export XARGO_RUST_SRC="${rust}/lib/rustlib/src/rust/library"
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
@ -156,7 +141,7 @@
"${target}-experiments" = build-crate "${target}-experiments" "experiments" "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:
results // targetCrates target
) {} targets);
@ -175,7 +160,7 @@
hydraJobs = packages.x86_64-linux;
inherit rust rustPlatform;
inherit rust rustPlatform llvmPackages_11;
devShell.x86_64-linux = pkgs.mkShell {
name = "zynq-rs-dev-shell";
@ -186,7 +171,7 @@
pkgs.openocd pkgs.gdb
pkgs.openssh pkgs.rsync
pkgs.llvmPackages_16.clang-unwrapped
llvmPackages_11.clang-unwrapped
(pkgs.python3.withPackages(ps: [ ps.pyftdi ]))
];
};

View File

@ -8,6 +8,7 @@ edition = "2018"
[features]
target_zc706 = []
target_coraz7 = []
target_ebaz4205 = []
target_redpitaya = []
target_kasli_soc = []
ipv6 = [ "smoltcp/proto-ipv6" ]

View File

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

View File

@ -6,6 +6,8 @@ use super::slcr;
pub const PS_CLK: u32 = 33_333_333;
#[cfg(feature = "target_coraz7")]
pub const PS_CLK: u32 = 50_000_000;
#[cfg(feature = "target_ebaz4205")]
pub const PS_CLK: u32 = 33_333_333;
#[cfg(feature = "target_redpitaya")]
pub const PS_CLK: u32 = 33_333_333;
#[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
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")]
/// Alliance Memory AS4C256M16D3B: 800 MHz DDR3 at 533 MHz
const DDR_FREQ: u32 = 533_333_333;
@ -147,22 +151,23 @@ impl DdrRam {
.output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(feature = "target_zc706")]
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()
.inp_type(slcr::DdriobInputType::VrefDifferential)
.term_en(true)
.dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))]
let data1_config = slcr::DdriobConfig::zeroed()
.pullup_en(true);
#[cfg(feature = "target_redpitaya")]
let data0_config = slcr::DdriobConfig::zeroed()
.inp_type(slcr::DdriobInputType::VrefDifferential)
.term_en(true)
.dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(feature = "target_redpitaya")]
#[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
let data1_config = slcr::DdriobConfig::zeroed()
.pullup_en(true);
slcr.ddriob_data0.write(data0_config);
@ -176,22 +181,23 @@ impl DdrRam {
.output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(feature = "target_zc706")]
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()
.inp_type(slcr::DdriobInputType::Differential)
.term_en(true)
.dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))]
let diff1_config = slcr::DdriobConfig::zeroed()
.pullup_en(true);
#[cfg(feature = "target_redpitaya")]
let diff0_config = slcr::DdriobConfig::zeroed()
.inp_type(slcr::DdriobInputType::Differential)
.term_en(true)
.dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf);
#[cfg(feature = "target_redpitaya")]
#[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
let diff1_config = slcr::DdriobConfig::zeroed()
.pullup_en(true);
slcr.ddriob_diff0.write(diff0_config);
@ -210,7 +216,12 @@ impl DdrRam {
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
.vref_int_en(false)
.vref_ext_en_lower(true)
@ -224,13 +235,6 @@ impl DdrRam {
.vref_ext_en_lower(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)
.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")]
self.regs.dram_param0.write(
regs::DramParam0::zeroed()
@ -256,6 +267,12 @@ impl DdrRam {
.t_rfc_min(0x56)
.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")]
self.regs.dram_param1.modify(
|_, w| w
@ -277,6 +294,11 @@ impl DdrRam {
.rd2pre(0x4)
.t_rcd(0x7)
);
#[cfg(feature = "target_ebaz4205")]
self.regs.dram_param3.modify(
|_, w| w
.t_rp(7)
);
#[cfg(feature = "target_redpitaya")]
self.regs.dram_param3.modify(
|_, w| w
@ -298,19 +320,21 @@ impl DdrRam {
.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(
|_, w| w.data_slice_in_use(false)
);
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))]
self.regs.phy_configs[3].modify(
|_, w| w.data_slice_in_use(false)
);
#[cfg(feature = "target_redpitaya")]
self.regs.phy_configs[2].modify(
|_, w| w.data_slice_in_use(false)
);
#[cfg(feature = "target_redpitaya")]
#[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
self.regs.phy_configs[3].modify(
|_, w| w.data_slice_in_use(false)
);
@ -354,7 +378,11 @@ impl DdrRam {
.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(
|_, w| w
.phy_ctrl_slave_ratio(0x100)
@ -390,9 +418,12 @@ impl DdrRam {
fn reset_ddrc<F: FnMut(&mut Self)>(&mut self, mut f: F) {
#[cfg(feature = "target_zc706")]
let width = regs::DataBusWidth::Width32bit;
#[cfg(any(feature = "target_coraz7", feature = "target_kasli_soc"))]
let width = regs::DataBusWidth::Width16bit;
#[cfg(feature = "target_redpitaya")]
#[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
let width = regs::DataBusWidth::Width16bit;
self.regs.ddrc_ctrl.modify(|_, w| w
.soft_rstb(false)
@ -410,6 +441,7 @@ impl DdrRam {
}
#[cfg(any(
feature = "target_coraz7",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
@ -450,6 +482,8 @@ impl DdrRam {
feature = "target_kasli_soc",
))]
let megabytes = 512;
#[cfg(feature = "target_ebaz4205")]
let megabytes = 256;
megabytes * 1024 * 1024
}

View File

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

View File

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

View File

@ -55,12 +55,22 @@ impl Status {
pub fn get_link(&self) -> Option<Link> {
if ! self.link_status() {
None
} else if self.cap_10base_t_half() {
} else if self.cap_100base_tx_full() {
Some(Link {
speed: LinkSpeed::S10,
speed: LinkSpeed::S100,
duplex: LinkDuplex::Full,
})
} else if self.cap_100base_tx_half() {
Some(Link {
speed: LinkSpeed::S100,
duplex: LinkDuplex::Half,
})
} else if self.cap_10base_t_full() {
} else if self.cap_100base_t4() {
Some(Link {
speed: LinkSpeed::S100,
duplex: LinkDuplex::Half,
})
} else if self.cap_10base_t2_full() {
Some(Link {
speed: LinkSpeed::S10,
duplex: LinkDuplex::Full,
@ -70,26 +80,16 @@ impl Status {
speed: LinkSpeed::S10,
duplex: LinkDuplex::Half,
})
} else if self.cap_10base_t2_full() {
} else if self.cap_10base_t_full() {
Some(Link {
speed: LinkSpeed::S10,
duplex: LinkDuplex::Full,
})
} else if self.cap_100base_t4() {
} else if self.cap_10base_t_half() {
Some(Link {
speed: LinkSpeed::S100,
speed: LinkSpeed::S10,
duplex: LinkDuplex::Half,
})
} else if self.cap_100base_tx_half() {
Some(Link {
speed: LinkSpeed::S100,
duplex: LinkDuplex::Half,
})
} else if self.cap_100base_tx_full() {
Some(Link {
speed: LinkSpeed::S100,
duplex: LinkDuplex::Full,
})
} else {
None
}

View File

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

View File

@ -2,10 +2,13 @@
mod regs;
pub mod eeprom;
#[cfg(not(feature = "target_ebaz4205"))]
use super::slcr;
use super::time::Microseconds;
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")]
use log::info;
@ -22,9 +25,10 @@ pub struct 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 {
// Route I2C 0 SCL / SDA Signals to MIO Pins 50 / 51
#[cfg(not(feature = "target_ebaz4205"))]
slcr::RegisterBlock::unlocked(|slcr| {
// SCL
slcr.mio_pin_50.write(

View File

@ -21,6 +21,7 @@ use libregister::{
// Current compatibility:
// zc706: GPIO 50, 51 == SCL, SDA
// kasli_soc: GPIO 50, 51 == SCL, SDA; GPIO 33 == I2C_SW_RESET
// ebaz4205: GPIO (EMIO)
pub struct RegisterBlock {
pub gpio_output_mask: &'static mut GPIOOutputMask,
@ -48,17 +49,17 @@ register!(gpio_output_mask,
/// MASK_DATA_1_MSW:
/// Maskable output data for MIO[53:48]
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);
#[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,
/// Output for SCL
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,
/// Output for SDA
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,
/// Mask for keeping bits except SCL and SDA unchanged
mask, u16, 16, 31);
@ -82,13 +83,13 @@ register!(gpio_input,
/// DATA_1_RO:
/// Input data for MIO[53:32]
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);
#[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,
/// Input for SCL
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,
/// Input for SDA
sda, 19);
@ -98,13 +99,13 @@ register!(gpio_direction,
/// DIRM_1:
/// Direction mode for MIO[53:32]; 0/1 = in/out
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);
#[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,
/// Direction for SCL
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,
/// Direction for SDA
sda, 19);
@ -117,13 +118,13 @@ register!(gpio_output_enable,
/// OEN_1:
/// Output enable for MIO[53:32]
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);
#[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,
/// Output enable for SCL
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,
/// Output enable for SDA
sda, 19);

View File

@ -19,7 +19,7 @@ pub mod gic;
pub mod time;
pub mod timer;
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 logger;
pub mod ps7_init;

View File

@ -116,8 +116,8 @@ impl Sdio {
.speed(true),
);
}
// redpitaya card detect pin
#[cfg(any(feature = "target_redpitaya", feature = "target_kasli_soc"))]
// kasli_soc and redpitaya card detect pin
#[cfg(any(feature = "target_kasli_soc", feature = "target_redpitaya"))]
{
unsafe {
slcr.sd0_wp_cd_sel.write(46 << 16);
@ -128,6 +128,20 @@ impl Sdio {
.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.aper_clk_ctrl.enable_sdio0();
slcr.sdio_clk_ctrl.enable_sdio0();

View File

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

View File

@ -47,7 +47,11 @@ impl DerefMut for LazyUart {
LazyUart::Uninitialized => {
#[cfg(any(feature = "target_coraz7", feature = "target_redpitaya"))]
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);
*self = LazyUart::Initialized(uart);
self

View File

@ -79,6 +79,39 @@ impl Uart {
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) {
while self.tx_fifo_full() {}

View File

@ -6,13 +6,15 @@ edition = "2018"
[dependencies]
libboard_zynq = { path = "../libboard_zynq" }
fatfs = { default-features = false, git = "https://github.com/rafalh/rust-fatfs" }
core_io = { version = "0.1", features = ["collections"] }
fatfs = { version = "0.3", features = ["core_io"], default-features = false }
log = "0.4"
[features]
target_zc706 = []
target_coraz7 = []
target_ebaz4205 = []
target_redpitaya = []
target_kasli_soc = []
ipv6 = []
fat_lfn = [ "fatfs/alloc" ]
fat_lfn = [ "fatfs/alloc" ]

View File

@ -1,7 +1,5 @@
use alloc::vec::Vec;
use fatfs::{Read, Seek, SeekFrom, IoBase};
use core::fmt::Write;
use crate::sd_reader::IoError;
use core_io::{Error, Read, Seek, SeekFrom};
use libboard_zynq::devc;
use log::debug;
@ -10,13 +8,12 @@ pub enum BootgenLoadingError {
InvalidBootImageHeader,
MissingPartition,
EncryptedBitstream,
IoError(IoError),
IoError(Error),
DevcError(devc::DevcError),
}
impl From<T: IoError> for BootgenLoadingError {
fn from(error: IoError) -> Self {
impl From<Error> for BootgenLoadingError {
fn from(error: Error) -> Self {
BootgenLoadingError::IoError(error)
}
}
@ -72,7 +69,7 @@ fn read_u32<Reader: Read>(reader: &mut Reader) -> Result<u32, BootgenLoadingErro
}
/// Load PL partition header.
fn load_pl_header<File: Read + Seek + IoBase>(
fn load_pl_header<File: Read + Seek>(
file: &mut File,
) -> Result<Option<PartitionHeader>, BootgenLoadingError> {
let mut buffer: [u8; 0x40] = [0; 0x40];

View File

@ -3,7 +3,7 @@ extern crate alloc;
use core::fmt;
use alloc::{string::FromUtf8Error, string::String, vec::Vec, rc::Rc};
use fatfs::{self as fatfs, SeekFrom, Write, Read, Seek};
use core_io::{self as io, BufRead, BufReader, Read, Write, Seek, SeekFrom};
use libboard_zynq::sdio;
pub mod sd_reader;
@ -13,7 +13,7 @@ pub mod bootgen;
#[derive(Debug)]
pub enum Error<'a> {
SdError(sdio::sd_card::CardInitializationError),
IoError(fatfs::Error<sd_reader::IoError>),
IoError(io::Error),
Utf8Error(FromUtf8Error),
KeyNotFoundError(&'a str),
NoConfig,
@ -39,8 +39,8 @@ impl<'a> From<sdio::sd_card::CardInitializationError> for Error<'a> {
}
}
impl<'a> From<fatfs::Error<sd_reader::IoError>> for Error<'a> {
fn from(error: fatfs::Error<sd_reader::IoError>) -> Self {
impl<'a> From<io::Error> for Error<'a> {
fn from(error: io::Error) -> Self {
Error::IoError(error)
}
}
@ -51,19 +51,14 @@ impl<'a> From<FromUtf8Error> for Error<'a> {
}
}
pub type FFile = fatfs::File<sd_reader::SdReader, fatfs::DefaultTimeProvider, fatfs::LossyOemCpConverter>;
fn parse_config<'a>(
key: &'a str,
buffer: &mut Vec<u8>,
file: FFile,
file: fatfs::File<sd_reader::SdReader>,
) -> Result<'a, ()> {
let prefix = [key, "="].concat().to_ascii_lowercase();
let file_buf = &mut [];
let length = file.read(file_buf)?;
let s = core::str::from_utf8(file_buf)?;
for line in s.lines() {
let line = line.make_ascii_lowercase()?;
for line in BufReader::new(file).lines() {
let line = line?.to_ascii_lowercase();
if line.starts_with(&prefix) {
buffer.extend(line[prefix.len()..].as_bytes());
return Ok(());

View File

@ -59,6 +59,10 @@ pub fn get_addresses(cfg: &Config) -> NetAddresses {
let mut hardware_addr = get_address_from_eeprom();
#[cfg(feature = "target_kasli_soc")]
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()) {
hardware_addr = addr;

View File

@ -1,8 +1,8 @@
use fatfs::{self as fatfs, Read, Seek, SeekFrom, Write, IoBase, IoError as BaseIoError};
use core_io::{BufRead, Error, ErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write};
use fatfs;
use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError};
use log::debug;
use alloc::vec::Vec;
use alloc::string::String;
const MBR_SIGNATURE: [u8; 2] = [0x55, 0xAA];
const PARTID_FAT12: u8 = 0x01;
@ -12,49 +12,12 @@ const PARTID_FAT32: u8 = 0x0B;
const PARTID_FAT32_LBA: u8 = 0x0C;
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;
#[derive(Debug)]
pub enum ErrorKind {
InvalidData,
InvalidInput,
Other
}
#[derive(Debug)]
pub struct IoError {
error: ErrorKind,
message: String
}
impl IoError {
pub fn new(error: ErrorKind, message: &str) -> Self {
IoError {
error,
message: String::from(message)
}
}
}
impl BaseIoError for IoError {
fn is_interrupted() -> IoError {
false
}
fn new_unexpected_eof_error() -> IoError{
}
fn new_write_zero_error() -> IoError {
}
}
pub type IoResult<T> = core::Result<T, IoError>;
fn cmd_error_to_io_error(_: CmdTransferError) -> IoError {
IoError::new(ErrorKind::Other, "Command transfer error")
}
/// SdReader struct implementing `Read + BufRead + Write + Seek` traits for `core_io`.
/// Used as an adaptor for fatfs crate, but could be used directly for raw data access.
///
@ -90,10 +53,6 @@ pub enum PartitionEntry {
Entry4 = 0x1EE,
}
impl IoBase for SdReader {
type Error = IoError;
}
impl SdReader {
/// Create SdReader from SdCard
pub fn new(sd: SdCard) -> SdReader {
@ -192,7 +151,10 @@ impl SdReader {
self.read_exact(&mut buffer[..2])?;
// check MBR signature
if buffer[..2] != MBR_SIGNATURE {
return Err(IoError::new(ErrorKind::InvalidData, "Incorrect signature for MBR sector."));
return Err(Error::new(
ErrorKind::InvalidData,
"Incorrect signature for MBR sector.",
));
}
// Read partition ID.
self.seek(SeekFrom::Start(entry as u64 + 0x4))?;
@ -202,8 +164,9 @@ impl SdReader {
PARTID_FAT12 | PARTID_FAT16_LESS32M | PARTID_FAT16 |
PARTID_FAT16_LBA | PARTID_FAT32 | PARTID_FAT32_LBA => {}
_ => {
return Err(IoError::new(ErrorKind::InvalidData,
"No FAT partition found for the specified entry."
return Err(Error::new(
ErrorKind::InvalidData,
"No FAT partition found for the specified entry.",
));
}
}
@ -220,29 +183,8 @@ impl SdReader {
// setup fatfs
fatfs::FileSystem::new(self, fatfs::FsOptions::new())
}
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 Read for SdReader {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
let total_length = buf.len();
@ -269,6 +211,28 @@ 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 {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
let (a, b, c) = self.block_align(buf);
@ -296,7 +260,7 @@ impl Write for SdReader {
let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32);
self.sd
.write_block(block_addr, 1, &self.buffer)
.map_err(self.cmd_error_to_io_error)?;
.map_err(cmd_error_to_io_error)?;
self.dirty = false;
}
Ok(())
@ -311,7 +275,7 @@ impl Seek for SdReader {
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 {
return Err(IoError::new(ErrorKind::InvalidInput, "Invalid address"));
return Err(Error::new(ErrorKind::InvalidInput, "Invalid address"));
}
let target_byte_addr = raw_target as u32;
let address_same_block =

View File

@ -1,60 +1,59 @@
use core::arch::asm;
/// The classic no-op
#[inline]
pub fn nop() {
unsafe { asm!("nop") }
unsafe { llvm_asm!("nop" :::: "volatile") }
}
/// Wait For Event
#[inline]
pub fn wfe() {
unsafe { asm!("wfe") }
unsafe { llvm_asm!("wfe" :::: "volatile") }
}
/// Send Event
#[inline]
pub fn sev() {
unsafe { asm!("sev") }
unsafe { llvm_asm!("sev" :::: "volatile") }
}
/// Data Memory Barrier
#[inline]
pub fn dmb() {
unsafe { asm!("dmb") }
unsafe { llvm_asm!("dmb" :::: "volatile") }
}
/// Data Synchronization Barrier
#[inline]
pub fn dsb() {
unsafe { asm!("dsb") }
unsafe { llvm_asm!("dsb" :::: "volatile") }
}
/// Instruction Synchronization Barrier
#[inline]
pub fn isb() {
unsafe { asm!("isb") }
unsafe { llvm_asm!("isb" :::: "volatile") }
}
/// Enable FIQ
#[inline]
pub unsafe fn enable_fiq() {
asm!("cpsie f");
llvm_asm!("cpsie f":::: "volatile");
}
/// Enable IRQ
#[inline]
pub unsafe fn enable_irq() {
asm!("cpsie i");
llvm_asm!("cpsie i":::: "volatile");
}
/// Disable IRQ, return if IRQ was originally enabled.
#[inline]
pub unsafe fn enter_critical() -> bool {
let mut cpsr: u32;
asm!(
"mrs {}, cpsr
cpsid i", out(reg) cpsr);
llvm_asm!(
"mrs $0, cpsr
cpsid i"
: "=r"(cpsr) ::: "volatile");
(cpsr & (1 << 7)) == 0
}
@ -66,18 +65,18 @@ pub unsafe fn exit_critical(enable: bool) {
} else {
0
};
asm!(
llvm_asm!(
"mrs r1, cpsr
bic r1, r1, {}
bic r1, r1, $0
msr cpsr_c, r1"
, in(reg) mask);
:: "r"(mask) : "r1");
}
/// Exiting IRQ
#[inline]
pub unsafe fn exit_irq() {
asm!("
llvm_asm!("
mrs r0, SPSR
msr CPSR, r0
");
" ::: "r0");
}

View File

@ -1,12 +1,11 @@
use super::asm::{dmb, dsb};
use super::l2c::*;
use core::arch::asm;
/// Invalidate TLBs
#[inline(always)]
pub fn tlbiall() {
unsafe {
asm!("mcr p15, 0, {}, c8, c7, 0", in(reg) 0);
llvm_asm!("mcr p15, 0, $0, c8, c7, 0" :: "r" (0) :: "volatile");
}
}
@ -14,7 +13,7 @@ pub fn tlbiall() {
#[inline(always)]
pub fn iciallu() {
unsafe {
asm!("mcr p15, 0, {}, c7, c5, 0", in(reg) 0);
llvm_asm!("mcr p15, 0, $0, c7, c5, 0" :: "r" (0) :: "volatile");
}
}
@ -22,7 +21,7 @@ pub fn iciallu() {
#[inline(always)]
pub fn bpiall() {
unsafe {
asm!("mcr p15, 0, {}, c7, c5, 6", in(reg) 0);
llvm_asm!("mcr p15, 0, $0, c7, c5, 6" :: "r" (0) :: "volatile");
}
}
@ -30,7 +29,7 @@ pub fn bpiall() {
#[inline(always)]
pub fn dccsw(setway: u32) {
unsafe {
asm!("mcr p15, 0, {}, c7, c10, 2", in(reg) setway);
llvm_asm!("mcr p15, 0, $0, c7, c10, 2" :: "r" (setway) :: "volatile");
}
}
@ -42,7 +41,7 @@ pub fn dcisw(setway: u32) {
// also see example code (for DCCISW, but DCISW will be
// analogous) "Example code for cache maintenance operations"
// on pages B2-1286 and B2-1287.
asm!("mcr p15, 0, {}, c7, c6, 2", in(reg) setway);
llvm_asm!("mcr p15, 0, $0, c7, c6, 2" :: "r" (setway) :: "volatile");
}
}
@ -50,7 +49,7 @@ pub fn dcisw(setway: u32) {
#[inline(always)]
pub fn dccisw(setway: u32) {
unsafe {
asm!("mcr p15, 0, {}, c7, c14, 2", in(reg) setway);
llvm_asm!("mcr p15, 0, $0, c7, c14, 2" :: "r" (setway) :: "volatile");
}
}
@ -70,7 +69,7 @@ pub fn dciall_l1() {
// select L1 data cache
unsafe {
asm!("mcr p15, 2, {}, c0, c0, 0", in(reg) 0);
llvm_asm!("mcr p15, 2, $0, c0, c0, 0" :: "r" (0) :: "volatile");
}
// Invalidate entire D-Cache by iterating every set and every way
@ -105,7 +104,7 @@ pub fn dcciall_l1() {
// select L1 data cache
unsafe {
asm!("mcr p15, 2, {}, c0, c0, 0", in(reg) 0);
llvm_asm!("mcr p15, 2, $0, c0, c0, 0" :: "r" (0) :: "volatile");
}
// Invalidate entire D-Cache by iterating every set and every way
@ -157,7 +156,7 @@ fn slice_cache_line_addrs<T>(slice: &[T]) -> impl Iterator<Item = usize> {
#[inline(always)]
pub fn dccimvac(addr: usize) {
unsafe {
asm!("mcr p15, 0, {}, c7, c14, 1", in(reg) addr);
llvm_asm!("mcr p15, 0, $0, c7, c14, 1" :: "r" (addr) :: "volatile");
}
}
@ -199,9 +198,10 @@ pub fn dcci_slice<T>(slice: &[T]) {
#[inline(always)]
pub fn dccmvac(addr: usize) {
unsafe {
asm!("mcr p15, 0, {}, c7, c10, 1", in(reg) addr);
llvm_asm!("mcr p15, 0, $0, c7, c10, 1" :: "r" (addr) :: "volatile");
}
}
/// Data cache clean for an object.
pub fn dcc<T>(object: &T) {
dmb();
@ -239,7 +239,7 @@ pub fn dcc_slice<T>(slice: &[T]) {
/// affecting more data than intended.
#[inline(always)]
pub unsafe fn dcimvac(addr: usize) {
asm!("mcr p15, 0, {}, c7, c6, 1", in(reg) addr);
llvm_asm!("mcr p15, 0, $0, c7, c6, 1" :: "r" (addr) :: "volatile");
}
/// Data cache clean and invalidate for an object.

View File

@ -1,8 +1,7 @@
use core::arch::asm;
/// Enable FPU in the current core.
pub fn enable_fpu() {
unsafe {
asm!("
llvm_asm!("
mrc p15, 0, r1, c1, c0, 2
orr r1, r1, (0b1111<<20)
mcr p15, 0, r1, c1, c0, 2
@ -10,6 +9,6 @@ pub fn enable_fpu() {
vmrs r1, fpexc
orr r1, r1, (1<<30)
vmsr fpexc, r1
");
":::"r1");
}
}

View File

@ -1,5 +1,7 @@
#![no_std]
#![feature(llvm_asm, global_asm)]
#![feature(never_type)]
#![feature(const_fn)]
extern crate alloc;
@ -15,7 +17,6 @@ pub mod sync_channel;
mod uncached;
pub use fpu::enable_fpu;
pub use uncached::UncachedSlice;
use core::arch::global_asm;
global_asm!(include_str!("exceptions.s"));

View File

@ -2,7 +2,6 @@ use libregister::{
register_bit, register_bits,
RegisterR, RegisterW, RegisterRW,
};
use core::arch::asm;
macro_rules! def_reg_r {
($name:tt, $type: ty, $asm_instr:tt) => {
@ -12,7 +11,7 @@ macro_rules! def_reg_r {
#[inline]
fn read(&self) -> Self::R {
let mut value: u32;
unsafe { asm!($asm_instr, out(reg) value) }
unsafe { llvm_asm!($asm_instr : "=r" (value) ::: "volatile") }
value.into()
}
}
@ -27,7 +26,7 @@ macro_rules! def_reg_w {
#[inline]
fn write(&mut self, value: Self::W) {
let value: u32 = value.into();
unsafe { asm!($asm_instr, in(reg) value) }
unsafe { llvm_asm!($asm_instr :: "r" (value) :: "volatile") }
}
#[inline]
@ -72,29 +71,29 @@ macro_rules! wrap_reg {
/// Stack Pointer
pub struct SP;
def_reg_r!(SP, u32, "mov {}, sp");
def_reg_w!(SP, u32, "mov sp, {}");
def_reg_r!(SP, u32, "mov $0, sp");
def_reg_w!(SP, u32, "mov sp, $0");
/// Link register (function call return address)
pub struct LR;
def_reg_r!(LR, u32, "mov {}, lr");
def_reg_w!(LR, u32, "mov lr, {}");
def_reg_r!(LR, u32, "mov $0, lr");
def_reg_w!(LR, u32, "mov lr, $0");
pub struct VBAR;
def_reg_r!(VBAR, u32, "mrc p15, 0, {}, c12, c0, 0");
def_reg_w!(VBAR, u32, "mcr p15, 0, {}, c12, c0, 0");
def_reg_r!(VBAR, u32, "mrc p15, 0, $0, c12, c0, 0");
def_reg_w!(VBAR, u32, "mcr p15, 0, $0, c12, c0, 0");
pub struct MVBAR;
def_reg_r!(MVBAR, u32, "mrc p15, 0, {}, c12, c0, 1");
def_reg_w!(MVBAR, u32, "mcr p15, 0, {}, c12, c0, 1");
def_reg_r!(MVBAR, u32, "mrc p15, 0, $0, c12, c0, 1");
def_reg_w!(MVBAR, u32, "mcr p15, 0, $0, c12, c0, 1");
pub struct HVBAR;
def_reg_r!(HVBAR, u32, "mrc p15, 4, {}, c12, c0, 0");
def_reg_w!(HVBAR, u32, "mcr p15, 4, {}, c12, c0, 0");
def_reg_r!(HVBAR, u32, "mrc p15, 4, $0, c12, c0, 0");
def_reg_w!(HVBAR, u32, "mcr p15, 4, $0, c12, c0, 0");
/// Multiprocess Affinity Register
pub struct MPIDR;
def_reg_r!(MPIDR, mpidr::Read, "mrc p15, 0, {}, c0, c0, 5");
def_reg_r!(MPIDR, mpidr::Read, "mrc p15, 0, $0, c0, c0, 5");
wrap_reg!(mpidr);
register_bits!(mpidr,
/// CPU core index
@ -107,15 +106,15 @@ register_bit!(mpidr,
u, 30);
pub struct DFAR;
def_reg_r!(DFAR, u32, "mrc p15, 0, {}, c6, c0, 0");
def_reg_r!(DFAR, u32, "mrc p15, 0, $0, c6, c0, 0");
pub struct DFSR;
def_reg_r!(DFSR, u32, "mrc p15, 0, {}, c5, c0, 0");
def_reg_r!(DFSR, u32, "mrc p15, 0, $0, c5, c0, 0");
pub struct SCTLR;
wrap_reg!(sctlr);
def_reg_r!(SCTLR, sctlr::Read, "mrc p15, 0, {}, c1, c0, 0");
def_reg_w!(SCTLR, sctlr::Write, "mcr p15, 0, {}, c1, c0, 0");
def_reg_r!(SCTLR, sctlr::Read, "mrc p15, 0, $0, c1, c0, 0");
def_reg_w!(SCTLR, sctlr::Write, "mcr p15, 0, $0, c1, c0, 0");
register_bit!(sctlr,
/// Enables MMU
m, 0);
@ -148,8 +147,8 @@ register_bit!(sctlr,
/// Auxiliary Control Register
pub struct ACTLR;
wrap_reg!(actlr);
def_reg_r!(ACTLR, actlr::Read, "mrc p15, 0, {}, c1, c0, 1");
def_reg_w!(ACTLR, actlr::Write, "mcr p15, 0, {}, c1, c0, 1");
def_reg_r!(ACTLR, actlr::Read, "mrc p15, 0, $0, c1, c0, 1");
def_reg_w!(ACTLR, actlr::Write, "mcr p15, 0, $0, c1, c0, 1");
// SMP bit
register_bit!(actlr, parity_on, 9);
register_bit!(actlr, alloc_one_way, 8);
@ -184,17 +183,17 @@ impl ACTLR {
/// Domain Access Control Register
pub struct DACR;
def_reg_r!(DACR, u32, "mrc p15, 0, {}, c3, c0, 0");
def_reg_w!(DACR, u32, "mcr p15, 0, {}, c3, c0, 0");
def_reg_r!(DACR, u32, "mrc p15, 0, $0, c3, c0, 0");
def_reg_w!(DACR, u32, "mcr p15, 0, $0, c3, c0, 0");
/// Translation Table Base Register 0
pub struct TTBR0;
/// Translation Table Base Register 1
pub struct TTBR1;
def_reg_r!(TTBR0, ttbr::Read, "mrc p15, 0, {}, c2, c0, 0");
def_reg_w!(TTBR0, ttbr::Write, "mcr p15, 0, {}, c2, c0, 0");
def_reg_r!(TTBR1, ttbr::Read, "mrc p15, 0, {}, c2, c0, 1");
def_reg_w!(TTBR1, ttbr::Write, "mcr p15, 0, {}, c2, c0, 1");
def_reg_r!(TTBR0, ttbr::Read, "mrc p15, 0, $0, c2, c0, 0");
def_reg_w!(TTBR0, ttbr::Write, "mcr p15, 0, $0, c2, c0, 0");
def_reg_r!(TTBR1, ttbr::Read, "mrc p15, 0, $0, c2, c0, 1");
def_reg_w!(TTBR1, ttbr::Write, "mcr p15, 0, $0, c2, c0, 1");
wrap_reg!(ttbr);
register_bits!(ttbr, table_base, u32, 14, 31);
register_bit!(ttbr, irgn0, 6);

View File

@ -178,8 +178,7 @@ macro_rules! sync_channel {
{
use core::sync::atomic::{AtomicUsize, AtomicPtr};
use $crate::sync_channel::{Sender, Receiver};
const cnst_ptr: AtomicPtr<$t> = AtomicPtr::new(core::ptr::null_mut());
static LIST: [AtomicPtr<$t>; $cap + 1] = [cnst_ptr; $cap + 1];
static LIST: [AtomicPtr<$t>; $cap + 1] = [AtomicPtr::new(core::ptr::null_mut()); $cap + 1];
static WRITE: AtomicUsize = AtomicUsize::new(0);
static READ: AtomicUsize = AtomicUsize::new(0);
(Sender::new(&LIST, &WRITE, &READ), Receiver::new(&LIST, &WRITE, &READ))

View File

@ -8,6 +8,7 @@ edition = "2018"
[features]
target_zc706 = ["libboard_zynq/target_zc706"]
target_coraz7 = ["libboard_zynq/target_coraz7"]
target_ebaz4205 = ["libboard_zynq/target_ebaz4205"]
target_redpitaya = ["libboard_zynq/target_redpitaya"]
target_kasli_soc = ["libboard_zynq/target_kasli_soc"]
panic_handler = []
@ -19,7 +20,7 @@ default = ["panic_handler", "dummy_irq_handler", "dummy_fiq_handler"]
[dependencies]
r0 = "1"
compiler_builtins = { version = "0.1", features = ["no-f16-f128"] }
compiler_builtins = "=0.1.39"
linked_list_allocator = { version = "0.8", default-features = false, features = ["const_mut_refs"] }
libregister = { path = "../libregister" }
libcortex_a9 = { path = "../libcortex_a9" }

View File

@ -1,6 +1,5 @@
use r0::zero_bss;
use core::ptr::write_volatile;
use core::arch::asm;
use libregister::{
VolatileCell,
RegisterR, RegisterRW,

View File

@ -1,7 +1,6 @@
use libregister::{RegisterR, RegisterW};
use libcortex_a9::{regs::{DFSR, MPIDR, VBAR}, interrupt_handler};
use libboard_zynq::{println, stdio};
use core::arch::asm;
pub fn set_vector_table(base_addr: u32){
VBAR.write(base_addr);

View File

@ -3,6 +3,7 @@
#![feature(alloc_error_handler)]
#![feature(panic_info_message)]
#![feature(naked_functions)]
#![feature(asm)]
pub extern crate alloc;
pub extern crate compiler_builtins;

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

@ -8,6 +8,7 @@ edition = "2018"
[features]
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_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_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc", "libconfig/target_kasli_soc"]
default = ["target_zc706"]
@ -15,6 +16,7 @@ default = ["target_zc706"]
[dependencies]
log = "0.4"
byteorder = { version = "1.3", default-features = false }
core_io = { version = "0.1", features = ["collections"] }
libboard_zynq = { path = "../libboard_zynq" }
libsupport_zynq = { path = "../libsupport_zynq" }

View File

@ -80,12 +80,15 @@ pub fn main_core0() {
);
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;
#[cfg(feature = "target_kasli_soc")]
const CPU_FREQ: u32 = 1_000_000_000;
#[cfg(feature = "target_ebaz4205")]
const CPU_FREQ: u32 = 666_666_666;
ArmPll::setup(2 * CPU_FREQ);
Clocks::set_cpu_freq(CPU_FREQ);
IoPll::setup(1_000_000_000);