Compare commits

...

11 Commits

50 changed files with 1082 additions and 1044 deletions

5
.cargo/config.toml Normal file
View File

@ -0,0 +1,5 @@
[alias]
xtask = "run --package xtask --"
[target.'cfg(all(target_arch = "riscv64", target_os = "none"))']
runner = "qemu-system-riscv64 -nographic -machine virt -serial mon:stdio -smp 1 -kernel "

View File

@ -8,6 +8,13 @@ env:
jobs:
build:
strategy:
matrix:
include:
- arch: riscv64
qemu: qemu-system-misc
target: riscv64imac-unknown-none-elf
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@ -15,17 +22,20 @@ jobs:
- name: Install Qemu
uses: ConorMacBride/install-package@v1
with:
apt: qemu-system-misc
apt: ${{ matrix.qemu }}
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
targets: riscv64imac-unknown-none-elf
components: clippy
targets: ${{ matrix.target }}
components: clippy, rust-src
- name: Install cargo-make
uses: davidB/rust-cargo-make@v1
- name: Run Clippy
run: cargo xtask clippy
- name: Run CI Flow
run: cargo make ci-flow
- name: Build
run: cargo xtask build --arch ${{ matrix.arch }}
- name: Test
run: cargo xtask test --arch ${{ matrix.arch }}

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
/.idea
**/*/target
/target

509
Cargo.lock generated Normal file
View File

@ -0,0 +1,509 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "allocator"
version = "0.1.0"
dependencies = [
"spin",
"static_assertions",
"utils",
"vspace",
]
[[package]]
name = "anstream"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]]
name = "anstyle-parse"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "anyhow"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
[[package]]
name = "api"
version = "0.1.0"
dependencies = [
"num-derive",
"num-traits",
]
[[package]]
name = "autocfg"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "cpio"
version = "0.1.0"
dependencies = [
"flate2",
]
[[package]]
name = "crc32fast"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
dependencies = [
"cfg-if",
]
[[package]]
name = "critical-section"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
name = "embedded-hal"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
[[package]]
name = "fdt"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784a4df722dc6267a04af36895398f59d21d07dce47232adf31ec0ff2fa45e67"
[[package]]
name = "flate2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "kernel"
version = "0.1.0"
dependencies = [
"allocator",
"api",
"bitflags 2.5.0",
"cfg-if",
"fdt",
"log",
"num-derive",
"num-traits",
"riscv",
"sbi-rt",
"spin",
"static_assertions",
"uart_16550",
"utils",
"vspace",
]
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "miniz_oxide"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
dependencies = [
"adler",
]
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "raw-cpuid"
version = "10.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "riscv"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9"
dependencies = [
"critical-section",
"embedded-hal",
]
[[package]]
name = "rustversion"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47"
[[package]]
name = "sbi-rt"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fbaa69be1eedc61c426e6d489b2260482e928b465360576900d52d496a58bd0"
dependencies = [
"sbi-spec",
]
[[package]]
name = "sbi-spec"
version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e36312fb5ddc10d08ecdc65187402baba4ac34585cb9d1b78522ae2358d890"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "uart_16550"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687"
dependencies = [
"bitflags 1.3.2",
"rustversion",
"x86",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "utils"
version = "0.1.0"
dependencies = [
"vspace",
]
[[package]]
name = "vspace"
version = "0.1.0"
dependencies = [
"bitflags 2.5.0",
"num-derive",
"num-traits",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
[[package]]
name = "x86"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
dependencies = [
"bit_field",
"bitflags 1.3.2",
"raw-cpuid",
]
[[package]]
name = "xshell"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db0ab86eae739efd1b054a8d3d16041914030ac4e01cd1dca0cf252fd8b6437"
dependencies = [
"xshell-macros",
]
[[package]]
name = "xshell-macros"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852"
[[package]]
name = "xtask"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"xshell",
]

10
Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[workspace]
resolver = "2"
members = ["api", "kernel", "lib/*", "xtask"]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
lto = "thin"

View File

@ -1,10 +0,0 @@
[env]
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
CARGO_MAKE_WORKSPACE_EMULATION = true
CARGO_MAKE_CRATE_WORKSPACE_MEMBERS = ["kernel"]
[tasks.build]
args = ["build"]
[tasks.test]
args = ["test"]

72
api/Cargo.lock generated
View File

@ -1,72 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "api"
version = "0.1.0"
dependencies = [
"num-derive",
"num-traits",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "2.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"

View File

@ -1,8 +0,0 @@
[build]
target = "riscv64imac-unknown-none-elf"
[target.'cfg(all(target_arch = "riscv64", target_os = "none"))']
runner = "qemu-system-riscv64 -nographic -machine virt -serial mon:stdio -smp 1 -kernel "
[target.'cfg(all(target_arch = "riscv32", target_os = "none"))']
runner = "qemu-system-riscv32 -nographic -machine virt -serial mon:stdio -smp 1 -kernel "

276
kernel/Cargo.lock generated
View File

@ -1,276 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "allocator"
version = "0.1.0"
dependencies = [
"spin 0.9.8",
"static_assertions",
"utils",
"vspace",
]
[[package]]
name = "api"
version = "0.1.0"
dependencies = [
"num-derive",
"num-traits",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "critical-section"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
name = "embedded-hal"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
[[package]]
name = "fdt"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784a4df722dc6267a04af36895398f59d21d07dce47232adf31ec0ff2fa45e67"
[[package]]
name = "kernel"
version = "0.1.0"
dependencies = [
"allocator",
"api",
"bitflags 2.5.0",
"cfg-if",
"fdt",
"lazy_static",
"log",
"num-derive",
"num-traits",
"riscv",
"sbi-rt",
"spin 0.9.8",
"static_assertions",
"uart_16550",
"utils",
"vspace",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin 0.5.2",
]
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "raw-cpuid"
version = "10.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "riscv"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9"
dependencies = [
"critical-section",
"embedded-hal",
]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "sbi-rt"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fbaa69be1eedc61c426e6d489b2260482e928b465360576900d52d496a58bd0"
dependencies = [
"sbi-spec",
]
[[package]]
name = "sbi-spec"
version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e36312fb5ddc10d08ecdc65187402baba4ac34585cb9d1b78522ae2358d890"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "2.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "uart_16550"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687"
dependencies = [
"bitflags 1.3.2",
"rustversion",
"x86",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utils"
version = "0.1.0"
dependencies = [
"vspace",
]
[[package]]
name = "vspace"
version = "0.1.0"
dependencies = [
"bitflags 2.5.0",
"num-derive",
"num-traits",
]
[[package]]
name = "x86"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
dependencies = [
"bit_field",
"bitflags 1.3.2",
"raw-cpuid",
]

View File

@ -6,32 +6,19 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = ["riscv.board.virt", "log_color"]
legacy = ["utils/legacy", "vspace/legacy"]
default = ["riscv.board.virt"]
riscv = []
"riscv.pagetable.sv32" = []
"riscv.pagetable.sv39" = []
"riscv.pagetable.sv48" = []
"riscv.pagetable.sv57" = []
"riscv.riscv64" = ["riscv", "riscv.pagetable.sv39"]
"riscv.riscv32" = ["riscv", "riscv.pagetable.sv32", "legacy"]
"riscv.board.default" = ["riscv.riscv64"]
"riscv.board.virt" = ["riscv.riscv64"]
log_color = []
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
lto = "thin"
[dependencies]
allocator = { path = "../lib/allocator" }
api = { path = "../api" }
@ -41,7 +28,6 @@ vspace = { path = "../lib/vspace", default-features = false }
bitflags = "2.5"
cfg-if = "1.0"
fdt = "0.1"
lazy_static = { version = "1.4", features = ["spin_no_std"] }
log = "0.4"
num-derive = "0.4"
num-traits = { version = "0.2", default-features = false }
@ -49,6 +35,6 @@ spin = "0.9"
static_assertions = "1.1"
uart_16550 = "0.3"
[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies]
[target.'cfg(target_arch = "riscv64")'.dependencies]
riscv = { version = "0.11", features = ["s-mode"] }
sbi-rt = { version = "0.0" }

View File

@ -1,30 +0,0 @@
fn main() {
println!("cargo:rerun-if-changed=build.rs");
struct TargetConfig {
target: &'static str,
lds: &'static str,
}
const TARGET_LDS: &[TargetConfig] = &[
TargetConfig {
target: "riscv64",
lds: "src/arch/riscv/linker64.ld",
},
TargetConfig {
target: "riscv32",
lds: "src/arch/riscv/linker32.ld",
},
];
let target = std::env::var("TARGET").unwrap();
for cfg in TARGET_LDS {
if target.starts_with(cfg.target) {
println!("cargo:rerun-if-changed={}", cfg.lds);
println!("cargo:rustc-link-arg=-T{}", cfg.lds);
return;
}
}
panic!("Unsupported target: {}", target);
}

View File

@ -0,0 +1,31 @@
use core::arch::global_asm;
global_asm!(
"
.section .text
.global boot_setup_early_paging
boot_setup_early_paging:
lla t1, boot_page_table
srli t1, t1, 12
li t2, 8 << 60
or t1, t1, t2
csrw satp, t1
sfence.vma
jr ra
.section .temp.boot_page_table
.align 12
boot_page_table:
# sv39 page table
# 0x00000000_00000000 -> 0x00000000 [ 0x00000000_00000000 -> 0x00000000_40000000 ]
# 0x00000000_40000000 -> 0x40000000 [ 0x00000000_40000000 -> 0x00000000_80000000 ]
# 0x00000000_80000000 -> 0x80000000 [ 0x00000000_80000000 -> 0x00000001_00000000 ]
# 0xFFFFFFD0_00000000 -> 0x80000000 [ 0xFFFFFFD0_00000000 -> 0xFFFFFFD0_40000000 ]
.quad (0x00000 << 10) | 0xf
.quad (0x40000 << 10) | 0xf
.quad (0x80000 << 10) | 0xf
.zero 8 * 317
.quad (0x80000 << 10) | 0xf
.zero 8 * 191
"
);

View File

@ -14,8 +14,7 @@ impl ConsoleDevice for EarlyConsole {
fn try_read(&mut self) -> Option<u8> {
let mut buf = [0u8; 1];
let ret = sbi_rt::console_read(sbi_rt::Physical::new(1, buf.as_mut_ptr() as _, 0));
ret.ok()
.and_then(|len| if len == 0 { None } else { Some(buf[0]) })
ret.ok().and_then(|len| if len == 0 { None } else { Some(buf[0]) })
}
fn write(&mut self, ch: u8) {

View File

@ -1,4 +1,5 @@
pub const TIMER_TICKS: u64 = 100_000; // 100ms
mod boot;
pub mod console;
mod lowlevel;

View File

@ -1,16 +1,26 @@
use super::super::lowlevel::{ArchLL, ArchLLOps};
use super::TEST_DEVICE;
use crate::arch::layout::mmap_phys_to_virt;
use crate::arch::vspace::is_kernel_pagetable_installed;
unsafe fn get_qemu_test_device() -> *mut u32 {
if is_kernel_pagetable_installed() {
return mmap_phys_to_virt(TEST_DEVICE.into()).into();
} else {
return TEST_DEVICE;
}
}
impl ArchLLOps for ArchLL {
fn board_shutdown(failure: bool) {
if failure {
unsafe { TEST_DEVICE.write_volatile(0x0001_3333) }
unsafe { get_qemu_test_device().write_volatile(0x0001_3333) }
} else {
unsafe { TEST_DEVICE.write_volatile(0x0000_5555) }
unsafe { get_qemu_test_device().write_volatile(0x0000_5555) }
}
}
fn board_reset(_failure: bool) {
unsafe { TEST_DEVICE.write_volatile(0x0042_7777) }
unsafe { get_qemu_test_device().write_volatile(0x0042_7777) }
}
}

View File

@ -5,5 +5,7 @@ pub const UART0_BASE: usize = 0x1000_0000;
pub const UART0_LSR: usize = 0x1000_0005;
pub const TEST_DEVICE: *mut u32 = 0x10_0000 as *mut u32;
#[path = "../default/boot.rs"]
mod boot;
pub mod console;
mod lowlevel;

View File

@ -1,6 +1,10 @@
use crate::arch::layout::zero_bss;
use crate::arch::vspace::utils::{setup_kernel_paging, setup_memory};
use allocator::RamBlock;
use crate::arch::init_early_console;
use crate::arch::layout::{mmap_phys_to_virt, zero_bss, KERNEL_OFFSET};
use crate::arch::vspace::{setup_kernel_paging, setup_memory};
use crate::entry::{rust_main, HART_ID};
use crate::plat::console::mute_console;
use fdt::Fdt;
use vspace::addr::AddressOps;
#[naked]
#[no_mangle]
@ -25,15 +29,29 @@ unsafe extern "C" fn _start(hart_id: usize, device_tree_addr: usize) -> ! {
addi gp, gp, %pcrel_lo(1b)
.option pop
la tp, TSS_START
la sp, {stack} + {stack_size}
j {main}
lla t0, KERNEL_OFFSET
ld t0, 0(t0)
# load and relocate registers
lla tp, TSS_START
lla sp, {stack} + {stack_size}
add gp, gp, t0
add tp, tp, t0
add sp, sp, t0
# setup early paging
call boot_setup_early_paging
# jump to absolute address
lla t1, {main}
add t1, t1, t0
jr t1
.section .data
.global KERNEL_OFFSET
KERNEL_OFFSET: .quad __kernel_offset
.global MMAP_OFFSET
MMAP_OFFSET: .quad MMAP_BASE_ADDRESS
.global KERNEL_OFFSET
KERNEL_OFFSET: .quad __kernel_offset
.global MMAP_OFFSET
MMAP_OFFSET: .quad MMAP_BASE_ADDRESS
",
stack_size = const STACK_SIZE,
stack = sym STACK,
@ -42,24 +60,19 @@ unsafe extern "C" fn _start(hart_id: usize, device_tree_addr: usize) -> ! {
)
}
extern "C" fn pre_main(hart_id: usize, fdt_addr: usize) -> ! {
unsafe fn pre_main(hart_id: usize, fdt_addr: usize) {
zero_bss();
// Don't know why, but the **fucking** rust compiler will hard-code jump table to absolute
// addresses, even if I forced compiler to use pic mode, and global spin-lock depends on it,
// so we must remap the kernel to the higher half before anything.
// Console is not available yet !!
let fdt = unsafe { Fdt::from_ptr(fdt_addr as *const u8).unwrap() };
let mut allocator = RamBlock::<8>::new();
unsafe {
setup_memory(&fdt, fdt_addr, &mut allocator);
setup_kernel_paging(&mut allocator);
}
HART_ID.set(hart_id);
crate::logging::init();
init_early_console();
crate::entry::rust_main(hart_id, fdt, allocator);
setup_memory(fdt_addr);
setup_kernel_paging();
// after kernel paging, board level early console is broken (no address mapping)
mute_console();
let fdt = unsafe { Fdt::from_ptr(mmap_phys_to_virt(fdt_addr.into()).as_const_ptr()).unwrap() };
rust_main(fdt);
}

View File

@ -37,16 +37,19 @@ pub const PAGE_LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(PAGE_
#[inline(always)]
pub fn zero_bss() {
fn clear_range<T: Clone>(bgn: *mut T, end: *mut T) {
unsafe {
core::slice::from_raw_parts_mut(bgn, end.offset_from(bgn) as usize)
.fill(core::mem::zeroed())
}
fn clear_range(bgn: *mut u8, end: *mut u8) {
unsafe { core::slice::from_raw_parts_mut(bgn, end.offset_from(bgn) as usize).fill(core::mem::zeroed()) }
}
unsafe {
clear_range(BOOT_STACK_END.as_mut_ptr(), BSS_END.as_mut_ptr());
clear_range(TBSS_START.as_mut_ptr(), TBSS_END.as_mut_ptr());
clear_range(
kernel_virt_to_phys(BOOT_STACK_END.as_virt_addr()).as_mut_ptr(),
kernel_virt_to_phys(BSS_END.as_virt_addr()).as_mut_ptr(),
);
clear_range(
kernel_virt_to_phys(TBSS_START.as_virt_addr()).as_mut_ptr(),
kernel_virt_to_phys(TBSS_END.as_virt_addr()).as_mut_ptr(),
);
}
}

View File

@ -1,16 +1,17 @@
OUTPUT_ARCH(riscv)
ENTRY(_start)
MMAP_BASE_ADDRESS = 0x0;
BASE_ADDRESS = 0x80200000;
PHY_BASE_ADDRESS = 0x80200000;
PAGE_SIZE = 0x1000;
MMAP_BASE_ADDRESS = 0x00000000;
BASE_ADDRESS = 0x80200000;
PHY_BASE_ADDRESS = 0x80200000;
PAGE_SIZE = 0x1000;
SECTIONS {
. = BASE_ADDRESS;
KERNEL_START = .;
__kernel_offset = . - PHY_BASE_ADDRESS;
. = ALIGN(PAGE_SIZE);
.text : AT(ADDR(.text) - __kernel_offset) {
TEXT_START = .;
*(.text.entry)
@ -18,26 +19,27 @@ SECTIONS {
TEXT_END = .;
}
. = ALIGN(PAGE_SIZE);
.rodata : AT(ADDR(.rodata) - __kernel_offset) {
. = ALIGN(PAGE_SIZE);
RODATA_START = .;
*(.rodata .rodata.*)
*(.srodata .srodata.*)
RODATA_END = .;
}
. = ALIGN(PAGE_SIZE);
.data : AT(ADDR(.data) - __kernel_offset) {
. = ALIGN(PAGE_SIZE);
DATA_START = .;
*(.data .data.*)
*(.temp .temp.*)
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
DATA_END = .;
}
. = ALIGN(PAGE_SIZE);
.bss : AT(ADDR(.bss) - __kernel_offset) {
. = ALIGN(PAGE_SIZE);
BSS_START = .;
*(.bss.boot_stack)
BOOT_STACK_END = .;
@ -47,8 +49,8 @@ SECTIONS {
BSS_END = .;
}
. = ALIGN(PAGE_SIZE);
.tss : AT(ADDR(.tss) - __kernel_offset) {
. = ALIGN(PAGE_SIZE);
TSS_START = .;
. = ALIGN(8);

View File

@ -3,19 +3,20 @@ ENTRY(_start)
/* We use high memory (0xFFFF....) for kernel space
* For sv39 and larger layout, memory base starts from 0xFFFFFFC000000000: {1'b1, {38{1'b0}}}
* Our kernel will placed at 0xFFFFFFD000000000 (VA) and 0x80200000 (PA)
* Regions between 0x...C... and 0x...D... will be reserved for firmware starting from 0x80000000 (PA) */
* Our kernel will placed at 0xFFFFFFD000200000 (VA) and 0x80200000 (PA)
*/
MMAP_BASE_ADDRESS = 0xFFFFFFC000000000;
BASE_ADDRESS = 0xFFFFFFD000000000;
PHY_BASE_ADDRESS = 0x80200000;
PAGE_SIZE = 0x1000;
BASE_ADDRESS = 0xFFFFFFD000200000;
PHY_BASE_ADDRESS = 0x0000000080200000;
PAGE_SIZE = 0x1000;
SECTIONS {
. = BASE_ADDRESS;
KERNEL_START = .;
__kernel_offset = . - PHY_BASE_ADDRESS;
. = ALIGN(PAGE_SIZE);
.text : AT(ADDR(.text) - __kernel_offset) {
TEXT_START = .;
*(.text.entry)
@ -23,26 +24,27 @@ SECTIONS {
TEXT_END = .;
}
. = ALIGN(PAGE_SIZE);
.rodata : AT(ADDR(.rodata) - __kernel_offset) {
. = ALIGN(PAGE_SIZE);
RODATA_START = .;
*(.rodata .rodata.*)
*(.srodata .srodata.*)
RODATA_END = .;
}
. = ALIGN(PAGE_SIZE);
.data : AT(ADDR(.data) - __kernel_offset) {
. = ALIGN(PAGE_SIZE);
DATA_START = .;
*(.data .data.*)
*(.temp .temp.*)
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
DATA_END = .;
}
. = ALIGN(PAGE_SIZE);
.bss : AT(ADDR(.bss) - __kernel_offset) {
. = ALIGN(PAGE_SIZE);
BSS_START = .;
*(.bss.boot_stack)
BOOT_STACK_END = .;
@ -52,8 +54,8 @@ SECTIONS {
BSS_END = .;
}
. = ALIGN(PAGE_SIZE);
.tss : AT(ADDR(.tss) - __kernel_offset) {
. = ALIGN(PAGE_SIZE);
TSS_START = .;
. = ALIGN(8);

View File

@ -3,15 +3,3 @@
// https://github.com/riscv-non-isa/riscv-elf-psabi-doc
// - Rust #[thread_local] feature
// https://github.com/rust-lang/rust/issues/29594
// TODO: use TLS for per-hart data
pub fn get_hart_id() -> usize {
let id;
unsafe { core::arch::asm!("mv {}, tp", out(reg) id) }
id
}
pub fn set_hart_id(id: usize) {
unsafe { core::arch::asm!("mv tp, {}", in(reg) id) }
}

View File

@ -1,21 +1,14 @@
use crate::entry::HART_ID;
use crate::plat::console::CONSOLE;
use cfg_if::cfg_if;
use log::trace;
use riscv::register::scause::{Interrupt as I, Trap as T};
use riscv::register::stvec::TrapMode;
use super::tls::get_hart_id;
use crate::plat::timer::{Timer, TimerOps};
use crate::plat::trap::{Trap, TrapContextOps, TrapOps};
cfg_if! {
if #[cfg(feature = "riscv.riscv64")] {
core::arch::global_asm!(include_str!("./asm/trap64.S"));
} else if #[cfg(feature = "riscv.riscv32")] {
core::arch::global_asm!(include_str!("./asm/trap32.S"));
}
}
core::arch::global_asm!(include_str!("./asm/trap64.S"));
core::arch::global_asm!(include_str!("./asm/trap_common.S"));
extern "C" {
@ -32,11 +25,7 @@ extern "C" fn kernel_trap_handler(tf: &mut TrapContext) {
fn trap_handler(_tf: &mut TrapContext, _from_kernel: bool) {
let scause = riscv::register::scause::read();
trace!(
"[Interrupt] cpu@{} scause: {:?}",
get_hart_id(),
scause.cause()
);
trace!("[Interrupt] cpu@{} scause: {:?}", HART_ID.get(), scause.cause());
match scause.cause() {
T::Interrupt(I::SupervisorTimer) => {
// TODO: refactor this

View File

@ -34,8 +34,7 @@ impl From<PTEFlags> for MapAttr {
if flags.contains(PTEFlags::USER_ACCESSIBLE) {
attr.insert(Self::USER_ACCESSIBLE);
}
if flags.contains(PTEFlags::VALID)
&& !flags.contains(PTEFlags::READABLE | PTEFlags::WRITABLE | PTEFlags::EXECUTABLE)
if flags.contains(PTEFlags::VALID) && !flags.contains(PTEFlags::READABLE | PTEFlags::WRITABLE | PTEFlags::EXECUTABLE)
{
attr.insert(Self::PAGE_TABLE);
}
@ -74,12 +73,8 @@ impl From<MapAttr> for PTEFlags {
}
}
#[cfg(not(feature = "riscv.pagetable.sv32"))]
assert_eq_size!(Entry, u64);
#[cfg(feature = "riscv.pagetable.sv32")]
assert_eq_size!(Entry, u32);
#[derive(Clone, Copy, Default)]
pub struct Entry(usize);

View File

@ -1,4 +1,6 @@
mod entry;
mod table;
mod traits;
pub mod utils;
mod utils;
pub use utils::*;

View File

@ -32,8 +32,6 @@ impl Table {
}
pub fn mode() -> riscv::register::satp::Mode {
#[cfg(feature = "riscv.pagetable.sv32")]
return riscv::register::satp::Mode::Sv32;
#[cfg(feature = "riscv.pagetable.sv39")]
return riscv::register::satp::Mode::Sv39;
#[cfg(feature = "riscv.pagetable.sv48")]
@ -46,8 +44,6 @@ impl Table {
impl TableOps for Table {
type Entry = Entry;
#[cfg(feature = "riscv.pagetable.sv32")]
const MAX_PAGE_SIZE: TableLevel = TableLevel::Level1;
#[cfg(feature = "riscv.pagetable.sv39")]
const MAX_PAGE_SIZE: TableLevel = TableLevel::Level2;
@ -57,13 +53,7 @@ impl TableOps for Table {
&mut *ptr
}
fn map(
&mut self,
from: VirtAddr,
to: PhysAddr,
attr: MapAttr,
level: TableLevel,
) -> PageResult {
fn map(&mut self, from: VirtAddr, to: PhysAddr, attr: MapAttr, level: TableLevel) -> PageResult {
assert!(from.is_aligned(PAGE_SIZE));
assert!(to.is_aligned(PAGE_SIZE));
assert!(level.is_aligned(from));
@ -124,12 +114,7 @@ impl TableOps for Table {
}
impl Table {
fn debug_walk(
&self,
f: &mut core::fmt::Formatter,
base: VirtAddr,
level: TableLevel,
) -> core::fmt::Result {
fn debug_walk(&self, f: &mut core::fmt::Formatter, base: VirtAddr, level: TableLevel) -> core::fmt::Result {
macro_rules! print_one {
($($arg:tt)*) => {
for _ in level.to_usize().unwrap()..Self::MAX_PAGE_SIZE.to_usize().unwrap() {

View File

@ -34,13 +34,6 @@ pub trait PhysAddrPaging {
}
}
#[cfg(feature = "riscv.pagetable.sv32")]
impl PhysAddrPaging for PhysAddr {
const PG_OFFSET: usize = 12;
const PPN_BITS: usize = 22;
const PPN_OFFSET: usize = 10;
}
#[cfg(feature = "riscv.pagetable.sv39")]
impl PhysAddrPaging for PhysAddr {
const PG_OFFSET: usize = 12;
@ -56,8 +49,7 @@ pub trait VirtAddrPaging {
fn to_vpn(&self, level: TableLevel) -> usize
where Self: AddressOps {
self.as_usize() >> (Self::PG_OFFSET + Self::VPN_BITS * level.to_usize().unwrap())
& Self::VPN_MASK
self.as_usize() >> (Self::PG_OFFSET + Self::VPN_BITS * level.to_usize().unwrap()) & Self::VPN_MASK
}
fn merge_vpn(&self, vpn: usize, size: TableLevel) -> VirtAddr
@ -73,12 +65,6 @@ pub trait VirtAddrPaging {
}
}
#[cfg(feature = "riscv.pagetable.sv32")]
impl VirtAddrPaging for VirtAddr {
const PG_OFFSET: usize = 12;
const VPN_BITS: usize = 10;
}
#[cfg(feature = "riscv.pagetable.sv39")]
impl VirtAddrPaging for VirtAddr {
const PG_OFFSET: usize = 12;
@ -99,14 +85,9 @@ impl TableLevelSize for TableLevel {
fn level_size(&self) -> usize {
match self {
Self::Level0 => 4 * KIB,
#[cfg(feature = "riscv.pagetable.sv32")]
Self::Level1 => 4 * MIB,
#[cfg(not(feature = "riscv.pagetable.sv32"))]
Self::Level1 => 2 * MIB,
Self::Level2 => 1 * GIB,
#[cfg(not(feature = "legacy"))]
Self::Level3 => 512 * GIB,
#[cfg(not(feature = "legacy"))]
Self::Level4 => 256 * TIB,
}
}

View File

@ -2,16 +2,34 @@ use super::table::Table;
use super::traits::{PhysAddrPaging, TableLevelSize};
use crate::arch::layout::*;
use allocator::RamBlock;
use fdt::Fdt;
use log::{debug, info};
use spin::Mutex;
use utils::size::GIB;
use vspace::addr::*;
use vspace::paging::{MapAttr, PageError::*, TableLevel, TableOps};
use vspace::paging::PageError::*;
use vspace::paging::*;
pub unsafe fn setup_memory(fdt_addr: usize, mem: &mut RamBlock<8>) {
let fdt = unsafe { Fdt::from_ptr(fdt_addr as *const u8).unwrap() };
#[thread_local]
static KERNEL_PAGETABLE: Mutex<Option<&mut Table>> = Mutex::new(None);
static KERNEL_ALLOCATOR: Mutex<RamBlock<8>> = Mutex::new(RamBlock::new());
#[inline]
fn alloc_page() -> PhysAddr {
KERNEL_ALLOCATOR.lock().alloc(PAGE_LAYOUT).expect("Failed to allocate page")
}
pub unsafe fn setup_memory(fdt_addr: usize) {
info!("Setting up memory");
let fdt = unsafe { fdt::Fdt::from_ptr(fdt_addr as *const u8).unwrap() };
let mut mem = KERNEL_ALLOCATOR.lock();
// Add main memory regions to allocator
for region in fdt.memory().regions() {
debug!(
"Adding free memory:\tstart: {:x?}, size: {:x?}",
region.starting_address, region.size
);
mem.dealloc(
PhysAddr::from(region.starting_address),
align_up(region.size.unwrap(), PAGE_SIZE),
@ -20,10 +38,12 @@ pub unsafe fn setup_memory(fdt_addr: usize, mem: &mut RamBlock<8>) {
// Exclude memory occupied by UEFI
for region in fdt.memory_reservations() {
mem.reserve(
PhysAddr::from(region.address()),
align_up(region.size(), PAGE_SIZE),
debug!(
"Reserving memory:\tstart: {:x?}, size: {:x?}",
region.address(),
region.size()
);
mem.reserve(PhysAddr::from(region.address()), align_up(region.size(), PAGE_SIZE));
}
// Exclude memory occupied by OpenSBI
@ -33,6 +53,10 @@ pub unsafe fn setup_memory(fdt_addr: usize, mem: &mut RamBlock<8>) {
.expect("No reserved memory found in device tree");
for child in reserved_memory {
let region = child.reg().unwrap().next().unwrap();
debug!(
"Reserving memory:\tstart: {:x?}, size: {:x?}",
region.starting_address, region.size
);
mem.reserve(
PhysAddr::from(region.starting_address),
align_up(region.size.unwrap(), PAGE_SIZE),
@ -40,56 +64,98 @@ pub unsafe fn setup_memory(fdt_addr: usize, mem: &mut RamBlock<8>) {
}
// Exclude kernel memory
let kernel_start = KERNEL_START.as_phys_addr() - KERNEL_OFFSET;
let kernel_end = (KERNEL_END.as_phys_addr() - KERNEL_OFFSET).align_up(PAGE_SIZE);
let kernel_start = kernel_virt_to_phys(KERNEL_START.as_virt_addr());
let kernel_end = kernel_virt_to_phys(KERNEL_END.as_virt_addr()).align_up(PAGE_SIZE);
debug!("Reserving kernel memory:\tstart: {:x?}, end: {:x?}", kernel_start, kernel_end);
mem.reserve(kernel_start, (kernel_end - kernel_start).as_usize());
// Exclude FDT table
let fdt_addr = PhysAddr::from(fdt_addr);
let fdt_size = align_up(fdt.total_size(), PAGE_SIZE);
debug!("Reserving FDT memory:\tstart: {:x?}, size: {:x?}", fdt_addr, fdt_size);
mem.reserve(fdt_addr, fdt_size);
}
pub unsafe fn setup_kernel_paging(
allocator: &mut RamBlock<8>,
hart_id: usize,
fdt_addr: usize,
) -> ! {
let mut alloc = || {
allocator
.alloc(PAGE_LAYOUT)
.expect("Failed to allocate page table")
};
let root_pt = alloc();
let kernel_pt = unsafe { Table::new(root_pt.as_usize().into()) };
let mut map = |vaddr: VirtAddr, paddr: PhysAddr, attr: MapAttr, level: TableLevel| loop {
match kernel_pt.map(vaddr, paddr, attr, level) {
Ok(_) => return true,
Err(MissingEntry(missed_level)) => kernel_pt
.map(
missed_level.align(vaddr),
alloc(),
MapAttr::PAGE_TABLE,
missed_level,
)
.expect("Failed to map miss-ed page table"),
Err(AlreadyMapped(_)) => return false,
#[inline]
fn map_one(pt: &mut Table, vaddr: VirtAddr, paddr: PhysAddr, attr: MapAttr, level: TableLevel) -> PageResult<()> {
loop {
let ret = pt.map(vaddr, paddr, attr, level);
if let Err(MissingEntry(missed_level)) = ret {
pt.map(missed_level.align(vaddr), alloc_page(), MapAttr::PAGE_TABLE, missed_level)?;
continue;
}
};
return ret;
}
}
#[inline]
fn map_range(pt: &mut Table, from: VirtAddr, to: PhysAddr, size: usize, attr: MapAttr) -> PageResult<()> {
let mut virt_start = from;
let mut phys_start = to;
let virt_end = from + size;
let mut map_level = Table::MAX_PAGE_SIZE;
debug!("Mapping physical memory:\t[{:X?}, {:X?}]", virt_start, virt_end,);
while virt_start < virt_end {
let ret = map_one(pt, virt_start, phys_start, attr, map_level);
if ret.is_ok() {
// map success, move to next region
virt_start += map_level.level_size();
phys_start += map_level.level_size();
// check whether we could raise the level
if let Some(prv) = map_level.previous()
&& prv.is_aligned(phys_start)
{
map_level = prv;
}
continue;
}
// already mapped, try smaller level
match map_level.next() {
Some(next) => map_level = next,
None => return ret,
}
}
Ok(())
}
pub unsafe fn map(from: VirtAddr, to: PhysAddr, size: usize, attr: MapAttr) {
let mut guard = KERNEL_PAGETABLE.lock();
let pt = guard.as_mut().unwrap();
map_range(pt, from, to, size, attr).expect("Failed to map memory");
}
#[inline]
pub fn is_kernel_pagetable_installed() -> bool {
KERNEL_PAGETABLE.lock().is_some()
}
pub unsafe fn setup_kernel_paging() {
info!("Setting up kernel paging");
assert!(!is_kernel_pagetable_installed(), "Kernel pagetable already installed");
let root_pt = alloc_page();
let kernel_pt = Table::new(root_pt.as_usize().into());
macro_rules! map_section {
(($($section:ident),+),$attr:expr) => {
$(
for addr in (concat_idents!($section, _START).as_phys_addr()..concat_idents!($section, _END).as_phys_addr()).step_by(PAGE_SIZE) {
if !map(kernel_phys_to_virt(addr), addr, $attr, TableLevel::Level0) {
let start = concat_idents!($section, _START).as_virt_addr();
let end = concat_idents!($section, _END).as_virt_addr();
debug!("Mapping section {}:\t[{:X?}, {:X?}]", stringify!($section), start, end);
for addr in (start..end).step_by(PAGE_SIZE) {
let _ = map_one(kernel_pt, addr, kernel_virt_to_phys(addr), $attr, TableLevel::Level0).is_err_and(|_| {
panic!(
"Failed to map section: {:X?} - {:X?}",
concat_idents!($section, _START).as_phys_addr(),
concat_idents!($section, _END).as_phys_addr()
concat_idents!($section, _START).as_virt_addr(),
concat_idents!($section, _END).as_virt_addr()
);
}
});
}
)+
};
@ -103,54 +169,21 @@ pub unsafe fn setup_kernel_paging(
map_section!((TSS), MapAttr::READABLE | MapAttr::WRITABLE);
// map 4 GiB physical memory
// TODO: walk fdt to get all memory region?
{
#[cfg(feature = "legacy")]
let level = TableLevel::Level1;
#[cfg(not(feature = "legacy"))]
let level = TableLevel::Level2;
// TODO: walk fdt to get all memory region? put it in driver init
map_range(
kernel_pt,
mmap_phys_to_virt(PhysAddr(0)),
PhysAddr(0),
3 * GIB - 1 + GIB,
MapAttr::READABLE | MapAttr::WRITABLE,
)
.expect("Failed to map physical memory");
let addr_end = PhysAddr(3 * GIB - 1 + GIB);
let mut phys_addr = PhysAddr(0);
let mut map_level = level;
while phys_addr < addr_end {
let ok = map(
kernel_phys_to_virt(phys_addr),
phys_addr,
MapAttr::READABLE | MapAttr::WRITABLE,
map_level,
);
if ok || map_level.next().is_none() {
// map success or reach the end, move to next region
phys_addr += map_level.level_size();
// check whether we could raise the level
if let Some(prv) = map_level.previous()
&& prv.is_aligned(phys_addr)
{
map_level = prv;
}
continue;
}
// already mapped, try smaller level
map_level = map_level.next().unwrap();
}
}
riscv::register::satp::set(riscv::register::satp::Mode::Sv39, 0, root_pt.to_ppn());
// setup new pagetable
debug!("Setting up new kernel pagetable");
riscv::register::satp::set(Table::mode(), 0, root_pt.to_ppn());
riscv::asm::sfence_vma_all();
macro_rules! remap {
($reg:ident) => {
let $reg: usize;
core::arch::asm!(concat!("mv {}, ", stringify!($reg)), out(reg) $reg);
let $reg = kernel_phys_to_virt(PhysAddr($reg));
core::arch::asm!(concat!("mv ", stringify!($reg), ", {}"), in(reg) $reg.as_usize());
};
}
todo!("remap registers");
// switch to virtual address
*KERNEL_PAGETABLE.lock() = Some(Table::new(mmap_phys_to_virt(root_pt)));
}

View File

@ -1,8 +1,10 @@
use crate::arch::layout::mmap_phys_to_virt;
use crate::drivers::serial::SerialDriver;
use crate::drivers::Driver;
use crate::plat::console::ConsoleDevice;
use core::sync::atomic::{AtomicPtr, Ordering};
use fdt::node::FdtNode;
use vspace::addr::PhysAddr;
// https://static.dev.sifive.com/FU540-C000-v1.0.pdf
@ -121,7 +123,9 @@ impl Driver for UartSifive {
}
fn setup(fdt: FdtNode) -> Self {
let addr = fdt.reg().unwrap().next().unwrap().starting_address as *mut u32;
let addr = fdt.reg().unwrap().next().unwrap().starting_address;
let addr = unsafe { mmap_phys_to_virt(PhysAddr::from(addr)) };
let addr: *mut u32 = addr.into();
let uart = unsafe {
UartSifive {
tx_data: AtomicPtr::new(addr),

View File

@ -1,8 +1,10 @@
use crate::arch::layout::mmap_phys_to_virt;
use crate::drivers::serial::SerialDriver;
use crate::drivers::Driver;
use crate::plat::console::ConsoleDevice;
use fdt::node::FdtNode;
use uart_16550::MmioSerialPort;
use vspace::addr::PhysAddr;
pub struct Uart16550
where Uart16550: SerialDriver
@ -17,7 +19,8 @@ impl Driver for Uart16550 {
fn setup(fdt: FdtNode) -> Self {
let addr = fdt.reg().unwrap().next().unwrap().starting_address;
let mut serial_port = unsafe { MmioSerialPort::new(addr as usize) };
let addr = unsafe { mmap_phys_to_virt(PhysAddr::from(addr)) };
let mut serial_port = unsafe { MmioSerialPort::new(addr.into()) };
serial_port.init();
Uart16550 { port: serial_port }
}

View File

@ -1,9 +1,7 @@
use crate::arch::init_early_console;
use crate::plat::console::{set_console, ConsoleDevice, ConsoleDriver, CONSOLE};
use crate::plat::lowlevel::{Hardware, LowLevel};
use crate::plat::timer::{Timer, TimerOps};
use crate::plat::trap::{Trap, TrapOps};
use allocator::RamBlock;
use core::cell::Cell;
use fdt::Fdt;
use log::{debug, error, info, warn};
@ -11,13 +9,9 @@ use log::{debug, error, info, warn};
#[thread_local]
pub static HART_ID: Cell<usize> = Cell::new(0);
// NOTE: we will call rust_main through trap (stvec), make sure it is aligned
#[repr(align(4))]
pub extern "C" fn rust_main(hart_id: usize, fdt_addr: usize, allocator: &mut RamBlock<8>) -> ! {
HART_ID.set(hart_id);
info!("Kernel Started");
pub fn rust_main(fdt: Fdt) -> ! {
setup_console(&fdt);
info!("Kernel Started");
#[cfg(test)]
{
@ -52,13 +46,9 @@ pub extern "C" fn rust_main(hart_id: usize, fdt_addr: usize, allocator: &mut Ram
Hardware::shutdown(true);
}
fn setup_console(fdt: &fdt::Fdt) {
fn setup_console(fdt: &Fdt) {
// NOTE: ignore stdin: both stdin and stdout will go through stdout device
match fdt
.chosen()
.stdout()
.and_then(|stdout| ConsoleDriver::new(stdout))
{
match fdt.chosen().stdout().and_then(|stdout| ConsoleDriver::new(stdout)) {
None => warn!("No stdout device found or no compatible drivers found, falling back to platform default"),
Some(driver) => set_console(driver),
}

View File

@ -15,19 +15,16 @@ impl Log for SimpleLogger {
return;
}
let (color_prefix, color_reset) = if cfg!(feature = "log_color") {
let color = match record.level() {
log::Level::Error => "\x1b[31m",
log::Level::Warn => "\x1b[33m",
log::Level::Info => "\x1b[32m",
log::Level::Debug => "\x1b[34m",
log::Level::Trace => "\x1b[37m",
};
(color, "\x1b[0m")
} else {
("", "")
let color_prefix = match record.level() {
log::Level::Error => "\x1b[31m",
log::Level::Warn => "\x1b[33m",
log::Level::Info => "\x1b[32m",
log::Level::Debug => "\x1b[34m",
log::Level::Trace => "\x1b[37m",
};
let color_reset = "\x1b[0m";
CONSOLE
.lock()
.write_fmt(format_args!(

View File

@ -22,7 +22,7 @@ macro_rules! create_console_driver {
.any(|s| $dynamic_driver::compatible().contains(&s))
{
debug!("Console: Using driver: {}", stringify!($dynamic_driver));
return Some(ConsoleDriver::$dynamic_driver($dynamic_driver::setup(fdt)))
return Some(ConsoleDriver::$dynamic_driver($dynamic_driver::setup(fdt)));
}
)+
}
@ -99,13 +99,16 @@ pub trait ConsoleDevice {
}
}
pub static CONSOLE: Mutex<ConsoleDriver> =
Mutex::new(ConsoleDriver::SilenceConsole(SilenceConsole));
pub static CONSOLE: Mutex<ConsoleDriver> = Mutex::new(ConsoleDriver::SilenceConsole(SilenceConsole));
pub fn set_console(driver: ConsoleDriver) {
*CONSOLE.lock() = driver;
}
pub fn mute_console() {
*CONSOLE.lock() = ConsoleDriver::SilenceConsole(SilenceConsole);
}
#[cfg(test)]
mod tests {
use super::*;
@ -114,9 +117,6 @@ mod tests {
#[test_case]
fn print_with_console() {
CONSOLE.lock().write(b'A');
CONSOLE
.lock()
.write_fmt(format_args!("B {}\n", 0x42))
.unwrap();
CONSOLE.lock().write_fmt(format_args!("B {}\n", 0x42)).unwrap();
}
}

127
lib/allocator/Cargo.lock generated
View File

@ -1,127 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "allocator"
version = "0.1.0"
dependencies = [
"spin",
"static_assertions",
"utils",
"vspace",
]
[[package]]
name = "autocfg"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utils"
version = "0.1.0"
dependencies = [
"vspace",
]
[[package]]
name = "vspace"
version = "0.1.0"
dependencies = [
"bitflags",
"num-derive",
"num-traits",
]

View File

@ -120,10 +120,7 @@ pub type Bitmap1K = Bitmap<Bitmap32>;
pub type Bitmap32K = Bitmap<Bitmap1K>;
const_assert_eq!(core::mem::size_of::<Bitmap1K>(), (32 + 1) * 32 / 8);
const_assert_eq!(
core::mem::size_of::<Bitmap32K>(),
(32 * (32 + 1) + 1) * 32 / 8
);
const_assert_eq!(core::mem::size_of::<Bitmap32K>(), (32 * (32 + 1) + 1) * 32 / 8);
pub struct BitmapAllocator<B: BitmapCfg = Bitmap32K> {
bitmap: Mutex<B>,

View File

@ -58,9 +58,7 @@ pub struct FreeList {
impl FreeList {
pub const fn new() -> Self {
Self {
head: ListNode::new(0),
}
Self { head: ListNode::new(0) }
}
fn alloc_node<F, V>(&mut self, mut predicate: F) -> Option<(&'static mut ListNode, V)>
@ -120,9 +118,9 @@ impl FreeList {
pub fn reserve(&mut self, start: PhysAddr, size: usize) {
// NOTE: only support inclusive range
if let Some((region, _)) = self.alloc_node(|region| {
(region.start_addr() <= start && start < region.end_addr()).some(|| (), ())
}) {
if let Some((region, _)) =
self.alloc_node(|region| (region.start_addr() <= start && start < region.end_addr()).some(|| (), ()))
{
let region_start = region.start_addr();
let region_end = region.end_addr();
@ -164,9 +162,7 @@ impl FreeListAllocator {
pub fn new(start: PhysAddr, size: usize) -> Self {
let mut list = FreeList::new();
unsafe { list.dealloc(start, size) }
Self {
list: Mutex::new(list),
}
Self { list: Mutex::new(list) }
}
}
@ -217,10 +213,7 @@ mod tests {
let base = PhysAddr::from(vec.as_ptr()).align_up(PAGE_SIZE);
let allocator = FreeListAllocator::new(base, 32 * PAGE_SIZE);
allocator
.list
.lock()
.reserve(base + 4 * PAGE_SIZE, 4 * PAGE_SIZE);
allocator.list.lock().reserve(base + 4 * PAGE_SIZE, 4 * PAGE_SIZE);
let mut cnt = 32 - 4;
loop {

View File

@ -1,5 +1,4 @@
#![cfg_attr(not(test), no_std)]
#![feature(const_mut_refs)]
#[macro_use]

50
lib/cpio/Cargo.lock generated
View File

@ -1,50 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cpio"
version = "0.1.0"
dependencies = [
"flate2",
]
[[package]]
name = "crc32fast"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
dependencies = [
"cfg-if",
]
[[package]]
name = "flate2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "miniz_oxide"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
dependencies = [
"adler",
]

View File

@ -193,10 +193,7 @@ mod tests {
fn test_read_hex_u32() {
assert_eq!(read_hex_u32(&[b'0'; 8]), 0x00000000);
assert_eq!(read_hex_u32(&[b'f'; 8]), 0xffffffff);
assert_eq!(
read_hex_u32(&[b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8']),
0x12345678
);
assert_eq!(read_hex_u32(&[b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8']), 0x12345678);
}
#[test]

86
lib/utils/Cargo.lock generated
View File

@ -1,86 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utils"
version = "0.1.0"
dependencies = [
"vspace",
]
[[package]]
name = "vspace"
version = "0.1.0"
dependencies = [
"bitflags",
"num-derive",
"num-traits",
]

View File

@ -1,4 +1,4 @@
use vspace::addr::{PhysAddr, VirtAddr};
use vspace::addr::VirtAddr;
extern "C" {
pub type ExternSymbol;
@ -20,11 +20,6 @@ impl ExternSymbol {
self.as_ptr() as usize
}
#[inline(always)]
pub fn as_phys_addr(&'static self) -> PhysAddr {
PhysAddr::from(self.as_usize())
}
#[inline(always)]
pub fn as_virt_addr(&'static self) -> VirtAddr {
VirtAddr::from(self.as_usize())

79
lib/vspace/Cargo.lock generated
View File

@ -1,79 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "vspace"
version = "0.1.0"
dependencies = [
"bitflags",
"num-derive",
"num-traits",
]

View File

@ -24,6 +24,9 @@ pub trait AddressOps: Copy + Clone + Default + Eq + Ord + PartialOrd + PartialEq
fn as_mut_ptr<T>(&self) -> *mut T {
self.as_usize() as *mut T
}
fn as_const_ptr<T>(&self) -> *const T {
self.as_usize() as *const T
}
fn as_u32(&self) -> u32;
fn as_u64(&self) -> u64;
fn as_usize(&self) -> usize;

View File

@ -7,9 +7,7 @@ pub enum TableLevel {
Level0 = 0, // KiloPage
Level1 = 1, // MegaPage
Level2 = 2, // GigaPage
#[cfg(not(feature = "legacy"))]
Level3 = 3, // TeraPage
#[cfg(not(feature = "legacy"))]
Level4 = 4, // PetaPage
}
@ -19,9 +17,7 @@ impl TableLevel {
Self::Level0 => None,
Self::Level1 => Some(Self::Level0),
Self::Level2 => Some(Self::Level1),
#[cfg(not(feature = "legacy"))]
Self::Level3 => Some(Self::Level2),
#[cfg(not(feature = "legacy"))]
Self::Level4 => Some(Self::Level3),
}
}
@ -31,9 +27,7 @@ impl TableLevel {
Self::Level0 => Some(Self::Level1),
Self::Level1 => Some(Self::Level2),
Self::Level2 => Some(Self::Level3),
#[cfg(not(feature = "legacy"))]
Self::Level3 => Some(Self::Level4),
#[cfg(not(feature = "legacy"))]
Self::Level4 => None,
}
}
@ -55,8 +49,7 @@ pub trait TableOps: Debug {
/// `location` must be a page-aligned virtual address and will not be dropped.
unsafe fn new(location: VirtAddr) -> &'static mut Self;
fn map(&mut self, from: VirtAddr, to: PhysAddr, attr: MapAttr, level: TableLevel)
-> PageResult;
fn map(&mut self, from: VirtAddr, to: PhysAddr, attr: MapAttr, level: TableLevel) -> PageResult;
fn unmap(&mut self, vaddr: VirtAddr) -> PageResult;
fn lookup(&mut self, vaddr: VirtAddr) -> Option<&Self::Entry>;

View File

@ -1,6 +1,8 @@
unstable_features = true
edition = "2021"
max_width = 125
blank_lines_lower_bound = 0
enum_discrim_align_threshold = 20
struct_field_align_threshold = 20

9
xtask/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "xtask"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0"
clap = { version = "4.5", features = ["derive"] }
xshell = "0.2"

131
xtask/src/artifact.rs Normal file
View File

@ -0,0 +1,131 @@
use anyhow::Result;
use clap::{Args, ValueEnum};
#[derive(ValueEnum, Copy, Clone)]
#[value(rename_all = "snake_case")]
pub enum Profile {
Debug,
Release,
}
#[derive(ValueEnum, Copy, Clone)]
#[value(rename_all = "snake_case")]
pub enum Arch {
RISCV64,
}
impl Arch {
const ARGS_BUILD_STD: [&'static str; 2] = [
"-Zbuild-std=core,compiler_builtins,alloc",
"-Zbuild-std-features=compiler-builtins-mem",
];
const FLAGS_RELOCATION: [&'static str; 3] =
["-Crelocation-model=static", "-Ccode-model=medium", "-Ctarget-feature=+relax"];
pub fn cargo_args(&self, test: bool) -> Vec<String> {
let mut args: Vec<String> = Vec::new();
if !test {
args.extend(Self::ARGS_BUILD_STD.iter().map(|s| s.to_string()).collect::<Vec<_>>());
}
args.push(format!("--target={}", self.triple()));
args
}
pub fn rust_flags(&self) -> Vec<String> {
let mut flags = Self::FLAGS_RELOCATION.iter().map(|s| s.to_string()).collect::<Vec<_>>();
match self {
Arch::RISCV64 => {
flags.push("-Clink-arg=-Tkernel/src/arch/riscv/linker64.ld".to_string());
flags
},
}
}
pub fn triple(&self) -> String {
match self {
Arch::RISCV64 => "riscv64imac-unknown-none-elf".to_string(),
}
}
pub fn bits(&self) -> u32 {
match self {
Arch::RISCV64 => 64,
}
}
pub fn board_arch_name(&self) -> String {
"riscv".to_string()
}
}
#[derive(ValueEnum, Copy, Clone)]
#[value(rename_all = "snake_case")]
pub enum Board {
Default,
Virt,
}
impl Board {
pub fn cargo_args(&self, arch: &Arch) -> Result<String> {
match self {
Board::Default => Ok(arch.board_arch_name().to_string() + ".board.default"),
Board::Virt => Ok(arch.board_arch_name().to_string() + ".board.virt"),
}
}
}
#[derive(Args)]
pub struct Artifact {
#[arg(long)]
pub arch: Arch,
#[arg(long)]
pub profile: Option<Profile>,
#[arg(long)]
pub board: Option<Board>,
#[arg(long)]
pub features: Vec<String>,
}
impl Artifact {
pub fn cargo_args(&self, test: bool) -> Result<Vec<String>> {
let mut args: Vec<String> = Vec::new();
let mut features: Vec<String> = Vec::new();
// profile
if let Some(Profile::Release) = self.profile {
args.push("--release".to_string());
}
// arch
args.extend(self.arch.cargo_args(test).iter().map(|s| s.to_string()));
// board
if let Some(board) = self.board {
features.push(board.cargo_args(&self.arch)?);
}
// features
features.extend(self.features.iter().map(|s| s.to_string()));
if !features.is_empty() {
args.push("--no-default-features".to_string());
args.push(format!("--features={}", features.join(",")));
}
Ok(args)
}
pub fn rust_flags(&self) -> Result<Vec<String>> {
let mut flags: Vec<String>;
let existing = std::env::var("CARGO_ENCODED_RUSTFLAGS").unwrap_or_default();
if !existing.is_empty() {
flags = existing.split('\x1f').map(|s| s.to_string()).collect::<Vec<_>>();
} else {
flags = Vec::new();
}
flags.extend(self.arch.rust_flags().iter().map(|s| s.to_string()));
Ok(flags)
}
}

24
xtask/src/build.rs Normal file
View File

@ -0,0 +1,24 @@
use crate::artifact::Artifact;
use anyhow::Result;
use clap::Args;
use xshell::cmd;
#[derive(Args)]
pub struct Build {
#[command(flatten)]
pub artifact: Artifact,
}
impl Build {
pub fn run(&self) -> Result<()> {
let sh = crate::shell()?;
cmd!(sh, "cargo build")
.env("CARGO_ENCODED_RUSTFLAGS", self.artifact.rust_flags()?.join("\x1f"))
.args(["--bin", "kernel"])
.args(self.artifact.cargo_args(false)?)
.run()?;
Ok(())
}
}

24
xtask/src/clippy.rs Normal file
View File

@ -0,0 +1,24 @@
use crate::artifact::Arch;
use anyhow::Result;
use clap::Args;
use xshell::cmd;
#[derive(Args)]
pub struct Clippy;
impl Clippy {
pub fn run(&self) -> Result<()> {
let sh = crate::shell()?;
{
let target = Arch::RISCV64;
cmd!(sh, "cargo clippy")
.arg("--target")
.arg(target.triple())
.args(["--no-deps", "--manifest-path", "kernel/Cargo.toml"])
.run()?;
}
Ok(())
}
}

36
xtask/src/main.rs Normal file
View File

@ -0,0 +1,36 @@
mod artifact;
mod build;
mod clippy;
mod test;
use anyhow::Result;
use clap::Parser;
use std::path::Path;
use xshell::Shell;
#[derive(Parser)]
enum Cli {
Build(build::Build),
Clippy(clippy::Clippy),
Test(test::Test),
}
impl Cli {
fn run(&self) -> Result<()> {
match self {
Cli::Build(build) => build.run(),
Cli::Clippy(clippy) => clippy.run(),
Cli::Test(ci) => ci.run(),
}
}
}
fn main() -> Result<()> {
Cli::parse().run()
}
pub fn shell() -> Result<Shell> {
let sh = Shell::new()?;
sh.change_dir(Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap());
Ok(sh)
}

23
xtask/src/test.rs Normal file
View File

@ -0,0 +1,23 @@
use crate::artifact::Artifact;
use clap::Args;
use xshell::cmd;
#[derive(Args)]
pub struct Test {
#[command(flatten)]
pub artifact: Artifact,
}
impl Test {
pub fn run(&self) -> anyhow::Result<()> {
let sh = crate::shell()?;
cmd!(sh, "cargo test")
.env("CARGO_ENCODED_RUSTFLAGS", self.artifact.rust_flags()?.join("\x1f"))
.args(["--bin", "kernel"])
.args(self.artifact.cargo_args(true)?)
.run()?;
Ok(())
}
}