Compare commits

...

50 Commits

Author SHA1 Message Date
Sebastien Bourdeauducq 731684abb4 flake: switch to nixpkgs master, update dependencies 2024-05-09 10:02:43 +08:00
Florian Agbuya 195a21fe78 use nix format for arm gnu toolchain 2024-03-25 17:20:19 +08:00
Florian Agbuya 96cefe6f06 update fsbl source 2024-03-25 17:16:56 +08:00
morgan 7c58c0cf43 abort: rename to exception_vectors 2024-03-07 12:26:28 +08:00
morgan 9005b73316 experiment: add set_vector_table example 2024-03-07 12:03:49 +08:00
morgan b1994dbe16 abort: support custom exception vector table addr 2024-03-07 12:03:29 +08:00
morgan 5bd336c961 add support for using custom FIQ handler
cfg: add dummy FIQ handler cfg
abort: gate dummy FIQ handler using cfg
2024-02-02 17:01:07 +08:00
morgan 298f64a2f9 boot: enable FIQ
asm: add FIQ enable instruction
2024-02-02 16:34:28 +08:00
morgan 4168eb63a7 GIC: fix wrong core target config when enabling interrupt (#109)
# Summary

- Before the patch, an extra 1 is added to `target_cpu` and the interrupt will be configured to the wrong CPU target.

| target_cpu | bits set before patch | bits set after patch   |
| -----------| -----------                      | -----------                       |
| core0      | 0b10 (enable interrupt on core1) | 0b01 (enable interrupt on core0)  |
| core1      | 0b11 (enable interrupt on core0 & core1)| 0b10 (enable interrupt on core1) |

- [Correct ICDIPTR Register configuration from AMD](https://docs.xilinx.com/r/en-US/ug585-zynq-7000-SoC-TRM/Software-Generated-Interrupts-SGI?tocId=0TsxAmy8MHRPDsayG96K1Q)

Reviewed-on: M-Labs/zynq-rs#109
Co-authored-by: morgan <mc@m-labs.hk>
Co-committed-by: morgan <mc@m-labs.hk>
2023-12-19 18:41:03 +08:00
Sebastien Bourdeauducq a43b8bf64e mkbootimage: work around buffer overflow 2023-12-03 16:16:22 +08:00
Sebastien Bourdeauducq 91bae572f9 fix "unknown argument '-Wl,--undefined=AUDITABLE_VERSION_INFO'" 2023-12-03 11:09:31 +08:00
Sebastien Bourdeauducq 301f9236e5 switch to nixpkgs cargo-xbuild (with workaround for rust nonsense) 2023-12-03 10:55:05 +08:00
Sebastien Bourdeauducq 55b36ee37e switch to new nixpkgs release 2023-12-03 10:45:47 +08:00
morgan 24c804e6f0 libcortex_a9: add interrupt exit support for interrupt_handler macro (#107)
Co-authored-by: morgan <mc@m-labs.hk>
Co-committed-by: morgan <mc@m-labs.hk>
2023-11-20 12:30:27 +08:00
Sebastien Bourdeauducq be672ab662 flake: update dependencies 2023-10-20 17:46:01 +08:00
mwojcik 0106430805 remove gpio reset 2023-10-18 17:33:19 +08:00
jmatyas c15b54f92b kasli-soc: add support for PHY_RST GPIO 2023-08-31 12:58:59 +02:00
Sebastien Bourdeauducq de42a5d1b2 flake: update to LLVM 14 2023-08-07 23:26:58 +08:00
Sebastien Bourdeauducq ff03bf92a3 flake: update dependencies 2023-08-07 23:23:02 +08:00
Sebastien Bourdeauducq f20c008264 flake: nixpkgs 23.05 2023-05-27 18:20:53 +08:00
Sebastien Bourdeauducq 67dbb5932f flake: update mkbootimage 2022-11-30 22:36:56 +08:00
Sebastien Bourdeauducq dab5c6f070 flake: NixOS 22.11, update dependencies 2022-11-30 22:29:58 +08:00
Egor Savkin 0a3a777652 Fix soft_rst bit, add reboot function 2022-10-07 12:57:56 +08:00
mwojcik 92b3f3e1dd panic: turn on error_led for kasli_soc 2022-08-26 17:22:42 +08:00
mwojcik f586ba5a13 experiments: add error led test for kasli_soc 2022-08-26 17:22:42 +08:00
mwojcik 42cc256812 add error led 2022-08-26 17:22:42 +08:00
occheung 043a152b91 szl: change CPU frequency of Kasli-SoC to 1 GHz 2022-07-20 15:16:15 +08:00
Sebastien Bourdeauducq 6cd32f6ee0 flake: update dependencies 2022-05-31 21:02:28 +08:00
mwojcik 605c8f73a6 mutex: add async version of lock 2022-05-25 10:22:16 +08:00
mwojcik 56c27e98e4 config: add "fat_lfn" feature 2022-04-07 15:44:07 +08:00
mwojcik f496da4f3e config: create config dir if not present 2022-04-06 16:17:35 +08:00
mwojcik 1c8e2c318c eth phy: reset page to 0 on kasli-soc for ident 2022-03-10 17:11:41 +08:00
mwojcik 67880b4e0b openocd: moved common code from target files 2022-03-10 17:05:25 +08:00
Sebastien Bourdeauducq e96222ff6f update dependencies 2022-03-10 17:01:37 +08:00
mwojcik dc1ca3d3d0 szl: fallback to netboot if boot mode not supported 2022-03-10 16:48:00 +08:00
mwojcik c4c52c33b4 eth phy: use unreachable!() for impossible values 2022-03-10 16:45:29 +08:00
mwojcik 072fd5f015 eth phy: set LEDs only on Kasli-SoC 2022-03-10 16:42:25 +08:00
mwojcik 2b3c7e4b2f eth leds:
* break led0 from led1 - similar, but not the same settings (led2 not implemented)
* fix values, make it compilable
* set default behavior (one led for link, other for activity)
2022-03-10 16:42:25 +08:00
mwojcik 84d6d391ce libboard_zynq: eth phy for Marvell 88E1518
* add support for LED control registers
* support for registers on different pages
2022-03-10 16:42:25 +08:00
mwojcik 43e0440911 Kasli-SoC: Get MAC address from EEPROM (#90)
Co-authored-by: mwojcik <mw@m-labs.hk>
Co-committed-by: mwojcik <mw@m-labs.hk>
2022-03-07 18:01:44 +08:00
mwojcik 3e95df1f64 pca954x_select: api supports no channel enabled 2022-02-11 13:46:51 +08:00
mwojcik 26ab2927b9 pca954x: log detected type 2022-02-11 12:00:39 +08:00
mwojcik dacc816eb4 pca954x: improve code, fix I2C_SW_RESET behavior 2022-02-11 11:22:53 +08:00
mwojcik fbc783d7ad flake: add pyftdi to env 2022-02-11 11:19:15 +08:00
mwojcik 14b0247716 pca954x: fix to work on cold boot 2022-02-09 17:23:33 +08:00
mwojcik bc41b91192 adjust pca address 2022-02-08 16:39:12 +08:00
mwojcik 3efc682bd6 add pca954x autodetection, pca9547 support 2022-02-08 15:40:17 +08:00
mwojcik e5e646f40e Additional outputs to flakes (#86)
Co-authored-by: mwojcik <mw@m-labs.hk>
Co-committed-by: mwojcik <mw@m-labs.hk>
2022-02-04 18:42:35 +08:00
Sebastien Bourdeauducq 2e7cfe04c8 update copyright year 2022-01-27 18:00:24 +08:00
mwojcik 24e0d724f2 nix flakes support (#85)
Reviewed-on: M-Labs/zynq-rs#85
Co-authored-by: mwojcik <mw@m-labs.hk>
Co-committed-by: mwojcik <mw@m-labs.hk>
2022-01-27 16:26:33 +08:00
51 changed files with 943 additions and 22740 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target
result*

16
Cargo.lock generated
View File

@ -8,9 +8,9 @@ checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
[[package]]
name = "bitflags"
version = "1.2.1"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "byteorder"
@ -20,9 +20,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.69"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
@ -47,9 +47,9 @@ dependencies = [
[[package]]
name = "embedded-hal"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e36cfb62ff156596c892272f3015ef952fe1525e85261fa3a7f327bd6b384ab9"
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
dependencies = [
"nb 0.1.3",
"void",
@ -250,9 +250,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "volatile-register"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
dependencies = [
"vcell",
]

View File

@ -14,7 +14,7 @@ members = [
panic = "abort"
debug = true
codegen-units = 1
opt-level = 'z'
opt-level = 's'
lto = true
debug-assertions = false
overflow-checks = false

View File

@ -20,18 +20,30 @@ Supported boards:
## Build
Zynq-rs is packaged using the [Nix](https://nixos.org) Flakes system. Install Nix 2.4+ and enable flakes by adding ``experimental-features = nix-command flakes`` to ``nix.conf`` (e.g. ``~/.config/nix/nix.conf``).
You can build SZL or experiments crate for the platform of your choice by using ``nix build`` command, e.g.
```shell
nix-shell --command "cargo xbuild --release -p experiments"
nix build .#coraz7-experiments
```
Currently the ELF output is placed at `target/armv7-none-eabihf/release/experiments`
Alternatively, you can still use ``cargo xbuild`` within ``nix develop`` shell.
```shell
nix develop
cargo xbuild --release -p experiments
```
Currently the ELF output is placed at `target/armv7-none-eabihf/release/experiments`, or `result/experiments.elf` for Nix Flakes build.
## Debug
### Running on the ZC706
```shell
nix-shell --command "cargo xbuild --release -p experiments"
nix develop
cargo xbuild --release -p experiments
cd openocd
openocd -f zc706.cfg
```
@ -39,7 +51,8 @@ openocd -f zc706.cfg
### Running on the Cora Z7-10
```shell
nix-shell --command "cd experiments && cargo xbuild --release --no-default-features --features=target_coraz7"
nix develop
cargo xbuild --release -p experiments --no-default-features --features=target_coraz7
cd openocd
openocd -f cora-z7-10.cfg
```
@ -52,5 +65,5 @@ openocd -f zc706.cfg -c "pld load 0 blinker_migen.bit; exit"
## License
Copyright (C) 2019-2021 M-Labs Limited.
Copyright (C) 2019-2022 M-Labs Limited.
Released under the GNU LGPL v3. See the LICENSE file for details.

View File

@ -1,55 +0,0 @@
let
pkgs = import <nixpkgs> { overlays = [ (import ./nix/mozilla-overlay.nix) ]; };
rustPlatform = (import ./nix/rust-platform.nix { inherit pkgs; });
cargo-xbuild = pkgs.callPackage ./nix/cargo-xbuild.nix {};
cargoSha256Experiments = "1bvffgr4588bbkjwnhim8rvkjvbnajaiv7hc98b19sr8kb7rcj63";
cargoSha256SZL = "13022ssk6s2fgxmmh5msbx01fzcmk2cj95fjpxcsmfy14k9wd77l";
build-crate = name: crate: features: cargoSha256:
rustPlatform.buildRustPackage rec {
name = "${crate}";
src = builtins.filterSource (path: type:
baseNameOf path != "target"
) ./.;
inherit cargoSha256;
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_9.clang-unwrapped ];
buildPhase = ''
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 \
--no-default-features \
--features=${features}
popd
'';
installPhase = ''
mkdir -p $out $out/nix-support
cp target/armv7-none-eabihf/release/${name} $out/${name}.elf
echo file binary-dist $out/${name}.elf >> $out/nix-support/hydra-build-products
'';
doCheck = false;
dontFixup = true;
};
targetCrates = target: {
"${target}-experiments" = build-crate "${target}-experiments" "experiments" "target_${target}" cargoSha256Experiments;
"${target}-szl" = build-crate "${target}-szl" "szl" "target_${target}" cargoSha256SZL;
};
targets = ["zc706" "coraz7" "redpitaya" "kasli_soc"];
allTargetCrates = (builtins.foldl' (results: target:
results // targetCrates target
) {} targets);
in
{
inherit cargo-xbuild;
zc706-fsbl = import ./nix/fsbl.nix { inherit pkgs; };
szl = pkgs.runCommand "szl" {} (builtins.foldl' (commands: target:
let
szlResult = builtins.getAttr "${target}-szl" allTargetCrates;
in
commands + "ln -s ${szlResult}/szl.elf $out/szl-${target}.elf\n"
) "mkdir $out\n" targets);
} // allTargetCrates

View File

@ -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"]}
libsupport_zynq = { path = "../libsupport_zynq", default-features = false, features = ["panic_handler", "dummy_fiq_handler"]}
libasync = { path = "../libasync" }

View File

@ -39,7 +39,7 @@ use libcortex_a9::{
};
use libregister::{RegisterR, RegisterW};
use libsupport_zynq::{
boot, ram,
boot, exception_vectors, ram,
};
use log::{info, warn};
use core::sync::atomic::{AtomicBool, Ordering};
@ -56,19 +56,29 @@ extern "C" {
static CORE1_RESTART: AtomicBool = AtomicBool::new(false);
interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, {
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();
}
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();
}
},
_ => {}
}
stdio::drop_uart();
println!("IRQ");
@ -86,6 +96,7 @@ 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");
@ -134,6 +145,10 @@ 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 };
@ -183,6 +198,20 @@ 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");

44
flake.lock Normal file
View File

@ -0,0 +1,44 @@
{
"nodes": {
"mozilla-overlay": {
"flake": false,
"locked": {
"lastModified": 1704373101,
"narHash": "sha256-+gi59LRWRQmwROrmE1E2b3mtocwueCQqZ60CwLG+gbg=",
"owner": "mozilla",
"repo": "nixpkgs-mozilla",
"rev": "9b11a87c0cc54e308fa83aac5b4ee1816d5418a2",
"type": "github"
},
"original": {
"owner": "mozilla",
"repo": "nixpkgs-mozilla",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1715087517,
"narHash": "sha256-CLU5Tsg24Ke4+7sH8azHWXKd0CFd4mhLWfhYgUiDBpQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b211b392b8486ee79df6cdfb1157ad2133427a29",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"mozilla-overlay": "mozilla-overlay",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

172
flake.nix Normal file
View File

@ -0,0 +1,172 @@
{
description = "Bare-metal Rust on Zynq-7000";
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable;
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 ]; };
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;
rustPlatform = pkgs.recurseIntoAttrs (pkgs.makeRustPlatform {
rustc = rust;
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";
};
};
};
});
mkbootimage = pkgs.stdenv.mkDerivation {
pname = "mkbootimage";
version = "2.3dev";
src = pkgs.fetchFromGitHub {
owner = "antmicro";
repo = "zynq-mkbootimage";
rev = "872363ce32c249f8278cf107bc6d3bdeb38d849f";
sha256 = "sha256-5FPyAhUWZDwHbqmp9J2ZXTmjaXPz+dzrJMolaNwADHs=";
};
propagatedBuildInputs = [ pkgs.libelf pkgs.pcre ];
patchPhase =
''
substituteInPlace Makefile --replace "git rev-parse --short HEAD" "echo nix"
'';
installPhase =
''
mkdir -p $out/bin
cp mkbootimage $out/bin
'';
hardeningDisable = [ "fortify" ];
};
fsbl = { board ? "zc706" }: pkgs.stdenv.mkDerivation {
name = "${board}-fsbl";
src = pkgs.fetchFromGitHub {
owner = "Xilinx";
repo = "embeddedsw";
rev = "xilinx_v2022.2";
sha256 = "sha256-UDz9KK/Hw3qM1BAeKif30rE8Bi6C2uvuZlvyvtJCMfw=";
};
nativeBuildInputs = [
pkgs.pkgsCross.zynq-baremetal.buildPackages.binutils
pkgs.pkgsCross.zynq-baremetal.buildPackages.gcc
];
patchPhase = ''
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
'';
buildPhase = ''
cd lib/sw_apps/zynq_fsbl/src
make BOARD=${board} "CFLAGS=-DFSBL_DEBUG_INFO -g"
'';
installPhase = ''
mkdir $out
cp fsbl.elf $out
'';
doCheck = false;
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}";
src = builtins.filterSource (path: type:
baseNameOf path != "target"
) ./.;
cargoLock = { lockFile = ./Cargo.lock; };
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_14.clang-unwrapped ];
buildPhase = ''
export XARGO_RUST_SRC="${rust}/lib/rustlib/src/rust/library"
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
pushd ${crate}
cargo xbuild --release --frozen \
--no-default-features \
--features=${features}
popd
'';
installPhase = ''
mkdir -p $out $out/nix-support
cp target/armv7-none-eabihf/release/${name} $out/${name}.elf
echo file binary-dist $out/${name}.elf >> $out/nix-support/hydra-build-products
'';
doCheck = false;
dontFixup = true;
auditable = false;
};
targetCrates = target: {
"${target}-experiments" = build-crate "${target}-experiments" "experiments" "target_${target}";
"${target}-szl" = build-crate "${target}-szl" "szl" "target_${target}";
};
targets = ["zc706" "coraz7" "redpitaya" "kasli_soc"];
allTargetCrates = (builtins.foldl' (results: target:
results // targetCrates target
) {} targets);
szl = pkgs.runCommand "szl" {} (builtins.foldl' (commands: target:
let
szlResult = builtins.getAttr "${target}-szl" allTargetCrates;
in
commands + "ln -s ${szlResult}/szl.elf $out/szl-${target}.elf\n"
) "mkdir $out\n" targets);
in rec {
packages.x86_64-linux = {
inherit cargo-xbuild szl mkbootimage;
zc706-fsbl = fsbl { board = "zc706"; };
} // allTargetCrates ;
hydraJobs = packages.x86_64-linux;
inherit rust rustPlatform;
devShell.x86_64-linux = pkgs.mkShell {
name = "zynq-rs-dev-shell";
buildInputs = [
rust
cargo-xbuild
mkbootimage
pkgs.openocd pkgs.gdb
pkgs.openssh pkgs.rsync
pkgs.llvmPackages_14.clang-unwrapped
(pkgs.python3.withPackages(ps: [ ps.pyftdi ]))
];
};
};
}

View File

@ -0,0 +1,114 @@
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);

View File

@ -13,6 +13,9 @@ 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
@ -300,16 +303,25 @@ 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: (),
@ -480,6 +492,69 @@ 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>,

View File

@ -82,6 +82,10 @@ impl PhyRegister for Control {
fn addr() -> u8 {
0
}
fn page() -> u8 {
0
}
}
impl From<u16> for Control {

View File

@ -11,6 +11,9 @@ 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 {

View File

@ -0,0 +1,79 @@
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
}
}

View File

@ -6,6 +6,8 @@ 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 {
@ -26,6 +28,42 @@ 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);
@ -33,6 +71,7 @@ pub trait PhyAccess {
pub trait PhyRegister {
fn addr() -> u8;
fn page() -> u8;
}
@ -45,6 +84,10 @@ 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> {
@ -84,6 +127,9 @@ 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()
}
@ -93,6 +139,9 @@ 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())
@ -106,6 +155,14 @@ 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)
}
@ -139,4 +196,12 @@ 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)
);
}
}

View File

@ -43,6 +43,10 @@ impl PhyRegister for PSSR {
fn addr() -> u8 {
0x11
}
fn page() -> u8 {
0
}
}
impl From<u16> for PSSR {

View File

@ -100,6 +100,10 @@ impl PhyRegister for Status {
fn addr() -> u8 {
1
}
fn page() -> u8 {
0
}
}
impl From<u16> for Status {

View File

@ -110,6 +110,49 @@ 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);

View File

@ -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 + 1));
self.mpcore.icdiptr[m].modify(|mut icdiptr| *icdiptr.set_bits(n..=n+1, target_cpu as u32));
}
// sensitivity

View File

@ -35,16 +35,14 @@ impl<'a> EEPROM<'a> {
#[cfg(feature = "target_zc706")]
fn select(&mut self) -> Result<(), &'static str> {
let mask: u16 = 1 << self.port;
self.i2c.pca9548_select(0b1110100, mask as u8)?;
self.i2c.pca954x_select(0b1110100, Some(self.port))?;
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.pca9548_select(0b1110001, mask as u8)?;
self.i2c.pca954x_select(0b1110001, Some(self.port))?;
Ok(())
}

View File

@ -6,10 +6,19 @@ 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>
count_down: super::timer::global::CountDown<Microseconds>,
pca_type: I2cMultiplexer
}
impl I2c {
@ -44,18 +53,17 @@ impl I2c {
.pullup(false)
.disable_rcvr(true)
);
// Reset
slcr.gpio_rst_ctrl.reset_gpio();
});
Self::i2c_common(0xFFFF - 0x000C)
Self::i2c_common(0xFFFF - 0x000C, 0xFFFF - 0x0002)
}
fn i2c_common(gpio_output_mask: u16) -> Self {
fn i2c_common(gpio_output_mask: u16, _gpio_output_mask_lower: u16) -> Self {
// Setup register block
let self_ = Self {
regs: regs::RegisterBlock::i2c(),
count_down: unsafe { super::timer::GlobalTimer::get() }.countdown()
count_down: unsafe { super::timer::GlobalTimer::get() }.countdown(),
pca_type: I2cMultiplexer::PCA9548 //default for zc706
};
// Setup GPIO output mask
@ -67,6 +75,17 @@ 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_
}
@ -110,6 +129,48 @@ 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);
@ -136,6 +197,13 @@ 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(())
}
@ -219,7 +287,7 @@ impl I2c {
if self.sda_i() { data |= 1 << bit }
self.scl_oe(true);
}
// Send ack/nack
// Send ack/nack (true = nack, false = ack)
self.sda_oe(ack);
self.unit_delay();
self.scl_oe(false);
@ -231,13 +299,32 @@ impl I2c {
Ok(data)
}
pub fn pca9548_select(&mut self, address: u8, channels: u8) -> Result<(), &'static str> {
pub fn pca954x_select(&mut self, address: u8, channel: Option<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("PCA9548 failed to ack write address")
return Err("PCA954X failed to ack write address")
}
if !self.write(channels)? {
return Err("PCA9548 failed to ack control word")
if !self.write(setting)? {
return Err("PCA954X failed to ack control word")
}
self.stop()?;
Ok(())

View File

@ -20,13 +20,15 @@ use libregister::{
//
// Current compatibility:
// zc706: GPIO 50, 51 == SCL, SDA
// kasli_soc: GPIO 50, 51 == SCL, SDA
// kasli_soc: GPIO 50, 51 == SCL, SDA; GPIO 33 == I2C_SW_RESET
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 {
@ -35,7 +37,9 @@ impl RegisterBlock {
gpio_output_mask: GPIOOutputMask::new(),
gpio_input: GPIOInput::new(),
gpio_direction: GPIODirection::new(),
gpio_output_enable: GPIOOutputEnable::new()
gpio_output_enable: GPIOOutputEnable::new(),
#[cfg(feature = "target_kasli_soc")]
gpio_output_mask_lower: GPIOOutputMaskLower::new(),
}
}
}
@ -59,6 +63,21 @@ 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]
@ -74,6 +93,7 @@ register_bit!(gpio_input,
/// Input for SDA
sda, 19);
register!(gpio_direction,
/// DIRM_1:
/// Direction mode for MIO[53:32]; 0/1 = in/out
@ -88,6 +108,10 @@ 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:
@ -103,3 +127,8 @@ 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);

View File

@ -23,3 +23,5 @@ pub mod sdio;
pub mod i2c;
pub mod logger;
pub mod ps7_init;
#[cfg(feature="target_kasli_soc")]
pub mod error_led;

View File

@ -587,6 +587,17 @@ 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 {
@ -605,7 +616,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, 1);
register_bit!(pss_rst_ctrl, soft_rst, 0);
/// Used for MioPin*.io_type
#[repr(u8)]

View File

@ -16,3 +16,4 @@ target_coraz7 = []
target_redpitaya = []
target_kasli_soc = []
ipv6 = []
fat_lfn = [ "fatfs/alloc" ]

View File

@ -164,7 +164,8 @@ impl Config {
f.seek(SeekFrom::End(0))?;
write!(f, "{}={}\n", key, String::from_utf8(value).unwrap())?;
} else {
let mut f = root_dir.create_file(&["/CONFIG/", key, ".BIN"].concat())?;
let dir = root_dir.create_dir("/CONFIG")?;
let mut f = dir.create_file(&[key, ".BIN"].concat())?;
f.write_all(&value)?;
}
}

View File

@ -30,7 +30,19 @@ impl fmt::Display for NetAddresses {
}
}
pub fn get_adresses(cfg: &Config) -> 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 {
#[cfg(feature = "target_zc706")]
let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x52]);
#[cfg(feature = "target_zc706")]
@ -44,7 +56,7 @@ pub fn get_adresses(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 = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x56]);
let mut hardware_addr = get_address_from_eeprom();
#[cfg(feature = "target_kasli_soc")]
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 56);

View File

@ -34,6 +34,12 @@ 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() {

View File

@ -36,7 +36,9 @@ pub fn notify_spin_lock() {
}
#[macro_export]
/// Interrupt handler, which setup the stack and jump to actual interrupt handler.
/// 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.
///
/// - `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.
@ -44,8 +46,7 @@ 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, so
/// interrupt handlers should not return to normal program or it may corrupt the stack.
/// Note that the interrupt handler would use the same stack as normal programs by default.
macro_rules! interrupt_handler {
($name:ident, $name2:ident, $stack0:ident, $stack1:ident, $body:block) => {
#[link_section = ".text.boot"]
@ -54,19 +55,27 @@ 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
};
}

View File

@ -1,6 +1,9 @@
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}
@ -20,6 +23,23 @@ 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 {
@ -42,6 +62,10 @@ 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() {

View File

@ -12,9 +12,10 @@ 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"]
default = ["panic_handler", "dummy_irq_handler", "dummy_fiq_handler"]
[dependencies]
r0 = "1"

View File

@ -54,6 +54,7 @@ unsafe extern "C" fn boot_core0() -> ! {
asm::dmb();
asm::dsb();
asm::enable_fiq();
asm::enable_irq();
main_core0();
panic!("return from main");
@ -75,6 +76,7 @@ unsafe extern "C" fn boot_core1() -> ! {
asm::dmb();
asm::dsb();
asm::enable_fiq();
asm::enable_irq();
main_core1();
panic!("return from main_core1");

View File

@ -1,6 +1,10 @@
use libregister::RegisterR;
use libcortex_a9::{regs::{DFSR, MPIDR}, interrupt_handler};
use libboard_zynq::{println, stdio};
use libregister::{RegisterR, RegisterW};
use libcortex_a9::{regs::{DFSR, MPIDR, VBAR}, 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();
@ -42,6 +46,7 @@ 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");

View File

@ -9,7 +9,7 @@ pub extern crate alloc;
pub extern crate compiler_builtins;
pub mod boot;
mod abort;
pub mod exception_vectors;
#[cfg(feature = "panic_handler")]
mod panic;
pub mod ram;

View File

@ -1,4 +1,6 @@
use libboard_zynq::{print, println};
#[cfg(feature = "target_kasli_soc")]
use libboard_zynq::error_led::ErrorLED;
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
@ -13,6 +15,10 @@ 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 {}
}

View File

@ -1,22 +0,0 @@
{ lib, fetchFromGitHub, rustPlatform }:
rustPlatform.buildRustPackage rec {
pname = "cargo-xbuild";
version = "0.6.5";
src = fetchFromGitHub {
owner = "rust-osdev";
repo = pname;
rev = "v${version}";
sha256 = "18djvygq9v8rmfchvi2hfj0i6fhn36m716vqndqnj56fiqviwxvf";
};
cargoSha256 = "13sj9j9kl6js75h9xq0yidxy63vixxm9q3f8jil6ymarml5wkhx8";
meta = with 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 ];
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +0,0 @@
{ pkgs, board ? "zc706" }:
let
gnutoolchain = import ./gnutoolchain.nix { inherit pkgs; };
in
pkgs.stdenv.mkDerivation {
name = "${board}-fsbl";
src = pkgs.fetchFromGitHub {
owner = "Xilinx";
repo = "embeddedsw";
rev = "65c849ed46c88c67457e1fc742744f96db968ff1";
sha256 = "1rvl06ha40dzd6s9aa4sylmksh4xb9dqaxq462lffv1fdk342pda";
};
patches = [ ./fsbl.patch ];
nativeBuildInputs = [
pkgs.gnumake
gnutoolchain.binutils
gnutoolchain.gcc
];
patchPhase =
''
patch -p1 -i ${./fsbl.patch}
patchShebangs lib/sw_apps/zynq_fsbl/misc/copy_bsp.sh
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
make BOARD=${board} "CFLAGS=-DFSBL_DEBUG_INFO -g"
'';
installPhase =
''
mkdir $out
cp fsbl.elf $out
'';
doCheck = false;
dontFixup = true;
}

View File

@ -1,31 +0,0 @@
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

View File

@ -1,134 +0,0 @@
{ pkgs ? import <nixpkgs> }:
let
platform = "arm-none-eabi";
binutils-pkg = { stdenv, lib, buildPackages
, fetchurl, zlib
, extraConfigureFlags ? []
}:
stdenv.mkDerivation rec {
basename = "binutils";
version = "2.30";
name = "${basename}-${platform}-${version}";
src = fetchurl {
url = "https://ftp.gnu.org/gnu/binutils/binutils-${version}.tar.bz2";
sha256 = "028cklfqaab24glva1ks2aqa1zxa6w6xmc8q34zs1sb7h22dxspg";
};
configureFlags = [
"--enable-deterministic-archives"
"--target=${platform}"
"--with-cpu=cortex-a9"
"--with-fpu=vfpv3"
"--with-float=hard"
"--with-mode=thumb"
] ++ extraConfigureFlags;
outputs = [ "out" "info" "man" ];
depsBuildBuild = [ 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 = 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 = { stdenv, buildPackages
, fetchurl, gmp, mpfr, libmpc, platform-binutils
, extraConfigureFlags ? []
}:
stdenv.mkDerivation rec {
basename = "gcc";
version = "9.1.0";
name = "${basename}-${platform}-${version}";
src = 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=${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/${platform}-as"
"--with-ld=${platform-binutils}/bin/${platform}-ld" ] ++ extraConfigureFlags;
outputs = [ "out" "info" "man" ];
hardeningDisable = [ "format" "pie" ];
propagatedBuildInputs = [ gmp mpfr libmpc platform-binutils ];
enableParallelBuilding = true;
dontFixup = true;
};
newlib-pkg = { stdenv, fetchurl, buildPackages, platform-binutils, platform-gcc }:
stdenv.mkDerivation rec {
pname = "newlib";
version = "3.1.0";
src = fetchurl {
url = "ftp://sourceware.org/pub/newlib/newlib-${version}.tar.gz";
sha256 = "0ahh3n079zjp7d9wynggwrnrs27440aac04340chf1p9476a2kzv";
};
nativeBuildInputs = [ platform-binutils platform-gcc ];
configureFlags = [
"--target=${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;
};
in 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" ];
};
}

View File

@ -1,24 +0,0 @@
{ pkgs }:
pkgs.stdenv.mkDerivation {
pname = "mkbootimage";
version = "2.2";
src = pkgs.fetchFromGitHub {
owner = "antmicro";
repo = "zynq-mkbootimage";
rev = "4ee42d782a9ba65725ed165a4916853224a8edf7";
sha256 = "1k1mbsngqadqihzjgvwvsrkvryxy5ladpxd9yh9iqn2s7fxqwqa9";
};
propagatedBuildInputs = [ pkgs.libelf pkgs.pcre ];
patchPhase =
''
substituteInPlace Makefile --replace "git rev-parse --short HEAD" "echo nix"
'';
installPhase =
''
mkdir -p $out/bin
cp mkbootimage $out/bin
'';
}

View File

@ -1,10 +0,0 @@
let
pkgs = import <nixpkgs> {};
overlay = pkgs.fetchFromGitHub {
owner = "mozilla";
repo = "nixpkgs-mozilla";
rev = "b1001ed670666ca4ce1c1b064481f88694315c1d";
sha256 = "1hpig8z4pzdwc2vazr6hg7qyxllbgznsaivaigjnmrdszlxz55zz";
};
in
import overlay

View File

@ -1,20 +0,0 @@
{ pkgs }:
let
rustManifest = ./channel-rust-nightly.toml;
targets = [];
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 targets;
in
pkgs.recurseIntoAttrs (pkgs.makeRustPlatform {
rustc = rust;
cargo = rust;
})

20
openocd/common.cfg Normal file
View File

@ -0,0 +1,20 @@
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

View File

@ -8,26 +8,7 @@ source ./zynq-7000.cfg
reset_config srst_only srst_push_pull
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
source ./common.cfg
reset halt

View File

@ -17,26 +17,7 @@ reset_config srst_only srst_open_drain
adapter srst pulse_width 250
adapter srst delay 400
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
source ./common.cfg
reset halt

View File

@ -8,26 +8,7 @@ source ./zynq-7000.cfg
reset_config none
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
source ./common.cfg
halt

View File

@ -10,26 +10,7 @@ reset_config srst_only srst_open_drain
adapter srst pulse_width 250
adapter srst delay 400
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
source ./common.cfg
reset halt

View File

@ -1,26 +0,0 @@
let
pkgs = import <nixpkgs> { overlays = [ (import ./nix/mozilla-overlay.nix) ]; };
rustPlatform = (import ./nix/rust-platform.nix { inherit pkgs; });
cargo-xbuild = (import ./default.nix).cargo-xbuild;
in
pkgs.stdenv.mkDerivation {
name = "zynq-env";
buildInputs = [
rustPlatform.rust.rustc
rustPlatform.rust.cargo
pkgs.cacert
cargo-xbuild
pkgs.openocd pkgs.gdb
pkgs.openssh pkgs.rsync
pkgs.llvmPackages_9.clang-unwrapped
(import ./nix/mkbootimage.nix { inherit pkgs; })
];
XARGO_RUST_SRC = "${rustPlatform.rust.rustc}/lib/rustlib/src/rust/library";
shellHook = ''
echo "Run 'cargo xbuild --release -p ...' to build."
'';
}

View File

@ -75,13 +75,17 @@ pub fn main_core0() {
___/ / / /__/ /___
/____/ /____/_____/
(C) 2020-2021 M-Labs
(C) 2020-2022 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);
@ -136,7 +140,14 @@ pub fn main_core0() {
}
}
v => {
panic!("Boot mode {:?} not supported", 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,
)
}
};
}

View File

@ -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_adresses(&cfg);
let net_addresses = net_settings::get_addresses(&cfg);
log::info!("Network addresses: {}", net_addresses);
let eth = Eth::eth0(net_addresses.hardware_addr.0.clone());
let eth = eth.start_rx(8);