Compare commits

...

72 commits
uefi ... master

Author SHA1 Message Date
Able 7492cef2fc update to the tool chain file 2022-04-24 04:20:15 -05:00
Able 2d2a9df7c5 update to the hello world program 2022-04-24 03:23:23 -05:00
Able 9d1cb9c640 print SYSCALL works 2022-04-19 02:38:59 -05:00
Able 9e836f8098 updates 2022-04-19 02:15:45 -05:00
Able 8d70bb08ca Messaging api done 2022-04-12 18:17:48 -05:00
Erin 225b35c3d0 fmt 2022-04-13 00:50:01 +02:00
Able b3f8b11c5a riscv work 2022-04-12 13:46:50 -05:00
Able 51c841e2de upgrades people upgrades
destroying erins clean code
2022-04-12 13:26:52 -05:00
Erin ddfbd579e3 Peek and poke works 2022-04-12 15:35:09 +02:00
Erin c613e5eb1a oh, i missed a bit! 2022-04-12 00:27:57 +02:00
Able 1dca7c4705 Merge branches 'master' and 'master' of ssh://git.ablecorp.us:20/able/ableos 2022-04-11 17:26:30 -05:00
Erin 1ccd643ff6 reorder 2022-04-12 00:23:27 +02:00
Erin 9ed7dbb34c chore: fmt 2022-04-12 00:23:11 +02:00
Erin b86d42e48c Obeyed clippy, our paperclip overlord (mostly) 2022-04-11 23:07:01 +02:00
Erin a258676d20 supressed false positive 2022-04-11 23:02:36 +02:00
Erin 91dc000502 fixed type in feature 2022-04-11 22:53:06 +02:00
Erin 56b569deb2 Refactoring
- Applied some clippy lints
- Formatting
- Replaced lazy_static with Lazy from spin
2022-04-11 22:51:54 +02:00
Able 2b04ff3cdd fixes 2022-04-11 15:36:45 -05:00
Able 2e1ad746fe Merge branch 'master' of ssh://git.ablecorp.us:20/able/ableos 2022-04-11 15:34:52 -05:00
Able 22cb0d71af fixes 2022-04-11 15:34:40 -05:00
Erin 2b35e3054e fixed repbuild 2022-04-11 21:48:20 +02:00
Able 4fcde8bf41 Merge branch 'master' of ssh://git.ablecorp.us:20/able/ableos 2022-04-11 13:53:37 -05:00
Able d78bb002f3 workspace 2022-04-11 13:53:33 -05:00
Erin 5f707e990c Fixed compilation on latest nightly 2022-04-11 19:51:26 +02:00
Able 762e6a27ea ableOS input update 2022-04-09 23:49:17 -05:00
Able 20482f57a3 The issue was trivial, Axel had std deps I didn't check 2022-04-09 22:04:16 -05:00
Able 72457cc34e simplification 2022-04-09 17:26:43 -05:00
Able fe342406b4 Merge branch 'theoddgarlic-repbuild-mount-unmount' 2022-03-26 07:01:19 -05:00
Able 709b90c8f4 Merge branch 'repbuild-mount-unmount' of https://git.ablecorp.us:443/theoddgarlic/ableos into theoddgarlic-repbuild-mount-unmount 2022-03-26 06:59:29 -05:00
TheOddGarlic 10646959fa Add repbuild subcommands mount & unmount
These repbuild subcommands mount the filesystem root to the
userland/root_fs/mnt folder, and this makes editing the initial file
system easier.

This also renames userland/root_rs to userland/root_fs.
2022-03-26 14:52:23 +03:00
Able 6bf591a313 incorperate axel 2022-03-26 06:35:33 -05:00
Able b1eaea239e VTerm| VTerm device 2022-03-16 09:38:47 -05:00
Able 8e66a677fa Feature| afetch update, scheduler rework 2022-03-16 05:39:01 -05:00
Able c18035feb4 Patch| Serial out agnostic 2022-03-11 17:13:41 -06:00
Able d2638b1fb4 Patch| Logging repaired 2022-03-11 15:14:35 -06:00
Able 4b6dae5fd1 Merge branch 'riscv' 2022-03-11 14:20:28 -06:00
Able 0c1169adab merge work 2022-03-11 14:18:07 -06:00
Able a857253314 Merge branch 'master' into riscv 2022-03-11 14:16:15 -06:00
Able 19323ef935 gitignore update 2022-03-11 13:57:10 -06:00
Able 0379a34a59 TOML config|moved a ton of boiler plate to prelude 2022-03-11 13:51:47 -06:00
Able 05ce9f61c7 commit message 2022-03-07 12:21:16 -06:00
Able beba2ae0ad modularizing the kernel 2022-03-02 08:38:22 -06:00
Able 6c3a67e6b5 seperate the core kernel into its own directory 2022-02-28 08:54:41 -06:00
Able c21b1a75f5 pci cleaned up 2022-02-28 06:48:56 -06:00
Able 65259360eb adding time syscall 2022-02-26 07:47:44 -06:00
Able 3ce2026d32 wasm jumploader patches 2022-02-26 07:35:36 -06:00
Able ab3110923e metadata and peek/poke 2022-02-23 10:06:27 -06:00
Able 64d6e1e166 PIT Timer settable 2022-02-22 18:15:16 -06:00
Able f6143d3895 string colorizer 2022-02-21 07:17:16 -06:00
Able 7fc1606a18 fruitless efforts in persuit of #12 2022-02-20 08:34:20 -06:00
Able 5876cb6049 Merge branch 'fix/rhai-repl' 2022-02-20 05:08:28 -06:00
able 9273d74446 Merge branch 'master' into fix/rhai-repl 2022-02-20 11:06:56 +00:00
Able e661e5c255 merge work 2022-02-20 05:05:50 -06:00
Able c49eb97397 patchup 2022-02-19 09:07:33 -06:00
Able b7431ba474 move rhai shell to its own sub folder 2022-02-19 08:46:11 -06:00
Able 44c252ed84 persistant scope 2022-02-19 07:17:44 -06:00
Erin ca743955c5 chore: fmt 2022-02-18 19:25:54 +01:00
Erin bdd866eafe Working Rhai REPL 2022-02-18 19:12:07 +01:00
Able d8d093cb98 booting on riscv 2022-02-18 10:04:10 -06:00
Able 38a8ae6e20 pci work 2022-02-18 02:24:10 -06:00
Able d4e4d70461 rhai shell tinkering 2022-02-17 04:05:56 -06:00
Able 19508c979e main graphics loop 2022-02-12 23:17:17 -06:00
Able b21c53fa82 minor changes 2022-02-12 03:25:02 -06:00
Able 75cfb18c77 character device impl, pci devices found 2022-02-09 07:08:40 -06:00
Able a78570b85f rootfs changes 2022-02-08 04:13:53 -06:00
Able f61d4fe9e7 filesystem implementation 2022-02-08 03:01:29 -06:00
Able 5ea5172cae ext2fs 2022-02-07 21:14:47 -06:00
Able 80ac635ceb relocate 2022-02-07 20:18:23 -06:00
Able 19f908dac2 litter todo about 2022-02-07 07:33:40 -06:00
Able 5a1a84b1c7 syscall 2022-02-07 06:38:18 -06:00
Able df86c272f3 qprofiler integration 2022-02-07 03:42:57 -06:00
Able 45acef0c97 revert broken changes 2022-02-07 03:01:50 -06:00
158 changed files with 5617 additions and 2691 deletions

6
.gitignore vendored
View file

@ -3,3 +3,9 @@ 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

View file

@ -2,7 +2,5 @@
"files.associations": { "files.associations": {
"stddef.h": "c" "stddef.h": "c"
}, },
"settings": { "rust-analyzer.checkOnSave.allTargets": false,
}
} }

1100
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

10
Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[workspace]
members = [
"ableos",
"kernel",
"facepalm",
"shadeable",
"repbuild",
]

View file

@ -1,18 +1,15 @@
[build] [build]
# target = "./json_targets/x86_64-ableos.json" # target = "riscv64gc-unknown-none-elf"
target = "x86_64-unknown-uefi" 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=+rdrnd"] 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=-T../ableos/src/arch/riscv/virt.lds" rustflags = "-C link-arg=-Tableos/src/arch/riscv/virt.lds"
# ableos/src/arch/riscv/virt.lds

425
ableos/Cargo.lock generated
View file

@ -4,9 +4,9 @@ version = 3
[[package]] [[package]]
name = "ab_glyph" name = "ab_glyph"
version = "0.2.13" version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61caed9aec6daeee1ea38ccf5fb225e4f96c1eeead1b4a5c267324a63cf02326" checksum = "24606928a235e73cdef55a0c909719cadd72fce573e5713d58cb2952d8f5794c"
dependencies = [ dependencies = [
"ab_glyph_rasterizer", "ab_glyph_rasterizer",
"libm", "libm",
@ -24,38 +24,64 @@ dependencies = [
[[package]] [[package]]
name = "ableos" name = "ableos"
version = "0.1.0" version = "0.1.1"
dependencies = [ dependencies = [
"ab_glyph", "ab_glyph",
"acpi",
"axel",
"bootloader", "bootloader",
"cpuio", "cpuio",
"ext2",
"externc-libm", "externc-libm",
"facepalm", "facepalm",
"hashbrown", "genfs",
"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", "rdrand",
"rhai",
"riscv",
"rkyv", "rkyv",
"serde", "serde",
"serde_json",
"shadeable", "shadeable",
"smoltcp", "spin 0.5.2",
"spin", "toml",
"uart_16550", "uart_16550",
"uefi",
"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"
@ -69,10 +95,42 @@ dependencies = [
] ]
[[package]] [[package]]
name = "autocfg" name = "aho-corasick"
version = "1.0.1" version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[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"
@ -88,15 +146,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bootloader" name = "bootloader"
version = "0.9.21" version = "0.9.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62c8f6168cd106687ee36a2b71a46c4144d73399f72814104d33094b8092fd2" checksum = "de78decc37247c7cfac5dbf3495c7298c6ac97cb355161caa7e15969c6648e6c"
[[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"
@ -167,6 +219,17 @@ 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"
@ -182,6 +245,12 @@ 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"
@ -189,10 +258,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e" checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
[[package]] [[package]]
name = "getrandom" name = "genfs"
version = "0.2.4" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" checksum = "65b9e52a0ffd4c2f11f9f84e8885a40cb99f490971eee78bbd7ddffd6ac023d6"
[[package]]
name = "getrandom"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -201,11 +276,21 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.11.2" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" checksum = "96282e96bfcd3da0d3aa9938bedf1e50df3269b6db08b4876d2da0bb1a0841cf"
dependencies = [ dependencies = [
"ahash", "ahash 0.3.8",
"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]]
@ -218,10 +303,13 @@ dependencies = [
] ]
[[package]] [[package]]
name = "itoa" name = "kernel"
version = "1.0.1" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" "lazy_static",
"log",
"versioning",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
@ -229,20 +317,25 @@ 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", "spin 0.5.2",
] ]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.112" version = "0.2.119"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
[[package]] [[package]]
name = "libm" name = "libm"
version = "0.2.1" 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 = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db"
[[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"
@ -261,9 +354,9 @@ checksum = "2d502c8bcc35a4f7ca9a7ffb7ac27b15ba30b1b92c2d69a1e4437e2635d73af7"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.5" version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
dependencies = [ dependencies = [
"scopeguard", "scopeguard",
] ]
@ -278,10 +371,34 @@ dependencies = [
] ]
[[package]] [[package]]
name = "managed" name = "logos"
version = "0.8.0" version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" checksum = "427e2abca5be13136da9afdbf874e6b34ad9001dd70f2b103b083a85daa7b345"
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"
@ -328,15 +445,15 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.9.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]] [[package]]
name = "owned_ttf_parser" name = "owned_ttf_parser"
version = "0.14.0" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ef05f2882a8b3e7acc10c153ade2631f7bfc8ce00d2bf3fb8f4e9d2ae6ea5c3" checksum = "4fb1e509cfe7a12db2a90bfa057dfcdbc55a347f5da677c506b53dd099cfec9d"
dependencies = [ dependencies = [
"ttf-parser", "ttf-parser",
] ]
@ -347,6 +464,14 @@ 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"
@ -405,9 +530,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.14" version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -428,12 +553,30 @@ dependencies = [
] ]
[[package]] [[package]]
name = "rhai" name = "regex"
version = "1.4.0" version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c7433068977c56619bf2b7831da26eb986d0645fe56f2ad9357eda7ae4c435e" checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [ dependencies = [
"ahash", "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]]
name = "rhai"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ef3d57e55ca044c53ced279d2d3ee9df229b247556b005a23713d5206a2ecfc"
dependencies = [
"ahash 0.7.6",
"bitflags",
"core-error", "core-error",
"instant", "instant",
"libm", "libm",
@ -446,9 +589,9 @@ dependencies = [
[[package]] [[package]]
name = "rhai_codegen" name = "rhai_codegen"
version = "1.3.0" 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 = "e02d33d76a7aa8ec72ac8298d5b52134fd2dff77445ada0c65f6f8c40d8f2931" checksum = "faa0ff1c9dc19c9f8bba510a2a75d3f0449f6233570c2672c7e31c692a11a59a"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -456,12 +599,33 @@ dependencies = [
] ]
[[package]] [[package]]
name = "rkyv" name = "riscv"
version = "0.7.29" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49a37de5dfc60bae2d94961dacd03c7b80e426b66a99fa1b17799570dbdd8f96" checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba"
dependencies = [ dependencies = [
"hashbrown", "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]]
name = "rkyv"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cdcf5caf69bcc87b1e3f5427b4f21a32fdd53c2847687bdf9861abb1cdaa0d8"
dependencies = [
"hashbrown 0.12.0",
"ptr_meta", "ptr_meta",
"rkyv_derive", "rkyv_derive",
"seahash", "seahash",
@ -469,9 +633,9 @@ dependencies = [
[[package]] [[package]]
name = "rkyv_derive" name = "rkyv_derive"
version = "0.7.29" version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719d447dd0e84b23cee6cb5b32d97e21efb112a3e3c636c8da36647b938475a1" checksum = "a6cf557da1f81b8c7e889c59c9c3abaf6978f7feb156b9579e4f8bf6d7a2bada"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -479,10 +643,19 @@ dependencies = [
] ]
[[package]] [[package]]
name = "ryu" name = "rlibc"
version = "1.0.9" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" checksum = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe"
[[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"
@ -498,35 +671,24 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.133" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.133" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
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"
@ -534,7 +696,6 @@ dependencies = [
"libm", "libm",
"log", "log",
"rhai", "rhai",
"vga",
] ]
[[package]] [[package]]
@ -545,23 +706,13 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]] [[package]]
name = "smartstring" name = "smartstring"
version = "0.2.9" 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 = "31aa6a31c0c2b21327ce875f7e8952322acfcfd0c27569a6e18a647281352c9b" checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
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]]
@ -570,6 +721,15 @@ 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"
@ -587,9 +747,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.85" version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -605,11 +765,20 @@ 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.14.0" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ccbe8381883510b6a2d8f1e32905bddd178c11caef8083086d0c0c9ab0ac281" checksum = "c74c96594835e10fa545e2a51e8709f30b173a092bfd6036ef2cec53376244f3"
[[package]] [[package]]
name = "uart_16550" name = "uart_16550"
@ -621,38 +790,6 @@ dependencies = [
"x86_64", "x86_64",
] ]
[[package]]
name = "ucs2"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bad643914094137d475641b6bab89462505316ec2ce70907ad20102d28a79ab8"
dependencies = [
"bit_field",
]
[[package]]
name = "uefi"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21398a404f6fa14f6df34756714874eccdf73587eba863cb5bd55d8bada7496"
dependencies = [
"bitflags",
"log",
"ucs2",
"uefi-macros",
]
[[package]]
name = "uefi-macros"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7006b85ae8acaf2b448c5f1630a434caaacaedcc0907f12404e4e31c9dafcdb3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.9" version = "0.1.9"
@ -665,12 +802,26 @@ 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"
@ -728,10 +879,26 @@ dependencies = [
] ]
[[package]] [[package]]
name = "x86_64" name = "watson"
version = "0.14.7" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb611915c917c6296d11e23f71ff1ecfe49c5766daba92cd3df52df6b58285b6" 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]]
name = "x86_64"
version = "0.14.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "958ab3202b01bc43ba2eb832102c4a487ed93151667a2289062e5f2b00058be2"
dependencies = [ dependencies = [
"bit_field", "bit_field",
"bitflags", "bitflags",

View file

@ -1,7 +1,7 @@
[package] [package]
edition = "2021" edition = "2021"
name = "ableos" name = "ableos"
version = "0.1.0" version = "0.1.1"
# 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,30 +9,32 @@ panic = "abort"
[package.metadata.bootimage] [package.metadata.bootimage]
run-args = [ run-args = [
"--nodefaults",
"-cpu", "-cpu",
# "kvm64-v1", "Broadwell-v3",
# Support for rdrand
# "Broadwell",
"EPYC-v1",
"-serial", "-serial",
"stdio", "stdio",
"-smp", "-smp",
"cores=2", "cores=2",
# An example gpu used with ableOS
# "-device",
# "virtio-gpu",
# An example disk used with ableOS
"-device", "-device",
"virtio-blk-pci,drive=drive0,id=virtblk0,num-queues=4", "cirrus-vga",
# "-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",
@ -43,51 +45,61 @@ test-args = [
[dependencies] [dependencies]
linked_list_allocator = "0.9.0" linked_list_allocator = "0.9.0"
lliw = "0.2.0" lliw = "0.2.0"
# qoi_rs = "*" spin = "0.9"
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 = "*" picorand = "0.1.0"
# watson = "0.4" watson = "0.4"
uefi = { version="*", features = ["exts"] } 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] [dependencies.rdrand]
version = "0.8.1" version = "0.8"
default-features = false default-features = false
[dependencies.kernel]
path = "../kernel"
[dependencies.serde] [dependencies.serde]
version = "*" version = "1.0"
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 = "*" version = "0.7"
default-features = false default-features = false
features = ["inline-more"] features = ["inline-more"]
[dependencies.rkyv] [dependencies.rkyv]
version = "0.7.29" version = "0.7"
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"
@ -104,13 +116,14 @@ 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" }
@ -118,3 +131,6 @@ 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"

13
ableos/assets/kernel.toml Normal file
View file

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

View file

@ -1,7 +0,0 @@
{
"logging_level": "Trace",
"logger_padding": 10,
"run_tests": false,
"run_demos": false,
"run_shader_tests": false
}

View file

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

View file

@ -1,3 +0,0 @@
wgpu
write using wgpu and compiles to native/web

View file

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

View file

@ -1 +0,0 @@
start custom unicode at E100

View file

@ -1,3 +0,0 @@
user
> execute
> file system

View file

@ -1,17 +0,0 @@
VGA
pcie
gpu
amd
ati
set_red
ssd

View file

@ -1,9 +1,7 @@
use alloc::string::{String, ToString};
use hashbrown::HashMap; use hashbrown::HashMap;
lazy_static::lazy_static! { pub static ALIAS_TABLE: spin::Mutex<AliasTable> = spin::Mutex::new(AliasTable::new());
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
@ -17,6 +15,7 @@ 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);
} }

View file

@ -1,14 +1,16 @@
/*! //! 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()
} }

View file

@ -1,22 +1,12 @@
mod aalloc; mod aalloc;
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_BASE: usize = 100;
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; use linked_list_allocator::LockedHeap;
pub const HEAP_START: usize = 0x_4444_4444_0000;
pub const HEAP_MULTIPLIER: usize = 100000;
pub const HEAP_BASE: usize = 100;
pub const HEAP_SIZE: usize = HEAP_BASE * HEAP_MULTIPLIER;
#[global_allocator] #[global_allocator]
pub static ALLOCATOR: LockedHeap = LockedHeap::empty(); pub static ALLOCATOR: LockedHeap = LockedHeap::empty();

View file

@ -2,7 +2,6 @@ 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()

View file

@ -7,21 +7,27 @@ 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() {}

View file

@ -1,36 +1,8 @@
//! 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;
@ -40,7 +12,8 @@ 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) {
@ -71,3 +44,27 @@ 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) }
}
}

View file

@ -1,11 +1,10 @@
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) {
@ -33,7 +32,6 @@ 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;
// //
@ -46,14 +44,15 @@ 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;

View file

@ -2,7 +2,6 @@ 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()

View file

@ -7,21 +7,27 @@ 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() {}

View file

@ -0,0 +1,35 @@
/// # 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() }
}

View file

@ -1,3 +1,5 @@
pub mod allocator; pub mod allocator;
pub mod graphics; pub mod graphics;
pub mod serial; pub mod mmio;
pub mod sysinfo;
pub mod uart;

View file

@ -1,47 +0,0 @@
/// 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,
};

View file

@ -0,0 +1,23 @@
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()
}
}

View file

@ -0,0 +1,129 @@
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(())
}
}

View file

@ -1,5 +1,10 @@
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() -> ! {
@ -31,19 +36,64 @@ unsafe extern "C" fn _boot() -> ! {
} }
extern "C" fn _start() -> ! { extern "C" fn _start() -> ! {
use crate::serial_println;
let uart = crate::arch::drivers::uart::Uart::new(0x1000_0000);
uart.init();
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);
}
/* /*
let uart_data = 0x10000000 as *mut u8; 91 => {
for c in b"Hardcoded serial output\n" { if let Some(ch) = uart.get() {
unsafe { uart_data.write_volatile(*c) }; 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!");
}
}
}
} }
*/ */
crate::serial_print!("Hi"); _ => {
crate::kmain::kernel_main(); uart.put(c);
}
}
}
}
serial_println!("Serial connection closed.\r");
sloop() sloop()
} }
pub fn sloop() -> ! { pub fn sloop() -> ! {
loop { loop {
unsafe { asm!("nop") }; unsafe {
asm!("wfi");
};
} }
} }
pub fn shutdown() {}
pub fn generate_process_pass() -> u128 {
123
}

View file

@ -1,6 +1,5 @@
use alloc::alloc::{GlobalAlloc, Layout};
// use core::alloc::{GlobalAlloc, Layout};
use crate::allocator::{HEAP_SIZE, HEAP_START}; use crate::allocator::{HEAP_SIZE, HEAP_START};
use alloc::alloc::{GlobalAlloc, Layout};
use core::ptr::null_mut; use core::ptr::null_mut;
use x86_64::{ use x86_64::{
structures::paging::{ structures::paging::{
@ -9,7 +8,6 @@ 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()

View file

@ -8,25 +8,32 @@ 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() {

View file

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

View file

@ -1,13 +1,12 @@
use lazy_static::lazy_static; use spin::{Lazy, Mutex};
use spin::Mutex;
use uart_16550::SerialPort; use uart_16550::SerialPort;
lazy_static! {
pub static ref SERIAL1: Mutex<SerialPort> = { pub static SERIAL1: Lazy<Mutex<SerialPort>> = Lazy::new(|| {
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;
@ -16,18 +15,20 @@ pub fn _print(args: ::core::fmt::Arguments) {
.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! serial_print { macro_rules! sprint {
($($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! serial_println { macro_rules! sprintln {
() => ($crate::serial_print!("\n")); () => ($crate::sprint!("\n"));
($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n"))); ($fmt:expr) => ($crate::sprint!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => ($crate::serial_print!( ($fmt:expr, $($arg:tt)*) => ($crate::sprint!(
concat!($fmt, "\n"), $($arg)*)); concat!($fmt, "\n"), $($arg)*));
} }

View file

@ -1,9 +1,3 @@
#![feature(asm)]
#![cfg_attr(
not(any(target_arch = "x86_64", target_arch = "x86")),
allow(dead_code)
)]
//! ``` //! ```
//! extern crate cupid; //! extern crate cupid;
//! //!
@ -18,10 +12,50 @@
//! } //! }
//! ``` //! ```
#![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,
@ -39,85 +73,6 @@ pub enum RequestType {
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,
@ -247,8 +202,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, {
@ -283,10 +238,16 @@ 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", {
@ -352,7 +313,7 @@ impl fmt::Debug for VersionInformation {
ss, ss,
htt, htt,
tm, tm,
pbe pbe,
}) })
} }
} }
@ -374,7 +335,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
}); });
@ -387,7 +348,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
}); });
} }
@ -402,14 +363,11 @@ 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],
} }
@ -446,7 +404,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: bytes } BrandString { bytes }
} }
} }
@ -502,7 +460,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 {
@ -530,9 +488,7 @@ 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
}) })
@ -573,7 +529,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
}); });
@ -602,7 +558,7 @@ impl fmt::Debug for StructuredExtendedInformation {
adx, adx,
smap, smap,
intel_processor_trace, intel_processor_trace,
prefetchwt1 prefetchwt1,
}) })
} }
} }
@ -620,7 +576,6 @@ 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);
@ -685,7 +640,6 @@ 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);
@ -753,12 +707,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
@ -768,9 +722,8 @@ 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 = let brand_string = when_supported(max_value, RequestType::BrandString3, BrandString::new);
when_supported(max_value, RequestType::BrandString3, || BrandString::new()); let cache_line = when_supported(max_value, RequestType::CacheLine, CacheLine::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()
}); });
@ -783,8 +736,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,
} }
@ -808,7 +761,7 @@ impl Master {
self.brand_string self.brand_string
.as_ref() .as_ref()
.map(|bs| bs as &str) .map(|bs| bs as &str)
.or(self.version_information.and_then(|vi| vi.brand_string())) .or_else(|| self.version_information.and_then(|vi| vi.brand_string()))
} }
delegate_flag!(version_information, { delegate_flag!(version_information, {
@ -870,7 +823,7 @@ impl Master {
ss, ss,
htt, htt,
tm, tm,
pbe pbe,
}); });
delegate_flag!(thermal_power_management_information, { delegate_flag!(thermal_power_management_information, {
@ -886,7 +839,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, {
@ -918,11 +871,66 @@ 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"))] {

View file

@ -1,3 +1,10 @@
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)]
@ -19,31 +26,34 @@ 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 {
fn new(foreground: Color, background: Color) -> ColorCode { const 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 {
@ -63,6 +73,7 @@ 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 {
@ -73,6 +84,7 @@ 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 {
@ -83,6 +95,7 @@ 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' ',
@ -108,35 +121,33 @@ 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 ref WRITER: Mutex<Writer> = Mutex::new(Writer { pub static WRITER: Lazy<Mutex<Writer>> = Lazy::new(|| {
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;

View file

@ -1,10 +1,16 @@
use lazy_static::lazy_static; use spin::Lazy;
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 = { struct Selectors {
code_selector: SegmentSelector,
tss_selector: SegmentSelector,
}
static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
let mut tss = TaskStateSegment::new(); let mut tss = TaskStateSegment::new();
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = { tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
const STACK_SIZE: usize = 4096 * 5; const STACK_SIZE: usize = 4096 * 5;
@ -14,14 +20,9 @@ lazy_static! {
stack_start + STACK_SIZE stack_start + STACK_SIZE
}; };
tss tss
}; });
}
struct Selectors { static GDT: Lazy<(GlobalDescriptorTable, Selectors)> = Lazy::new(|| {
code_selector: SegmentSelector,
tss_selector: SegmentSelector,
}
lazy_static! {
static ref GDT: (GlobalDescriptorTable, Selectors) = {
let mut gdt = GlobalDescriptorTable::new(); let mut gdt = GlobalDescriptorTable::new();
let code_selector = gdt.add_entry(Descriptor::kernel_code_segment()); let code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS)); let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS));
@ -32,8 +33,8 @@ lazy_static! {
tss_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;

View file

@ -1,25 +1,42 @@
// #![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::{
network::socket::SimpleSock, relib::network::socket::Socket,
scheduler::priority::Priority::High, stdio::StdIO,
};
let mut log_socket_id = SimpleSock::new();
log_socket_id.register_protocol("Logger".to_string());
let result = logger::init(); let result = logger::init();
match result { match result {
Ok(_) => {} Ok(_) => {
serial_println!("Logger initialized");
}
Err(err) => error!("{}", err), Err(err) => error!("{}", err),
} }
gdt::init(); gdt::init();
use crate::scheduler::Priority::High;
let mut scheduler = SCHEDULER.lock(); let mut scheduler = SCHEDULER.lock();
let process_0 = scheduler.new_process(High); let process_0 = scheduler.new_process(
Capabilities::empty(),
High,
"".to_string(),
StdIO::new("null".to_string()),
);
scheduler.add_process(process_0); scheduler.add_process(process_0);
drop(scheduler); drop(scheduler);
interrupts::init_idt(); interrupts::init_idt();
unsafe { interrupts::PICS.lock().initialize() }; unsafe { interrupts::PICS.lock().initialize() };
x86_64::instructions::interrupts::enable(); x86_64::instructions::interrupts::enable();
} }

View file

@ -2,14 +2,16 @@ 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 lazy_static::lazy_static;
use pic8259::ChainedPics; use pic8259::ChainedPics;
use spin; use spin::Lazy;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame}; 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) });
@ -19,7 +21,10 @@ 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
@ -28,39 +33,49 @@ impl InterruptIndex {
usize::from(self.as_u8()) usize::from(self.as_u8())
} }
} }
pub fn init_idt() {
IDT.load(); static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
}
lazy_static! {
static ref IDT: InterruptDescriptorTable = {
let mut idt = InterruptDescriptorTable::new(); let mut idt = InterruptDescriptorTable::new();
idt.breakpoint.set_handler_fn(breakpoint_handler); idt.breakpoint.set_handler_fn(breakpoint_handler);
unsafe { unsafe {
idt.double_fault.set_handler_fn(double_fault_handler) idt.double_fault
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); // new .set_handler_fn(double_fault_handler)
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
} }
// This gives fast interrupts
set_pit_frequency(1000);
idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer_interrupt_handler); idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer_interrupt_handler);
idt[InterruptIndex::Keyboard.as_usize()].set_handler_fn(keyboard_interrupt_handler); idt[InterruptIndex::Keyboard.as_usize()].set_handler_fn(keyboard_interrupt_handler);
idt[6].set_handler_fn(floppy_disk_interrupt_handler);
idt 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!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); panic!(
"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) {
crate::kmain::tick(); kernel::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,
@ -68,14 +83,15 @@ 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 ref KEYBOARD: Mutex<Keyboard<CustomLayout, CustomScancodeSet>> = static KEYBOARD: Lazy<Mutex<Keyboard<CustomLayout, CustomScancodeSet>>> = Lazy::new(|| {
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() };
@ -90,20 +106,18 @@ 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());
} }
} }
@ -129,16 +143,21 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
} }
} }
/* extern "x86-interrupt" fn floppy_disk_interrupt_handler(_stack_frame: InterruptStackFrame) {
extern "x86-interrupt" fn page_fault_handler( println!("EXCEPTION: FLOPPY DISK");
stack_frame: InterruptStackFrame, }
error_code: PageFaultErrorCode,
) { pub fn init_idt() {
use x86_64::registers::control::Cr2; IDT.load();
println!["Exception: Page Fault"]; }
println!["Address: {:?}", Cr2::read()];
println!["Error Code: {:?}", error_code]; fn set_pit_frequency(freq: u32) {
println!["{:#?}", stack_frame]; let divisor: u16 = (1193180 / freq).try_into().unwrap();
sloop();
unsafe {
outb(0x36, 0x43);
outb((divisor & 0xFF) as u8, 0x40);
outb((divisor >> 8) as u8, 0x40);
}
} }
*/

View file

@ -74,7 +74,6 @@ pub fn create_example_mapping(
} }
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

View file

@ -1,16 +1,13 @@
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) -> ! {
@ -19,13 +16,12 @@ 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_ptr: *mut u64 = page.start_address().as_mut_ptr(); // let page = Page::containing_address(VirtAddr::new(0xdeadbeaf000));
unsafe { page_ptr.offset(400).write_volatile(0xf021_f077_f065_804e) }; // memory::create_example_mapping(page, &mut mapper, &mut frame_allocator);
} //
// 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");
@ -47,3 +43,12 @@ 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)
}

View file

@ -1,5 +1,4 @@
use log::LevelFilter; use log::LevelFilter;
// use rkyv::{Deserialize, Serialize};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Debug, Deserialize)] #[derive(Serialize, Debug, Deserialize)]
@ -19,29 +18,20 @@ pub enum LogLevel {
} }
#[derive(Serialize, Debug, Deserialize)] #[derive(Serialize, Debug, Deserialize)]
pub struct BootConfig { pub struct KernelConfig {
pub logging_level: LogLevel, pub boot: BootConfig,
pub logger_padding: usize, pub logging: LoggingConfig,
pub run_tests: bool, pub tests: TestsConfig,
pub run_demos: bool,
pub run_shader_tests: bool,
} }
impl BootConfig { impl KernelConfig {
pub fn new() -> Self { pub fn new() -> Self {
let data = include_str!("../assets/kernel_config.json"); toml::from_str(include_str!("../assets/kernel.toml")).unwrap()
// 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,
@ -51,3 +41,28 @@ impl BootConfig {
} }
} }
} }
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>,
}

View file

@ -0,0 +1,29 @@
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!()
}
}

View file

@ -0,0 +1,49 @@
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()
}

View file

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

View file

@ -0,0 +1,5 @@
pub mod dev_null;
pub mod dev_unicode;
pub mod dev_zero;
pub use kernel::device_interface::character::CharacterDevice;

View file

@ -0,0 +1,264 @@
// ! 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
}
}

14
ableos/src/devices/id.rs Normal file
View file

@ -0,0 +1,14 @@
#[derive(Debug)]
pub enum Vendor {
Unknown = 0,
Ati = 1002,
}
pub fn match_vendor(id: u16) -> Vendor {
use Vendor::*;
match id {
1002 => Ati,
_ => Unknown,
}
}

58
ableos/src/devices/mod.rs Normal file
View file

@ -0,0 +1,58 @@
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()
}
}

View file

@ -0,0 +1,55 @@
//! 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() {}

View file

@ -1,4 +0,0 @@
pub trait Device {
fn probe();
fn reset();
}

View file

@ -1,16 +1,21 @@
#![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,
@ -22,13 +27,8 @@ 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);

View file

@ -1,5 +1,3 @@
// TODO: Bitmasking // TODO: Bitmasking
pub enum Mouse { pub enum Mouse {
Button1, Button1,

View file

@ -1,4 +1,37 @@
pub trait Serial { use kernel::device_interface::character::CharacterDevice;
fn print();
fn recieve(); pub struct Serial {
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');
} }

View file

@ -1,67 +1,107 @@
use crate::{ use logos::{Lexer, Logos};
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))
}

View file

@ -1,20 +1,13 @@
use alloc::{string::String, vec, vec::Vec}; use alloc::{string::String, vec, vec::Vec};
// use crate::String;
// use crate::Vec; pub static CLIPBOARD: spin::Mutex<Clipboard> = spin::Mutex::new(Clipboard::new());
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
@ -25,30 +18,36 @@ pub struct Clipboard {
pub index: usize, pub index: usize,
pub pages: Vec<Mime>, pub pages: Vec<Mime>,
} }
impl Clipboard { impl Clipboard {
pub fn new() -> Clipboard { pub const 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 {
let paste_pos = &self.pages[self.index]; &self.pages[self.index] as _
paste_pos
} }
} }

View file

@ -1,11 +1,6 @@
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) {
@ -23,9 +18,8 @@ impl AtomicU32 {
} }
} }
/* /*
// SUPER HANDWAVEY
SUPER HANDWAVEY // YOU WILL NEED LOCKING THAT I DIDNT WRITE OUT (you == zuurr#9735)
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) {
@ -46,7 +40,6 @@ pub fn futex_wake(atom: &AtomicU32, threads_to_wake: usize) {
waiting_thread.wake() waiting_thread.wake()
} }
} }
*/ */
struct FutexWaitlist { struct FutexWaitlist {

View file

@ -1,34 +1,74 @@
// Can be standardized use super::systeminfo::SystemMemory;
// NOTE: Move this to relib use crate::{arch::drivers::sysinfo::master, ALLOCATOR};
pub struct SemanticVersion { use core::fmt::Display;
pub major: u8, use versioning::Version;
pub minor: u8, use x86_64::instructions::interrupts::{disable, enable};
pub patch: u8,
pub enum CpuType {
RiscV(String),
X86_64(String),
} }
impl core::fmt::Display for SemanticVersion { impl Display for CpuType {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "v{}.{}.{}", self.major, self.minor, self.patch) write!(
f,
"{}",
match self {
CpuType::RiscV(s) => s,
CpuType::X86_64(s) => s,
}
)
} }
} }
// NOTE: Move to somewhere else
lazy_static! {
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: SemanticVersion, pub kernel_version: Version,
// cpu: String, pub cpu: CpuType,
// gpu: String, // gpu: String,
pub memory: SystemMemory, pub memory: SystemMemory,
} }
use super::systeminfo::SystemMemory;
use lazy_static::lazy_static; 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
)
}
}

View file

@ -5,6 +5,7 @@ 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 {
@ -12,15 +13,18 @@ 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 => {
@ -101,3 +105,9 @@ impl MailBoxes {
); );
} }
} }
impl Default for MailBoxes {
fn default() -> Self {
Self::new()
}
}

View file

@ -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");

View file

@ -5,4 +5,3 @@ pub struct Notification {
text_body: String, text_body: String,
time: u64, time: u64,
} }
impl Notification {}

View file

@ -1,8 +1,9 @@
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,

View file

@ -1,10 +1,13 @@
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 // put data in the servers outbox
fn send(); fn send();
// put data in the servers inbox and notify it // put data in the servers inbox and notify it
fn recieve(); fn recieve();
} }

View file

@ -1,36 +1,6 @@
// 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
@ -38,3 +8,14 @@ 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)
}
}

View file

@ -4,4 +4,4 @@ pub struct Scheduler {
executables: usize, executables: usize,
} }
pub struct RunQueue {} pub struct RunQueue;

View file

@ -1,7 +1,12 @@
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()
} }
} }

View file

@ -1,3 +1,3 @@
//! //!
pub mod window;
pub mod compositor; pub mod compositor;
pub mod window;

View file

@ -1,19 +1,17 @@
use crate::driver_traits::graphics::Point; use crate::driver_traits::graphics::Point;
use alloc::string::String; pub type MenuBar = Vec<MenuOption>;
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 {

View file

@ -1 +0,0 @@

View file

@ -0,0 +1,42 @@
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()
}

View file

@ -1,23 +1,18 @@
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; use spin::Lazy;
use vga::writers::GraphicsWriter;
#[derive(Debug)] pub static SCREEN_BUFFER: Lazy<spin::Mutex<ScreenBuffer>> =
pub struct ScreenSize { Lazy::new(|| spin::Mutex::new(ScreenBuffer::new(640, 480)));
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;
lazy_static::lazy_static! { #[derive(Debug)]
pub static ref SCREEN_BUFFER: spin::Mutex<ScreenBuffer> = spin::Mutex::new(ScreenBuffer::new(640, 480)); pub struct ScreenSize {
pub x: usize,
pub y: usize,
} }
impl ScreenSize { impl ScreenSize {
@ -34,7 +29,7 @@ pub enum GraphicsReturn {
pub struct ScreenBuffer { pub struct ScreenBuffer {
pub size: ScreenSize, pub size: ScreenSize,
pub clear_color: Rgba64, pub clear_color: Rgba64,
pub buff: Box<[Rgba64]>, // Vec<Rgba64>, pub buff: Box<[Rgba64]>,
} }
impl ScreenBuffer { impl ScreenBuffer {
@ -46,6 +41,7 @@ impl ScreenBuffer {
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) { pub fn draw_filled_circle(&mut self, cx: i32, cy: i32, radius: usize, color: Rgba64) {
let r = radius as i32 * 2; let r = radius as i32 * 2;
for y in 0..640 { for y in 0..640 {
@ -70,6 +66,7 @@ impl ScreenBuffer {
} }
pub fn blit(&mut self, _width: usize, _height: usize) {} 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) { pub fn draw_filled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) {
for y in y1..y2 { for y in y1..y2 {
for x in x1..x2 { for x in x1..x2 {
@ -126,8 +123,7 @@ impl ScreenBuffer {
// TODO force clear // TODO force clear
pub fn force_redraw(&mut self) { pub fn force_redraw(&mut self) {
use shadeable::pixel_format::into_vga_16; // VGAE.lock().clear_screen(vga::colors::Color16::Black);
VGAE.lock().clear_screen(into_vga_16(self.clear_color));
} }
/// Draw a glyph on the screen at the given position /// Draw a glyph on the screen at the given position
@ -201,26 +197,6 @@ impl ScreenBuffer {
} }
} }
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 = 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);
@ -261,5 +237,6 @@ pub fn get_coordinates(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<(usize, usize)
current_y += sy; current_y += sy;
} }
} }
coordinates coordinates
} }

View file

@ -1,13 +1,10 @@
use alloc::string::{String, ToString}; use spin::Lazy;
use lazy_static::lazy_static;
lazy_static! { pub static KERNEL_STATE: Lazy<spin::Mutex<KernelInternalState>> =
pub static ref KERNEL_STATE: spin::Mutex<KernelInternalState> = Lazy::new(|| spin::Mutex::new(KernelInternalState::new()));
spin::Mutex::new(KernelInternalState::new());
}
pub struct KernelInternalState { pub struct KernelInternalState {
hostname: String, pub hostname: String,
should_shutdown: bool, should_shutdown: bool,
} }
@ -31,3 +28,9 @@ impl KernelInternalState {
} }
} }
} }
impl Default for KernelInternalState {
fn default() -> Self {
Self::new()
}
}

View file

@ -2,104 +2,382 @@ 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(
KeyCode::BackTick,
LayoutEntry::regular().unshifted('`').shifted('`'),
);
mapping.set(KeyCode::Escape, LayoutEntry::regular().unshifted('\x1B')); mapping.set(KeyCode::Escape, LayoutEntry::regular().unshifted('\x1B'));
mapping.set(KeyCode::Key0, LayoutEntry::regular().unshifted('0').shifted(')')); mapping.set(
mapping.set(KeyCode::Key1, LayoutEntry::regular().unshifted('1').shifted('!')); KeyCode::Key0,
mapping.set(KeyCode::Key2, LayoutEntry::regular().unshifted('2').shifted('@')); LayoutEntry::regular().unshifted('0').shifted(')'),
mapping.set(KeyCode::Key3, LayoutEntry::regular().unshifted('3').shifted('#')); );
mapping.set(KeyCode::Key4, LayoutEntry::regular().unshifted('4').shifted('$')); mapping.set(
mapping.set(KeyCode::Key5, LayoutEntry::regular().unshifted('5').shifted('%')); KeyCode::Key1,
mapping.set(KeyCode::Key6, LayoutEntry::regular().unshifted('6').shifted('^')); LayoutEntry::regular().unshifted('1').shifted('!'),
mapping.set(KeyCode::Key7, LayoutEntry::regular().unshifted('7').shifted('&')); );
mapping.set(KeyCode::Key8, LayoutEntry::regular().unshifted('8').shifted('*')); mapping.set(
mapping.set(KeyCode::Key9, LayoutEntry::regular().unshifted('9').shifted('(')); KeyCode::Key2,
mapping.set(KeyCode::Minus, LayoutEntry::regular().unshifted('-').shifted('_')); LayoutEntry::regular().unshifted('2').shifted('@'),
mapping.set(KeyCode::Equals, LayoutEntry::regular().unshifted('=').shifted('+')); );
mapping.set(
KeyCode::Key3,
LayoutEntry::regular().unshifted('3').shifted('#'),
);
mapping.set(
KeyCode::Key4,
LayoutEntry::regular().unshifted('4').shifted('$'),
);
mapping.set(
KeyCode::Key5,
LayoutEntry::regular().unshifted('5').shifted('%'),
);
mapping.set(
KeyCode::Key6,
LayoutEntry::regular().unshifted('6').shifted('^'),
);
mapping.set(
KeyCode::Key7,
LayoutEntry::regular().unshifted('7').shifted('&'),
);
mapping.set(
KeyCode::Key8,
LayoutEntry::regular().unshifted('8').shifted('*'),
);
mapping.set(
KeyCode::Key9,
LayoutEntry::regular().unshifted('9').shifted('('),
);
mapping.set(
KeyCode::Minus,
LayoutEntry::regular().unshifted('-').shifted('_'),
);
mapping.set(
KeyCode::Equals,
LayoutEntry::regular().unshifted('=').shifted('+'),
);
mapping.set(KeyCode::Backspace, LayoutEntry::regular().all('\x08')); mapping.set(KeyCode::Backspace, LayoutEntry::regular().all('\x08'));
mapping.set(KeyCode::Tab, LayoutEntry::regular().all('\x09')); mapping.set(KeyCode::Tab, LayoutEntry::regular().all('\x09'));
mapping.set(KeyCode::Q, LayoutEntry::alphabet().low('q').high('Q').raw_unicode('\u{0011}')); mapping.set(
mapping.set(KeyCode::W, LayoutEntry::alphabet().low('w').high('W').raw_unicode('\u{0017}')); KeyCode::Q,
mapping.set(KeyCode::E, LayoutEntry::alphabet().low('e').high('E').raw_unicode('\u{0005}')); LayoutEntry::alphabet()
mapping.set(KeyCode::R, LayoutEntry::alphabet().low('r').high('R').raw_unicode('\u{0012}')); .low('q')
mapping.set(KeyCode::T, LayoutEntry::alphabet().low('t').high('T').raw_unicode('\u{0014}')); .high('Q')
mapping.set(KeyCode::Y, LayoutEntry::alphabet().low('y').high('Y').raw_unicode('\u{0019}')); .raw_unicode('\u{0011}'),
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(
mapping.set(KeyCode::O, LayoutEntry::alphabet().low('o').high('O').raw_unicode('\u{000F}')); KeyCode::W,
mapping.set(KeyCode::P, LayoutEntry::alphabet().low('p').high('P').raw_unicode('\u{0010}')); LayoutEntry::alphabet()
mapping.set(KeyCode::A, LayoutEntry::alphabet().low('a').high('A').raw_unicode('\u{0001}')); .low('w')
mapping.set(KeyCode::S, LayoutEntry::alphabet().low('s').high('S').raw_unicode('\u{0013}')); .high('W')
mapping.set(KeyCode::D, LayoutEntry::alphabet().low('d').high('D').raw_unicode('\u{0004}')); .raw_unicode('\u{0017}'),
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(
mapping.set(KeyCode::H, LayoutEntry::alphabet().low('h').high('H').raw_unicode('\u{0008}')); KeyCode::E,
mapping.set(KeyCode::J, LayoutEntry::alphabet().low('j').high('J').raw_unicode('\u{000A}')); LayoutEntry::alphabet()
mapping.set(KeyCode::K, LayoutEntry::alphabet().low('k').high('K').raw_unicode('\u{000B}')); .low('e')
mapping.set(KeyCode::L, LayoutEntry::alphabet().low('l').high('L').raw_unicode('\u{000C}')); .high('E')
mapping.set(KeyCode::Z, LayoutEntry::alphabet().low('z').high('Z').raw_unicode('\u{001A}')); .raw_unicode('\u{0005}'),
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::R,
mapping.set(KeyCode::B, LayoutEntry::alphabet().low('b').high('B').raw_unicode('\u{0002}')); LayoutEntry::alphabet()
mapping.set(KeyCode::N, LayoutEntry::alphabet().low('n').high('N').raw_unicode('\u{000E}')); .low('r')
mapping.set(KeyCode::M, LayoutEntry::alphabet().low('m').high('M').raw_unicode('\u{000D}')); .high('R')
mapping.set(KeyCode::BracketSquareLeft, LayoutEntry::regular().unshifted('{').shifted('[')); .raw_unicode('\u{0012}'),
mapping.set(KeyCode::BracketSquareRight, LayoutEntry::regular().unshifted('}').shifted(']')); );
mapping.set(KeyCode::BackSlash, LayoutEntry::regular().unshifted('|').shifted('\\')); mapping.set(
mapping.set(KeyCode::SemiColon, LayoutEntry::regular().unshifted(';').shifted(':')); KeyCode::T,
mapping.set(KeyCode::Quote, LayoutEntry::regular().unshifted('\'').shifted('"')); 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::Enter, LayoutEntry::regular().all('\x0A'));
mapping.set(KeyCode::Comma, LayoutEntry::regular().unshifted(',').shifted('<')); mapping.set(
mapping.set(KeyCode::Fullstop, LayoutEntry::regular().unshifted('.').shifted('>')); KeyCode::Comma,
mapping.set(KeyCode::Slash, LayoutEntry::regular().unshifted('/').shifted('?')); 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::Spacebar, LayoutEntry::regular().all(' '));
mapping.set(KeyCode::Delete, LayoutEntry::regular().all('\x7F')); mapping.set(KeyCode::Delete, LayoutEntry::regular().all('\x7F'));
mapping.set(KeyCode::NumpadSlash, LayoutEntry::numpad().all('/')); mapping.set(KeyCode::NumpadSlash, LayoutEntry::numpad().all('/'));
mapping.set(KeyCode::NumpadStar, LayoutEntry::numpad().all('*')); mapping.set(KeyCode::NumpadStar, LayoutEntry::numpad().all('*'));
mapping.set(KeyCode::NumpadMinus, LayoutEntry::numpad().all('-')); mapping.set(KeyCode::NumpadMinus, LayoutEntry::numpad().all('-'));
mapping.set(KeyCode::Numpad7, LayoutEntry::numpad().low('7').high(KeyCode::Home)); mapping.set(
mapping.set(KeyCode::Numpad8, LayoutEntry::numpad().low('8').high(KeyCode::ArrowUp)); KeyCode::Numpad7,
mapping.set(KeyCode::Numpad9, LayoutEntry::numpad().low('9').high(KeyCode::PageUp)); 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::NumpadPlus, LayoutEntry::numpad().all('+'));
mapping.set(KeyCode::Numpad4, LayoutEntry::numpad().low('4').high(KeyCode::ArrowLeft)); mapping.set(
KeyCode::Numpad4,
LayoutEntry::numpad().low('4').high(KeyCode::ArrowLeft),
);
mapping.set(KeyCode::Numpad5, LayoutEntry::numpad().all('5')); 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::Numpad6,
mapping.set(KeyCode::Numpad2, LayoutEntry::numpad().low('2').high(KeyCode::ArrowDown)); LayoutEntry::numpad().low('6').high(KeyCode::ArrowRight),
mapping.set(KeyCode::Numpad3, LayoutEntry::numpad().low('3').high(KeyCode::PageDown)); );
mapping.set(KeyCode::Numpad0, LayoutEntry::numpad().low('0').high(KeyCode::Insert)); mapping.set(
mapping.set(KeyCode::NumpadPeriod, LayoutEntry::numpad().low('.').high('\x7F')); 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.set(KeyCode::NumpadEnter, LayoutEntry::numpad().all('\x0A'));
mapping mapping
} }
pub fn new_us105key() -> Self { pub fn new_us105key() -> Self {
let mut mapping = Self::new_us104key(); let mut mapping = Self::new_us104key();
mapping.set(KeyCode::BackTick, LayoutEntry::regular().unshifted('`').shifted('¬').altgr('|')); mapping.set(
mapping.set(KeyCode::Key2, LayoutEntry::regular().unshifted('2').shifted('"')); KeyCode::BackTick,
mapping.set(KeyCode::Quote, LayoutEntry::regular().unshifted('\'').shifted('@')); LayoutEntry::regular()
mapping.set(KeyCode::Key3, LayoutEntry::regular().unshifted('3').shifted('£')); .unshifted('`')
mapping.set(KeyCode::BackTick, LayoutEntry::regular().unshifted('4').shifted('$').altgr('€')); .shifted('¬')
mapping.set(KeyCode::HashTilde, 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 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,
@ -164,13 +442,3 @@ impl KeyboardLayout for CustomLayout {
} }
} }
} }
// 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;
}
}

View file

@ -1,20 +1,25 @@
use crate::{KeyCode, ScancodeSet, DecodeState, KeyEvent, Error, KeyState, keyboard::EXTENDED_KEY_CODE}; use crate::{
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
@ -179,6 +184,7 @@ impl CustomScancodeSet {
} }
scancode_set scancode_set
} }
pub fn scancode_set2() -> Self { pub fn scancode_set2() -> Self {
Self { Self {
single_byte: [None; 256], single_byte: [None; 256],
@ -186,6 +192,7 @@ impl CustomScancodeSet {
} }
} }
} }
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 {
@ -236,6 +243,7 @@ impl ScancodeSet for CustomScancodeSet {
} }
} }
} }
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)
@ -243,6 +251,7 @@ impl ScancodeSet for CustomScancodeSet {
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)

View file

@ -1,4 +1,4 @@
use super::DecodedKey; use crate::DecodedKey;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum LayoutEntryKind { pub enum LayoutEntryKind {
@ -32,6 +32,7 @@ impl LayoutEntry {
..Default::default() ..Default::default()
} }
} }
#[must_use] #[must_use]
pub fn numpad() -> Self { pub fn numpad() -> Self {
Self { Self {
@ -39,6 +40,7 @@ impl LayoutEntry {
..Default::default() ..Default::default()
} }
} }
#[must_use] #[must_use]
pub fn alphabet() -> Self { pub fn alphabet() -> Self {
Self { Self {
@ -46,56 +48,64 @@ impl LayoutEntry {
..Default::default() ..Default::default()
} }
} }
#[must_use] #[must_use]
pub fn unshifted(mut self, c: impl Into<DecodedKey>) -> Self { pub fn unshifted(mut self, c: impl Into<DecodedKey>) -> Self {
self.unshifted = Some(c.into()); self.unshifted = Some(c.into());
self self
} }
#[must_use] #[must_use]
pub fn shifted(mut self, c: impl Into<DecodedKey>) -> Self { pub fn shifted(mut self, c: impl Into<DecodedKey>) -> Self {
self.shifted = Some(c.into()); self.shifted = Some(c.into());
self self
} }
#[must_use] #[must_use]
pub fn altgr(mut self, c: impl Into<DecodedKey>) -> Self { pub fn altgr(mut self, c: impl Into<DecodedKey>) -> Self {
self.altgr = Some(c.into()); self.altgr = Some(c.into());
self self
} }
#[must_use] #[must_use]
pub fn raw_unicode(mut self, c: impl Into<DecodedKey>) -> Self { pub fn raw_unicode(mut self, c: impl Into<DecodedKey>) -> Self {
self.raw_unicode = 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 locked(mut self, c: impl Into<DecodedKey>) -> Self {
self.locked = Some(c.into()); self.locked = Some(c.into());
self self
} }
#[must_use] #[must_use]
pub fn locked_shifted(mut self, c: impl Into<DecodedKey>) -> Self { pub fn locked_shifted(mut self, c: impl Into<DecodedKey>) -> Self {
self.locked_shifted = Some(c.into()); self.locked_shifted = Some(c.into());
self self
} }
#[must_use] #[must_use]
pub fn common(self, c: impl Into<DecodedKey> + Clone) -> Self { pub fn common(self, c: impl Into<DecodedKey> + Clone) -> Self {
self self.unshifted(c.clone())
.unshifted(c.clone())
.shifted(c.clone()) .shifted(c.clone())
.locked(c.clone()) .locked(c.clone())
.locked_shifted(c) .locked_shifted(c)
} }
#[must_use] #[must_use]
pub fn low(self, c: impl Into<DecodedKey> + Clone) -> Self { pub fn low(self, c: impl Into<DecodedKey> + Clone) -> Self {
self.unshifted(c.clone()).locked_shifted(c) self.unshifted(c.clone()).locked_shifted(c)
} }
#[must_use] #[must_use]
pub fn high(self, c: impl Into<DecodedKey> + Clone) -> Self { pub fn high(self, c: impl Into<DecodedKey> + Clone) -> Self {
self.shifted(c.clone()).locked(c) self.shifted(c.clone()).locked(c)
} }
#[must_use] #[must_use]
pub fn all(self, c: impl Into<DecodedKey> + Clone) -> Self { pub fn all(self, c: impl Into<DecodedKey> + Clone) -> Self {
self self.unshifted(c.clone())
.unshifted(c.clone())
.shifted(c.clone()) .shifted(c.clone())
.locked(c.clone()) .locked(c.clone())
.locked_shifted(c.clone()) .locked_shifted(c.clone())

View file

@ -1,5 +1,3 @@
use super::*;
mod custom_layout; mod custom_layout;
mod custom_scancode_set; mod custom_scancode_set;
mod layout_entry; mod layout_entry;

View file

@ -1,13 +1,17 @@
#![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 KEYCODE_BITS: u8 = 11;
const EXTENDED_KEY_CODE: u8 = 0xE0; const EXTENDED_KEY_CODE: u8 = 0xE0;
const KEYCODE_BITS: u8 = 11;
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
@ -22,6 +26,7 @@ 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,
@ -47,14 +52,17 @@ 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.
@ -63,6 +71,7 @@ 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.
@ -74,6 +83,7 @@ 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
@ -81,6 +91,7 @@ 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.
@ -97,6 +108,7 @@ 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.
/// ///
@ -199,12 +211,15 @@ 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);
@ -222,9 +237,11 @@ 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"#

View file

@ -1,4 +1,5 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
#[derive(Debug)] #[derive(Debug)]
pub struct Modifiers { pub struct Modifiers {
pub lshift: bool, pub lshift: bool,
@ -9,17 +10,21 @@ pub struct Modifiers {
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 { pub fn is_caps(&self) -> bool {
self.capslock self.capslock
} }
} }
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum KeyState { pub enum KeyState {
Up, Up,
@ -30,11 +35,13 @@ 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
@ -45,6 +52,7 @@ pub enum HandleControl {
/// 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,
@ -52,6 +60,7 @@ pub enum DecodeState {
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 {
@ -61,6 +70,7 @@ pub enum Error {
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 {
@ -73,6 +83,7 @@ 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 {
@ -81,6 +92,7 @@ impl From<char> for DecodedKey {
} }
} }
} }
impl From<KeyCode> for DecodedKey { impl From<KeyCode> for DecodedKey {
fn from(kc: KeyCode) -> Self { fn from(kc: KeyCode) -> Self {
Self { Self {
@ -89,6 +101,7 @@ impl From<KeyCode> for DecodedKey {
} }
} }
} }
impl DecodedKey { impl DecodedKey {
pub const ZERO: Self = Self { pub const ZERO: Self = Self {
kind: DecodedKeyKind::Unicode, kind: DecodedKeyKind::Unicode,
@ -107,6 +120,7 @@ impl DecodedKey {
} }
} }
} }
macro_rules! keycode_enum { macro_rules! keycode_enum {
(@get_last $Variant:ident) => { (@get_last $Variant:ident) => {
Self::$Variant Self::$Variant
@ -134,6 +148,7 @@ 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,

View file

@ -1,13 +1,18 @@
use super::*; use super::Error;
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

View file

@ -1,105 +1,52 @@
#![allow(clippy::empty_loop)] #![allow(clippy::empty_loop)]
use { use crate::arch::drivers::sysinfo::master;
crate::{ use crate::scheduler::SCHEDULER;
use crate::{
arch::{init, sloop}, arch::{init, sloop},
boot_conf,
boot_conf::BootConfig,
capabilities::FileAccess,
experiments::{
info::master,
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
},
file::PathRep,
relib::network::socket::{SimpleSock, Socket}, relib::network::socket::{SimpleSock, Socket},
scheduler::SCHEDULER, scratchpad,
VgaBuffer, SCREEN_BUFFER,
},
alloc::{
format,
string::{String, ToString},
vec,
},
core::sync::atomic::{AtomicU64, Ordering::*},
facepalm::start_facepalm,
lazy_static::lazy_static,
log::*,
shadeable::pixel_format::from_vga_16,
vga::colors::Color16,
}; };
use crate::{boot_conf::KernelConfig, systeminfo::RELEASE_TYPE};
use kernel::KERNEL_VERSION;
use spin::Lazy;
lazy_static! { // TODO: Change this structure to allow for multiple cores loaded
pub static ref TICK: AtomicU64 = AtomicU64::new(0); pub static KERNEL_CONF: Lazy<KernelConfig> = Lazy::new(KernelConfig::new);
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 {
{ log::set_max_level(KERNEL_CONF.log_level());
let mut scheduler = SCHEDULER.lock(); } else {
log::set_max_level(log::LevelFilter::Off);
use crate::scheduler::Priority::*;
let mut process_1 = scheduler.new_process(High);
process_1.capabilities.files = FileAccess::Some(vec![PathRep {
location: FileLocations::Home,
file_name: "test".to_string(),
}]);
scheduler.add_process(process_1);
for ref_process in &scheduler.list {
trace!("{:?}", ref_process);
} }
let scheduler = SCHEDULER.lock();
for proc in &scheduler.execution_queue {
trace!("{:?}", proc);
}
drop(scheduler); drop(scheduler);
}
use crate::proto_filetable::file::FileLocations; // start_facepalm();
scratchpad();
{
let mut sock_print_id = SimpleSock::new();
sock_print_id.register_protocol("Screen Printer".to_string());
sock_print_id.write(format!("🐑").into());
let mut mode = SCREEN_BUFFER.lock();
mode.force_redraw();
for current in (*String::from_utf8_lossy(&sock_print_id.peek().unwrap())).chars() {
mode.draw_char(0, 0, current, from_vga_16(Color16::Red));
}
mode.copy_to_buffer();
}
}
start_facepalm();
sloop() 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()

View file

@ -4,89 +4,82 @@
//! //!
#![no_std] #![no_std]
#![feature( #![feature(abi_x86_interrupt)]
abi_x86_interrupt, #![feature(alloc_error_handler)]
asm_sym, #![feature(prelude_import)]
alloc_error_handler, #![feature(asm_sym)] // Needed for riscv
core_intrinsics, #![feature(naked_functions)]
exclusive_range_pattern,
lang_items, #[macro_use]
naked_functions, pub extern crate log;
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 x86_64.
#[cfg(target_arch = "x86_64")]
#[path = "arch/x86_64/mod.rs"]
pub mod arch;
/// Contains architecture specific code for riscv64. /// Contains architecture specific code for riscv64.
#[cfg(target_arch = "riscv64")] #[cfg(target_arch = "riscv64")]
#[path = "arch/riscv/mod.rs"] #[path = "arch/riscv/mod.rs"]
pub mod arch; pub mod arch;
/// Contains architecture specific code for x86_64.
#[cfg(target_arch = "x86_64")]
#[path = "arch/x86_64/mod.rs"]
pub mod arch;
#[cfg(target_arch = "x86_64")]
pub mod port_io;
#[macro_use] #[macro_use]
pub mod print; pub mod print;
#[macro_use] #[macro_use]
pub extern crate log; pub mod serial_print;
/////////////
// 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 panic; pub mod prelude;
pub mod proto_filetable;
pub mod relib; pub mod relib;
pub mod rhai_shell;
pub mod scheduler; pub mod scheduler;
mod unicode_utils; pub mod scratchpad;
pub mod stdio;
pub mod time;
pub mod utils; pub mod utils;
pub mod vga_e; pub mod virtio;
pub mod wasm; pub mod wasm;
pub mod wasm_jumploader;
pub extern crate alloc; mod unicode_utils;
pub extern crate externc_libm as libm;
#[prelude_import]
pub use prelude::rust_2021::*;
//////////////////
// 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 scheduler::*; pub use scratchpad::*;
pub use utils::*; pub use utils::*;
pub use vga_e::*;
pub use wasm::*;
//////////////////
pub mod virtio;
pub use virtio::*; pub use virtio::*;
pub use wasm::*;
pub mod alias_table;
pub use alias_table::*;
pub mod tests;
pub use tests::*;
pub mod syscalls;
pub use syscalls::*;

View file

@ -1,34 +1,42 @@
use core::sync::atomic::Ordering; use crate::kmain::KERNEL_CONF;
use crate::network::socket::{SimpleSock, Socket};
use crate::kmain::TICK; use crate::time::fetch_time;
use crate::serial_println;
use lliw::{Fg, Reset}; use lliw::{Fg, Reset};
pub use log::{debug, info, trace, warn};
use log::{Level, Metadata, Record}; use log::{Level, Metadata, Record};
use log::{LevelFilter, SetLoggerError};
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 color; let time_float = fetch_time();
let time = TICK.load(Ordering::Relaxed) as f64;
let time_float = time / TIMER_INTERRUPT_HERTZ; let color = match record.level() {
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$"),
};
match record.level() { let msg = format!(
log::Level::Error => color = (Fg::Red, "$RED$"), "[{}{}$RESET$][$GREEN${}$RESET$]{}\n",
log::Level::Warn => color = (Fg::LightYellow, "$LIGHTYELLOW$"), color.1,
log::Level::Info => color = (Fg::LightWhite, "$LIGHTGRAY$"), record.level(),
log::Level::Debug => color = (Fg::Blue, "$BLUE$"), time_float,
log::Level::Trace => color = (Fg::Yellow, "$YELLOW$"), record.args()
} );
// kprint!("{}", msg);
// NOTE: This needs to be fixed before merge
if KERNEL_CONF.logging.log_to_serial {
// #[track_caller]
serial_println!( serial_println!(
"[{}{}{}][{}{}{}] {}", "[{}{}{}][{}{}{}] {}",
@ -38,18 +46,23 @@ impl log::Log for SimpleLogger {
Fg::Green, Fg::Green,
time_float, time_float,
Reset, Reset,
record.args(), 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))
} }

View file

@ -1,22 +0,0 @@
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!");
}

17
ableos/src/port_io.rs Normal file
View file

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

View file

@ -0,0 +1 @@
pub mod rust_2021;

View file

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

View file

@ -1,5 +1,10 @@
pub struct Stdout; // TODO: refactor this file
// TODO: make STDOUT redirect to a socket owned
// by the process named "stdout"
use core::fmt::{Arguments, Error}; use core::fmt::{Arguments, Error};
pub struct Stdout;
impl Stdout { impl Stdout {
pub fn write_fmt(&mut self, arg: Arguments<'_>) /*-> Result<(), Error> */ pub fn write_fmt(&mut self, arg: Arguments<'_>) /*-> Result<(), Error> */
{ {
@ -7,33 +12,31 @@ 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::experiments::absi::colorify; use crate::kprint;
colorify(s); kprint!("{}", 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 {
() => { () => {
@ -45,12 +48,7 @@ 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![];
}; };
} }

View file

@ -1,5 +0,0 @@
use crate::ProtoFileTable;
lazy_static::lazy_static!(
pub static ref FILE_TABLE: spin::Mutex<ProtoFileTable> = spin::Mutex::new(ProtoFileTable::new());
);

View file

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

View file

@ -1,61 +0,0 @@
//! 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;

View file

@ -1,16 +0,0 @@
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()
);
}

View file

@ -1,15 +1,6 @@
use alloc::{ /// # clparse
string::{String, ToString}, /// simple command line parser for ableOS
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,
@ -25,25 +16,22 @@ 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 subcommand in split_command { for (root_count, subcommand) in split_command.enumerate() {
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 = "";
let mut arg_count = 0; for (n, arg) in subarg.split('=').enumerate() {
for arg in subarg.split("=") { if n == 0 {
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(),
@ -54,7 +42,6 @@ impl Command {
} }
_ => {} _ => {}
} }
root_count += 1;
} }
Command { Command {
@ -63,6 +50,7 @@ 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());

View file

@ -1,6 +1,3 @@
use alloc::{boxed::Box};
pub struct BinCodeWriter { pub struct BinCodeWriter {
pub stream: Box<u8>, pub stream: Box<u8>,
} }

View file

@ -1,14 +1,9 @@
use alloc::vec;
use alloc::vec::Vec;
pub fn encode(bytes: &[u8]) -> Vec<u8> { pub fn encode(bytes: &[u8]) -> Vec<u8> {
let mut encoding; let mut encoding = if bytes.first().is_none() {
if bytes.first().is_none() {
return vec![]; return vec![];
} else { } else {
encoding = vec![*bytes.first().unwrap()]; vec![*bytes.first().unwrap()]
} };
let mut occurrences = 1; let mut occurrences = 1;
@ -22,13 +17,12 @@ 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();

View file

@ -1,3 +1 @@
pub mod mono_bitmap; pub mod mono_bitmap;
pub mod stupid_simple_image;

View file

@ -1,10 +1,8 @@
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 super::qoi; use shadeable::pixel_format::new_rgba64;
pub fn bruh() { pub fn bruh() {
#[rustfmt::skip] #[rustfmt::skip]

View file

@ -1,6 +0,0 @@
/*
r[255,0,0]
g[0,0,0]
b[0,0,0]
a[0,0,0]
*/

View file

@ -1,7 +1,6 @@
use alloc::string::String; pub static SOCKETS: spin::Mutex<SocketState> = spin::Mutex::new(vec![]);
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)]
@ -11,12 +10,7 @@ pub struct SocketID {
impl SocketID { impl SocketID {
pub fn protocol(self) -> Option<String> { pub fn protocol(self) -> Option<String> {
let x = SOCKETS.lock()[self.id].protocol.clone(); SOCKETS.lock()[self.id].protocol.clone()
match x {
Some(protocol_name) => Some(protocol_name),
None => None,
}
} }
} }
@ -41,11 +35,6 @@ 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;
@ -58,6 +47,7 @@ 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),
@ -120,10 +110,11 @@ 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.clone()); return_vec.push(*x);
} }
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() {
@ -136,9 +127,11 @@ 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;
@ -146,11 +139,13 @@ 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) {}
} }

View file

@ -1,8 +1,27 @@
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;
@ -36,37 +55,23 @@ 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