Compare commits
13 Commits
master
...
flakes_sup
Author | SHA1 | Date |
---|---|---|
mwojcik | 95a1ea03da | |
mwojcik | 810f17c874 | |
mwojcik | 68c8bb09ac | |
mwojcik | e81d020e90 | |
mwojcik | 8497f9746b | |
mwojcik | a7db47276b | |
mwojcik | 8308efa39e | |
mwojcik | bf15ad091f | |
mwojcik | b96458da26 | |
mwojcik | 7efd12f3b4 | |
mwojcik | 1cc4a33fce | |
mwojcik | 8a84d0bbf0 | |
mwojcik | d6e3167e44 |
|
@ -8,9 +8,9 @@ checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
|
@ -20,9 +20,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -47,9 +47,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "embedded-hal"
|
||||
version = "0.2.7"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
|
||||
checksum = "e36cfb62ff156596c892272f3015ef952fe1525e85261fa3a7f327bd6b384ab9"
|
||||
dependencies = [
|
||||
"nb 0.1.3",
|
||||
"void",
|
||||
|
@ -250,9 +250,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
|||
|
||||
[[package]]
|
||||
name = "volatile-register"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
|
||||
checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
|
||||
dependencies = [
|
||||
"vcell",
|
||||
]
|
||||
|
|
|
@ -14,7 +14,7 @@ members = [
|
|||
panic = "abort"
|
||||
debug = true
|
||||
codegen-units = 1
|
||||
opt-level = 's'
|
||||
opt-level = 'z'
|
||||
lto = true
|
||||
debug-assertions = false
|
||||
overflow-checks = false
|
||||
|
|
|
@ -65,5 +65,5 @@ openocd -f zc706.cfg -c "pld load 0 blinker_migen.bit; exit"
|
|||
|
||||
## License
|
||||
|
||||
Copyright (C) 2019-2022 M-Labs Limited.
|
||||
Copyright (C) 2019-2021 M-Labs Limited.
|
||||
Released under the GNU LGPL v3. See the LICENSE file for details.
|
||||
|
|
|
@ -18,5 +18,5 @@ embedded-hal = "0.2"
|
|||
libregister = { path = "../libregister" }
|
||||
libcortex_a9 = { path = "../libcortex_a9" }
|
||||
libboard_zynq = { path = "../libboard_zynq" }
|
||||
libsupport_zynq = { path = "../libsupport_zynq", default-features = false, features = ["panic_handler", "dummy_fiq_handler"]}
|
||||
libsupport_zynq = { path = "../libsupport_zynq", default-features = false, features = ["panic_handler"]}
|
||||
libasync = { path = "../libasync" }
|
||||
|
|
|
@ -39,7 +39,7 @@ use libcortex_a9::{
|
|||
};
|
||||
use libregister::{RegisterR, RegisterW};
|
||||
use libsupport_zynq::{
|
||||
boot, exception_vectors, ram,
|
||||
boot, ram,
|
||||
};
|
||||
use log::{info, warn};
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
@ -56,29 +56,19 @@ extern "C" {
|
|||
static CORE1_RESTART: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, {
|
||||
let mpcore = mpcore::RegisterBlock::mpcore();
|
||||
let mut gic = gic::InterruptController::gic(mpcore);
|
||||
let id = gic.get_interrupt_id();
|
||||
match MPIDR.read().cpu_id(){
|
||||
0 => {
|
||||
if id.0 == 0 {
|
||||
println!("Interrupting core0...");
|
||||
gic.end_interrupt(id);
|
||||
return;
|
||||
}
|
||||
},
|
||||
1 => {
|
||||
if id.0 == 0 {
|
||||
gic.end_interrupt(id);
|
||||
asm::exit_irq();
|
||||
SP.write(&mut __stack1_start as *mut _ as u32);
|
||||
asm::enable_irq();
|
||||
CORE1_RESTART.store(false, Ordering::Relaxed);
|
||||
notify_spin_lock();
|
||||
main_core1();
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
if MPIDR.read().cpu_id() == 1{
|
||||
let mpcore = mpcore::RegisterBlock::mpcore();
|
||||
let mut gic = gic::InterruptController::gic(mpcore);
|
||||
let id = gic.get_interrupt_id();
|
||||
if id.0 == 0 {
|
||||
gic.end_interrupt(id);
|
||||
asm::exit_irq();
|
||||
SP.write(&mut __stack1_start as *mut _ as u32);
|
||||
asm::enable_irq();
|
||||
CORE1_RESTART.store(false, Ordering::Relaxed);
|
||||
notify_spin_lock();
|
||||
main_core1();
|
||||
}
|
||||
}
|
||||
stdio::drop_uart();
|
||||
println!("IRQ");
|
||||
|
@ -96,7 +86,6 @@ pub fn restart_core1() {
|
|||
|
||||
#[no_mangle]
|
||||
pub fn main_core0() {
|
||||
exception_vectors::set_vector_table(0x0);
|
||||
// zynq::clocks::CpuClocks::enable_io(1_250_000_000);
|
||||
enable_l2_cache(0x8);
|
||||
println!("\nZynq experiments");
|
||||
|
@ -145,10 +134,6 @@ pub fn main_core0() {
|
|||
ddr.memtest();
|
||||
ram::init_alloc_ddr(&mut ddr);
|
||||
|
||||
info!("Send software interrupt to core0");
|
||||
interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core0.into());
|
||||
info!("Core0 returned from interrupt");
|
||||
|
||||
boot::Core1::start(false);
|
||||
|
||||
let core1_req = unsafe { &mut CORE1_REQ.0 };
|
||||
|
@ -198,20 +183,6 @@ pub fn main_core0() {
|
|||
println!("");
|
||||
}
|
||||
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
{
|
||||
let mut err_cdwn = timer.countdown();
|
||||
let mut err_state = true;
|
||||
let mut led = zynq::error_led::ErrorLED::error_led();
|
||||
task::spawn( async move {
|
||||
loop {
|
||||
led.toggle(err_state);
|
||||
err_state = !err_state;
|
||||
delay(&mut err_cdwn, Milliseconds(1000)).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let eth = zynq::eth::Eth::eth0(HWADDR.clone());
|
||||
println!("Eth on");
|
||||
|
||||
|
|
14
flake.lock
14
flake.lock
|
@ -3,11 +3,11 @@
|
|||
"mozilla-overlay": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1704373101,
|
||||
"narHash": "sha256-+gi59LRWRQmwROrmE1E2b3mtocwueCQqZ60CwLG+gbg=",
|
||||
"lastModified": 1638887313,
|
||||
"narHash": "sha256-FMYV6rVtvSIfthgC1sK1xugh3y7muoQcvduMdriz4ag=",
|
||||
"owner": "mozilla",
|
||||
"repo": "nixpkgs-mozilla",
|
||||
"rev": "9b11a87c0cc54e308fa83aac5b4ee1816d5418a2",
|
||||
"rev": "7c1e8b1dd6ed0043fb4ee0b12b815256b0b9de6f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -18,16 +18,16 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1715087517,
|
||||
"narHash": "sha256-CLU5Tsg24Ke4+7sH8azHWXKd0CFd4mhLWfhYgUiDBpQ=",
|
||||
"lastModified": 1642961095,
|
||||
"narHash": "sha256-RLatktZmvwFBOyqdoIk4qdS4OGKB7aKIvvs4ZP2L8D8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b211b392b8486ee79df6cdfb1157ad2133427a29",
|
||||
"rev": "604c44137d97b5111be1ca5c0d97f6e24fbc5c2c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"ref": "nixos-21.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
|
208
flake.nix
208
flake.nix
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
description = "Bare-metal Rust on Zynq-7000";
|
||||
|
||||
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable;
|
||||
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-21.11;
|
||||
inputs.mozilla-overlay = { url = github:mozilla/nixpkgs-mozilla; flake = false; };
|
||||
|
||||
outputs = { self, nixpkgs, mozilla-overlay }:
|
||||
let
|
||||
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import mozilla-overlay) crosspkgs-overlay ]; };
|
||||
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import mozilla-overlay) ]; };
|
||||
|
||||
rustManifest = pkgs.fetchurl {
|
||||
url = "https://static.rust-lang.org/dist/2021-01-29/channel-rust-nightly.toml";
|
||||
|
@ -26,29 +26,148 @@
|
|||
cargo = rust;
|
||||
});
|
||||
|
||||
crosspkgs-overlay = (self: super: {
|
||||
pkgsCross = super.pkgsCross // {
|
||||
zynq-baremetal = import super.path {
|
||||
system = "x86_64-linux";
|
||||
crossSystem = {
|
||||
config = "arm-none-eabihf";
|
||||
libc = "newlib";
|
||||
gcc.cpu = "cortex-a9";
|
||||
gcc.fpu = "vfpv3";
|
||||
};
|
||||
};
|
||||
gnu-platform = "arm-none-eabi";
|
||||
|
||||
binutils-pkg = { zlib, extraConfigureFlags ? [] }: pkgs.stdenv.mkDerivation rec {
|
||||
basename = "binutils";
|
||||
version = "2.30";
|
||||
name = "${basename}-${gnu-platform}-${version}";
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://ftp.gnu.org/gnu/binutils/binutils-${version}.tar.bz2";
|
||||
sha256 = "028cklfqaab24glva1ks2aqa1zxa6w6xmc8q34zs1sb7h22dxspg";
|
||||
};
|
||||
});
|
||||
configureFlags = [
|
||||
"--enable-deterministic-archives"
|
||||
"--target=${gnu-platform}"
|
||||
"--with-cpu=cortex-a9"
|
||||
"--with-fpu=vfpv3"
|
||||
"--with-float=hard"
|
||||
"--with-mode=thumb"
|
||||
] ++ extraConfigureFlags;
|
||||
outputs = [ "out" "info" "man" ];
|
||||
depsBuildBuild = [ pkgs.buildPackages.stdenv.cc ];
|
||||
buildInputs = [ zlib ];
|
||||
enableParallelBuilding = true;
|
||||
meta = {
|
||||
description = "Tools for manipulating binaries (linker, assembler, etc.)";
|
||||
longDescription = ''
|
||||
The GNU Binutils are a collection of binary tools. The main
|
||||
ones are `ld' (the GNU linker) and `as' (the GNU assembler).
|
||||
They also include the BFD (Binary File Descriptor) library,
|
||||
`gprof', `nm', `strip', etc.
|
||||
'';
|
||||
homepage = http://www.gnu.org/software/binutils/;
|
||||
license = pkgs.lib.licenses.gpl3Plus;
|
||||
/* Give binutils a lower priority than gcc-wrapper to prevent a
|
||||
collision due to the ld/as wrappers/symlinks in the latter. */
|
||||
priority = "10";
|
||||
};
|
||||
};
|
||||
|
||||
gcc-pkg = { gmp, mpfr, libmpc, platform-binutils, extraConfigureFlags ? [] }: pkgs.stdenv.mkDerivation rec {
|
||||
basename = "gcc";
|
||||
version = "9.1.0";
|
||||
name = "${basename}-${gnu-platform}-${version}";
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://ftp.gnu.org/gnu/gcc/gcc-${version}/gcc-${version}.tar.xz";
|
||||
sha256 = "1817nc2bqdc251k0lpc51cimna7v68xjrnvqzvc50q3ax4s6i9kr";
|
||||
};
|
||||
preConfigure = ''
|
||||
mkdir build
|
||||
cd build
|
||||
'';
|
||||
configureScript = "../configure";
|
||||
configureFlags = [
|
||||
"--target=${gnu-platform}"
|
||||
"--with-arch=armv7-a"
|
||||
"--with-tune=cortex-a9"
|
||||
"--with-fpu=vfpv3"
|
||||
"--with-float=hard"
|
||||
"--disable-libssp"
|
||||
"--enable-languages=c"
|
||||
"--with-as=${platform-binutils}/bin/${gnu-platform}-as"
|
||||
"--with-ld=${platform-binutils}/bin/${gnu-platform}-ld" ] ++ extraConfigureFlags;
|
||||
outputs = [ "out" "info" "man" ];
|
||||
hardeningDisable = [ "format" "pie" ];
|
||||
propagatedBuildInputs = [ gmp mpfr libmpc platform-binutils ];
|
||||
enableParallelBuilding = true;
|
||||
dontFixup = true;
|
||||
};
|
||||
|
||||
newlib-pkg = { platform-binutils, platform-gcc }: pkgs.stdenv.mkDerivation rec {
|
||||
pname = "newlib";
|
||||
version = "3.1.0";
|
||||
src = pkgs.fetchurl {
|
||||
url = "ftp://sourceware.org/pub/newlib/newlib-${version}.tar.gz";
|
||||
sha256 = "0ahh3n079zjp7d9wynggwrnrs27440aac04340chf1p9476a2kzv";
|
||||
};
|
||||
nativeBuildInputs = [ platform-binutils platform-gcc ];
|
||||
configureFlags = [
|
||||
"--target=${gnu-platform}"
|
||||
|
||||
"--with-cpu=cortex-a9"
|
||||
"--with-fpu=vfpv3"
|
||||
"--with-float=hard"
|
||||
"--with-mode=thumb"
|
||||
"--enable-interwork"
|
||||
"--disable-multilib"
|
||||
|
||||
"--disable-newlib-supplied-syscalls"
|
||||
"--with-gnu-ld"
|
||||
"--with-gnu-as"
|
||||
"--disable-newlib-io-float"
|
||||
"--disable-werror"
|
||||
];
|
||||
dontFixup = true;
|
||||
};
|
||||
gnutoolchain = rec {
|
||||
binutils-bootstrap = pkgs.callPackage binutils-pkg { };
|
||||
gcc-bootstrap = pkgs.callPackage gcc-pkg {
|
||||
platform-binutils = binutils-bootstrap;
|
||||
extraConfigureFlags = [ "--disable-libgcc" ];
|
||||
};
|
||||
newlib = pkgs.callPackage newlib-pkg {
|
||||
platform-binutils = binutils-bootstrap;
|
||||
platform-gcc = gcc-bootstrap;
|
||||
};
|
||||
binutils = pkgs.callPackage binutils-pkg {
|
||||
extraConfigureFlags = [ "--with-lib-path=${newlib}/arm-none-eabi/lib" ];
|
||||
};
|
||||
gcc = pkgs.callPackage gcc-pkg {
|
||||
platform-binutils = binutils;
|
||||
extraConfigureFlags = [ "--enable-newlib" "--with-headers=${newlib}/arm-none-eabi/include" ];
|
||||
};
|
||||
};
|
||||
|
||||
cargo-xbuild = rustPlatform.buildRustPackage rec {
|
||||
pname = "cargo-xbuild";
|
||||
version = "0.6.5";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "rust-osdev";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "18djvygq9v8rmfchvi2hfj0i6fhn36m716vqndqnj56fiqviwxvf";
|
||||
};
|
||||
cargoSha256 = "13sj9j9kl6js75h9xq0yidxy63vixxm9q3f8jil6ymarml5wkhx8";
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "Automatically cross-compiles the sysroot crates core, compiler_builtins, and alloc";
|
||||
homepage = "https://github.com/rust-osdev/cargo-xbuild";
|
||||
license = with licenses; [ mit asl20 ];
|
||||
maintainers = with maintainers; [ johntitor xrelkd ];
|
||||
};
|
||||
};
|
||||
|
||||
mkbootimage = pkgs.stdenv.mkDerivation {
|
||||
pname = "mkbootimage";
|
||||
version = "2.3dev";
|
||||
version = "2.2";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "antmicro";
|
||||
repo = "zynq-mkbootimage";
|
||||
rev = "872363ce32c249f8278cf107bc6d3bdeb38d849f";
|
||||
sha256 = "sha256-5FPyAhUWZDwHbqmp9J2ZXTmjaXPz+dzrJMolaNwADHs=";
|
||||
rev = "4ee42d782a9ba65725ed165a4916853224a8edf7";
|
||||
sha256 = "1k1mbsngqadqihzjgvwvsrkvryxy5ladpxd9yh9iqn2s7fxqwqa9";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [ pkgs.libelf pkgs.pcre ];
|
||||
|
@ -61,7 +180,6 @@
|
|||
mkdir -p $out/bin
|
||||
cp mkbootimage $out/bin
|
||||
'';
|
||||
hardeningDisable = [ "fortify" ];
|
||||
};
|
||||
|
||||
fsbl = { board ? "zc706" }: pkgs.stdenv.mkDerivation {
|
||||
|
@ -69,20 +187,19 @@
|
|||
src = pkgs.fetchFromGitHub {
|
||||
owner = "Xilinx";
|
||||
repo = "embeddedsw";
|
||||
rev = "xilinx_v2022.2";
|
||||
sha256 = "sha256-UDz9KK/Hw3qM1BAeKif30rE8Bi6C2uvuZlvyvtJCMfw=";
|
||||
rev = "65c849ed46c88c67457e1fc742744f96db968ff1";
|
||||
sha256 = "1rvl06ha40dzd6s9aa4sylmksh4xb9dqaxq462lffv1fdk342pda";
|
||||
};
|
||||
patches = [ ./fsbl.patch ];
|
||||
nativeBuildInputs = [
|
||||
pkgs.pkgsCross.zynq-baremetal.buildPackages.binutils
|
||||
pkgs.pkgsCross.zynq-baremetal.buildPackages.gcc
|
||||
pkgs.gnumake
|
||||
gnutoolchain.binutils
|
||||
gnutoolchain.gcc
|
||||
];
|
||||
patchPhase = ''
|
||||
patch -p1 -i ${./fsbl.patch}
|
||||
patchShebangs lib/sw_apps/zynq_fsbl/misc/copy_bsp.sh
|
||||
|
||||
for x in lib/sw_apps/zynq_fsbl/src/Makefile lib/sw_apps/zynq_fsbl/misc/copy_bsp.sh lib/bsp/standalone/src/arm/cortexa9/gcc/Makefile; do
|
||||
substituteInPlace $x \
|
||||
--replace "arm-none-eabi-" "arm-none-eabihf-"
|
||||
done
|
||||
echo 'SEARCH_DIR("${gnutoolchain.newlib}/arm-none-eabi/lib");' >> lib/sw_apps/zynq_fsbl/src/lscript.ld
|
||||
'';
|
||||
buildPhase = ''
|
||||
cd lib/sw_apps/zynq_fsbl/src
|
||||
|
@ -96,10 +213,6 @@
|
|||
dontFixup = true;
|
||||
};
|
||||
|
||||
cargo-xbuild = pkgs.cargo-xbuild.overrideAttrs(oa: {
|
||||
postPatch = "substituteInPlace src/sysroot.rs --replace 2021 2018";
|
||||
});
|
||||
|
||||
build-crate = name: crate: features: rustPlatform.buildRustPackage rec {
|
||||
name = "${crate}";
|
||||
|
||||
|
@ -108,9 +221,9 @@
|
|||
) ./.;
|
||||
cargoLock = { lockFile = ./Cargo.lock; };
|
||||
|
||||
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_14.clang-unwrapped ];
|
||||
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_9.clang-unwrapped ];
|
||||
buildPhase = ''
|
||||
export XARGO_RUST_SRC="${rust}/lib/rustlib/src/rust/library"
|
||||
export XARGO_RUST_SRC="${rustPlatform.rust.rustc}/lib/rustlib/src/rust/library"
|
||||
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
|
||||
pushd ${crate}
|
||||
cargo xbuild --release --frozen \
|
||||
|
@ -127,7 +240,6 @@
|
|||
|
||||
doCheck = false;
|
||||
dontFixup = true;
|
||||
auditable = false;
|
||||
};
|
||||
|
||||
targetCrates = target: {
|
||||
|
@ -145,28 +257,28 @@
|
|||
in
|
||||
commands + "ln -s ${szlResult}/szl.elf $out/szl-${target}.elf\n"
|
||||
) "mkdir $out\n" targets);
|
||||
in rec {
|
||||
packages.x86_64-linux = {
|
||||
inherit cargo-xbuild szl mkbootimage;
|
||||
|
||||
allOutputs = {
|
||||
inherit cargo-xbuild szl;
|
||||
zc706-fsbl = fsbl { board = "zc706"; };
|
||||
} // allTargetCrates ;
|
||||
in rec {
|
||||
packages.x86_64-linux = allOutputs;
|
||||
|
||||
hydraJobs = packages.x86_64-linux;
|
||||
|
||||
inherit rust rustPlatform;
|
||||
|
||||
devShell.x86_64-linux = pkgs.mkShell {
|
||||
name = "zynq-rs-dev-shell";
|
||||
buildInputs = [
|
||||
rust
|
||||
buildInputs = with pkgs; [
|
||||
rustPlatform.rust.rustc
|
||||
rustPlatform.rust.cargo
|
||||
cacert
|
||||
cargo-xbuild
|
||||
mkbootimage
|
||||
|
||||
pkgs.openocd pkgs.gdb
|
||||
pkgs.openssh pkgs.rsync
|
||||
pkgs.llvmPackages_14.clang-unwrapped
|
||||
(pkgs.python3.withPackages(ps: [ ps.pyftdi ]))
|
||||
];
|
||||
};
|
||||
openocd gdb
|
||||
openssh rsync
|
||||
llvmPackages_9.clang-unwrapped
|
||||
mkbootimage ];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
diff --git a/lib/sw_apps/zynq_fsbl/src/Makefile b/lib/sw_apps/zynq_fsbl/src/Makefile
|
||||
index 0e3ccdf1c5..a5b02f386e 100644
|
||||
--- a/lib/sw_apps/zynq_fsbl/src/Makefile
|
||||
+++ b/lib/sw_apps/zynq_fsbl/src/Makefile
|
||||
@@ -71,11 +71,14 @@ endif
|
||||
all: $(EXEC)
|
||||
|
||||
$(EXEC): $(LIBS) $(OBJS) $(INCLUDES)
|
||||
- cp $(BSP_DIR)/$(BOARD)/ps7_init.* .
|
||||
$(LINKER) $(LD1FLAGS) -o $@ $(OBJS) $(LDFLAGS)
|
||||
rm -rf $(OBJS)
|
||||
-
|
||||
-
|
||||
+
|
||||
+.PHONY: ps7_init
|
||||
+
|
||||
+ps7_init:
|
||||
+ cp $(BSP_DIR)/$(BOARD)/ps7_init.* .
|
||||
+
|
||||
$(LIBS):
|
||||
echo "Copying BSP files"
|
||||
$(BSP_DIR)/copy_bsp.sh $(BOARD) $(CC)
|
||||
@@ -86,7 +89,7 @@ $(LIBS):
|
||||
make -C $(BSP_DIR) -k all "CC=armcc" "AR=armar" "C_FLAGS= -O2 -c" "EC_FLAGS=--debug --wchar32"; \
|
||||
fi;
|
||||
|
||||
-%.o:%.c
|
||||
+%.o:%.c ps7_init
|
||||
$(CC) $(CC_FLAGS) $(CFLAGS) $(ECFLAGS) -c $< -o $@ $(INCLUDEPATH)
|
||||
|
||||
%.o:%.S
|
|
@ -1,114 +0,0 @@
|
|||
use libregister::{RegisterRW, RegisterW};
|
||||
use libregister::{register, register_at, register_bit, register_bits};
|
||||
use super::slcr;
|
||||
|
||||
pub struct ErrorLED {
|
||||
regs: RegisterBlock,
|
||||
}
|
||||
|
||||
impl ErrorLED {
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
pub fn error_led() -> Self {
|
||||
slcr::RegisterBlock::unlocked(|slcr| {
|
||||
// Error LED at MIO pin 37
|
||||
slcr.mio_pin_37.write(
|
||||
slcr::MioPin37::zeroed()
|
||||
.l3_sel(0b000)
|
||||
.io_type(slcr::IoBufferType::Lvcmos25)
|
||||
.pullup(true)
|
||||
.disable_rcvr(true)
|
||||
);
|
||||
});
|
||||
|
||||
Self::error_led_common(0xFFFF - 0x0080)
|
||||
}
|
||||
|
||||
fn error_led_common(gpio_output_mask: u16) -> Self {
|
||||
// Setup register block
|
||||
let self_ = Self {
|
||||
regs: RegisterBlock::error_led(),
|
||||
};
|
||||
|
||||
// Setup GPIO output mask
|
||||
self_.regs.gpio_output_mask.modify(|_, w| {
|
||||
w.mask(gpio_output_mask)
|
||||
});
|
||||
|
||||
self_.regs.gpio_direction.modify(|_, w| {
|
||||
w.lederr(true)
|
||||
});
|
||||
|
||||
self_
|
||||
}
|
||||
|
||||
fn led_oe(&mut self, oe: bool) {
|
||||
self.regs.gpio_output_enable.modify(|_, w| {
|
||||
w.lederr(oe)
|
||||
})
|
||||
}
|
||||
|
||||
fn led_o(&mut self, o: bool) {
|
||||
self.regs.gpio_output_mask.modify(|_, w| {
|
||||
w.lederr_o(o)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn toggle(&mut self, state: bool) {
|
||||
self.led_o(state);
|
||||
self.led_oe(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct RegisterBlock {
|
||||
pub gpio_output_mask: &'static mut GPIOOutputMask,
|
||||
pub gpio_direction: &'static mut GPIODirection,
|
||||
pub gpio_output_enable: &'static mut GPIOOutputEnable,
|
||||
}
|
||||
|
||||
impl RegisterBlock {
|
||||
pub fn error_led() -> Self {
|
||||
Self {
|
||||
gpio_output_mask: GPIOOutputMask::new(),
|
||||
gpio_direction: GPIODirection::new(),
|
||||
gpio_output_enable: GPIOOutputEnable::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
register!(gpio_output_mask,
|
||||
/// MASK_DATA_1_LSW:
|
||||
/// Maskable output data for MIO[47:32]
|
||||
GPIOOutputMask, RW, u32);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_at!(GPIOOutputMask, 0xE000A008, new);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_bit!(gpio_output_mask,
|
||||
/// Output for LED_ERR (MIO[37])
|
||||
lederr_o, 5);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_bits!(gpio_output_mask,
|
||||
mask, u16, 16, 31);
|
||||
|
||||
register!(gpio_direction,
|
||||
/// DIRM_1:
|
||||
/// Direction mode for MIO[53:32]; 0/1 = in/out
|
||||
GPIODirection, RW, u32);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_at!(GPIODirection, 0xE000A244, new);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_bit!(gpio_direction,
|
||||
/// Direction for LED_ERR
|
||||
lederr, 5);
|
||||
|
||||
register!(gpio_output_enable,
|
||||
/// OEN_1:
|
||||
/// Output enable for MIO[53:32]
|
||||
GPIOOutputEnable, RW, u32);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_at!(GPIOOutputEnable, 0xE000A248, new);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_bit!(gpio_output_enable,
|
||||
/// Output enable for LED_ERR
|
||||
lederr, 5);
|
||||
|
|
@ -13,9 +13,6 @@ mod regs;
|
|||
pub mod rx;
|
||||
pub mod tx;
|
||||
|
||||
use super::time::Milliseconds;
|
||||
use embedded_hal::timer::CountDown;
|
||||
|
||||
/// Size of all the buffers
|
||||
pub const MTU: usize = 1536;
|
||||
/// Maximum MDC clock
|
||||
|
@ -303,25 +300,16 @@ impl<GEM: Gem> Eth<GEM, (), ()> {
|
|||
fn gem_common(macaddr: [u8; 6]) -> Self {
|
||||
GEM::setup_clock(TX_1000);
|
||||
|
||||
#[cfg(feature="target_kasli_soc")]
|
||||
{
|
||||
let mut eth_reset_pin = PhyRst::rst_pin();
|
||||
eth_reset_pin.reset();
|
||||
}
|
||||
|
||||
let mut inner = EthInner {
|
||||
gem: PhantomData,
|
||||
link: None,
|
||||
};
|
||||
inner.init();
|
||||
|
||||
inner.configure(macaddr);
|
||||
|
||||
let phy = Phy::find(&mut inner).expect("phy");
|
||||
phy.reset(&mut inner);
|
||||
phy.restart_autoneg(&mut inner);
|
||||
#[cfg(feature="target_kasli_soc")]
|
||||
phy.set_leds(&mut inner);
|
||||
|
||||
Eth {
|
||||
rx: (),
|
||||
|
@ -492,69 +480,6 @@ impl<'a, GEM: Gem> smoltcp::phy::Device<'a> for &mut Eth<GEM, rx::DescList, tx::
|
|||
}
|
||||
}
|
||||
|
||||
pub struct PhyRst {
|
||||
regs: regs::GpioRegisterBlock,
|
||||
count_down: super::timer::global::CountDown<Milliseconds>,
|
||||
}
|
||||
|
||||
impl PhyRst {
|
||||
pub fn rst_pin() -> Self {
|
||||
slcr::RegisterBlock::unlocked(|slcr| {
|
||||
// Hardware Reset for PHY
|
||||
slcr.mio_pin_47.write(
|
||||
slcr::MioPin47::zeroed()
|
||||
.l3_sel(0b000)
|
||||
.io_type(slcr::IoBufferType::Lvcmos18)
|
||||
.pullup(true)
|
||||
.disable_rcvr(true)
|
||||
);
|
||||
});
|
||||
Self::eth_reset_common(0xFFFF - 0x8000)
|
||||
}
|
||||
|
||||
fn delay_ms(&mut self, ms: u64) {
|
||||
self.count_down.start(Milliseconds(ms));
|
||||
nb::block!(self.count_down.wait()).unwrap();
|
||||
}
|
||||
|
||||
fn eth_reset_common(gpio_output_mask: u16) -> Self {
|
||||
let self_ = Self {
|
||||
regs: regs::GpioRegisterBlock::regs(),
|
||||
count_down: unsafe { super::timer::GlobalTimer::get() }.countdown(),
|
||||
};
|
||||
|
||||
// Setup GPIO output mask
|
||||
self_.regs.gpio_output_mask.modify(|_, w| {
|
||||
w.mask(gpio_output_mask)
|
||||
});
|
||||
|
||||
self_.regs.gpio_direction.modify(|_, w| {
|
||||
w.phy_rst(true)
|
||||
});
|
||||
|
||||
self_
|
||||
}
|
||||
|
||||
fn oe(&mut self, oe: bool) {
|
||||
self.regs.gpio_output_enable.modify(|_, w| {
|
||||
w.phy_rst(oe)
|
||||
})
|
||||
}
|
||||
|
||||
fn toggle(&mut self, o: bool) {
|
||||
self.regs.gpio_output_mask.modify(|_, w| {
|
||||
w.phy_rst(o)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.toggle(false); // drive phy_rst (active LOW) pin low
|
||||
self.oe(true); // enable pin's output
|
||||
self.delay_ms(10);
|
||||
self.toggle(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct EthInner<GEM: Gem> {
|
||||
gem: PhantomData<GEM>,
|
||||
|
|
|
@ -82,10 +82,6 @@ impl PhyRegister for Control {
|
|||
fn addr() -> u8 {
|
||||
0
|
||||
}
|
||||
|
||||
fn page() -> u8 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u16> for Control {
|
||||
|
|
|
@ -11,9 +11,6 @@ pub struct PhyIdentifier {
|
|||
}
|
||||
|
||||
pub fn identify_phy<PA: PhyAccess>(pa: &mut PA, addr: u8) -> Option<PhyIdentifier> {
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
pa.write_phy(addr, 0x16, 0); //reset page
|
||||
|
||||
let id1 = pa.read_phy(addr, 2);
|
||||
let id2 = pa.read_phy(addr, 3);
|
||||
if id1 != 0xFFFF || id2 != 0xFFFF {
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
use bit_field::BitField;
|
||||
use super::{PhyRegister, Led0Control, Led1Control};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
/// LED Control Register
|
||||
pub struct Leds(pub u16);
|
||||
|
||||
impl Leds {
|
||||
pub fn led0(&self) -> Led0Control {
|
||||
match self.0.get_bits(0..=3) {
|
||||
0b0000 => Led0Control::OnLinkOffNoLink,
|
||||
0b0001 => Led0Control::OnLinkBlinkActivityOffNoLink,
|
||||
0b0010 => Led0Control::BlinkDependingOnLink,
|
||||
0b0011 => Led0Control::OnActivityOffNoActivity,
|
||||
0b0100 => Led0Control::BlinkActivityOffNoActivity,
|
||||
0b0101 => Led0Control::OnTransmitOffNoTransmit,
|
||||
0b0110 => Led0Control::OnCopperLinkOffElse,
|
||||
0b0111 => Led0Control::On1000LinkOffElse,
|
||||
0b1000 => Led0Control::ForceOff,
|
||||
0b1001 => Led0Control::ForceOn,
|
||||
0b1010 => Led0Control::ForceHiZ,
|
||||
0b1011 => Led0Control::ForceBlink,
|
||||
0b1100 => Led0Control::Mode1,
|
||||
0b1101 => Led0Control::Mode2,
|
||||
0b1110 => Led0Control::Mode3,
|
||||
0b1111 => Led0Control::Mode4,
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn led1(&self) -> Led1Control {
|
||||
match self.0.get_bits(4..=7) {
|
||||
0b0000 => Led1Control::OnReceiveOffNoReceive,
|
||||
0b0001 => Led1Control::OnLinkBlinkActivityOffNoLink,
|
||||
0b0010 => Led1Control::OnLinkBlinkReceiveOffNoLink,
|
||||
0b0011 => Led1Control::OnActivityOffNoActivity,
|
||||
0b0100 => Led1Control::BlinkActivityOffNoActivity,
|
||||
0b0101 => Led1Control::On100OrFiberOffElse,
|
||||
0b0110 => Led1Control::On1001000LinkOffElse,
|
||||
0b0111 => Led1Control::On100LinkOffElse,
|
||||
0b1000 => Led1Control::ForceOff,
|
||||
0b1001 => Led1Control::ForceOn,
|
||||
0b1010 => Led1Control::ForceHiZ,
|
||||
0b1011 => Led1Control::ForceBlink,
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_led0(mut self, setting: Led0Control) -> Self {
|
||||
self.0.set_bits(0..=3, setting as u16);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_led1(mut self, setting: Led1Control) -> Self {
|
||||
self.0.set_bits(4..=7, setting as u16);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl PhyRegister for Leds {
|
||||
fn addr() -> u8 {
|
||||
0x10
|
||||
}
|
||||
|
||||
fn page() -> u8 {
|
||||
3
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u16> for Leds {
|
||||
fn from(value: u16) -> Self {
|
||||
Leds(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<u16> for Leds {
|
||||
fn into(self) -> u16 {
|
||||
self.0
|
||||
}
|
||||
}
|
|
@ -6,8 +6,6 @@ mod control;
|
|||
pub use control::Control;
|
||||
mod pssr;
|
||||
pub use pssr::PSSR;
|
||||
mod leds;
|
||||
pub use leds::Leds;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct Link {
|
||||
|
@ -28,42 +26,6 @@ pub enum LinkDuplex {
|
|||
Full,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Led0Control {
|
||||
OnLinkOffNoLink = 0b0000,
|
||||
OnLinkBlinkActivityOffNoLink = 0b0001,
|
||||
BlinkDependingOnLink = 0b0010,
|
||||
OnActivityOffNoActivity = 0b0011,
|
||||
BlinkActivityOffNoActivity = 0b0100,
|
||||
OnTransmitOffNoTransmit = 0b0101,
|
||||
OnCopperLinkOffElse = 0b0110,
|
||||
On1000LinkOffElse = 0b0111,
|
||||
ForceOff = 0b1000,
|
||||
ForceOn = 0b1001,
|
||||
ForceHiZ = 0b1010,
|
||||
ForceBlink = 0b1011,
|
||||
Mode1 = 0b1100,
|
||||
Mode2 = 0b1101,
|
||||
Mode3 = 0b1110,
|
||||
Mode4 = 0b1111
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Led1Control {
|
||||
OnReceiveOffNoReceive = 0b0000,
|
||||
OnLinkBlinkActivityOffNoLink = 0b0001,
|
||||
OnLinkBlinkReceiveOffNoLink = 0b0010,
|
||||
OnActivityOffNoActivity = 0b0011,
|
||||
BlinkActivityOffNoActivity = 0b0100,
|
||||
On100OrFiberOffElse = 0b0101,
|
||||
On1001000LinkOffElse = 0b0110,
|
||||
On100LinkOffElse = 0b0111,
|
||||
ForceOff = 0b1000,
|
||||
ForceOn = 0b1001,
|
||||
ForceHiZ = 0b1010,
|
||||
ForceBlink = 0b1011,
|
||||
}
|
||||
|
||||
pub trait PhyAccess {
|
||||
fn read_phy(&mut self, addr: u8, reg: u8) -> u16;
|
||||
fn write_phy(&mut self, addr: u8, reg: u8, data: u16);
|
||||
|
@ -71,7 +33,6 @@ pub trait PhyAccess {
|
|||
|
||||
pub trait PhyRegister {
|
||||
fn addr() -> u8;
|
||||
fn page() -> u8;
|
||||
}
|
||||
|
||||
|
||||
|
@ -84,10 +45,6 @@ const OUI_MARVELL: u32 = 0x005043;
|
|||
const OUI_REALTEK: u32 = 0x000732;
|
||||
const OUI_LANTIQ : u32 = 0x355969;
|
||||
|
||||
//only change pages on Kasli-SoC's Marvel 88E11xx
|
||||
#[cfg(feature="target_kasli_soc")]
|
||||
const PAGE_REGISTER: u8 = 0x16;
|
||||
|
||||
impl Phy {
|
||||
/// Probe all addresses on MDIO for a known PHY
|
||||
pub fn find<PA: PhyAccess>(pa: &mut PA) -> Option<Phy> {
|
||||
|
@ -127,9 +84,6 @@ impl Phy {
|
|||
PA: PhyAccess,
|
||||
PR: PhyRegister + From<u16>,
|
||||
{
|
||||
#[cfg(feature="target_kasli_soc")]
|
||||
pa.write_phy(self.addr, PAGE_REGISTER, PR::page().into());
|
||||
|
||||
pa.read_phy(self.addr, PR::addr()).into()
|
||||
}
|
||||
|
||||
|
@ -139,9 +93,6 @@ impl Phy {
|
|||
PR: PhyRegister + From<u16> + Into<u16>,
|
||||
F: FnMut(PR) -> PR,
|
||||
{
|
||||
#[cfg(feature="target_kasli_soc")]
|
||||
pa.write_phy(self.addr, PAGE_REGISTER, PR::page().into());
|
||||
|
||||
let reg = pa.read_phy(self.addr, PR::addr()).into();
|
||||
let reg = f(reg);
|
||||
pa.write_phy(self.addr, PR::addr(), reg.into())
|
||||
|
@ -155,14 +106,6 @@ impl Phy {
|
|||
self.modify_reg(pa, f)
|
||||
}
|
||||
|
||||
pub fn modify_leds<PA, F>(&self, pa: &mut PA, f: F)
|
||||
where
|
||||
PA: PhyAccess,
|
||||
F: FnMut(Leds) -> Leds,
|
||||
{
|
||||
self.modify_reg(pa, f)
|
||||
}
|
||||
|
||||
pub fn get_control<PA: PhyAccess>(&self, pa: &mut PA) -> Control {
|
||||
self.read_reg(pa)
|
||||
}
|
||||
|
@ -196,12 +139,4 @@ impl Phy {
|
|||
.set_restart_autoneg(true)
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature="target_kasli_soc")]
|
||||
pub fn set_leds<PA: PhyAccess>(&self, pa: &mut PA) {
|
||||
self.modify_leds(pa, |leds|
|
||||
leds.set_led0(Led0Control::OnCopperLinkOffElse)
|
||||
.set_led1(Led1Control::BlinkActivityOffNoActivity)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,10 +43,6 @@ impl PhyRegister for PSSR {
|
|||
fn addr() -> u8 {
|
||||
0x11
|
||||
}
|
||||
|
||||
fn page() -> u8 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u16> for PSSR {
|
||||
|
|
|
@ -100,10 +100,6 @@ impl PhyRegister for Status {
|
|||
fn addr() -> u8 {
|
||||
1
|
||||
}
|
||||
|
||||
fn page() -> u8 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u16> for Status {
|
||||
|
|
|
@ -110,49 +110,6 @@ pub struct RegisterBlock {
|
|||
pub design_cfg5: RO<u32>,
|
||||
}
|
||||
|
||||
pub struct GpioRegisterBlock {
|
||||
pub gpio_output_mask: &'static mut OutputMask,
|
||||
pub gpio_direction: &'static mut Direction,
|
||||
pub gpio_output_enable: &'static mut OutputEnable,
|
||||
}
|
||||
|
||||
impl GpioRegisterBlock {
|
||||
pub fn regs() -> Self {
|
||||
Self {
|
||||
gpio_output_mask: OutputMask::new(),
|
||||
gpio_direction: Direction::new(),
|
||||
gpio_output_enable: OutputEnable::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
register!(gpio_output_mask,
|
||||
/// MASK_DATA_1_SW:
|
||||
/// Maskable output data for MIO[47:32]
|
||||
OutputMask, RW, u32);
|
||||
register_at!(OutputMask, 0xE000A008, new);
|
||||
register_bit!(gpio_output_mask,
|
||||
/// Output for PHY_RST (MIO[47])
|
||||
phy_rst, 15);
|
||||
register_bits!(gpio_output_mask,
|
||||
mask, u16, 16, 31);
|
||||
register!(gpio_direction,
|
||||
/// DIRM_1:
|
||||
/// Direction mode for MIO[53:32]; 0/1 = in/out
|
||||
Direction, RW, u32);
|
||||
register_at!(Direction, 0xE000A244, new);
|
||||
register_bit!(gpio_direction,
|
||||
/// Direction for PHY_RST
|
||||
phy_rst, 15);
|
||||
register!(gpio_output_enable,
|
||||
/// OEN_1:
|
||||
/// Output enable for MIO[53:32]
|
||||
OutputEnable, RW, u32);
|
||||
register_at!(OutputEnable, 0xE000A248, new);
|
||||
register_bit!(gpio_output_enable,
|
||||
/// Output enable for PHY_RST
|
||||
phy_rst, 15);
|
||||
|
||||
register_at!(RegisterBlock, 0xE000B000, gem0);
|
||||
register_at!(RegisterBlock, 0xE000C000, gem1);
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ impl InterruptController {
|
|||
let m = (id.0 >> 2) as usize;
|
||||
let n = (8 * (id.0 & 3)) as usize;
|
||||
unsafe {
|
||||
self.mpcore.icdiptr[m].modify(|mut icdiptr| *icdiptr.set_bits(n..=n+1, target_cpu as u32));
|
||||
self.mpcore.icdiptr[m].modify(|mut icdiptr| *icdiptr.set_bits(n..=n+1, target_cpu as u32 + 1));
|
||||
}
|
||||
|
||||
// sensitivity
|
||||
|
|
|
@ -35,14 +35,16 @@ impl<'a> EEPROM<'a> {
|
|||
|
||||
#[cfg(feature = "target_zc706")]
|
||||
fn select(&mut self) -> Result<(), &'static str> {
|
||||
self.i2c.pca954x_select(0b1110100, Some(self.port))?;
|
||||
let mask: u16 = 1 << self.port;
|
||||
self.i2c.pca9548_select(0b1110100, mask as u8)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
fn select(&mut self) -> Result<(), &'static str> {
|
||||
let mask: u16 = 1 << self.port;
|
||||
// tca9548 is compatible with pca9548
|
||||
self.i2c.pca954x_select(0b1110001, Some(self.port))?;
|
||||
self.i2c.pca9548_select(0b1110001, mask as u8)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -6,19 +6,10 @@ use super::slcr;
|
|||
use super::time::Microseconds;
|
||||
use embedded_hal::timer::CountDown;
|
||||
use libregister::{RegisterR, RegisterRW, RegisterW};
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
use log::info;
|
||||
|
||||
pub enum I2cMultiplexer {
|
||||
PCA9548 = 0,
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
PCA9547 = 1,
|
||||
}
|
||||
|
||||
pub struct I2c {
|
||||
regs: regs::RegisterBlock,
|
||||
count_down: super::timer::global::CountDown<Microseconds>,
|
||||
pca_type: I2cMultiplexer
|
||||
count_down: super::timer::global::CountDown<Microseconds>
|
||||
}
|
||||
|
||||
impl I2c {
|
||||
|
@ -53,17 +44,18 @@ impl I2c {
|
|||
.pullup(false)
|
||||
.disable_rcvr(true)
|
||||
);
|
||||
// Reset
|
||||
slcr.gpio_rst_ctrl.reset_gpio();
|
||||
});
|
||||
|
||||
Self::i2c_common(0xFFFF - 0x000C, 0xFFFF - 0x0002)
|
||||
Self::i2c_common(0xFFFF - 0x000C)
|
||||
}
|
||||
|
||||
fn i2c_common(gpio_output_mask: u16, _gpio_output_mask_lower: u16) -> Self {
|
||||
fn i2c_common(gpio_output_mask: u16) -> Self {
|
||||
// Setup register block
|
||||
let self_ = Self {
|
||||
regs: regs::RegisterBlock::i2c(),
|
||||
count_down: unsafe { super::timer::GlobalTimer::get() }.countdown(),
|
||||
pca_type: I2cMultiplexer::PCA9548 //default for zc706
|
||||
count_down: unsafe { super::timer::GlobalTimer::get() }.countdown()
|
||||
};
|
||||
|
||||
// Setup GPIO output mask
|
||||
|
@ -75,17 +67,6 @@ impl I2c {
|
|||
w.scl(true).sda(true)
|
||||
});
|
||||
|
||||
//Kasli-SoC only: I2C_SW_RESET configuration
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
{
|
||||
self_.regs.gpio_output_mask_lower.modify(|_, w| {
|
||||
w.mask(_gpio_output_mask_lower)
|
||||
});
|
||||
self_.regs.gpio_direction.modify(|_, w| {
|
||||
w.i2cswr(true)
|
||||
});
|
||||
}
|
||||
|
||||
self_
|
||||
}
|
||||
|
||||
|
@ -129,48 +110,6 @@ impl I2c {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
fn i2cswr_oe(&mut self, oe: bool) {
|
||||
self.regs.gpio_output_enable.modify(|_, w| {
|
||||
w.i2cswr(oe)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
fn i2cswr_o(&mut self, o: bool) {
|
||||
self.regs.gpio_output_mask_lower.modify(|_, w| {
|
||||
w.i2cswr_o(o)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
fn pca_autodetect(&mut self) -> Result<I2cMultiplexer, &'static str> {
|
||||
// start with resetting the PCA954X
|
||||
// SDA must be clear (before start)
|
||||
// reset time is 500ns, unit_delay (100us) to account for propagation
|
||||
self.i2cswr_o(true);
|
||||
self.unit_delay();
|
||||
self.i2cswr_o(false);
|
||||
self.unit_delay();
|
||||
|
||||
let pca954x_read_addr = (0x71 << 1) | 0x01;
|
||||
|
||||
self.start()?;
|
||||
// read the config register
|
||||
if !self.write(pca954x_read_addr)? {
|
||||
return Err("PCA954X failed to ack read address");
|
||||
}
|
||||
let config = self.read(false)?;
|
||||
|
||||
let pca = match config {
|
||||
0x00 => { info!("PCA9548 detected"); I2cMultiplexer::PCA9548 },
|
||||
0x08 => { info!("PCA9547 detected"); I2cMultiplexer::PCA9547 },
|
||||
_ => { return Err("Unknown response for PCA954X autodetect")},
|
||||
};
|
||||
self.stop()?;
|
||||
Ok(pca)
|
||||
}
|
||||
|
||||
pub fn init(&mut self) -> Result<(), &'static str> {
|
||||
self.scl_oe(false);
|
||||
self.sda_oe(false);
|
||||
|
@ -197,13 +136,6 @@ impl I2c {
|
|||
return Err("SCL is stuck low");
|
||||
}
|
||||
// postcondition: SCL and SDA high
|
||||
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
{
|
||||
self.i2cswr_oe(true);
|
||||
self.pca_type = self.pca_autodetect()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -287,7 +219,7 @@ impl I2c {
|
|||
if self.sda_i() { data |= 1 << bit }
|
||||
self.scl_oe(true);
|
||||
}
|
||||
// Send ack/nack (true = nack, false = ack)
|
||||
// Send ack/nack
|
||||
self.sda_oe(ack);
|
||||
self.unit_delay();
|
||||
self.scl_oe(false);
|
||||
|
@ -299,32 +231,13 @@ impl I2c {
|
|||
Ok(data)
|
||||
}
|
||||
|
||||
pub fn pca954x_select(&mut self, address: u8, channel: Option<u8>) -> Result<(), &'static str> {
|
||||
pub fn pca9548_select(&mut self, address: u8, channels: u8) -> Result<(), &'static str> {
|
||||
self.start()?;
|
||||
// PCA9547 supports only one channel at a time
|
||||
// for compatibility, PCA9548 is treated as such too
|
||||
// channel - Some(x) - # of the channel [0,7], or None for all disabled
|
||||
let setting = match self.pca_type {
|
||||
I2cMultiplexer::PCA9548 => {
|
||||
match channel {
|
||||
Some(ch) => 1 << ch,
|
||||
None => 0,
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
I2cMultiplexer::PCA9547 => {
|
||||
match channel {
|
||||
Some(ch) => ch | 0x08,
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if !self.write(address << 1)? {
|
||||
return Err("PCA954X failed to ack write address")
|
||||
return Err("PCA9548 failed to ack write address")
|
||||
}
|
||||
if !self.write(setting)? {
|
||||
return Err("PCA954X failed to ack control word")
|
||||
if !self.write(channels)? {
|
||||
return Err("PCA9548 failed to ack control word")
|
||||
}
|
||||
self.stop()?;
|
||||
Ok(())
|
||||
|
|
|
@ -20,15 +20,13 @@ use libregister::{
|
|||
//
|
||||
// Current compatibility:
|
||||
// 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
|
||||
|
||||
pub struct RegisterBlock {
|
||||
pub gpio_output_mask: &'static mut GPIOOutputMask,
|
||||
pub gpio_input: &'static mut GPIOInput,
|
||||
pub gpio_direction: &'static mut GPIODirection,
|
||||
pub gpio_output_enable: &'static mut GPIOOutputEnable,
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
pub gpio_output_mask_lower: &'static mut GPIOOutputMaskLower,
|
||||
}
|
||||
|
||||
impl RegisterBlock {
|
||||
|
@ -37,9 +35,7 @@ impl RegisterBlock {
|
|||
gpio_output_mask: GPIOOutputMask::new(),
|
||||
gpio_input: GPIOInput::new(),
|
||||
gpio_direction: GPIODirection::new(),
|
||||
gpio_output_enable: GPIOOutputEnable::new(),
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
gpio_output_mask_lower: GPIOOutputMaskLower::new(),
|
||||
gpio_output_enable: GPIOOutputEnable::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,21 +59,6 @@ register_bits!(gpio_output_mask,
|
|||
/// Mask for keeping bits except SCL and SDA unchanged
|
||||
mask, u16, 16, 31);
|
||||
|
||||
|
||||
register!(gpio_output_mask_lower,
|
||||
/// MASK_DATA_1_LSW:
|
||||
/// Maskable output data for MIO[47:32]
|
||||
GPIOOutputMaskLower, RW, u32);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_at!(GPIOOutputMaskLower, 0xE000A008, new);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_bit!(gpio_output_mask_lower,
|
||||
/// Output for I2C_SW_RESET (MIO[33])
|
||||
i2cswr_o, 1);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_bits!(gpio_output_mask_lower,
|
||||
mask, u16, 16, 31);
|
||||
|
||||
register!(gpio_input,
|
||||
/// DATA_1_RO:
|
||||
/// Input data for MIO[53:32]
|
||||
|
@ -93,7 +74,6 @@ register_bit!(gpio_input,
|
|||
/// Input for SDA
|
||||
sda, 19);
|
||||
|
||||
|
||||
register!(gpio_direction,
|
||||
/// DIRM_1:
|
||||
/// Direction mode for MIO[53:32]; 0/1 = in/out
|
||||
|
@ -108,10 +88,6 @@ register_bit!(gpio_direction,
|
|||
register_bit!(gpio_direction,
|
||||
/// Direction for SDA
|
||||
sda, 19);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_bit!(gpio_direction,
|
||||
/// Direction for I2C_SW_RESET
|
||||
i2cswr, 1);
|
||||
|
||||
register!(gpio_output_enable,
|
||||
/// OEN_1:
|
||||
|
@ -127,8 +103,3 @@ register_bit!(gpio_output_enable,
|
|||
register_bit!(gpio_output_enable,
|
||||
/// Output enable for SDA
|
||||
sda, 19);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
register_bit!(gpio_output_enable,
|
||||
/// Output enable for I2C_SW_RESET
|
||||
i2cswr, 1);
|
||||
|
|
@ -23,5 +23,3 @@ pub mod sdio;
|
|||
pub mod i2c;
|
||||
pub mod logger;
|
||||
pub mod ps7_init;
|
||||
#[cfg(feature="target_kasli_soc")]
|
||||
pub mod error_led;
|
||||
|
|
|
@ -587,17 +587,6 @@ register_bit!(a9_cpu_rst_ctrl, a9_clkstop0, 4);
|
|||
register_bit!(a9_cpu_rst_ctrl, a9_rst1, 1);
|
||||
register_bit!(a9_cpu_rst_ctrl, a9_rst0, 0);
|
||||
|
||||
pub fn reboot() {
|
||||
RegisterBlock::unlocked(|slcr| {
|
||||
unsafe {
|
||||
let reboot = slcr.reboot_status.read();
|
||||
slcr.reboot_status.write(reboot & 0xF0FFFFFF);
|
||||
slcr.pss_rst_ctrl.modify(|_, w| w.soft_rst(true));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum BootModePins {
|
||||
|
@ -616,7 +605,7 @@ register_bit!(boot_mode, jtag_routing, 3);
|
|||
register_bits_typed!(boot_mode, boot_mode_pins, u8, BootModePins, 0, 2);
|
||||
|
||||
register!(pss_rst_ctrl, PssRstCtrl, RW, u32);
|
||||
register_bit!(pss_rst_ctrl, soft_rst, 0);
|
||||
register_bit!(pss_rst_ctrl, soft_rst, 1);
|
||||
|
||||
/// Used for MioPin*.io_type
|
||||
#[repr(u8)]
|
||||
|
|
|
@ -16,4 +16,3 @@ target_coraz7 = []
|
|||
target_redpitaya = []
|
||||
target_kasli_soc = []
|
||||
ipv6 = []
|
||||
fat_lfn = [ "fatfs/alloc" ]
|
|
@ -164,8 +164,7 @@ impl Config {
|
|||
f.seek(SeekFrom::End(0))?;
|
||||
write!(f, "{}={}\n", key, String::from_utf8(value).unwrap())?;
|
||||
} else {
|
||||
let dir = root_dir.create_dir("/CONFIG")?;
|
||||
let mut f = dir.create_file(&[key, ".BIN"].concat())?;
|
||||
let mut f = root_dir.create_file(&["/CONFIG/", key, ".BIN"].concat())?;
|
||||
f.write_all(&value)?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,19 +30,7 @@ impl fmt::Display for NetAddresses {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
fn get_address_from_eeprom() -> EthernetAddress {
|
||||
use libboard_zynq::i2c::{I2c, eeprom};
|
||||
|
||||
let mut i2c = I2c::i2c0();
|
||||
i2c.init().unwrap();
|
||||
let mut eeprom = eeprom::EEPROM::new(&mut i2c, 16);
|
||||
let address = eeprom.read_eui48().unwrap_or([0x02, 0x00, 0x00, 0x00, 0x00, 0x56]);
|
||||
|
||||
EthernetAddress(address)
|
||||
}
|
||||
|
||||
pub fn get_addresses(cfg: &Config) -> NetAddresses {
|
||||
pub fn get_adresses(cfg: &Config) -> NetAddresses {
|
||||
#[cfg(feature = "target_zc706")]
|
||||
let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x52]);
|
||||
#[cfg(feature = "target_zc706")]
|
||||
|
@ -56,7 +44,7 @@ pub fn get_addresses(cfg: &Config) -> NetAddresses {
|
|||
#[cfg(feature = "target_redpitaya")]
|
||||
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 55);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
let mut hardware_addr = get_address_from_eeprom();
|
||||
let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x56]);
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 56);
|
||||
|
||||
|
|
|
@ -34,12 +34,6 @@ pub fn isb() {
|
|||
unsafe { llvm_asm!("isb" :::: "volatile") }
|
||||
}
|
||||
|
||||
/// Enable FIQ
|
||||
#[inline]
|
||||
pub unsafe fn enable_fiq() {
|
||||
llvm_asm!("cpsie f":::: "volatile");
|
||||
}
|
||||
|
||||
/// Enable IRQ
|
||||
#[inline]
|
||||
pub unsafe fn enable_irq() {
|
||||
|
|
|
@ -36,9 +36,7 @@ pub fn notify_spin_lock() {
|
|||
}
|
||||
|
||||
#[macro_export]
|
||||
/// Interrupt handler, which setup the stack and preserve registers before jumping to actual interrupt handler.
|
||||
/// Registers r0-r12, PC, SP and CPSR are restored after the actual handler.
|
||||
///
|
||||
/// Interrupt handler, which setup the stack and jump to actual interrupt handler.
|
||||
/// - `name` is the name of the interrupt, should be the same as the one defined in vector table.
|
||||
/// - `name2` is the name for the actual handler, should be different from name.
|
||||
/// - `stack0` is the stack for the interrupt handler when called from core0.
|
||||
|
@ -46,7 +44,8 @@ pub fn notify_spin_lock() {
|
|||
/// - `body` is the body of the actual interrupt handler, should be a normal unsafe rust function
|
||||
/// body.
|
||||
///
|
||||
/// Note that the interrupt handler would use the same stack as normal programs by default.
|
||||
/// Note that the interrupt handler would use the same stack as normal programs by default, so
|
||||
/// interrupt handlers should not return to normal program or it may corrupt the stack.
|
||||
macro_rules! interrupt_handler {
|
||||
($name:ident, $name2:ident, $stack0:ident, $stack1:ident, $body:block) => {
|
||||
#[link_section = ".text.boot"]
|
||||
|
@ -55,27 +54,19 @@ macro_rules! interrupt_handler {
|
|||
pub unsafe extern "C" fn $name() -> ! {
|
||||
asm!(
|
||||
// setup SP, depending on CPU 0 or 1
|
||||
// and preserve registers
|
||||
"sub lr, lr, #4",
|
||||
"stmfd sp!, {{r0-r12, lr}}",
|
||||
"mrc p15, #0, r0, c0, c0, #5",
|
||||
concat!("movw r1, :lower16:", stringify!($stack0)),
|
||||
concat!("movt r1, :upper16:", stringify!($stack0)),
|
||||
"tst r0, #3",
|
||||
concat!("movwne r1, :lower16:", stringify!($stack1)),
|
||||
concat!("movtne r1, :upper16:", stringify!($stack1)),
|
||||
"mov r0, sp",
|
||||
"mov sp, r1",
|
||||
"push {{r0, r1}}", // 2 registers are pushed to maintain 8 byte stack alignment
|
||||
concat!("bl ", stringify!($name2)),
|
||||
"pop {{r0, r1}}",
|
||||
"mov sp, r0",
|
||||
"ldmfd sp!, {{r0-r12, pc}}^", // caret ^ : copy SPSR to the CPSR
|
||||
options(noreturn)
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn $name2() $body
|
||||
pub unsafe extern "C" fn $name2() -> ! $body
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use core::ops::{Deref, DerefMut};
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
use core::cell::UnsafeCell;
|
||||
use core::task::{Context, Poll};
|
||||
use core::pin::Pin;
|
||||
use core::future::Future;
|
||||
use super::{
|
||||
spin_lock_yield, notify_spin_lock,
|
||||
asm::{enter_critical, exit_critical}
|
||||
|
@ -23,23 +20,6 @@ pub struct Mutex<T> {
|
|||
unsafe impl<T: Send> Sync for Mutex<T> {}
|
||||
unsafe impl<T: Send> Send for Mutex<T> {}
|
||||
|
||||
struct Fut<'a, T>(&'a Mutex<T>);
|
||||
|
||||
impl<'a, T> Future for Fut<'a, T> {
|
||||
type Output = MutexGuard<'a, T>;
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let irq = unsafe { enter_critical() };
|
||||
if self.0.locked.compare_exchange_weak(UNLOCKED, LOCKED, Ordering::AcqRel, Ordering::Relaxed).is_err() {
|
||||
unsafe { exit_critical(irq) };
|
||||
cx.waker().wake_by_ref();
|
||||
Poll::Pending
|
||||
}
|
||||
else {
|
||||
Poll::Ready(MutexGuard { mutex: self.0, irq })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Mutex<T> {
|
||||
/// Constructor, const-fn
|
||||
pub const fn new(inner: T) -> Self {
|
||||
|
@ -62,10 +42,6 @@ impl<T> Mutex<T> {
|
|||
MutexGuard { mutex: self, irq }
|
||||
}
|
||||
|
||||
pub async fn async_lock(&self) -> MutexGuard<'_, T> {
|
||||
Fut(&self).await
|
||||
}
|
||||
|
||||
pub fn try_lock(&self) -> Option<MutexGuard<T>> {
|
||||
let irq = unsafe { enter_critical() };
|
||||
if self.locked.compare_exchange_weak(UNLOCKED, LOCKED, Ordering::AcqRel, Ordering::Relaxed).is_err() {
|
||||
|
|
|
@ -12,10 +12,9 @@ target_redpitaya = ["libboard_zynq/target_redpitaya"]
|
|||
target_kasli_soc = ["libboard_zynq/target_kasli_soc"]
|
||||
panic_handler = []
|
||||
dummy_irq_handler = []
|
||||
dummy_fiq_handler = []
|
||||
alloc_core = []
|
||||
|
||||
default = ["panic_handler", "dummy_irq_handler", "dummy_fiq_handler"]
|
||||
default = ["panic_handler", "dummy_irq_handler"]
|
||||
|
||||
[dependencies]
|
||||
r0 = "1"
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use libregister::{RegisterR, RegisterW};
|
||||
use libcortex_a9::{regs::{DFSR, MPIDR, VBAR}, interrupt_handler};
|
||||
use libregister::RegisterR;
|
||||
use libcortex_a9::{regs::{DFSR, MPIDR}, interrupt_handler};
|
||||
use libboard_zynq::{println, stdio};
|
||||
|
||||
pub fn set_vector_table(base_addr: u32){
|
||||
VBAR.write(base_addr);
|
||||
}
|
||||
|
||||
interrupt_handler!(UndefinedInstruction, undefined_instruction, __irq_stack0_start, __irq_stack1_start, {
|
||||
stdio::drop_uart();
|
||||
println!("UndefinedInstruction");
|
||||
|
@ -46,7 +42,6 @@ interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, {
|
|||
loop {}
|
||||
});
|
||||
|
||||
#[cfg(feature = "dummy_fiq_handler")]
|
||||
interrupt_handler!(FIQ, fiq, __irq_stack0_start, __irq_stack1_start, {
|
||||
stdio::drop_uart();
|
||||
println!("FIQ");
|
|
@ -54,7 +54,6 @@ unsafe extern "C" fn boot_core0() -> ! {
|
|||
asm::dmb();
|
||||
asm::dsb();
|
||||
|
||||
asm::enable_fiq();
|
||||
asm::enable_irq();
|
||||
main_core0();
|
||||
panic!("return from main");
|
||||
|
@ -76,7 +75,6 @@ unsafe extern "C" fn boot_core1() -> ! {
|
|||
asm::dmb();
|
||||
asm::dsb();
|
||||
|
||||
asm::enable_fiq();
|
||||
asm::enable_irq();
|
||||
main_core1();
|
||||
panic!("return from main_core1");
|
||||
|
|
|
@ -9,7 +9,7 @@ pub extern crate alloc;
|
|||
pub extern crate compiler_builtins;
|
||||
|
||||
pub mod boot;
|
||||
pub mod exception_vectors;
|
||||
mod abort;
|
||||
#[cfg(feature = "panic_handler")]
|
||||
mod panic;
|
||||
pub mod ram;
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use libboard_zynq::{print, println};
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
use libboard_zynq::error_led::ErrorLED;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||
|
@ -15,10 +13,6 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
|
|||
} else {
|
||||
println!("");
|
||||
}
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
{
|
||||
let mut err_led = ErrorLED::error_led();
|
||||
err_led.toggle(true);
|
||||
}
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
set XC7_JSHUTDOWN 0x0d
|
||||
set XC7_JPROGRAM 0x0b
|
||||
set XC7_JSTART 0x0c
|
||||
set XC7_BYPASS 0x3f
|
||||
|
||||
proc xc7_program {tap} {
|
||||
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
||||
irscan $tap $XC7_JSHUTDOWN
|
||||
irscan $tap $XC7_JPROGRAM
|
||||
runtest 60000
|
||||
#JSTART prevents this from working...
|
||||
#irscan $tap $XC7_JSTART
|
||||
runtest 2000
|
||||
irscan $tap $XC7_BYPASS
|
||||
runtest 2000
|
||||
}
|
||||
|
||||
pld device virtex2 zynq.tap 1
|
||||
init
|
||||
xc7_program zynq.tap
|
|
@ -8,7 +8,26 @@ source ./zynq-7000.cfg
|
|||
|
||||
reset_config srst_only srst_push_pull
|
||||
|
||||
source ./common.cfg
|
||||
set XC7_JSHUTDOWN 0x0d
|
||||
set XC7_JPROGRAM 0x0b
|
||||
set XC7_JSTART 0x0c
|
||||
set XC7_BYPASS 0x3f
|
||||
|
||||
proc xc7_program {tap} {
|
||||
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
||||
irscan $tap $XC7_JSHUTDOWN
|
||||
irscan $tap $XC7_JPROGRAM
|
||||
runtest 60000
|
||||
#JSTART prevents this from working...
|
||||
#irscan $tap $XC7_JSTART
|
||||
runtest 2000
|
||||
irscan $tap $XC7_BYPASS
|
||||
runtest 2000
|
||||
}
|
||||
|
||||
pld device virtex2 zynq.tap 1
|
||||
init
|
||||
xc7_program zynq.tap
|
||||
|
||||
reset halt
|
||||
|
||||
|
|
|
@ -17,7 +17,26 @@ reset_config srst_only srst_open_drain
|
|||
adapter srst pulse_width 250
|
||||
adapter srst delay 400
|
||||
|
||||
source ./common.cfg
|
||||
set XC7_JSHUTDOWN 0x0d
|
||||
set XC7_JPROGRAM 0x0b
|
||||
set XC7_JSTART 0x0c
|
||||
set XC7_BYPASS 0x3f
|
||||
|
||||
proc xc7_program {tap} {
|
||||
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
||||
irscan $tap $XC7_JSHUTDOWN
|
||||
irscan $tap $XC7_JPROGRAM
|
||||
runtest 60000
|
||||
#JSTART prevents this from working...
|
||||
#irscan $tap $XC7_JSTART
|
||||
runtest 2000
|
||||
irscan $tap $XC7_BYPASS
|
||||
runtest 2000
|
||||
}
|
||||
|
||||
pld device virtex2 zynq.tap 1
|
||||
init
|
||||
xc7_program zynq.tap
|
||||
|
||||
reset halt
|
||||
|
||||
|
|
|
@ -8,7 +8,26 @@ source ./zynq-7000.cfg
|
|||
|
||||
reset_config none
|
||||
|
||||
source ./common.cfg
|
||||
set XC7_JSHUTDOWN 0x0d
|
||||
set XC7_JPROGRAM 0x0b
|
||||
set XC7_JSTART 0x0c
|
||||
set XC7_BYPASS 0x3f
|
||||
|
||||
proc xc7_program {tap} {
|
||||
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
||||
irscan $tap $XC7_JSHUTDOWN
|
||||
irscan $tap $XC7_JPROGRAM
|
||||
runtest 60000
|
||||
#JSTART prevents this from working...
|
||||
#irscan $tap $XC7_JSTART
|
||||
runtest 2000
|
||||
irscan $tap $XC7_BYPASS
|
||||
runtest 2000
|
||||
}
|
||||
|
||||
pld device virtex2 zynq.tap 1
|
||||
init
|
||||
xc7_program zynq.tap
|
||||
|
||||
halt
|
||||
|
||||
|
|
|
@ -10,7 +10,26 @@ reset_config srst_only srst_open_drain
|
|||
adapter srst pulse_width 250
|
||||
adapter srst delay 400
|
||||
|
||||
source ./common.cfg
|
||||
set XC7_JSHUTDOWN 0x0d
|
||||
set XC7_JPROGRAM 0x0b
|
||||
set XC7_JSTART 0x0c
|
||||
set XC7_BYPASS 0x3f
|
||||
|
||||
proc xc7_program {tap} {
|
||||
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
||||
irscan $tap $XC7_JSHUTDOWN
|
||||
irscan $tap $XC7_JPROGRAM
|
||||
runtest 60000
|
||||
#JSTART prevents this from working...
|
||||
#irscan $tap $XC7_JSTART
|
||||
runtest 2000
|
||||
irscan $tap $XC7_BYPASS
|
||||
runtest 2000
|
||||
}
|
||||
|
||||
pld device virtex2 zynq.tap 1
|
||||
init
|
||||
xc7_program zynq.tap
|
||||
|
||||
reset halt
|
||||
|
||||
|
|
|
@ -75,17 +75,13 @@ pub fn main_core0() {
|
|||
___/ / / /__/ /___
|
||||
/____/ /____/_____/
|
||||
|
||||
(C) 2020-2022 M-Labs
|
||||
(C) 2020-2021 M-Labs
|
||||
"#
|
||||
);
|
||||
info!("Simple Zynq Loader starting...");
|
||||
|
||||
#[cfg(not(feature = "target_kasli_soc"))]
|
||||
const CPU_FREQ: u32 = 800_000_000;
|
||||
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
const CPU_FREQ: u32 = 1_000_000_000;
|
||||
|
||||
ArmPll::setup(2 * CPU_FREQ);
|
||||
Clocks::set_cpu_freq(CPU_FREQ);
|
||||
IoPll::setup(1_000_000_000);
|
||||
|
@ -140,14 +136,7 @@ pub fn main_core0() {
|
|||
}
|
||||
}
|
||||
v => {
|
||||
log::error!("Boot mode {:?} not supported", v);
|
||||
log::info!("Fall back on netboot");
|
||||
netboot::netboot(
|
||||
&mut bootgen_file,
|
||||
config,
|
||||
&mut __runtime_start as *mut usize as *mut u8,
|
||||
max_len,
|
||||
)
|
||||
panic!("Boot mode {:?} not supported", v);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -316,7 +316,7 @@ pub fn netboot<File: Read + Seek>(
|
|||
runtime_max_len: usize,
|
||||
) {
|
||||
log::info!("Preparing network for netboot");
|
||||
let net_addresses = net_settings::get_addresses(&cfg);
|
||||
let net_addresses = net_settings::get_adresses(&cfg);
|
||||
log::info!("Network addresses: {}", net_addresses);
|
||||
let eth = Eth::eth0(net_addresses.hardware_addr.0.clone());
|
||||
let eth = eth.start_rx(8);
|
||||
|
|
Loading…
Reference in New Issue