Compare commits
8 Commits
master
...
use_new_zy
Author | SHA1 | Date | |
---|---|---|---|
1c739e81ab | |||
c0f508bb17 | |||
b68ebc9906 | |||
f28f1ee387 | |||
0d4a197d60 | |||
d1d03a02bd | |||
9d1bbff6b2 | |||
4aedb5a5ee |
48
flake.lock
generated
48
flake.lock
generated
@ -11,11 +11,11 @@
|
|||||||
"src-pythonparser": "src-pythonparser"
|
"src-pythonparser": "src-pythonparser"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1736946744,
|
"lastModified": 1732066716,
|
||||||
"narHash": "sha256-RKqrWcJfkLlm5JYVfz46KOVg1FYch1pNkKDpW5VzehU=",
|
"narHash": "sha256-krjvt9+RccnAxSEZcFhRpjA2S3CoqE4MSa1JUg421b4=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "33c91d73bb768a06fa427c237b124916261c5ab9",
|
"rev": "270a417a28b516d36983779a1adb6d33a3c55a4a",
|
||||||
"revCount": 9135,
|
"revCount": 9102,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/m-labs/artiq.git"
|
"url": "https://github.com/m-labs/artiq.git"
|
||||||
},
|
},
|
||||||
@ -37,11 +37,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1734270714,
|
"lastModified": 1720768567,
|
||||||
"narHash": "sha256-7bzGn/hXLIsLQHGQsvo+uoIFUrw9DjXSlMC449BY4ME=",
|
"narHash": "sha256-3VoK7o5MtHtbHLrc6Pv+eQWFtaz5Gd/YWyV5TD3c5Ss=",
|
||||||
"owner": "m-labs",
|
"owner": "m-labs",
|
||||||
"repo": "artiq-comtools",
|
"repo": "artiq-comtools",
|
||||||
"rev": "7e3152314af8f5987370e33b347b2ec2697567ed",
|
"rev": "f93570d8f2ed5a3cfb3e1c16ab00f2540551e994",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -70,11 +70,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1736798957,
|
"lastModified": 1731319897,
|
||||||
"narHash": "sha256-qwpCtZhSsSNQtK4xYGzMiyEDhkNzOCz/Vfu4oL2ETsQ=",
|
"narHash": "sha256-PbABj4tnbWFMfBp6OcUK5iGy1QY+/Z96ZcLpooIbuEI=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9abb87b552b7f55ac8916b6fc9e5cb486656a2f3",
|
"rev": "dc460ec76cbff0e66e269457d7b728432263166c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -142,11 +142,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1734267097,
|
"lastModified": 1728371104,
|
||||||
"narHash": "sha256-aWg7XDiOlWnkXfDbKrBn9ITR46/JXfndvYHxFJ1vN78=",
|
"narHash": "sha256-PPnAyDedUQ7Og/Cby9x5OT9wMkNGTP8GS53V6N/dk4w=",
|
||||||
"owner": "m-labs",
|
"owner": "m-labs",
|
||||||
"repo": "sipyco",
|
"repo": "sipyco",
|
||||||
"rev": "430978ada3fefe32de01f1b884b3031e48aaef96",
|
"rev": "094a6cd63ffa980ef63698920170e50dc9ba77fd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -158,11 +158,11 @@
|
|||||||
"src-migen": {
|
"src-migen": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1735131698,
|
"lastModified": 1727677091,
|
||||||
"narHash": "sha256-P4vaF+9iVekRAC2/mc9G7IwI6baBpPAxiDQ8uye4sAs=",
|
"narHash": "sha256-Zg3SQnTwMM/VkOGKogbPyuCC2NhLy8HB2SPEUWWNgCU=",
|
||||||
"owner": "m-labs",
|
"owner": "m-labs",
|
||||||
"repo": "migen",
|
"repo": "migen",
|
||||||
"rev": "4c2ae8dfeea37f235b52acb8166f12acaaae4f7c",
|
"rev": "c19ae9f8ae162ffe2d310a92bfce53ac2a821bc8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -174,11 +174,11 @@
|
|||||||
"src-misoc": {
|
"src-misoc": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1736416570,
|
"lastModified": 1729234629,
|
||||||
"narHash": "sha256-tbcN/fzejZIaYbTbwk8Ir1glYevESqMinMeDB3z8oxg=",
|
"narHash": "sha256-TLsTCXV5AC2xh+bS7EhBVBKqdqIU3eKrnlWcFF9LtAM=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "1f5318e9edc1085ac77e9b85b8f5e03371dba54c",
|
"rev": "6085a312bca26adeca6584e37d08c8ba2e1d6e38",
|
||||||
"revCount": 2464,
|
"revCount": 2460,
|
||||||
"submodules": true,
|
"submodules": true,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/m-labs/misoc.git"
|
"url": "https://github.com/m-labs/misoc.git"
|
||||||
@ -229,11 +229,11 @@
|
|||||||
"rust-overlay": "rust-overlay_2"
|
"rust-overlay": "rust-overlay_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1734668221,
|
"lastModified": 1731749494,
|
||||||
"narHash": "sha256-X0U2yPmlsD3VLBZQyfWv8qw04Qn0qFWIONJUPPigB0U=",
|
"narHash": "sha256-WGigAhvVCGN5YZ1dHPyvoqAh47W1Gtph036O1aKFlLE=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "213529cf7a50aa1b2d9ffdf575e3e38202ff9bd6",
|
"rev": "12975de2e110d7948bf47b768559f727d0abc8fc",
|
||||||
"revCount": 666,
|
"revCount": 655,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.m-labs.hk/m-labs/zynq-rs"
|
"url": "https://git.m-labs.hk/m-labs/zynq-rs"
|
||||||
},
|
},
|
||||||
|
20
flake.nix
20
flake.nix
@ -10,7 +10,6 @@
|
|||||||
pkgs = import artiq.inputs.nixpkgs { system = "x86_64-linux"; overlays = [ (import zynq-rs.inputs.rust-overlay) ]; };
|
pkgs = import artiq.inputs.nixpkgs { system = "x86_64-linux"; overlays = [ (import zynq-rs.inputs.rust-overlay) ]; };
|
||||||
zynqpkgs = zynq-rs.packages.x86_64-linux;
|
zynqpkgs = zynq-rs.packages.x86_64-linux;
|
||||||
artiqpkgs = artiq.packages.x86_64-linux;
|
artiqpkgs = artiq.packages.x86_64-linux;
|
||||||
zynqRev = self.sourceInfo.rev or "unknown";
|
|
||||||
|
|
||||||
rust = zynq-rs.rust;
|
rust = zynq-rs.rust;
|
||||||
rustPlatform = zynq-rs.rustPlatform;
|
rustPlatform = zynq-rs.rustPlatform;
|
||||||
@ -125,9 +124,7 @@
|
|||||||
lockFile = src/Cargo.lock;
|
lockFile = src/Cargo.lock;
|
||||||
outputHashes = {
|
outputHashes = {
|
||||||
"tar-no-std-0.1.8" = "sha256-xm17108v4smXOqxdLvHl9CxTCJslmeogjm4Y87IXFuM=";
|
"tar-no-std-0.1.8" = "sha256-xm17108v4smXOqxdLvHl9CxTCJslmeogjm4Y87IXFuM=";
|
||||||
"nalgebra-0.32.6" = "sha256-ZbQQZbM3A5cJ4QbujtUxkrI0/qGlI4UzfahtyQnvMZA=";
|
"fatfs-0.4.0" = "sha256-P7IgvhwTPXtNhcyv8cFqwO2UdaEcCGJY7UBG6+yBFSg=";
|
||||||
"core_io-0.1.0" = "sha256-0HINFWRiJx8pjMgUOL/CS336ih7SENSRh3Kah9LPRrw=";
|
|
||||||
"fatfs-0.3.6" = "sha256-Nz9hCq/1YgSXF8ltJ5ZawV0Hc8WV44KNK0tJdVnNb4U=";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -135,13 +132,12 @@
|
|||||||
pkgs.gnumake
|
pkgs.gnumake
|
||||||
(pkgs.python3.withPackages(ps: [ ps.jsonschema artiqpkgs.migen migen-axi artiqpkgs.misoc artiqpkgs.artiq ]))
|
(pkgs.python3.withPackages(ps: [ ps.jsonschema artiqpkgs.migen migen-axi artiqpkgs.misoc artiqpkgs.artiq ]))
|
||||||
zynqpkgs.cargo-xbuild
|
zynqpkgs.cargo-xbuild
|
||||||
pkgs.llvmPackages_13.llvm
|
pkgs.llvmPackages_18.llvm
|
||||||
pkgs.llvmPackages_13.clang-unwrapped
|
pkgs.llvmPackages_18.clang-unwrapped
|
||||||
];
|
];
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
export ZYNQ_REV=${zynqRev}
|
|
||||||
export XARGO_RUST_SRC="${rust}/lib/rustlib/src/rust/library"
|
export XARGO_RUST_SRC="${rust}/lib/rustlib/src/rust/library"
|
||||||
export CLANG_EXTRA_INCLUDE_DIR="${pkgs.llvmPackages_13.clang-unwrapped.lib}/lib/clang/13.0.1/include"
|
export CLANG_EXTRA_INCLUDE_DIR="${pkgs.llvmPackages_18.clang-unwrapped.lib}/lib/clang/18/include"
|
||||||
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
|
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
|
||||||
export ZYNQ_RS=${zynq-rs}
|
export ZYNQ_RS=${zynq-rs}
|
||||||
make TARGET=${target} GWARGS="${if json == null then "-V ${variant}" else json}" ${fwtype}
|
make TARGET=${target} GWARGS="${if json == null then "-V ${variant}" else json}" ${fwtype}
|
||||||
@ -167,7 +163,6 @@
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
export ZYNQ_REV=${zynqRev}
|
|
||||||
python ${./src/gateware}/${target}.py -g build ${if json == null then "-V ${variant}" else json}
|
python ${./src/gateware}/${target}.py -g build ${if json == null then "-V ${variant}" else json}
|
||||||
mkdir -p $out $out/nix-support
|
mkdir -p $out $out/nix-support
|
||||||
cp build/top.bit $out
|
cp build/top.bit $out
|
||||||
@ -376,8 +371,8 @@
|
|||||||
name = "artiq-zynq-dev-shell";
|
name = "artiq-zynq-dev-shell";
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
rust
|
rust
|
||||||
llvmPackages_13.llvm
|
llvmPackages_18.llvm
|
||||||
llvmPackages_13.clang-unwrapped
|
llvmPackages_18.clang-unwrapped
|
||||||
gnumake
|
gnumake
|
||||||
cacert
|
cacert
|
||||||
zynqpkgs.cargo-xbuild
|
zynqpkgs.cargo-xbuild
|
||||||
@ -390,9 +385,8 @@
|
|||||||
binutils-arm
|
binutils-arm
|
||||||
pre-commit
|
pre-commit
|
||||||
];
|
];
|
||||||
ZYNQ_REV="${zynqRev}";
|
|
||||||
XARGO_RUST_SRC = "${rust}/lib/rustlib/src/rust/library";
|
XARGO_RUST_SRC = "${rust}/lib/rustlib/src/rust/library";
|
||||||
CLANG_EXTRA_INCLUDE_DIR = "${pkgs.llvmPackages_13.clang-unwrapped.lib}/lib/clang/13.0.1/include";
|
CLANG_EXTRA_INCLUDE_DIR = "${pkgs.llvmPackages_18.clang-unwrapped.lib}/lib/clang/18/include";
|
||||||
ZYNQ_RS = "${zynq-rs}";
|
ZYNQ_RS = "${zynq-rs}";
|
||||||
OPENOCD_ZYNQ = "${zynq-rs}/openocd";
|
OPENOCD_ZYNQ = "${zynq-rs}/openocd";
|
||||||
SZL = "${zynqpkgs.szl}";
|
SZL = "${zynqpkgs.szl}";
|
||||||
|
51
src/Cargo.lock
generated
51
src/Cargo.lock
generated
@ -46,6 +46,12 @@ version = "1.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "build_const"
|
name = "build_const"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@ -58,9 +64,9 @@ version = "0.0.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.3.0"
|
version = "1.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60f0b0d4c0a382d2734228fd12b5a6b5dac185c60e938026fd31b265b94f9bd2"
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
@ -82,14 +88,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.49"
|
version = "0.1.109"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20b1438ef42c655665a8ab2c1c6d605a305f031d38d9be689ddfef41a20f3aa2"
|
checksum = "f11973008a8cf741fe6d22f339eba21fd0ca81e2760a769ba8243ed6c21edd7e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "core_io"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/rs-core_io.git?rev=e9d3edf027#e9d3edf0272502b0dd6c26e8a4869c2912657615"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc"
|
name = "crc"
|
||||||
@ -137,12 +138,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fatfs"
|
name = "fatfs"
|
||||||
version = "0.3.6"
|
version = "0.4.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/rust-fatfs.git?rev=4b5e420084#4b5e420084fd1c4a9c105680b687523909b6469c"
|
source = "git+https://github.com/rafalh/rust-fatfs?rev=85f06e0#85f06e08edbd3368e1b0562f2fc1b6d178bf7b8a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.6.0",
|
||||||
"byteorder",
|
|
||||||
"core_io",
|
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -224,7 +223,6 @@ name = "io"
|
|||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"core_io",
|
|
||||||
"libsupport_zynq",
|
"libsupport_zynq",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -234,7 +232,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"build_zynq",
|
"build_zynq",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"core_io",
|
|
||||||
"cslice",
|
"cslice",
|
||||||
"dwarf",
|
"dwarf",
|
||||||
"dyld",
|
"dyld",
|
||||||
@ -273,7 +270,6 @@ name = "libboard_artiq"
|
|||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"build_zynq",
|
"build_zynq",
|
||||||
"core_io",
|
|
||||||
"crc",
|
"crc",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"io",
|
"io",
|
||||||
@ -317,7 +313,6 @@ dependencies = [
|
|||||||
name = "libconfig"
|
name = "libconfig"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core_io",
|
|
||||||
"fatfs",
|
"fatfs",
|
||||||
"libboard_zynq",
|
"libboard_zynq",
|
||||||
"log",
|
"log",
|
||||||
@ -368,9 +363,9 @@ checksum = "822add9edb1860698b79522510da17bef885171f75aa395cff099d770c609c24"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.14"
|
version = "0.4.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
@ -389,8 +384,9 @@ checksum = "c75de51135344a4f8ed3cfe2720dc27736f7711989703a0b43aadf3753c55577"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nalgebra"
|
name = "nalgebra"
|
||||||
version = "0.32.6"
|
version = "0.33.2"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/nalgebra.git?rev=ad42410ab0#ad42410ab0abb014229e3ff6bc6ccd39ca92d5d1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"approx",
|
"approx",
|
||||||
"num-complex",
|
"num-complex",
|
||||||
@ -514,8 +510,6 @@ dependencies = [
|
|||||||
"async-recursion",
|
"async-recursion",
|
||||||
"build_zynq",
|
"build_zynq",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"core_io",
|
|
||||||
"crc",
|
|
||||||
"cslice",
|
"cslice",
|
||||||
"dwarf",
|
"dwarf",
|
||||||
"dyld",
|
"dyld",
|
||||||
@ -547,7 +541,6 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"build_zynq",
|
"build_zynq",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"core_io",
|
|
||||||
"crc",
|
"crc",
|
||||||
"cslice",
|
"cslice",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
@ -567,9 +560,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simba"
|
name = "simba"
|
||||||
version = "0.8.0"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50582927ed6f77e4ac020c057f37a268fc6aebc29225050365aacbb9deeeddc4"
|
checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"approx",
|
"approx",
|
||||||
"num-complex",
|
"num-complex",
|
||||||
@ -583,7 +576,7 @@ version = "0.7.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e4a069bef843d170df47e7c0a8bf8d037f217d9f5b325865acc3e466ffe40d3"
|
checksum = "3e4a069bef843d170df47e7c0a8bf8d037f217d9f5b325865acc3e466ffe40d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"managed",
|
"managed",
|
||||||
]
|
]
|
||||||
@ -605,7 +598,7 @@ version = "0.1.8"
|
|||||||
source = "git+https://git.m-labs.hk/M-Labs/tar-no-std?rev=2ab6dc5#2ab6dc58e5249c59c4eb03eaf3a119bcdd678d32"
|
source = "git+https://git.m-labs.hk/M-Labs/tar-no-std?rev=2ab6dc5#2ab6dc58e5249c59c4eb03eaf3a119bcdd678d32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
{
|
{
|
||||||
|
"abi-blacklist": [
|
||||||
|
"stdcall",
|
||||||
|
"fastcall",
|
||||||
|
"vectorcall",
|
||||||
|
"thiscall",
|
||||||
|
"win64",
|
||||||
|
"sysv64"
|
||||||
|
],
|
||||||
"arch": "arm",
|
"arch": "arm",
|
||||||
"data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
|
"data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
|
||||||
"emit-debug-gdb-scripts": false,
|
"emit-debug-gdb-scripts": false,
|
||||||
@ -13,6 +21,7 @@
|
|||||||
"os": "none",
|
"os": "none",
|
||||||
"panic-strategy": "abort",
|
"panic-strategy": "abort",
|
||||||
"requires-uwtable": true,
|
"requires-uwtable": true,
|
||||||
|
"force-unwind-tables": "yes",
|
||||||
"relocation-model": "static",
|
"relocation-model": "static",
|
||||||
"target-c-int-width": "32",
|
"target-c-int-width": "32",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
|
@ -1,15 +1,5 @@
|
|||||||
import os
|
|
||||||
from artiq._version import get_version
|
|
||||||
from misoc.integration import cpu_interface
|
from misoc.integration import cpu_interface
|
||||||
|
|
||||||
|
|
||||||
def generate_ident(variant):
|
|
||||||
return "{}+{};{}".format(
|
|
||||||
get_version().split(".")[0],
|
|
||||||
os.getenv("ZYNQ_REV", default="unknown")[:8],
|
|
||||||
variant,
|
|
||||||
)
|
|
||||||
|
|
||||||
def write_csr_file(soc, filename):
|
def write_csr_file(soc, filename):
|
||||||
with open(filename, "w") as f:
|
with open(filename, "w") as f:
|
||||||
f.write(cpu_interface.get_csr_rust(
|
f.write(cpu_interface.get_csr_rust(
|
||||||
|
@ -7,7 +7,7 @@ import dma
|
|||||||
from artiq.gateware import rtio
|
from artiq.gateware import rtio
|
||||||
from artiq.gateware.rtio.phy import spi2, ttl_simple
|
from artiq.gateware.rtio.phy import spi2, ttl_simple
|
||||||
from artiq.gateware.rtio.xilinx_clocking import fix_serdes_timing_path
|
from artiq.gateware.rtio.xilinx_clocking import fix_serdes_timing_path
|
||||||
from config import generate_ident, write_csr_file, write_mem_file, write_rustc_cfg_file
|
from config import write_csr_file, write_mem_file, write_rustc_cfg_file
|
||||||
from migen import *
|
from migen import *
|
||||||
from migen.build.generic_platform import IOStandard, Misc, Pins, Subsignal
|
from migen.build.generic_platform import IOStandard, Misc, Pins, Subsignal
|
||||||
from migen.build.platforms import ebaz4205
|
from migen.build.platforms import ebaz4205
|
||||||
@ -125,7 +125,7 @@ class EBAZ4205(SoCCore):
|
|||||||
"set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets gmii_tx_clk_IBUF]"
|
"set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets gmii_tx_clk_IBUF]"
|
||||||
)
|
)
|
||||||
|
|
||||||
ident = generate_ident(self.__class__.__name__)
|
ident = self.__class__.__name__
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
@ -24,10 +24,10 @@ from artiq.gateware.wrpll import wrpll
|
|||||||
|
|
||||||
import dma
|
import dma
|
||||||
import analyzer
|
import analyzer
|
||||||
import acpki as acpki_lib
|
import acpki
|
||||||
import drtio_aux_controller
|
import drtio_aux_controller
|
||||||
import zynq_clocking
|
import zynq_clocking
|
||||||
from config import generate_ident, write_csr_file, write_mem_file, write_rustc_cfg_file
|
from config import write_csr_file, write_mem_file, write_rustc_cfg_file
|
||||||
|
|
||||||
eem_iostandard_dict = {
|
eem_iostandard_dict = {
|
||||||
0: "LVDS_25",
|
0: "LVDS_25",
|
||||||
@ -115,7 +115,7 @@ class GenericStandalone(SoCCore):
|
|||||||
platform.toolchain.bitstream_commands.extend([
|
platform.toolchain.bitstream_commands.extend([
|
||||||
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
||||||
])
|
])
|
||||||
ident = generate_ident(description["variant"])
|
ident = description["variant"]
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
||||||
@ -184,10 +184,10 @@ class GenericStandalone(SoCCore):
|
|||||||
|
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
self.config["KI_IMPL"] = "acp"
|
self.config["KI_IMPL"] = "acp"
|
||||||
self.submodules.rtio = acpki_lib.KernelInitiator(self.rtio_tsc,
|
self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc,
|
||||||
bus=self.ps7.s_axi_acp,
|
bus=self.ps7.s_axi_acp,
|
||||||
user=self.ps7.s_axi_acp_user,
|
user=self.ps7.s_axi_acp_user,
|
||||||
evento=self.ps7.event.o)
|
evento=self.ps7.event.o)
|
||||||
self.csr_devices.append("rtio")
|
self.csr_devices.append("rtio")
|
||||||
else:
|
else:
|
||||||
self.config["KI_IMPL"] = "csr"
|
self.config["KI_IMPL"] = "csr"
|
||||||
@ -229,7 +229,7 @@ class GenericMaster(SoCCore):
|
|||||||
platform.toolchain.bitstream_commands.extend([
|
platform.toolchain.bitstream_commands.extend([
|
||||||
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
||||||
])
|
])
|
||||||
ident = generate_ident(description["variant"])
|
ident = description["variant"]
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
||||||
@ -349,10 +349,10 @@ class GenericMaster(SoCCore):
|
|||||||
|
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
self.config["KI_IMPL"] = "acp"
|
self.config["KI_IMPL"] = "acp"
|
||||||
self.submodules.rtio = acpki_lib.KernelInitiator(self.rtio_tsc,
|
self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc,
|
||||||
bus=self.ps7.s_axi_acp,
|
bus=self.ps7.s_axi_acp,
|
||||||
user=self.ps7.s_axi_acp_user,
|
user=self.ps7.s_axi_acp_user,
|
||||||
evento=self.ps7.event.o)
|
evento=self.ps7.event.o)
|
||||||
self.csr_devices.append("rtio")
|
self.csr_devices.append("rtio")
|
||||||
else:
|
else:
|
||||||
self.config["KI_IMPL"] = "csr"
|
self.config["KI_IMPL"] = "csr"
|
||||||
@ -438,7 +438,7 @@ class GenericSatellite(SoCCore):
|
|||||||
platform.toolchain.bitstream_commands.extend([
|
platform.toolchain.bitstream_commands.extend([
|
||||||
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
||||||
])
|
])
|
||||||
ident = generate_ident(description["variant"])
|
ident = description["variant"]
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
||||||
@ -544,10 +544,10 @@ class GenericSatellite(SoCCore):
|
|||||||
|
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
self.config["KI_IMPL"] = "acp"
|
self.config["KI_IMPL"] = "acp"
|
||||||
self.submodules.rtio = acpki_lib.KernelInitiator(self.rtio_tsc,
|
self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc,
|
||||||
bus=self.ps7.s_axi_acp,
|
bus=self.ps7.s_axi_acp,
|
||||||
user=self.ps7.s_axi_acp_user,
|
user=self.ps7.s_axi_acp_user,
|
||||||
evento=self.ps7.event.o)
|
evento=self.ps7.event.o)
|
||||||
self.csr_devices.append("rtio")
|
self.csr_devices.append("rtio")
|
||||||
else:
|
else:
|
||||||
self.config["KI_IMPL"] = "csr"
|
self.config["KI_IMPL"] = "csr"
|
||||||
|
@ -25,7 +25,7 @@ import analyzer
|
|||||||
import acpki
|
import acpki
|
||||||
import drtio_aux_controller
|
import drtio_aux_controller
|
||||||
import zynq_clocking
|
import zynq_clocking
|
||||||
from config import generate_ident, write_csr_file, write_mem_file, write_rustc_cfg_file
|
from config import write_csr_file, write_mem_file, write_rustc_cfg_file
|
||||||
|
|
||||||
class SMAClkinForward(Module):
|
class SMAClkinForward(Module):
|
||||||
def __init__(self, platform):
|
def __init__(self, platform):
|
||||||
@ -130,7 +130,7 @@ class ZC706(SoCCore):
|
|||||||
platform = zc706.Platform()
|
platform = zc706.Platform()
|
||||||
prepare_zc706_platform(platform)
|
prepare_zc706_platform(platform)
|
||||||
|
|
||||||
ident = generate_ident(self.__class__.__name__)
|
ident = self.__class__.__name__
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
||||||
@ -203,7 +203,7 @@ class _MasterBase(SoCCore):
|
|||||||
|
|
||||||
platform = zc706.Platform()
|
platform = zc706.Platform()
|
||||||
prepare_zc706_platform(platform)
|
prepare_zc706_platform(platform)
|
||||||
ident = generate_ident(self.__class__.__name__)
|
ident = self.__class__.__name__
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
||||||
@ -344,7 +344,7 @@ class _SatelliteBase(SoCCore):
|
|||||||
|
|
||||||
platform = zc706.Platform()
|
platform = zc706.Platform()
|
||||||
prepare_zc706_platform(platform)
|
prepare_zc706_platform(platform)
|
||||||
ident = generate_ident(self.__class__.__name__)
|
ident = self.__class__.__name__
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident, ps_cd_sys=False)
|
||||||
|
@ -20,7 +20,6 @@ build_zynq = { path = "../libbuild_zynq" }
|
|||||||
log = "0.4"
|
log = "0.4"
|
||||||
log_buffer = { version = "1.2" }
|
log_buffer = { version = "1.2" }
|
||||||
crc = { version = "1.7", default-features = false }
|
crc = { version = "1.7", default-features = false }
|
||||||
core_io = { git = "https://git.m-labs.hk/M-Labs/rs-core_io.git", rev = "e9d3edf027", features = ["collections"] }
|
|
||||||
embedded-hal = "0.2"
|
embedded-hal = "0.2"
|
||||||
nb = "1.0"
|
nb = "1.0"
|
||||||
void = { version = "1", default-features = false }
|
void = { version = "1", default-features = false }
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
use core::slice;
|
use core::slice;
|
||||||
|
|
||||||
use core_io::{Error as IoError, ErrorKind as IoErrorKind};
|
|
||||||
use crc;
|
use crc;
|
||||||
use io::{proto::{ProtoRead, ProtoWrite},
|
use io::{proto::{ProtoRead, ProtoWrite},
|
||||||
Cursor};
|
Cursor, Error as IoError};
|
||||||
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
|
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
|
||||||
|
|
||||||
pub use crate::drtioaux_proto::{Packet, MAX_PACKET};
|
pub use crate::drtioaux_proto::Packet;
|
||||||
use crate::{drtioaux_proto::Error as ProtocolError, mem::mem::DRTIOAUX_MEM, pl::csr::DRTIOAUX};
|
use crate::{drtioaux_proto::Error as ProtocolError, mem::mem::DRTIOAUX_MEM, pl::csr::DRTIOAUX};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error<T> {
|
||||||
GatewareError,
|
GatewareError,
|
||||||
CorruptedPacket,
|
CorruptedPacket,
|
||||||
|
|
||||||
@ -20,30 +19,21 @@ pub enum Error {
|
|||||||
|
|
||||||
RoutingError,
|
RoutingError,
|
||||||
|
|
||||||
Protocol(ProtocolError),
|
Protocol(ProtocolError<T>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ProtocolError> for Error {
|
impl<T> From<ProtocolError<T>> for Error<T> {
|
||||||
fn from(value: ProtocolError) -> Error {
|
fn from(value: ProtocolError<T>) -> Error<T> {
|
||||||
Error::Protocol(value)
|
Error::Protocol(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<IoError> for Error {
|
impl<T> From<IoError<T>> for Error<T> {
|
||||||
fn from(value: IoError) -> Error {
|
fn from(value: IoError<T>) -> Error<T> {
|
||||||
Error::Protocol(ProtocolError::Io(value))
|
Error::Protocol(ProtocolError::Io(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_work_buffer(src: *mut u32, dst: *mut u32, len: isize) {
|
|
||||||
// fix for artiq-zynq#344
|
|
||||||
unsafe {
|
|
||||||
for i in 0..(len / 4) {
|
|
||||||
*dst.offset(i) = *src.offset(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset(linkno: u8) {
|
pub fn reset(linkno: u8) {
|
||||||
let linkno = linkno as usize;
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -66,8 +56,8 @@ pub fn has_rx_error(linkno: u8) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error>
|
fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error<!>>
|
||||||
where F: FnOnce(&[u8]) -> Result<T, Error> {
|
where F: FnOnce(&[u8]) -> Result<T, Error<!>> {
|
||||||
let linkidx = linkno as usize;
|
let linkidx = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
||||||
@ -82,14 +72,14 @@ where F: FnOnce(&[u8]) -> Result<T, Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv(linkno: u8) -> Result<Option<Packet>, Error> {
|
pub fn recv(linkno: u8) -> Result<Option<Packet>, Error<!>> {
|
||||||
if has_rx_error(linkno) {
|
if has_rx_error(linkno) {
|
||||||
return Err(Error::GatewareError);
|
return Err(Error::GatewareError);
|
||||||
}
|
}
|
||||||
|
|
||||||
receive(linkno, |buffer| {
|
receive(linkno, |buffer| {
|
||||||
if buffer.len() < 8 {
|
if buffer.len() < 8 {
|
||||||
return Err(IoError::new(IoErrorKind::UnexpectedEof, "Unexpected end").into());
|
return Err(IoError::UnexpectedEnd.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut reader = Cursor::new(buffer);
|
let mut reader = Cursor::new(buffer);
|
||||||
@ -106,7 +96,7 @@ pub fn recv(linkno: u8) -> Result<Option<Packet>, Error> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) -> Result<Packet, Error> {
|
pub fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) -> Result<Packet, Error<!>> {
|
||||||
let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10));
|
let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10));
|
||||||
let limit = timer.get_time() + timeout_ms;
|
let limit = timer.get_time() + timeout_ms;
|
||||||
while timer.get_time() < limit {
|
while timer.get_time() < limit {
|
||||||
@ -118,22 +108,20 @@ pub fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) ->
|
|||||||
Err(Error::TimedOut)
|
Err(Error::TimedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transmit<F>(linkno: u8, f: F) -> Result<(), Error>
|
fn transmit<F>(linkno: u8, f: F) -> Result<(), Error<!>>
|
||||||
where F: FnOnce(&mut [u8]) -> Result<usize, Error> {
|
where F: FnOnce(&mut [u8]) -> Result<usize, Error<!>> {
|
||||||
let linkno = linkno as usize;
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
|
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
|
||||||
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
|
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
|
||||||
let mut buf: [u8; MAX_PACKET] = [0; MAX_PACKET];
|
let len = f(slice::from_raw_parts_mut(ptr as *mut u8, 0x400 as usize))?;
|
||||||
let len = f(&mut buf)?;
|
|
||||||
copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize);
|
|
||||||
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
||||||
(DRTIOAUX[linkno].aux_tx_write)(1);
|
(DRTIOAUX[linkno].aux_tx_write)(1);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(linkno: u8, packet: &Packet) -> Result<(), Error> {
|
pub fn send(linkno: u8, packet: &Packet) -> Result<(), Error<!>> {
|
||||||
transmit(linkno, |buffer| {
|
transmit(linkno, |buffer| {
|
||||||
let mut writer = Cursor::new(buffer);
|
let mut writer = Cursor::new(buffer);
|
||||||
|
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
use core::slice;
|
use core::slice;
|
||||||
|
|
||||||
use core_io::{Error as IoError, ErrorKind as IoErrorKind};
|
|
||||||
use crc;
|
use crc;
|
||||||
use io::{proto::{ProtoRead, ProtoWrite},
|
use io::{proto::{ProtoRead, ProtoWrite},
|
||||||
Cursor};
|
Cursor, Error as IoError};
|
||||||
use libasync::{block_async, task};
|
use libasync::{block_async, task};
|
||||||
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
|
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
|
||||||
use nb;
|
use nb;
|
||||||
use void::Void;
|
use void::Void;
|
||||||
|
|
||||||
pub use crate::drtioaux_proto::{Packet, MAX_PACKET};
|
pub use crate::drtioaux_proto::Packet;
|
||||||
use crate::{drtioaux::{copy_work_buffer, has_rx_error, Error},
|
use crate::{drtioaux::{has_rx_error, Error},
|
||||||
mem::mem::DRTIOAUX_MEM,
|
mem::mem::DRTIOAUX_MEM,
|
||||||
pl::csr::DRTIOAUX};
|
pl::csr::DRTIOAUX};
|
||||||
|
|
||||||
@ -35,8 +34,8 @@ fn tx_ready(linkno: usize) -> nb::Result<(), Void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error>
|
async fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error<!>>
|
||||||
where F: FnOnce(&[u8]) -> Result<T, Error> {
|
where F: FnOnce(&[u8]) -> Result<T, Error<!>> {
|
||||||
let linkidx = linkno as usize;
|
let linkidx = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
||||||
@ -51,14 +50,14 @@ where F: FnOnce(&[u8]) -> Result<T, Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recv(linkno: u8) -> Result<Option<Packet>, Error> {
|
pub async fn recv(linkno: u8) -> Result<Option<Packet>, Error<!>> {
|
||||||
if has_rx_error(linkno) {
|
if has_rx_error(linkno) {
|
||||||
return Err(Error::GatewareError);
|
return Err(Error::GatewareError);
|
||||||
}
|
}
|
||||||
|
|
||||||
receive(linkno, |buffer| {
|
receive(linkno, |buffer| {
|
||||||
if buffer.len() < 8 {
|
if buffer.len() < 8 {
|
||||||
return Err(IoError::new(IoErrorKind::UnexpectedEof, "Unexpected end").into());
|
return Err(IoError::UnexpectedEnd.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut reader = Cursor::new(buffer);
|
let mut reader = Cursor::new(buffer);
|
||||||
@ -76,7 +75,7 @@ pub async fn recv(linkno: u8) -> Result<Option<Packet>, Error> {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) -> Result<Packet, Error> {
|
pub async fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) -> Result<Packet, Error<!>> {
|
||||||
let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10));
|
let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10));
|
||||||
let limit = timer.get_time() + timeout_ms;
|
let limit = timer.get_time() + timeout_ms;
|
||||||
let mut would_block = false;
|
let mut would_block = false;
|
||||||
@ -96,22 +95,20 @@ pub async fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTime
|
|||||||
Err(Error::TimedOut)
|
Err(Error::TimedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn transmit<F>(linkno: u8, f: F) -> Result<(), Error>
|
async fn transmit<F>(linkno: u8, f: F) -> Result<(), Error<!>>
|
||||||
where F: FnOnce(&mut [u8]) -> Result<usize, Error> {
|
where F: FnOnce(&mut [u8]) -> Result<usize, Error<!>> {
|
||||||
let linkno = linkno as usize;
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
let _ = block_async!(tx_ready(linkno)).await;
|
let _ = block_async!(tx_ready(linkno)).await;
|
||||||
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
|
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
|
||||||
let mut buf: [u8; MAX_PACKET] = [0; MAX_PACKET];
|
let len = f(slice::from_raw_parts_mut(ptr as *mut u8, 0x400 as usize))?;
|
||||||
let len = f(&mut buf)?;
|
|
||||||
copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize);
|
|
||||||
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
||||||
(DRTIOAUX[linkno].aux_tx_write)(1);
|
(DRTIOAUX[linkno].aux_tx_write)(1);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(linkno: u8, packet: &Packet) -> Result<(), Error> {
|
pub async fn send(linkno: u8, packet: &Packet) -> Result<(), Error<!>> {
|
||||||
transmit(linkno, |buffer| {
|
transmit(linkno, |buffer| {
|
||||||
let mut writer = Cursor::new(buffer);
|
let mut writer = Cursor::new(buffer);
|
||||||
|
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
use core_io::{Error as IoError, Read, Write};
|
use io::{Error as IoError, Read, Write};
|
||||||
use io::proto::{ProtoRead, ProtoWrite};
|
use io::proto::{ProtoRead, ProtoWrite};
|
||||||
|
|
||||||
pub const MAX_PACKET: usize = 1024;
|
const MAX_PACKET: usize = 1024;
|
||||||
|
|
||||||
// maximum size of arbitrary payloads
|
// maximum size of arbitrary payloads
|
||||||
// used by satellite -> master analyzer, subkernel exceptions
|
// used by satellite -> master analyzer, subkernel exceptions
|
||||||
pub const SAT_PAYLOAD_MAX_SIZE: usize = /*max size*/
|
pub const SAT_PAYLOAD_MAX_SIZE: usize = /*max size*/MAX_PACKET - /*CRC*/4 - /*packet ID*/1 - /*last*/1 - /*length*/2;
|
||||||
MAX_PACKET - /*CRC*/4 - /*packet ID*/1 - /*last*/1 - /*length*/2;
|
|
||||||
// used by DDMA, subkernel program data (need to provide extra ID and destination)
|
// used by DDMA, subkernel program data (need to provide extra ID and destination)
|
||||||
pub const MASTER_PAYLOAD_MAX_SIZE: usize = SAT_PAYLOAD_MAX_SIZE - /*source*/1 - /*destination*/1 - /*ID*/4;
|
pub const MASTER_PAYLOAD_MAX_SIZE: usize = SAT_PAYLOAD_MAX_SIZE - /*source*/1 - /*destination*/1 - /*ID*/4;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error<T> {
|
||||||
UnknownPacket(u8),
|
UnknownPacket(u8),
|
||||||
Io(IoError),
|
Io(IoError<T>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<IoError> for Error {
|
impl<T> From<IoError<T>> for Error<T> {
|
||||||
fn from(value: IoError) -> Error {
|
fn from(value: IoError<T>) -> Error<T> {
|
||||||
Error::Io(value)
|
Error::Io(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,7 +362,7 @@ pub enum Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Packet {
|
impl Packet {
|
||||||
pub fn read_from<R>(reader: &mut R) -> Result<Self, Error>
|
pub fn read_from<R>(reader: &mut R) -> Result<Self, Error<R::ReadError>>
|
||||||
where R: Read + ?Sized {
|
where R: Read + ?Sized {
|
||||||
Ok(match reader.read_u8()? {
|
Ok(match reader.read_u8()? {
|
||||||
0x00 => Packet::EchoRequest,
|
0x00 => Packet::EchoRequest,
|
||||||
@ -750,7 +749,7 @@ impl Packet {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_to<W>(&self, writer: &mut W) -> Result<(), IoError>
|
pub fn write_to<W>(&self, writer: &mut W) -> Result<(), IoError<W::WriteError>>
|
||||||
where W: Write + ?Sized {
|
where W: Write + ?Sized {
|
||||||
match *self {
|
match *self {
|
||||||
Packet::EchoRequest => writer.write_u8(0x00)?,
|
Packet::EchoRequest => writer.write_u8(0x00)?,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use libboard_zynq::{println, stdio};
|
use libboard_zynq::{println, stdio};
|
||||||
use libcortex_a9::{interrupt_handler, regs::MPIDR};
|
use libcortex_a9::{interrupt_handler, regs::MPIDR};
|
||||||
|
use core::arch::asm;
|
||||||
use libregister::RegisterR;
|
use libregister::RegisterR;
|
||||||
|
|
||||||
#[cfg(has_si549)]
|
#[cfg(has_si549)]
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![feature(asm)]
|
#![allow(unexpected_cfgs)]
|
||||||
|
|
||||||
extern crate core_io;
|
|
||||||
extern crate crc;
|
extern crate crc;
|
||||||
extern crate embedded_hal;
|
extern crate embedded_hal;
|
||||||
extern crate io;
|
extern crate io;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![allow(unexpected_cfgs)]
|
||||||
|
|
||||||
use std::{env,
|
use std::{env,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{BufRead, BufReader, Write},
|
io::{BufRead, BufReader, Write},
|
||||||
|
@ -8,7 +8,6 @@ name = "io"
|
|||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
core_io = { git = "https://git.m-labs.hk/M-Labs/rs-core_io.git", rev = "e9d3edf027", features = ["collections"] }
|
|
||||||
byteorder = { version = "1.0", default-features = false, optional = true }
|
byteorder = { version = "1.0", default-features = false, optional = true }
|
||||||
|
|
||||||
libsupport_zynq = { path = "@@ZYNQ_RS@@/libsupport_zynq", default-features = false, features = ["alloc_core"] }
|
libsupport_zynq = { path = "@@ZYNQ_RS@@/libsupport_zynq", default-features = false, features = ["alloc_core"] }
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
|
||||||
use core_io::{Error as IoError, Read, Write};
|
use crate::{Read, Write};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Cursor<T> {
|
pub struct Cursor<T> {
|
||||||
@ -43,14 +44,16 @@ impl<T> Cursor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<[u8]>> Read for Cursor<T> {
|
impl<T: AsRef<[u8]>> Read for Cursor<T> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, IoError> {
|
type ReadError = !;
|
||||||
|
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::ReadError> {
|
||||||
let data = &self.inner.as_ref()[self.pos..];
|
let data = &self.inner.as_ref()[self.pos..];
|
||||||
let len = buf.len().min(data.len());
|
let len = buf.len().min(data.len());
|
||||||
// ``copy_from_slice`` generates AXI bursts, use a regular loop instead
|
// ``copy_from_slice`` generates AXI bursts, use a regular loop instead
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
unsafe {
|
// HACK: On opt-level=2 or above, LLVM 18 may insert memcpy calls as an optimization pass,
|
||||||
asm!("", options(preserves_flags, nostack, readonly));
|
// causing AXI bursts.
|
||||||
}
|
unsafe { asm!("", options(preserves_flags, nostack, readonly)); }
|
||||||
buf[i] = data[i];
|
buf[i] = data[i];
|
||||||
}
|
}
|
||||||
self.pos += len;
|
self.pos += len;
|
||||||
@ -59,13 +62,15 @@ impl<T: AsRef<[u8]>> Read for Cursor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Write for Cursor<&mut [u8]> {
|
impl Write for Cursor<&mut [u8]> {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
type WriteError = !;
|
||||||
|
type FlushError = !;
|
||||||
|
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::WriteError> {
|
||||||
let data = &mut self.inner[self.pos..];
|
let data = &mut self.inner[self.pos..];
|
||||||
let len = buf.len().min(data.len());
|
let len = buf.len().min(data.len());
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
unsafe {
|
// HACK: On opt-level=2 or above, this is too fast and sends corrupted packets.
|
||||||
asm!("", options(preserves_flags, nostack, readonly));
|
unsafe { asm!("", options(preserves_flags, nostack, readonly)); }
|
||||||
}
|
|
||||||
data[i] = buf[i];
|
data[i] = buf[i];
|
||||||
}
|
}
|
||||||
self.pos += len;
|
self.pos += len;
|
||||||
@ -73,20 +78,23 @@ impl Write for Cursor<&mut [u8]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> Result<(), IoError> {
|
fn flush(&mut self) -> Result<(), Self::FlushError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl Write for Cursor<Vec<u8>> {
|
impl Write for Cursor<Vec<u8>> {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
type WriteError = !;
|
||||||
|
type FlushError = !;
|
||||||
|
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::WriteError> {
|
||||||
self.inner.extend_from_slice(buf);
|
self.inner.extend_from_slice(buf);
|
||||||
Ok(buf.len())
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> Result<(), IoError> {
|
fn flush(&mut self) -> Result<(), Self::FlushError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
137
src/libio/lib.rs
137
src/libio/lib.rs
@ -1,10 +1,9 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(asm)]
|
#![allow(unexpected_cfgs)]
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate core_io;
|
|
||||||
|
|
||||||
#[cfg(feature = "byteorder")]
|
#[cfg(feature = "byteorder")]
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
@ -13,8 +12,142 @@ pub mod cursor;
|
|||||||
#[cfg(feature = "byteorder")]
|
#[cfg(feature = "byteorder")]
|
||||||
pub mod proto;
|
pub mod proto;
|
||||||
|
|
||||||
|
use core::fmt::{Display, Formatter};
|
||||||
|
|
||||||
pub use cursor::Cursor;
|
pub use cursor::Cursor;
|
||||||
#[cfg(all(feature = "byteorder", feature = "alloc"))]
|
#[cfg(all(feature = "byteorder", feature = "alloc"))]
|
||||||
pub use proto::ReadStringError;
|
pub use proto::ReadStringError;
|
||||||
#[cfg(feature = "byteorder")]
|
#[cfg(feature = "byteorder")]
|
||||||
pub use proto::{ProtoRead, ProtoWrite};
|
pub use proto::{ProtoRead, ProtoWrite};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum Error<T> {
|
||||||
|
UnexpectedEnd,
|
||||||
|
Other(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<T> for Error<T> {
|
||||||
|
fn from(value: T) -> Error<T> {
|
||||||
|
Error::Other(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Display> Display for Error<T> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
|
||||||
|
match self {
|
||||||
|
Error::UnexpectedEnd => write!(f, "unexpected end of stream"),
|
||||||
|
Error::Other(other) => write!(f, "other IO error: {}", other),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Read {
|
||||||
|
type ReadError;
|
||||||
|
|
||||||
|
/// Pull some bytes from this source into the specified buffer, returning
|
||||||
|
/// how many bytes were read.
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::ReadError>;
|
||||||
|
|
||||||
|
/// Read the exact number of bytes required to fill `buf`.
|
||||||
|
fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<(), Error<Self::ReadError>> {
|
||||||
|
while !buf.is_empty() {
|
||||||
|
let read_bytes = self.read(buf)?;
|
||||||
|
if read_bytes == 0 {
|
||||||
|
return Err(Error::UnexpectedEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = &mut { buf }[read_bytes..];
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Read> Read for &'a mut T {
|
||||||
|
type ReadError = T::ReadError;
|
||||||
|
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::ReadError> {
|
||||||
|
T::read(self, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Write {
|
||||||
|
type WriteError;
|
||||||
|
type FlushError;
|
||||||
|
|
||||||
|
/// Write a buffer into this object, returning how many bytes were written.
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::WriteError>;
|
||||||
|
|
||||||
|
/// Flush this output stream, ensuring that all intermediately buffered contents
|
||||||
|
/// reach their destination.
|
||||||
|
fn flush(&mut self) -> Result<(), Self::FlushError>;
|
||||||
|
|
||||||
|
/// Attempts to write an entire buffer into `self`.
|
||||||
|
fn write_all(&mut self, mut buf: &[u8]) -> Result<(), Error<Self::WriteError>> {
|
||||||
|
while buf.len() > 0 {
|
||||||
|
let written_bytes = self.write(buf)?;
|
||||||
|
if written_bytes == 0 {
|
||||||
|
return Err(Error::UnexpectedEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = &buf[written_bytes..];
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hints the writer how much bytes will be written after call to this function.
|
||||||
|
///
|
||||||
|
/// At least `min` bytes should be written after the call to this function and
|
||||||
|
/// if `max` is `Some(x)` than at most `x` bytes should be written.
|
||||||
|
fn size_hint(&mut self, _min: usize, _max: Option<usize>) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Write> Write for &'a mut T {
|
||||||
|
type WriteError = T::WriteError;
|
||||||
|
type FlushError = T::FlushError;
|
||||||
|
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::WriteError> {
|
||||||
|
T::write(self, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> Result<(), Self::FlushError> {
|
||||||
|
T::flush(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&mut self, min: usize, max: Option<usize>) {
|
||||||
|
T::size_hint(self, min, max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Write for &'a mut [u8] {
|
||||||
|
type WriteError = !;
|
||||||
|
type FlushError = !;
|
||||||
|
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::WriteError> {
|
||||||
|
let len = buf.len().min(self.len());
|
||||||
|
self[..len].copy_from_slice(&buf[..len]);
|
||||||
|
Ok(len)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn flush(&mut self) -> Result<(), Self::FlushError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
impl<'a> Write for alloc::vec::Vec<u8> {
|
||||||
|
type WriteError = !;
|
||||||
|
type FlushError = !;
|
||||||
|
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::WriteError> {
|
||||||
|
self.extend_from_slice(buf);
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn flush(&mut self) -> Result<(), Self::FlushError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,7 +3,9 @@ use alloc::{string::String, vec};
|
|||||||
use core::str::Utf8Error;
|
use core::str::Utf8Error;
|
||||||
|
|
||||||
use byteorder::{ByteOrder, NativeEndian};
|
use byteorder::{ByteOrder, NativeEndian};
|
||||||
use core_io::{Error as IoError, Read, Write};
|
use Error as IoError;
|
||||||
|
use Read;
|
||||||
|
use Write;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
@ -147,7 +149,7 @@ pub trait ProtoWrite {
|
|||||||
impl<T> ProtoRead for T
|
impl<T> ProtoRead for T
|
||||||
where T: Read + ?Sized
|
where T: Read + ?Sized
|
||||||
{
|
{
|
||||||
type ReadError = IoError;
|
type ReadError = IoError<T::ReadError>;
|
||||||
|
|
||||||
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::ReadError> {
|
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::ReadError> {
|
||||||
T::read_exact(self, buf)
|
T::read_exact(self, buf)
|
||||||
@ -157,7 +159,7 @@ where T: Read + ?Sized
|
|||||||
impl<T> ProtoWrite for T
|
impl<T> ProtoWrite for T
|
||||||
where T: Write + ?Sized
|
where T: Write + ?Sized
|
||||||
{
|
{
|
||||||
type WriteError = IoError;
|
type WriteError = IoError<T::WriteError>;
|
||||||
|
|
||||||
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::WriteError> {
|
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::WriteError> {
|
||||||
T::write_all(self, buf)
|
T::write_all(self, buf)
|
||||||
|
@ -12,12 +12,12 @@ build_zynq = { path = "../libbuild_zynq" }
|
|||||||
cslice = "0.3"
|
cslice = "0.3"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
nb = "0.1"
|
nb = "0.1"
|
||||||
core_io = { git = "https://git.m-labs.hk/M-Labs/rs-core_io.git", rev = "e9d3edf027", features = ["collections"] }
|
|
||||||
byteorder = { version = "1.3", default-features = false }
|
byteorder = { version = "1.3", default-features = false }
|
||||||
void = { version = "1", default-features = false }
|
void = { version = "1", default-features = false }
|
||||||
log_buffer = { version = "1.2" }
|
log_buffer = { version = "1.2" }
|
||||||
libm = { version = "0.2", features = ["unstable"] }
|
libm = { version = "0.2", features = ["unstable"] }
|
||||||
vcell = "0.1"
|
vcell = "0.1"
|
||||||
|
nalgebra = { version = "0.33.0", default-features = false, features = ["libm", "alloc"]}
|
||||||
|
|
||||||
libboard_zynq = { path = "@@ZYNQ_RS@@/libboard_zynq", features = ["ipv6"]}
|
libboard_zynq = { path = "@@ZYNQ_RS@@/libboard_zynq", features = ["ipv6"]}
|
||||||
libsupport_zynq = { path = "@@ZYNQ_RS@@/libsupport_zynq", default-features = false, features = ["alloc_core"] }
|
libsupport_zynq = { path = "@@ZYNQ_RS@@/libsupport_zynq", default-features = false, features = ["alloc_core"] }
|
||||||
@ -32,9 +32,3 @@ unwind = { path = "../libunwind" }
|
|||||||
libc = { path = "../libc" }
|
libc = { path = "../libc" }
|
||||||
io = { path = "../libio" }
|
io = { path = "../libio" }
|
||||||
libboard_artiq = { path = "../libboard_artiq" }
|
libboard_artiq = { path = "../libboard_artiq" }
|
||||||
|
|
||||||
[dependencies.nalgebra]
|
|
||||||
git = "https://git.m-labs.hk/M-Labs/nalgebra.git"
|
|
||||||
rev = "ad42410ab0"
|
|
||||||
default-features = false
|
|
||||||
features = ["libm", "alloc"]
|
|
||||||
|
@ -14,10 +14,9 @@
|
|||||||
|
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
use core_io::Error as ReadError;
|
|
||||||
use cslice::{AsCSlice, CSlice};
|
use cslice::{AsCSlice, CSlice};
|
||||||
use dwarf::eh::{self, EHAction, EHContext};
|
use dwarf::eh::{self, EHAction, EHContext};
|
||||||
use io::{Cursor, ProtoRead};
|
use io::{Cursor, Error as ReadError, ProtoRead, Read};
|
||||||
use libc::{c_int, c_void, uintptr_t};
|
use libc::{c_int, c_void, uintptr_t};
|
||||||
use log::{error, trace};
|
use log::{error, trace};
|
||||||
use unwind as uw;
|
use unwind as uw;
|
||||||
@ -96,36 +95,30 @@ struct ExceptionBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static mut EXCEPTION_BUFFER: ExceptionBuffer = ExceptionBuffer {
|
static mut EXCEPTION_BUFFER: ExceptionBuffer = ExceptionBuffer {
|
||||||
uw_exceptions: [const {
|
uw_exceptions: [ const { uw::_Unwind_Exception {
|
||||||
uw::_Unwind_Exception {
|
exception_class: EXCEPTION_CLASS,
|
||||||
exception_class: EXCEPTION_CLASS,
|
exception_cleanup: cleanup,
|
||||||
exception_cleanup: cleanup,
|
private: [0; uw::unwinder_private_data_size],
|
||||||
private: [0; uw::unwinder_private_data_size],
|
} }; MAX_INFLIGHT_EXCEPTIONS],
|
||||||
}
|
|
||||||
}; MAX_INFLIGHT_EXCEPTIONS],
|
|
||||||
exceptions: [None; MAX_INFLIGHT_EXCEPTIONS + 1],
|
exceptions: [None; MAX_INFLIGHT_EXCEPTIONS + 1],
|
||||||
exception_stack: [-1; MAX_INFLIGHT_EXCEPTIONS + 1],
|
exception_stack: [-1; MAX_INFLIGHT_EXCEPTIONS + 1],
|
||||||
backtrace: [(0, 0); MAX_BACKTRACE_SIZE],
|
backtrace: [(0, 0); MAX_BACKTRACE_SIZE],
|
||||||
backtrace_size: 0,
|
backtrace_size: 0,
|
||||||
stack_pointers: [const {
|
stack_pointers: [ const { StackPointerBacktrace {
|
||||||
StackPointerBacktrace {
|
stack_pointer: 0,
|
||||||
stack_pointer: 0,
|
initial_backtrace_size: 0,
|
||||||
initial_backtrace_size: 0,
|
current_backtrace_size: 0,
|
||||||
current_backtrace_size: 0,
|
} }; MAX_INFLIGHT_EXCEPTIONS + 1],
|
||||||
}
|
|
||||||
}; MAX_INFLIGHT_EXCEPTIONS + 1],
|
|
||||||
exception_count: 0,
|
exception_count: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub unsafe extern "C" fn reset_exception_buffer() {
|
pub unsafe extern "C" fn reset_exception_buffer() {
|
||||||
trace!("reset exception buffer");
|
trace!("reset exception buffer");
|
||||||
EXCEPTION_BUFFER.uw_exceptions = [const {
|
EXCEPTION_BUFFER.uw_exceptions = [ const { uw::_Unwind_Exception {
|
||||||
uw::_Unwind_Exception {
|
exception_class: EXCEPTION_CLASS,
|
||||||
exception_class: EXCEPTION_CLASS,
|
exception_cleanup: cleanup,
|
||||||
exception_cleanup: cleanup,
|
private: [0; uw::unwinder_private_data_size],
|
||||||
private: [0; uw::unwinder_private_data_size],
|
} }; MAX_INFLIGHT_EXCEPTIONS];
|
||||||
}
|
|
||||||
}; MAX_INFLIGHT_EXCEPTIONS];
|
|
||||||
EXCEPTION_BUFFER.exceptions = [None; MAX_INFLIGHT_EXCEPTIONS + 1];
|
EXCEPTION_BUFFER.exceptions = [None; MAX_INFLIGHT_EXCEPTIONS + 1];
|
||||||
EXCEPTION_BUFFER.exception_stack = [-1; MAX_INFLIGHT_EXCEPTIONS + 1];
|
EXCEPTION_BUFFER.exception_stack = [-1; MAX_INFLIGHT_EXCEPTIONS + 1];
|
||||||
EXCEPTION_BUFFER.backtrace_size = 0;
|
EXCEPTION_BUFFER.backtrace_size = 0;
|
||||||
@ -301,7 +294,9 @@ pub unsafe extern "C" fn raise(exception: *const Exception) -> ! {
|
|||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_exception_string<'a>(reader: &mut Cursor<&[u8]>) -> Result<CSlice<'a, u8>, ReadError> {
|
fn read_exception_string<'a, 'b>(
|
||||||
|
reader: &mut Cursor<&'b [u8]>,
|
||||||
|
) -> Result<CSlice<'a, u8>, ReadError<<Cursor<&'b [u8]> as Read>::ReadError>> {
|
||||||
let len = reader.read_u32()? as usize;
|
let len = reader.read_u32()? as usize;
|
||||||
if len == usize::MAX {
|
if len == usize::MAX {
|
||||||
let data = reader.read_u32()?;
|
let data = reader.read_u32()?;
|
||||||
@ -317,7 +312,7 @@ fn read_exception_string<'a>(reader: &mut Cursor<&[u8]>) -> Result<CSlice<'a, u8
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_exception(raw_exception: &[u8]) -> Result<Exception, ReadError> {
|
fn read_exception(raw_exception: &[u8]) -> Result<Exception, ReadError<<Cursor<&[u8]> as Read>::ReadError>> {
|
||||||
let mut reader = Cursor::new(raw_exception);
|
let mut reader = Cursor::new(raw_exception);
|
||||||
|
|
||||||
let mut byte = reader.read_u8()?;
|
let mut byte = reader.read_u8()?;
|
||||||
|
149
src/libksupport/src/eh_rust.rs
Normal file
149
src/libksupport/src/eh_rust.rs
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// This is the Rust personality function, adapted for use in ARTIQ. We never actually panic
|
||||||
|
// from Rust or recover from Rust exceptions (there's nothing to catch the panics), but we
|
||||||
|
// need a personality function to step back through Rust frames in order to make a backtrace.
|
||||||
|
//
|
||||||
|
// By design, this personality function is only ever called in the search phase, although
|
||||||
|
// to keep things simple and close to upstream, it is not modified
|
||||||
|
use unwind as uw;
|
||||||
|
use libc::c_int;
|
||||||
|
|
||||||
|
use dwarf::eh::{EHAction, EHContext};
|
||||||
|
|
||||||
|
// Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister()
|
||||||
|
// and TargetLowering::getExceptionSelectorRegister() for each architecture,
|
||||||
|
// then mapped to DWARF register numbers via register definition tables
|
||||||
|
// (typically <arch>RegisterInfo.td, search for "DwarfRegNum").
|
||||||
|
// See also http://llvm.org/docs/WritingAnLLVMBackend.html#defining-a-register.
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86")]
|
||||||
|
const UNWIND_DATA_REG: (i32, i32) = (0, 2); // EAX, EDX
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
const UNWIND_DATA_REG: (i32, i32) = (0, 1); // RAX, RDX
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "riscv32"))]
|
||||||
|
const UNWIND_DATA_REG: (i32, i32) = (10, 11); // X10, X11
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||||
|
const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 / X0, X1
|
||||||
|
|
||||||
|
// The following code is based on GCC's C and C++ personality routines. For reference, see:
|
||||||
|
// https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc
|
||||||
|
// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
|
||||||
|
#[lang = "eh_personality"]
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn rust_eh_personality(
|
||||||
|
state: uw::_Unwind_State,
|
||||||
|
exception_object: *mut uw::_Unwind_Exception,
|
||||||
|
context: *mut uw::_Unwind_Context,
|
||||||
|
) -> uw::_Unwind_Reason_Code {
|
||||||
|
let state = state as c_int;
|
||||||
|
let action = state & uw::_US_ACTION_MASK as c_int;
|
||||||
|
let search_phase = if action == uw::_US_VIRTUAL_UNWIND_FRAME as c_int {
|
||||||
|
// Backtraces on ARM will call the personality routine with
|
||||||
|
// state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
|
||||||
|
// we want to continue unwinding the stack, otherwise all our backtraces
|
||||||
|
// would end at __rust_try
|
||||||
|
if state & uw::_US_FORCE_UNWIND as c_int != 0 {
|
||||||
|
return continue_unwind(exception_object, context);
|
||||||
|
}
|
||||||
|
true
|
||||||
|
} else if action == uw::_US_UNWIND_FRAME_STARTING as c_int {
|
||||||
|
false
|
||||||
|
} else if action == uw::_US_UNWIND_FRAME_RESUME as c_int {
|
||||||
|
return continue_unwind(exception_object, context);
|
||||||
|
} else {
|
||||||
|
return uw::_URC_FAILURE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The DWARF unwinder assumes that _Unwind_Context holds things like the function
|
||||||
|
// and LSDA pointers, however ARM EHABI places them into the exception object.
|
||||||
|
// To preserve signatures of functions like _Unwind_GetLanguageSpecificData(), which
|
||||||
|
// take only the context pointer, GCC personality routines stash a pointer to
|
||||||
|
// exception_object in the context, using location reserved for ARM's
|
||||||
|
// "scratch register" (r12).
|
||||||
|
uw::_Unwind_SetGR(context, uw::UNWIND_POINTER_REG, exception_object as uw::_Unwind_Ptr);
|
||||||
|
// ...A more principled approach would be to provide the full definition of ARM's
|
||||||
|
// _Unwind_Context in our libunwind bindings and fetch the required data from there
|
||||||
|
// directly, bypassing DWARF compatibility functions.
|
||||||
|
|
||||||
|
let eh_action = match find_eh_action(context) {
|
||||||
|
Ok(action) => action,
|
||||||
|
Err(_) => return uw::_URC_FAILURE,
|
||||||
|
};
|
||||||
|
if search_phase {
|
||||||
|
match eh_action {
|
||||||
|
EHAction::None | EHAction::Cleanup(_) => {
|
||||||
|
return continue_unwind(exception_object, context);
|
||||||
|
}
|
||||||
|
EHAction::Catch(_) => {
|
||||||
|
// EHABI requires the personality routine to update the
|
||||||
|
// SP value in the barrier cache of the exception object.
|
||||||
|
(*exception_object).private[5] =
|
||||||
|
uw::_Unwind_GetGR(context, uw::UNWIND_SP_REG);
|
||||||
|
return uw::_URC_HANDLER_FOUND;
|
||||||
|
}
|
||||||
|
EHAction::Terminate => return uw::_URC_FAILURE,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match eh_action {
|
||||||
|
EHAction::None => return continue_unwind(exception_object, context),
|
||||||
|
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
|
||||||
|
uw::_Unwind_SetGR(
|
||||||
|
context,
|
||||||
|
UNWIND_DATA_REG.0,
|
||||||
|
exception_object as uw::_Unwind_Ptr,
|
||||||
|
);
|
||||||
|
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
|
||||||
|
uw::_Unwind_SetIP(context, lpad);
|
||||||
|
return uw::_URC_INSTALL_CONTEXT;
|
||||||
|
}
|
||||||
|
EHAction::Terminate => return uw::_URC_FAILURE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On ARM EHABI the personality routine is responsible for actually
|
||||||
|
// unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
|
||||||
|
unsafe fn continue_unwind(
|
||||||
|
exception_object: *mut uw::_Unwind_Exception,
|
||||||
|
context: *mut uw::_Unwind_Context,
|
||||||
|
) -> uw::_Unwind_Reason_Code {
|
||||||
|
if __gnu_unwind_frame(exception_object, context) == uw::_URC_NO_REASON {
|
||||||
|
uw::_URC_CONTINUE_UNWIND
|
||||||
|
} else {
|
||||||
|
uw::_URC_FAILURE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// defined in libgcc
|
||||||
|
extern "C" {
|
||||||
|
fn __gnu_unwind_frame(
|
||||||
|
exception_object: *mut uw::_Unwind_Exception,
|
||||||
|
context: *mut uw::_Unwind_Context,
|
||||||
|
) -> uw::_Unwind_Reason_Code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> Result<EHAction, ()> {
|
||||||
|
let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8;
|
||||||
|
let mut ip_before_instr: c_int = 0;
|
||||||
|
let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr);
|
||||||
|
let eh_context = EHContext {
|
||||||
|
// The return address points 1 byte past the call instruction,
|
||||||
|
// which could be in the next IP range in LSDA range table.
|
||||||
|
ip: if ip_before_instr != 0 { ip } else { ip - 1 },
|
||||||
|
func_start: uw::_Unwind_GetRegionStart(context),
|
||||||
|
get_text_start: &|| uw::_Unwind_GetTextRelBase(context),
|
||||||
|
get_data_start: &|| uw::_Unwind_GetDataRelBase(context),
|
||||||
|
};
|
||||||
|
dwarf::eh::find_eh_action(lsda, &eh_context, false,0)
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use core::arch::asm;
|
||||||
use libboard_zynq::{gic, mpcore, println, stdio};
|
use libboard_zynq::{gic, mpcore, println, stdio};
|
||||||
use libcortex_a9::{asm, interrupt_handler, notify_spin_lock, regs::MPIDR, spin_lock_yield};
|
use libcortex_a9::{asm, interrupt_handler, notify_spin_lock, regs::MPIDR, spin_lock_yield};
|
||||||
use libregister::RegisterR;
|
use libregister::RegisterR;
|
||||||
|
@ -25,12 +25,14 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn attribute_writeback(typeinfo: *const ()) {
|
unsafe fn attribute_writeback(typeinfo: *const ()) {
|
||||||
|
#[repr(C)]
|
||||||
struct Attr {
|
struct Attr {
|
||||||
offset: usize,
|
offset: usize,
|
||||||
tag: CSlice<'static, u8>,
|
tag: CSlice<'static, u8>,
|
||||||
name: CSlice<'static, u8>,
|
name: CSlice<'static, u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
struct Type {
|
struct Type {
|
||||||
attributes: *const *const Attr,
|
attributes: *const *const Attr,
|
||||||
objects: *const *const (),
|
objects: *const *const (),
|
||||||
|
@ -82,7 +82,7 @@ pub extern "C" fn dma_record_stop(duration: i64, enable_ddma: bool) {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn dma_record_output_prepare(timestamp: i64, target: i32, words: usize) {
|
unsafe fn dma_record_output_prepare(timestamp: i64, target: i32, words: usize) {
|
||||||
// See gateware/rtio/dma.py.
|
// See gateware/rtio/dma.py.
|
||||||
const HEADER_LENGTH: usize = /*length*/ 1 + /*channel*/3 + /*timestamp*/8 + /*address*/1;
|
const HEADER_LENGTH: usize = /*length*/1 + /*channel*/3 + /*timestamp*/8 + /*address*/1;
|
||||||
let length = HEADER_LENGTH + /*data*/words * 4;
|
let length = HEADER_LENGTH + /*data*/words * 4;
|
||||||
|
|
||||||
let buffer = &mut RECORDER.as_mut().unwrap().buffer;
|
let buffer = &mut RECORDER.as_mut().unwrap().buffer;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(c_variadic)]
|
#![feature(c_variadic)]
|
||||||
#![feature(const_btree_new)]
|
#![feature(lang_items)]
|
||||||
#![feature(inline_const)]
|
#![feature(const_btree_len)]
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![feature(asm)]
|
#![allow(unexpected_cfgs)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
@ -22,6 +22,7 @@ pub use pl::csr::rtio_core;
|
|||||||
use void::Void;
|
use void::Void;
|
||||||
|
|
||||||
pub mod eh_artiq;
|
pub mod eh_artiq;
|
||||||
|
pub mod eh_rust;
|
||||||
pub mod i2c;
|
pub mod i2c;
|
||||||
pub mod irq;
|
pub mod irq;
|
||||||
pub mod kernel;
|
pub mod kernel;
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use core::str;
|
use core::str;
|
||||||
|
|
||||||
use byteorder::{ByteOrder, NativeEndian};
|
use byteorder::{ByteOrder, NativeEndian};
|
||||||
use core_io::{Error, Read, Write};
|
|
||||||
use cslice::{CMutSlice, CSlice};
|
use cslice::{CMutSlice, CSlice};
|
||||||
use io::{ProtoRead, ProtoWrite};
|
use io::{Error, ProtoRead, ProtoWrite, Read, Write};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
|
||||||
use self::tag::{split_tag, Tag, TagIterator};
|
use self::tag::{split_tag, Tag, TagIterator};
|
||||||
@ -37,16 +36,17 @@ pub unsafe fn align_ptr_mut<T>(ptr: *mut ()) -> *mut T {
|
|||||||
|
|
||||||
// versions for reader rather than TcpStream
|
// versions for reader rather than TcpStream
|
||||||
// they will be made into sync for satellite subkernels later
|
// they will be made into sync for satellite subkernels later
|
||||||
unsafe fn recv_elements<F, R>(
|
unsafe fn recv_elements<F, R, E>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
elt_tag: Tag,
|
elt_tag: Tag,
|
||||||
length: usize,
|
length: usize,
|
||||||
storage: *mut (),
|
storage: *mut (),
|
||||||
alloc: &mut F,
|
alloc: &mut F,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), E>
|
||||||
where
|
where
|
||||||
F: FnMut(usize) -> *mut (),
|
F: FnMut(usize) -> Result<*mut (), E>,
|
||||||
R: Read + ?Sized,
|
R: Read + ?Sized,
|
||||||
|
E: From<Error<R::ReadError>>,
|
||||||
{
|
{
|
||||||
match elt_tag {
|
match elt_tag {
|
||||||
Tag::Bool => {
|
Tag::Bool => {
|
||||||
@ -57,7 +57,6 @@ where
|
|||||||
let ptr = storage as *mut u32;
|
let ptr = storage as *mut u32;
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 4);
|
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 4);
|
||||||
reader.read_exact(dest)?;
|
reader.read_exact(dest)?;
|
||||||
drop(dest);
|
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
||||||
NativeEndian::from_slice_u32(dest);
|
NativeEndian::from_slice_u32(dest);
|
||||||
}
|
}
|
||||||
@ -65,7 +64,6 @@ where
|
|||||||
let ptr = storage as *mut u64;
|
let ptr = storage as *mut u64;
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 8);
|
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 8);
|
||||||
reader.read_exact(dest)?;
|
reader.read_exact(dest)?;
|
||||||
drop(dest);
|
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
||||||
NativeEndian::from_slice_u64(dest);
|
NativeEndian::from_slice_u64(dest);
|
||||||
}
|
}
|
||||||
@ -79,10 +77,11 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn recv_value<F, R>(reader: &mut R, tag: Tag, data: &mut *mut (), alloc: &mut F) -> Result<(), Error>
|
unsafe fn recv_value<F, R, E>(reader: &mut R, tag: Tag, data: &mut *mut (), alloc: &mut F) -> Result<(), E>
|
||||||
where
|
where
|
||||||
F: FnMut(usize) -> *mut (),
|
F: FnMut(usize) -> Result<*mut (), E>,
|
||||||
R: Read + ?Sized,
|
R: Read + ?Sized,
|
||||||
|
E: From<Error<R::ReadError>>,
|
||||||
{
|
{
|
||||||
macro_rules! consume_value {
|
macro_rules! consume_value {
|
||||||
($ty:ty, | $ptr:ident | $map:expr) => {{
|
($ty:ty, | $ptr:ident | $map:expr) => {{
|
||||||
@ -109,7 +108,7 @@ where
|
|||||||
Tag::String | Tag::Bytes | Tag::ByteArray => {
|
Tag::String | Tag::Bytes | Tag::ByteArray => {
|
||||||
consume_value!(CMutSlice<u8>, |ptr| {
|
consume_value!(CMutSlice<u8>, |ptr| {
|
||||||
let length = reader.read_u32()? as usize;
|
let length = reader.read_u32()? as usize;
|
||||||
*ptr = CMutSlice::new(alloc(length) as *mut u8, length);
|
*ptr = CMutSlice::new(alloc(length)? as *mut u8, length);
|
||||||
reader.read_exact((*ptr).as_mut())?;
|
reader.read_exact((*ptr).as_mut())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@ -139,7 +138,7 @@ where
|
|||||||
let storage_offset = round_up(list_size, tag.alignment());
|
let storage_offset = round_up(list_size, tag.alignment());
|
||||||
let storage_size = tag.size() * length;
|
let storage_size = tag.size() * length;
|
||||||
|
|
||||||
let allocation = alloc(storage_offset + storage_size) as *mut u8;
|
let allocation = alloc(storage_offset + storage_size)? as *mut u8;
|
||||||
*ptr_to_list = allocation as *mut List;
|
*ptr_to_list = allocation as *mut List;
|
||||||
let storage = allocation.offset(storage_offset as isize) as *mut ();
|
let storage = allocation.offset(storage_offset as isize) as *mut ();
|
||||||
|
|
||||||
@ -158,7 +157,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let elt_tag = it.clone().next().expect("truncated tag");
|
let elt_tag = it.clone().next().expect("truncated tag");
|
||||||
*buffer = alloc(elt_tag.size() * total_len);
|
*buffer = alloc(elt_tag.size() * total_len)?;
|
||||||
recv_elements(reader, elt_tag, total_len, *buffer, alloc)
|
recv_elements(reader, elt_tag, total_len, *buffer, alloc)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -175,15 +174,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_return<'a, F, R>(
|
pub fn recv_return<'a, F, R, E>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
tag_bytes: &'a [u8],
|
tag_bytes: &'a [u8],
|
||||||
data: *mut (),
|
data: *mut (),
|
||||||
alloc: &mut F,
|
alloc: &mut F,
|
||||||
) -> Result<&'a [u8], Error>
|
) -> Result<&'a [u8], E>
|
||||||
where
|
where
|
||||||
F: FnMut(usize) -> *mut (),
|
F: FnMut(usize) -> Result<*mut (), E>,
|
||||||
R: Read + ?Sized,
|
R: Read + ?Sized,
|
||||||
|
E: From<Error<R::ReadError>>,
|
||||||
{
|
{
|
||||||
let mut it = TagIterator::new(tag_bytes);
|
let mut it = TagIterator::new(tag_bytes);
|
||||||
trace!("recv ...->{}", it);
|
trace!("recv ...->{}", it);
|
||||||
@ -201,7 +201,7 @@ unsafe fn send_elements<W>(
|
|||||||
length: usize,
|
length: usize,
|
||||||
data: *const (),
|
data: *const (),
|
||||||
write_tags: bool,
|
write_tags: bool,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error<W::WriteError>>
|
||||||
where
|
where
|
||||||
W: Write + ?Sized,
|
W: Write + ?Sized,
|
||||||
{
|
{
|
||||||
@ -233,8 +233,15 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn send_value<W>(writer: &mut W, tag: Tag, data: &mut *const (), write_tags: bool) -> Result<(), Error>
|
unsafe fn send_value<W>(
|
||||||
where W: Write + ?Sized {
|
writer: &mut W,
|
||||||
|
tag: Tag,
|
||||||
|
data: &mut *const (),
|
||||||
|
write_tags: bool,
|
||||||
|
) -> Result<(), Error<W::WriteError>>
|
||||||
|
where
|
||||||
|
W: Write + ?Sized,
|
||||||
|
{
|
||||||
macro_rules! consume_value {
|
macro_rules! consume_value {
|
||||||
($ty:ty, | $ptr:ident | $map:expr) => {{
|
($ty:ty, | $ptr:ident | $map:expr) => {{
|
||||||
let $ptr = align_ptr::<$ty>(*data);
|
let $ptr = align_ptr::<$ty>(*data);
|
||||||
@ -337,7 +344,7 @@ pub fn send_args<W>(
|
|||||||
tag_bytes: &[u8],
|
tag_bytes: &[u8],
|
||||||
data: *const *const (),
|
data: *const *const (),
|
||||||
write_tags: bool,
|
write_tags: bool,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error<W::WriteError>>
|
||||||
where
|
where
|
||||||
W: Write + ?Sized,
|
W: Write + ?Sized,
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(link_cfg)]
|
#![feature(link_cfg)]
|
||||||
#![feature(nll)]
|
|
||||||
#![feature(c_unwind)]
|
|
||||||
#![feature(static_nobundle)]
|
|
||||||
#![cfg_attr(not(target_env = "msvc"), feature(libc))]
|
#![cfg_attr(not(target_env = "msvc"), feature(libc))]
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
@ -17,17 +14,3 @@ cfg_if::cfg_if! {
|
|||||||
pub use backtrace::backtrace;
|
pub use backtrace::backtrace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_env = "musl")]
|
|
||||||
#[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))]
|
|
||||||
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
|
|
||||||
extern "C" {}
|
|
||||||
|
|
||||||
#[cfg(target_os = "redox")]
|
|
||||||
#[link(name = "gcc_eh", kind = "static-nobundle", cfg(target_feature = "crt-static"))]
|
|
||||||
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
|
|
||||||
extern "C" {}
|
|
||||||
|
|
||||||
#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
|
|
||||||
#[link(name = "unwind", kind = "static-nobundle")]
|
|
||||||
extern "C" {}
|
|
||||||
|
@ -20,7 +20,6 @@ num-derive = "0.3"
|
|||||||
cslice = "0.3"
|
cslice = "0.3"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
embedded-hal = "0.2"
|
embedded-hal = "0.2"
|
||||||
core_io = { git = "https://git.m-labs.hk/M-Labs/rs-core_io.git", rev = "e9d3edf027", features = ["collections"] }
|
|
||||||
crc = { version = "1.7", default-features = false }
|
crc = { version = "1.7", default-features = false }
|
||||||
byteorder = { version = "1.3", default-features = false }
|
byteorder = { version = "1.3", default-features = false }
|
||||||
void = { version = "1", default-features = false }
|
void = { version = "1", default-features = false }
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![allow(unexpected_cfgs)]
|
||||||
extern crate build_zynq;
|
extern crate build_zynq;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -1,20 +1,24 @@
|
|||||||
use alloc::{collections::BTreeMap, rc::Rc, string::String, vec, vec::Vec};
|
use alloc::{collections::BTreeMap, rc::Rc, string::String, vec, vec::Vec};
|
||||||
use core::{cell::RefCell, fmt, slice, str};
|
use core::{cell::RefCell, fmt, slice, str};
|
||||||
|
|
||||||
use core_io::Error as IoError;
|
|
||||||
use cslice::CSlice;
|
use cslice::CSlice;
|
||||||
use dyld::elf;
|
use dyld::elf;
|
||||||
use futures::{future::FutureExt, select_biased};
|
use futures::{future::FutureExt, select_biased};
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
use io::Cursor;
|
use io::Cursor;
|
||||||
|
use io::Error as IoError;
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
use ksupport::rpc;
|
use ksupport::rpc;
|
||||||
use ksupport::{kernel, resolve_channel_name};
|
use ksupport::{kernel, resolve_channel_name};
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
use libasync::delay;
|
||||||
use libasync::{smoltcp::{Sockets, TcpStream},
|
use libasync::{smoltcp::{Sockets, TcpStream},
|
||||||
task};
|
task};
|
||||||
use libboard_artiq::drtio_routing;
|
use libboard_artiq::drtio_routing;
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
use libboard_zynq::error_led::ErrorLED;
|
use libboard_zynq::error_led::ErrorLED;
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
use libboard_zynq::time::Milliseconds;
|
||||||
use libboard_zynq::{self as zynq,
|
use libboard_zynq::{self as zynq,
|
||||||
smoltcp::{self,
|
smoltcp::{self,
|
||||||
iface::{EthernetInterfaceBuilder, NeighborCache},
|
iface::{EthernetInterfaceBuilder, NeighborCache},
|
||||||
@ -74,8 +78,8 @@ impl From<smoltcp::Error> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<IoError> for Error {
|
impl<T> From<IoError<T>> for Error {
|
||||||
fn from(_error: IoError) -> Self {
|
fn from(_error: IoError<T>) -> Self {
|
||||||
Error::IoError
|
Error::IoError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -484,14 +488,14 @@ async fn handle_run_kernel(
|
|||||||
kernel::Message::RpcRecvRequest(slot) => slot,
|
kernel::Message::RpcRecvRequest(slot) => slot,
|
||||||
other => panic!("expected root value slot from core1, not {:?}", other),
|
other => panic!("expected root value slot from core1, not {:?}", other),
|
||||||
};
|
};
|
||||||
let remaining_tags = rpc::recv_return(&mut reader, ¤t_tags, slot, &mut |size| {
|
let remaining_tags = rpc::recv_return(&mut reader, ¤t_tags, slot, &mut |size| -> Result<*mut ()> {
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
0 as *mut ()
|
Ok(0 as *mut ())
|
||||||
} else {
|
} else {
|
||||||
let mut control = control.borrow_mut();
|
let mut control = control.borrow_mut();
|
||||||
control.tx.send(kernel::Message::RpcRecvReply(Ok(size)));
|
control.tx.send(kernel::Message::RpcRecvReply(Ok(size)));
|
||||||
match control.rx.recv() {
|
match control.rx.recv() {
|
||||||
kernel::Message::RpcRecvRequest(slot) => slot,
|
kernel::Message::RpcRecvRequest(slot) => Ok(slot),
|
||||||
other => {
|
other => {
|
||||||
panic!("expected nested value slot from kernel CPU, not {:?}", other)
|
panic!("expected nested value slot from kernel CPU, not {:?}", other)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![recursion_limit = "1024"] // for futures_util::select!
|
#![recursion_limit = "1024"] // for futures_util::select!
|
||||||
|
#![allow(unexpected_cfgs)]
|
||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
#![feature(const_btree_new)]
|
#![feature(const_btree_len)]
|
||||||
#![feature(panic_info_message)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
@ -22,7 +22,7 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
|
|||||||
} else {
|
} else {
|
||||||
print!("unknown location");
|
print!("unknown location");
|
||||||
}
|
}
|
||||||
if let Some(message) = info.message() {
|
if let Some(message) = info.message().as_str() {
|
||||||
println!(": {}", message);
|
println!(": {}", message);
|
||||||
} else {
|
} else {
|
||||||
println!("");
|
println!("");
|
||||||
@ -61,7 +61,7 @@ fn soft_panic(info: &core::panic::PanicInfo) -> ! {
|
|||||||
} else {
|
} else {
|
||||||
error!("panic at unknown location");
|
error!("panic at unknown location");
|
||||||
}
|
}
|
||||||
if let Some(message) = info.message() {
|
if let Some(message) = info.message().as_str() {
|
||||||
error!("panic message: {}", message);
|
error!("panic message: {}", message);
|
||||||
}
|
}
|
||||||
let timer = GlobalTimer::start();
|
let timer = GlobalTimer::start();
|
||||||
|
@ -63,8 +63,8 @@ pub mod drtio {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DrtioError> for Error {
|
impl<T> From<DrtioError<T>> for Error {
|
||||||
fn from(_error: DrtioError) -> Self {
|
fn from(_error: DrtioError<T>) -> Self {
|
||||||
Error::AuxError
|
Error::AuxError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -411,32 +411,29 @@ pub mod drtio {
|
|||||||
}
|
}
|
||||||
Ok(Packet::DestinationOkReply) => (),
|
Ok(Packet::DestinationOkReply) => (),
|
||||||
Ok(Packet::DestinationSequenceErrorReply { channel }) => {
|
Ok(Packet::DestinationSequenceErrorReply { channel }) => {
|
||||||
let global_ch = ((destination as u32) << 16) | channel as u32;
|
|
||||||
error!(
|
error!(
|
||||||
"[DEST#{}] RTIO sequence error involving channel 0x{:04x}:{}",
|
"[DEST#{}] RTIO sequence error involving channel 0x{:04x}:{}",
|
||||||
destination,
|
destination,
|
||||||
channel,
|
channel,
|
||||||
resolve_channel_name(global_ch)
|
resolve_channel_name(channel as u32)
|
||||||
);
|
);
|
||||||
unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_SEQUENCE_ERROR };
|
unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_SEQUENCE_ERROR };
|
||||||
}
|
}
|
||||||
Ok(Packet::DestinationCollisionReply { channel }) => {
|
Ok(Packet::DestinationCollisionReply { channel }) => {
|
||||||
let global_ch = ((destination as u32) << 16) | channel as u32;
|
|
||||||
error!(
|
error!(
|
||||||
"[DEST#{}] RTIO collision involving channel 0x{:04x}:{}",
|
"[DEST#{}] RTIO collision involving channel 0x{:04x}:{}",
|
||||||
destination,
|
destination,
|
||||||
channel,
|
channel,
|
||||||
resolve_channel_name(global_ch)
|
resolve_channel_name(channel as u32)
|
||||||
);
|
);
|
||||||
unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_COLLISION };
|
unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_COLLISION };
|
||||||
}
|
}
|
||||||
Ok(Packet::DestinationBusyReply { channel }) => {
|
Ok(Packet::DestinationBusyReply { channel }) => {
|
||||||
let global_ch = ((destination as u32) << 16) | channel as u32;
|
|
||||||
error!(
|
error!(
|
||||||
"[DEST#{}] RTIO busy error involving channel 0x{:04x}:{}",
|
"[DEST#{}] RTIO busy error involving channel 0x{:04x}:{}",
|
||||||
destination,
|
destination,
|
||||||
channel,
|
channel,
|
||||||
resolve_channel_name(global_ch)
|
resolve_channel_name(channel as u32)
|
||||||
);
|
);
|
||||||
unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_BUSY };
|
unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_BUSY };
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ use_field_init_shorthand = false
|
|||||||
force_explicit_abi = true
|
force_explicit_abi = true
|
||||||
condense_wildcard_suffixes = false
|
condense_wildcard_suffixes = false
|
||||||
color = "Auto"
|
color = "Auto"
|
||||||
required_version = "1.4.37"
|
required_version = "1.4.32"
|
||||||
unstable_features = false
|
unstable_features = false
|
||||||
disable_all_formatting = false
|
disable_all_formatting = false
|
||||||
skip_children = false
|
skip_children = false
|
||||||
|
@ -16,7 +16,6 @@ build_zynq = { path = "../libbuild_zynq" }
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
log = { version = "0.4", default-features = false }
|
log = { version = "0.4", default-features = false }
|
||||||
byteorder = { version = "1.3", default-features = false }
|
byteorder = { version = "1.3", default-features = false }
|
||||||
core_io = { git = "https://git.m-labs.hk/M-Labs/rs-core_io.git", rev = "e9d3edf027", features = ["collections"] }
|
|
||||||
crc = { version = "1.7", default-features = false }
|
crc = { version = "1.7", default-features = false }
|
||||||
cslice = "0.3"
|
cslice = "0.3"
|
||||||
embedded-hal = "0.2"
|
embedded-hal = "0.2"
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(alloc_error_handler, never_type, panic_info_message)]
|
#![feature(alloc_error_handler, never_type)]
|
||||||
|
#![allow(unexpected_cfgs)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate core_io;
|
|
||||||
extern crate crc;
|
extern crate crc;
|
||||||
extern crate cslice;
|
extern crate cslice;
|
||||||
extern crate embedded_hal;
|
extern crate embedded_hal;
|
||||||
@ -155,7 +155,7 @@ fn process_aux_packet(
|
|||||||
kernel_manager: &mut KernelManager,
|
kernel_manager: &mut KernelManager,
|
||||||
core_manager: &mut CoreManager,
|
core_manager: &mut CoreManager,
|
||||||
router: &mut Router,
|
router: &mut Router,
|
||||||
) -> Result<(), drtioaux::Error> {
|
) -> Result<(), drtioaux::Error<!>> {
|
||||||
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
||||||
// and u16 otherwise; hence the `as _` conversion.
|
// and u16 otherwise; hence the `as _` conversion.
|
||||||
match packet {
|
match packet {
|
||||||
@ -1797,7 +1797,7 @@ pub fn panic_fmt(info: &core::panic::PanicInfo) -> ! {
|
|||||||
} else {
|
} else {
|
||||||
print!("unknown location");
|
print!("unknown location");
|
||||||
}
|
}
|
||||||
if let Some(message) = info.message() {
|
if let Some(message) = info.message().as_str() {
|
||||||
println!(": {}", message);
|
println!(": {}", message);
|
||||||
} else {
|
} else {
|
||||||
println!("");
|
println!("");
|
||||||
|
@ -191,7 +191,7 @@ impl Repeater {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv_aux_timeout(&self, timeout: u32, timer: &mut GlobalTimer) -> Result<drtioaux::Packet, drtioaux::Error> {
|
fn recv_aux_timeout(&self, timeout: u32, timer: &mut GlobalTimer) -> Result<drtioaux::Packet, drtioaux::Error<!>> {
|
||||||
let max_time = timer.get_time() + Milliseconds(timeout.into());
|
let max_time = timer.get_time() + Milliseconds(timeout.into());
|
||||||
loop {
|
loop {
|
||||||
if !rep_link_rx_up(self.repno) {
|
if !rep_link_rx_up(self.repno) {
|
||||||
@ -216,7 +216,7 @@ impl Repeater {
|
|||||||
rank: u8,
|
rank: u8,
|
||||||
self_destination: u8,
|
self_destination: u8,
|
||||||
timer: &mut GlobalTimer,
|
timer: &mut GlobalTimer,
|
||||||
) -> Result<(), drtioaux::Error> {
|
) -> Result<(), drtioaux::Error<!>> {
|
||||||
self.aux_send(request)?;
|
self.aux_send(request)?;
|
||||||
loop {
|
loop {
|
||||||
let reply = self.recv_aux_timeout(200, timer)?;
|
let reply = self.recv_aux_timeout(200, timer)?;
|
||||||
@ -242,14 +242,14 @@ impl Repeater {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aux_send(&self, request: &drtioaux::Packet) -> Result<(), drtioaux::Error> {
|
pub fn aux_send(&self, request: &drtioaux::Packet) -> Result<(), drtioaux::Error<!>> {
|
||||||
if self.state != RepeaterState::Up {
|
if self.state != RepeaterState::Up {
|
||||||
return Err(drtioaux::Error::LinkDown);
|
return Err(drtioaux::Error::LinkDown);
|
||||||
}
|
}
|
||||||
drtioaux::send(self.auxno, request)
|
drtioaux::send(self.auxno, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_tsc(&self, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
pub fn sync_tsc(&self, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
||||||
if self.state != RepeaterState::Up {
|
if self.state != RepeaterState::Up {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -275,7 +275,7 @@ impl Repeater {
|
|||||||
destination: u8,
|
destination: u8,
|
||||||
hops: &[u8; drtio_routing::MAX_HOPS],
|
hops: &[u8; drtio_routing::MAX_HOPS],
|
||||||
timer: &mut GlobalTimer,
|
timer: &mut GlobalTimer,
|
||||||
) -> Result<(), drtioaux::Error> {
|
) -> Result<(), drtioaux::Error<!>> {
|
||||||
if self.state != RepeaterState::Up {
|
if self.state != RepeaterState::Up {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -299,14 +299,14 @@ impl Repeater {
|
|||||||
&self,
|
&self,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
timer: &mut GlobalTimer,
|
timer: &mut GlobalTimer,
|
||||||
) -> Result<(), drtioaux::Error> {
|
) -> Result<(), drtioaux::Error<!>> {
|
||||||
for i in 0..drtio_routing::DEST_COUNT {
|
for i in 0..drtio_routing::DEST_COUNT {
|
||||||
self.set_path(i as u8, &routing_table.0[i], timer)?;
|
self.set_path(i as u8, &routing_table.0[i], timer)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_rank(&self, rank: u8, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
pub fn set_rank(&self, rank: u8, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
||||||
if self.state != RepeaterState::Up {
|
if self.state != RepeaterState::Up {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -318,7 +318,7 @@ impl Repeater {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rtio_reset(&self, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
pub fn rtio_reset(&self, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
||||||
let repno = self.repno as usize;
|
let repno = self.repno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
(csr::DRTIOREP[repno].reset_write)(1);
|
(csr::DRTIOREP[repno].reset_write)(1);
|
||||||
@ -361,11 +361,11 @@ impl Repeater {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_tsc(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
pub fn sync_tsc(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rtio_reset(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
pub fn rtio_reset(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ impl Router {
|
|||||||
_routing_table: &drtio_routing::RoutingTable,
|
_routing_table: &drtio_routing::RoutingTable,
|
||||||
_rank: u8,
|
_rank: u8,
|
||||||
_destination: u8,
|
_destination: u8,
|
||||||
) -> Result<(), drtioaux::Error> {
|
) -> Result<(), drtioaux::Error<!>> {
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
{
|
{
|
||||||
let destination = packet.routable_destination();
|
let destination = packet.routable_destination();
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
use alloc::{collections::BTreeMap,
|
use alloc::{
|
||||||
format,
|
collections::BTreeMap,
|
||||||
string::{String, ToString},
|
format,
|
||||||
vec::Vec};
|
string::{String, ToString},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
use core::{slice, str};
|
use core::{slice, str};
|
||||||
|
|
||||||
use core_io::{Error as IoError, Write};
|
|
||||||
use cslice::AsCSlice;
|
use cslice::AsCSlice;
|
||||||
use dma::{Error as DmaError, Manager as DmaManager};
|
use dma::{Error as DmaError, Manager as DmaManager};
|
||||||
use io::{Cursor, ProtoWrite};
|
use io::{Cursor, Error as IoError, ProtoWrite, Write};
|
||||||
use ksupport::{eh_artiq, kernel, rpc, rtio};
|
use ksupport::{eh_artiq, kernel, rpc, rtio};
|
||||||
use libboard_artiq::{drtio_routing::RoutingTable,
|
use libboard_artiq::{
|
||||||
drtioaux,
|
drtio_routing::RoutingTable,
|
||||||
drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE},
|
drtioaux,
|
||||||
pl::csr};
|
drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE},
|
||||||
|
pl::csr,
|
||||||
|
};
|
||||||
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
|
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
|
||||||
use libcortex_a9::sync_channel::Receiver;
|
use libcortex_a9::sync_channel::Receiver;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
@ -52,6 +55,7 @@ enum KernelState {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Load(String),
|
Load(String),
|
||||||
@ -65,8 +69,8 @@ pub enum Error {
|
|||||||
DmaError(DmaError),
|
DmaError(DmaError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<IoError> for Error {
|
impl<T> From<IoError<T>> for Error {
|
||||||
fn from(_value: IoError) -> Error {
|
fn from(_value: IoError<T>) -> Error {
|
||||||
Error::SubkernelIoError
|
Error::SubkernelIoError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,8 +87,8 @@ impl From<()> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<drtioaux::Error> for Error {
|
impl<T> From<drtioaux::Error<T>> for Error {
|
||||||
fn from(_value: drtioaux::Error) -> Error {
|
fn from(_value: drtioaux::Error<T>) -> Error {
|
||||||
Error::DrtioError
|
Error::DrtioError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,7 +124,7 @@ struct MessageManager {
|
|||||||
struct Session {
|
struct Session {
|
||||||
id: u32,
|
id: u32,
|
||||||
kernel_state: KernelState,
|
kernel_state: KernelState,
|
||||||
last_exception: Option<Sliceable>, // exceptions raised locally
|
last_exception: Option<Sliceable>, // exceptions raised locally
|
||||||
external_exception: Option<Vec<u8>>, // exceptions from sub-subkernels
|
external_exception: Option<Vec<u8>>, // exceptions from sub-subkernels
|
||||||
messages: MessageManager,
|
messages: MessageManager,
|
||||||
source: u8, // which destination requested running the kernel
|
source: u8, // which destination requested running the kernel
|
||||||
@ -216,7 +220,10 @@ impl MessageManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_outgoing_slice(&mut self, data_slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE]) -> Option<SliceMeta> {
|
pub fn get_outgoing_slice(
|
||||||
|
&mut self,
|
||||||
|
data_slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE],
|
||||||
|
) -> Option<SliceMeta> {
|
||||||
if self.out_state != OutMessageState::MessageBeingSent {
|
if self.out_state != OutMessageState::MessageBeingSent {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -297,7 +304,13 @@ impl<'a> Manager<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, id: u32, status: PayloadStatus, data: &[u8], data_len: usize) -> Result<(), Error> {
|
pub fn add(
|
||||||
|
&mut self,
|
||||||
|
id: u32,
|
||||||
|
status: PayloadStatus,
|
||||||
|
data: &[u8],
|
||||||
|
data_len: usize,
|
||||||
|
) -> Result<(), Error> {
|
||||||
let kernel = match self.kernels.get_mut(&id) {
|
let kernel = match self.kernels.get_mut(&id) {
|
||||||
Some(kernel) => {
|
Some(kernel) => {
|
||||||
if kernel.complete || status.is_first() {
|
if kernel.complete || status.is_first() {
|
||||||
@ -310,7 +323,7 @@ impl<'a> Manager<'_> {
|
|||||||
complete: false,
|
complete: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.kernels.get_mut(&id).ok_or_else(|| Error::KernelNotFound)?
|
self.kernels.get_mut(&id).ok_or(Error::KernelNotFound)?
|
||||||
} else {
|
} else {
|
||||||
kernel
|
kernel
|
||||||
}
|
}
|
||||||
@ -323,7 +336,7 @@ impl<'a> Manager<'_> {
|
|||||||
complete: false,
|
complete: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.kernels.get_mut(&id).ok_or_else(|| Error::KernelNotFound)?
|
self.kernels.get_mut(&id).ok_or(Error::KernelNotFound)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
kernel.library.extend(&data[0..data_len]);
|
kernel.library.extend(&data[0..data_len]);
|
||||||
@ -368,10 +381,15 @@ impl<'a> Manager<'_> {
|
|||||||
if !self.running() {
|
if !self.running() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.session.messages.handle_incoming(status, id, length, slice);
|
self.session
|
||||||
|
.messages
|
||||||
|
.handle_incoming(status, id, length, slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message_get_slice(&mut self, slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE]) -> Option<SliceMeta> {
|
pub fn message_get_slice(
|
||||||
|
&mut self,
|
||||||
|
slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE],
|
||||||
|
) -> Option<SliceMeta> {
|
||||||
if !self.running() {
|
if !self.running() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -390,7 +408,7 @@ impl<'a> Manager<'_> {
|
|||||||
if self.session.id == id && self.session.kernel_state == KernelState::Loaded {
|
if self.session.id == id && self.session.kernel_state == KernelState::Loaded {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if !self.kernels.get(&id).ok_or_else(|| Error::KernelNotFound)?.complete {
|
if !self.kernels.get(&id).ok_or(Error::KernelNotFound)?.complete {
|
||||||
return Err(Error::KernelNotFound);
|
return Err(Error::KernelNotFound);
|
||||||
}
|
}
|
||||||
self.session = Session::new(id);
|
self.session = Session::new(id);
|
||||||
@ -399,7 +417,7 @@ impl<'a> Manager<'_> {
|
|||||||
self.control.tx.send(kernel::Message::LoadRequest(
|
self.control.tx.send(kernel::Message::LoadRequest(
|
||||||
self.kernels
|
self.kernels
|
||||||
.get(&id)
|
.get(&id)
|
||||||
.ok_or_else(|| Error::KernelNotFound)?
|
.ok_or(Error::KernelNotFound)?
|
||||||
.library
|
.library
|
||||||
.clone(),
|
.clone(),
|
||||||
));
|
));
|
||||||
@ -414,7 +432,10 @@ impl<'a> Manager<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exception_get_slice(&mut self, data_slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE]) -> SliceMeta {
|
pub fn exception_get_slice(
|
||||||
|
&mut self,
|
||||||
|
data_slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE],
|
||||||
|
) -> SliceMeta {
|
||||||
match self.session.last_exception.as_mut() {
|
match self.session.last_exception.as_mut() {
|
||||||
Some(exception) => exception.get_slice_master(data_slice),
|
Some(exception) => exception.get_slice_master(data_slice),
|
||||||
None => SliceMeta {
|
None => SliceMeta {
|
||||||
@ -568,7 +589,14 @@ impl<'a> Manager<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.process_kern_message(router, routing_table, rank, destination, dma_manager, timer) {
|
match self.process_kern_message(
|
||||||
|
router,
|
||||||
|
routing_table,
|
||||||
|
rank,
|
||||||
|
destination,
|
||||||
|
dma_manager,
|
||||||
|
timer,
|
||||||
|
) {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
self.last_finished = Some(SubkernelFinished {
|
self.last_finished = Some(SubkernelFinished {
|
||||||
id: self.session.id,
|
id: self.session.id,
|
||||||
@ -611,7 +639,9 @@ impl<'a> Manager<'_> {
|
|||||||
for (i, (status, exception_source)) in self.session.subkernels_finished.iter().enumerate() {
|
for (i, (status, exception_source)) in self.session.subkernels_finished.iter().enumerate() {
|
||||||
if *status == id {
|
if *status == id {
|
||||||
if exception_source.is_none() {
|
if exception_source.is_none() {
|
||||||
self.control.tx.send(kernel::Message::SubkernelAwaitFinishReply);
|
self.control
|
||||||
|
.tx
|
||||||
|
.send(kernel::Message::SubkernelAwaitFinishReply);
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
self.session.subkernels_finished.swap_remove(i);
|
self.session.subkernels_finished.swap_remove(i);
|
||||||
} else {
|
} else {
|
||||||
@ -639,15 +669,26 @@ impl<'a> Manager<'_> {
|
|||||||
if self.session.kernel_state == KernelState::SubkernelAwaitLoad {
|
if self.session.kernel_state == KernelState::SubkernelAwaitLoad {
|
||||||
self.control
|
self.control
|
||||||
.tx
|
.tx
|
||||||
.send(kernel::Message::SubkernelLoadRunReply { succeeded: succeeded });
|
.send(kernel::Message::SubkernelLoadRunReply {
|
||||||
|
succeeded: succeeded,
|
||||||
|
});
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
} else {
|
} else {
|
||||||
warn!("received unsolicited SubkernelLoadRunReply");
|
warn!("received unsolicited SubkernelLoadRunReply");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remote_subkernel_finished(&mut self, id: u32, with_exception: bool, exception_source: u8) {
|
pub fn remote_subkernel_finished(
|
||||||
let exception_src = if with_exception { Some(exception_source) } else { None };
|
&mut self,
|
||||||
|
id: u32,
|
||||||
|
with_exception: bool,
|
||||||
|
exception_source: u8,
|
||||||
|
) {
|
||||||
|
let exception_src = if with_exception {
|
||||||
|
Some(exception_source)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
self.session.subkernels_finished.push((id, exception_src));
|
self.session.subkernels_finished.push((id, exception_src));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,18 +701,19 @@ impl<'a> Manager<'_> {
|
|||||||
rank: u8,
|
rank: u8,
|
||||||
self_destination: u8,
|
self_destination: u8,
|
||||||
) {
|
) {
|
||||||
if let KernelState::SubkernelRetrievingException { destination } = self.session.kernel_state {
|
if let KernelState::SubkernelRetrievingException { destination } = self.session.kernel_state
|
||||||
|
{
|
||||||
self.session
|
self.session
|
||||||
.external_exception
|
.external_exception
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.extend_from_slice(exception_data);
|
.extend_from_slice(exception_data);
|
||||||
if last {
|
if last {
|
||||||
self.control
|
self.control.tx.send(kernel::Message::SubkernelError(
|
||||||
.tx
|
kernel::SubkernelStatus::Exception(
|
||||||
.send(kernel::Message::SubkernelError(kernel::SubkernelStatus::Exception(
|
|
||||||
self.session.external_exception.take().unwrap(),
|
self.session.external_exception.take().unwrap(),
|
||||||
)));
|
),
|
||||||
|
));
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
} else {
|
} else {
|
||||||
/* fetch another slice */
|
/* fetch another slice */
|
||||||
@ -706,7 +748,12 @@ impl<'a> Manager<'_> {
|
|||||||
dma_manager.cleanup(router, rank, self_destination, routing_table);
|
dma_manager.cleanup(router, rank, self_destination, routing_table);
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
kernel::Message::KernelException(exceptions, stack_pointers, backtrace, async_errors) => {
|
kernel::Message::KernelException(
|
||||||
|
exceptions,
|
||||||
|
stack_pointers,
|
||||||
|
backtrace,
|
||||||
|
async_errors,
|
||||||
|
) => {
|
||||||
error!("exception in kernel");
|
error!("exception in kernel");
|
||||||
for exception in exceptions {
|
for exception in exceptions {
|
||||||
error!("{:?}", exception.unwrap());
|
error!("{:?}", exception.unwrap());
|
||||||
@ -715,12 +762,21 @@ impl<'a> Manager<'_> {
|
|||||||
error!("backtrace: {:?}", backtrace);
|
error!("backtrace: {:?}", backtrace);
|
||||||
let buf: Vec<u8> = Vec::new();
|
let buf: Vec<u8> = Vec::new();
|
||||||
let mut writer = Cursor::new(buf);
|
let mut writer = Cursor::new(buf);
|
||||||
match write_exception(&mut writer, exceptions, stack_pointers, backtrace, async_errors) {
|
match write_exception(
|
||||||
|
&mut writer,
|
||||||
|
exceptions,
|
||||||
|
stack_pointers,
|
||||||
|
backtrace,
|
||||||
|
async_errors,
|
||||||
|
) {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(_) => error!("Error writing exception data"),
|
Err(_) => error!("Error writing exception data"),
|
||||||
}
|
}
|
||||||
self.kernel_stop();
|
self.kernel_stop();
|
||||||
return Err(Error::KernelException(Sliceable::new(0, writer.into_inner())));
|
return Err(Error::KernelException(Sliceable::new(
|
||||||
|
0,
|
||||||
|
writer.into_inner(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
kernel::Message::CachePutRequest(key, value) => {
|
kernel::Message::CachePutRequest(key, value) => {
|
||||||
self.cache.insert(key, value);
|
self.cache.insert(key, value);
|
||||||
@ -768,11 +824,13 @@ impl<'a> Manager<'_> {
|
|||||||
let max_time = timer.get_time() + Milliseconds(10000);
|
let max_time = timer.get_time() + Milliseconds(10000);
|
||||||
self.session.kernel_state = match self.session.kernel_state {
|
self.session.kernel_state = match self.session.kernel_state {
|
||||||
// if we are still waiting for the traces to be uploaded, extend the state by timeout
|
// if we are still waiting for the traces to be uploaded, extend the state by timeout
|
||||||
KernelState::DmaPendingPlayback { id, timestamp } => KernelState::DmaPendingAwait {
|
KernelState::DmaPendingPlayback { id, timestamp } => {
|
||||||
id: id,
|
KernelState::DmaPendingAwait {
|
||||||
timestamp: timestamp,
|
id: id,
|
||||||
max_time: max_time,
|
timestamp: timestamp,
|
||||||
},
|
max_time: max_time,
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => KernelState::DmaAwait { max_time: max_time },
|
_ => KernelState::DmaAwait { max_time: max_time },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -845,7 +903,10 @@ impl<'a> Manager<'_> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unexpected!("unexpected message from core1 while kernel was running: {:?}", reply);
|
unexpected!(
|
||||||
|
"unexpected message from core1 while kernel was running: {:?}",
|
||||||
|
reply
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(false)
|
Ok(false)
|
||||||
@ -863,9 +924,9 @@ impl<'a> Manager<'_> {
|
|||||||
KernelState::MsgAwait { max_time, id, tags } => {
|
KernelState::MsgAwait { max_time, id, tags } => {
|
||||||
if let Some(max_time) = *max_time {
|
if let Some(max_time) = *max_time {
|
||||||
if timer.get_time() > max_time {
|
if timer.get_time() > max_time {
|
||||||
self.control
|
self.control.tx.send(kernel::Message::SubkernelError(
|
||||||
.tx
|
kernel::SubkernelStatus::Timeout,
|
||||||
.send(kernel::Message::SubkernelError(kernel::SubkernelStatus::Timeout));
|
));
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -873,7 +934,9 @@ impl<'a> Manager<'_> {
|
|||||||
if let Some(message) = self.session.messages.get_incoming(*id) {
|
if let Some(message) = self.session.messages.get_incoming(*id) {
|
||||||
self.control
|
self.control
|
||||||
.tx
|
.tx
|
||||||
.send(kernel::Message::SubkernelMsgRecvReply { count: message.count });
|
.send(kernel::Message::SubkernelMsgRecvReply {
|
||||||
|
count: message.count,
|
||||||
|
});
|
||||||
let tags = tags.clone();
|
let tags = tags.clone();
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
self.pass_message_to_kernel(&message, tags, timer)
|
self.pass_message_to_kernel(&message, tags, timer)
|
||||||
@ -895,9 +958,9 @@ impl<'a> Manager<'_> {
|
|||||||
KernelState::SubkernelAwaitFinish { max_time, id } => {
|
KernelState::SubkernelAwaitFinish { max_time, id } => {
|
||||||
if let Some(max_time) = *max_time {
|
if let Some(max_time) = *max_time {
|
||||||
if timer.get_time() > max_time {
|
if timer.get_time() > max_time {
|
||||||
self.control
|
self.control.tx.send(kernel::Message::SubkernelError(
|
||||||
.tx
|
kernel::SubkernelStatus::Timeout,
|
||||||
.send(kernel::Message::SubkernelError(kernel::SubkernelStatus::Timeout));
|
));
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -923,7 +986,12 @@ impl<'a> Manager<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pass_message_to_kernel(&mut self, message: &Message, tags: Vec<u8>, timer: &GlobalTimer) -> Result<(), Error> {
|
fn pass_message_to_kernel(
|
||||||
|
&mut self,
|
||||||
|
message: &Message,
|
||||||
|
tags: Vec<u8>,
|
||||||
|
timer: &GlobalTimer,
|
||||||
|
) -> Result<(), Error> {
|
||||||
let mut reader = Cursor::new(&message.data);
|
let mut reader = Cursor::new(&message.data);
|
||||||
let mut current_tags: &[u8] = &tags;
|
let mut current_tags: &[u8] = &tags;
|
||||||
let mut i = message.count;
|
let mut i = message.count;
|
||||||
@ -934,33 +1002,54 @@ impl<'a> Manager<'_> {
|
|||||||
};
|
};
|
||||||
let mut exception: Option<Sliceable> = None;
|
let mut exception: Option<Sliceable> = None;
|
||||||
let mut unexpected: Option<String> = None;
|
let mut unexpected: Option<String> = None;
|
||||||
let remaining_tags = rpc::recv_return(&mut reader, current_tags, slot, &mut |size| {
|
let remaining_tags =
|
||||||
if size == 0 {
|
rpc::recv_return(&mut reader, current_tags, slot, &mut |size| -> Result<
|
||||||
0 as *mut ()
|
_,
|
||||||
} else {
|
Error,
|
||||||
self.control.tx.send(kernel::Message::RpcRecvReply(Ok(size)));
|
> {
|
||||||
match recv_w_timeout(&mut self.control.rx, timer, 100) {
|
if size == 0 {
|
||||||
Ok(kernel::Message::RpcRecvRequest(slot)) => slot,
|
Ok(0 as *mut ())
|
||||||
Ok(kernel::Message::KernelException(exceptions, stack_pointers, backtrace, async_errors)) => {
|
} else {
|
||||||
let buf: Vec<u8> = Vec::new();
|
self.control
|
||||||
let mut writer = Cursor::new(buf);
|
.tx
|
||||||
match write_exception(&mut writer, exceptions, stack_pointers, backtrace, async_errors) {
|
.send(kernel::Message::RpcRecvReply(Ok(size)));
|
||||||
Ok(()) => {
|
match recv_w_timeout(&mut self.control.rx, timer, 100) {
|
||||||
exception = Some(Sliceable::new(0, writer.into_inner()));
|
Ok(kernel::Message::RpcRecvRequest(slot)) => Ok(slot),
|
||||||
}
|
Ok(kernel::Message::KernelException(
|
||||||
Err(_) => {
|
exceptions,
|
||||||
unexpected = Some("Error writing exception data".to_string());
|
stack_pointers,
|
||||||
}
|
backtrace,
|
||||||
};
|
async_errors,
|
||||||
0 as *mut ()
|
)) => {
|
||||||
}
|
let buf: Vec<u8> = Vec::new();
|
||||||
other => {
|
let mut writer = Cursor::new(buf);
|
||||||
unexpected = Some(format!("expected nested value slot from kernel CPU, not {:?}", other));
|
match write_exception(
|
||||||
0 as *mut ()
|
&mut writer,
|
||||||
|
exceptions,
|
||||||
|
stack_pointers,
|
||||||
|
backtrace,
|
||||||
|
async_errors,
|
||||||
|
) {
|
||||||
|
Ok(()) => {
|
||||||
|
exception = Some(Sliceable::new(0, writer.into_inner()));
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
unexpected =
|
||||||
|
Some("Error writing exception data".to_string());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(0 as *mut ())
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
unexpected = Some(format!(
|
||||||
|
"expected nested value slot from kernel CPU, not {:?}",
|
||||||
|
other
|
||||||
|
));
|
||||||
|
Ok(0 as *mut ())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})?;
|
||||||
})?;
|
|
||||||
if let Some(exception) = exception {
|
if let Some(exception) = exception {
|
||||||
self.kernel_stop();
|
self.kernel_stop();
|
||||||
return Err(Error::KernelException(exception));
|
return Err(Error::KernelException(exception));
|
||||||
@ -1002,17 +1091,18 @@ where
|
|||||||
writer.write_u32(u32::MAX)?;
|
writer.write_u32(u32::MAX)?;
|
||||||
writer.write_u32(exception.message.as_ptr() as u32)?;
|
writer.write_u32(exception.message.as_ptr() as u32)?;
|
||||||
} else {
|
} else {
|
||||||
let msg =
|
let msg = str::from_utf8(unsafe {
|
||||||
str::from_utf8(unsafe { slice::from_raw_parts(exception.message.as_ptr(), exception.message.len()) })
|
slice::from_raw_parts(exception.message.as_ptr(), exception.message.len())
|
||||||
.unwrap()
|
})
|
||||||
.replace(
|
.unwrap()
|
||||||
"{rtio_channel_info:0}",
|
.replace(
|
||||||
&format!(
|
"{rtio_channel_info:0}",
|
||||||
"0x{:04x}:{}",
|
&format!(
|
||||||
exception.param[0],
|
"0x{:04x}:{}",
|
||||||
ksupport::resolve_channel_name(exception.param[0] as u32)
|
exception.param[0],
|
||||||
),
|
ksupport::resolve_channel_name(exception.param[0] as u32)
|
||||||
);
|
),
|
||||||
|
);
|
||||||
writer.write_string(&msg)?;
|
writer.write_string(&msg)?;
|
||||||
}
|
}
|
||||||
writer.write_u64(exception.param[0] as u64)?;
|
writer.write_u64(exception.param[0] as u64)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user