Compare commits
1 commit
master
...
elfabiliti
Author | SHA1 | Date | |
---|---|---|---|
ab39b02bb9 |
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -3,9 +3,3 @@ ableos/target
|
||||||
aos_wasm_stress_test/target
|
aos_wasm_stress_test/target
|
||||||
facepalm/target
|
facepalm/target
|
||||||
shadeable/target
|
shadeable/target
|
||||||
userland/*/target
|
|
||||||
kernel/target
|
|
||||||
userland/root_fs/mnt/*
|
|
||||||
target/
|
|
||||||
|
|
||||||
!*/.gitkeep
|
|
||||||
|
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -2,5 +2,7 @@
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"stddef.h": "c"
|
"stddef.h": "c"
|
||||||
},
|
},
|
||||||
"rust-analyzer.checkOnSave.allTargets": false,
|
"settings": {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
1100
Cargo.lock
generated
1100
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
10
Cargo.toml
10
Cargo.toml
|
@ -1,10 +0,0 @@
|
||||||
[workspace]
|
|
||||||
|
|
||||||
members = [
|
|
||||||
"ableos",
|
|
||||||
"kernel",
|
|
||||||
"facepalm",
|
|
||||||
"shadeable",
|
|
||||||
"repbuild",
|
|
||||||
|
|
||||||
]
|
|
|
@ -1,15 +1,13 @@
|
||||||
[build]
|
[build]
|
||||||
# target = "riscv64gc-unknown-none-elf"
|
target = "./json_targets/x86_64-ableos.json"
|
||||||
target = "json_targets/x86_64-ableos.json"
|
|
||||||
|
|
||||||
[unstable]
|
[unstable]
|
||||||
build-std = ["core", "compiler_builtins", "alloc"]
|
build-std = ["core", "compiler_builtins", "alloc"]
|
||||||
build-std-features = ["compiler-builtins-mem"]
|
build-std-features = ["compiler-builtins-mem"]
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")']
|
[target.'cfg(target_arch = "x86_64")']
|
||||||
rustflags = ["-C", "target-feature=+rdrand"]
|
|
||||||
runner = "bootimage runner"
|
runner = "bootimage runner"
|
||||||
|
|
||||||
[target.riscv64gc-unknown-none-elf]
|
[target.riscv64gc-unknown-none-elf]
|
||||||
rustflags = "-C link-arg=-Tableos/src/arch/riscv/virt.lds"
|
rustflags = "-C link-arg=-T../ableos/src/arch/riscv/virt.lds"
|
||||||
# ableos/src/arch/riscv/virt.lds
|
|
||||||
|
|
398
ableos/Cargo.lock
generated
398
ableos/Cargo.lock
generated
|
@ -4,9 +4,9 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ab_glyph"
|
name = "ab_glyph"
|
||||||
version = "0.2.15"
|
version = "0.2.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24606928a235e73cdef55a0c909719cadd72fce573e5713d58cb2952d8f5794c"
|
checksum = "61caed9aec6daeee1ea38ccf5fb225e4f96c1eeead1b4a5c267324a63cf02326"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph_rasterizer",
|
"ab_glyph_rasterizer",
|
||||||
"libm",
|
"libm",
|
||||||
|
@ -24,64 +24,36 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ableos"
|
name = "ableos"
|
||||||
version = "0.1.1"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph",
|
"ab_glyph",
|
||||||
"acpi",
|
|
||||||
"axel",
|
|
||||||
"bootloader",
|
"bootloader",
|
||||||
"cpuio",
|
"cpuio",
|
||||||
"ext2",
|
|
||||||
"externc-libm",
|
"externc-libm",
|
||||||
"facepalm",
|
"facepalm",
|
||||||
"genfs",
|
"hashbrown",
|
||||||
"hashbrown 0.7.2",
|
|
||||||
"kernel",
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libwasm",
|
|
||||||
"linked_list_allocator",
|
"linked_list_allocator",
|
||||||
"lliw",
|
"lliw",
|
||||||
"log",
|
"log",
|
||||||
"logos",
|
|
||||||
"pc-beeper",
|
|
||||||
"pic8259",
|
"pic8259",
|
||||||
"picorand",
|
"picorand",
|
||||||
"pretty-hex",
|
"pretty-hex",
|
||||||
"rdrand",
|
|
||||||
"rhai",
|
|
||||||
"riscv",
|
|
||||||
"rkyv",
|
"rkyv",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"shadeable",
|
"shadeable",
|
||||||
"spin 0.5.2",
|
"smoltcp",
|
||||||
"toml",
|
"spin",
|
||||||
"uart_16550",
|
"uart_16550",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"vga",
|
"vga",
|
||||||
"volatile 0.2.7",
|
"volatile 0.2.7",
|
||||||
"wasmi",
|
"wasmi",
|
||||||
"watson",
|
|
||||||
"x86_64",
|
"x86_64",
|
||||||
"y-compositor-protocol",
|
"y-compositor-protocol",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "acpi"
|
|
||||||
version = "4.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "55237649c6e747ea67e5ed45125af5e6a35ea1250c5e44995eb6049a955bd004"
|
|
||||||
dependencies = [
|
|
||||||
"bit_field",
|
|
||||||
"log",
|
|
||||||
"rsdp",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ahash"
|
|
||||||
version = "0.3.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
@ -94,43 +66,11 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "0.7.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "axel"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "git+https://git.ablecorp.us/able/aos_userland#a96bc8b896fdee392e8f26125298da6b4b21dd9a"
|
|
||||||
dependencies = [
|
|
||||||
"hashbrown 0.7.2",
|
|
||||||
"log",
|
|
||||||
"logos",
|
|
||||||
"versioning",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bare-metal"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "beef"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bed554bd50246729a1ec158d08aa3235d1b69d94ad120ebe187e28894787e736"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit_field"
|
name = "bit_field"
|
||||||
|
@ -146,9 +86,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bootloader"
|
name = "bootloader"
|
||||||
version = "0.9.22"
|
version = "0.9.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de78decc37247c7cfac5dbf3495c7298c6ac97cb355161caa7e15969c6648e6c"
|
checksum = "a62c8f6168cd106687ee36a2b71a46c4144d73399f72814104d33094b8092fd2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -219,17 +165,6 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ext2"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "git+https://git.ablecorp.us/able/ext2-rs.git#15bcf9f72e2523e7ebe2a8d09c1231ca9139f326"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"genfs",
|
|
||||||
"rlibc",
|
|
||||||
"spin 0.9.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "externc-libm"
|
name = "externc-libm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -245,29 +180,17 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fnv"
|
|
||||||
version = "1.0.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "font8x8"
|
name = "font8x8"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
|
checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "genfs"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "65b9e52a0ffd4c2f11f9f84e8885a40cb99f490971eee78bbd7ddffd6ac023d6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.5"
|
version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
|
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -276,21 +199,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.7.2"
|
version = "0.11.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "96282e96bfcd3da0d3aa9938bedf1e50df3269b6db08b4876d2da0bb1a0841cf"
|
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash 0.3.8",
|
"ahash",
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.12.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758"
|
|
||||||
dependencies = [
|
|
||||||
"ahash 0.7.6",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -303,13 +216,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel"
|
name = "itoa"
|
||||||
version = "0.1.2"
|
version = "1.0.1"
|
||||||
dependencies = [
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"lazy_static",
|
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||||
"log",
|
|
||||||
"versioning",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
|
@ -317,25 +227,20 @@ version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"spin 0.5.2",
|
"spin",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.119"
|
version = "0.2.112"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
|
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.2.2"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db"
|
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libwasm"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "git+https://git.ablecorp.us/able/libwasm.git#aa1f7d5c0985649b6d73249dcad908272e82d7eb"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked_list_allocator"
|
name = "linked_list_allocator"
|
||||||
|
@ -354,9 +259,9 @@ checksum = "2d502c8bcc35a4f7ca9a7ffb7ac27b15ba30b1b92c2d69a1e4437e2635d73af7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.6"
|
version = "0.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
|
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
@ -371,34 +276,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "logos"
|
name = "managed"
|
||||||
version = "0.12.0"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "427e2abca5be13136da9afdbf874e6b34ad9001dd70f2b103b083a85daa7b345"
|
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
|
||||||
dependencies = [
|
|
||||||
"logos-derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "logos-derive"
|
|
||||||
version = "0.12.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56a7d287fd2ac3f75b11f19a1c8a874a7d55744bd91f7a1b3e7cf87d4343c36d"
|
|
||||||
dependencies = [
|
|
||||||
"beef",
|
|
||||||
"fnv",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"regex-syntax",
|
|
||||||
"syn",
|
|
||||||
"utf8-ranges",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memory_units"
|
name = "memory_units"
|
||||||
|
@ -445,15 +326,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.10.0"
|
version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owned_ttf_parser"
|
name = "owned_ttf_parser"
|
||||||
version = "0.15.0"
|
version = "0.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fb1e509cfe7a12db2a90bfa057dfcdbc55a347f5da677c506b53dd099cfec9d"
|
checksum = "4ef05f2882a8b3e7acc10c153ade2631f7bfc8ce00d2bf3fb8f4e9d2ae6ea5c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ttf-parser",
|
"ttf-parser",
|
||||||
]
|
]
|
||||||
|
@ -464,14 +345,6 @@ version = "0.42.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92"
|
checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pc-beeper"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "git+https://github.com/AbleOS/pc-beeper#9b61a9d60552a9da4285f5ceb39ab2cccbb60b4b"
|
|
||||||
dependencies = [
|
|
||||||
"x86_64",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pic8259"
|
name = "pic8259"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
|
@ -530,53 +403,20 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.15"
|
version = "1.0.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rdrand"
|
|
||||||
version = "0.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c4e0d5cb05cb40e4e5805399c27b12a064427cf553081ae9b82bc1a88111a576"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "1.5.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.6.25"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rhai"
|
name = "rhai"
|
||||||
version = "1.6.1"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ef3d57e55ca044c53ced279d2d3ee9df229b247556b005a23713d5206a2ecfc"
|
checksum = "2c7433068977c56619bf2b7831da26eb986d0645fe56f2ad9357eda7ae4c435e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash 0.7.6",
|
"ahash",
|
||||||
"bitflags",
|
|
||||||
"core-error",
|
"core-error",
|
||||||
"instant",
|
"instant",
|
||||||
"libm",
|
"libm",
|
||||||
|
@ -589,43 +429,22 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rhai_codegen"
|
name = "rhai_codegen"
|
||||||
version = "1.4.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "faa0ff1c9dc19c9f8bba510a2a75d3f0449f6233570c2672c7e31c692a11a59a"
|
checksum = "e02d33d76a7aa8ec72ac8298d5b52134fd2dff77445ada0c65f6f8c40d8f2931"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "riscv"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba"
|
|
||||||
dependencies = [
|
|
||||||
"bare-metal",
|
|
||||||
"bit_field",
|
|
||||||
"riscv-target",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "riscv-target"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
"regex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rkyv"
|
name = "rkyv"
|
||||||
version = "0.7.35"
|
version = "0.7.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2cdcf5caf69bcc87b1e3f5427b4f21a32fdd53c2847687bdf9861abb1cdaa0d8"
|
checksum = "49a37de5dfc60bae2d94961dacd03c7b80e426b66a99fa1b17799570dbdd8f96"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown 0.12.0",
|
"hashbrown",
|
||||||
"ptr_meta",
|
"ptr_meta",
|
||||||
"rkyv_derive",
|
"rkyv_derive",
|
||||||
"seahash",
|
"seahash",
|
||||||
|
@ -633,9 +452,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rkyv_derive"
|
name = "rkyv_derive"
|
||||||
version = "0.7.35"
|
version = "0.7.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a6cf557da1f81b8c7e889c59c9c3abaf6978f7feb156b9579e4f8bf6d7a2bada"
|
checksum = "719d447dd0e84b23cee6cb5b32d97e21efb112a3e3c636c8da36647b938475a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -643,19 +462,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rlibc"
|
name = "ryu"
|
||||||
version = "1.0.0"
|
version = "1.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe"
|
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rsdp"
|
|
||||||
version = "2.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "66d3add2fc55ef37511bcf81a08ee7a09eff07b23aae38b06a29024a38c604b1"
|
|
||||||
dependencies = [
|
|
||||||
"log",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
|
@ -671,24 +481,35 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.136"
|
version = "1.0.133"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
|
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.136"
|
version = "1.0.133"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
|
checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shadeable"
|
name = "shadeable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -696,6 +517,7 @@ dependencies = [
|
||||||
"libm",
|
"libm",
|
||||||
"log",
|
"log",
|
||||||
"rhai",
|
"rhai",
|
||||||
|
"vga",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -706,13 +528,23 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smartstring"
|
name = "smartstring"
|
||||||
version = "1.0.1"
|
version = "0.2.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
|
checksum = "31aa6a31c0c2b21327ce875f7e8952322acfcfd0c27569a6e18a647281352c9b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
"version_check",
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smoltcp"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2308a1657c8db1f5b4993bab4e620bdbe5623bd81f254cf60326767bb243237"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"byteorder",
|
||||||
|
"log",
|
||||||
|
"managed",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -721,15 +553,6 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "spin"
|
|
||||||
version = "0.9.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5"
|
|
||||||
dependencies = [
|
|
||||||
"lock_api",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spinning_top"
|
name = "spinning_top"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
|
@ -747,9 +570,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.86"
|
version = "1.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -765,20 +588,11 @@ dependencies = [
|
||||||
"crunchy",
|
"crunchy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.5.6"
|
|
||||||
source = "git+https://github.com/diondokter/toml-rs#c4161aa70202b3992dbec79b76e7a8659713b604"
|
|
||||||
dependencies = [
|
|
||||||
"hashbrown 0.7.2",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ttf-parser"
|
name = "ttf-parser"
|
||||||
version = "0.15.0"
|
version = "0.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c74c96594835e10fa545e2a51e8709f30b173a092bfd6036ef2cec53376244f3"
|
checksum = "4ccbe8381883510b6a2d8f1e32905bddd178c11caef8083086d0c0c9ab0ac281"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uart_16550"
|
name = "uart_16550"
|
||||||
|
@ -802,26 +616,12 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "utf8-ranges"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "versioning"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "git+https://git.ablecorp.us/able/aos_userland#a96bc8b896fdee392e8f26125298da6b4b21dd9a"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vga"
|
name = "vga"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
@ -878,27 +678,11 @@ dependencies = [
|
||||||
"parity-wasm",
|
"parity-wasm",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "watson"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1cea7ead78c402dbf14e7f11911b0b48955ea13d46e012e2d98775e23c65d4ef"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
"webassembly",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "webassembly"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1d1a10e1dedffff9cfcbdd33c289c65b87da634259a460a3f23d513649fa7a8c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x86_64"
|
name = "x86_64"
|
||||||
version = "0.14.8"
|
version = "0.14.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "958ab3202b01bc43ba2eb832102c4a487ed93151667a2289062e5f2b00058be2"
|
checksum = "fb611915c917c6296d11e23f71ff1ecfe49c5766daba92cd3df52df6b58285b6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
name = "ableos"
|
name = "ableos"
|
||||||
version = "0.1.1"
|
version = "0.1.0"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
@ -9,32 +9,25 @@ panic = "abort"
|
||||||
|
|
||||||
[package.metadata.bootimage]
|
[package.metadata.bootimage]
|
||||||
run-args = [
|
run-args = [
|
||||||
"--nodefaults",
|
|
||||||
"-cpu",
|
"-cpu",
|
||||||
"Broadwell-v3",
|
"kvm64-v1",
|
||||||
|
|
||||||
"-serial",
|
"-serial",
|
||||||
"stdio",
|
"stdio",
|
||||||
"-smp",
|
"-smp",
|
||||||
"cores=2",
|
"cores=2",
|
||||||
|
|
||||||
"-device",
|
|
||||||
"cirrus-vga",
|
|
||||||
|
|
||||||
# "-device",
|
# An example gpu used with ableOS
|
||||||
# "virtio-blk-pci,drive=drive0,id=virtblk0,num-queues=4",
|
"-device",
|
||||||
|
"virtio-gpu",
|
||||||
|
|
||||||
|
# An example disk used with ableOS
|
||||||
|
"-device",
|
||||||
|
"virtio-blk-pci,drive=drive0,id=virtblk0,num-queues=4",
|
||||||
# A simple example of a boot image
|
# A simple example of a boot image
|
||||||
# "-drive",
|
"-drive",
|
||||||
# "file=disk.qcow2,if=none,id=drive0",
|
"file=disk.qcow2,if=none,id=drive0",
|
||||||
|
|
||||||
"-device",
|
|
||||||
"virtio-rng",
|
|
||||||
|
|
||||||
"-qmp",
|
|
||||||
"unix:../qmp-sock,server,nowait"
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
test-args = [
|
test-args = [
|
||||||
"-device",
|
"-device",
|
||||||
"isa-debug-exit,iobase=0xf4,iosize=0x04",
|
"isa-debug-exit,iobase=0xf4,iosize=0x04",
|
||||||
|
@ -45,61 +38,43 @@ test-args = [
|
||||||
[dependencies]
|
[dependencies]
|
||||||
linked_list_allocator = "0.9.0"
|
linked_list_allocator = "0.9.0"
|
||||||
lliw = "0.2.0"
|
lliw = "0.2.0"
|
||||||
spin = "0.9"
|
# qoi_rs = "*"
|
||||||
|
spin = "0.5.2"
|
||||||
|
vga = "*"
|
||||||
log = "*"
|
log = "*"
|
||||||
pretty-hex = "0.2.1"
|
pretty-hex = "0.2.1"
|
||||||
unicode-width = "0.1.7"
|
unicode-width = "0.1.7"
|
||||||
picorand = "0.1.0"
|
picorand = "*"
|
||||||
watson = "0.4"
|
# watson = "0.4"
|
||||||
genfs = "0.1.0"
|
|
||||||
rhai = "1.6.0"
|
|
||||||
libwasm = {git="https://git.ablecorp.us:443/able/libwasm.git"}
|
|
||||||
axel = { git = "https://git.ablecorp.us/able/aos_userland" }
|
|
||||||
versioning = { git = "https://git.ablecorp.us/able/aos_userland" }
|
|
||||||
|
|
||||||
[dependencies.logos]
|
|
||||||
version = "0.12"
|
|
||||||
default-features = false
|
|
||||||
features = ["export_derive"]
|
|
||||||
|
|
||||||
[dependencies.rdrand]
|
|
||||||
version = "0.8"
|
|
||||||
default-features = false
|
|
||||||
|
|
||||||
[dependencies.kernel]
|
|
||||||
path = "../kernel"
|
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1.0"
|
version = "*"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["derive", "alloc"]
|
features = ["derive", "alloc"]
|
||||||
|
|
||||||
|
[dependencies.serde_json]
|
||||||
|
version = "*"
|
||||||
|
default-features = false
|
||||||
|
features = ["alloc"]
|
||||||
|
|
||||||
[dependencies.hashbrown]
|
[dependencies.hashbrown]
|
||||||
version = "0.7"
|
version = "*"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["inline-more"]
|
features = ["inline-more"]
|
||||||
|
|
||||||
[dependencies.rkyv]
|
[dependencies.rkyv]
|
||||||
version = "0.7"
|
version = "0.7.29"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["size_64", "alloc"]
|
features = ["size_64", "alloc"]
|
||||||
|
|
||||||
# [dependencies.smoltcp]
|
[dependencies.smoltcp]
|
||||||
# version = "0.8.0"
|
version = "0.8.0"
|
||||||
# default-features = false
|
default-features = false
|
||||||
# features = ["log", "proto-ipv4"]
|
features = ["log", "proto-ipv4"]
|
||||||
|
|
||||||
[dependencies.y-compositor-protocol]
|
[dependencies.y-compositor-protocol]
|
||||||
git = "https://git.ablecorp.us:443/able/y-compositor-protocol.git"
|
git = "https://git.ablecorp.us:443/able/y-compositor-protocol.git"
|
||||||
|
|
||||||
[dependencies.ext2]
|
|
||||||
git = "https://git.ablecorp.us:443/able/ext2-rs.git"
|
|
||||||
|
|
||||||
[dependencies.toml]
|
|
||||||
git = "https://github.com/diondokter/toml-rs"
|
|
||||||
# version = "0.5.8"
|
|
||||||
default-features = false
|
|
||||||
|
|
||||||
[dependencies.shadeable]
|
[dependencies.shadeable]
|
||||||
path = "../shadeable"
|
path = "../shadeable"
|
||||||
|
|
||||||
|
@ -116,14 +91,13 @@ default-features = false
|
||||||
features = ["core"]
|
features = ["core"]
|
||||||
version = "*"
|
version = "*"
|
||||||
|
|
||||||
|
[dependencies.lazy_static]
|
||||||
|
features = ["spin_no_std"]
|
||||||
|
version = "1.0"
|
||||||
|
|
||||||
[dependencies.externc-libm]
|
[dependencies.externc-libm]
|
||||||
git = "https://git.ablecorp.us:443/able/externc-libm.git"
|
git = "https://git.ablecorp.us:443/able/externc-libm.git"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(target_arch = "riscv")'.dependencies]
|
|
||||||
riscv="*"
|
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||||
bootloader = { version = "0.9.8", features = ["map_physical_memory"] }
|
bootloader = { version = "0.9.8", features = ["map_physical_memory"] }
|
||||||
cpuio = { git = "https://git.ablecorp.us/ondra05/cpuio.git" }
|
cpuio = { git = "https://git.ablecorp.us/ondra05/cpuio.git" }
|
||||||
|
@ -131,6 +105,3 @@ pic8259 = "0.10.1"
|
||||||
uart_16550 = "0.2.0"
|
uart_16550 = "0.2.0"
|
||||||
volatile = "0.2.6"
|
volatile = "0.2.6"
|
||||||
x86_64 = "*"
|
x86_64 = "*"
|
||||||
pc-beeper = {git = "https://github.com/AbleOS/pc-beeper"}
|
|
||||||
vga = "*"
|
|
||||||
acpi = "4.1.0"
|
|
|
@ -1,13 +0,0 @@
|
||||||
[boot]
|
|
||||||
system_processes = []
|
|
||||||
user_processes = ["shell"]
|
|
||||||
|
|
||||||
[logging]
|
|
||||||
enabled = true
|
|
||||||
level = "Trace"
|
|
||||||
log_to_serial = true
|
|
||||||
|
|
||||||
[tests]
|
|
||||||
run_tests = false
|
|
||||||
run_demos = false
|
|
||||||
run_shader_tests = false
|
|
7
ableos/assets/kernel_config.json
Normal file
7
ableos/assets/kernel_config.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"logging_level": "Trace",
|
||||||
|
"logger_padding": 10,
|
||||||
|
"run_tests": false,
|
||||||
|
"run_demos": false,
|
||||||
|
"run_shader_tests": false
|
||||||
|
}
|
|
@ -1,17 +0,0 @@
|
||||||
pub struct KeyEvent{
|
|
||||||
lctrl 1
|
|
||||||
rctrl 2
|
|
||||||
lalt 3
|
|
||||||
ralt 4
|
|
||||||
lsup 5
|
|
||||||
rsup 6
|
|
||||||
lshift 7
|
|
||||||
rshift 8
|
|
||||||
caps 9
|
|
||||||
|
|
||||||
down 10
|
|
||||||
# Keycodes
|
|
||||||
key 11-32
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
3
ableos/notes/GraphicsNote.md
Normal file
3
ableos/notes/GraphicsNote.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
wgpu
|
||||||
|
|
||||||
|
write using wgpu and compiles to native/web
|
9
ableos/notes/NOTES.md
Normal file
9
ableos/notes/NOTES.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Don't keep piling on API shit
|
||||||
|
Good docs are a must!!!!!!!!!!!!
|
||||||
|
No Bloat
|
||||||
|
One thing One Way
|
||||||
|
Bloat makes M!nt sad
|
||||||
|
Have rust-like strings only
|
||||||
|
|
||||||
|
# Don't
|
||||||
|
memory gun
|
1
ableos/notes/UNICODE_PRIV.md
Normal file
1
ableos/notes/UNICODE_PRIV.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
start custom unicode at E100
|
3
ableos/notes/USER.md
Normal file
3
ableos/notes/USER.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
user
|
||||||
|
> execute
|
||||||
|
> file system
|
17
ableos/notes/pci_tree.md
Normal file
17
ableos/notes/pci_tree.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
VGA
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pcie
|
||||||
|
gpu
|
||||||
|
amd
|
||||||
|
ati
|
||||||
|
set_red
|
||||||
|
ssd
|
|
@ -1,7 +1,9 @@
|
||||||
|
use alloc::string::{String, ToString};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
pub static ALIAS_TABLE: spin::Mutex<AliasTable> = spin::Mutex::new(AliasTable::new());
|
lazy_static::lazy_static! {
|
||||||
|
pub static ref ALIAS_TABLE: spin::Mutex<AliasTable> = spin::Mutex::new(AliasTable::new());
|
||||||
|
}
|
||||||
/// A table of aliases
|
/// A table of aliases
|
||||||
///
|
///
|
||||||
/// This is used to allow users to specify aliases for files and commands
|
/// This is used to allow users to specify aliases for files and commands
|
||||||
|
@ -15,7 +17,6 @@ impl AliasTable {
|
||||||
table: HashMap::new(),
|
table: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_alias(&mut self, alias: String, path: String) {
|
pub fn add_alias(&mut self, alias: String, path: String) {
|
||||||
self.table.insert(alias, path);
|
self.table.insert(alias, path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
//! The allocator to be implemented by ableOS
|
/*!
|
||||||
|
The allocator to be implemented by ableOS
|
||||||
|
*/
|
||||||
|
|
||||||
use alloc::alloc::{GlobalAlloc, Layout};
|
use alloc::alloc::{GlobalAlloc, Layout};
|
||||||
use core::ptr::null_mut;
|
use core::ptr::null_mut;
|
||||||
|
|
||||||
pub struct AAloc;
|
pub struct AAloc;
|
||||||
|
|
||||||
unsafe impl GlobalAlloc for AAloc {
|
unsafe impl GlobalAlloc for AAloc {
|
||||||
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
|
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
|
||||||
println!("Allocating memory");
|
|
||||||
|
|
||||||
println!("{}", _layout.size());
|
|
||||||
println!("{}", _layout.align());
|
|
||||||
|
|
||||||
null_mut()
|
null_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,21 @@
|
||||||
mod aalloc;
|
mod aalloc;
|
||||||
|
|
||||||
use linked_list_allocator::LockedHeap;
|
|
||||||
|
|
||||||
pub const HEAP_START: usize = 0x_4444_4444_0000;
|
pub const HEAP_START: usize = 0x_4444_4444_0000;
|
||||||
|
/// 131072 bytes
|
||||||
|
// pub const HEAP_MULTIPLIER: usize = 1024;
|
||||||
pub const HEAP_MULTIPLIER: usize = 100000;
|
pub const HEAP_MULTIPLIER: usize = 100000;
|
||||||
|
|
||||||
pub const HEAP_BASE: usize = 100;
|
pub const HEAP_BASE: usize = 100;
|
||||||
|
|
||||||
pub const HEAP_SIZE: usize = HEAP_BASE * HEAP_MULTIPLIER;
|
pub const HEAP_SIZE: usize = HEAP_BASE * HEAP_MULTIPLIER;
|
||||||
|
// X86 alloc should be in arch/drivers/x86/alloc.rs
|
||||||
|
|
||||||
|
/*
|
||||||
|
use crate::arch::drivers::allocator::Dummy;
|
||||||
|
#[global_allocator]
|
||||||
|
static ALLOCATOR: Dummy = Dummy;
|
||||||
|
*/
|
||||||
|
use linked_list_allocator::LockedHeap;
|
||||||
|
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
pub static ALLOCATOR: LockedHeap = LockedHeap::empty();
|
pub static ALLOCATOR: LockedHeap = LockedHeap::empty();
|
||||||
|
|
|
@ -2,6 +2,7 @@ use alloc::alloc::{GlobalAlloc, Layout};
|
||||||
use core::ptr::null_mut;
|
use core::ptr::null_mut;
|
||||||
|
|
||||||
pub struct Dummy;
|
pub struct Dummy;
|
||||||
|
|
||||||
unsafe impl GlobalAlloc for Dummy {
|
unsafe impl GlobalAlloc for Dummy {
|
||||||
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
|
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
|
||||||
null_mut()
|
null_mut()
|
||||||
|
|
|
@ -7,27 +7,21 @@ impl Graphics for GraphicsBuffer {
|
||||||
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb) {
|
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb) {
|
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_circle(coords: Point, radius: u32) {
|
fn put_circle(coords: Point, radius: u32) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb) {
|
fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_pixel(coords: Point, color: Rgb) {
|
fn put_pixel(coords: Point, color: Rgb) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_cursor(coords: Point) {
|
fn paint_cursor(coords: Point) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hide_cursor() {}
|
fn hide_cursor() {}
|
||||||
fn show_cursor() {}
|
fn show_cursor() {}
|
||||||
fn draw() {}
|
fn draw() {}
|
||||||
|
|
|
@ -1,8 +1,36 @@
|
||||||
//! A not-very-useful abstraction of GPIOs in Rust
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
// A not-very-useful abstraction of GPIOs in Rust
|
||||||
|
|
||||||
use core::sync::atomic::{AtomicBool, Ordering::SeqCst};
|
use core::sync::atomic::{AtomicBool, Ordering::SeqCst};
|
||||||
|
|
||||||
|
/// A struct that represents an nRF52 Pin
|
||||||
|
pub struct Pin(u8);
|
||||||
|
|
||||||
|
/// A struct that represents P0 of the nRF52
|
||||||
|
pub struct Pins {
|
||||||
|
pub p0_31: Pin,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pins {
|
||||||
|
/// A function to obtain a Port 0 singleton structure
|
||||||
|
pub fn take() -> Self {
|
||||||
|
static TAKEN: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
|
// Enforce this as a singleton
|
||||||
|
assert!(!TAKEN.swap(true, SeqCst));
|
||||||
|
|
||||||
|
Self { p0_31: Pin(31) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The level of a GPIO
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub enum Level {
|
||||||
|
Low,
|
||||||
|
High,
|
||||||
|
}
|
||||||
|
|
||||||
const REG_P0_PIN_CNF_BASE: *mut u32 = 0x5000_0700 as *mut u32;
|
const REG_P0_PIN_CNF_BASE: *mut u32 = 0x5000_0700 as *mut u32;
|
||||||
const REG_P0_OUT_SET: *mut u32 = 0x5000_0508 as *mut u32;
|
const REG_P0_OUT_SET: *mut u32 = 0x5000_0508 as *mut u32;
|
||||||
const REG_P0_OUT_CLR: *mut u32 = 0x5000_050C as *mut u32;
|
const REG_P0_OUT_CLR: *mut u32 = 0x5000_050C as *mut u32;
|
||||||
|
@ -12,8 +40,7 @@ const PIN_CNF_INPUT_CONNECT: u32 = 0x0000_0000;
|
||||||
const PIN_CNF_PULL_DISABLED: u32 = 0x0000_0000;
|
const PIN_CNF_PULL_DISABLED: u32 = 0x0000_0000;
|
||||||
const PIN_CNF_DRIVE_S0S1: u32 = 0x0000_0000;
|
const PIN_CNF_DRIVE_S0S1: u32 = 0x0000_0000;
|
||||||
const PIN_CNF_SENSE_DISABLED: u32 = 0x0000_0000;
|
const PIN_CNF_SENSE_DISABLED: u32 = 0x0000_0000;
|
||||||
/// A struct that represents an nRF52 Pin
|
|
||||||
pub struct Pin(u8);
|
|
||||||
impl Pin {
|
impl Pin {
|
||||||
/// Set a pin to be a push pull output
|
/// Set a pin to be a push pull output
|
||||||
pub fn set_push_pull_output(&mut self, level: Level) {
|
pub fn set_push_pull_output(&mut self, level: Level) {
|
||||||
|
@ -44,27 +71,3 @@ impl Pin {
|
||||||
unsafe { core::ptr::write_volatile(REG_P0_OUT_CLR, 1 << (self.0 as u32)) }
|
unsafe { core::ptr::write_volatile(REG_P0_OUT_CLR, 1 << (self.0 as u32)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The level of a GPIO
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum Level {
|
|
||||||
Low,
|
|
||||||
High,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A struct that represents P0 of the nRF52
|
|
||||||
pub struct Pins {
|
|
||||||
pub p0_31: Pin,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Pins {
|
|
||||||
/// A function to obtain a Port 0 singleton structure
|
|
||||||
pub fn take() -> Self {
|
|
||||||
static TAKEN: AtomicBool = AtomicBool::new(false);
|
|
||||||
|
|
||||||
// Enforce this as a singleton
|
|
||||||
assert!(!TAKEN.swap(true, SeqCst));
|
|
||||||
|
|
||||||
Self { p0_31: Pin(31) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
use core::ptr;
|
||||||
|
|
||||||
|
// mod panic;
|
||||||
pub mod drivers;
|
pub mod drivers;
|
||||||
pub mod init;
|
pub mod init;
|
||||||
|
|
||||||
use crate::arch::drivers::nrf52::{Level, Pins};
|
use crate::arch::drivers::nrf52::{Level, Pins};
|
||||||
use core::ptr;
|
|
||||||
use core::ptr::write_volatile;
|
use core::ptr::write_volatile;
|
||||||
|
|
||||||
global_asm!(include_str!("boot.s"));
|
global_asm!(include_str!("boot.s"));
|
||||||
|
|
||||||
fn delay(ticks: usize) {
|
fn delay(ticks: usize) {
|
||||||
|
@ -32,6 +33,7 @@ pub extern "C" fn not_main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// let gpios = Pins::take();
|
// let gpios = Pins::take();
|
||||||
// let mut led = gpios.p0_31;
|
// let mut led = gpios.p0_31;
|
||||||
//
|
//
|
||||||
|
@ -44,15 +46,14 @@ pub extern "C" fn not_main() {
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// led.set_push_pull_output(Level::Low);
|
// led.set_push_pull_output(Level::Low);
|
||||||
|
|
||||||
crate::kmain::kernel_main();
|
crate::kmain::kernel_main();
|
||||||
|
|
||||||
sloop();
|
sloop();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sloop() -> ! {
|
pub fn sloop() -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print() {
|
pub fn print() {
|
||||||
for byte in b"ableOS Arm 64" {
|
for byte in b"ableOS Arm 64" {
|
||||||
const UART0: *mut u8 = 0x0900_0000 as *mut u8;
|
const UART0: *mut u8 = 0x0900_0000 as *mut u8;
|
||||||
|
|
|
@ -2,6 +2,7 @@ use alloc::alloc::{GlobalAlloc, Layout};
|
||||||
use core::ptr::null_mut;
|
use core::ptr::null_mut;
|
||||||
|
|
||||||
pub struct Dummy;
|
pub struct Dummy;
|
||||||
|
|
||||||
unsafe impl GlobalAlloc for Dummy {
|
unsafe impl GlobalAlloc for Dummy {
|
||||||
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
|
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
|
||||||
null_mut()
|
null_mut()
|
||||||
|
|
|
@ -7,27 +7,21 @@ impl Graphics for GraphicsBuffer {
|
||||||
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb) {
|
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb) {
|
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_circle(coords: Point, radius: u32) {
|
fn put_circle(coords: Point, radius: u32) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb) {
|
fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_pixel(coords: Point, color: Rgb) {
|
fn put_pixel(coords: Point, color: Rgb) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_cursor(coords: Point) {
|
fn paint_cursor(coords: Point) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hide_cursor() {}
|
fn hide_cursor() {}
|
||||||
fn show_cursor() {}
|
fn show_cursor() {}
|
||||||
fn draw() {}
|
fn draw() {}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// We label the mmio function unsafe since
|
|
||||||
/// we will be working with raw memory. Rust cannot
|
|
||||||
/// make any guarantees when we do this.
|
|
||||||
#[inline(always)]
|
|
||||||
fn mmio_write(address: usize, offset: usize, value: u8) {
|
|
||||||
// Set the pointer based off of the address
|
|
||||||
let reg = address as *mut u8;
|
|
||||||
|
|
||||||
// write_volatile is a member of the *mut raw
|
|
||||||
// and we can use the .add() to give us another pointer
|
|
||||||
// at an offset based on the original pointer's memory
|
|
||||||
// address. NOTE: The add uses pointer arithmetic so it is
|
|
||||||
// new_pointer = old_pointer + sizeof(pointer_type) * offset
|
|
||||||
unsafe {
|
|
||||||
reg.add(offset).write_volatile(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// We label the mmio function unsafe since
|
|
||||||
/// we will be working with raw memory. Rust cannot
|
|
||||||
/// make any guarantees when we do this.
|
|
||||||
fn mmio_read(address: usize, offset: usize, value: u8) -> u8 {
|
|
||||||
// Set the pointer based off of the address
|
|
||||||
let reg = address as *mut u8;
|
|
||||||
|
|
||||||
// read_volatile() is much like write_volatile() except it
|
|
||||||
// will grab 8-bits from the pointer and give that value to us.
|
|
||||||
// We don't add a semi-colon at the end here so that the value
|
|
||||||
// is "returned".
|
|
||||||
unsafe { reg.add(offset).read_volatile() }
|
|
||||||
}
|
|
|
@ -1,5 +1,3 @@
|
||||||
pub mod allocator;
|
pub mod allocator;
|
||||||
pub mod graphics;
|
pub mod graphics;
|
||||||
pub mod mmio;
|
pub mod serial;
|
||||||
pub mod sysinfo;
|
|
||||||
pub mod uart;
|
|
||||||
|
|
47
ableos/src/arch/riscv/drivers/serial.rs
Normal file
47
ableos/src/arch/riscv/drivers/serial.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/// Prints to the host through the serial interface.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! serial_print {
|
||||||
|
($($arg:tt)*) => {
|
||||||
|
crate::arch::drivers::serial::SERIAL.lock().out(format_args!($($arg)*))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/// Prints to the host through the serial interface, appending a newline.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! serial_println {
|
||||||
|
() => {
|
||||||
|
crate::arch::drivers::serial::SERIAL
|
||||||
|
.lock()
|
||||||
|
.out(format_args!("\r\n"))
|
||||||
|
};
|
||||||
|
|
||||||
|
($($arg:tt)*) => ($crate::print!("{}\r\n", format_args!($($arg)*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Serial123 {
|
||||||
|
uart_data: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serial123 {
|
||||||
|
pub fn out(&mut self, s: ::core::fmt::Arguments) {
|
||||||
|
let uart_data = self.uart_data as *mut u8;
|
||||||
|
for c in b"Hello, world!\n" {
|
||||||
|
unsafe { uart_data.write_volatile(*c) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref SERIAL: Mutex<Serial123> = {
|
||||||
|
let serial_port = Serial123 {
|
||||||
|
/// UART port for the serial bus
|
||||||
|
uart_data: 0x10000000,
|
||||||
|
};
|
||||||
|
Mutex::new(serial_port)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
use {
|
||||||
|
core::fmt::{Arguments, Error},
|
||||||
|
lazy_static::lazy_static,
|
||||||
|
spin::Mutex,
|
||||||
|
};
|
|
@ -1,23 +0,0 @@
|
||||||
pub fn sysinfo() {}
|
|
||||||
pub fn master() -> Option<Master> {
|
|
||||||
Some(Master {
|
|
||||||
brand_string: Some("riscv".to_string()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Master {
|
|
||||||
// TODO: Rename struct
|
|
||||||
// version_information: Option<VersionInformation>,
|
|
||||||
// thermal_power_management_information: Option<ThermalPowerManagementInformation>,
|
|
||||||
// structured_extended_information: Option<StructuredExtendedInformation>,
|
|
||||||
// extended_processor_signature: Option<ExtendedProcessorSignature>,
|
|
||||||
pub brand_string: Option<String>,
|
|
||||||
// cache_line: Option<CacheLine>,
|
|
||||||
// time_stamp_counter: Option<TimeStampCounter>,
|
|
||||||
// physical_address_size: Option<PhysicalAddressSize>,
|
|
||||||
}
|
|
||||||
impl Master {
|
|
||||||
pub fn brand_string(&self) -> Option<&str> {
|
|
||||||
self.brand_string.as_deref()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,129 +0,0 @@
|
||||||
use core::fmt::{Error, Write};
|
|
||||||
|
|
||||||
/// Initialize the UART driver by setting
|
|
||||||
/// the word length, FIFOs, and interrupts
|
|
||||||
pub fn uart_init(base_addr: usize) {
|
|
||||||
let ptr = base_addr as *mut u8;
|
|
||||||
unsafe {
|
|
||||||
// First, set the word length, which
|
|
||||||
// are bits 0, and 1 of the line control register (LCR)
|
|
||||||
// which is at base_address + 3
|
|
||||||
// We can easily write the value 3 here or 0b11, but I'm
|
|
||||||
// extending it so that it is clear we're setting two individual
|
|
||||||
// fields
|
|
||||||
// Word 0 Word 1
|
|
||||||
// ~~~~~~ ~~~~~~
|
|
||||||
let lcr = (1 << 0) | (1 << 1);
|
|
||||||
ptr.add(3).write_volatile(lcr);
|
|
||||||
|
|
||||||
// Now, enable the FIFO, which is bit index 0 of the FIFO
|
|
||||||
// control register (FCR at offset 2).
|
|
||||||
// Again, we can just write 1 here, but when we use left shift,
|
|
||||||
// it's easier to see that we're trying to write bit index #0.
|
|
||||||
ptr.add(2).write_volatile(1 << 0);
|
|
||||||
|
|
||||||
// Enable receiver buffer interrupts, which is at bit index
|
|
||||||
// 0 of the interrupt enable register (IER at offset 1).
|
|
||||||
ptr.add(1).write_volatile(1 << 0);
|
|
||||||
|
|
||||||
// If we cared about the divisor, the code below would set the divisor
|
|
||||||
// from a global clock rate of 22.729 MHz (22,729,000 cycles per second)
|
|
||||||
// to a signaling rate of 2400 (BAUD). We usually have much faster signalling
|
|
||||||
// rates nowadays, but this demonstrates what the divisor actually does.
|
|
||||||
// The formula given in the NS16500A specification for calculating the divisor
|
|
||||||
// is:
|
|
||||||
// divisor = ceil( (clock_hz) / (baud_sps x 16) )
|
|
||||||
// So, we substitute our values and get:
|
|
||||||
// divisor = ceil( 22_729_000 / (2400 x 16) )
|
|
||||||
// divisor = ceil( 22_729_000 / 38_400 )
|
|
||||||
// divisor = ceil( 591.901 ) = 592
|
|
||||||
|
|
||||||
// The divisor register is two bytes (16 bits), so we need to split the value
|
|
||||||
// 592 into two bytes. Typically, we would calculate this based on measuring
|
|
||||||
// the clock rate, but again, for our purposes [qemu], this doesn't really do
|
|
||||||
// anything.
|
|
||||||
let divisor: u16 = 592;
|
|
||||||
let divisor_least: u8 = (divisor & 0xff).try_into().unwrap();
|
|
||||||
let divisor_most: u8 = (divisor >> 8).try_into().unwrap();
|
|
||||||
|
|
||||||
// Notice that the divisor register DLL (divisor latch least) and DLM (divisor
|
|
||||||
// latch most) have the same base address as the receiver/transmitter and the
|
|
||||||
// interrupt enable register. To change what the base address points to, we
|
|
||||||
// open the "divisor latch" by writing 1 into the Divisor Latch Access Bit
|
|
||||||
// (DLAB), which is bit index 7 of the Line Control Register (LCR) which
|
|
||||||
// is at base_address + 3.
|
|
||||||
ptr.add(3).write_volatile(lcr | 1 << 7);
|
|
||||||
|
|
||||||
// Now, base addresses 0 and 1 point to DLL and DLM, respectively.
|
|
||||||
// Put the lower 8 bits of the divisor into DLL
|
|
||||||
ptr.add(0).write_volatile(divisor_least);
|
|
||||||
ptr.add(1).write_volatile(divisor_most);
|
|
||||||
|
|
||||||
// Now that we've written the divisor, we never have to touch this again. In
|
|
||||||
// hardware, this will divide the global clock (22.729 MHz) into one suitable
|
|
||||||
// for 2,400 signals per second. So, to once again get access to the
|
|
||||||
// RBR/THR/IER registers, we need to close the DLAB bit by clearing it to 0.
|
|
||||||
ptr.add(3).write_volatile(lcr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn uart_get(base_addr: usize) -> Option<u8> {
|
|
||||||
let ptr = base_addr as *mut u8;
|
|
||||||
unsafe {
|
|
||||||
// Bit index #5 is the Line Control Register.
|
|
||||||
if ptr.add(5).read_volatile() & 1 == 0 {
|
|
||||||
// The DR bit is 0, meaning no data
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
// The DR bit is 1, meaning data!
|
|
||||||
Some(ptr.add(0).read_volatile())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn uart_put(base_addr: usize, c: u8) {
|
|
||||||
let ptr = base_addr as *mut u8;
|
|
||||||
unsafe {
|
|
||||||
// If we get here, the transmitter is empty, so transmit
|
|
||||||
// our stuff!
|
|
||||||
ptr.add(0).write_volatile(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Uart {
|
|
||||||
base_address: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Uart {
|
|
||||||
pub fn new(base_address: usize) -> Self {
|
|
||||||
Uart { base_address }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self) -> Option<u8> {
|
|
||||||
uart_get(self.base_address)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn put(&self, c: u8) {
|
|
||||||
uart_put(self.base_address, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(&self) {
|
|
||||||
uart_init(self.base_address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a slightly different syntax. Write is this "trait", meaning it is much like
|
|
||||||
// an interface where we're just guaranteeing a certain function signature. In the Write
|
|
||||||
// trait, one is absolutely required to be implemented, which is write_str. There are other
|
|
||||||
// functions, but they all rely on write_str(), so their default implementation is OK for now.
|
|
||||||
impl Write for Uart {
|
|
||||||
// The trait Write expects us to write the function write_str
|
|
||||||
// which looks like:
|
|
||||||
fn write_str(&mut self, s: &str) -> Result<(), Error> {
|
|
||||||
for c in s.bytes() {
|
|
||||||
self.put(c);
|
|
||||||
}
|
|
||||||
// Return that we succeeded.
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,5 @@
|
||||||
pub mod drivers;
|
pub mod drivers;
|
||||||
pub mod init;
|
pub mod init;
|
||||||
|
|
||||||
use crate::print;
|
|
||||||
use crate::println;
|
|
||||||
use core::arch::asm;
|
|
||||||
|
|
||||||
#[naked]
|
#[naked]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn _boot() -> ! {
|
unsafe extern "C" fn _boot() -> ! {
|
||||||
|
@ -36,64 +31,19 @@ unsafe extern "C" fn _boot() -> ! {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn _start() -> ! {
|
extern "C" fn _start() -> ! {
|
||||||
use crate::serial_println;
|
/*
|
||||||
|
let uart_data = 0x10000000 as *mut u8;
|
||||||
let uart = crate::arch::drivers::uart::Uart::new(0x1000_0000);
|
for c in b"Hardcoded serial output\n" {
|
||||||
uart.init();
|
unsafe { uart_data.write_volatile(*c) };
|
||||||
serial_println!("Hello, world!\r");
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if let Some(c) = uart.get() {
|
|
||||||
match c {
|
|
||||||
66 => break,
|
|
||||||
10 | 13 => {
|
|
||||||
uart.put('\n' as u8);
|
|
||||||
uart.put('\r' as u8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
91 => {
|
|
||||||
if let Some(ch) = uart.get() {
|
|
||||||
match ch as char {
|
|
||||||
'A' => {
|
|
||||||
serial_println!("That's the up arrow!");
|
|
||||||
}
|
|
||||||
'B' => {
|
|
||||||
serial_println!("That's the down arrow!");
|
|
||||||
}
|
|
||||||
'C' => {
|
|
||||||
serial_println!("That's the right arrow!");
|
|
||||||
}
|
|
||||||
'D' => {
|
|
||||||
serial_println!("That's the left arrow!");
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
serial_println!("That's something else!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
_ => {
|
|
||||||
uart.put(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
serial_println!("Serial connection closed.\r");
|
crate::serial_print!("Hi");
|
||||||
|
crate::kmain::kernel_main();
|
||||||
sloop()
|
sloop()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sloop() -> ! {
|
pub fn sloop() -> ! {
|
||||||
loop {
|
loop {
|
||||||
unsafe {
|
unsafe { asm!("nop") };
|
||||||
asm!("wfi");
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shutdown() {}
|
|
||||||
pub fn generate_process_pass() -> u128 {
|
|
||||||
123
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::allocator::{HEAP_SIZE, HEAP_START};
|
|
||||||
use alloc::alloc::{GlobalAlloc, Layout};
|
use alloc::alloc::{GlobalAlloc, Layout};
|
||||||
|
// use core::alloc::{GlobalAlloc, Layout};
|
||||||
|
use crate::allocator::{HEAP_SIZE, HEAP_START};
|
||||||
use core::ptr::null_mut;
|
use core::ptr::null_mut;
|
||||||
use x86_64::{
|
use x86_64::{
|
||||||
structures::paging::{
|
structures::paging::{
|
||||||
|
@ -8,6 +9,7 @@ use x86_64::{
|
||||||
VirtAddr,
|
VirtAddr,
|
||||||
};
|
};
|
||||||
pub struct Dummy;
|
pub struct Dummy;
|
||||||
|
|
||||||
unsafe impl GlobalAlloc for Dummy {
|
unsafe impl GlobalAlloc for Dummy {
|
||||||
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
|
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
|
||||||
null_mut()
|
null_mut()
|
||||||
|
|
|
@ -8,32 +8,25 @@ impl Graphics for GraphicsBuffer {
|
||||||
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb) {
|
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb) {}
|
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb) {}
|
||||||
|
|
||||||
fn put_circle(coords: Point, radius: u32) {
|
fn put_circle(coords: Point, radius: u32) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb) {
|
fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_pixel(coords: Point, color: Rgb) {
|
fn put_pixel(coords: Point, color: Rgb) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_cursor(coords: Point) {
|
fn paint_cursor(coords: Point) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hide_cursor() {
|
fn hide_cursor() {
|
||||||
unsafe {
|
unsafe {
|
||||||
outw(0x0A, 0x3D4);
|
outw(0x0A, 0x3D4);
|
||||||
outw(0x20, 0x3D5);
|
outw(0x20, 0x3D5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_cursor() {}
|
fn show_cursor() {}
|
||||||
fn draw() {}
|
fn draw() {}
|
||||||
fn clear() {
|
fn clear() {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
pub mod allocator;
|
pub mod allocator;
|
||||||
pub mod graphics;
|
pub mod graphics;
|
||||||
pub mod serial;
|
pub mod serial;
|
||||||
pub mod sysinfo;
|
|
||||||
pub mod timer;
|
pub mod timer;
|
||||||
|
|
||||||
#[deprecated(note = "The use of hardware specific drivers for VGA is discouraged")]
|
// #[deprecated(note = "The use of hardware specific drivers for VGA is discouraged")]
|
||||||
pub mod vga;
|
pub mod vga;
|
||||||
|
|
|
@ -1,34 +1,33 @@
|
||||||
use spin::{Lazy, Mutex};
|
use lazy_static::lazy_static;
|
||||||
|
use spin::Mutex;
|
||||||
use uart_16550::SerialPort;
|
use uart_16550::SerialPort;
|
||||||
|
lazy_static! {
|
||||||
pub static SERIAL1: Lazy<Mutex<SerialPort>> = Lazy::new(|| {
|
pub static ref SERIAL1: Mutex<SerialPort> = {
|
||||||
let mut serial_port = unsafe { SerialPort::new(0x3F8) };
|
let mut serial_port = unsafe { SerialPort::new(0x3F8) };
|
||||||
serial_port.init();
|
serial_port.init();
|
||||||
Mutex::new(serial_port)
|
Mutex::new(serial_port)
|
||||||
});
|
};
|
||||||
|
}
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn _print(args: ::core::fmt::Arguments) {
|
pub fn _print(args: ::core::fmt::Arguments) {
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
SERIAL1
|
SERIAL1
|
||||||
.lock()
|
.lock()
|
||||||
.write_fmt(args)
|
.write_fmt(args)
|
||||||
.expect("Printing to serial failed");
|
.expect("Printing to serial failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints to the host through the serial interface.
|
/// Prints to the host through the serial interface.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! sprint {
|
macro_rules! serial_print {
|
||||||
($($arg:tt)*) => {
|
($($arg:tt)*) => {
|
||||||
$crate::arch::drivers::serial::_print(format_args!($($arg)*));
|
$crate::arch::drivers::serial::_print(format_args!($($arg)*));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints to the host through the serial interface, appending a newline.
|
/// Prints to the host through the serial interface, appending a newline.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! sprintln {
|
macro_rules! serial_println {
|
||||||
() => ($crate::sprint!("\n"));
|
() => ($crate::serial_print!("\n"));
|
||||||
($fmt:expr) => ($crate::sprint!(concat!($fmt, "\n")));
|
($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n")));
|
||||||
($fmt:expr, $($arg:tt)*) => ($crate::sprint!(
|
($fmt:expr, $($arg:tt)*) => ($crate::serial_print!(
|
||||||
concat!($fmt, "\n"), $($arg)*));
|
concat!($fmt, "\n"), $($arg)*));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
use core::fmt;
|
|
||||||
use spin::{Lazy, Mutex};
|
|
||||||
use volatile::Volatile;
|
|
||||||
|
|
||||||
const BUFFER_HEIGHT: usize = 25;
|
|
||||||
const BUFFER_WIDTH: usize = 80;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
@ -26,34 +19,31 @@ pub enum Color {
|
||||||
Yellow = 14,
|
Yellow = 14,
|
||||||
White = 15,
|
White = 15,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
struct ColorCode(u8);
|
struct ColorCode(u8);
|
||||||
impl ColorCode {
|
impl ColorCode {
|
||||||
const fn new(foreground: Color, background: Color) -> ColorCode {
|
fn new(foreground: Color, background: Color) -> ColorCode {
|
||||||
ColorCode((background as u8) << 4 | (foreground as u8))
|
ColorCode((background as u8) << 4 | (foreground as u8))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct ScreenChar {
|
struct ScreenChar {
|
||||||
ascii_character: u8,
|
ascii_character: u8,
|
||||||
color_code: ColorCode,
|
color_code: ColorCode,
|
||||||
}
|
}
|
||||||
|
const BUFFER_HEIGHT: usize = 25;
|
||||||
|
const BUFFER_WIDTH: usize = 80;
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
struct Buffer {
|
struct Buffer {
|
||||||
chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
|
chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Writer {
|
pub struct Writer {
|
||||||
column_position: usize,
|
column_position: usize,
|
||||||
color_code: ColorCode,
|
color_code: ColorCode,
|
||||||
buffer: &'static mut Buffer,
|
buffer: &'static mut Buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Writer {
|
impl Writer {
|
||||||
pub fn write_byte(&mut self, byte: u8) {
|
pub fn write_byte(&mut self, byte: u8) {
|
||||||
match byte {
|
match byte {
|
||||||
|
@ -73,7 +63,6 @@ impl Writer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_string(&mut self, s: &str) {
|
pub fn write_string(&mut self, s: &str) {
|
||||||
for byte in s.bytes() {
|
for byte in s.bytes() {
|
||||||
match byte {
|
match byte {
|
||||||
|
@ -84,7 +73,6 @@ impl Writer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_line(&mut self) {
|
fn new_line(&mut self) {
|
||||||
for row in 1..BUFFER_HEIGHT {
|
for row in 1..BUFFER_HEIGHT {
|
||||||
for col in 0..BUFFER_WIDTH {
|
for col in 0..BUFFER_WIDTH {
|
||||||
|
@ -95,7 +83,6 @@ impl Writer {
|
||||||
self.clear_row(BUFFER_HEIGHT - 1);
|
self.clear_row(BUFFER_HEIGHT - 1);
|
||||||
self.column_position = 0;
|
self.column_position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_row(&mut self, row: usize) {
|
fn clear_row(&mut self, row: usize) {
|
||||||
let blank = ScreenChar {
|
let blank = ScreenChar {
|
||||||
ascii_character: b' ',
|
ascii_character: b' ',
|
||||||
|
@ -121,33 +108,35 @@ impl Writer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Write for Writer {
|
impl fmt::Write for Writer {
|
||||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
self.write_string(s);
|
self.write_string(s);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lazy_static! {
|
||||||
pub static WRITER: Lazy<Mutex<Writer>> = Lazy::new(|| {
|
pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer {
|
||||||
Mutex::new(Writer {
|
|
||||||
column_position: 0,
|
column_position: 0,
|
||||||
color_code: ColorCode::new(Color::White, Color::Black),
|
color_code: ColorCode::new(Color::White, Color::Black),
|
||||||
buffer: unsafe { &mut *(0xb8000 as *mut Buffer) },
|
buffer: unsafe { &mut *(0xb8000 as *mut Buffer) },
|
||||||
})
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
use core::fmt;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use spin::Mutex;
|
||||||
|
|
||||||
|
use volatile::Volatile;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! kprint {
|
macro_rules! kprint {
|
||||||
($($arg:tt)*) => ($crate::arch::drivers::vga::_kprint(format_args!($($arg)*)));
|
($($arg:tt)*) => ($crate::arch::drivers::vga::_kprint(format_args!($($arg)*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! kprintln {
|
macro_rules! kprintln {
|
||||||
() => ($crate::kprint!("\n"));
|
() => ($crate::kprint!("\n"));
|
||||||
($($arg:tt)*) => ($crate::kprint!("{}\n", format_args!($($arg)*)));
|
($($arg:tt)*) => ($crate::kprint!("{}\n", format_args!($($arg)*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn _kprint(args: fmt::Arguments) {
|
pub fn _kprint(args: fmt::Arguments) {
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
|
|
@ -1,40 +1,39 @@
|
||||||
use spin::Lazy;
|
use lazy_static::lazy_static;
|
||||||
use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector};
|
use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector};
|
||||||
use x86_64::structures::tss::TaskStateSegment;
|
use x86_64::structures::tss::TaskStateSegment;
|
||||||
use x86_64::VirtAddr;
|
use x86_64::VirtAddr;
|
||||||
|
|
||||||
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
|
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
|
||||||
|
lazy_static! {
|
||||||
|
static ref TSS: TaskStateSegment = {
|
||||||
|
let mut tss = TaskStateSegment::new();
|
||||||
|
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
stack_start + STACK_SIZE
|
||||||
|
};
|
||||||
|
tss
|
||||||
|
};
|
||||||
|
}
|
||||||
struct Selectors {
|
struct Selectors {
|
||||||
code_selector: SegmentSelector,
|
code_selector: SegmentSelector,
|
||||||
tss_selector: SegmentSelector,
|
tss_selector: SegmentSelector,
|
||||||
}
|
}
|
||||||
|
lazy_static! {
|
||||||
static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
|
static ref GDT: (GlobalDescriptorTable, Selectors) = {
|
||||||
let mut tss = TaskStateSegment::new();
|
let mut gdt = GlobalDescriptorTable::new();
|
||||||
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
|
let code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
|
||||||
const STACK_SIZE: usize = 4096 * 5;
|
let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS));
|
||||||
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
(
|
||||||
|
gdt,
|
||||||
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
Selectors {
|
||||||
stack_start + STACK_SIZE
|
code_selector,
|
||||||
|
tss_selector,
|
||||||
|
},
|
||||||
|
)
|
||||||
};
|
};
|
||||||
tss
|
}
|
||||||
});
|
|
||||||
|
|
||||||
static GDT: Lazy<(GlobalDescriptorTable, Selectors)> = Lazy::new(|| {
|
|
||||||
let mut gdt = GlobalDescriptorTable::new();
|
|
||||||
let code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
|
|
||||||
let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS));
|
|
||||||
(
|
|
||||||
gdt,
|
|
||||||
Selectors {
|
|
||||||
code_selector,
|
|
||||||
tss_selector,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
use x86_64::instructions::segmentation::{Segment, CS};
|
use x86_64::instructions::segmentation::{Segment, CS};
|
||||||
use x86_64::instructions::tables::load_tss;
|
use x86_64::instructions::tables::load_tss;
|
||||||
|
|
|
@ -1,42 +1,26 @@
|
||||||
// #![allow(clippy::print_literal)]
|
// #![allow(clippy::print_literal)]
|
||||||
|
use crate::{logger, SCHEDULER};
|
||||||
|
|
||||||
use super::{gdt, interrupts};
|
use super::{gdt, interrupts};
|
||||||
use crate::{
|
|
||||||
logger,
|
|
||||||
scheduler::{capabilities::Capabilities, SCHEDULER},
|
|
||||||
serial_println,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// x86_64 initialization
|
/// x86_64 initialization
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
use crate::{
|
let result = logger::init();
|
||||||
network::socket::SimpleSock, relib::network::socket::Socket,
|
match result {
|
||||||
scheduler::priority::Priority::High, stdio::StdIO,
|
Ok(_) => {}
|
||||||
};
|
Err(err) => error!("{}", err),
|
||||||
|
}
|
||||||
|
gdt::init();
|
||||||
|
|
||||||
let mut log_socket_id = SimpleSock::new();
|
use crate::scheduler::Priority;
|
||||||
log_socket_id.register_protocol("Logger".to_string());
|
let mut scheduler = SCHEDULER.lock();
|
||||||
|
use Priority::*;
|
||||||
|
let process_0 = scheduler.new_process(High);
|
||||||
|
scheduler.add_process(process_0);
|
||||||
|
drop(scheduler);
|
||||||
|
|
||||||
let result = logger::init();
|
interrupts::init_idt();
|
||||||
match result {
|
|
||||||
Ok(_) => {
|
|
||||||
serial_println!("Logger initialized");
|
|
||||||
}
|
|
||||||
Err(err) => error!("{}", err),
|
|
||||||
}
|
|
||||||
|
|
||||||
gdt::init();
|
unsafe { interrupts::PICS.lock().initialize() };
|
||||||
|
x86_64::instructions::interrupts::enable();
|
||||||
let mut scheduler = SCHEDULER.lock();
|
|
||||||
let process_0 = scheduler.new_process(
|
|
||||||
Capabilities::empty(),
|
|
||||||
High,
|
|
||||||
"".to_string(),
|
|
||||||
StdIO::new("null".to_string()),
|
|
||||||
);
|
|
||||||
scheduler.add_process(process_0);
|
|
||||||
drop(scheduler);
|
|
||||||
|
|
||||||
interrupts::init_idt();
|
|
||||||
unsafe { interrupts::PICS.lock().initialize() };
|
|
||||||
x86_64::instructions::interrupts::enable();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,14 @@ use crate::{
|
||||||
arch::{drivers::vga::WRITER, gdt},
|
arch::{drivers::vga::WRITER, gdt},
|
||||||
kernel_state::KERNEL_STATE,
|
kernel_state::KERNEL_STATE,
|
||||||
print, println,
|
print, println,
|
||||||
rhai_shell::KEYBUFF,
|
|
||||||
};
|
};
|
||||||
use cpuio::outb;
|
|
||||||
use pic8259::ChainedPics;
|
|
||||||
use spin::Lazy;
|
|
||||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use pic8259::ChainedPics;
|
||||||
|
use spin;
|
||||||
|
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||||
pub const PIC_1_OFFSET: u8 = 32;
|
pub const PIC_1_OFFSET: u8 = 32;
|
||||||
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
|
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
|
||||||
|
|
||||||
pub static PICS: spin::Mutex<ChainedPics> =
|
pub static PICS: spin::Mutex<ChainedPics> =
|
||||||
spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
|
spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
|
||||||
|
|
||||||
|
@ -21,10 +19,7 @@ pub static PICS: spin::Mutex<ChainedPics> =
|
||||||
pub enum InterruptIndex {
|
pub enum InterruptIndex {
|
||||||
Timer = PIC_1_OFFSET,
|
Timer = PIC_1_OFFSET,
|
||||||
Keyboard,
|
Keyboard,
|
||||||
// SecondInterrupt = PIC_2_OFFSET,
|
|
||||||
Cmos = 0x70,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InterruptIndex {
|
impl InterruptIndex {
|
||||||
fn as_u8(self) -> u8 {
|
fn as_u8(self) -> u8 {
|
||||||
self as u8
|
self as u8
|
||||||
|
@ -33,49 +28,39 @@ impl InterruptIndex {
|
||||||
usize::from(self.as_u8())
|
usize::from(self.as_u8())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn init_idt() {
|
||||||
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
|
IDT.load();
|
||||||
let mut idt = InterruptDescriptorTable::new();
|
}
|
||||||
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
lazy_static! {
|
||||||
unsafe {
|
static ref IDT: InterruptDescriptorTable = {
|
||||||
idt.double_fault
|
let mut idt = InterruptDescriptorTable::new();
|
||||||
.set_handler_fn(double_fault_handler)
|
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
||||||
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
|
unsafe {
|
||||||
}
|
idt.double_fault.set_handler_fn(double_fault_handler)
|
||||||
|
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); // new
|
||||||
// This gives fast interrupts
|
}
|
||||||
set_pit_frequency(1000);
|
idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer_interrupt_handler);
|
||||||
|
idt[InterruptIndex::Keyboard.as_usize()] .set_handler_fn(keyboard_interrupt_handler);
|
||||||
idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer_interrupt_handler);
|
idt
|
||||||
idt[InterruptIndex::Keyboard.as_usize()].set_handler_fn(keyboard_interrupt_handler);
|
};
|
||||||
|
}
|
||||||
idt[6].set_handler_fn(floppy_disk_interrupt_handler);
|
|
||||||
|
|
||||||
idt
|
|
||||||
});
|
|
||||||
|
|
||||||
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
||||||
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
||||||
}
|
}
|
||||||
|
// new
|
||||||
extern "x86-interrupt" fn double_fault_handler(
|
extern "x86-interrupt" fn double_fault_handler(
|
||||||
stack_frame: InterruptStackFrame,
|
stack_frame: InterruptStackFrame,
|
||||||
error_code: u64,
|
_error_code: u64,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
panic!(
|
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
|
||||||
"EXCEPTION: Error code{}\nDOUBLE FAULT\n{:#?}",
|
|
||||||
error_code, stack_frame
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||||
kernel::tick();
|
crate::kmain::tick();
|
||||||
unsafe {
|
unsafe {
|
||||||
PICS.lock()
|
PICS.lock()
|
||||||
.notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
.notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||||
use crate::keyboard::{
|
use crate::keyboard::{
|
||||||
CustomLayout, CustomScancodeSet, DecodedKey, DecodedKeyKind, HandleControl, KeyCode,
|
CustomLayout, CustomScancodeSet, DecodedKey, DecodedKeyKind, HandleControl, KeyCode,
|
||||||
|
@ -83,15 +68,14 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
|
||||||
};
|
};
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use x86_64::instructions::port::Port;
|
use x86_64::instructions::port::Port;
|
||||||
|
lazy_static! {
|
||||||
static KEYBOARD: Lazy<Mutex<Keyboard<CustomLayout, CustomScancodeSet>>> = Lazy::new(|| {
|
static ref KEYBOARD: Mutex<Keyboard<CustomLayout, CustomScancodeSet>> =
|
||||||
Mutex::new(Keyboard::new(
|
Mutex::new(Keyboard::new(
|
||||||
CustomLayout::new_us104key(),
|
CustomLayout::new_us104key(),
|
||||||
CustomScancodeSet::default(),
|
CustomScancodeSet::default(),
|
||||||
HandleControl::Ignore,
|
HandleControl::Ignore
|
||||||
))
|
));
|
||||||
});
|
}
|
||||||
|
|
||||||
let mut keyboard = KEYBOARD.lock();
|
let mut keyboard = KEYBOARD.lock();
|
||||||
let mut port = Port::new(0x60);
|
let mut port = Port::new(0x60);
|
||||||
let scancode: u8 = unsafe { port.read() };
|
let scancode: u8 = unsafe { port.read() };
|
||||||
|
@ -106,18 +90,20 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
|
||||||
// Backspace
|
// Backspace
|
||||||
8 => {
|
8 => {
|
||||||
WRITER.lock().backspace();
|
WRITER.lock().backspace();
|
||||||
KEYBUFF.lock().push(8_u8 as _);
|
|
||||||
// print!(" ");
|
// print!(" ");
|
||||||
// WRITER.lock().backspace();
|
// WRITER.lock().backspace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enter
|
||||||
|
0x0A => {
|
||||||
|
// let _xyz = crate::kmain::KEY_BUFFER.lock();
|
||||||
|
|
||||||
|
// print!("{}", char::try_from(character).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
0x5E => KERNEL_STATE.lock().shutdown(),
|
0x5E => KERNEL_STATE.lock().shutdown(),
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let mut buff = KEYBUFF.lock();
|
|
||||||
|
|
||||||
buff.push(character as u8 as char);
|
|
||||||
|
|
||||||
print!("{}", char::try_from(character).unwrap());
|
print!("{}", char::try_from(character).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,21 +129,16 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn floppy_disk_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
/*
|
||||||
println!("EXCEPTION: FLOPPY DISK");
|
extern "x86-interrupt" fn page_fault_handler(
|
||||||
}
|
stack_frame: InterruptStackFrame,
|
||||||
|
error_code: PageFaultErrorCode,
|
||||||
pub fn init_idt() {
|
) {
|
||||||
IDT.load();
|
use x86_64::registers::control::Cr2;
|
||||||
}
|
println!["Exception: Page Fault"];
|
||||||
|
println!["Address: {:?}", Cr2::read()];
|
||||||
fn set_pit_frequency(freq: u32) {
|
println!["Error Code: {:?}", error_code];
|
||||||
let divisor: u16 = (1193180 / freq).try_into().unwrap();
|
println!["{:#?}", stack_frame];
|
||||||
|
sloop();
|
||||||
unsafe {
|
|
||||||
outb(0x36, 0x43);
|
|
||||||
|
|
||||||
outb((divisor & 0xFF) as u8, 0x40);
|
|
||||||
outb((divisor >> 8) as u8, 0x40);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,111 +1,112 @@
|
||||||
use bootloader::bootinfo::{MemoryMap, MemoryRegionType};
|
use bootloader::bootinfo::{MemoryMap, MemoryRegionType};
|
||||||
use x86_64::{
|
use x86_64::{
|
||||||
structures::paging::{
|
structures::paging::{
|
||||||
FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB,
|
FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB,
|
||||||
},
|
},
|
||||||
PhysAddr, VirtAddr,
|
PhysAddr, VirtAddr,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub unsafe fn init(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> {
|
pub unsafe fn init(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> {
|
||||||
let level_4_table = active_level_4_table(physical_memory_offset);
|
let level_4_table = active_level_4_table(physical_memory_offset);
|
||||||
OffsetPageTable::new(level_4_table, physical_memory_offset)
|
OffsetPageTable::new(level_4_table, physical_memory_offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTable {
|
unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTable {
|
||||||
use x86_64::registers::control::Cr3;
|
use x86_64::registers::control::Cr3;
|
||||||
|
|
||||||
let (level_4_table_frame, _) = Cr3::read();
|
let (level_4_table_frame, _) = Cr3::read();
|
||||||
|
|
||||||
let phys = level_4_table_frame.start_address();
|
let phys = level_4_table_frame.start_address();
|
||||||
let virt = physical_memory_offset + phys.as_u64();
|
let virt = physical_memory_offset + phys.as_u64();
|
||||||
let page_table_ptr: *mut PageTable = virt.as_mut_ptr();
|
let page_table_ptr: *mut PageTable = virt.as_mut_ptr();
|
||||||
|
|
||||||
// THIS IS UNSAFE
|
// THIS IS UNSAFE
|
||||||
&mut *page_table_ptr
|
&mut *page_table_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_addr_inner(addr: VirtAddr, physical_memory_offset: VirtAddr) -> Option<PhysAddr> {
|
fn translate_addr_inner(addr: VirtAddr, physical_memory_offset: VirtAddr) -> Option<PhysAddr> {
|
||||||
use x86_64::registers::control::Cr3;
|
use x86_64::registers::control::Cr3;
|
||||||
use x86_64::structures::paging::page_table::FrameError;
|
use x86_64::structures::paging::page_table::FrameError;
|
||||||
|
|
||||||
let (level_4_table_frame, _) = Cr3::read();
|
let (level_4_table_frame, _) = Cr3::read();
|
||||||
|
|
||||||
let table_indexes = [
|
let table_indexes = [
|
||||||
addr.p4_index(),
|
addr.p4_index(),
|
||||||
addr.p3_index(),
|
addr.p3_index(),
|
||||||
addr.p2_index(),
|
addr.p2_index(),
|
||||||
addr.p1_index(),
|
addr.p1_index(),
|
||||||
];
|
];
|
||||||
let mut frame = level_4_table_frame;
|
let mut frame = level_4_table_frame;
|
||||||
|
|
||||||
for &index in &table_indexes {
|
for &index in &table_indexes {
|
||||||
// convert the frame into a page table reference
|
// convert the frame into a page table reference
|
||||||
let virt = physical_memory_offset + frame.start_address().as_u64();
|
let virt = physical_memory_offset + frame.start_address().as_u64();
|
||||||
let table_ptr: *const PageTable = virt.as_ptr();
|
let table_ptr: *const PageTable = virt.as_ptr();
|
||||||
let table = unsafe { &*table_ptr };
|
let table = unsafe { &*table_ptr };
|
||||||
|
|
||||||
let entry = &table[index];
|
let entry = &table[index];
|
||||||
frame = match entry.frame() {
|
frame = match entry.frame() {
|
||||||
Ok(frame) => frame,
|
Ok(frame) => frame,
|
||||||
Err(FrameError::FrameNotPresent) => return None,
|
Err(FrameError::FrameNotPresent) => return None,
|
||||||
Err(FrameError::HugeFrame) => panic!["huge pages not supported"],
|
Err(FrameError::HugeFrame) => panic!["huge pages not supported"],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(frame.start_address() + u64::from(addr.page_offset()))
|
Some(frame.start_address() + u64::from(addr.page_offset()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn translate_addr(addr: VirtAddr, physical_memory_offset: VirtAddr) -> Option<PhysAddr> {
|
pub unsafe fn translate_addr(addr: VirtAddr, physical_memory_offset: VirtAddr) -> Option<PhysAddr> {
|
||||||
translate_addr_inner(addr, physical_memory_offset)
|
translate_addr_inner(addr, physical_memory_offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_example_mapping(
|
pub fn create_example_mapping(
|
||||||
page: Page,
|
page: Page,
|
||||||
mapper: &mut OffsetPageTable,
|
mapper: &mut OffsetPageTable,
|
||||||
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
|
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
|
||||||
) {
|
) {
|
||||||
use x86_64::structures::paging::PageTableFlags as Flags;
|
use x86_64::structures::paging::PageTableFlags as Flags;
|
||||||
|
|
||||||
let frame = PhysFrame::containing_address(PhysAddr::new(0xb8000));
|
let frame = PhysFrame::containing_address(PhysAddr::new(0xb8000));
|
||||||
let flags = Flags::PRESENT | Flags::WRITABLE;
|
let flags = Flags::PRESENT | Flags::WRITABLE;
|
||||||
|
|
||||||
let map_to_result = unsafe { mapper.map_to(page, frame, flags, frame_allocator) };
|
let map_to_result = unsafe { mapper.map_to(page, frame, flags, frame_allocator) };
|
||||||
map_to_result.expect("map_to failed").flush();
|
map_to_result.expect("map_to failed").flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EmptyFrameAllocator;
|
pub struct EmptyFrameAllocator;
|
||||||
|
|
||||||
unsafe impl FrameAllocator<Size4KiB> for EmptyFrameAllocator {
|
unsafe impl FrameAllocator<Size4KiB> for EmptyFrameAllocator {
|
||||||
fn allocate_frame(&mut self) -> Option<PhysFrame<Size4KiB>> {
|
fn allocate_frame(&mut self) -> Option<PhysFrame<Size4KiB>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BootInfoFrameAllocator {
|
pub struct BootInfoFrameAllocator {
|
||||||
memory_map: &'static MemoryMap,
|
memory_map: &'static MemoryMap,
|
||||||
next: usize,
|
next: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BootInfoFrameAllocator {
|
impl BootInfoFrameAllocator {
|
||||||
pub unsafe fn init(memory_map: &'static MemoryMap) -> Self {
|
pub unsafe fn init(memory_map: &'static MemoryMap) -> Self {
|
||||||
Self {
|
Self {
|
||||||
memory_map,
|
memory_map,
|
||||||
next: 0,
|
next: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
|
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
|
||||||
let regions = self.memory_map.iter();
|
let regions = self.memory_map.iter();
|
||||||
let usable_regions = regions.filter(|r| r.region_type == MemoryRegionType::Usable);
|
let usable_regions = regions.filter(|r| r.region_type == MemoryRegionType::Usable);
|
||||||
let addr_range = usable_regions.map(|r| r.range.start_addr()..r.range.end_addr());
|
let addr_range = usable_regions.map(|r| r.range.start_addr()..r.range.end_addr());
|
||||||
let frame_address = addr_range.flat_map(|r| r.step_by(4096));
|
let frame_address = addr_range.flat_map(|r| r.step_by(4096));
|
||||||
frame_address.map(|addr| PhysFrame::containing_address(PhysAddr::new(addr)))
|
frame_address.map(|addr| PhysFrame::containing_address(PhysAddr::new(addr)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
|
unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
|
||||||
fn allocate_frame(&mut self) -> Option<PhysFrame<Size4KiB>> {
|
fn allocate_frame(&mut self) -> Option<PhysFrame<Size4KiB>> {
|
||||||
let frame = self.usable_frames().nth(self.next);
|
let frame = self.usable_frames().nth(self.next);
|
||||||
self.next += 1;
|
self.next += 1;
|
||||||
frame
|
frame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
|
use crate::arch::drivers::allocator;
|
||||||
|
use bootloader::{entry_point, BootInfo};
|
||||||
|
use x86_64::{
|
||||||
|
instructions::hlt,
|
||||||
|
{structures::paging::Page, VirtAddr},
|
||||||
|
};
|
||||||
|
|
||||||
pub mod drivers;
|
pub mod drivers;
|
||||||
pub mod gdt;
|
pub mod gdt;
|
||||||
pub mod init;
|
pub mod init;
|
||||||
pub mod interrupts;
|
pub mod interrupts;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
|
|
||||||
use crate::arch::drivers::allocator;
|
|
||||||
use bootloader::{entry_point, BootInfo};
|
|
||||||
use x86_64::{instructions::hlt, VirtAddr};
|
|
||||||
|
|
||||||
entry_point![start];
|
entry_point![start];
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn start(boot_info: &'static BootInfo) -> ! {
|
pub fn start(boot_info: &'static BootInfo) -> ! {
|
||||||
|
@ -16,12 +19,13 @@ pub fn start(boot_info: &'static BootInfo) -> ! {
|
||||||
let mut mapper = unsafe { memory::init(phys_mem_offset) };
|
let mut mapper = unsafe { memory::init(phys_mem_offset) };
|
||||||
let mut frame_allocator =
|
let mut frame_allocator =
|
||||||
unsafe { memory::BootInfoFrameAllocator::init(&boot_info.memory_map) };
|
unsafe { memory::BootInfoFrameAllocator::init(&boot_info.memory_map) };
|
||||||
|
if false {
|
||||||
|
let page = Page::containing_address(VirtAddr::new(0xdeadbeaf000));
|
||||||
|
memory::create_example_mapping(page, &mut mapper, &mut frame_allocator);
|
||||||
|
|
||||||
// let page = Page::containing_address(VirtAddr::new(0xdeadbeaf000));
|
let page_ptr: *mut u64 = page.start_address().as_mut_ptr();
|
||||||
// memory::create_example_mapping(page, &mut mapper, &mut frame_allocator);
|
unsafe { page_ptr.offset(400).write_volatile(0xf021_f077_f065_804e) };
|
||||||
//
|
}
|
||||||
// let page_ptr: *mut u64 = page.start_address().as_mut_ptr();
|
|
||||||
// unsafe { page_ptr.offset(400).write_volatile(0xf021_f077_f065_804e) };
|
|
||||||
|
|
||||||
allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed");
|
allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed");
|
||||||
|
|
||||||
|
@ -43,12 +47,3 @@ pub fn sloop() -> ! {
|
||||||
hlt();
|
hlt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Split up into the randomness and the password generation
|
|
||||||
pub fn generate_process_pass() -> u128 {
|
|
||||||
// TODO: Move this into entropy_pool module
|
|
||||||
use rdrand::RdRand;
|
|
||||||
let gen = RdRand::new().unwrap();
|
|
||||||
|
|
||||||
(gen.try_next_u64().unwrap() as u128) << 64 | (gen.try_next_u64().unwrap() as u128)
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,20 +18,29 @@ pub enum LogLevel {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Debug, Deserialize)]
|
#[derive(Serialize, Debug, Deserialize)]
|
||||||
pub struct KernelConfig {
|
pub struct BootConfig {
|
||||||
pub boot: BootConfig,
|
pub logging_level: LogLevel,
|
||||||
pub logging: LoggingConfig,
|
pub logger_padding: usize,
|
||||||
pub tests: TestsConfig,
|
pub run_tests: bool,
|
||||||
|
pub run_demos: bool,
|
||||||
|
pub run_shader_tests: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KernelConfig {
|
impl BootConfig {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
toml::from_str(include_str!("../assets/kernel.toml")).unwrap()
|
let data = include_str!("../assets/kernel_config.json");
|
||||||
|
|
||||||
|
// Parse the string of data into a Person object. This is exactly the
|
||||||
|
// same function as the one that produced serde_json::Value above, but
|
||||||
|
// now we are asking it for a Person as output.
|
||||||
|
let p: BootConfig = serde_json::from_str(data).unwrap();
|
||||||
|
// info!("{:?}", p);
|
||||||
|
p
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_level(&self) -> LevelFilter {
|
pub fn log_level(&self) -> LevelFilter {
|
||||||
use LevelFilter::*;
|
use LevelFilter::*;
|
||||||
match self.logging.level {
|
match self.logging_level {
|
||||||
LogLevel::Off => Off,
|
LogLevel::Off => Off,
|
||||||
LogLevel::Error => Error,
|
LogLevel::Error => Error,
|
||||||
LogLevel::Warn => Warn,
|
LogLevel::Warn => Warn,
|
||||||
|
@ -41,28 +50,3 @@ impl KernelConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for KernelConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Debug, Deserialize)]
|
|
||||||
pub struct LoggingConfig {
|
|
||||||
pub enabled: bool,
|
|
||||||
pub log_to_serial: bool,
|
|
||||||
pub level: LogLevel,
|
|
||||||
}
|
|
||||||
#[derive(Serialize, Debug, Deserialize)]
|
|
||||||
pub struct TestsConfig {
|
|
||||||
pub run_tests: bool,
|
|
||||||
pub run_demos: bool,
|
|
||||||
pub run_shader_tests: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Debug, Deserialize)]
|
|
||||||
pub struct BootConfig {
|
|
||||||
pub system_processes: Vec<String>,
|
|
||||||
pub user_processes: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
use kernel::device_interface::character::CharacterDevice;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub struct DevNull;
|
|
||||||
impl CharacterDevice for DevNull {
|
|
||||||
fn can_read(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_write(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_char(&mut self) -> Option<char> {
|
|
||||||
Some(0x00 as char)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_char(&mut self, _: char) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset(&mut self) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn initialize(&mut self) -> bool {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
use kernel::device_interface::character::CharacterDevice;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct DevUnicode {
|
|
||||||
pub next_write_char: char,
|
|
||||||
pub next_read_char: char,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CharacterDevice for DevUnicode {
|
|
||||||
fn can_read(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_write(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_char(&mut self) -> Option<char> {
|
|
||||||
let c = self.next_read_char;
|
|
||||||
self.next_read_char = add1_char(c);
|
|
||||||
|
|
||||||
Some(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_char(&mut self, c: char) -> bool {
|
|
||||||
if self.next_write_char != c {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset(&mut self) {
|
|
||||||
self.next_write_char = 0x00 as char;
|
|
||||||
self.next_read_char = 0x00 as char;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn initialize(&mut self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add1_char(c: char) -> char {
|
|
||||||
if c == char::MAX {
|
|
||||||
return 0x00 as char;
|
|
||||||
}
|
|
||||||
|
|
||||||
char::from_u32(c as u32 + 1).unwrap()
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
use kernel::device_interface::character::CharacterDevice;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct DevZero;
|
|
||||||
impl CharacterDevice for DevZero {
|
|
||||||
fn can_read(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_write(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_char(&mut self) -> Option<char> {
|
|
||||||
Some(0 as char)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_char(&mut self, _: char) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset(&mut self) {}
|
|
||||||
|
|
||||||
fn initialize(&mut self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
pub mod dev_null;
|
|
||||||
pub mod dev_unicode;
|
|
||||||
pub mod dev_zero;
|
|
||||||
|
|
||||||
pub use kernel::device_interface::character::CharacterDevice;
|
|
|
@ -1,264 +0,0 @@
|
||||||
// ! A virtual terminal device.
|
|
||||||
|
|
||||||
use core::ops::Not;
|
|
||||||
use core::sync::atomic::AtomicU32;
|
|
||||||
use core::sync::atomic::Ordering;
|
|
||||||
use kernel::device_interface::character::CharacterDevice;
|
|
||||||
use shadeable::pixel_format::Rgba64;
|
|
||||||
|
|
||||||
pub const VTERM_HEIGHT: u32 = 40;
|
|
||||||
pub const VTERM_WIDTH: u32 = 100;
|
|
||||||
|
|
||||||
pub static VIRTUAL_TERMINAL_COUNT: AtomicU32 = AtomicU32::new(0);
|
|
||||||
|
|
||||||
/// Fg and bg colors for vterm
|
|
||||||
pub type ColorCharacter = (Rgba64, Rgba64);
|
|
||||||
|
|
||||||
/// A vterm representation of a character
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct VtermCharacter {
|
|
||||||
pub character: char,
|
|
||||||
//
|
|
||||||
pub style: Style,
|
|
||||||
//
|
|
||||||
pub char_color: ColorCharacter,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Copy)]
|
|
||||||
|
|
||||||
pub struct Style(pub u8);
|
|
||||||
impl Style {
|
|
||||||
pub fn bold(&self) -> bool {
|
|
||||||
(self.0 & 0x01) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn underlined(&self) -> bool {
|
|
||||||
(self.0 & 0x02) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn italic(&self) -> bool {
|
|
||||||
(self.0 & 0x04) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn blinking(&self) -> bool {
|
|
||||||
(self.0 & 0x08) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reversed(&self) -> bool {
|
|
||||||
(self.0 & 0x10) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn struck(&self) -> bool {
|
|
||||||
(self.0 & 0x20) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn set_bold(mut self, v: bool) -> Self {
|
|
||||||
if v {
|
|
||||||
self.0 |= 0x01;
|
|
||||||
} else {
|
|
||||||
self.0 &= 0x01u8.not();
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn set_underlined(mut self, v: bool) -> Self {
|
|
||||||
if v {
|
|
||||||
self.0 |= 0x02;
|
|
||||||
} else {
|
|
||||||
self.0 &= 0x02u8.not();
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn set_italic(mut self, v: bool) -> Self {
|
|
||||||
if v {
|
|
||||||
self.0 |= 0x04;
|
|
||||||
} else {
|
|
||||||
self.0 &= 0x04u8.not();
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn set_blinking(mut self, v: bool) -> Self {
|
|
||||||
if v {
|
|
||||||
self.0 |= 0x08;
|
|
||||||
} else {
|
|
||||||
self.0 &= 0x08u8.not();
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn set_reversed(mut self, v: bool) -> Self {
|
|
||||||
if v {
|
|
||||||
self.0 |= 0x10;
|
|
||||||
} else {
|
|
||||||
self.0 &= 0x10u8.not();
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn set_struck(mut self, v: bool) -> Self {
|
|
||||||
if v {
|
|
||||||
self.0 |= 0x20;
|
|
||||||
} else {
|
|
||||||
self.0 &= 0x20u8.not();
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct VTerm {
|
|
||||||
pub characters: [[VtermCharacter; VTERM_WIDTH as usize]; VTERM_HEIGHT as usize],
|
|
||||||
pub cursor_visible: bool,
|
|
||||||
|
|
||||||
/// Internal ID of the vterm
|
|
||||||
iid: u32,
|
|
||||||
|
|
||||||
/// The internal representation of the vterm
|
|
||||||
style: Style,
|
|
||||||
|
|
||||||
/// The cursor position in layout x,y
|
|
||||||
cursor_position: (u32, u32),
|
|
||||||
key_buff: Vec<char>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for VTerm {
|
|
||||||
fn default() -> Self {
|
|
||||||
VTerm {
|
|
||||||
iid: 0,
|
|
||||||
characters: [[VtermCharacter {
|
|
||||||
character: 0x00 as char,
|
|
||||||
char_color: (0xff_ff_ff_ff, 0x00_00_00_00),
|
|
||||||
style: Style::default(),
|
|
||||||
}; VTERM_WIDTH as usize]; VTERM_HEIGHT as usize],
|
|
||||||
cursor_position: (0, 0),
|
|
||||||
cursor_visible: true,
|
|
||||||
style: Style::default(),
|
|
||||||
key_buff: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The primitive interface for a vterm
|
|
||||||
impl VTerm {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut vterm = VTerm::default();
|
|
||||||
let mut vtc = VIRTUAL_TERMINAL_COUNT.load(Ordering::Relaxed);
|
|
||||||
vterm.iid = vtc;
|
|
||||||
vtc += 1;
|
|
||||||
VIRTUAL_TERMINAL_COUNT.store(vtc, Ordering::Relaxed);
|
|
||||||
|
|
||||||
vterm
|
|
||||||
}
|
|
||||||
/// Set the vterm cursor to the given position
|
|
||||||
pub fn set_cursor_position(&mut self, x: u32, y: u32) {
|
|
||||||
if x > VTERM_WIDTH {
|
|
||||||
self.cursor_position.0 = VTERM_WIDTH;
|
|
||||||
error!("Cursor x position out of bounds");
|
|
||||||
} else {
|
|
||||||
self.cursor_position.0 = x;
|
|
||||||
}
|
|
||||||
if y > VTERM_HEIGHT {
|
|
||||||
error!("Cursor y position out of bounds");
|
|
||||||
self.cursor_position.1 = VTERM_HEIGHT;
|
|
||||||
} else {
|
|
||||||
self.cursor_position.1 = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the vterm style
|
|
||||||
pub fn set_vterm_style(&mut self, style: Style) {
|
|
||||||
self.style = style;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CharacterDevice for VTerm {
|
|
||||||
fn can_read(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_write(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_char(&mut self) -> Option<char> {
|
|
||||||
if let Some(c) = self.key_buff.pop() {
|
|
||||||
return Some(c);
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_char(&mut self, c: char) -> bool {
|
|
||||||
match c {
|
|
||||||
'\n' => {
|
|
||||||
self.cursor_position.1 += 1;
|
|
||||||
self.cursor_position.0 = 0;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
'\r' => {
|
|
||||||
self.cursor_position.0 = 0;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
'\t' => {
|
|
||||||
self.cursor_position.0 += 4;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
'\x08' => {
|
|
||||||
self.cursor_position.0 -= 1;
|
|
||||||
self.characters[self.cursor_position.1 as usize][self.cursor_position.0 as usize]
|
|
||||||
.character = ' ';
|
|
||||||
true
|
|
||||||
}
|
|
||||||
// This is a form feed, which is used to clear the screen
|
|
||||||
'\x0c' => {
|
|
||||||
self.characters = [[VtermCharacter {
|
|
||||||
character: ' ',
|
|
||||||
char_color: (0xff_ff_ff_ff, 0x00_00_00_00),
|
|
||||||
style: Style::default(),
|
|
||||||
}; VTERM_WIDTH as usize]; VTERM_HEIGHT as usize];
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
self.characters[self.cursor_position.1 as usize][self.cursor_position.0 as usize]
|
|
||||||
.character = c;
|
|
||||||
self.characters[self.cursor_position.1 as usize][self.cursor_position.0 as usize]
|
|
||||||
.char_color = (0xff_ff_ff_ff, 0x00_00_00_00);
|
|
||||||
self.characters[self.cursor_position.1 as usize][self.cursor_position.0 as usize]
|
|
||||||
.style = self.style;
|
|
||||||
|
|
||||||
if self.cursor_position.0 < VTERM_WIDTH {
|
|
||||||
self.cursor_position.0 += 1;
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
self.cursor_position.0 = 0;
|
|
||||||
self.cursor_position.1 += 1;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset(&mut self) {
|
|
||||||
self.characters = [[VtermCharacter {
|
|
||||||
character: ' ',
|
|
||||||
char_color: (0xff_ff_ff_ff, 0x00_00_00_00),
|
|
||||||
style: Style::default(),
|
|
||||||
}; VTERM_WIDTH as usize]; VTERM_HEIGHT as usize];
|
|
||||||
|
|
||||||
self.cursor_position = (0, 0);
|
|
||||||
self.cursor_visible = true;
|
|
||||||
self.style = Style::default();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn initialize(&mut self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Vendor {
|
|
||||||
Unknown = 0,
|
|
||||||
Ati = 1002,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn match_vendor(id: u16) -> Vendor {
|
|
||||||
use Vendor::*;
|
|
||||||
|
|
||||||
match id {
|
|
||||||
1002 => Ati,
|
|
||||||
_ => Unknown,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
pub mod character_devs;
|
|
||||||
pub mod id;
|
|
||||||
pub mod pci_inner;
|
|
||||||
|
|
||||||
mod dev_vterm;
|
|
||||||
|
|
||||||
pub use self::Device::*;
|
|
||||||
|
|
||||||
use crate::devices::dev_vterm::VTerm;
|
|
||||||
use character_devs::{dev_null::DevNull, dev_unicode::DevUnicode, dev_zero::DevZero};
|
|
||||||
use hashbrown::HashMap;
|
|
||||||
use kernel::device_interface::character::CharacterDevice;
|
|
||||||
use spin::Lazy;
|
|
||||||
|
|
||||||
pub static DEVICE_TABLE: Lazy<spin::Mutex<DeviceTable>> =
|
|
||||||
Lazy::new(|| spin::Mutex::new(DeviceTable::new()));
|
|
||||||
|
|
||||||
// FIXME: This is a hack to hold a device.
|
|
||||||
// #[derive(Debug)]
|
|
||||||
pub enum Device {
|
|
||||||
Character(Box<dyn CharacterDevice>),
|
|
||||||
Vterm(Box<VTerm>),
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Sync for Device {}
|
|
||||||
unsafe impl Send for Device {}
|
|
||||||
|
|
||||||
pub struct DeviceTable {
|
|
||||||
pub devices: HashMap<String, Device>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeviceTable {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
DeviceTable {
|
|
||||||
devices: [
|
|
||||||
("null", Character(Box::new(DevNull))),
|
|
||||||
("zero", Character(Box::new(DevZero))),
|
|
||||||
(
|
|
||||||
"unicode",
|
|
||||||
Character(Box::new(DevUnicode {
|
|
||||||
next_write_char: 0x00 as char,
|
|
||||||
next_read_char: 0x00 as char,
|
|
||||||
})),
|
|
||||||
),
|
|
||||||
("kvterm", Vterm(Box::new(VTerm::new()))),
|
|
||||||
]
|
|
||||||
.into_iter()
|
|
||||||
.map(|(k, v)| (k.to_string(), v))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for DeviceTable {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
//! map the DeviceClass via <https://pci-ids.ucw.cz/read/PD>
|
|
||||||
//!
|
|
||||||
//!
|
|
||||||
|
|
||||||
pub enum Vendors {
|
|
||||||
ThreeDfxInteractiveInc = 0x121a,
|
|
||||||
ThreeDLabs = 0x3d3d,
|
|
||||||
AllianceSemiconductorCorp = 0x1142,
|
|
||||||
ARKLogicInc = 0xedd8,
|
|
||||||
ATITechnologiesInc = 0x1002,
|
|
||||||
AvanceLogicIncALI = 0x1005,
|
|
||||||
ChipsandTechnologies = 0x102c,
|
|
||||||
CirrusLogic = 0x1013,
|
|
||||||
Compaq = 0x0e11,
|
|
||||||
CyrixCorp = 0x1078,
|
|
||||||
DiamondMultimediaSystems = 0x1092,
|
|
||||||
DigitalEquipmentCorp = 0x1011,
|
|
||||||
Iit = 0x1061,
|
|
||||||
IntegratedMicroSolutionsInc = 0x10e0,
|
|
||||||
IntelCorp = 0x8086,
|
|
||||||
IntergraphicsSystems = 0x10ea,
|
|
||||||
MacronixInc = 0x10d9,
|
|
||||||
MatroxGraphicsInc = 0x102b,
|
|
||||||
MiroComputersProductsAG = 0x1031,
|
|
||||||
NationalSemiconductorCorp = 0x100b,
|
|
||||||
NeoMagicCorp = 0x10c8,
|
|
||||||
Number9ComputerCompany = 0x105d,
|
|
||||||
NVidiaCorporation = 0x10de,
|
|
||||||
NVidiaSgsthomson = 0x12d2,
|
|
||||||
OakTechnologyInc = 0x104e,
|
|
||||||
QuantumDesignsHKLtd = 0x1098,
|
|
||||||
Real3D = 0x003d,
|
|
||||||
Rendition = 0x1163,
|
|
||||||
S3Inc = 0x5333,
|
|
||||||
SierraSemiconductor = 0x10a8,
|
|
||||||
SiliconIntegratedSystemsSiS = 0x1039,
|
|
||||||
SiliconMotionInc = 0x126f,
|
|
||||||
STBSystemsInc = 0x10b4,
|
|
||||||
TexasInstruments = 0x104c,
|
|
||||||
ToshibaAmericaInfoSystems = 0x1179,
|
|
||||||
TridentMicrosystems = 0x1023,
|
|
||||||
TsengLabsInc = 0x100c,
|
|
||||||
TundraSemiconductorCorp = 0x10e3,
|
|
||||||
VIATechnologiesInc = 0x1106,
|
|
||||||
VMWareInc = 0x15ad,
|
|
||||||
Weitek = 0x100e,
|
|
||||||
Unknown = 0xffff,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PciDevice {
|
|
||||||
pub vendor: Vendors,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn scan_pci_bus() {}
|
|
4
ableos/src/driver_traits/device.rs
Normal file
4
ableos/src/driver_traits/device.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
pub trait Device {
|
||||||
|
fn probe();
|
||||||
|
fn reset();
|
||||||
|
}
|
|
@ -1,21 +1,16 @@
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
pub const REFRESH_RATE: u8 = 60;
|
|
||||||
|
|
||||||
pub type RefreshRate = u8;
|
|
||||||
pub type Resolution = (usize, usize);
|
|
||||||
pub type Point = (GCoord, GCoord);
|
|
||||||
pub type GCoord = usize;
|
|
||||||
|
|
||||||
pub enum GModes {
|
pub enum GModes {
|
||||||
Vga800x600,
|
Vga800x600,
|
||||||
Custom(u16, u16),
|
Custom(u16, u16),
|
||||||
}
|
}
|
||||||
|
pub type GCoord = usize;
|
||||||
|
|
||||||
// TODO remap to a bitmasked u32
|
// TODO remap to a bitmasked u32
|
||||||
// REASON: More effecient memory wise so less overhead on the wasm memory
|
/* REASON: More effecient memory wise so less overhead on the wasm memory
|
||||||
// Current: u32+u32+u32
|
Current: u32+u32+u32
|
||||||
// Proposed: u32 with bitmaps
|
Proposed: u32 with bitmaps
|
||||||
|
*/
|
||||||
|
|
||||||
pub struct Rgb {
|
pub struct Rgb {
|
||||||
pub r: u32,
|
pub r: u32,
|
||||||
pub g: u32,
|
pub g: u32,
|
||||||
|
@ -27,8 +22,13 @@ impl Rgb {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub type RefreshRate = u8;
|
||||||
|
|
||||||
|
pub const REFRESH_RATE: u8 = 60;
|
||||||
|
pub type Resolution = (usize, usize);
|
||||||
|
pub type Point = (GCoord, GCoord);
|
||||||
pub struct FrameBuffer;
|
pub struct FrameBuffer;
|
||||||
|
// [[Rgb; 5]; 5]
|
||||||
pub trait Graphics {
|
pub trait Graphics {
|
||||||
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb);
|
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb);
|
||||||
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb);
|
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
// TODO: Bitmasking
|
// TODO: Bitmasking
|
||||||
pub enum Mouse {
|
pub enum Mouse {
|
||||||
Button1,
|
Button1,
|
||||||
|
|
|
@ -1,37 +1,4 @@
|
||||||
use kernel::device_interface::character::CharacterDevice;
|
pub trait Serial {
|
||||||
|
fn print();
|
||||||
pub struct Serial {
|
fn recieve();
|
||||||
pub base: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CharacterDevice for Serial {
|
|
||||||
fn can_read(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_write(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_char(&mut self) -> Option<char> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_char(&mut self, _c: char) -> bool {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset(&mut self) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn initialize(&mut self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_serial_test() {
|
|
||||||
let mut serial = Serial { base: 0x3F8 };
|
|
||||||
serial.initialize();
|
|
||||||
serial.write_char('a');
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,107 +1,67 @@
|
||||||
use logos::{Lexer, Logos};
|
use crate::{
|
||||||
|
arch::drivers::vga::{set_vga_color, Color},
|
||||||
|
kprint,
|
||||||
|
};
|
||||||
|
|
||||||
// TODO improve tokenizer/parser
|
// TODO improve tokenizer/parser
|
||||||
pub fn colorify(eval: &str) {
|
pub fn colorify(eval: &str) {
|
||||||
let y = eval.split('$');
|
let y = eval.split("$");
|
||||||
for z in y {
|
for z in y {
|
||||||
match z {
|
match z {
|
||||||
"BLACK" => {
|
"BLACK" => {
|
||||||
// set_vga_color(Color::Black, Color::Black);
|
set_vga_color(Color::Black, Color::Black);
|
||||||
}
|
}
|
||||||
"RED" => {
|
"RED" => {
|
||||||
// set_vga_color(Color::Red, Color::Black);
|
set_vga_color(Color::Red, Color::Black);
|
||||||
}
|
}
|
||||||
"GREEN" => {
|
"GREEN" => {
|
||||||
// set_vga_color(Color::Green, Color::Black);
|
set_vga_color(Color::Green, Color::Black);
|
||||||
}
|
}
|
||||||
"BLUE" => {
|
"BLUE" => {
|
||||||
// set_vga_color(Color::Blue, Color::Black);
|
set_vga_color(Color::Blue, Color::Black);
|
||||||
}
|
}
|
||||||
"CYAN" => {
|
"CYAN" => {
|
||||||
// set_vga_color(Color::Cyan, Color::Black);
|
set_vga_color(Color::Cyan, Color::Black);
|
||||||
}
|
}
|
||||||
"MAGENTA" => {
|
"MAGENTA" => {
|
||||||
// set_vga_color(Color::Magenta, Color::Black);
|
set_vga_color(Color::Magenta, Color::Black);
|
||||||
}
|
}
|
||||||
"BROWN" => {
|
"BROWN" => {
|
||||||
// set_vga_color(Color::Brown, Color::Black);
|
set_vga_color(Color::Brown, Color::Black);
|
||||||
}
|
}
|
||||||
"LIGHTGRAY" => {
|
"LIGHTGRAY" => {
|
||||||
// set_vga_color(Color::LightGray, Color::Black);
|
set_vga_color(Color::LightGray, Color::Black);
|
||||||
}
|
}
|
||||||
"DARKGRAY" => {
|
"DARKGRAY" => {
|
||||||
// set_vga_color(Color::DarkGray, Color::Black);
|
set_vga_color(Color::DarkGray, Color::Black);
|
||||||
}
|
}
|
||||||
"LIGHTBLUE" => {
|
"LIGHTBLUE" => {
|
||||||
// set_vga_color(Color::LightBlue, Color::Black);
|
set_vga_color(Color::LightBlue, Color::Black);
|
||||||
}
|
}
|
||||||
"LIGHTGREEN" => {
|
"LIGHTGREEN" => {
|
||||||
// set_vga_color(Color::LightGreen, Color::Black);
|
set_vga_color(Color::LightGreen, Color::Black);
|
||||||
}
|
}
|
||||||
"LIGHTCYAN" => {
|
"LIGHTCYAN" => {
|
||||||
// set_vga_color(Color::LightCyan, Color::Black);
|
set_vga_color(Color::LightCyan, Color::Black);
|
||||||
}
|
}
|
||||||
"LIGHTRED" => {
|
"LIGHTRED" => {
|
||||||
// set_vga_color(Color::LightRed, Color::Black);
|
set_vga_color(Color::LightRed, Color::Black);
|
||||||
}
|
}
|
||||||
"PINK" => {
|
"PINK" => {
|
||||||
// set_vga_color(Color::Pink, Color::Black);
|
set_vga_color(Color::Pink, Color::Black);
|
||||||
}
|
}
|
||||||
"YELLOW" => {
|
"YELLOW" => {
|
||||||
// set_vga_color(Color::Yellow, Color::Black);
|
set_vga_color(Color::Yellow, Color::Black);
|
||||||
}
|
}
|
||||||
"WHITE" => {
|
"WHITE" => {
|
||||||
// set_vga_color(Color::White, Color::Black);
|
set_vga_color(Color::White, Color::Black);
|
||||||
}
|
}
|
||||||
"RESET" => {
|
"RESET" => {
|
||||||
// set_vga_color(Color::White, Color::Black);
|
set_vga_color(Color::White, Color::Black);
|
||||||
}
|
}
|
||||||
_elk => {
|
elk => {
|
||||||
// kprint!("{}", elk);
|
kprint!("{}", elk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Logos, Debug, PartialEq)]
|
|
||||||
pub enum Token {
|
|
||||||
// Hex(u32),
|
|
||||||
#[regex(r"\$RED\$")]
|
|
||||||
Red,
|
|
||||||
|
|
||||||
#[regex(r"\$RESET\$")]
|
|
||||||
Reset,
|
|
||||||
|
|
||||||
#[regex("[a-zA-Z!@#$%^&*\">()\n ]+", parse_text, priority = 2)]
|
|
||||||
Text(String),
|
|
||||||
|
|
||||||
#[error]
|
|
||||||
#[regex(r"[ \t\n\f]+", logos::skip)]
|
|
||||||
Error,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn colorify_2(eval: &str) {
|
|
||||||
let lexer = Token::lexer(eval);
|
|
||||||
for token in lexer {
|
|
||||||
use Token::*;
|
|
||||||
match token {
|
|
||||||
Red => {
|
|
||||||
// set_vga_color(Color::Red, Color::Black);
|
|
||||||
}
|
|
||||||
Reset => {
|
|
||||||
// set_vga_color(Color::White, Color::Black);
|
|
||||||
}
|
|
||||||
Text(_text) => {
|
|
||||||
// kprint!("{}", text);
|
|
||||||
}
|
|
||||||
err => {
|
|
||||||
error!("Error parsing {:?}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_text(lex: &mut Lexer<Token>) -> Option<String> {
|
|
||||||
let slice = lex.slice();
|
|
||||||
Some(String::from(slice))
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
use alloc::{string::String, vec, vec::Vec};
|
use alloc::{string::String, vec, vec::Vec};
|
||||||
|
// use crate::String;
|
||||||
pub static CLIPBOARD: spin::Mutex<Clipboard> = spin::Mutex::new(Clipboard::new());
|
// use crate::Vec;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Mime {
|
pub enum Mime {
|
||||||
None,
|
None,
|
||||||
Text(String),
|
Text(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref CLIPBOARD: spin::Mutex<Clipboard> = {
|
||||||
|
let clipboard = Clipboard::new();
|
||||||
|
spin::Mutex::new(clipboard)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// ctrl+v paste but not pop and pastes
|
// ctrl+v paste but not pop and pastes
|
||||||
// ctrl+shift+v pops from the stack and pastes
|
// ctrl+shift+v pops from the stack and pastes
|
||||||
// ctrl+c pushes to the stack
|
// ctrl+c pushes to the stack
|
||||||
|
@ -18,36 +25,30 @@ pub struct Clipboard {
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
pub pages: Vec<Mime>,
|
pub pages: Vec<Mime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clipboard {
|
impl Clipboard {
|
||||||
pub const fn new() -> Clipboard {
|
pub fn new() -> Clipboard {
|
||||||
Clipboard {
|
Clipboard {
|
||||||
index: 0,
|
index: 0,
|
||||||
pages: vec![],
|
pages: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.pages = vec![];
|
self.pages = vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_index(&mut self, index_new: usize) {
|
pub fn set_index(&mut self, index_new: usize) {
|
||||||
self.index = index_new;
|
self.index = index_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clip_end(&mut self) {
|
pub fn clip_end(&mut self) {
|
||||||
self.index = 0;
|
self.index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clip_home(&mut self) {
|
pub fn clip_home(&mut self) {
|
||||||
self.index = self.pages.len();
|
self.index = self.pages.len();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy(&mut self, copy_mime: Mime) {
|
pub fn copy(&mut self, copy_mime: Mime) {
|
||||||
self.pages.push(copy_mime);
|
self.pages.push(copy_mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paste(&mut self) -> &Mime {
|
pub fn paste(&mut self) -> &Mime {
|
||||||
&self.pages[self.index] as _
|
let paste_pos = &self.pages[self.index];
|
||||||
|
paste_pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
|
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
|
// pub struct Duration {}
|
||||||
|
|
||||||
pub struct AtomicU32(u32);
|
pub struct AtomicU32(u32);
|
||||||
|
|
||||||
impl AtomicU32 {
|
impl AtomicU32 {
|
||||||
//if v != current value
|
//if v != current value
|
||||||
pub fn wait(&self, _v: u32) {
|
pub fn wait(&self, _v: u32) {
|
||||||
|
@ -18,8 +23,9 @@ impl AtomicU32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
// SUPER HANDWAVEY
|
|
||||||
// YOU WILL NEED LOCKING THAT I DIDNT WRITE OUT (you == zuurr#9735)
|
SUPER HANDWAVEY
|
||||||
|
YOU WILL NEED LOCKING THAT I DIDNT WRITE OUT (you == zuurr#9735)
|
||||||
|
|
||||||
// all the red is by design
|
// all the red is by design
|
||||||
pub fn futex_wait(atom: &AtomicU32, value: usize, current_thread: ThreadID) {
|
pub fn futex_wait(atom: &AtomicU32, value: usize, current_thread: ThreadID) {
|
||||||
|
@ -40,6 +46,7 @@ pub fn futex_wake(atom: &AtomicU32, threads_to_wake: usize) {
|
||||||
waiting_thread.wake()
|
waiting_thread.wake()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct FutexWaitlist {
|
struct FutexWaitlist {
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
#![feature(asm)]
|
||||||
|
#![cfg_attr(
|
||||||
|
not(any(target_arch = "x86_64", target_arch = "x86")),
|
||||||
|
allow(dead_code)
|
||||||
|
)]
|
||||||
|
|
||||||
//! ```
|
//! ```
|
||||||
//! extern crate cupid;
|
//! extern crate cupid;
|
||||||
//!
|
//!
|
||||||
|
@ -12,50 +18,10 @@
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![cfg_attr(
|
|
||||||
not(any(target_arch = "x86_64", target_arch = "x86")),
|
|
||||||
allow(dead_code)
|
|
||||||
)]
|
|
||||||
|
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
use core::{fmt, slice, str};
|
use core::{fmt, slice, str};
|
||||||
|
|
||||||
// 3 calls of 4 registers of 4 bytes
|
|
||||||
const BRAND_STRING_LENGTH: usize = 3 * 4 * 4;
|
|
||||||
|
|
||||||
macro_rules! bit {
|
|
||||||
($reg:ident, {$($idx:expr => $name:ident),+ $(,)?}) => {
|
|
||||||
$(pub fn $name(self) -> bool {
|
|
||||||
((self.$reg >> $idx) & 1) != 0
|
|
||||||
})+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! dump {
|
|
||||||
($me:expr, $f: expr, $sname:expr, {$($name:ident),+ $(,)?}) => {
|
|
||||||
$f.debug_struct($sname)
|
|
||||||
$(.field(stringify!($name), &$me.$name()))+
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! delegate_flag {
|
|
||||||
($item:ident, {$($name:ident),+ $(,)?}) => {
|
|
||||||
$(pub fn $name(&self) -> bool {
|
|
||||||
self.$item.map(|i| i.$name()).unwrap_or(false)
|
|
||||||
})+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! master_attr_reader {
|
|
||||||
($name:ident, $kind:ty) => {
|
|
||||||
pub fn $name(&self) -> Option<&$kind> {
|
|
||||||
self.$name.as_ref()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum RequestType {
|
pub enum RequestType {
|
||||||
BasicInformation = 0x00000000,
|
BasicInformation = 0x00000000,
|
||||||
|
@ -67,12 +33,91 @@ pub enum RequestType {
|
||||||
BrandString1 = 0x80000002,
|
BrandString1 = 0x80000002,
|
||||||
BrandString2 = 0x80000003,
|
BrandString2 = 0x80000003,
|
||||||
BrandString3 = 0x80000004,
|
BrandString3 = 0x80000004,
|
||||||
// reserved = 0x80000005,
|
// reserved = 0x80000005,
|
||||||
CacheLine = 0x80000006,
|
CacheLine = 0x80000006,
|
||||||
TimeStampCounter = 0x80000007,
|
TimeStampCounter = 0x80000007,
|
||||||
PhysicalAddressSize = 0x80000008,
|
PhysicalAddressSize = 0x80000008,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cpuid(code: RequestType) -> (u32, u32, u32, u32) {
|
||||||
|
let eax;
|
||||||
|
let ebx;
|
||||||
|
let ecx;
|
||||||
|
let edx;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
asm!(
|
||||||
|
"movq %rbx, {0:r}",
|
||||||
|
"cpuid",
|
||||||
|
"xchgq %rbx, {0:r}",
|
||||||
|
lateout(reg) ebx,
|
||||||
|
inlateout("eax") code as u32 => eax,
|
||||||
|
inlateout("ecx") 0 => ecx,
|
||||||
|
lateout("edx") edx,
|
||||||
|
options(nostack, preserves_flags, att_syntax),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
(eax, ebx, ecx, edx)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The main entrypoint to the CPU information
|
||||||
|
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
|
||||||
|
pub fn master() -> Option<Master> {
|
||||||
|
Some(Master::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
// This matches the Intel Architecture guide, with bits 31 -> 0.
|
||||||
|
// The bit positions are inclusive.
|
||||||
|
fn bits_of(val: u32, start_bit: u8, end_bit: u8) -> u32 {
|
||||||
|
let mut silly = 0;
|
||||||
|
|
||||||
|
for _ in start_bit..end_bit + 1 {
|
||||||
|
silly <<= 1;
|
||||||
|
silly |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(val >> start_bit) & silly
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_bytes(v: &u32) -> &[u8] {
|
||||||
|
let start = v as *const u32 as *const u8;
|
||||||
|
// TODO: use u32::BYTES
|
||||||
|
unsafe { slice::from_raw_parts(start, 4) }
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! bit {
|
||||||
|
($reg:ident, {$($idx:expr => $name:ident),+}) => {
|
||||||
|
$(pub fn $name(self) -> bool {
|
||||||
|
((self.$reg >> $idx) & 1) != 0
|
||||||
|
})+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! dump {
|
||||||
|
($me:expr, $f: expr, $sname:expr, {$($name:ident),+}) => {
|
||||||
|
$f.debug_struct($sname)
|
||||||
|
$(.field(stringify!($name), &$me.$name()))+
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! delegate_flag {
|
||||||
|
($item:ident, {$($name:ident),+}) => {
|
||||||
|
$(pub fn $name(&self) -> bool {
|
||||||
|
self.$item.map(|i| i.$name()).unwrap_or(false)
|
||||||
|
})+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! master_attr_reader {
|
||||||
|
($name:ident, $kind:ty) => {
|
||||||
|
pub fn $name(&self) -> Option<&$kind> {
|
||||||
|
self.$name.as_ref()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct VersionInformation {
|
pub struct VersionInformation {
|
||||||
eax: u32,
|
eax: u32,
|
||||||
|
@ -202,8 +247,8 @@ impl VersionInformation {
|
||||||
27 => osxsave,
|
27 => osxsave,
|
||||||
28 => avx,
|
28 => avx,
|
||||||
29 => f16c,
|
29 => f16c,
|
||||||
30 => rdrand,
|
30 => rdrand
|
||||||
// 31 - unused,
|
// 31 - unused
|
||||||
});
|
});
|
||||||
|
|
||||||
bit!(edx, {
|
bit!(edx, {
|
||||||
|
@ -238,16 +283,10 @@ impl VersionInformation {
|
||||||
28 => htt,
|
28 => htt,
|
||||||
29 => tm,
|
29 => tm,
|
||||||
// 30 -reserved
|
// 30 -reserved
|
||||||
31 => pbe,
|
31 => pbe
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for VersionInformation {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for VersionInformation {
|
impl fmt::Debug for VersionInformation {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
dump!(self, f, "VersionInformation", {
|
dump!(self, f, "VersionInformation", {
|
||||||
|
@ -313,7 +352,7 @@ impl fmt::Debug for VersionInformation {
|
||||||
ss,
|
ss,
|
||||||
htt,
|
htt,
|
||||||
tm,
|
tm,
|
||||||
pbe,
|
pbe
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,7 +374,7 @@ impl ExtendedProcessorSignature {
|
||||||
// 1-4 reserved
|
// 1-4 reserved
|
||||||
5 => lzcnt,
|
5 => lzcnt,
|
||||||
// 6-7 reserved
|
// 6-7 reserved
|
||||||
8 => prefetchw,
|
8 => prefetchw
|
||||||
// 9-31 reserved
|
// 9-31 reserved
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -348,7 +387,7 @@ impl ExtendedProcessorSignature {
|
||||||
26 => gigabyte_pages,
|
26 => gigabyte_pages,
|
||||||
27 => rdtscp_and_ia32_tsc_aux,
|
27 => rdtscp_and_ia32_tsc_aux,
|
||||||
// 28 reserved
|
// 28 reserved
|
||||||
29 => intel_64_bit_architecture,
|
29 => intel_64_bit_architecture
|
||||||
// 30-31 reserved
|
// 30-31 reserved
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -363,11 +402,14 @@ impl fmt::Debug for ExtendedProcessorSignature {
|
||||||
execute_disable,
|
execute_disable,
|
||||||
gigabyte_pages,
|
gigabyte_pages,
|
||||||
rdtscp_and_ia32_tsc_aux,
|
rdtscp_and_ia32_tsc_aux,
|
||||||
intel_64_bit_architecture,
|
intel_64_bit_architecture
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3 calls of 4 registers of 4 bytes
|
||||||
|
const BRAND_STRING_LENGTH: usize = 3 * 4 * 4;
|
||||||
|
|
||||||
pub struct BrandString {
|
pub struct BrandString {
|
||||||
bytes: [u8; BRAND_STRING_LENGTH],
|
bytes: [u8; BRAND_STRING_LENGTH],
|
||||||
}
|
}
|
||||||
|
@ -404,7 +446,7 @@ impl Clone for BrandString {
|
||||||
for (d, s) in bytes.iter_mut().zip(self.bytes.iter()) {
|
for (d, s) in bytes.iter_mut().zip(self.bytes.iter()) {
|
||||||
*d = *s;
|
*d = *s;
|
||||||
}
|
}
|
||||||
BrandString { bytes }
|
BrandString { bytes: bytes }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +502,7 @@ impl ThermalPowerManagementInformation {
|
||||||
9 => hwp_activity_window,
|
9 => hwp_activity_window,
|
||||||
10 => hwp_energy_performance_preference,
|
10 => hwp_energy_performance_preference,
|
||||||
// 12 - reserved
|
// 12 - reserved
|
||||||
13 => hdc,
|
13 => hdc
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn number_of_interrupt_thresholds(self) -> u32 {
|
pub fn number_of_interrupt_thresholds(self) -> u32 {
|
||||||
|
@ -488,7 +530,9 @@ impl fmt::Debug for ThermalPowerManagementInformation {
|
||||||
hwp_activity_window,
|
hwp_activity_window,
|
||||||
hwp_energy_performance_preference,
|
hwp_energy_performance_preference,
|
||||||
hdc,
|
hdc,
|
||||||
|
|
||||||
number_of_interrupt_thresholds,
|
number_of_interrupt_thresholds,
|
||||||
|
|
||||||
hardware_coordination_feedback,
|
hardware_coordination_feedback,
|
||||||
performance_energy_bias
|
performance_energy_bias
|
||||||
})
|
})
|
||||||
|
@ -529,7 +573,7 @@ impl StructuredExtendedInformation {
|
||||||
19 => adx,
|
19 => adx,
|
||||||
20 => smap,
|
20 => smap,
|
||||||
// 21-24 - reserved
|
// 21-24 - reserved
|
||||||
25 => intel_processor_trace,
|
25 => intel_processor_trace
|
||||||
// 26-31 - reserved
|
// 26-31 - reserved
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -558,7 +602,7 @@ impl fmt::Debug for StructuredExtendedInformation {
|
||||||
adx,
|
adx,
|
||||||
smap,
|
smap,
|
||||||
intel_processor_trace,
|
intel_processor_trace,
|
||||||
prefetchwt1,
|
prefetchwt1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -576,6 +620,7 @@ pub enum CacheLineAssociativity {
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct CacheLine(u32);
|
pub struct CacheLine(u32);
|
||||||
|
|
||||||
impl CacheLine {
|
impl CacheLine {
|
||||||
fn new() -> CacheLine {
|
fn new() -> CacheLine {
|
||||||
let (_, _, c, _) = cpuid(RequestType::CacheLine);
|
let (_, _, c, _) = cpuid(RequestType::CacheLine);
|
||||||
|
@ -640,6 +685,7 @@ impl fmt::Debug for TimeStampCounter {
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct PhysicalAddressSize(u32);
|
pub struct PhysicalAddressSize(u32);
|
||||||
|
|
||||||
impl PhysicalAddressSize {
|
impl PhysicalAddressSize {
|
||||||
fn new() -> PhysicalAddressSize {
|
fn new() -> PhysicalAddressSize {
|
||||||
let (a, _, _, _) = cpuid(RequestType::PhysicalAddressSize);
|
let (a, _, _, _) = cpuid(RequestType::PhysicalAddressSize);
|
||||||
|
@ -707,12 +753,12 @@ impl Master {
|
||||||
let tpm = when_supported(
|
let tpm = when_supported(
|
||||||
max_value,
|
max_value,
|
||||||
RequestType::ThermalPowerManagementInformation,
|
RequestType::ThermalPowerManagementInformation,
|
||||||
ThermalPowerManagementInformation::new,
|
|| ThermalPowerManagementInformation::new(),
|
||||||
);
|
);
|
||||||
let sei = when_supported(
|
let sei = when_supported(
|
||||||
max_value,
|
max_value,
|
||||||
RequestType::StructuredExtendedInformation,
|
RequestType::StructuredExtendedInformation,
|
||||||
StructuredExtendedInformation::new,
|
|| StructuredExtendedInformation::new(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Extended information
|
// Extended information
|
||||||
|
@ -722,8 +768,9 @@ impl Master {
|
||||||
let eps = when_supported(max_value, RequestType::ExtendedProcessorSignature, || {
|
let eps = when_supported(max_value, RequestType::ExtendedProcessorSignature, || {
|
||||||
ExtendedProcessorSignature::new()
|
ExtendedProcessorSignature::new()
|
||||||
});
|
});
|
||||||
let brand_string = when_supported(max_value, RequestType::BrandString3, BrandString::new);
|
let brand_string =
|
||||||
let cache_line = when_supported(max_value, RequestType::CacheLine, CacheLine::new);
|
when_supported(max_value, RequestType::BrandString3, || BrandString::new());
|
||||||
|
let cache_line = when_supported(max_value, RequestType::CacheLine, || CacheLine::new());
|
||||||
let tsc = when_supported(max_value, RequestType::TimeStampCounter, || {
|
let tsc = when_supported(max_value, RequestType::TimeStampCounter, || {
|
||||||
TimeStampCounter::new()
|
TimeStampCounter::new()
|
||||||
});
|
});
|
||||||
|
@ -736,8 +783,8 @@ impl Master {
|
||||||
thermal_power_management_information: tpm,
|
thermal_power_management_information: tpm,
|
||||||
structured_extended_information: sei,
|
structured_extended_information: sei,
|
||||||
extended_processor_signature: eps,
|
extended_processor_signature: eps,
|
||||||
brand_string,
|
brand_string: brand_string,
|
||||||
cache_line,
|
cache_line: cache_line,
|
||||||
time_stamp_counter: tsc,
|
time_stamp_counter: tsc,
|
||||||
physical_address_size: pas,
|
physical_address_size: pas,
|
||||||
}
|
}
|
||||||
|
@ -761,7 +808,7 @@ impl Master {
|
||||||
self.brand_string
|
self.brand_string
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|bs| bs as &str)
|
.map(|bs| bs as &str)
|
||||||
.or_else(|| self.version_information.and_then(|vi| vi.brand_string()))
|
.or(self.version_information.and_then(|vi| vi.brand_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate_flag!(version_information, {
|
delegate_flag!(version_information, {
|
||||||
|
@ -823,7 +870,7 @@ impl Master {
|
||||||
ss,
|
ss,
|
||||||
htt,
|
htt,
|
||||||
tm,
|
tm,
|
||||||
pbe,
|
pbe
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate_flag!(thermal_power_management_information, {
|
delegate_flag!(thermal_power_management_information, {
|
||||||
|
@ -839,7 +886,7 @@ impl Master {
|
||||||
hwp_energy_performance_preference,
|
hwp_energy_performance_preference,
|
||||||
hdc,
|
hdc,
|
||||||
hardware_coordination_feedback,
|
hardware_coordination_feedback,
|
||||||
performance_energy_bias,
|
performance_energy_bias
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate_flag!(structured_extended_information, {
|
delegate_flag!(structured_extended_information, {
|
||||||
|
@ -871,66 +918,11 @@ impl Master {
|
||||||
execute_disable,
|
execute_disable,
|
||||||
gigabyte_pages,
|
gigabyte_pages,
|
||||||
rdtscp_and_ia32_tsc_aux,
|
rdtscp_and_ia32_tsc_aux,
|
||||||
intel_64_bit_architecture,
|
intel_64_bit_architecture
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate_flag!(time_stamp_counter, { invariant_tsc });
|
delegate_flag!(time_stamp_counter, { invariant_tsc });
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Master {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The main entrypoint to the CPU information
|
|
||||||
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
|
|
||||||
pub fn master() -> Option<Master> {
|
|
||||||
Some(Master::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sysinfo() {}
|
|
||||||
|
|
||||||
pub fn as_bytes(v: &u32) -> &[u8] {
|
|
||||||
let start = v as *const u32 as *const u8;
|
|
||||||
// TODO: use u32::BYTES
|
|
||||||
unsafe { slice::from_raw_parts(start, 4) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cpuid(code: RequestType) -> (u32, u32, u32, u32) {
|
|
||||||
let eax;
|
|
||||||
let ebx;
|
|
||||||
let ecx;
|
|
||||||
let edx;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
asm!(
|
|
||||||
"movq %rbx, {0:r}",
|
|
||||||
"cpuid",
|
|
||||||
"xchgq %rbx, {0:r}",
|
|
||||||
lateout(reg) ebx,
|
|
||||||
inlateout("eax") code as u32 => eax,
|
|
||||||
inlateout("ecx") 0 => ecx,
|
|
||||||
lateout("edx") edx,
|
|
||||||
options(nostack, preserves_flags, att_syntax),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
(eax, ebx, ecx, edx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This matches the Intel Architecture guide, with bits 31 -> 0.
|
|
||||||
// The bit positions are inclusive.
|
|
||||||
fn bits_of(val: u32, start_bit: u8, end_bit: u8) -> u32 {
|
|
||||||
let mut silly = 0;
|
|
||||||
for _ in start_bit..end_bit + 1 {
|
|
||||||
silly <<= 1;
|
|
||||||
silly |= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
(val >> start_bit) & silly
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] {
|
if #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] {
|
|
@ -1,74 +1,34 @@
|
||||||
use super::systeminfo::SystemMemory;
|
// Can be standardized
|
||||||
use crate::{arch::drivers::sysinfo::master, ALLOCATOR};
|
// NOTE: Move this to relib
|
||||||
use core::fmt::Display;
|
pub struct SemanticVersion {
|
||||||
use versioning::Version;
|
pub major: u8,
|
||||||
use x86_64::instructions::interrupts::{disable, enable};
|
pub minor: u8,
|
||||||
|
pub patch: u8,
|
||||||
pub enum CpuType {
|
|
||||||
RiscV(String),
|
|
||||||
X86_64(String),
|
|
||||||
}
|
}
|
||||||
impl Display for CpuType {
|
impl core::fmt::Display for SemanticVersion {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
write!(
|
write!(f, "v{}.{}.{}", self.major, self.minor, self.patch)
|
||||||
f,
|
}
|
||||||
"{}",
|
}
|
||||||
match self {
|
// NOTE: Move to somewhere else
|
||||||
CpuType::RiscV(s) => s,
|
lazy_static! {
|
||||||
CpuType::X86_64(s) => s,
|
pub static ref KINFO: KernelInfo = KernelInfo {
|
||||||
}
|
kernel_version: SemanticVersion {
|
||||||
)
|
major: 0,
|
||||||
}
|
minor: 0,
|
||||||
|
patch: 0,
|
||||||
|
},
|
||||||
|
memory: SystemMemory { used: 0, total: 0 }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// simple info you would want to know in a neofetch like program
|
/// simple info you would want to know in a neofetch like program
|
||||||
pub struct KernelInfo {
|
pub struct KernelInfo {
|
||||||
// os: String,
|
// os: String,
|
||||||
// host: String,
|
// host: String,
|
||||||
pub kernel_version: Version,
|
pub kernel_version: SemanticVersion,
|
||||||
pub cpu: CpuType,
|
// cpu: String,
|
||||||
// gpu: String,
|
// gpu: String,
|
||||||
pub memory: SystemMemory,
|
pub memory: SystemMemory,
|
||||||
}
|
|
||||||
|
|
||||||
impl KernelInfo {
|
|
||||||
pub fn get() -> KernelInfo {
|
|
||||||
disable();
|
|
||||||
let allocator = ALLOCATOR.lock();
|
|
||||||
let total = allocator.size();
|
|
||||||
let used = allocator.used();
|
|
||||||
enable();
|
|
||||||
|
|
||||||
let cpu = CpuType::X86_64(master().unwrap().brand_string().unwrap().to_string());
|
|
||||||
KernelInfo {
|
|
||||||
kernel_version: Version {
|
|
||||||
major: 0,
|
|
||||||
minor: 0,
|
|
||||||
patch: 0,
|
|
||||||
},
|
|
||||||
cpu,
|
|
||||||
memory: SystemMemory { total, used },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for KernelInfo {
|
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"
|
|
||||||
OS: AbleOS
|
|
||||||
Host: {{}}
|
|
||||||
Kernel: {}.{}.{}
|
|
||||||
CPU: {}
|
|
||||||
Memory: {}/{}
|
|
||||||
",
|
|
||||||
self.kernel_version.major,
|
|
||||||
self.kernel_version.minor,
|
|
||||||
self.kernel_version.patch,
|
|
||||||
self.cpu,
|
|
||||||
self.memory.used,
|
|
||||||
self.memory.total
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
use super::systeminfo::SystemMemory;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
|
@ -5,7 +5,6 @@ pub struct MailBoxes {
|
||||||
flags: u8,
|
flags: u8,
|
||||||
mailboxes: [u64; 4],
|
mailboxes: [u64; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MailBoxes {
|
impl MailBoxes {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -13,18 +12,15 @@ impl MailBoxes {
|
||||||
mailboxes: [0; 4],
|
mailboxes: [0; 4],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.flags = 0b0000_0000;
|
self.flags = 0b0000_0000;
|
||||||
self.mailboxes = [0; 4];
|
self.mailboxes = [0; 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mailbox(&mut self, mailbox_num: u8, mailbox_data: u64) {
|
pub fn set_mailbox(&mut self, mailbox_num: u8, mailbox_data: u64) {
|
||||||
if let 0..=3 = mailbox_num {
|
if let 0..=3 = mailbox_num {
|
||||||
self.mailboxes[mailbox_num as usize] = mailbox_data
|
self.mailboxes[mailbox_num as usize] = mailbox_data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_flag(&mut self, flag_num: u8) {
|
pub fn set_flag(&mut self, flag_num: u8) {
|
||||||
match flag_num {
|
match flag_num {
|
||||||
0 => {
|
0 => {
|
||||||
|
@ -105,9 +101,3 @@ impl MailBoxes {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MailBoxes {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
pub mod absi;
|
pub mod absi;
|
||||||
pub mod clip;
|
pub mod clip;
|
||||||
pub mod futex;
|
pub mod futex;
|
||||||
|
pub mod info;
|
||||||
pub mod kinfo;
|
pub mod kinfo;
|
||||||
pub mod mail;
|
pub mod mail;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod systeminfo;
|
pub mod systeminfo;
|
||||||
pub mod virtual_memory;
|
pub mod virtual_memory;
|
||||||
pub mod y_compositor;
|
pub mod y_compositor;
|
||||||
|
|
||||||
pub const BANNER: &str = include_str!("banner.txt");
|
pub const BANNER: &str = include_str!("banner.txt");
|
||||||
|
|
|
@ -5,3 +5,4 @@ pub struct Notification {
|
||||||
text_body: String,
|
text_body: String,
|
||||||
time: u64,
|
time: u64,
|
||||||
}
|
}
|
||||||
|
impl Notification {}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
|
pub type PackageName = String;
|
||||||
use crate::experiments::kinfo::SemanticVersion;
|
use crate::experiments::kinfo::SemanticVersion;
|
||||||
|
|
||||||
// Scuffed
|
// Scuffed
|
||||||
pub type Hash = u8;
|
pub type Hash = u8;
|
||||||
pub type PackageName = String;
|
|
||||||
|
|
||||||
pub struct MetaPackage {
|
pub struct MetaPackage {
|
||||||
pub name: u8,
|
pub name: u8,
|
||||||
pub version: SemanticVersion,
|
pub version: SemanticVersion,
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
pub trait Server {
|
pub trait Server {
|
||||||
/// Initialize the server and return a number
|
/// Initialize the server and return a number
|
||||||
fn initialize() -> u32;
|
fn initialize() -> u32;
|
||||||
|
/// kill the server
|
||||||
/// kill the server
|
fn kill() -> bool;
|
||||||
fn kill() -> bool;
|
// put data in the servers outbox
|
||||||
|
fn send();
|
||||||
// put data in the servers outbox
|
// put data in the servers inbox and notify it
|
||||||
fn send();
|
fn recieve();
|
||||||
|
|
||||||
// put data in the servers inbox and notify it
|
|
||||||
fn recieve();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,36 @@
|
||||||
// Can be standardized
|
// Can be standardized
|
||||||
// NOTE: move the file to the src/ dir
|
// NOTE: move the file to the src/ dir
|
||||||
|
pub struct SystemMemory {
|
||||||
|
pub used: u64,
|
||||||
|
pub total: u64,
|
||||||
|
}
|
||||||
|
impl core::fmt::Display for SystemMemory {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
|
write!(f, "{} Bytes / {} Bytes", self.used, self.total)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
pub fn format_system_info() -> core::string::String {
|
||||||
|
let x = format!(
|
||||||
|
"{}
|
||||||
|
OS: AbleOS
|
||||||
|
Host: ComputAble
|
||||||
|
Kernel: {}
|
||||||
|
Uptime: 0:0:0
|
||||||
|
Packages: 0
|
||||||
|
Shell: Ashell
|
||||||
|
Gpu: MIPS32 R4000 R4k
|
||||||
|
Cpu: {}
|
||||||
|
Memory: {}
|
||||||
|
",
|
||||||
|
crate::experiments::BANNER,
|
||||||
|
crate::experiments::kinfo::KINFO.kernel_version,
|
||||||
|
crate::arch::ARCH,
|
||||||
|
crate::experiments::kinfo::KINFO.memory
|
||||||
|
);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
// */
|
||||||
pub const KERNEL_VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const KERNEL_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
/// A constant to check if the kernel is in debug mode
|
/// A constant to check if the kernel is in debug mode
|
||||||
|
@ -8,14 +38,3 @@ pub const RELEASE_TYPE: &str = "debug";
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
/// A constant to check if the kernel is in release mode
|
/// A constant to check if the kernel is in release mode
|
||||||
pub const RELEASE_TYPE: &str = "release";
|
pub const RELEASE_TYPE: &str = "release";
|
||||||
|
|
||||||
pub struct SystemMemory {
|
|
||||||
pub used: usize,
|
|
||||||
pub total: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl core::fmt::Display for SystemMemory {
|
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
|
||||||
write!(f, "{} Bytes / {} Bytes", self.used, self.total)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,4 +4,4 @@ pub struct Scheduler {
|
||||||
executables: usize,
|
executables: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RunQueue;
|
pub struct RunQueue {}
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
pub struct Compositor;
|
pub struct Compositor {}
|
||||||
|
|
||||||
impl Compositor {
|
impl Compositor {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self
|
Self {}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Compositor {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
//!
|
//!
|
||||||
pub mod compositor;
|
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
pub mod compositor;
|
|
@ -1,17 +1,19 @@
|
||||||
use crate::driver_traits::graphics::Point;
|
use crate::driver_traits::graphics::Point;
|
||||||
|
|
||||||
pub type MenuBar = Vec<MenuOption>;
|
use alloc::string::String;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
pub struct MenuOption {
|
pub struct MenuOption {
|
||||||
symbol: char,
|
symbol: char,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type MenuBar = Vec<MenuOption>;
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
title: String,
|
title: String,
|
||||||
position: Point,
|
position: Point,
|
||||||
fullscreen: bool,
|
fullscreen: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
// all of these should return a result
|
// all of these should return a result
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(title: String, position: Point, fullscreen: bool) -> Self {
|
pub fn new(title: String, position: Point, fullscreen: bool) -> Self {
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
use ext2::{
|
|
||||||
fs::{
|
|
||||||
sync::{Inode, Synced},
|
|
||||||
Ext2,
|
|
||||||
},
|
|
||||||
sector::{SectorSize, Size1024},
|
|
||||||
volume::Volume,
|
|
||||||
};
|
|
||||||
use spin::Lazy;
|
|
||||||
|
|
||||||
pub static FILE_SYSTEM: Lazy<spin::Mutex<Synced<Ext2<Size1024, Vec<u8>>>>> =
|
|
||||||
Lazy::new(|| spin::Mutex::new(load_fs()));
|
|
||||||
|
|
||||||
pub fn walk<S: SectorSize, V: Volume<u8, S>>(
|
|
||||||
fs: &Synced<Ext2<S, V>>,
|
|
||||||
inode: Inode<S, V>,
|
|
||||||
name: String,
|
|
||||||
) {
|
|
||||||
if let Some(dir) = inode.directory() {
|
|
||||||
for entry in dir {
|
|
||||||
assert!(entry.is_ok());
|
|
||||||
let entry = entry.unwrap();
|
|
||||||
let entry_name = String::from_utf8_lossy(&entry.name);
|
|
||||||
|
|
||||||
println!("{}/{} => {}", name, entry_name, entry.inode,);
|
|
||||||
if entry_name != "." && entry_name != ".." {
|
|
||||||
walk(
|
|
||||||
fs,
|
|
||||||
fs.inode_nth(entry.inode).unwrap(),
|
|
||||||
format!("{}/{}", name, entry_name),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_fs() -> Synced<Ext2<Size1024, Vec<u8>>> {
|
|
||||||
let mut volume = Vec::new();
|
|
||||||
volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img"));
|
|
||||||
|
|
||||||
Synced::<Ext2<Size1024, _>>::new(volume).unwrap()
|
|
||||||
}
|
|
|
@ -1,242 +1,260 @@
|
||||||
|
use crate::vga_e::VGAE;
|
||||||
use ab_glyph::{Font, FontRef, Glyph};
|
use ab_glyph::{Font, FontRef, Glyph};
|
||||||
|
use alloc::{boxed::Box, vec, vec::Vec};
|
||||||
use shadeable::{evaluate_shader, pixel_format::Rgba64};
|
use shadeable::{evaluate_shader, pixel_format::Rgba64};
|
||||||
use spin::Lazy;
|
use spin;
|
||||||
|
use vga::writers::GraphicsWriter;
|
||||||
|
|
||||||
pub static SCREEN_BUFFER: Lazy<spin::Mutex<ScreenBuffer>> =
|
#[derive(Debug)]
|
||||||
Lazy::new(|| spin::Mutex::new(ScreenBuffer::new(640, 480)));
|
pub struct ScreenSize {
|
||||||
|
pub x: usize,
|
||||||
|
pub y: usize,
|
||||||
|
}
|
||||||
|
|
||||||
const FONT_SCALE: f32 = 1.6;
|
const FONT_SCALE: f32 = 1.6;
|
||||||
const GLYPH_HEIGHT: f32 = 18.0;
|
const GLYPH_HEIGHT: f32 = 18.0;
|
||||||
const GLYPH_WIDTH: f32 = 10.0;
|
const GLYPH_WIDTH: f32 = 10.0;
|
||||||
|
|
||||||
#[derive(Debug)]
|
lazy_static::lazy_static! {
|
||||||
pub struct ScreenSize {
|
pub static ref SCREEN_BUFFER: spin::Mutex<ScreenBuffer> = spin::Mutex::new(ScreenBuffer::new(640, 480));
|
||||||
pub x: usize,
|
|
||||||
pub y: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenSize {
|
impl ScreenSize {
|
||||||
pub fn new(x: usize, y: usize) -> Self {
|
pub fn new(x: usize, y: usize) -> Self {
|
||||||
Self { x, y }
|
Self { x, y }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum GraphicsReturn {
|
pub enum GraphicsReturn {
|
||||||
Ok,
|
Ok,
|
||||||
ImproperScreenSize,
|
ImproperScreenSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ScreenBuffer {
|
pub struct ScreenBuffer {
|
||||||
pub size: ScreenSize,
|
pub size: ScreenSize,
|
||||||
pub clear_color: Rgba64,
|
pub clear_color: Rgba64,
|
||||||
pub buff: Box<[Rgba64]>,
|
pub buff: Box<[Rgba64]>, // Vec<Rgba64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenBuffer {
|
impl ScreenBuffer {
|
||||||
// Add optional size later
|
// Add optional size later
|
||||||
pub fn new(x: usize, y: usize) -> Self {
|
pub fn new(x: usize, y: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
size: ScreenSize::new(x, y),
|
size: ScreenSize::new(x, y),
|
||||||
clear_color: 0,
|
clear_color: 0,
|
||||||
buff: vec![0u64; x * y].into_boxed_slice(),
|
buff: vec![0u64; x * y].into_boxed_slice(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn draw_filled_circle(&mut self, cx: i32, cy: i32, radius: usize, color: Rgba64) {
|
||||||
|
let r = radius as i32 * 2;
|
||||||
|
for y in 0..640 {
|
||||||
|
for x in 0..480 {
|
||||||
|
let dx = cx - x as i32 * 2 - 1;
|
||||||
|
let dy = cy - y as i32 * 2 - 1;
|
||||||
|
|
||||||
pub fn draw_filled_circle(&mut self, cx: i32, cy: i32, radius: usize, color: Rgba64) {
|
if dx * dx + dy * dy <= r * r {
|
||||||
let r = radius as i32 * 2;
|
self.set_pixel(x, y, color);
|
||||||
for y in 0..640 {
|
};
|
||||||
for x in 0..480 {
|
}
|
||||||
let dx = cx - x as i32 * 2 - 1;
|
}
|
||||||
let dy = cy - y as i32 * 2 - 1;
|
}
|
||||||
|
|
||||||
if dx * dx + dy * dy <= r * r {
|
#[inline]
|
||||||
self.set_pixel(x, y, color);
|
pub fn set_pixel(&mut self, x: usize, y: usize, color: Rgba64) {
|
||||||
};
|
self.buff[y * self.size.x + x] = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.buff = vec![0u64; self.buff.len()].into_boxed_slice();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blit(&mut self, _width: usize, _height: usize) {}
|
||||||
|
pub fn draw_filled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) {
|
||||||
|
for y in y1..y2 {
|
||||||
|
for x in x1..x2 {
|
||||||
|
self.set_pixel(x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn draw_unfilled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) {
|
||||||
|
// x1 y1 => x2 y1 => x2 y2 => x1 y2 => x1 y1
|
||||||
|
self.draw_line(x1, y1, x2, y1, color);
|
||||||
|
self.draw_line(x2, y1, x2, y2, color);
|
||||||
|
self.draw_line(x2, y2, x1, y2, color);
|
||||||
|
self.draw_line(x1, y2, x1, y1, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn draw_line(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) {
|
||||||
|
let x = crate::graphics::get_coordinates(
|
||||||
|
x1.try_into().unwrap(),
|
||||||
|
y1.try_into().unwrap(),
|
||||||
|
x2.try_into().unwrap(),
|
||||||
|
y2.try_into().unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
for coord in x {
|
||||||
|
self.set_pixel(coord.0, coord.1, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shade(&mut self) {
|
||||||
|
for y in 0..100 {
|
||||||
|
for x in 0..100 {
|
||||||
|
let rgba_ret = evaluate_shader(x, y, self.buff[y * self.size.x + x]);
|
||||||
|
match rgba_ret {
|
||||||
|
Ok(pixel) => {
|
||||||
|
// info!("{:?}", pixel);
|
||||||
|
self.set_pixel(x, y, pixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(err) => error!("{}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
info!("Shaders done");
|
||||||
pub fn set_pixel(&mut self, x: usize, y: usize, color: Rgba64) {
|
}
|
||||||
self.buff[y * self.size.x + x] = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
// TODO force clear
|
||||||
self.buff = vec![0u64; self.buff.len()].into_boxed_slice();
|
pub fn force_redraw(&mut self) {
|
||||||
}
|
use shadeable::pixel_format::into_vga_16;
|
||||||
|
VGAE.lock().clear_screen(into_vga_16(self.clear_color));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn blit(&mut self, _width: usize, _height: usize) {}
|
/// Draw a glyph on the screen at the given position
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `x` - the x position of the glyph
|
||||||
|
/// * `y` - the y position of the glyph
|
||||||
|
/// * `glyph` - the glyph to draw
|
||||||
|
/// * `color` - the color of the glyph
|
||||||
|
pub fn draw_char(&mut self, mut x: u32, mut y: u32, character: char, color: Rgba64) {
|
||||||
|
// trace!["Judy Hopps is thicc af"];
|
||||||
|
// let mode = *VGAE.lock();
|
||||||
|
// trace!["She got them bouncy bunny buns"];
|
||||||
|
|
||||||
pub fn draw_filled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) {
|
let basic_multingual_plane = FontRef::try_from_slice(include_bytes!(
|
||||||
for y in y1..y2 {
|
"../../../ableos/assets/fonts/unifont-14.0.01.ttf"
|
||||||
for x in x1..x2 {
|
))
|
||||||
self.set_pixel(x, y, color);
|
.unwrap();
|
||||||
|
|
||||||
|
let supplementary_multilingual_plane = FontRef::try_from_slice(include_bytes!(
|
||||||
|
"../../../ableos/assets/fonts/unifont_upper-14.0.01.ttf"
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// let mut has_char = false;
|
||||||
|
// for x in font.codepoint_ids() {
|
||||||
|
// if x.1 == character {
|
||||||
|
// has_char = true;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
let in_supp_plane = character as u32 > 0xffff;
|
||||||
|
|
||||||
|
let plane = match in_supp_plane {
|
||||||
|
false => basic_multingual_plane,
|
||||||
|
true => supplementary_multilingual_plane,
|
||||||
|
};
|
||||||
|
|
||||||
|
match character {
|
||||||
|
'\n' => {
|
||||||
|
// x = 0;
|
||||||
|
// y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let q_glyph: Glyph = plane.glyph_id(character).with_scale_and_position(
|
||||||
|
20.0 * FONT_SCALE,
|
||||||
|
ab_glyph::point(GLYPH_WIDTH * FONT_SCALE, GLYPH_HEIGHT * FONT_SCALE),
|
||||||
|
);
|
||||||
|
|
||||||
|
// elf: I don't know if GLYPH_HEIGHT is in the right units here. I'm just guessing.
|
||||||
|
if x as usize > self.size.x {
|
||||||
|
x = 0;
|
||||||
|
y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn draw_unfilled_rect(
|
|
||||||
&mut self,
|
|
||||||
x1: usize,
|
|
||||||
y1: usize,
|
|
||||||
x2: usize,
|
|
||||||
y2: usize,
|
|
||||||
color: Rgba64,
|
|
||||||
) {
|
|
||||||
// x1 y1 => x2 y1 => x2 y2 => x1 y2 => x1 y1
|
|
||||||
self.draw_line(x1, y1, x2, y1, color);
|
|
||||||
self.draw_line(x2, y1, x2, y2, color);
|
|
||||||
self.draw_line(x2, y2, x1, y2, color);
|
|
||||||
self.draw_line(x1, y2, x1, y1, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
if let Some(q) = plane.outline_glyph(q_glyph) {
|
||||||
pub fn draw_line(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) {
|
q.draw(|gx, gy, c| {
|
||||||
let x = crate::graphics::get_coordinates(
|
if c > 0.015 {
|
||||||
x1.try_into().unwrap(),
|
let corner = q.px_bounds().min;
|
||||||
y1.try_into().unwrap(),
|
self.set_pixel(
|
||||||
x2.try_into().unwrap(),
|
gx as usize + corner.x as usize + x as usize,
|
||||||
y2.try_into().unwrap(),
|
gy as usize + corner.y as usize + y as usize,
|
||||||
);
|
color,
|
||||||
|
);
|
||||||
for coord in x {
|
}
|
||||||
self.set_pixel(coord.0, coord.1, color);
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shade(&mut self) {
|
|
||||||
for y in 0..100 {
|
|
||||||
for x in 0..100 {
|
|
||||||
let rgba_ret = evaluate_shader(x, y, self.buff[y * self.size.x + x]);
|
|
||||||
match rgba_ret {
|
|
||||||
Ok(pixel) => {
|
|
||||||
// info!("{:?}", pixel);
|
|
||||||
self.set_pixel(x, y, pixel);
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(err) => error!("{}", err),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
info!("Shaders done");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO force clear
|
|
||||||
pub fn force_redraw(&mut self) {
|
|
||||||
// VGAE.lock().clear_screen(vga::colors::Color16::Black);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw a glyph on the screen at the given position
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
/// * `x` - the x position of the glyph
|
|
||||||
/// * `y` - the y position of the glyph
|
|
||||||
/// * `glyph` - the glyph to draw
|
|
||||||
/// * `color` - the color of the glyph
|
|
||||||
pub fn draw_char(&mut self, mut x: u32, mut y: u32, character: char, color: Rgba64) {
|
|
||||||
// trace!["Judy Hopps is thicc af"];
|
|
||||||
// let mode = *VGAE.lock();
|
|
||||||
// trace!["She got them bouncy bunny buns"];
|
|
||||||
|
|
||||||
let basic_multingual_plane = FontRef::try_from_slice(include_bytes!(
|
|
||||||
"../../../ableos/assets/fonts/unifont-14.0.01.ttf"
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let supplementary_multilingual_plane = FontRef::try_from_slice(include_bytes!(
|
|
||||||
"../../../ableos/assets/fonts/unifont_upper-14.0.01.ttf"
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// let mut has_char = false;
|
|
||||||
// for x in font.codepoint_ids() {
|
|
||||||
// if x.1 == character {
|
|
||||||
// has_char = true;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
let in_supp_plane = character as u32 > 0xffff;
|
|
||||||
|
|
||||||
let plane = match in_supp_plane {
|
|
||||||
false => basic_multingual_plane,
|
|
||||||
true => supplementary_multilingual_plane,
|
|
||||||
};
|
|
||||||
|
|
||||||
match character {
|
|
||||||
'\n' => {
|
|
||||||
// x = 0;
|
|
||||||
// y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let q_glyph: Glyph = plane.glyph_id(character).with_scale_and_position(
|
|
||||||
20.0 * FONT_SCALE,
|
|
||||||
ab_glyph::point(GLYPH_WIDTH * FONT_SCALE, GLYPH_HEIGHT * FONT_SCALE),
|
|
||||||
);
|
|
||||||
|
|
||||||
// elf: I don't know if GLYPH_HEIGHT is in the right units here. I'm just guessing.
|
|
||||||
if x as usize > self.size.x {
|
|
||||||
x = 0;
|
|
||||||
y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(q) = plane.outline_glyph(q_glyph) {
|
|
||||||
q.draw(|gx, gy, c| {
|
|
||||||
if c > 0.015 {
|
|
||||||
let corner = q.px_bounds().min;
|
|
||||||
self.set_pixel(
|
|
||||||
gx as usize + corner.x as usize + x as usize,
|
|
||||||
gy as usize + corner.y as usize + y as usize,
|
|
||||||
color,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait VgaBuffer {
|
||||||
|
fn copy_to_buffer(&self) -> GraphicsReturn;
|
||||||
|
}
|
||||||
|
impl VgaBuffer for ScreenBuffer {
|
||||||
|
fn copy_to_buffer(&self) -> GraphicsReturn {
|
||||||
|
let mode = VGAE.lock();
|
||||||
|
for y in 0..self.size.y {
|
||||||
|
for x in 0..self.size.x {
|
||||||
|
use shadeable::pixel_format::into_vga_16;
|
||||||
|
// let vga_color = get_color16(self.buff[y * self.size.x + x]);
|
||||||
|
|
||||||
|
let vga_color = into_vga_16(self.buff[y * self.size.x + x]);
|
||||||
|
|
||||||
|
if into_vga_16(self.clear_color) != vga_color {
|
||||||
|
mode.set_pixel(x, y, vga_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicsReturn::Ok
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn get_coordinates(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<(usize, usize)> {
|
pub fn get_coordinates(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<(usize, usize)> {
|
||||||
let mut coordinates: Vec<(usize, usize)> = vec![];
|
let mut coordinates: Vec<(usize, usize)> = vec![];
|
||||||
let dx: i32 = i32::abs(x2 - x1);
|
let dx: i32 = i32::abs(x2 - x1);
|
||||||
let dy: i32 = i32::abs(y2 - y1);
|
let dy: i32 = i32::abs(y2 - y1);
|
||||||
let sx: i32 = {
|
let sx: i32 = {
|
||||||
if x1 < x2 {
|
if x1 < x2 {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let sy: i32 = {
|
let sy: i32 = {
|
||||||
if y1 < y2 {
|
if y1 < y2 {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut error: i32 = (if dx > dy { dx } else { -dy }) / 2;
|
let mut error: i32 = (if dx > dy { dx } else { -dy }) / 2;
|
||||||
let mut current_x: i32 = x1;
|
let mut current_x: i32 = x1;
|
||||||
let mut current_y: i32 = y1;
|
let mut current_y: i32 = y1;
|
||||||
loop {
|
loop {
|
||||||
coordinates.push((current_x as usize, current_y as usize));
|
coordinates.push((current_x as usize, current_y as usize));
|
||||||
// info!("0 {:?}", (current_x, current_y));
|
// info!("0 {:?}", (current_x, current_y));
|
||||||
|
|
||||||
if current_x == x2 && current_y == y2 {
|
if current_x == x2 && current_y == y2 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let error2: i32 = error;
|
let error2: i32 = error;
|
||||||
|
|
||||||
if error2 > -dx {
|
if error2 > -dx {
|
||||||
error -= dy;
|
error -= dy;
|
||||||
current_x += sx;
|
current_x += sx;
|
||||||
}
|
}
|
||||||
if error2 < dy {
|
if error2 < dy {
|
||||||
error += dx;
|
error += dx;
|
||||||
current_y += sy;
|
current_y += sy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
coordinates
|
||||||
coordinates
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
use spin::Lazy;
|
use alloc::string::{String, ToString};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
pub static KERNEL_STATE: Lazy<spin::Mutex<KernelInternalState>> =
|
lazy_static! {
|
||||||
Lazy::new(|| spin::Mutex::new(KernelInternalState::new()));
|
pub static ref KERNEL_STATE: spin::Mutex<KernelInternalState> =
|
||||||
|
spin::Mutex::new(KernelInternalState::new());
|
||||||
|
}
|
||||||
|
|
||||||
pub struct KernelInternalState {
|
pub struct KernelInternalState {
|
||||||
pub hostname: String,
|
hostname: String,
|
||||||
should_shutdown: bool,
|
should_shutdown: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,9 +31,3 @@ impl KernelInternalState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for KernelInternalState {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,444 +1,176 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
DecodedKey, HandleControl, KeyCode, KeyboardLayout, LayoutEntry, LayoutEntryKind, Modifiers,
|
DecodedKey, HandleControl, KeyCode, KeyboardLayout, LayoutEntry, LayoutEntryKind, Modifiers,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Do not edit this file directly. Instead, create a `Keyboard` and modify that.
|
||||||
|
|
||||||
pub struct CustomLayout {
|
pub struct CustomLayout {
|
||||||
mapping: [LayoutEntry; 256],
|
mapping: [LayoutEntry; 256],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CustomLayout {
|
impl Default for CustomLayout {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new_us104key()
|
Self::new_us104key()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[rustfmt::skip]
|
||||||
impl CustomLayout {
|
impl CustomLayout {
|
||||||
pub fn new_us104key() -> Self {
|
pub fn new_us104key() -> Self {
|
||||||
let mut mapping = Self {
|
let mut mapping = Self {
|
||||||
mapping: [LayoutEntry::default(); 256],
|
mapping: [LayoutEntry::default(); 256],
|
||||||
};
|
};
|
||||||
|
mapping.set(KeyCode::BackTick, LayoutEntry::regular().unshifted('`').shifted('`'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::Escape, LayoutEntry::regular().unshifted('\x1B'));
|
||||||
KeyCode::BackTick,
|
mapping.set(KeyCode::Key0, LayoutEntry::regular().unshifted('0').shifted(')'));
|
||||||
LayoutEntry::regular().unshifted('`').shifted('`'),
|
mapping.set(KeyCode::Key1, LayoutEntry::regular().unshifted('1').shifted('!'));
|
||||||
);
|
mapping.set(KeyCode::Key2, LayoutEntry::regular().unshifted('2').shifted('@'));
|
||||||
mapping.set(KeyCode::Escape, LayoutEntry::regular().unshifted('\x1B'));
|
mapping.set(KeyCode::Key3, LayoutEntry::regular().unshifted('3').shifted('#'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::Key4, LayoutEntry::regular().unshifted('4').shifted('$'));
|
||||||
KeyCode::Key0,
|
mapping.set(KeyCode::Key5, LayoutEntry::regular().unshifted('5').shifted('%'));
|
||||||
LayoutEntry::regular().unshifted('0').shifted(')'),
|
mapping.set(KeyCode::Key6, LayoutEntry::regular().unshifted('6').shifted('^'));
|
||||||
);
|
mapping.set(KeyCode::Key7, LayoutEntry::regular().unshifted('7').shifted('&'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::Key8, LayoutEntry::regular().unshifted('8').shifted('*'));
|
||||||
KeyCode::Key1,
|
mapping.set(KeyCode::Key9, LayoutEntry::regular().unshifted('9').shifted('('));
|
||||||
LayoutEntry::regular().unshifted('1').shifted('!'),
|
mapping.set(KeyCode::Minus, LayoutEntry::regular().unshifted('-').shifted('_'));
|
||||||
);
|
mapping.set(KeyCode::Equals, LayoutEntry::regular().unshifted('=').shifted('+'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::Backspace, LayoutEntry::regular().all('\x08'));
|
||||||
KeyCode::Key2,
|
mapping.set(KeyCode::Tab, LayoutEntry::regular().all('\x09'));
|
||||||
LayoutEntry::regular().unshifted('2').shifted('@'),
|
mapping.set(KeyCode::Q, LayoutEntry::alphabet().low('q').high('Q').raw_unicode('\u{0011}'));
|
||||||
);
|
mapping.set(KeyCode::W, LayoutEntry::alphabet().low('w').high('W').raw_unicode('\u{0017}'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::E, LayoutEntry::alphabet().low('e').high('E').raw_unicode('\u{0005}'));
|
||||||
KeyCode::Key3,
|
mapping.set(KeyCode::R, LayoutEntry::alphabet().low('r').high('R').raw_unicode('\u{0012}'));
|
||||||
LayoutEntry::regular().unshifted('3').shifted('#'),
|
mapping.set(KeyCode::T, LayoutEntry::alphabet().low('t').high('T').raw_unicode('\u{0014}'));
|
||||||
);
|
mapping.set(KeyCode::Y, LayoutEntry::alphabet().low('y').high('Y').raw_unicode('\u{0019}'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::U, LayoutEntry::alphabet().low('u').high('U').raw_unicode('\u{0015}'));
|
||||||
KeyCode::Key4,
|
mapping.set(KeyCode::I, LayoutEntry::alphabet().low('i').high('I').raw_unicode('\u{0009}'));
|
||||||
LayoutEntry::regular().unshifted('4').shifted('$'),
|
mapping.set(KeyCode::O, LayoutEntry::alphabet().low('o').high('O').raw_unicode('\u{000F}'));
|
||||||
);
|
mapping.set(KeyCode::P, LayoutEntry::alphabet().low('p').high('P').raw_unicode('\u{0010}'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::A, LayoutEntry::alphabet().low('a').high('A').raw_unicode('\u{0001}'));
|
||||||
KeyCode::Key5,
|
mapping.set(KeyCode::S, LayoutEntry::alphabet().low('s').high('S').raw_unicode('\u{0013}'));
|
||||||
LayoutEntry::regular().unshifted('5').shifted('%'),
|
mapping.set(KeyCode::D, LayoutEntry::alphabet().low('d').high('D').raw_unicode('\u{0004}'));
|
||||||
);
|
mapping.set(KeyCode::F, LayoutEntry::alphabet().low('f').high('F').raw_unicode('\u{0006}'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::G, LayoutEntry::alphabet().low('g').high('G').raw_unicode('\u{0007}'));
|
||||||
KeyCode::Key6,
|
mapping.set(KeyCode::H, LayoutEntry::alphabet().low('h').high('H').raw_unicode('\u{0008}'));
|
||||||
LayoutEntry::regular().unshifted('6').shifted('^'),
|
mapping.set(KeyCode::J, LayoutEntry::alphabet().low('j').high('J').raw_unicode('\u{000A}'));
|
||||||
);
|
mapping.set(KeyCode::K, LayoutEntry::alphabet().low('k').high('K').raw_unicode('\u{000B}'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::L, LayoutEntry::alphabet().low('l').high('L').raw_unicode('\u{000C}'));
|
||||||
KeyCode::Key7,
|
mapping.set(KeyCode::Z, LayoutEntry::alphabet().low('z').high('Z').raw_unicode('\u{001A}'));
|
||||||
LayoutEntry::regular().unshifted('7').shifted('&'),
|
mapping.set(KeyCode::X, LayoutEntry::alphabet().low('x').high('X').raw_unicode('\u{0018}'));
|
||||||
);
|
mapping.set(KeyCode::C, LayoutEntry::alphabet().low('c').high('C').raw_unicode('\u{0003}'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::V, LayoutEntry::alphabet().low('v').high('V').raw_unicode('\u{0016}'));
|
||||||
KeyCode::Key8,
|
mapping.set(KeyCode::B, LayoutEntry::alphabet().low('b').high('B').raw_unicode('\u{0002}'));
|
||||||
LayoutEntry::regular().unshifted('8').shifted('*'),
|
mapping.set(KeyCode::N, LayoutEntry::alphabet().low('n').high('N').raw_unicode('\u{000E}'));
|
||||||
);
|
mapping.set(KeyCode::M, LayoutEntry::alphabet().low('m').high('M').raw_unicode('\u{000D}'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::BracketSquareLeft, LayoutEntry::regular().unshifted('{').shifted('['));
|
||||||
KeyCode::Key9,
|
mapping.set(KeyCode::BracketSquareRight, LayoutEntry::regular().unshifted('}').shifted(']'));
|
||||||
LayoutEntry::regular().unshifted('9').shifted('('),
|
mapping.set(KeyCode::BackSlash, LayoutEntry::regular().unshifted('|').shifted('\\'));
|
||||||
);
|
mapping.set(KeyCode::SemiColon, LayoutEntry::regular().unshifted(';').shifted(':'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::Quote, LayoutEntry::regular().unshifted('\'').shifted('"'));
|
||||||
KeyCode::Minus,
|
mapping.set(KeyCode::Enter, LayoutEntry::regular().all('\x0A'));
|
||||||
LayoutEntry::regular().unshifted('-').shifted('_'),
|
mapping.set(KeyCode::Comma, LayoutEntry::regular().unshifted(',').shifted('<'));
|
||||||
);
|
mapping.set(KeyCode::Fullstop, LayoutEntry::regular().unshifted('.').shifted('>'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::Slash, LayoutEntry::regular().unshifted('/').shifted('?'));
|
||||||
KeyCode::Equals,
|
mapping.set(KeyCode::Spacebar, LayoutEntry::regular().all(' '));
|
||||||
LayoutEntry::regular().unshifted('=').shifted('+'),
|
mapping.set(KeyCode::Delete, LayoutEntry::regular().all('\x7F'));
|
||||||
);
|
mapping.set(KeyCode::NumpadSlash, LayoutEntry::numpad().all('/'));
|
||||||
mapping.set(KeyCode::Backspace, LayoutEntry::regular().all('\x08'));
|
mapping.set(KeyCode::NumpadStar, LayoutEntry::numpad().all('*'));
|
||||||
mapping.set(KeyCode::Tab, LayoutEntry::regular().all('\x09'));
|
mapping.set(KeyCode::NumpadMinus, LayoutEntry::numpad().all('-'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::Numpad7, LayoutEntry::numpad().low('7').high(KeyCode::Home));
|
||||||
KeyCode::Q,
|
mapping.set(KeyCode::Numpad8, LayoutEntry::numpad().low('8').high(KeyCode::ArrowUp));
|
||||||
LayoutEntry::alphabet()
|
mapping.set(KeyCode::Numpad9, LayoutEntry::numpad().low('9').high(KeyCode::PageUp));
|
||||||
.low('q')
|
mapping.set(KeyCode::NumpadPlus, LayoutEntry::numpad().all('+'));
|
||||||
.high('Q')
|
mapping.set(KeyCode::Numpad4, LayoutEntry::numpad().low('4').high(KeyCode::ArrowLeft));
|
||||||
.raw_unicode('\u{0011}'),
|
mapping.set(KeyCode::Numpad5, LayoutEntry::numpad().all('5'));
|
||||||
);
|
mapping.set(KeyCode::Numpad6, LayoutEntry::numpad().low('6').high(KeyCode::ArrowRight));
|
||||||
mapping.set(
|
mapping.set(KeyCode::Numpad1, LayoutEntry::numpad().low('1').high(KeyCode::End));
|
||||||
KeyCode::W,
|
mapping.set(KeyCode::Numpad2, LayoutEntry::numpad().low('2').high(KeyCode::ArrowDown));
|
||||||
LayoutEntry::alphabet()
|
mapping.set(KeyCode::Numpad3, LayoutEntry::numpad().low('3').high(KeyCode::PageDown));
|
||||||
.low('w')
|
mapping.set(KeyCode::Numpad0, LayoutEntry::numpad().low('0').high(KeyCode::Insert));
|
||||||
.high('W')
|
mapping.set(KeyCode::NumpadPeriod, LayoutEntry::numpad().low('.').high('\x7F'));
|
||||||
.raw_unicode('\u{0017}'),
|
mapping.set(KeyCode::NumpadEnter, LayoutEntry::numpad().all('\x0A'));
|
||||||
);
|
mapping
|
||||||
mapping.set(
|
}
|
||||||
KeyCode::E,
|
pub fn new_us105key() -> Self {
|
||||||
LayoutEntry::alphabet()
|
let mut mapping = Self::new_us104key();
|
||||||
.low('e')
|
mapping.set(KeyCode::BackTick, LayoutEntry::regular().unshifted('`').shifted('¬').altgr('|'));
|
||||||
.high('E')
|
mapping.set(KeyCode::Key2, LayoutEntry::regular().unshifted('2').shifted('"'));
|
||||||
.raw_unicode('\u{0005}'),
|
mapping.set(KeyCode::Quote, LayoutEntry::regular().unshifted('\'').shifted('@'));
|
||||||
);
|
mapping.set(KeyCode::Key3, LayoutEntry::regular().unshifted('3').shifted('£'));
|
||||||
mapping.set(
|
mapping.set(KeyCode::BackTick, LayoutEntry::regular().unshifted('4').shifted('$').altgr('€'));
|
||||||
KeyCode::R,
|
mapping.set(KeyCode::HashTilde, LayoutEntry::regular().unshifted('#').shifted('~'));
|
||||||
LayoutEntry::alphabet()
|
mapping
|
||||||
.low('r')
|
}
|
||||||
.high('R')
|
|
||||||
.raw_unicode('\u{0012}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::T,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('t')
|
|
||||||
.high('T')
|
|
||||||
.raw_unicode('\u{0014}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Y,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('y')
|
|
||||||
.high('Y')
|
|
||||||
.raw_unicode('\u{0019}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::U,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('u')
|
|
||||||
.high('U')
|
|
||||||
.raw_unicode('\u{0015}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::I,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('i')
|
|
||||||
.high('I')
|
|
||||||
.raw_unicode('\u{0009}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::O,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('o')
|
|
||||||
.high('O')
|
|
||||||
.raw_unicode('\u{000F}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::P,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('p')
|
|
||||||
.high('P')
|
|
||||||
.raw_unicode('\u{0010}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::A,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('a')
|
|
||||||
.high('A')
|
|
||||||
.raw_unicode('\u{0001}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::S,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('s')
|
|
||||||
.high('S')
|
|
||||||
.raw_unicode('\u{0013}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::D,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('d')
|
|
||||||
.high('D')
|
|
||||||
.raw_unicode('\u{0004}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::F,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('f')
|
|
||||||
.high('F')
|
|
||||||
.raw_unicode('\u{0006}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::G,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('g')
|
|
||||||
.high('G')
|
|
||||||
.raw_unicode('\u{0007}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::H,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('h')
|
|
||||||
.high('H')
|
|
||||||
.raw_unicode('\u{0008}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::J,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('j')
|
|
||||||
.high('J')
|
|
||||||
.raw_unicode('\u{000A}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::K,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('k')
|
|
||||||
.high('K')
|
|
||||||
.raw_unicode('\u{000B}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::L,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('l')
|
|
||||||
.high('L')
|
|
||||||
.raw_unicode('\u{000C}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Z,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('z')
|
|
||||||
.high('Z')
|
|
||||||
.raw_unicode('\u{001A}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::X,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('x')
|
|
||||||
.high('X')
|
|
||||||
.raw_unicode('\u{0018}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::C,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('c')
|
|
||||||
.high('C')
|
|
||||||
.raw_unicode('\u{0003}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::V,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('v')
|
|
||||||
.high('V')
|
|
||||||
.raw_unicode('\u{0016}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::B,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('b')
|
|
||||||
.high('B')
|
|
||||||
.raw_unicode('\u{0002}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::N,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('n')
|
|
||||||
.high('N')
|
|
||||||
.raw_unicode('\u{000E}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::M,
|
|
||||||
LayoutEntry::alphabet()
|
|
||||||
.low('m')
|
|
||||||
.high('M')
|
|
||||||
.raw_unicode('\u{000D}'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::BracketSquareLeft,
|
|
||||||
LayoutEntry::regular().unshifted('{').shifted('['),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::BracketSquareRight,
|
|
||||||
LayoutEntry::regular().unshifted('}').shifted(']'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::BackSlash,
|
|
||||||
LayoutEntry::regular().unshifted('|').shifted('\\'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::SemiColon,
|
|
||||||
LayoutEntry::regular().unshifted(';').shifted(':'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Quote,
|
|
||||||
LayoutEntry::regular().unshifted('\'').shifted('"'),
|
|
||||||
);
|
|
||||||
mapping.set(KeyCode::Enter, LayoutEntry::regular().all('\x0A'));
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Comma,
|
|
||||||
LayoutEntry::regular().unshifted(',').shifted('<'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Fullstop,
|
|
||||||
LayoutEntry::regular().unshifted('.').shifted('>'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Slash,
|
|
||||||
LayoutEntry::regular().unshifted('/').shifted('?'),
|
|
||||||
);
|
|
||||||
mapping.set(KeyCode::Spacebar, LayoutEntry::regular().all(' '));
|
|
||||||
mapping.set(KeyCode::Delete, LayoutEntry::regular().all('\x7F'));
|
|
||||||
mapping.set(KeyCode::NumpadSlash, LayoutEntry::numpad().all('/'));
|
|
||||||
mapping.set(KeyCode::NumpadStar, LayoutEntry::numpad().all('*'));
|
|
||||||
mapping.set(KeyCode::NumpadMinus, LayoutEntry::numpad().all('-'));
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Numpad7,
|
|
||||||
LayoutEntry::numpad().low('7').high(KeyCode::Home),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Numpad8,
|
|
||||||
LayoutEntry::numpad().low('8').high(KeyCode::ArrowUp),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Numpad9,
|
|
||||||
LayoutEntry::numpad().low('9').high(KeyCode::PageUp),
|
|
||||||
);
|
|
||||||
mapping.set(KeyCode::NumpadPlus, LayoutEntry::numpad().all('+'));
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Numpad4,
|
|
||||||
LayoutEntry::numpad().low('4').high(KeyCode::ArrowLeft),
|
|
||||||
);
|
|
||||||
mapping.set(KeyCode::Numpad5, LayoutEntry::numpad().all('5'));
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Numpad6,
|
|
||||||
LayoutEntry::numpad().low('6').high(KeyCode::ArrowRight),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Numpad1,
|
|
||||||
LayoutEntry::numpad().low('1').high(KeyCode::End),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Numpad2,
|
|
||||||
LayoutEntry::numpad().low('2').high(KeyCode::ArrowDown),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Numpad3,
|
|
||||||
LayoutEntry::numpad().low('3').high(KeyCode::PageDown),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Numpad0,
|
|
||||||
LayoutEntry::numpad().low('0').high(KeyCode::Insert),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::NumpadPeriod,
|
|
||||||
LayoutEntry::numpad().low('.').high('\x7F'),
|
|
||||||
);
|
|
||||||
mapping.set(KeyCode::NumpadEnter, LayoutEntry::numpad().all('\x0A'));
|
|
||||||
mapping
|
|
||||||
}
|
|
||||||
pub fn new_us105key() -> Self {
|
|
||||||
let mut mapping = Self::new_us104key();
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::BackTick,
|
|
||||||
LayoutEntry::regular()
|
|
||||||
.unshifted('`')
|
|
||||||
.shifted('¬')
|
|
||||||
.altgr('|'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Key2,
|
|
||||||
LayoutEntry::regular().unshifted('2').shifted('"'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Quote,
|
|
||||||
LayoutEntry::regular().unshifted('\'').shifted('@'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::Key3,
|
|
||||||
LayoutEntry::regular().unshifted('3').shifted('£'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::BackTick,
|
|
||||||
LayoutEntry::regular()
|
|
||||||
.unshifted('4')
|
|
||||||
.shifted('$')
|
|
||||||
.altgr('€'),
|
|
||||||
);
|
|
||||||
mapping.set(
|
|
||||||
KeyCode::HashTilde,
|
|
||||||
LayoutEntry::regular().unshifted('#').shifted('~'),
|
|
||||||
);
|
|
||||||
mapping
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set(&mut self, pos: KeyCode, entry: LayoutEntry) {
|
|
||||||
self.mapping[pos as usize] = entry;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyboardLayout for CustomLayout {
|
impl KeyboardLayout for CustomLayout {
|
||||||
fn map_keycode(
|
fn map_keycode(
|
||||||
&self,
|
&self,
|
||||||
keycode: KeyCode,
|
keycode: KeyCode,
|
||||||
modifiers: &Modifiers,
|
modifiers: &Modifiers,
|
||||||
handle_ctrl: HandleControl,
|
handle_ctrl: HandleControl,
|
||||||
) -> DecodedKey {
|
) -> DecodedKey {
|
||||||
let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode;
|
let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode;
|
||||||
let spot = &self.mapping[keycode as usize];
|
let spot = &self.mapping[keycode as usize];
|
||||||
if let Some(k) = if map_to_unicode && modifiers.is_ctrl() {
|
if let Some(k) = if map_to_unicode && modifiers.is_ctrl() {
|
||||||
match spot.kind {
|
match spot.kind {
|
||||||
LayoutEntryKind::Regular => spot.raw_unicode,
|
LayoutEntryKind::Regular => spot.raw_unicode,
|
||||||
LayoutEntryKind::Numlockable => None,
|
LayoutEntryKind::Numlockable => None,
|
||||||
LayoutEntryKind::Capslockable => spot.raw_unicode,
|
LayoutEntryKind::Capslockable => spot.raw_unicode,
|
||||||
|
}
|
||||||
|
} else if modifiers.alt_gr {
|
||||||
|
match spot.kind {
|
||||||
|
LayoutEntryKind::Regular => spot.altgr,
|
||||||
|
LayoutEntryKind::Numlockable => None,
|
||||||
|
LayoutEntryKind::Capslockable => spot.altgr,
|
||||||
|
}
|
||||||
|
} else if modifiers.is_shifted() {
|
||||||
|
match spot.kind {
|
||||||
|
LayoutEntryKind::Regular => spot.shifted,
|
||||||
|
LayoutEntryKind::Numlockable => {
|
||||||
|
if modifiers.numlock {
|
||||||
|
spot.locked_shifted
|
||||||
|
} else {
|
||||||
|
spot.shifted
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if modifiers.alt_gr {
|
LayoutEntryKind::Capslockable => {
|
||||||
match spot.kind {
|
if modifiers.is_caps() {
|
||||||
LayoutEntryKind::Regular => spot.altgr,
|
spot.locked_shifted
|
||||||
LayoutEntryKind::Numlockable => None,
|
} else {
|
||||||
LayoutEntryKind::Capslockable => spot.altgr,
|
spot.shifted
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if modifiers.is_shifted() {
|
}
|
||||||
match spot.kind {
|
} else {
|
||||||
LayoutEntryKind::Regular => spot.shifted,
|
match spot.kind {
|
||||||
LayoutEntryKind::Numlockable => {
|
LayoutEntryKind::Regular => spot.unshifted,
|
||||||
if modifiers.numlock {
|
LayoutEntryKind::Numlockable => {
|
||||||
spot.locked_shifted
|
if modifiers.numlock {
|
||||||
} else {
|
spot.locked
|
||||||
spot.shifted
|
} else {
|
||||||
}
|
spot.unshifted
|
||||||
}
|
}
|
||||||
LayoutEntryKind::Capslockable => {
|
|
||||||
if modifiers.is_caps() {
|
|
||||||
spot.locked_shifted
|
|
||||||
} else {
|
|
||||||
spot.shifted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
LayoutEntryKind::Capslockable => {
|
||||||
match spot.kind {
|
if modifiers.is_caps() {
|
||||||
LayoutEntryKind::Regular => spot.unshifted,
|
spot.locked
|
||||||
LayoutEntryKind::Numlockable => {
|
} else {
|
||||||
if modifiers.numlock {
|
spot.unshifted
|
||||||
spot.locked
|
}
|
||||||
} else {
|
|
||||||
spot.unshifted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LayoutEntryKind::Capslockable => {
|
|
||||||
if modifiers.is_caps() {
|
|
||||||
spot.locked
|
|
||||||
} else {
|
|
||||||
spot.unshifted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} {
|
}
|
||||||
k
|
} {
|
||||||
} else {
|
k
|
||||||
DecodedKey::RawKey(keycode as u8)
|
} else {
|
||||||
}
|
DecodedKey::RawKey(keycode as u8)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note(elfein) Not super hard to get right, but still- DO NOT TOUCH
|
||||||
|
impl CustomLayout {
|
||||||
|
// See how hard this is to get right?
|
||||||
|
// See the complexity of all the methods?
|
||||||
|
// Yeah- if you don't know what you're doing, ask before you touch!
|
||||||
|
pub fn set(&mut self, pos: KeyCode, entry: LayoutEntry) {
|
||||||
|
self.mapping[pos as usize] = entry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,262 +1,253 @@
|
||||||
use crate::{
|
use crate::{KeyCode, ScancodeSet, DecodeState, KeyEvent, Error, KeyState, keyboard::EXTENDED_KEY_CODE};
|
||||||
keyboard::EXTENDED_KEY_CODE, DecodeState, Error, KeyCode, KeyEvent, KeyState, ScancodeSet,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct CustomScancodeSet {
|
pub struct CustomScancodeSet {
|
||||||
single_byte: [Option<KeyCode>; 256],
|
single_byte: [Option<KeyCode>; 256],
|
||||||
extended: [Option<KeyCode>; 256],
|
extended: [Option<KeyCode>; 256],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CustomScancodeSet {
|
impl Default for CustomScancodeSet {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::scancode_set1()
|
Self::scancode_set1()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CustomScancodeSet {
|
impl CustomScancodeSet {
|
||||||
pub fn scancode_set1() -> Self {
|
pub fn scancode_set1() -> Self {
|
||||||
let mut scancode_set = Self {
|
let mut scancode_set = Self {
|
||||||
single_byte: [None; 256],
|
single_byte: [None; 256],
|
||||||
extended: [None; 256],
|
extended: [None; 256],
|
||||||
};
|
};
|
||||||
|
scancode_set.single_byte[0x01] = Some(KeyCode::Escape); // 01
|
||||||
scancode_set.single_byte[0x01] = Some(KeyCode::Escape); // 01
|
scancode_set.single_byte[0x02] = Some(KeyCode::Key1); // 02
|
||||||
scancode_set.single_byte[0x02] = Some(KeyCode::Key1); // 02
|
scancode_set.single_byte[0x03] = Some(KeyCode::Key2); // 03
|
||||||
scancode_set.single_byte[0x03] = Some(KeyCode::Key2); // 03
|
scancode_set.single_byte[0x04] = Some(KeyCode::Key3); // 04
|
||||||
scancode_set.single_byte[0x04] = Some(KeyCode::Key3); // 04
|
scancode_set.single_byte[0x05] = Some(KeyCode::Key4); // 05
|
||||||
scancode_set.single_byte[0x05] = Some(KeyCode::Key4); // 05
|
scancode_set.single_byte[0x06] = Some(KeyCode::Key5); // 06
|
||||||
scancode_set.single_byte[0x06] = Some(KeyCode::Key5); // 06
|
scancode_set.single_byte[0x07] = Some(KeyCode::Key6); // 07
|
||||||
scancode_set.single_byte[0x07] = Some(KeyCode::Key6); // 07
|
scancode_set.single_byte[0x08] = Some(KeyCode::Key7); // 08
|
||||||
scancode_set.single_byte[0x08] = Some(KeyCode::Key7); // 08
|
scancode_set.single_byte[0x09] = Some(KeyCode::Key8); // 09
|
||||||
scancode_set.single_byte[0x09] = Some(KeyCode::Key8); // 09
|
scancode_set.single_byte[0x0A] = Some(KeyCode::Key9); // 0A
|
||||||
scancode_set.single_byte[0x0A] = Some(KeyCode::Key9); // 0A
|
scancode_set.single_byte[0x0B] = Some(KeyCode::Key0); // 0B
|
||||||
scancode_set.single_byte[0x0B] = Some(KeyCode::Key0); // 0B
|
scancode_set.single_byte[0x0C] = Some(KeyCode::Minus); // 0C
|
||||||
scancode_set.single_byte[0x0C] = Some(KeyCode::Minus); // 0C
|
scancode_set.single_byte[0x0D] = Some(KeyCode::Equals); // 0D
|
||||||
scancode_set.single_byte[0x0D] = Some(KeyCode::Equals); // 0D
|
scancode_set.single_byte[0x0E] = Some(KeyCode::Backspace); // 0E
|
||||||
scancode_set.single_byte[0x0E] = Some(KeyCode::Backspace); // 0E
|
scancode_set.single_byte[0x0F] = Some(KeyCode::Tab); // 0F
|
||||||
scancode_set.single_byte[0x0F] = Some(KeyCode::Tab); // 0F
|
scancode_set.single_byte[0x10] = Some(KeyCode::Q); // 10
|
||||||
scancode_set.single_byte[0x10] = Some(KeyCode::Q); // 10
|
scancode_set.single_byte[0x11] = Some(KeyCode::W); // 11
|
||||||
scancode_set.single_byte[0x11] = Some(KeyCode::W); // 11
|
scancode_set.single_byte[0x12] = Some(KeyCode::E); // 12
|
||||||
scancode_set.single_byte[0x12] = Some(KeyCode::E); // 12
|
scancode_set.single_byte[0x13] = Some(KeyCode::R); // 13
|
||||||
scancode_set.single_byte[0x13] = Some(KeyCode::R); // 13
|
scancode_set.single_byte[0x14] = Some(KeyCode::T); // 14
|
||||||
scancode_set.single_byte[0x14] = Some(KeyCode::T); // 14
|
scancode_set.single_byte[0x15] = Some(KeyCode::Y); // 15
|
||||||
scancode_set.single_byte[0x15] = Some(KeyCode::Y); // 15
|
scancode_set.single_byte[0x16] = Some(KeyCode::U); // 16
|
||||||
scancode_set.single_byte[0x16] = Some(KeyCode::U); // 16
|
scancode_set.single_byte[0x17] = Some(KeyCode::I); // 17
|
||||||
scancode_set.single_byte[0x17] = Some(KeyCode::I); // 17
|
scancode_set.single_byte[0x18] = Some(KeyCode::O); // 18
|
||||||
scancode_set.single_byte[0x18] = Some(KeyCode::O); // 18
|
scancode_set.single_byte[0x19] = Some(KeyCode::P); // 19
|
||||||
scancode_set.single_byte[0x19] = Some(KeyCode::P); // 19
|
scancode_set.single_byte[0x1A] = Some(KeyCode::BracketSquareLeft); // 1A
|
||||||
scancode_set.single_byte[0x1A] = Some(KeyCode::BracketSquareLeft); // 1A
|
scancode_set.single_byte[0x1B] = Some(KeyCode::BracketSquareRight); // 1B
|
||||||
scancode_set.single_byte[0x1B] = Some(KeyCode::BracketSquareRight); // 1B
|
scancode_set.single_byte[0x1C] = Some(KeyCode::Enter); // 1C
|
||||||
scancode_set.single_byte[0x1C] = Some(KeyCode::Enter); // 1C
|
scancode_set.single_byte[0x1D] = Some(KeyCode::ControlLeft); // 1D
|
||||||
scancode_set.single_byte[0x1D] = Some(KeyCode::ControlLeft); // 1D
|
scancode_set.single_byte[0x1E] = Some(KeyCode::A); // 1E
|
||||||
scancode_set.single_byte[0x1E] = Some(KeyCode::A); // 1E
|
scancode_set.single_byte[0x1F] = Some(KeyCode::S); // 1F
|
||||||
scancode_set.single_byte[0x1F] = Some(KeyCode::S); // 1F
|
scancode_set.single_byte[0x20] = Some(KeyCode::D); // 20
|
||||||
scancode_set.single_byte[0x20] = Some(KeyCode::D); // 20
|
scancode_set.single_byte[0x21] = Some(KeyCode::F); // 21
|
||||||
scancode_set.single_byte[0x21] = Some(KeyCode::F); // 21
|
scancode_set.single_byte[0x22] = Some(KeyCode::G); // 22
|
||||||
scancode_set.single_byte[0x22] = Some(KeyCode::G); // 22
|
scancode_set.single_byte[0x23] = Some(KeyCode::H); // 23
|
||||||
scancode_set.single_byte[0x23] = Some(KeyCode::H); // 23
|
scancode_set.single_byte[0x24] = Some(KeyCode::J); // 24
|
||||||
scancode_set.single_byte[0x24] = Some(KeyCode::J); // 24
|
scancode_set.single_byte[0x25] = Some(KeyCode::K); // 25
|
||||||
scancode_set.single_byte[0x25] = Some(KeyCode::K); // 25
|
scancode_set.single_byte[0x26] = Some(KeyCode::L); // 26
|
||||||
scancode_set.single_byte[0x26] = Some(KeyCode::L); // 26
|
scancode_set.single_byte[0x27] = Some(KeyCode::SemiColon); // 27
|
||||||
scancode_set.single_byte[0x27] = Some(KeyCode::SemiColon); // 27
|
scancode_set.single_byte[0x28] = Some(KeyCode::Quote); // 28
|
||||||
scancode_set.single_byte[0x28] = Some(KeyCode::Quote); // 28
|
scancode_set.single_byte[0x29] = Some(KeyCode::BackTick); // 29
|
||||||
scancode_set.single_byte[0x29] = Some(KeyCode::BackTick); // 29
|
scancode_set.single_byte[0x2A] = Some(KeyCode::ShiftLeft); // 2A
|
||||||
scancode_set.single_byte[0x2A] = Some(KeyCode::ShiftLeft); // 2A
|
scancode_set.single_byte[0x2B] = Some(KeyCode::BackSlash); // 2B
|
||||||
scancode_set.single_byte[0x2B] = Some(KeyCode::BackSlash); // 2B
|
scancode_set.single_byte[0x2C] = Some(KeyCode::Z); // 2C
|
||||||
scancode_set.single_byte[0x2C] = Some(KeyCode::Z); // 2C
|
scancode_set.single_byte[0x2D] = Some(KeyCode::X); // 2D
|
||||||
scancode_set.single_byte[0x2D] = Some(KeyCode::X); // 2D
|
scancode_set.single_byte[0x2E] = Some(KeyCode::C); // 2E
|
||||||
scancode_set.single_byte[0x2E] = Some(KeyCode::C); // 2E
|
scancode_set.single_byte[0x2F] = Some(KeyCode::V); // 2F
|
||||||
scancode_set.single_byte[0x2F] = Some(KeyCode::V); // 2F
|
scancode_set.single_byte[0x30] = Some(KeyCode::B); // 30
|
||||||
scancode_set.single_byte[0x30] = Some(KeyCode::B); // 30
|
scancode_set.single_byte[0x31] = Some(KeyCode::N); // 31
|
||||||
scancode_set.single_byte[0x31] = Some(KeyCode::N); // 31
|
scancode_set.single_byte[0x32] = Some(KeyCode::M); // 32
|
||||||
scancode_set.single_byte[0x32] = Some(KeyCode::M); // 32
|
scancode_set.single_byte[0x33] = Some(KeyCode::Comma); // 33
|
||||||
scancode_set.single_byte[0x33] = Some(KeyCode::Comma); // 33
|
scancode_set.single_byte[0x34] = Some(KeyCode::Fullstop); // 34
|
||||||
scancode_set.single_byte[0x34] = Some(KeyCode::Fullstop); // 34
|
scancode_set.single_byte[0x35] = Some(KeyCode::Slash); // 35
|
||||||
scancode_set.single_byte[0x35] = Some(KeyCode::Slash); // 35
|
scancode_set.single_byte[0x36] = Some(KeyCode::ShiftRight); // 36
|
||||||
scancode_set.single_byte[0x36] = Some(KeyCode::ShiftRight); // 36
|
scancode_set.single_byte[0x37] = Some(KeyCode::NumpadStar); // 37
|
||||||
scancode_set.single_byte[0x37] = Some(KeyCode::NumpadStar); // 37
|
scancode_set.single_byte[0x38] = Some(KeyCode::AltLeft); // 38
|
||||||
scancode_set.single_byte[0x38] = Some(KeyCode::AltLeft); // 38
|
scancode_set.single_byte[0x39] = Some(KeyCode::Spacebar); // 39
|
||||||
scancode_set.single_byte[0x39] = Some(KeyCode::Spacebar); // 39
|
scancode_set.single_byte[0x3A] = Some(KeyCode::CapsLock); // 3A
|
||||||
scancode_set.single_byte[0x3A] = Some(KeyCode::CapsLock); // 3A
|
scancode_set.single_byte[0x3B] = Some(KeyCode::F1); // 3B
|
||||||
scancode_set.single_byte[0x3B] = Some(KeyCode::F1); // 3B
|
scancode_set.single_byte[0x3C] = Some(KeyCode::F2); // 3C
|
||||||
scancode_set.single_byte[0x3C] = Some(KeyCode::F2); // 3C
|
scancode_set.single_byte[0x3D] = Some(KeyCode::F3); // 3D
|
||||||
scancode_set.single_byte[0x3D] = Some(KeyCode::F3); // 3D
|
scancode_set.single_byte[0x3E] = Some(KeyCode::F4); // 3E
|
||||||
scancode_set.single_byte[0x3E] = Some(KeyCode::F4); // 3E
|
scancode_set.single_byte[0x3F] = Some(KeyCode::F5); // 3F
|
||||||
scancode_set.single_byte[0x3F] = Some(KeyCode::F5); // 3F
|
scancode_set.single_byte[0x40] = Some(KeyCode::F6); // 40
|
||||||
scancode_set.single_byte[0x40] = Some(KeyCode::F6); // 40
|
scancode_set.single_byte[0x41] = Some(KeyCode::F7); // 41
|
||||||
scancode_set.single_byte[0x41] = Some(KeyCode::F7); // 41
|
scancode_set.single_byte[0x42] = Some(KeyCode::F8); // 42
|
||||||
scancode_set.single_byte[0x42] = Some(KeyCode::F8); // 42
|
scancode_set.single_byte[0x43] = Some(KeyCode::F9); // 43
|
||||||
scancode_set.single_byte[0x43] = Some(KeyCode::F9); // 43
|
scancode_set.single_byte[0x44] = Some(KeyCode::F10); // 44
|
||||||
scancode_set.single_byte[0x44] = Some(KeyCode::F10); // 44
|
scancode_set.single_byte[0x45] = Some(KeyCode::NumpadLock); // 45
|
||||||
scancode_set.single_byte[0x45] = Some(KeyCode::NumpadLock); // 45
|
scancode_set.single_byte[0x46] = Some(KeyCode::ScrollLock); // 46
|
||||||
scancode_set.single_byte[0x46] = Some(KeyCode::ScrollLock); // 46
|
scancode_set.single_byte[0x47] = Some(KeyCode::Numpad7); // 47
|
||||||
scancode_set.single_byte[0x47] = Some(KeyCode::Numpad7); // 47
|
scancode_set.single_byte[0x48] = Some(KeyCode::Numpad8); // 48
|
||||||
scancode_set.single_byte[0x48] = Some(KeyCode::Numpad8); // 48
|
scancode_set.single_byte[0x49] = Some(KeyCode::Numpad9); // 49
|
||||||
scancode_set.single_byte[0x49] = Some(KeyCode::Numpad9); // 49
|
scancode_set.single_byte[0x4A] = Some(KeyCode::NumpadMinus); // 4A
|
||||||
scancode_set.single_byte[0x4A] = Some(KeyCode::NumpadMinus); // 4A
|
scancode_set.single_byte[0x4B] = Some(KeyCode::Numpad4); // 4B
|
||||||
scancode_set.single_byte[0x4B] = Some(KeyCode::Numpad4); // 4B
|
scancode_set.single_byte[0x4C] = Some(KeyCode::Numpad5); // 4C
|
||||||
scancode_set.single_byte[0x4C] = Some(KeyCode::Numpad5); // 4C
|
scancode_set.single_byte[0x4D] = Some(KeyCode::Numpad6); // 4D
|
||||||
scancode_set.single_byte[0x4D] = Some(KeyCode::Numpad6); // 4D
|
scancode_set.single_byte[0x4E] = Some(KeyCode::NumpadPlus); // 4E
|
||||||
scancode_set.single_byte[0x4E] = Some(KeyCode::NumpadPlus); // 4E
|
scancode_set.single_byte[0x4F] = Some(KeyCode::Numpad1); // 4F
|
||||||
scancode_set.single_byte[0x4F] = Some(KeyCode::Numpad1); // 4F
|
scancode_set.single_byte[0x50] = Some(KeyCode::Numpad2); // 50
|
||||||
scancode_set.single_byte[0x50] = Some(KeyCode::Numpad2); // 50
|
scancode_set.single_byte[0x51] = Some(KeyCode::Numpad3); // 51
|
||||||
scancode_set.single_byte[0x51] = Some(KeyCode::Numpad3); // 51
|
scancode_set.single_byte[0x52] = Some(KeyCode::Numpad0); // 52
|
||||||
scancode_set.single_byte[0x52] = Some(KeyCode::Numpad0); // 52
|
scancode_set.single_byte[0x53] = Some(KeyCode::NumpadPeriod); // 53
|
||||||
scancode_set.single_byte[0x53] = Some(KeyCode::NumpadPeriod); // 53
|
// 0x54
|
||||||
// 0x54
|
// 0x55
|
||||||
// 0x55
|
// 0x56
|
||||||
// 0x56
|
scancode_set.single_byte[0x57] = Some(KeyCode::F11); // 57
|
||||||
scancode_set.single_byte[0x57] = Some(KeyCode::F11); // 57
|
scancode_set.single_byte[0x58] = Some(KeyCode::F12); // 58
|
||||||
scancode_set.single_byte[0x58] = Some(KeyCode::F12); // 58
|
for i in 0x81..=0xD8 {
|
||||||
for i in 0x81..=0xD8 {
|
scancode_set.single_byte[i] = scancode_set.single_byte[i - 0x80];
|
||||||
scancode_set.single_byte[i] = scancode_set.single_byte[i - 0x80];
|
}
|
||||||
}
|
scancode_set.extended[0x10] = Some(KeyCode::PrevTrack); // E010
|
||||||
scancode_set.extended[0x10] = Some(KeyCode::PrevTrack); // E010
|
//0x11
|
||||||
//0x11
|
//0x12
|
||||||
//0x12
|
//0x13
|
||||||
//0x13
|
//0x14
|
||||||
//0x14
|
//0x15
|
||||||
//0x15
|
//0x16
|
||||||
//0x16
|
//0x17
|
||||||
//0x17
|
//0x18
|
||||||
//0x18
|
scancode_set.extended[0x19] = Some(KeyCode::NextTrack); // E019
|
||||||
scancode_set.extended[0x19] = Some(KeyCode::NextTrack); // E019
|
//0x1A
|
||||||
//0x1A
|
//0x1B
|
||||||
//0x1B
|
scancode_set.extended[0x1C] = Some(KeyCode::NumpadEnter); // E01C
|
||||||
scancode_set.extended[0x1C] = Some(KeyCode::NumpadEnter); // E01C
|
scancode_set.extended[0x1D] = Some(KeyCode::ControlRight); // E01D
|
||||||
scancode_set.extended[0x1D] = Some(KeyCode::ControlRight); // E01D
|
//0x1E
|
||||||
//0x1E
|
//0x1F
|
||||||
//0x1F
|
scancode_set.extended[0x20] = Some(KeyCode::Mute); // E020
|
||||||
scancode_set.extended[0x20] = Some(KeyCode::Mute); // E020
|
scancode_set.extended[0x21] = Some(KeyCode::Calculator); // E021
|
||||||
scancode_set.extended[0x21] = Some(KeyCode::Calculator); // E021
|
scancode_set.extended[0x22] = Some(KeyCode::Play); // E022
|
||||||
scancode_set.extended[0x22] = Some(KeyCode::Play); // E022
|
//0x23
|
||||||
//0x23
|
scancode_set.extended[0x24] = Some(KeyCode::Stop); // E024
|
||||||
scancode_set.extended[0x24] = Some(KeyCode::Stop); // E024
|
//0x25
|
||||||
//0x25
|
//0x26
|
||||||
//0x26
|
//0x27
|
||||||
//0x27
|
//0x28
|
||||||
//0x28
|
//0x29
|
||||||
//0x29
|
//0x2A
|
||||||
//0x2A
|
//0x2B
|
||||||
//0x2B
|
//0x2C
|
||||||
//0x2C
|
//0x2D
|
||||||
//0x2D
|
scancode_set.extended[0x2E] = Some(KeyCode::VolumeDown); // E02E
|
||||||
scancode_set.extended[0x2E] = Some(KeyCode::VolumeDown); // E02E
|
//0x2F
|
||||||
//0x2F
|
scancode_set.extended[0x30] = Some(KeyCode::VolumeUp); // E030
|
||||||
scancode_set.extended[0x30] = Some(KeyCode::VolumeUp); // E030
|
//0x31
|
||||||
//0x31
|
scancode_set.extended[0x32] = Some(KeyCode::WWWHome); // E032
|
||||||
scancode_set.extended[0x32] = Some(KeyCode::WWWHome); // E032
|
//0x33
|
||||||
//0x33
|
//0x34
|
||||||
//0x34
|
scancode_set.extended[0x35] = Some(KeyCode::NumpadSlash); // E035
|
||||||
scancode_set.extended[0x35] = Some(KeyCode::NumpadSlash); // E035
|
//0x36
|
||||||
//0x36
|
//0x37
|
||||||
//0x37
|
scancode_set.extended[0x38] = Some(KeyCode::AltRight); // E038
|
||||||
scancode_set.extended[0x38] = Some(KeyCode::AltRight); // E038
|
//0x39
|
||||||
//0x39
|
//0x3A
|
||||||
//0x3A
|
//0x3B
|
||||||
//0x3B
|
//0x3C
|
||||||
//0x3C
|
//0x3D
|
||||||
//0x3D
|
//0x3E
|
||||||
//0x3E
|
//0x3F
|
||||||
//0x3F
|
//0x40
|
||||||
//0x40
|
//0x41
|
||||||
//0x41
|
//0x42
|
||||||
//0x42
|
//0x43
|
||||||
//0x43
|
//0x44
|
||||||
//0x44
|
//0x45
|
||||||
//0x45
|
//0x46
|
||||||
//0x46
|
scancode_set.extended[0x47] = Some(KeyCode::Home); // E047
|
||||||
scancode_set.extended[0x47] = Some(KeyCode::Home); // E047
|
scancode_set.extended[0x48] = Some(KeyCode::ArrowUp); // E048
|
||||||
scancode_set.extended[0x48] = Some(KeyCode::ArrowUp); // E048
|
scancode_set.extended[0x49] = Some(KeyCode::PageUp); // E049
|
||||||
scancode_set.extended[0x49] = Some(KeyCode::PageUp); // E049
|
//0x4A
|
||||||
//0x4A
|
scancode_set.extended[0x4B] = Some(KeyCode::ArrowLeft); // E04B
|
||||||
scancode_set.extended[0x4B] = Some(KeyCode::ArrowLeft); // E04B
|
//0x4C
|
||||||
//0x4C
|
scancode_set.extended[0x4D] = Some(KeyCode::ArrowRight); // E04D
|
||||||
scancode_set.extended[0x4D] = Some(KeyCode::ArrowRight); // E04D
|
//0x4E
|
||||||
//0x4E
|
scancode_set.extended[0x4F] = Some(KeyCode::End); // E04F
|
||||||
scancode_set.extended[0x4F] = Some(KeyCode::End); // E04F
|
scancode_set.extended[0x50] = Some(KeyCode::ArrowDown); // E050
|
||||||
scancode_set.extended[0x50] = Some(KeyCode::ArrowDown); // E050
|
scancode_set.extended[0x51] = Some(KeyCode::PageDown); // E051
|
||||||
scancode_set.extended[0x51] = Some(KeyCode::PageDown); // E051
|
scancode_set.extended[0x52] = Some(KeyCode::Insert); // E052
|
||||||
scancode_set.extended[0x52] = Some(KeyCode::Insert); // E052
|
scancode_set.extended[0x53] = Some(KeyCode::Delete); // E053
|
||||||
scancode_set.extended[0x53] = Some(KeyCode::Delete); // E053
|
for i in 0x90..=0xED {
|
||||||
for i in 0x90..=0xED {
|
scancode_set.extended[i] = scancode_set.extended[i - 0x80];
|
||||||
scancode_set.extended[i] = scancode_set.extended[i - 0x80];
|
}
|
||||||
}
|
scancode_set
|
||||||
scancode_set
|
}
|
||||||
}
|
pub fn scancode_set2() -> Self {
|
||||||
|
Self {
|
||||||
pub fn scancode_set2() -> Self {
|
single_byte: [None; 256],
|
||||||
Self {
|
extended: [None; 256],
|
||||||
single_byte: [None; 256],
|
}
|
||||||
extended: [None; 256],
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScancodeSet for CustomScancodeSet {
|
impl ScancodeSet for CustomScancodeSet {
|
||||||
fn advance_state(&self, state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error> {
|
fn advance_state(&self, state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error> {
|
||||||
match *state {
|
match *state {
|
||||||
DecodeState::Start => {
|
DecodeState::Start => {
|
||||||
match code {
|
match code {
|
||||||
EXTENDED_KEY_CODE => {
|
EXTENDED_KEY_CODE => {
|
||||||
*state = DecodeState::Extended;
|
*state = DecodeState::Extended;
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
0x80..=0xFF => {
|
0x80..=0xFF => {
|
||||||
// Release codes
|
// Release codes
|
||||||
Ok(Some(KeyEvent::new(
|
Ok(Some(KeyEvent::new(
|
||||||
self.map_scancode(code - 0x80)?,
|
self.map_scancode(code - 0x80)?,
|
||||||
KeyState::Up,
|
KeyState::Up,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Normal codes
|
// Normal codes
|
||||||
Ok(Some(KeyEvent::new(
|
Ok(Some(KeyEvent::new(
|
||||||
self.map_scancode(code)?,
|
self.map_scancode(code)?,
|
||||||
KeyState::Down,
|
KeyState::Down,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DecodeState::Extended => {
|
}
|
||||||
*state = DecodeState::Start;
|
DecodeState::Extended => {
|
||||||
match code {
|
*state = DecodeState::Start;
|
||||||
0x80..=0xFF => {
|
match code {
|
||||||
// Extended Release codes
|
0x80..=0xFF => {
|
||||||
Ok(Some(KeyEvent::new(
|
// Extended Release codes
|
||||||
self.map_extended_scancode(code - 0x80)?,
|
Ok(Some(KeyEvent::new(
|
||||||
KeyState::Up,
|
self.map_extended_scancode(code - 0x80)?,
|
||||||
)))
|
KeyState::Up,
|
||||||
}
|
)))
|
||||||
_ => {
|
}
|
||||||
// Normal release codes
|
_ => {
|
||||||
Ok(Some(KeyEvent::new(
|
// Normal release codes
|
||||||
self.map_extended_scancode(code)?,
|
Ok(Some(KeyEvent::new(
|
||||||
KeyState::Down,
|
self.map_extended_scancode(code)?,
|
||||||
)))
|
KeyState::Down,
|
||||||
}
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
}
|
||||||
// Can't get in to this state
|
_ => {
|
||||||
unimplemented!();
|
// Can't get in to this state
|
||||||
}
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fn map_scancode(&self, code: u8) -> Result<KeyCode, Error> {
|
fn map_scancode(&self, code: u8) -> Result<KeyCode, Error> {
|
||||||
if let Some(kc) = self.single_byte[code as usize] {
|
if let Some(kc) = self.single_byte[code as usize] {
|
||||||
Ok(kc)
|
Ok(kc)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::UnknownKeyCode)
|
Err(Error::UnknownKeyCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn map_extended_scancode(&self, code: u8) -> Result<KeyCode, Error> {
|
||||||
fn map_extended_scancode(&self, code: u8) -> Result<KeyCode, Error> {
|
if let Some(kc) = self.extended[code as usize] {
|
||||||
if let Some(kc) = self.extended[code as usize] {
|
Ok(kc)
|
||||||
Ok(kc)
|
} else {
|
||||||
} else {
|
Err(Error::UnknownKeyCode)
|
||||||
Err(Error::UnknownKeyCode)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,115 +1,105 @@
|
||||||
use crate::DecodedKey;
|
use super::DecodedKey;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum LayoutEntryKind {
|
pub enum LayoutEntryKind {
|
||||||
Regular,
|
Regular,
|
||||||
Numlockable,
|
Numlockable,
|
||||||
Capslockable,
|
Capslockable,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LayoutEntryKind {
|
impl Default for LayoutEntryKind {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Regular
|
Self::Regular
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct LayoutEntry {
|
pub struct LayoutEntry {
|
||||||
pub kind: LayoutEntryKind,
|
pub kind: LayoutEntryKind,
|
||||||
pub unshifted: Option<DecodedKey>,
|
pub unshifted: Option<DecodedKey>,
|
||||||
pub shifted: Option<DecodedKey>,
|
pub shifted: Option<DecodedKey>,
|
||||||
pub locked: Option<DecodedKey>,
|
pub locked: Option<DecodedKey>,
|
||||||
pub locked_shifted: Option<DecodedKey>,
|
pub locked_shifted: Option<DecodedKey>,
|
||||||
pub altgr: Option<DecodedKey>,
|
pub altgr: Option<DecodedKey>,
|
||||||
pub raw_unicode: Option<DecodedKey>,
|
pub raw_unicode: Option<DecodedKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutEntry {
|
impl LayoutEntry {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn regular() -> Self {
|
pub fn regular() -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: LayoutEntryKind::Regular,
|
kind: LayoutEntryKind::Regular,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[must_use]
|
||||||
#[must_use]
|
pub fn numpad() -> Self {
|
||||||
pub fn numpad() -> Self {
|
Self {
|
||||||
Self {
|
kind: LayoutEntryKind::Numlockable,
|
||||||
kind: LayoutEntryKind::Numlockable,
|
..Default::default()
|
||||||
..Default::default()
|
}
|
||||||
}
|
}
|
||||||
}
|
#[must_use]
|
||||||
|
pub fn alphabet() -> Self {
|
||||||
#[must_use]
|
Self {
|
||||||
pub fn alphabet() -> Self {
|
kind: LayoutEntryKind::Capslockable,
|
||||||
Self {
|
..Default::default()
|
||||||
kind: LayoutEntryKind::Capslockable,
|
}
|
||||||
..Default::default()
|
}
|
||||||
}
|
#[must_use]
|
||||||
}
|
pub fn unshifted(mut self, c: impl Into<DecodedKey>) -> Self {
|
||||||
|
self.unshifted = Some(c.into());
|
||||||
#[must_use]
|
self
|
||||||
pub fn unshifted(mut self, c: impl Into<DecodedKey>) -> Self {
|
}
|
||||||
self.unshifted = Some(c.into());
|
#[must_use]
|
||||||
self
|
pub fn shifted(mut self, c: impl Into<DecodedKey>) -> Self {
|
||||||
}
|
self.shifted = Some(c.into());
|
||||||
|
self
|
||||||
#[must_use]
|
}
|
||||||
pub fn shifted(mut self, c: impl Into<DecodedKey>) -> Self {
|
#[must_use]
|
||||||
self.shifted = Some(c.into());
|
pub fn altgr(mut self, c: impl Into<DecodedKey>) -> Self {
|
||||||
self
|
self.altgr = Some(c.into());
|
||||||
}
|
self
|
||||||
|
}
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn altgr(mut self, c: impl Into<DecodedKey>) -> Self {
|
pub fn raw_unicode(mut self, c: impl Into<DecodedKey>) -> Self {
|
||||||
self.altgr = Some(c.into());
|
self.raw_unicode = Some(c.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
#[must_use]
|
||||||
#[must_use]
|
pub fn locked(mut self, c: impl Into<DecodedKey>) -> Self {
|
||||||
pub fn raw_unicode(mut self, c: impl Into<DecodedKey>) -> Self {
|
self.locked = Some(c.into());
|
||||||
self.raw_unicode = Some(c.into());
|
self
|
||||||
self
|
}
|
||||||
}
|
#[must_use]
|
||||||
|
pub fn locked_shifted(mut self, c: impl Into<DecodedKey>) -> Self {
|
||||||
#[must_use]
|
self.locked_shifted = Some(c.into());
|
||||||
pub fn locked(mut self, c: impl Into<DecodedKey>) -> Self {
|
self
|
||||||
self.locked = Some(c.into());
|
}
|
||||||
self
|
#[must_use]
|
||||||
}
|
pub fn common(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
||||||
|
self
|
||||||
#[must_use]
|
.unshifted(c.clone())
|
||||||
pub fn locked_shifted(mut self, c: impl Into<DecodedKey>) -> Self {
|
.shifted(c.clone())
|
||||||
self.locked_shifted = Some(c.into());
|
.locked(c.clone())
|
||||||
self
|
.locked_shifted(c)
|
||||||
}
|
}
|
||||||
|
#[must_use]
|
||||||
#[must_use]
|
pub fn low(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
||||||
pub fn common(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
self.unshifted(c.clone()).locked_shifted(c)
|
||||||
self.unshifted(c.clone())
|
}
|
||||||
.shifted(c.clone())
|
#[must_use]
|
||||||
.locked(c.clone())
|
pub fn high(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
||||||
.locked_shifted(c)
|
self.shifted(c.clone()).locked(c)
|
||||||
}
|
}
|
||||||
|
#[must_use]
|
||||||
#[must_use]
|
pub fn all(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
||||||
pub fn low(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
self
|
||||||
self.unshifted(c.clone()).locked_shifted(c)
|
.unshifted(c.clone())
|
||||||
}
|
.shifted(c.clone())
|
||||||
|
.locked(c.clone())
|
||||||
#[must_use]
|
.locked_shifted(c.clone())
|
||||||
pub fn high(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
.altgr(c.clone())
|
||||||
self.shifted(c.clone()).locked(c)
|
.raw_unicode(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn all(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
|
||||||
self.unshifted(c.clone())
|
|
||||||
.shifted(c.clone())
|
|
||||||
.locked(c.clone())
|
|
||||||
.locked_shifted(c.clone())
|
|
||||||
.altgr(c.clone())
|
|
||||||
.raw_unicode(c)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
mod custom_layout;
|
mod custom_layout;
|
||||||
mod custom_scancode_set;
|
mod custom_scancode_set;
|
||||||
mod layout_entry;
|
mod layout_entry;
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
mod abstractions;
|
mod abstractions;
|
||||||
mod small_types;
|
mod small_types;
|
||||||
mod traits;
|
mod traits;
|
||||||
|
|
||||||
pub use abstractions::*;
|
pub use abstractions::*;
|
||||||
pub use small_types::*;
|
pub use small_types::*;
|
||||||
pub use traits::*;
|
pub use traits::*;
|
||||||
|
|
||||||
const EXTENDED_KEY_CODE: u8 = 0xE0;
|
|
||||||
const KEYCODE_BITS: u8 = 11;
|
const KEYCODE_BITS: u8 = 11;
|
||||||
|
const EXTENDED_KEY_CODE: u8 = 0xE0;
|
||||||
const KEY_RELEASE_CODE: u8 = 0xF0;
|
const KEY_RELEASE_CODE: u8 = 0xF0;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Keyboard<T, S>
|
pub struct Keyboard<T, S>
|
||||||
where
|
where
|
||||||
|
@ -26,7 +22,6 @@ where
|
||||||
layout: T,
|
layout: T,
|
||||||
set: S,
|
set: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S> Keyboard<T, S>
|
impl<T, S> Keyboard<T, S>
|
||||||
where
|
where
|
||||||
T: KeyboardLayout + Default,
|
T: KeyboardLayout + Default,
|
||||||
|
@ -52,17 +47,14 @@ where
|
||||||
set: S::default(),
|
set: S::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// /// Change the Ctrl key mapping.
|
||||||
/// Change the Ctrl key mapping.
|
|
||||||
pub fn set_ctrl_handling(&mut self, new_value: HandleControl) {
|
pub fn set_ctrl_handling(&mut self, new_value: HandleControl) {
|
||||||
self.handle_ctrl = new_value;
|
self.handle_ctrl = new_value;
|
||||||
}
|
}
|
||||||
|
// /// Get the current Ctrl key mapping.
|
||||||
/// Get the current Ctrl key mapping.
|
|
||||||
pub fn get_ctrl_handling(&self) -> HandleControl {
|
pub fn get_ctrl_handling(&self) -> HandleControl {
|
||||||
self.handle_ctrl
|
self.handle_ctrl
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the bit register.
|
/// Clears the bit register.
|
||||||
///
|
///
|
||||||
/// Call this when there is a timeout reading data from the keyboard.
|
/// Call this when there is a timeout reading data from the keyboard.
|
||||||
|
@ -71,7 +63,6 @@ where
|
||||||
self.num_bits = 0;
|
self.num_bits = 0;
|
||||||
self.decode_state = DecodeState::Start;
|
self.decode_state = DecodeState::Start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes a 16-bit word from the keyboard.
|
/// Processes a 16-bit word from the keyboard.
|
||||||
///
|
///
|
||||||
/// * The start bit (0) must be in bit 0.
|
/// * The start bit (0) must be in bit 0.
|
||||||
|
@ -83,7 +74,6 @@ where
|
||||||
let byte = self.check_word(word)?;
|
let byte = self.check_word(word)?;
|
||||||
self.add_byte(byte)
|
self.add_byte(byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes an 8-bit byte from the keyboard.
|
/// Processes an 8-bit byte from the keyboard.
|
||||||
///
|
///
|
||||||
/// We assume the start, stop and parity bits have been processed and
|
/// We assume the start, stop and parity bits have been processed and
|
||||||
|
@ -91,7 +81,6 @@ where
|
||||||
pub fn add_byte(&mut self, byte: u8) -> Result<Option<KeyEvent>, Error> {
|
pub fn add_byte(&mut self, byte: u8) -> Result<Option<KeyEvent>, Error> {
|
||||||
self.set.advance_state(&mut self.decode_state, byte)
|
self.set.advance_state(&mut self.decode_state, byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shift a bit into the register.
|
/// Shift a bit into the register.
|
||||||
///
|
///
|
||||||
/// Call this /or/ call `add_word` - don't call both.
|
/// Call this /or/ call `add_word` - don't call both.
|
||||||
|
@ -108,7 +97,6 @@ where
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes a `KeyEvent` returned from `add_bit`, `add_byte` or `add_word`
|
/// Processes a `KeyEvent` returned from `add_bit`, `add_byte` or `add_word`
|
||||||
/// and produces a decoded key.
|
/// and produces a decoded key.
|
||||||
///
|
///
|
||||||
|
@ -211,15 +199,12 @@ where
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_bit(&self, word: u16, offset: usize) -> bool {
|
fn get_bit(&self, word: u16, offset: usize) -> bool {
|
||||||
((word >> offset) & 0x0001) != 0
|
((word >> offset) & 0x0001) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_even_number_bits(&self, data: u8) -> bool {
|
fn has_even_number_bits(&self, data: u8) -> bool {
|
||||||
(data.count_ones() % 2) == 0
|
(data.count_ones() % 2) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check 11-bit word has 1 start bit, 1 stop bit and an odd parity bit.
|
/// Check 11-bit word has 1 start bit, 1 stop bit and an odd parity bit.
|
||||||
fn check_word(&self, word: u16) -> Result<u8, Error> {
|
fn check_word(&self, word: u16) -> Result<u8, Error> {
|
||||||
let start_bit = self.get_bit(word, 0);
|
let start_bit = self.get_bit(word, 0);
|
||||||
|
@ -237,11 +222,9 @@ where
|
||||||
if need_parity != parity_bit {
|
if need_parity != parity_bit {
|
||||||
return Err(Error::ParityError);
|
return Err(Error::ParityError);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_format() {
|
pub fn parse_format() {
|
||||||
let test = include_str!("../../keymaps/qwerty.keymap").lines();
|
let test = include_str!("../../keymaps/qwerty.keymap").lines();
|
||||||
// r#"0-NONE\n1-HI#Says HI"#
|
// r#"0-NONE\n1-HI#Says HI"#
|
||||||
|
|
|
@ -1,126 +1,112 @@
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Modifiers {
|
pub struct Modifiers {
|
||||||
pub lshift: bool,
|
pub lshift: bool,
|
||||||
pub rshift: bool,
|
pub rshift: bool,
|
||||||
pub lctrl: bool,
|
pub lctrl: bool,
|
||||||
pub rctrl: bool,
|
pub rctrl: bool,
|
||||||
pub numlock: bool,
|
pub numlock: bool,
|
||||||
pub capslock: bool,
|
pub capslock: bool,
|
||||||
pub alt_gr: bool,
|
pub alt_gr: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Modifiers {
|
impl Modifiers {
|
||||||
pub fn is_shifted(&self) -> bool {
|
pub fn is_shifted(&self) -> bool {
|
||||||
self.lshift | self.rshift
|
self.lshift | self.rshift
|
||||||
}
|
}
|
||||||
|
pub fn is_ctrl(&self) -> bool {
|
||||||
pub fn is_ctrl(&self) -> bool {
|
self.lctrl | self.rctrl
|
||||||
self.lctrl | self.rctrl
|
}
|
||||||
}
|
pub fn is_caps(&self) -> bool {
|
||||||
|
self.capslock
|
||||||
pub fn is_caps(&self) -> bool {
|
}
|
||||||
self.capslock
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum KeyState {
|
pub enum KeyState {
|
||||||
Up,
|
Up,
|
||||||
Down,
|
Down,
|
||||||
}
|
}
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct KeyEvent {
|
pub struct KeyEvent {
|
||||||
pub code: KeyCode,
|
pub code: KeyCode,
|
||||||
pub state: KeyState,
|
pub state: KeyState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyEvent {
|
impl KeyEvent {
|
||||||
pub fn new(code: KeyCode, state: KeyState) -> KeyEvent {
|
pub fn new(code: KeyCode, state: KeyState) -> KeyEvent {
|
||||||
KeyEvent { code, state }
|
KeyEvent { code, state }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum HandleControl {
|
pub enum HandleControl {
|
||||||
/// If either Ctrl key is held down, convert the letters A through Z into
|
/// If either Ctrl key is held down, convert the letters A through Z into
|
||||||
/// Unicode chars U+0001 through U+001A. If the Ctrl keys are not held
|
/// Unicode chars U+0001 through U+001A. If the Ctrl keys are not held
|
||||||
/// down, letters go through normally.
|
/// down, letters go through normally.
|
||||||
MapLettersToUnicode,
|
MapLettersToUnicode,
|
||||||
/// Don't do anything special - send through the Ctrl key up/down events,
|
/// Don't do anything special - send through the Ctrl key up/down events,
|
||||||
/// and leave the letters as letters.
|
/// and leave the letters as letters.
|
||||||
Ignore,
|
Ignore,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
pub enum DecodeState {
|
pub enum DecodeState {
|
||||||
Start,
|
Start,
|
||||||
Extended,
|
Extended,
|
||||||
Release,
|
Release,
|
||||||
ExtendedRelease,
|
ExtendedRelease,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates different error conditions.
|
/// Indicates different error conditions.
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
BadStartBit,
|
BadStartBit,
|
||||||
BadStopBit,
|
BadStopBit,
|
||||||
ParityError,
|
ParityError,
|
||||||
UnknownKeyCode,
|
UnknownKeyCode,
|
||||||
InvalidState,
|
InvalidState,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum DecodedKeyKind {
|
pub enum DecodedKeyKind {
|
||||||
RawKey = 0,
|
RawKey = 0,
|
||||||
Unicode = 1,
|
Unicode = 1,
|
||||||
}
|
}
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DecodedKey {
|
pub struct DecodedKey {
|
||||||
pub kind: DecodedKeyKind,
|
pub kind: DecodedKeyKind,
|
||||||
pub value: u32,
|
pub value: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<char> for DecodedKey {
|
impl From<char> for DecodedKey {
|
||||||
fn from(ch: char) -> Self {
|
fn from(ch: char) -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: DecodedKeyKind::Unicode,
|
kind: DecodedKeyKind::Unicode,
|
||||||
value: ch as u32,
|
value: ch as u32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<KeyCode> for DecodedKey {
|
impl From<KeyCode> for DecodedKey {
|
||||||
fn from(kc: KeyCode) -> Self {
|
fn from(kc: KeyCode) -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: DecodedKeyKind::RawKey,
|
kind: DecodedKeyKind::RawKey,
|
||||||
value: kc as u32,
|
value: kc as u32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DecodedKey {
|
impl DecodedKey {
|
||||||
pub const ZERO: Self = Self {
|
pub const ZERO: Self = Self {
|
||||||
kind: DecodedKeyKind::Unicode,
|
kind: DecodedKeyKind::Unicode,
|
||||||
value: 0,
|
value: 0,
|
||||||
};
|
};
|
||||||
pub fn Unicode(ch: char) -> Self {
|
pub fn Unicode(ch: char) -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: DecodedKeyKind::Unicode,
|
kind: DecodedKeyKind::Unicode,
|
||||||
value: ch.into(),
|
value: ch.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn RawKey(byte: u8) -> Self {
|
pub fn RawKey(byte: u8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: DecodedKeyKind::RawKey,
|
kind: DecodedKeyKind::RawKey,
|
||||||
value: byte.into(),
|
value: byte.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! keycode_enum {
|
macro_rules! keycode_enum {
|
||||||
(@get_last $Variant:ident) => {
|
(@get_last $Variant:ident) => {
|
||||||
Self::$Variant
|
Self::$Variant
|
||||||
|
@ -148,7 +134,6 @@ macro_rules! keycode_enum {
|
||||||
keycode_enum!($($Variant=$Value,)* );
|
keycode_enum!($($Variant=$Value,)* );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will be a way to map keys to other keys / keyyngs / macros
|
// This will be a way to map keys to other keys / keyyngs / macros
|
||||||
keycode_enum! {
|
keycode_enum! {
|
||||||
AltLeft = 0x00,
|
AltLeft = 0x00,
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
use super::Error;
|
use super::*;
|
||||||
use crate::{DecodeState, DecodedKey, HandleControl, KeyCode, KeyEvent, Modifiers};
|
|
||||||
|
|
||||||
pub trait ScancodeSet {
|
pub trait ScancodeSet {
|
||||||
/// Handles the state logic for the decoding of scan codes into key events.
|
/// Handles the state logic for the decoding of scan codes into key events.
|
||||||
fn advance_state(&self, state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error>;
|
fn advance_state(&self, state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error>;
|
||||||
|
|
||||||
/// Convert a Scan Code set X byte to our 'KeyType' enum
|
/// Convert a Scan Code set X byte to our 'KeyType' enum
|
||||||
fn map_scancode(&self, code: u8) -> Result<KeyCode, Error>;
|
fn map_scancode(&self, code: u8) -> Result<KeyCode, Error>;
|
||||||
|
|
||||||
/// Convert a Scan Code Set X extended byte (prefixed E0) to our `KeyType`
|
/// Convert a Scan Code Set X extended byte (prefixed E0) to our `KeyType`
|
||||||
/// enum.
|
/// enum.
|
||||||
fn map_extended_scancode(&self, code: u8) -> Result<KeyCode, Error>;
|
fn map_extended_scancode(&self, code: u8) -> Result<KeyCode, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait KeyboardLayout {
|
pub trait KeyboardLayout {
|
||||||
/// Convert a `KeyType` enum to a Unicode character, if possible.
|
/// Convert a `KeyType` enum to a Unicode character, if possible.
|
||||||
/// `KeyType::A` maps to `Some('a')` (or `Some('A')` if shifted), while
|
/// `KeyType::A` maps to `Some('a')` (or `Some('A')` if shifted), while
|
||||||
|
|
|
@ -1,54 +1,112 @@
|
||||||
#![allow(clippy::empty_loop)]
|
#![allow(clippy::empty_loop)]
|
||||||
|
|
||||||
use crate::arch::drivers::sysinfo::master;
|
// use crate::scheduler;
|
||||||
use crate::scheduler::SCHEDULER;
|
|
||||||
use crate::{
|
|
||||||
arch::{init, sloop},
|
|
||||||
relib::network::socket::{SimpleSock, Socket},
|
|
||||||
scratchpad,
|
|
||||||
};
|
|
||||||
use crate::{boot_conf::KernelConfig, systeminfo::RELEASE_TYPE};
|
|
||||||
use kernel::KERNEL_VERSION;
|
|
||||||
use spin::Lazy;
|
|
||||||
|
|
||||||
// TODO: Change this structure to allow for multiple cores loaded
|
use {
|
||||||
pub static KERNEL_CONF: Lazy<KernelConfig> = Lazy::new(KernelConfig::new);
|
crate::{
|
||||||
|
arch::{init, sloop},
|
||||||
|
boot_conf,
|
||||||
|
boot_conf::BootConfig,
|
||||||
|
capabilities,
|
||||||
|
experiments::{
|
||||||
|
info::master,
|
||||||
|
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
|
||||||
|
},
|
||||||
|
file::{File, PathRep},
|
||||||
|
relib::network::socket::SimpleSock,
|
||||||
|
relib::network::socket::Socket,
|
||||||
|
scheduler::SCHEDULER,
|
||||||
|
},
|
||||||
|
alloc::{
|
||||||
|
string::{String, ToString},
|
||||||
|
vec,
|
||||||
|
},
|
||||||
|
core::sync::atomic::{AtomicU64, Ordering::*},
|
||||||
|
lazy_static::lazy_static,
|
||||||
|
log::*,
|
||||||
|
};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref TICK: AtomicU64 = AtomicU64::new(0);
|
||||||
|
pub static ref BOOT_CONF: BootConfig = boot_conf::BootConfig::new();
|
||||||
|
}
|
||||||
|
|
||||||
/// The main entry point of the kernel
|
/// The main entry point of the kernel
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn kernel_main() -> ! {
|
pub fn kernel_main() -> ! {
|
||||||
init::init();
|
init::init();
|
||||||
|
log::set_max_level(BOOT_CONF.log_level());
|
||||||
|
|
||||||
if KERNEL_CONF.logging.enabled {
|
use crate::scheduler::Priority;
|
||||||
log::set_max_level(KERNEL_CONF.log_level());
|
let mut scheduler = SCHEDULER.lock();
|
||||||
} else {
|
|
||||||
log::set_max_level(log::LevelFilter::Off);
|
|
||||||
}
|
|
||||||
let scheduler = SCHEDULER.lock();
|
|
||||||
for proc in &scheduler.execution_queue {
|
|
||||||
trace!("{:?}", proc);
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(scheduler);
|
use Priority::*;
|
||||||
|
|
||||||
// start_facepalm();
|
let mut process_1 = scheduler.new_process(High);
|
||||||
scratchpad();
|
process_1.capabilities.set_file_access(vec![PathRep {
|
||||||
|
location: FileLocations::Home,
|
||||||
|
file_name: "test".to_string(),
|
||||||
|
}]);
|
||||||
|
scheduler.add_process(process_1);
|
||||||
|
for ref_process in &scheduler.list {
|
||||||
|
trace!("{:?}", ref_process);
|
||||||
|
}
|
||||||
|
drop(scheduler);
|
||||||
|
|
||||||
sloop()
|
use crate::proto_filetable::contain::FILE_TABLE;
|
||||||
|
use crate::proto_filetable::file::FileLocations;
|
||||||
|
|
||||||
|
let mut file_table = FILE_TABLE.lock();
|
||||||
|
let mut new_file = File::new(FileLocations::Bin, "test".to_string(), "txt".to_string());
|
||||||
|
|
||||||
|
new_file.write_bytes(b"Hello, world!");
|
||||||
|
file_table.add_file("test", new_file);
|
||||||
|
|
||||||
|
let file = file_table.get_file("test");
|
||||||
|
|
||||||
|
match file {
|
||||||
|
Some(file) => {
|
||||||
|
let file_bytes = &file.data_pointer;
|
||||||
|
let file_string = String::from_utf8(file_bytes.to_vec()).unwrap();
|
||||||
|
info!("{}", file_string);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
info!("File not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::wasm::WasmProgram;
|
||||||
|
let ret = WasmProgram::new_from_bytes(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]);
|
||||||
|
trace!("Binary Valid: {:?}", ret.validate_header());
|
||||||
|
|
||||||
|
sloop()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// called by arch specific timers to tick up all kernel related functions
|
||||||
|
pub fn tick() {
|
||||||
|
let mut data = TICK.load(Relaxed);
|
||||||
|
data += 1;
|
||||||
|
|
||||||
|
crate::kernel_state::KERNEL_STATE.lock().update_state();
|
||||||
|
|
||||||
|
// let mut scheduler = SCHEDULER.lock();
|
||||||
|
// scheduler.bump_exec();
|
||||||
|
|
||||||
|
TICK.store(data, Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cpu_socket_startup() {
|
pub fn cpu_socket_startup() {
|
||||||
let mut cpu_info_socket = SimpleSock::new();
|
let mut cpu_info_socket = SimpleSock::new();
|
||||||
cpu_info_socket.register_protocol("CPU_INFO".to_string());
|
cpu_info_socket.register_protocol("CPU_INFO".to_string());
|
||||||
|
|
||||||
// let x = master().unwrap();
|
let x = master().unwrap();
|
||||||
// let _xyz = x.brand_string().unwrap();
|
let _xyz = x.brand_string().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_version_data() {
|
pub fn log_version_data() {
|
||||||
info!("{} v{:?}", RELEASE_TYPE, KERNEL_VERSION);
|
info!("{} v{}", RELEASE_TYPE, KERNEL_VERSION);
|
||||||
info!(
|
info!(
|
||||||
"Brand String: {}",
|
"Brand String: {:?}",
|
||||||
master().unwrap().brand_string().unwrap()
|
master().unwrap().brand_string().unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,82 +4,87 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(abi_x86_interrupt)]
|
#![feature(
|
||||||
#![feature(alloc_error_handler)]
|
abi_x86_interrupt,
|
||||||
#![feature(prelude_import)]
|
asm_sym,
|
||||||
#![feature(asm_sym)] // Needed for riscv
|
alloc_error_handler,
|
||||||
#![feature(naked_functions)]
|
core_intrinsics,
|
||||||
|
exclusive_range_pattern,
|
||||||
#[macro_use]
|
lang_items,
|
||||||
pub extern crate log;
|
naked_functions,
|
||||||
|
slice_pattern,
|
||||||
pub extern crate alloc;
|
)]
|
||||||
pub extern crate externc_libm as libm;
|
|
||||||
|
|
||||||
/// Contains architecture specific code for aarch64.
|
/// Contains architecture specific code for aarch64.
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
#[path = "arch/aarch64/mod.rs"]
|
#[path = "arch/aarch64/mod.rs"]
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
|
|
||||||
/// Contains architecture specific code for riscv64.
|
|
||||||
#[cfg(target_arch = "riscv64")]
|
|
||||||
#[path = "arch/riscv/mod.rs"]
|
|
||||||
pub mod arch;
|
|
||||||
|
|
||||||
/// Contains architecture specific code for x86_64.
|
/// Contains architecture specific code for x86_64.
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[path = "arch/x86_64/mod.rs"]
|
#[path = "arch/x86_64/mod.rs"]
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
/// Contains architecture specific code for riscv64.
|
||||||
pub mod port_io;
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
#[path = "arch/riscv/mod.rs"]
|
||||||
|
pub mod arch;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod print;
|
pub mod print;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod serial_print;
|
pub extern crate log;
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Modules //
|
||||||
|
/////////////
|
||||||
pub mod allocator;
|
pub mod allocator;
|
||||||
pub mod boot_conf;
|
pub mod boot_conf;
|
||||||
pub mod devices;
|
|
||||||
pub mod driver_traits;
|
pub mod driver_traits;
|
||||||
pub mod experiments;
|
pub mod experiments;
|
||||||
pub mod filesystem;
|
|
||||||
pub mod graphics;
|
pub mod graphics;
|
||||||
pub mod kernel_state;
|
pub mod kernel_state;
|
||||||
pub mod keyboard;
|
pub mod keyboard;
|
||||||
pub mod kmain;
|
pub mod kmain;
|
||||||
pub mod logger;
|
pub mod logger;
|
||||||
pub mod prelude;
|
pub mod panic;
|
||||||
|
pub mod proto_filetable;
|
||||||
pub mod relib;
|
pub mod relib;
|
||||||
pub mod rhai_shell;
|
|
||||||
pub mod scheduler;
|
pub mod scheduler;
|
||||||
pub mod scratchpad;
|
|
||||||
pub mod stdio;
|
|
||||||
pub mod time;
|
|
||||||
pub mod utils;
|
|
||||||
pub mod virtio;
|
|
||||||
pub mod wasm;
|
|
||||||
pub mod wasm_jumploader;
|
|
||||||
|
|
||||||
mod unicode_utils;
|
mod unicode_utils;
|
||||||
|
pub mod utils;
|
||||||
|
pub mod vga_e;
|
||||||
|
pub mod wasm;
|
||||||
|
|
||||||
#[prelude_import]
|
pub extern crate alloc;
|
||||||
pub use prelude::rust_2021::*;
|
pub extern crate externc_libm as libm;
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
// Re-exports ///
|
||||||
|
////////////////
|
||||||
pub use allocator::*;
|
pub use allocator::*;
|
||||||
|
pub use boot_conf::*;
|
||||||
pub use driver_traits::*;
|
pub use driver_traits::*;
|
||||||
pub use experiments::*;
|
pub use experiments::*;
|
||||||
pub use graphics::*;
|
pub use graphics::*;
|
||||||
pub use kernel;
|
|
||||||
pub use kernel::messaging;
|
|
||||||
pub use kernel::panic;
|
|
||||||
pub use kernel_state::*;
|
pub use kernel_state::*;
|
||||||
pub use keyboard::*;
|
pub use keyboard::*;
|
||||||
pub use logger::*;
|
pub use logger::*;
|
||||||
|
pub use panic::*;
|
||||||
|
pub use proto_filetable::*;
|
||||||
pub use relib::*;
|
pub use relib::*;
|
||||||
pub use scratchpad::*;
|
pub use scheduler::*;
|
||||||
pub use utils::*;
|
pub use utils::*;
|
||||||
pub use virtio::*;
|
pub use vga_e::*;
|
||||||
pub use wasm::*;
|
pub use wasm::*;
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
pub mod virtio;
|
||||||
|
pub use virtio::*;
|
||||||
|
|
||||||
|
pub mod alias_table;
|
||||||
|
pub use alias_table::*;
|
||||||
|
|
||||||
|
pub mod tests;
|
||||||
|
pub use tests::*;
|
||||||
|
|
|
@ -1,68 +1,55 @@
|
||||||
use crate::kmain::KERNEL_CONF;
|
use core::sync::atomic::Ordering;
|
||||||
use crate::network::socket::{SimpleSock, Socket};
|
|
||||||
use crate::time::fetch_time;
|
use crate::kmain::TICK;
|
||||||
use lliw::{Fg, Reset};
|
use crate::serial_println;
|
||||||
use log::{Level, Metadata, Record};
|
use lliw::{Fg, Reset};
|
||||||
use log::{LevelFilter, SetLoggerError};
|
pub use log::{debug, info, trace, warn};
|
||||||
|
use log::{Level, Metadata, Record};
|
||||||
|
|
||||||
|
use crate::arch::drivers::timer::TIMER_INTERRUPT_HERTZ;
|
||||||
|
|
||||||
static LOGGER: SimpleLogger = SimpleLogger;
|
|
||||||
// TODO: Rebuild this to take advantage of sockets
|
|
||||||
// DETAIL: Log to a socket instead of the screen
|
|
||||||
// So that we can log in the kernel and display it in userland
|
|
||||||
struct SimpleLogger;
|
struct SimpleLogger;
|
||||||
|
|
||||||
impl log::Log for SimpleLogger {
|
impl log::Log for SimpleLogger {
|
||||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||||
metadata.level() <= Level::Trace
|
metadata.level() <= Level::Trace
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log(&self, record: &Record) {
|
fn log(&self, record: &Record) {
|
||||||
if self.enabled(record.metadata()) {
|
if self.enabled(record.metadata()) {
|
||||||
let time_float = fetch_time();
|
let color;
|
||||||
|
let time = TICK.load(Ordering::Relaxed) as f64;
|
||||||
|
|
||||||
let color = match record.level() {
|
let time_float = time / TIMER_INTERRUPT_HERTZ;
|
||||||
log::Level::Error => (Fg::Red, "$RED$"),
|
|
||||||
log::Level::Warn => (Fg::LightYellow, "$LIGHTYELLOW$"),
|
|
||||||
log::Level::Info => (Fg::LightWhite, "$LIGHTGRAY$"),
|
|
||||||
log::Level::Debug => (Fg::Blue, "$BLUE$"),
|
|
||||||
log::Level::Trace => (Fg::Yellow, "$YELLOW$"),
|
|
||||||
};
|
|
||||||
|
|
||||||
let msg = format!(
|
match record.level() {
|
||||||
"[{}{}$RESET$][$GREEN${}$RESET$]{}\n",
|
log::Level::Error => color = (Fg::Red, "$RED$"),
|
||||||
color.1,
|
log::Level::Warn => color = (Fg::LightYellow, "$LIGHTYELLOW$"),
|
||||||
|
log::Level::Info => color = (Fg::LightWhite, "$LIGHTGRAY$"),
|
||||||
|
log::Level::Debug => color = (Fg::Blue, "$BLUE$"),
|
||||||
|
log::Level::Trace => color = (Fg::Yellow, "$YELLOW$"),
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_println!(
|
||||||
|
"[{}{}{}][{}{}{}] {}",
|
||||||
|
color.0,
|
||||||
record.level(),
|
record.level(),
|
||||||
|
Fg::Reset,
|
||||||
|
Fg::Green,
|
||||||
time_float,
|
time_float,
|
||||||
record.args()
|
Reset,
|
||||||
|
record.args(),
|
||||||
);
|
);
|
||||||
// kprint!("{}", msg);
|
|
||||||
// NOTE: This needs to be fixed before merge
|
|
||||||
if KERNEL_CONF.logging.log_to_serial {
|
|
||||||
// #[track_caller]
|
|
||||||
|
|
||||||
serial_println!(
|
|
||||||
"[{}{}{}][{}{}{}] {}",
|
|
||||||
color.0,
|
|
||||||
record.level(),
|
|
||||||
Fg::Reset,
|
|
||||||
Fg::Green,
|
|
||||||
time_float,
|
|
||||||
Reset,
|
|
||||||
record.args()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let log_socket_id = SimpleSock::grab_socket("Logger".to_string());
|
|
||||||
match log_socket_id {
|
|
||||||
Some(mut log_socket_id) => {
|
|
||||||
log_socket_id.write(msg.as_bytes().to_vec());
|
|
||||||
}
|
|
||||||
None => warn!("No socket found for Logger"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Clear the log buffer
|
/// Clear the log buffer
|
||||||
fn flush(&self) {}
|
fn flush(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use log::{LevelFilter, SetLoggerError};
|
||||||
|
|
||||||
|
static LOGGER: SimpleLogger = SimpleLogger;
|
||||||
|
|
||||||
pub fn init() -> Result<(), SetLoggerError> {
|
pub fn init() -> Result<(), SetLoggerError> {
|
||||||
log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Trace))
|
log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Trace))
|
||||||
}
|
}
|
||||||
|
|
22
ableos/src/panic.rs
Normal file
22
ableos/src/panic.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
use {crate::arch::sloop, core::panic::PanicInfo};
|
||||||
|
|
||||||
|
/// A function to handle a panic in the kernel.
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use ableos::panic::panic;
|
||||||
|
/// panic!("This is a panic!");
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// This function is unsafe because it does not guarantee that the panic is handled.
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
|
error!("{}", info);
|
||||||
|
// help me use facepalm::start_facepalm;
|
||||||
|
|
||||||
|
sloop()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test_panic() {
|
||||||
|
panic!("test panic!");
|
||||||
|
}
|
|
@ -1,17 +0,0 @@
|
||||||
use cpuio::{inb, inl, outb, outl};
|
|
||||||
|
|
||||||
pub fn read32(reg: u16) -> u32 {
|
|
||||||
unsafe { inl(reg) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read8(reg: u16) -> u8 {
|
|
||||||
unsafe { inb(reg) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write32(reg: u16, val: u32) {
|
|
||||||
unsafe { outl(val, reg) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write8(reg: u16, val: u8) {
|
|
||||||
unsafe { outb(val, reg) }
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
pub mod rust_2021;
|
|
|
@ -1,7 +0,0 @@
|
||||||
pub use crate::print::*;
|
|
||||||
pub use crate::serial_print::*;
|
|
||||||
pub use alloc::{boxed::Box, format, string::*, vec, vec::*};
|
|
||||||
pub use core::arch::asm;
|
|
||||||
pub use core::prelude::rust_2021::*;
|
|
||||||
pub use core::prelude::v1::*;
|
|
||||||
pub use log::{debug, info, trace, warn};
|
|
|
@ -1,10 +1,5 @@
|
||||||
// TODO: refactor this file
|
|
||||||
// TODO: make STDOUT redirect to a socket owned
|
|
||||||
// by the process named "stdout"
|
|
||||||
|
|
||||||
use core::fmt::{Arguments, Error};
|
|
||||||
|
|
||||||
pub struct Stdout;
|
pub struct Stdout;
|
||||||
|
use core::fmt::{Arguments, Error};
|
||||||
impl Stdout {
|
impl Stdout {
|
||||||
pub fn write_fmt(&mut self, arg: Arguments<'_>) /*-> Result<(), Error> */
|
pub fn write_fmt(&mut self, arg: Arguments<'_>) /*-> Result<(), Error> */
|
||||||
{
|
{
|
||||||
|
@ -12,31 +7,33 @@ impl Stdout {
|
||||||
// Ok(())
|
// Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::fmt::Write for Stdout {
|
impl core::fmt::Write for Stdout {
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn write_str(&mut self, s: &str) -> Result<(), Error> {
|
fn write_str(&mut self, s: &str) -> Result<(), Error> {
|
||||||
// Don't actually print anything yet lmao
|
// Don't actually print anything yet lmao
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn write_str(&mut self, s: &str) -> Result<(), Error> {
|
fn write_str(&mut self, s: &str) -> Result<(), Error> {
|
||||||
use crate::kprint;
|
use crate::experiments::absi::colorify;
|
||||||
kprint!("{}", s);
|
colorify(s);
|
||||||
|
// kprint!("{}", s);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "riscv64")]
|
#[cfg(target_arch = "riscv64")]
|
||||||
fn write_str(&mut self, s: &str) -> Result<(), Error> {
|
fn write_str(&mut self, s: &str) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_char(&mut self, c: char) -> core::fmt::Result {
|
fn write_char(&mut self, c: char) -> core::fmt::Result {
|
||||||
self.write_str(c.encode_utf8(&mut [0; 4]))
|
self.write_str(c.encode_utf8(&mut [0; 4]))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_fmt(mut self: &mut Self, args: Arguments<'_>) -> core::fmt::Result {
|
fn write_fmt(mut self: &mut Self, args: Arguments<'_>) -> core::fmt::Result {
|
||||||
core::fmt::write(&mut self, args)
|
core::fmt::write(&mut self, args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! print {
|
macro_rules! print {
|
||||||
() => {
|
() => {
|
||||||
|
@ -48,7 +45,12 @@ macro_rules! print {
|
||||||
}
|
}
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! println {
|
macro_rules! println {
|
||||||
|
() =>{
|
||||||
|
// ::core::writeln!($crate::print::Stdout, "\n")
|
||||||
|
panic![];
|
||||||
|
};
|
||||||
($($tt:tt)*) => {
|
($($tt:tt)*) => {
|
||||||
::core::writeln!($crate::print::Stdout, $($tt)*)
|
::core::writeln!($crate::print::Stdout, $($tt)*)
|
||||||
|
// panic![];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
5
ableos/src/proto_filetable/contain.rs
Normal file
5
ableos/src/proto_filetable/contain.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
use crate::ProtoFileTable;
|
||||||
|
|
||||||
|
lazy_static::lazy_static!(
|
||||||
|
pub static ref FILE_TABLE: spin::Mutex<ProtoFileTable> = spin::Mutex::new(ProtoFileTable::new());
|
||||||
|
);
|
76
ableos/src/proto_filetable/file.rs
Normal file
76
ableos/src/proto_filetable/file.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
use alloc::{string::String, vec, vec::Vec};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub struct PathRep {
|
||||||
|
pub location: FileLocations,
|
||||||
|
pub file_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FileMetadata {
|
||||||
|
pub file_type: String,
|
||||||
|
pub size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum FileLocations {
|
||||||
|
Bin,
|
||||||
|
Config,
|
||||||
|
Home,
|
||||||
|
}
|
||||||
|
impl fmt::Display for FileLocations {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct File {
|
||||||
|
pub location: FileLocations,
|
||||||
|
pub file_name: String,
|
||||||
|
pub meta_data: FileMetadata,
|
||||||
|
pub data_pointer: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl File {
|
||||||
|
/// Write the provided bytes to a file
|
||||||
|
pub fn write_bytes(&mut self, bytes: &[u8]) {
|
||||||
|
for byte in bytes {
|
||||||
|
self.data_pointer.push(*byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.meta_data.size = self.data_pointer.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(location: FileLocations, file_name: String, file_type: String) -> Self {
|
||||||
|
let bytes: Vec<u8> = vec![];
|
||||||
|
let abc123 = bytes;
|
||||||
|
|
||||||
|
Self {
|
||||||
|
location,
|
||||||
|
file_name,
|
||||||
|
meta_data: FileMetadata { file_type, size: 0 },
|
||||||
|
data_pointer: abc123,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> usize {
|
||||||
|
self.meta_data.size.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_to_string(&mut self, _string: &mut String) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_and_return(&mut self) -> String {
|
||||||
|
String::from_utf8(self.data_pointer.clone()).expect("Found invalid UTF-8")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for File {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}://{}", self.location, self.file_name)
|
||||||
|
}
|
||||||
|
}
|
61
ableos/src/proto_filetable/mod.rs
Normal file
61
ableos/src/proto_filetable/mod.rs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
//! A file table module for AbleOS
|
||||||
|
//!
|
||||||
|
//! This module provides a file table interface for AbleOS.
|
||||||
|
//!
|
||||||
|
//! # Examples
|
||||||
|
//! ```
|
||||||
|
//! use relib::filesystem::ProtoFileTable;
|
||||||
|
//! let mut file_table = ProtoFileTable::new();
|
||||||
|
//! file_table.add_file("test.txt", "Hello, world!".as_bytes());
|
||||||
|
//! let file = file_table.get_file("test.txt");
|
||||||
|
//! assert_eq!(file.unwrap().as_slice(), "Hello, world!".as_bytes());
|
||||||
|
//! ```
|
||||||
|
//! # Notes
|
||||||
|
//! The file table is a simple in-memory hashmap.
|
||||||
|
//! The file table is not thread safe.
|
||||||
|
//! The file table is not persistent.
|
||||||
|
|
||||||
|
use alloc::{
|
||||||
|
string::{String, ToString},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
|
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
|
pub mod contain;
|
||||||
|
pub mod file;
|
||||||
|
use file::File;
|
||||||
|
/// A prototype file table for AbleOS
|
||||||
|
///
|
||||||
|
/// This module provides a file table interface for AbleOS.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use crate::filesystem::ProtoFileTable;
|
||||||
|
/// let mut file_table = ProtoFileTable::new();
|
||||||
|
/// file_table.add_file("test.txt", "Hello, world!".as_bytes());
|
||||||
|
/// let file = file_table.get_file("test.txt");
|
||||||
|
/// assert_eq!(file.unwrap().as_slice(), "Hello, world!".as_bytes());
|
||||||
|
/// ```
|
||||||
|
pub struct ProtoFileTable {
|
||||||
|
files: HashMap<String, File>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProtoFileTable {
|
||||||
|
pub fn new() -> ProtoFileTable {
|
||||||
|
ProtoFileTable {
|
||||||
|
files: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_file(&mut self, path: &str, contents: File) {
|
||||||
|
self.files.insert(path.to_string(), contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_file(&self, path: &str) -> Option<&File> {
|
||||||
|
self.files.get(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
16
ableos/src/proto_filetable/tests.rs
Normal file
16
ableos/src/proto_filetable/tests.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
use super::file::FileLocations;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
fn test_add_file() {
|
||||||
|
let mut file_table = ProtoFileTable::new();
|
||||||
|
let file_to_add = File::new(FileLocations::Bin, "test".to_string(), "txt".to_string());
|
||||||
|
file_to_add.write_bytes(b"Hello, world!");
|
||||||
|
file_table.add_file("test", file_to_add);
|
||||||
|
let file = file_table.get_file("test.txt");
|
||||||
|
assert_eq!(
|
||||||
|
file.unwrap().data_pointer.as_slice(),
|
||||||
|
"Hello, world!".as_bytes()
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,6 +1,15 @@
|
||||||
/// # clparse
|
use alloc::{
|
||||||
/// simple command line parser for ableOS
|
string::{String, ToString},
|
||||||
|
vec,
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
clparse
|
||||||
|
* A simple command line parser for ableOS
|
||||||
|
*/
|
||||||
|
|
||||||
|
// use std::collections::HashMap;
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Argument {
|
pub struct Argument {
|
||||||
key: String,
|
key: String,
|
||||||
|
@ -16,22 +25,25 @@ pub struct Command {
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn parse(command: String) -> Command {
|
pub fn parse(command: String) -> Command {
|
||||||
let split_command = command.split('?');
|
let split_command = command.split("?");
|
||||||
let mut root = "".to_string();
|
let mut root = "".to_string();
|
||||||
|
let mut root_count = 0;
|
||||||
let mut args: Vec<Argument> = vec![];
|
let mut args: Vec<Argument> = vec![];
|
||||||
for (root_count, subcommand) in split_command.enumerate() {
|
for subcommand in split_command {
|
||||||
match root_count {
|
match root_count {
|
||||||
0 => root = subcommand.to_string(),
|
0 => root = subcommand.to_string(),
|
||||||
1 => {
|
1 => {
|
||||||
for subarg in subcommand.split('&') {
|
for subarg in subcommand.split("&") {
|
||||||
let mut arg1 = "";
|
let mut arg1 = "";
|
||||||
let mut arg2 = "";
|
let mut arg2 = "";
|
||||||
for (n, arg) in subarg.split('=').enumerate() {
|
let mut arg_count = 0;
|
||||||
if n == 0 {
|
for arg in subarg.split("=") {
|
||||||
|
if arg_count == 0 {
|
||||||
arg1 = arg;
|
arg1 = arg;
|
||||||
} else {
|
} else {
|
||||||
arg2 = arg;
|
arg2 = arg;
|
||||||
}
|
}
|
||||||
|
arg_count += 1;
|
||||||
}
|
}
|
||||||
let arg_struct = Argument {
|
let arg_struct = Argument {
|
||||||
key: arg1.to_string(),
|
key: arg1.to_string(),
|
||||||
|
@ -42,6 +54,7 @@ impl Command {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
root_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Command {
|
Command {
|
||||||
|
@ -50,7 +63,6 @@ impl Command {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test() {
|
pub fn test() {
|
||||||
let x = Command::parse("hi?there=uwu&hi=abc".to_string());
|
let x = Command::parse("hi?there=uwu&hi=abc".to_string());
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
use alloc::{boxed::Box};
|
||||||
|
|
||||||
|
|
||||||
pub struct BinCodeWriter {
|
pub struct BinCodeWriter {
|
||||||
pub stream: Box<u8>,
|
pub stream: Box<u8>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
|
use alloc::vec;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
pub fn encode(bytes: &[u8]) -> Vec<u8> {
|
pub fn encode(bytes: &[u8]) -> Vec<u8> {
|
||||||
let mut encoding = if bytes.first().is_none() {
|
let mut encoding;
|
||||||
|
|
||||||
|
if bytes.first().is_none() {
|
||||||
return vec![];
|
return vec![];
|
||||||
} else {
|
} else {
|
||||||
vec![*bytes.first().unwrap()]
|
encoding = vec![*bytes.first().unwrap()];
|
||||||
};
|
}
|
||||||
|
|
||||||
let mut occurrences = 1;
|
let mut occurrences = 1;
|
||||||
|
|
||||||
|
@ -17,12 +22,13 @@ pub fn encode(bytes: &[u8]) -> Vec<u8> {
|
||||||
}
|
}
|
||||||
|
|
||||||
encoding.push(occurrences);
|
encoding.push(occurrences);
|
||||||
|
|
||||||
encoding
|
encoding
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a run-length encoding and return its decoded contents.
|
/// Read a run-length encoding and return its decoded contents.
|
||||||
///
|
///
|
||||||
/// - `bytes` - The bytes to be decoded.
|
/// * `bytes` - The bytes to be decoded.
|
||||||
pub fn decode(bytes: &[u8]) -> Vec<u8> {
|
pub fn decode(bytes: &[u8]) -> Vec<u8> {
|
||||||
let mut decoding = Vec::<u8>::new();
|
let mut decoding = Vec::<u8>::new();
|
||||||
|
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
pub mod mono_bitmap;
|
pub mod mono_bitmap;
|
||||||
|
|
||||||
|
pub mod stupid_simple_image;
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
use shadeable::pixel_format::new_rgba64;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graphics::SCREEN_BUFFER,
|
graphics::SCREEN_BUFFER,
|
||||||
relib::encoding::rle::{decode, encode},
|
relib::encoding::rle::{decode, encode},
|
||||||
};
|
};
|
||||||
use shadeable::pixel_format::new_rgba64;
|
// use super::qoi;
|
||||||
|
|
||||||
pub fn bruh() {
|
pub fn bruh() {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
|
6
ableos/src/relib/image/stupid_simple_image/mod.rs
Normal file
6
ableos/src/relib/image/stupid_simple_image/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
r[255,0,0]
|
||||||
|
g[0,0,0]
|
||||||
|
b[0,0,0]
|
||||||
|
a[0,0,0]
|
||||||
|
*/
|
|
@ -1,6 +1,7 @@
|
||||||
pub static SOCKETS: spin::Mutex<SocketState> = spin::Mutex::new(vec![]);
|
use alloc::string::String;
|
||||||
|
use alloc::vec;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
pub type SocketState = Vec<SimpleSock>;
|
|
||||||
pub type Stream = Vec<u8>;
|
pub type Stream = Vec<u8>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -10,7 +11,12 @@ pub struct SocketID {
|
||||||
|
|
||||||
impl SocketID {
|
impl SocketID {
|
||||||
pub fn protocol(self) -> Option<String> {
|
pub fn protocol(self) -> Option<String> {
|
||||||
SOCKETS.lock()[self.id].protocol.clone()
|
let x = SOCKETS.lock()[self.id].protocol.clone();
|
||||||
|
|
||||||
|
match x {
|
||||||
|
Some(protocol_name) => Some(protocol_name),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +41,11 @@ impl Socket for SocketID {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type SocketState = Vec<SimpleSock>;
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
pub static ref SOCKETS: spin::Mutex<SocketState> = spin::Mutex::new(vec![]);
|
||||||
|
}
|
||||||
pub trait Socket {
|
pub trait Socket {
|
||||||
fn peek(&mut self) -> SocketReturns;
|
fn peek(&mut self) -> SocketReturns;
|
||||||
|
|
||||||
|
@ -47,7 +58,6 @@ pub trait Socket {
|
||||||
|
|
||||||
fn close(&mut self) {}
|
fn close(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SocketReturns {
|
pub enum SocketReturns {
|
||||||
ReadOk(Stream),
|
ReadOk(Stream),
|
||||||
|
@ -110,11 +120,10 @@ impl Socket for SimpleSock {
|
||||||
let mut return_vec = vec![];
|
let mut return_vec = vec![];
|
||||||
|
|
||||||
for x in &self.stream {
|
for x in &self.stream {
|
||||||
return_vec.push(*x);
|
return_vec.push(x.clone());
|
||||||
}
|
}
|
||||||
SocketReturns::ReadOk(return_vec)
|
SocketReturns::ReadOk(return_vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&mut self, length: usize) -> SocketReturns {
|
fn read(&mut self, length: usize) -> SocketReturns {
|
||||||
let mut return_vec = vec![];
|
let mut return_vec = vec![];
|
||||||
if length > self.stream.len() {
|
if length > self.stream.len() {
|
||||||
|
@ -127,11 +136,9 @@ impl Socket for SimpleSock {
|
||||||
SocketReturns::ReadOk(return_vec)
|
SocketReturns::ReadOk(return_vec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_protocol(&mut self, protocol_name: String) {
|
fn register_protocol(&mut self, protocol_name: String) {
|
||||||
self.protocol = Some(protocol_name);
|
self.protocol = Some(protocol_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_protocol(&mut self, protocol_name: String) -> bool {
|
fn check_protocol(&mut self, protocol_name: String) -> bool {
|
||||||
if self.protocol == Some(protocol_name) {
|
if self.protocol == Some(protocol_name) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -139,13 +146,11 @@ impl Socket for SimpleSock {
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, stream: Stream) -> SocketReturns {
|
fn write(&mut self, stream: Stream) -> SocketReturns {
|
||||||
for byte in stream {
|
for byte in stream {
|
||||||
self.stream.push(byte);
|
self.stream.push(byte);
|
||||||
}
|
}
|
||||||
SocketReturns::WriteOk
|
SocketReturns::WriteOk
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(&mut self) {}
|
fn close(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,8 @@
|
||||||
use super::Time;
|
use super::Time;
|
||||||
use core::fmt::{Display, Error, Formatter};
|
use core::fmt::{Display, Error, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Kilosecond(usize);
|
pub struct Kilosecond(usize);
|
||||||
impl Kilosecond {
|
|
||||||
pub fn from_ms(ms: usize) -> Self {
|
|
||||||
Self(ms)
|
|
||||||
}
|
|
||||||
pub fn from_sec(sec: usize) -> Self {
|
|
||||||
Self(sec * 1000)
|
|
||||||
}
|
|
||||||
pub fn from_minutes(min: usize) -> Self {
|
|
||||||
Self(min * 60 * 1000)
|
|
||||||
}
|
|
||||||
pub fn from_hours(hrs: usize) -> Self {
|
|
||||||
Self(hrs * 60 * 60 * 1000)
|
|
||||||
}
|
|
||||||
pub fn from_days(days: usize) -> Self {
|
|
||||||
Self(days * 24 * 60 * 60 * 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Kilosecond {
|
impl Display for Kilosecond {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||||
let mut reg = self.0;
|
let mut reg = self.0;
|
||||||
|
@ -55,23 +36,37 @@ impl Display for Kilosecond {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::ops::Add for Kilosecond {
|
impl core::ops::Add for Kilosecond {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn add(self, rhs: Self) -> Self {
|
fn add(self, rhs: Self) -> Self {
|
||||||
Self(self.0 + rhs.0)
|
Self(self.0 + rhs.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::ops::Sub for Kilosecond {
|
impl core::ops::Sub for Kilosecond {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn sub(self, rhs: Self) -> Self {
|
fn sub(self, rhs: Self) -> Self {
|
||||||
Self(self.0 - rhs.0)
|
Self(self.0 - rhs.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Time> for Kilosecond {
|
impl From<Time> for Kilosecond {
|
||||||
fn from(t: Time) -> Self {
|
fn from(t: Time) -> Self {
|
||||||
Self((t.hour as usize * 3600 + t.minutes as usize * 60 + t.seconds as usize) * 1000)
|
Self((t.hour as usize * 3600 + t.minutes as usize * 60 + t.seconds as usize) * 1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Kilosecond {
|
||||||
|
pub fn from_ms(ms: usize) -> Self {
|
||||||
|
Self(ms)
|
||||||
|
}
|
||||||
|
pub fn from_sec(sec: usize) -> Self {
|
||||||
|
Self(sec * 1000)
|
||||||
|
}
|
||||||
|
pub fn from_minutes(min: usize) -> Self {
|
||||||
|
Self(min * 60 * 1000)
|
||||||
|
}
|
||||||
|
pub fn from_hours(hrs: usize) -> Self {
|
||||||
|
Self(hrs * 60 * 60 * 1000)
|
||||||
|
}
|
||||||
|
pub fn from_days(days: usize) -> Self {
|
||||||
|
Self(days * 24 * 60 * 60 * 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue