Compare commits

..

46 Commits

Author SHA1 Message Date
af42d9b819 fix UB in UncachedSlice 2025-02-07 11:21:46 +08:00
19efdafce7 nixpkgs 24.11 2025-01-15 22:26:00 +08:00
213529cf7a update dependencies 2024-12-20 12:17:01 +08:00
4cfcc75d5c flake output hashes 2024-12-20 12:17:01 +08:00
578431cbc6 up cargo dependencies 2024-12-20 12:17:01 +08:00
6188fe7d69 silence inline_const warns 2024-12-20 12:17:01 +08:00
2713b459ed remove unused abi-blacklist 2024-12-20 12:17:01 +08:00
0ea7e2c760 fix const in arr expression 2024-12-20 12:17:01 +08:00
fa660a7433 migrate inline asm macro 2024-12-20 12:17:01 +08:00
d2ec041107 up compiler builtins 2024-12-20 12:17:01 +08:00
48ab85bf2e use forked core_io, fatfs 2024-12-20 12:17:01 +08:00
d477272c5c use llvm13, remove llvm11 copy 2024-12-20 12:17:01 +08:00
80180ba8f6 bump rust vers 2024-12-17 14:15:43 +08:00
12975de2e1 flake: add missing attributes on rustc (for nixpkgs-unstable compat) 2024-11-16 17:31:34 +08:00
8c404829ef flake: update nixpkgs 2024-11-16 17:15:03 +08:00
8f041b017c switch to oxalica rust overlay 2024-11-16 17:14:37 +08:00
5815baf88b Reorder Status.get_link to check for higher speeds before slower. 2024-11-15 13:09:17 -08:00
cc20478d91 Add i2c support 2024-10-04 23:38:28 -07:00
5ef3016554 flake: update dependencies 2024-09-30 14:15:10 +08:00
6a45a0dfd0 ebaz4205 support
Co-authored-by: newell <newell.jensen@gmail.com>
Co-committed-by: newell <newell.jensen@gmail.com>
2024-09-30 14:08:58 +08:00
b2b3e5c933 flake: update dependencies 2024-07-09 17:03:22 +02:00
0efbbe39fe llvm: patch for artiq-zynq release-7 2024-06-06 14:06:56 +08:00
51b8111e79 flake: move to nixos 24.05 2024-05-28 17:37:50 +08:00
46dc25b89e add LLVM copy from nixpkgs 2024-05-24 10:57:12 +08:00
731684abb4 flake: switch to nixpkgs master, update dependencies 2024-05-09 10:02:43 +08:00
195a21fe78 use nix format for arm gnu toolchain 2024-03-25 17:20:19 +08:00
96cefe6f06 update fsbl source 2024-03-25 17:16:56 +08:00
7c58c0cf43 abort: rename to exception_vectors 2024-03-07 12:26:28 +08:00
9005b73316 experiment: add set_vector_table example 2024-03-07 12:03:49 +08:00
b1994dbe16 abort: support custom exception vector table addr 2024-03-07 12:03:29 +08:00
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
298f64a2f9 boot: enable FIQ
asm: add FIQ enable instruction
2024-02-02 16:34:28 +08:00
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
a43b8bf64e mkbootimage: work around buffer overflow 2023-12-03 16:16:22 +08:00
91bae572f9 fix "unknown argument '-Wl,--undefined=AUDITABLE_VERSION_INFO'" 2023-12-03 11:09:31 +08:00
301f9236e5 switch to nixpkgs cargo-xbuild (with workaround for rust nonsense) 2023-12-03 10:55:05 +08:00
55b36ee37e switch to new nixpkgs release 2023-12-03 10:45:47 +08:00
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
be672ab662 flake: update dependencies 2023-10-20 17:46:01 +08:00
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
de42a5d1b2 flake: update to LLVM 14 2023-08-07 23:26:58 +08:00
ff03bf92a3 flake: update dependencies 2023-08-07 23:23:02 +08:00
f20c008264 flake: nixpkgs 23.05 2023-05-27 18:20:53 +08:00
67dbb5932f flake: update mkbootimage 2022-11-30 22:36:56 +08:00
dab5c6f070 flake: NixOS 22.11, update dependencies 2022-11-30 22:29:58 +08:00
53 changed files with 638 additions and 1451 deletions

54
Cargo.lock generated
View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bit_field"
version = "0.10.1"
@ -14,9 +16,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "byteorder"
version = "1.4.3"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
checksum = "60f0b0d4c0a382d2734228fd12b5a6b5dac185c60e938026fd31b265b94f9bd2"
[[package]]
name = "cc"
@ -32,18 +34,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "compiler_builtins"
version = "0.1.39"
version = "0.1.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3748f82c7d366a0b4950257d19db685d4958d2fa27c6d164a3f069fec42b748b"
checksum = "20b1438ef42c655665a8ab2c1c6d605a305f031d38d9be689ddfef41a20f3aa2"
[[package]]
name = "core_io"
version = "0.1.20210325"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97f8932064288cc79feb4d343a399d353a6f6f001e586ece47fe518a9e8507df"
dependencies = [
"rustc_version",
]
version = "0.1.0"
source = "git+https://git.m-labs.hk/M-Labs/rs-core_io.git?rev=e9d3edf027#e9d3edf0272502b0dd6c26e8a4869c2912657615"
[[package]]
name = "embedded-hal"
@ -70,9 +68,8 @@ dependencies = [
[[package]]
name = "fatfs"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e18f80a87439240dac45d927fd8f8081b6f1e34c03e97271189fa8a8c2e96c8f"
version = "0.3.6"
source = "git+https://git.m-labs.hk/M-Labs/rust-fatfs.git?rev=4b5e420084#4b5e420084fd1c4a9c105680b687523909b6469c"
dependencies = [
"bitflags",
"byteorder",
@ -107,22 +104,6 @@ dependencies = [
"volatile-register",
]
[[package]]
name = "libboard_zynq_us"
version = "0.0.0"
dependencies = [
"bit_field",
"embedded-hal",
"libasync",
"libboard_zynq",
"libregister",
"log",
"nb 0.1.3",
"smoltcp",
"void",
"volatile-register",
]
[[package]]
name = "libconfig"
version = "0.1.0"
@ -212,21 +193,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211"
[[package]]
name = "rustc_version"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
[[package]]
name = "smoltcp"
version = "0.7.5"

View File

@ -8,7 +8,6 @@ members = [
"libconfig",
"experiments",
"szl",
"libboard_zynq_us",
]
[profile.release]

View File

@ -1,12 +1,4 @@
{
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
],
"arch": "arm",
"data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
"emit-debug-gdb-scripts": false,

View File

@ -8,6 +8,7 @@ edition = "2018"
[features]
target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706"]
target_coraz7 = ["libboard_zynq/target_coraz7", "libsupport_zynq/target_coraz7"]
target_ebaz4205 = ["libboard_zynq/target_ebaz4205", "libsupport_zynq/target_ebaz4205"]
target_redpitaya = ["libboard_zynq/target_redpitaya", "libsupport_zynq/target_redpitaya"]
target_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc"]
default = ["target_zc706"]
@ -18,5 +19,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

@ -1,12 +1,14 @@
#![no_std]
#![no_main]
#![feature(const_in_array_repeat_expressions)]
#![allow(incomplete_features)]
#![feature(naked_functions)]
#![feature(asm)]
#![feature(inline_const)]
extern crate alloc;
use alloc::collections::BTreeMap;
use core::arch::asm;
use libasync::{
delay,
smoltcp::{Sockets, TcpStream},
@ -39,7 +41,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 +58,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 +98,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");
@ -105,6 +118,7 @@ pub fn main_core0() {
#[cfg(any(
feature = "target_zc706",
feature = "target_ebaz4205",
feature = "target_redpitaya",
feature = "target_kasli_soc",
))]
@ -134,6 +148,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 };

49
flake.lock generated
View File

@ -1,41 +1,46 @@
{
"nodes": {
"mozilla-overlay": {
"flake": false,
"locked": {
"lastModified": 1650459918,
"narHash": "sha256-sroCK+QJTmoXtcRkwZyKOP9iAYOPID2Bwdxn4GkG16w=",
"owner": "mozilla",
"repo": "nixpkgs-mozilla",
"rev": "e1f7540fc0a8b989fb8cf701dc4fd7fc76bcf168",
"type": "github"
},
"original": {
"owner": "mozilla",
"repo": "nixpkgs-mozilla",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1653920503,
"narHash": "sha256-BBeCZwZImtjP3oYy4WogkQYy5OxNyfNciVSc1AfZgLQ=",
"lastModified": 1736867362,
"narHash": "sha256-i/UJ5I7HoqmFMwZEH6vAvBxOrjjOJNU739lnZnhUln8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a634c8f6c1fbf9b9730e01764999666f3436f10a",
"rev": "9c6b49aeac36e2ed73a8c472f1546f6d9cf1addc",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-22.05",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"mozilla-overlay": "mozilla-overlay",
"nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1719454714,
"narHash": "sha256-MojqG0lyUINkEk0b3kM2drsU5vyaF8DFZe/FAlZVOGs=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "d1c527659cf076ecc4b96a91c702d080b213801e",
"type": "github"
},
"original": {
"owner": "oxalica",
"ref": "snapshot/2024-08-01",
"repo": "rust-overlay",
"type": "github"
}
}
},

246
flake.nix
View File

@ -1,173 +1,53 @@
{
description = "Bare-metal Rust on Zynq-7000";
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-22.05;
inputs.mozilla-overlay = { url = github:mozilla/nixpkgs-mozilla; flake = false; };
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-24.11;
inputs.rust-overlay = {
url = "github:oxalica/rust-overlay?ref=snapshot/2024-08-01";
inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, mozilla-overlay }:
outputs = { self, nixpkgs, rust-overlay }:
let
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import mozilla-overlay) ]; };
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import rust-overlay) crosspkgs-overlay ]; };
rustManifest = pkgs.fetchurl {
url = "https://static.rust-lang.org/dist/2021-01-29/channel-rust-nightly.toml";
sha256 = "sha256-EZKgw89AH4vxaJpUHmIMzMW/80wAFQlfcxRoBD9nz0c=";
rust = pkgs.rust-bin.nightly."2021-09-01".default.override {
extensions = [ "rust-src" ];
targets = [ ];
};
rustTargets = [];
rustChannelOfTargets = _channel: _date: targets:
(pkgs.lib.rustLib.fromManifestFile rustManifest {
inherit (pkgs) stdenv lib fetchurl patchelf;
}).rust.override {
inherit targets;
extensions = ["rust-src"];
rustPlatform = pkgs.makeRustPlatform {
rustc = rust // {
# https://github.com/oxalica/rust-overlay/commit/c48c2d76b68dd9ede0815fec53479375c61af857
targetPlatforms = pkgs.lib.platforms.all;
tier1TargetPlatforms = pkgs.lib.platforms.all;
badTargetPlatforms = [ ];
};
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";
};
};
};
});
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.2";
version = "2.3dev";
src = pkgs.fetchFromGitHub {
owner = "antmicro";
repo = "zynq-mkbootimage";
rev = "4ee42d782a9ba65725ed165a4916853224a8edf7";
sha256 = "1k1mbsngqadqihzjgvwvsrkvryxy5ladpxd9yh9iqn2s7fxqwqa9";
rev = "872363ce32c249f8278cf107bc6d3bdeb38d849f";
sha256 = "sha256-5FPyAhUWZDwHbqmp9J2ZXTmjaXPz+dzrJMolaNwADHs=";
};
propagatedBuildInputs = [ pkgs.libelf pkgs.pcre ];
@ -180,6 +60,7 @@
mkdir -p $out/bin
cp mkbootimage $out/bin
'';
hardeningDisable = [ "fortify" ];
};
fsbl = { board ? "zc706" }: pkgs.stdenv.mkDerivation {
@ -187,19 +68,20 @@
src = pkgs.fetchFromGitHub {
owner = "Xilinx";
repo = "embeddedsw";
rev = "65c849ed46c88c67457e1fc742744f96db968ff1";
sha256 = "1rvl06ha40dzd6s9aa4sylmksh4xb9dqaxq462lffv1fdk342pda";
rev = "xilinx_v2022.2";
sha256 = "sha256-UDz9KK/Hw3qM1BAeKif30rE8Bi6C2uvuZlvyvtJCMfw=";
};
patches = [ ./fsbl.patch ];
nativeBuildInputs = [
pkgs.gnumake
gnutoolchain.binutils
gnutoolchain.gcc
pkgs.pkgsCross.zynq-baremetal.buildPackages.binutils
pkgs.pkgsCross.zynq-baremetal.buildPackages.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
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
@ -213,17 +95,27 @@
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; };
cargoLock = {
lockFile = ./Cargo.lock;
outputHashes = {
"core_io-0.1.0" = "sha256-0HINFWRiJx8pjMgUOL/CS336ih7SENSRh3Kah9LPRrw=";
"fatfs-0.3.6" = "sha256-Nz9hCq/1YgSXF8ltJ5ZawV0Hc8WV44KNK0tJdVnNb4U=";
};
};
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_9.clang-unwrapped ];
nativeBuildInputs = [ cargo-xbuild pkgs.llvmPackages_13.clang-unwrapped ];
buildPhase = ''
export XARGO_RUST_SRC="${rustPlatform.rust.rustc}/lib/rustlib/src/rust/library"
export XARGO_RUST_SRC="${rust}/lib/rustlib/src/rust/library"
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
pushd ${crate}
cargo xbuild --release --frozen \
@ -240,13 +132,14 @@
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"];
targets = ["zc706" "coraz7" "redpitaya" "kasli_soc" "ebaz4205"];
allTargetCrates = (builtins.foldl' (results: target:
results // targetCrates target
) {} targets);
@ -265,21 +158,20 @@
hydraJobs = packages.x86_64-linux;
inherit rustPlatform;
inherit rust rustPlatform;
devShell.x86_64-linux = pkgs.mkShell {
name = "zynq-rs-dev-shell";
buildInputs = with pkgs; [
rustPlatform.rust.rustc
rustPlatform.rust.cargo
cacert
buildInputs = [
rust
cargo-xbuild
mkbootimage
openocd gdb
openssh rsync
llvmPackages_9.clang-unwrapped
(python3.withPackages(ps: [ ps.pyftdi ]))
mkbootimage ];
};
pkgs.openocd pkgs.gdb
pkgs.openssh pkgs.rsync
pkgs.llvmPackages_13.clang-unwrapped
(pkgs.python3.withPackages(ps: [ ps.pyftdi ]))
];
};
};
}
}

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

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

View File

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

View File

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

View File

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

View File

@ -18,8 +18,6 @@ impl ErrorLED {
.pullup(true)
.disable_rcvr(true)
);
// reset
slcr.gpio_rst_ctrl.reset_gpio();
});
Self::error_led_common(0xFFFF - 0x0080)

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

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

View File

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

View File

@ -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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,28 +0,0 @@
[package]
name = "libboard_zynq_us"
description = "Drivers for peripherals in the Zynq UltraScale+ PS"
version = "0.0.0"
authors = ["M-Labs"]
edition = "2018"
[features]
target_zcu111 = []
ipv6 = [ "smoltcp/proto-ipv6" ]
default = [ "target_zcu111" ]
[dependencies]
volatile-register = "0.2"
bit_field = "0.10"
embedded-hal = "0.2"
nb = "0.1"
void = { version = "1", default-features = false }
log = "0.4"
libregister = { path = "../libregister" }
# libcortex_a9 = { path = "../libcortex_a9" }
libasync = { path = "../libasync" }
libboard_zynq = { path = "../libboard_zynq" }
[dependencies.smoltcp]
version = "0.7"
features = ["ethernet", "proto-ipv4", "socket-tcp"]
default-features = false

View File

@ -1,89 +0,0 @@
use libregister::{RegisterR, RegisterRW};
use super::slcr::{crf_apb, crl_apb, common::SlcrRegisterBlock};
pub use super::slcr::crf_apb::ApuClkSource;
pub mod source;
use source::*;
#[derive(Debug, Clone)]
pub struct Clocks {
/// ARM PLL: Recommended clock source for the APUs and the FPD interconnect
pub apu: u32,
/// DDR PLL: Recommended clock for the DDR DRAM controller and AXI_HP interfaces
pub ddr: u32,
/// Video PLL: Recommended clock for display port
pub video: u32,
/// I/O PLL: Recommended clock for I/O peripherals
pub io: u32,
/// RPU PLL: Recommended clock for RPUs and LPD interconnect
pub rpu: u32,
}
impl Clocks {
pub fn get() -> Self {
let fpd_regs = crf_apb::RegisterBlock::slcr();
let lpd_regs = crl_apb::RegisterBlock::slcr();
Clocks {
apu: ApuPll::freq(&mut fpd_regs.apu_pll_ctrl),
ddr: DdrPll::freq(&mut fpd_regs.ddr_pll_ctrl),
video: VideoPll::freq(&mut fpd_regs.video_pll_ctrl),
io: IoPll::freq(&mut lpd_regs.io_pll_ctrl),
rpu: RpuPll::freq(&mut lpd_regs.rpu_pll_ctrl),
}
}
pub fn set_cpu_freq(target_freq: u32) {
let fpd_regs = crf_apb::RegisterBlock::slcr();
let apu_pll = ApuPll::freq(&mut fpd_regs.apu_pll_ctrl);
let mut div = 1u8;
while div < 63 && apu_pll / u32::from(div) > target_freq {
div += 1;
}
crf_apb::RegisterBlock::unlocked(|slcr| {
slcr.apu_clk_ctrl.modify(|_, w| w
.srcsel(ApuClkSource::ApuPll)
.divisor0(div)
);
})
}
pub fn uart0_ref_clk(&self) -> u32 {
let lpd_regs = crl_apb::RegisterBlock::slcr();
self.uart_ref_clk(&mut lpd_regs.uart0_clk_ctrl)
}
pub fn uart1_ref_clk(&self) -> u32 {
let lpd_regs = crl_apb::RegisterBlock::slcr();
self.uart_ref_clk(&mut lpd_regs.uart1_clk_ctrl)
}
fn uart_ref_clk(&self, uart_regs: &mut crl_apb::UartClkCtrl) -> u32 {
let uart_clk_ctrl = uart_regs.read();
let pll = match uart_clk_ctrl.srcsel() {
crl_apb::IoClkSource::IoPll => self.io,
crl_apb::IoClkSource::RpuPll => self.rpu,
crl_apb::IoClkSource::DdrPllToLpd => {
let fpd_regs = crf_apb::RegisterBlock::slcr();
let divisor = u32::from(fpd_regs.ddr_pll_to_lpd_ctrl.read().divisor0());
self.ddr / divisor
}
};
pll / (u32::from(uart_clk_ctrl.divisor0()) * u32::from(uart_clk_ctrl.divisor1()))
}
// pub fn sdio_ref_clk(&self) -> u32 {
// let regs = slcr::RegisterBlock::slcr();
// let sdio_clk_ctrl = regs.sdio_clk_ctrl.read();
// let pll = match sdio_clk_ctrl.srcsel() {
// slcr::PllSource::ArmPll =>
// self.arm,
// slcr::PllSource::DdrPll =>
// self.ddr,
// slcr::PllSource::IoPll =>
// self.io,
// };
// pll / u32::from(sdio_clk_ctrl.divisor())
// }
}

View File

@ -1,255 +0,0 @@
use crate::slcr::common::{PllCfg, PllCtrl, PllFracCfg, SlcrRegisterBlock};
use crate::slcr::{crf_apb, crl_apb};
use libregister::{RegisterR, RegisterRW};
use log::debug;
pub const PS_CLK: u32 = 33_333_000;
// DS926 Table: PS PLL Switching Characteristics (same for both speed grades)
// const PS_PLL_MAX_LOCK_TIME: f32 = 100e-6; // 100 us
const PS_PLL_MAX_OUT_FREQ: u32 = 1_600_000_000;
const PS_PLL_MIN_OUT_FREQ: u32 = 750_000_000;
// const PS_PLL_MAX_VCO_FREQ: u32 = 3_000_000_000;
const PS_PLL_MIN_VCO_FREQ: u32 = 1_500_000_000;
/// UG1085 table 37-1
/// (pll_fdiv_max, (pll_cp, pll_res, lfhf, lock_dly, lock_cnt))
const PLL_FDIV_LOCK_PARAM: &[(u8, (u8, u8, u8, u8, u16))] = &[
(25, (3, 10, 3, 63, 1000)),
(26, (3, 10, 3, 63, 1000)),
(27, (4, 6, 3, 63, 1000)),
(28, (4, 6, 3, 63, 1000)),
(29, (4, 6, 3, 63, 1000)),
(30, (4, 6, 3, 63, 1000)),
(31, (6, 1, 3, 63, 1000)),
(32, (6, 1, 3, 63, 1000)),
(33, (4, 10, 3, 63, 1000)),
(34, (5, 6, 3, 63, 1000)),
(35, (5, 6, 3, 63, 1000)),
(36, (5, 6, 3, 63, 1000)),
(37, (5, 6, 3, 63, 1000)),
(38, (5, 6, 3, 63, 975)),
(39, (3, 12, 3, 63, 950)),
(40, (3, 12, 3, 63, 925)),
(41, (3, 12, 3, 63, 900)),
(42, (3, 12, 3, 63, 875)),
(43, (3, 12, 3, 63, 850)),
(44, (3, 12, 3, 63, 850)),
(45, (3, 12, 3, 63, 825)),
(46, (3, 12, 3, 63, 800)),
(47, (3, 12, 3, 63, 775)),
(48, (3, 12, 3, 63, 775)),
(49, (3, 12, 3, 63, 750)),
(50, (3, 12, 3, 63, 750)),
(51, (3, 2, 3, 63, 725)),
(52, (3, 2, 3, 63, 700)),
(53, (3, 2, 3, 63, 700)),
(54, (3, 2, 3, 63, 675)),
(55, (3, 2, 3, 63, 675)),
(56, (3, 2, 3, 63, 650)),
(57, (3, 2, 3, 63, 650)),
(58, (3, 2, 3, 63, 625)),
(59, (3, 2, 3, 63, 625)),
(60, (3, 2, 3, 63, 625)),
(82, (3, 2, 3, 63, 600)), // 61-82
(102, (4, 2, 3, 63, 600)), // 83-102
(103, (5, 2, 3, 63, 600)),
(104, (5, 2, 3, 63, 600)),
(105, (5, 2, 3, 63, 600)),
(106, (5, 2, 3, 63, 600)),
(125, (3, 4, 3, 63, 600)), // 107-125
];
pub trait ClockSource<T: SlcrRegisterBlock> {
/// picks this ClockSource's registers from the SLCR block
fn pll_ctrl_regs(slcr: &mut T) -> (&mut PllCtrl, &mut PllCfg, &mut PllFracCfg);
/// query PLL lock status
fn pll_locked() -> bool;
// todo: is there any situation in which we'll actually want to use fractional mode?
/// query fraction mode enable bit
fn frac_enabled(pll_frac_cfg: &mut PllFracCfg) -> bool {
bool::from(pll_frac_cfg.read().enabled())
}
/// get configured frequency
fn freq(pll_ctrl: &mut PllCtrl) -> u32 {
// todo: take into account fractional part (if enabled)
u32::from(pll_ctrl.read().pll_fdiv()) * PS_CLK
}
fn name() -> &'static str;
// UG1085 Chapter 37: PS Clock Subsystem
fn setup(target_freq: u32) {
assert!(target_freq >= PS_PLL_MIN_OUT_FREQ && target_freq <= PS_PLL_MAX_OUT_FREQ);
let div2 = target_freq < PS_PLL_MIN_VCO_FREQ;
let divisor = u32::from(div2) + 1;
let fdiv = (target_freq * divisor / PS_CLK).min(125) as u8;
let (pll_cp, pll_res, lfhf, lock_dly, lock_cnt) = PLL_FDIV_LOCK_PARAM
.iter()
.filter(|(fdiv_max, _)| fdiv <= *fdiv_max)
.nth(0)
.expect("PLL_FDIV_LOCK_PARAM")
.1
.clone();
debug!("Set {} to {} Hz", Self::name(), target_freq);
T::unlocked(|slcr| {
let (pll_ctrl, pll_cfg, _) = Self::pll_ctrl_regs(slcr);
// Write fdiv, div2
pll_ctrl.modify(|_, w| w.pll_fdiv(fdiv).pll_div2(div2));
// Configure
// no need to zero as we're writing every field
pll_cfg.modify(|_, w| {
w.lock_dly(lock_dly)
.lock_cnt(lock_cnt)
.lfhf(lfhf)
.pll_cp(pll_cp)
.pll_res(pll_res)
});
// Bypass
pll_ctrl.modify(|_, w| w.pll_bypass_force(true));
// Reset
pll_ctrl.modify(|_, w| w.pll_reset(true));
pll_ctrl.modify(|_, w| w.pll_reset(false));
// Wait for PLL lock
// todo: add timeout here according to the 100 us spec?
while !Self::pll_locked() {}
// Remove bypass
pll_ctrl.modify(|_, w| w.pll_bypass_force(false));
});
}
}
/// APU PLL: Recommended clock source for the APUs and the FPD interconnect
pub struct ApuPll;
impl ClockSource<crf_apb::RegisterBlock> for ApuPll {
#[inline]
fn pll_ctrl_regs(
slcr: &mut crf_apb::RegisterBlock,
) -> (&mut PllCtrl, &mut PllCfg, &mut PllFracCfg) {
(
&mut slcr.apu_pll_ctrl,
&mut slcr.apu_pll_cfg,
&mut slcr.apu_pll_frac_cfg,
)
}
#[inline]
fn pll_locked() -> bool {
let slcr = crf_apb::RegisterBlock::slcr();
slcr.pll_status.read().apu_pll_lock()
}
fn name() -> &'static str {
&"APU_PLL"
}
}
/// DDR PLL: Recommended clock for the DDR DRAM controller and AXI_HP interfaces
pub struct DdrPll;
impl ClockSource<crf_apb::RegisterBlock> for DdrPll {
#[inline]
fn pll_ctrl_regs(
slcr: &mut crf_apb::RegisterBlock,
) -> (&mut PllCtrl, &mut PllCfg, &mut PllFracCfg) {
(
&mut slcr.ddr_pll_ctrl,
&mut slcr.ddr_pll_cfg,
&mut slcr.ddr_pll_frac_cfg,
)
}
#[inline]
fn pll_locked() -> bool {
let slcr = crf_apb::RegisterBlock::slcr();
slcr.pll_status.read().ddr_pll_lock()
}
fn name() -> &'static str {
&"DDR_PLL"
}
}
/// Video PLL: Recommended clock for DisplayPort
pub struct VideoPll;
impl ClockSource<crf_apb::RegisterBlock> for VideoPll {
#[inline]
fn pll_ctrl_regs(
slcr: &mut crf_apb::RegisterBlock,
) -> (&mut PllCtrl, &mut PllCfg, &mut PllFracCfg) {
(
&mut slcr.video_pll_ctrl,
&mut slcr.video_pll_cfg,
&mut slcr.video_pll_frac_cfg,
)
}
#[inline]
fn pll_locked() -> bool {
let slcr = crf_apb::RegisterBlock::slcr();
slcr.pll_status.read().video_pll_lock()
}
fn name() -> &'static str {
&"VIDEO_PLL"
}
}
/// I/O PLL: Recommended clock for I/O peripherals
pub struct IoPll;
impl ClockSource<crl_apb::RegisterBlock> for IoPll {
#[inline]
fn pll_ctrl_regs(
slcr: &mut crl_apb::RegisterBlock,
) -> (&mut PllCtrl, &mut PllCfg, &mut PllFracCfg) {
(
&mut slcr.io_pll_ctrl,
&mut slcr.io_pll_cfg,
&mut slcr.io_pll_frac_cfg,
)
}
#[inline]
fn pll_locked() -> bool {
let slcr = crl_apb::RegisterBlock::slcr();
slcr.pll_status.read().io_pll_lock()
}
fn name() -> &'static str {
&"IO_PLL"
}
}
/// RPU PLL: Recommended clock for RPUs and LPD interconnect
pub struct RpuPll;
impl ClockSource<crl_apb::RegisterBlock> for RpuPll {
#[inline]
fn pll_ctrl_regs(
slcr: &mut crl_apb::RegisterBlock,
) -> (&mut PllCtrl, &mut PllCfg, &mut PllFracCfg) {
(
&mut slcr.io_pll_ctrl,
&mut slcr.io_pll_cfg,
&mut slcr.io_pll_frac_cfg,
)
}
#[inline]
fn pll_locked() -> bool {
let slcr = crl_apb::RegisterBlock::slcr();
slcr.pll_status.read().rpu_pll_lock()
}
fn name() -> &'static str {
&"RPU_PLL"
}
}

View File

@ -1,9 +0,0 @@
#![no_std]
extern crate alloc;
/// Re-export so that dependents can always use the same version
pub use libboard_zynq::smoltcp;
pub mod slcr;
pub mod clocks;

View File

@ -1,29 +0,0 @@
///! Type definitions for re-use across SLCR blocks
use libregister::{register, register_bit, register_bits};
pub trait SlcrRegisterBlock {
fn unlocked<F: FnMut(&mut Self) -> R, R>(f: F) -> R;
}
register!(wprot, WProt, RW, u32);
register_bit!(wprot, active, 0);
register!(pll_ctrl, PllCtrl, RW, u32);
register_bits!(pll_ctrl, pll_post_src, u8, 24, 26);
register_bits!(pll_ctrl, pll_pre_src, u8, 20, 22);
register_bit!(pll_ctrl, pll_div2, 16);
register_bits!(pll_ctrl, pll_fdiv, u8, 8, 14);
register_bit!(pll_ctrl, pll_bypass_force, 3);
register_bit!(pll_ctrl, pll_reset, 0);
register!(pll_cfg, PllCfg, RW, u32);
register_bits!(pll_cfg, lock_dly, u8, 25, 31);
register_bits!(pll_cfg, lock_cnt, u16, 13, 22);
register_bits!(pll_cfg, lfhf, u8, 10, 11);
register_bits!(pll_cfg, pll_cp, u8, 5, 8);
register_bits!(pll_cfg, pll_res, u8, 0, 3);
register!(pll_frac_cfg, PllFracCfg, RW, u32);
register_bit!(pll_frac_cfg, enabled, 31);
register_bits!(pll_frac_cfg, data, u16, 0, 15);

View File

@ -1,100 +0,0 @@
///! FPD clock and reset control
use volatile_register::{RO, RW, WO};
use libregister::{
register, register_at,
register_bit, register_bits, register_bits_typed,
RegisterW,
};
use super::common::{SlcrRegisterBlock, WProt, PllCfg, PllCtrl, PllFracCfg};
#[repr(u8)]
pub enum ApuClkSource {
ApuPll = 0b00,
DdrPll = 0b10,
VideoPll = 0b11,
}
#[repr(C)]
pub struct RegisterBlock {
// CRF_APB
pub err_ctrl: RW<u32>,
pub ir_status: RW<u32>, // todo: WTC LSB
pub ir_mask: RO<u32>,
pub ir_enable: WO<u32>,
pub ir_disable: WO<u32>,
pub crf_wprot: WProt,
pub apu_pll_ctrl: PllCtrl,
pub apu_pll_cfg: PllCfg,
pub apu_pll_frac_cfg: PllFracCfg,
pub ddr_pll_ctrl: PllCtrl,
pub ddr_pll_cfg: PllCfg,
pub ddr_pll_frac_cfg: PllFracCfg,
pub video_pll_ctrl: PllCtrl,
pub video_pll_cfg: PllCfg,
pub video_pll_frac_cfg: PllFracCfg,
pub pll_status: PllStatus,
pub apu_pll_to_lpd_ctrl: PllToLpdCtrl,
pub ddr_pll_to_lpd_ctrl: PllToLpdCtrl,
pub video_pll_to_lpd_ctrl: PllToLpdCtrl,
reserved1: [u32; 3],
pub apu_clk_ctrl: ApuClkCtrl,
pub dbg_trace_clk_ctrl: RW<u32>,
pub dbg_fpd_clk_ctrl: RW<u32>,
reserved2: [u32; 1],
pub dp_video_clk_ctrl: RW<u32>,
pub dp_audio_clk_ctrl: RW<u32>,
reserved3: [u32; 1],
pub dp_sys_clk_ctrl: RW<u32>,
pub ddr_clk_ctrl: DdrClkCtrl,
pub gpu_clk_ctrl: RW<u32>,
reserved4: [u32; 6],
pub sata_clk_ctrl: RW<u32>,
reserved5: [u32; 4],
pub pcie_clk_ctrl: RW<u32>,
pub fpd_dma_clk_ctrl: RW<u32>,
pub dp_dma_clk_ctrl: RW<u32>,
pub topsw_main_clk_ctrl: RW<u32>,
pub topsw_lsbus_clk_ctrl: RW<u32>,
reserved6: [u32; 8],
pub dbg_tstmp_clk_ctrl: RW<u32>,
reserved7: [u32; 1],
pub rst_fpd_top: RW<u32>,
pub rst_fpd_apu: RW<u32>,
pub rst_ddr_ss: RW<u32>,
}
register_at!(RegisterBlock, 0xFD1A_0000, slcr);
impl SlcrRegisterBlock for RegisterBlock {
fn unlocked<F: FnMut(&mut Self) -> R, R>(mut f: F) -> R {
let mut self_ = Self::slcr();
self_.crf_wprot.write(WProt::zeroed().active(false));
let r = f(&mut self_);
self_.crf_wprot.write(WProt::zeroed().active(true));
r
}
}
register!(pll_status, PllStatus, RO, u32);
register_bit!(pll_status, video_pll_stable, 5);
register_bit!(pll_status, ddr_pll_stable, 4);
register_bit!(pll_status, apu_pll_stable, 3);
register_bit!(pll_status, video_pll_lock, 2);
register_bit!(pll_status, ddr_pll_lock, 1);
register_bit!(pll_status, apu_pll_lock, 0);
register!(pll_to_lpd_ctrl, PllToLpdCtrl, RW, u32);
register_bits!(pll_to_lpd_ctrl, divisor0, u8, 8, 13);
register!(apu_clk_ctrl, ApuClkCtrl, RW, u32);
register_bit!(apu_clk_ctrl, clkact_half, 25);
register_bit!(apu_clk_ctrl, clkact_full, 24);
register_bits!(apu_clk_ctrl, divisor0, u8, 8, 13);
register_bits_typed!(apu_clk_ctrl, srcsel, u8, ApuClkSource, 0, 2);
register!(ddr_clk_ctrl, DdrClkCtrl, RW, u32);
register_bits!(ddr_clk_ctrl, divisor0, u8, 8, 13);
// 000: DDR PLL
// 001: Video PLL
register_bits!(ddr_clk_ctrl, srcsel, u8, 0, 2);

View File

@ -1,315 +0,0 @@
///! FPD clock and reset control
use volatile_register::{RO, RW, WO};
use libregister::{
register, register_at,
register_bit, register_bits, register_bits_typed,
};
use super::common::{SlcrRegisterBlock, WProt, PllCfg, PllCtrl, PllFracCfg};
/// Clock source selection for IO-type devices
#[repr(u8)]
pub enum IoClkSource {
IoPll = 0b00,
RpuPll = 0b10,
DdrPllToLpd = 0b11,
}
/// Clock source selection for RPU and related (e.g. LPD interconnect) devices
#[repr(u8)]
pub enum RpuClkSource {
RpuPll = 0b00,
IoPll = 0b10,
DdrPllToLpd = 0b11,
}
#[repr(C)]
pub struct RegisterBlock {
pub err_ctrl: RW<u32>,
pub ir_status: RW<u32>, // todo: WTC LSB
pub ir_mask: RO<u32>,
pub ir_enable: WO<u32>,
pub ir_disable: WO<u32>,
reserved1: [u32; 2],
pub crl_wprot: WProt,
pub io_pll_ctrl: PllCtrl,
pub io_pll_cfg: PllCfg,
pub io_pll_frac_cfg: PllFracCfg,
reserved2: [u32; 1],
pub rpu_pll_ctrl: PllCtrl,
pub rpu_pll_cfg: PllCfg,
pub rpu_pll_frac_cfg: PllFracCfg,
reserved3: [u32; 1],
pub pll_status: PllStatus,
pub io_pll_to_fpd_ctrl: PllToFpdCtrl,
pub rpu_pll_to_fpd_ctrl: PllToFpdCtrl,
pub usb3_clk_ctrl: UsbClkCtrl,
pub gem0_clk_ctrl: GemClkCtrl,
pub gem1_clk_ctrl: GemClkCtrl,
pub gem2_clk_ctrl: GemClkCtrl,
pub gem3_clk_ctrl: GemClkCtrl,
pub usb0_bus_clk_ctrl: UsbClkCtrl,
pub usb1_bus_clk_ctrl: UsbClkCtrl,
pub qspi_clk_ctrl: QSpiClkCtrl,
pub sdio0_clk_ctrl: SdioClkCtrl,
pub sdio1_clk_ctrl: SdioClkCtrl,
pub uart0_clk_ctrl: UartClkCtrl,
pub uart1_clk_ctrl: UartClkCtrl,
pub spi0_clk_ctrl: SpiClkCtrl,
pub spi1_clk_ctrl: SpiClkCtrl,
pub can0_clk_ctrl: CanClkCtrl,
pub can1_clk_ctrl: CanClkCtrl,
reserved4: [u32; 1],
pub rpu_clk_ctrl: RpuClkCtrl,
reserved5: [u32; 2],
pub iou_switch_clk_ctrl: IouSwitchClkCtrl,
pub csu_clk_ctrl: CsuPllCtrl,
pub pcap_clk_ctrl: PcapClkCtrl,
pub lpd_switch_clk_ctrl: LpdSwitchClkCtrl,
pub lpd_lsbus_clk_ctrl: LpdLsbusClkCtrl,
pub dbg_lpd_clk_ctrl: DbgLpdClkCtrl,
pub nand_clk_ctrl: NandClkCtrl,
pub lpd_dma_clk_ctrl: LpdDmaClkCtrl,
reserved6: [u32; 1],
pub pl0_clk_ctrl: PlClkCtrl,
pub pl1_clk_ctrl: PlClkCtrl,
pub pl2_clk_ctrl: PlClkCtrl,
pub pl3_clk_ctrl: PlClkCtrl,
pub pl0_thr_ctrl: PlThrCtrl,
pub pl0_thr_cnt: PlThrCnt,
pub pl1_thr_ctrl: PlThrCtrl,
pub pl1_thr_cnt: PlThrCnt,
pub pl2_thr_ctrl: PlThrCtrl,
pub pl2_thr_cnt: PlThrCnt,
pub pl3_thr_ctrl: PlThrCtrl,
reserved7: [u32; 4],
pub pl3_thr_cnt: PlThrCnt,
pub gem_tsu_clk_ctrl: GemTsuClkCtrl,
pub dll_clk_ctrl: DllClkCtrl,
pub ps_sysmon_clk_ctrl: PsSysmonClkCtrl,
reserved8: [u32; 5],
pub i2c0_clk_ctrl: I2cClkCtrl,
pub i2c1_clk_ctrl: I2cClkCtrl,
pub timestamp_clk_ctrl: TimestampClkCtrl,
reserved9: [u32; 1],
pub safety_chk: RW<u32>,
reserved10: [u32; 3],
pub clkmon_status: RW<u32>,
pub clkmon_mask: RO<u32>,
pub clkmon_enable: WO<u32>,
pub clkmon_disable: WO<u32>,
pub clkmon_trigger: WO<u32>,
reserved11: [u32; 3],
pub chkr0_clka_upper: RW<u32>,
pub chkr0_clka_lower: RW<u32>,
pub chkr0_clkb_cnt: RW<u32>,
pub chkr0_ctrl: RW<u32>,
pub chkr1_clka_upper: RW<u32>,
pub chkr1_clka_lower: RW<u32>,
pub chkr1_clkb_cnt: RW<u32>,
pub chkr1_ctrl: RW<u32>,
pub chkr2_clka_upper: RW<u32>,
pub chkr2_clka_lower: RW<u32>,
pub chkr2_clkb_cnt: RW<u32>,
pub chkr2_ctrl: RW<u32>,
pub chkr3_clka_upper: RW<u32>,
pub chkr3_clka_lower: RW<u32>,
pub chkr3_clkb_cnt: RW<u32>,
pub chkr3_ctrl: RW<u32>,
pub chkr4_clka_upper: RW<u32>,
pub chkr4_clka_lower: RW<u32>,
pub chkr4_clkb_cnt: RW<u32>,
pub chkr4_ctrl: RW<u32>,
pub chkr5_clka_upper: RW<u32>,
pub chkr5_clka_lower: RW<u32>,
pub chkr5_clkb_cnt: RW<u32>,
pub chkr5_ctrl: RW<u32>,
pub chkr6_clka_upper: RW<u32>,
pub chkr6_clka_lower: RW<u32>,
pub chkr6_clkb_cnt: RW<u32>,
pub chkr6_ctrl: RW<u32>,
pub chkr7_clka_upper: RW<u32>,
pub chkr7_clka_lower: RW<u32>,
pub chkr7_clkb_cnt: RW<u32>,
pub chkr7_ctrl: RW<u32>,
reserved12: [u32; 8],
pub boot_mode_user: RW<u32>,
pub boot_mode: BootMode,
reserved13: [u32; 4],
pub reset_ctrl: RW<u32>,
pub blockonly_rst: RW<u32>, // todo: WTC LSB
pub reset_reason: RW<u32>, // todo: WTC 0:6
reserved14: [u32; 3],
pub gem_rst_ctrl: GemRstCtrl,
reserved15: [u32; 1],
pub peri_rst_ctrl: PeriRstCtrl,
pub rst_lpd_top: RstLpdTop,
pub rst_lpd_dbg: RW<u32>,
reserved16: [u32; 3],
pub boot_pin_ctrl: RW<u32>, // todo: RO 4:7
reserved17: [u32; 7],
pub bank3_drive0: RW<u32>,
pub bank3_drive1: RW<u32>,
pub bank3_input_ctrl: RW<u32>,
pub bank3_pull_ctrl: RW<u32>,
pub bank3_pull_enable: RW<u32>,
pub bank3_slew_ctrl: RW<u32>,
pub bank3_status: RO<u32>,
}
register_at!(RegisterBlock, 0xFF5E_0000, slcr);
impl SlcrRegisterBlock for RegisterBlock {
// Dummy definition (CRL_APB has no WProt) for consistency with CRF_APB
fn unlocked<F: FnMut(&mut Self) -> R, R>(mut f: F) -> R {
let mut self_ = Self::slcr();
f(&mut self_)
}
}
register!(pll_status, PllStatus, RO, u32);
register_bit!(pll_status, rpu_pll_stable, 4);
register_bit!(pll_status, io_pll_stable, 3);
register_bit!(pll_status, rpu_pll_lock, 1);
register_bit!(pll_status, io_pll_lock, 0);
register!(pll_to_fpd_ctrl, PllToFpdCtrl, RW, u32);
register_bits!(pll_to_fpd_ctrl, divisor0, u8, 8, 13);
register!(gem_clk_ctrl, GemClkCtrl, RW, u32);
register_bit!(gem_clk_ctrl, rx_clkact, 26);
register_bit!(gem_clk_ctrl, clkact, 25);
register_bits!(gem_clk_ctrl, divisor1, u8, 16, 21);
register_bits!(gem_clk_ctrl, divisor0, u8, 8, 13);
register_bits_typed!(gem_clk_ctrl, srcsel, u8, IoClkSource, 0, 2);
register!(usb_clk_ctrl, UsbClkCtrl, RW, u32);
register_bit!(usb_clk_ctrl, clkact, 25);
register_bits!(usb_clk_ctrl, divisor1, u8, 16, 21);
register_bits!(usb_clk_ctrl, divisor0, u8, 8, 13);
register_bits_typed!(usb_clk_ctrl, srcsel, u8, IoClkSource, 0, 2);
macro_rules! dual_div_clk_reg {
($mod_name: ident, $struct_name: ident, $srcsel_type: ident) => {
register!($mod_name, $struct_name, RW, u32);
register_bit!($mod_name, clkact, 24);
register_bits!($mod_name, divisor1, u8, 16, 21);
register_bits!($mod_name, divisor0, u8, 8, 13);
register_bits_typed!($mod_name, srcsel, u8, $srcsel_type, 0, 2);
};
}
dual_div_clk_reg!(qspi_clk_ctrl, QSpiClkCtrl, IoClkSource);
dual_div_clk_reg!(sdio_clk_ctrl, SdioClkCtrl, IoClkSource);
dual_div_clk_reg!(uart_clk_ctrl, UartClkCtrl, IoClkSource);
dual_div_clk_reg!(spi_clk_ctrl, SpiClkCtrl, IoClkSource);
dual_div_clk_reg!(can_clk_ctrl, CanClkCtrl, IoClkSource);
dual_div_clk_reg!(nand_clk_ctrl, NandClkCtrl, IoClkSource);
dual_div_clk_reg!(pl_clk_ctrl, PlClkCtrl, IoClkSource);
dual_div_clk_reg!(gem_tsu_clk_ctrl, GemTsuClkCtrl, IoClkSource);
dual_div_clk_reg!(ps_sysmon_clk_ctrl, PsSysmonClkCtrl, RpuClkSource);
dual_div_clk_reg!(i2c_clk_ctrl, I2cClkCtrl, IoClkSource);
register!(rpu_clk_ctrl, RpuClkCtrl, RW, u32);
register_bit!(rpu_clk_ctrl, clkact_core, 25);
register_bit!(rpu_clk_ctrl, clkact, 24);
register_bits!(rpu_clk_ctrl, divisor0, u8, 8, 13);
register_bits_typed!(rpu_clk_ctrl, srcsel, u8, RpuClkSource, 0, 2);
macro_rules! single_div_clk_reg {
// default to RpuClkSource
($mod_name: ident, $struct_name: ident, $srcsel_type: ident) => {
register!($mod_name, $struct_name, RW, u32);
register_bit!($mod_name, clkact, 24);
register_bits!($mod_name, divisor1, u8, 16, 21);
register_bits!($mod_name, divisor0, u8, 8, 13);
register_bits_typed!($mod_name, srcsel, u8, $srcsel_type, 0, 2);
};
}
single_div_clk_reg!(iou_switch_clk_ctrl, IouSwitchClkCtrl, RpuClkSource);
single_div_clk_reg!(csu_clk_ctrl, CsuPllCtrl, IoClkSource);
single_div_clk_reg!(pcap_clk_ctrl, PcapClkCtrl, IoClkSource);
single_div_clk_reg!(lpd_switch_clk_ctrl, LpdSwitchClkCtrl, RpuClkSource);
single_div_clk_reg!(lpd_lsbus_clk_ctrl, LpdLsbusClkCtrl, RpuClkSource);
single_div_clk_reg!(dbg_lpd_clk_ctrl, DbgLpdClkCtrl, RpuClkSource);
single_div_clk_reg!(lpd_dma_clk_ctrl, LpdDmaClkCtrl, RpuClkSource);
// todo: timestamp clk can also run directly from PS_REF_CLK (0b1xx)
single_div_clk_reg!(timestamp_clk_ctrl, TimestampClkCtrl, IoClkSource);
register!(pl_thr_ctrl, PlThrCtrl, RW, u32);
register_bits!(pl_thr_ctrl, curr_val, u16, 16, 31, RO);
register_bit!(pl_thr_ctrl, running, 15, RO);
register_bit!(pl_thr_ctrl, cpu_start, 1);
register_bit!(pl_thr_ctrl, cnt_rst, 0);
register!(pl_thr_cnt, PlThrCnt, RW, u32);
register_bits!(pl_thr_cnt, last_cnt, u16, 0, 15);
register!(dll_clk_ctrl, DllClkCtrl, RW, u32);
register_bits!(dll_clk_ctrl, srcsel, u8, 0, 2);
// boot mode pin values read after POR and "triplicated for security"
register!(boot_mode, BootMode, RO, u32);
register_bits!(boot_mode, boot_mode2, u8, 8, 11);
register_bits!(boot_mode, boot_mode1, u8, 4, 7);
register_bits!(boot_mode, boot_mode0, u8, 0, 3);
register!(gem_rst_ctrl, GemRstCtrl, RW, u32);
register_bit!(gem_rst_ctrl, gem3_rst, 3);
register_bit!(gem_rst_ctrl, gem2_rst, 2);
register_bit!(gem_rst_ctrl, gem1_rst, 1);
register_bit!(gem_rst_ctrl, gem0_rst, 0);
register!(peri_rst_ctrl, PeriRstCtrl, RW, u32);
register_bit!(peri_rst_ctrl, timestamp_rst, 20);
register_bit!(peri_rst_ctrl, iou_cc_rst, 19);
register_bit!(peri_rst_ctrl, gpio_rst, 18);
register_bit!(peri_rst_ctrl, lpd_dma_rst, 17);
register_bit!(peri_rst_ctrl, nand_rst, 16);
register_bit!(peri_rst_ctrl, swdt_rst, 15);
register_bit!(peri_rst_ctrl, ttc3_rst, 14);
register_bit!(peri_rst_ctrl, ttc2_rst, 13);
register_bit!(peri_rst_ctrl, ttc1_rst, 12);
register_bit!(peri_rst_ctrl, ttc0_rst, 11);
register_bit!(peri_rst_ctrl, i2c1_rst, 10);
register_bit!(peri_rst_ctrl, i2c0_rst, 9);
register_bit!(peri_rst_ctrl, can1_rst, 8);
register_bit!(peri_rst_ctrl, can0_rst, 7);
register_bit!(peri_rst_ctrl, sdio1_rst, 6);
register_bit!(peri_rst_ctrl, sdio0_rst, 5);
register_bit!(peri_rst_ctrl, spi1_rst, 4);
register_bit!(peri_rst_ctrl, spi0_rst, 3);
register_bit!(peri_rst_ctrl, uart1_rst, 2);
register_bit!(peri_rst_ctrl, uart0_rst, 1);
register_bit!(peri_rst_ctrl, qspi_rst, 0);
register!(rst_lpd_top, RstLpdTop, RW, u32);
register_bit!(rst_lpd_top, fpd_rst, 23);
register_bit!(rst_lpd_top, lpd_swdt_rst, 20);
register_bit!(rst_lpd_top, s_axi_lpd_rst, 19);
register_bit!(rst_lpd_top, sysmon_rst, 17);
register_bit!(rst_lpd_top, rtc_rst, 16);
register_bit!(rst_lpd_top, apm_rst, 15);
register_bit!(rst_lpd_top, ipi_rst, 14);
register_bit!(rst_lpd_top, usb1_apb_rst, 11);
register_bit!(rst_lpd_top, usb0_apb_rst, 10);
register_bit!(rst_lpd_top, usb1_hiber_rst, 9);
register_bit!(rst_lpd_top, usb0_hiber_rst, 8);
register_bit!(rst_lpd_top, usb1_core_rst, 7);
register_bit!(rst_lpd_top, usb0_core_rst, 6);
register_bit!(rst_lpd_top, rpu_pge_rst, 4);
register_bit!(rst_lpd_top, ocm_rst, 3);
register_bit!(rst_lpd_top, rpu_amba_rst, 2);
register_bit!(rst_lpd_top, rpu_core1_rst, 1);
register_bit!(rst_lpd_top, rpu_core0_rst, 0);

View File

@ -1,124 +0,0 @@
///! IOU SLCR for MIO pin configuration
use volatile_register::{RO, RW, WO};
use libregister::{
register, register_at,
register_bit, register_bits,
};
use super::common::SlcrRegisterBlock;
#[repr(C)]
pub struct RegisterBlock {
pub mio_pin: [MioPin; 78],
pub bank0_drive0: BankDriveCtrl,
pub bank0_drive1: BankDriveCtrl,
pub bank0_input_ctrl: BankInputCtrl,
pub bank0_pull_ctrl: BankPullCtrl,
pub bank0_pull_enable: BankPullEnable,
pub bank0_slew_ctrl: BankSlewCtrl,
pub bank0_status: BankStatus,
pub bank1_drive0: BankDriveCtrl,
pub bank1_drive1: BankDriveCtrl,
pub bank1_input_ctrl: BankInputCtrl,
pub bank1_pull_ctrl: BankPullCtrl,
pub bank1_pull_enable: BankPullEnable,
pub bank1_slew_ctrl: BankSlewCtrl,
pub bank1_status: BankStatus,
pub bank2_drive0: BankDriveCtrl,
pub bank2_drive1: BankDriveCtrl,
pub bank2_input_ctrl: BankInputCtrl,
pub bank2_pull_ctrl: BankPullCtrl,
pub bank2_pull_enable: BankPullEnable,
pub bank2_slew_ctrl: BankSlewCtrl,
pub bank2_status: BankStatus,
reserved1: [u32; 5],
pub mio_loopback: RW<u32>,
pub mio_mst_tri0: RW<u32>,
pub mio_mst_tri1: RW<u32>,
pub mio_mst_tri2: RW<u32>,
pub wdt_clk_sel: RW<u32>, // 0 = internal APB clock, 1 = external
pub can_mio_ctrl: RW<u32>,
pub gem_clk_ctrl: RW<u32>,
pub sdio_clk_ctrl: RW<u32>,
pub ctrl_reg_sd: RW<u32>,
pub sd_itap_dly: RW<u32>,
pub sd_otap_dly_sel: RW<u32>,
pub sd_cfg1: RW<u32>,
pub sd_cfg2: RW<u32>,
pub sd_cfg3: RW<u32>,
pub sd_init_preset: RW<u32>,
pub sd_speed_preset: RW<u32>,
pub sd_hspeed_preset: RW<u32>,
pub sd_sdr12_preset: RW<u32>,
pub sd_sdr25_preset: RW<u32>,
pub sd_sdr50_preset: RW<u32>,
reserved2: [u32; 1],
pub sd_sdr104_preset: RW<u32>,
pub sd_ddr50_preset: RW<u32>,
pub sd_max_cur_18: RW<u32>,
pub sd_max_cur_30: RW<u32>,
pub sd_max_cur_33: RW<u32>,
pub sd_dll_ctrl: RW<u32>,
pub sd_cdn_ctrl: RW<u32>,
pub gem_ctrl: RW<u32>,
reserved3: [u32; 7],
pub iou_ttc_apb_clk: RW<u32>,
reserved4: [u32; 3],
pub iou_tapdly_bypass: RW<u32>,
reserved5: [u32; 3],
pub iou_coherent_ctrl: RW<u32>,
pub video_pss_clk_sel: RW<u32>,
pub iou_interconnect_route: RW<u32>,
reserved6: [u32; 125],
pub ctrl: RW<u32>,
reserved7: [u32; 63],
pub isr: RW<u32>, // todo: WTC LSB
pub imr: RO<u32>,
pub ier: WO<u32>,
pub idr: WO<u32>,
pub itr: WO<u32>,
}
register_at!(RegisterBlock, 0xFF18_0000, slcr);
impl SlcrRegisterBlock for RegisterBlock {
// Dummy definition for consistency
fn unlocked<F: FnMut(&mut Self) -> R, R>(mut f: F) -> R {
let mut self_ = Self::slcr();
f(&mut self_)
}
}
register!(mio_pin, MioPin, RW, u32);
register_bits!(mio_pin, l3_sel, u8, 5, 7);
register_bits!(mio_pin, l2_sel, u8, 3, 4);
register_bit!(mio_pin, l1_sel, 2);
register_bit!(mio_pin, l0_sel, 1);
register!(bank_drive_ctrl, BankDriveCtrl, RW, u32);
register_bits!(bank_drive_ctrl, drive, u32, 0, 25);
// 0 = CMOS, 1 = Schmitt
register!(bank_input_ctrl, BankInputCtrl, RW, u32);
register_bits!(bank_input_ctrl, schmitt, u32, 0, 25);
// 0 = down, 1 = up
register!(bank_pull_ctrl, BankPullCtrl, RW, u32);
register_bits!(bank_pull_ctrl, pull_up, u32, 0, 25);
register!(bank_pull_enable, BankPullEnable, RW, u32);
register_bits!(bank_pull_enable, pull_enable, u32, 0, 25);
// 0 = fast, 1 = slow
register!(bank_slew_ctrl, BankSlewCtrl, RW, u32);
register_bits!(bank_slew_ctrl, slow_slew, u32, 0, 25);
// 0 = 2.5 or 3.3V, 1 = 1.8V
register!(bank_status, BankStatus, RO, u32);
register_bit!(bank_status, voltage_mode, 0);
// todo: impl for MioPin (or RegisterBlock?) to make drive ctrl less obnoxious
// might as well toss in convenience functions for pull up/down, etc.

View File

@ -1,15 +0,0 @@
///! Register definitions for UltraScale+ System Level Control
pub mod common;
pub mod crf_apb;
// APU
// FPD_SLCR
// FPD_SLCR_SECURE
pub mod iou_slcr;
// IOU_SECURE_SLCR
// IOU_SCNTRS
// LPD_SLCR
// LPD_SLCR_SECURE
pub mod crl_apb;
// RPU
// CCI_GPV
// FPD_GPV

View File

@ -1,7 +0,0 @@
use libregister::register_at;
use libboard_zynq::uart::baud_rate_gen;
use libboard_zync::uart::regs::RegisterBlock;
register_at!(RegisterBlock, 0xFF000000, uart0);
register_at!(RegisterBlock, 0xFF010000, uart1); // note: PS_UART1 is not connected on ZCU111

View File

@ -6,14 +6,24 @@ edition = "2018"
[dependencies]
libboard_zynq = { path = "../libboard_zynq" }
core_io = { version = "0.1", features = ["collections"] }
fatfs = { version = "0.3", features = ["core_io"], default-features = false }
log = "0.4"
[dependencies.core_io]
git = "https://git.m-labs.hk/M-Labs/rs-core_io.git"
rev = "e9d3edf027"
features = ["collections"]
[dependencies.fatfs]
git = "https://git.m-labs.hk/M-Labs/rust-fatfs.git"
rev = "4b5e420084"
default-features = false
features = ["core_io"]
[features]
target_zc706 = []
target_coraz7 = []
target_ebaz4205 = []
target_redpitaya = []
target_kasli_soc = []
ipv6 = []
fat_lfn = [ "fatfs/alloc" ]
fat_lfn = [ "fatfs/alloc" ]

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,10 @@
#![no_std]
#![feature(llvm_asm, global_asm)]
#![feature(never_type)]
#![feature(const_fn)]
#![feature(global_asm)]
#![feature(asm)]
#![allow(incomplete_features)]
#![feature(inline_const)]
#![feature(const_fn_trait_bound)]
extern crate alloc;
@ -17,6 +20,7 @@ pub mod sync_channel;
mod uncached;
pub use fpu::enable_fpu;
pub use uncached::UncachedSlice;
use core::arch::global_asm;
global_asm!(include_str!("exceptions.s"));
@ -36,7 +40,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 +50,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 +59,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

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

View File

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

View File

@ -19,8 +19,8 @@ impl<T> UncachedSlice<T> {
.max(L1_PAGE_SIZE);
let layout = Layout::from_size_align(size, align)?;
let ptr = unsafe { alloc::alloc::alloc(layout).cast::<T>() };
assert!(!ptr.is_null());
let start = ptr as usize;
assert_eq!(start & (L1_PAGE_SIZE - 1), 0);
for page_start in (start..(start + size)).step_by(L1_PAGE_SIZE) {
// non-shareable device
@ -33,9 +33,6 @@ impl<T> UncachedSlice<T> {
}
let slice = unsafe { core::slice::from_raw_parts_mut(ptr, len) };
// verify size
assert!(unsafe { slice.get_unchecked(len) } as *const _ as usize <= start + size);
// initialize
for e in slice.iter_mut() {
*e = default();
}

View File

@ -290,19 +290,6 @@ macro_rules! register_bits {
}
}
);
($mod_name: ident, $(#[$outer:meta])* $name: ident, $type: ty, $bit_begin: expr, $bit_end: expr, RO) => (
impl $mod_name::Read {
#[allow(unused)]
#[inline]
$(#[$outer])*
pub fn $name(&self) -> $type {
use bit_field::BitField;
self.inner.get_bits($bit_begin..=$bit_end) as $type
}
}
);
}
/// Define a multi-bit field of a register, coerced to a certain type

View File

@ -8,17 +8,19 @@ edition = "2018"
[features]
target_zc706 = ["libboard_zynq/target_zc706"]
target_coraz7 = ["libboard_zynq/target_coraz7"]
target_ebaz4205 = ["libboard_zynq/target_ebaz4205"]
target_redpitaya = ["libboard_zynq/target_redpitaya"]
target_kasli_soc = ["libboard_zynq/target_kasli_soc"]
panic_handler = []
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"
compiler_builtins = "=0.1.39"
compiler_builtins = "=0.1.49"
linked_list_allocator = { version = "0.8", default-features = false, features = ["const_mut_refs"] }
libregister = { path = "../libregister" }
libcortex_a9 = { path = "../libcortex_a9" }

View File

@ -1,5 +1,6 @@
use r0::zero_bss;
use core::ptr::write_volatile;
use core::arch::asm;
use libregister::{
VolatileCell,
RegisterR, RegisterRW,
@ -54,6 +55,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 +77,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,11 @@
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};
use core::arch::asm;
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 +47,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

@ -3,13 +3,14 @@
#![feature(alloc_error_handler)]
#![feature(panic_info_message)]
#![feature(naked_functions)]
#![feature(global_asm)]
#![feature(asm)]
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;

33
openocd/ebaz4205.cfg Normal file
View File

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

View File

@ -8,6 +8,7 @@ edition = "2018"
[features]
target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706", "libconfig/target_zc706"]
target_coraz7 = ["libboard_zynq/target_coraz7", "libsupport_zynq/target_coraz7", "libconfig/target_coraz7"]
target_ebaz4205 = ["libboard_zynq/target_ebaz4205", "libsupport_zynq/target_ebaz4205", "libconfig/target_ebaz4205"]
target_redpitaya = ["libboard_zynq/target_redpitaya", "libsupport_zynq/target_redpitaya", "libconfig/target_redpitaya"]
target_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc", "libconfig/target_kasli_soc"]
default = ["target_zc706"]
@ -15,10 +16,14 @@ default = ["target_zc706"]
[dependencies]
log = "0.4"
byteorder = { version = "1.3", default-features = false }
core_io = { version = "0.1", features = ["collections"] }
libboard_zynq = { path = "../libboard_zynq" }
libsupport_zynq = { path = "../libsupport_zynq" }
libcortex_a9 = { path = "../libcortex_a9" }
libregister = { path = "../libregister" }
libconfig = { path = "../libconfig" }
[dependencies.core_io]
git = "https://git.m-labs.hk/M-Labs/rs-core_io.git"
rev = "e9d3edf027"
features = ["collections"]

View File

@ -80,12 +80,15 @@ pub fn main_core0() {
);
info!("Simple Zynq Loader starting...");
#[cfg(not(feature = "target_kasli_soc"))]
#[cfg(not(any(feature = "target_kasli_soc", feature = "target_ebaz4205")))]
const CPU_FREQ: u32 = 800_000_000;
#[cfg(feature = "target_kasli_soc")]
const CPU_FREQ: u32 = 1_000_000_000;
#[cfg(feature = "target_ebaz4205")]
const CPU_FREQ: u32 = 666_666_666;
ArmPll::setup(2 * CPU_FREQ);
Clocks::set_cpu_freq(CPU_FREQ);
IoPll::setup(1_000_000_000);