2756 Commits

Author SHA1 Message Date
vasilito a240e73e44 0.3.0: refresh Cargo.lock for latest compatible dependencies 2026-07-06 20:41:35 +03:00
vasilito ec8e88c364 0.3.0: kernel build fixes - syscall aliases and FADT length type cast
- Add SYS_OPENAT/SYS_DUP aliases in local syscall fork for upstream 0.9.0 renamed constants.

- Cast FADT_MIN_SIZE_ACPI_2_0 to u32 to match sdt.length() return type.

- Keep Cargo.lock based on upstream master with only redox_syscall sourced from local fork.
2026-07-06 18:57:41 +03:00
vasilito ca67b1da37 0.3.0: converge kernel onto upstream master
- Rebase all Red Bear kernel changes onto upstream master (4d5d36d4).
- Update version to 0.5.12+rb0.3.0 and add Red Bear author attribution.
- Switch redox_syscall direct dependency to local fork path (../syscall).
- Bump rust-toolchain.toml to nightly-2026-05-24.
- Regenerate Cargo.lock for +rb0.3.0 suffixes and path deps.
2026-07-06 18:43:52 +03:00
R Aadarsh 4d5d36d44e Extract code that is common to both x86 and ARM to srat::init 2026-07-05 20:16:00 +05:30
R Aadarsh 35340a80c4 * Add ACPI-NUMA parsing code for ARM
* Fix bug in the x86 code that caused incorrect cpu-node mapping

* Remove the usage of page mappers. Instead use the already existing
  linear mapping
2026-07-05 15:01:48 +05:30
R Aadarsh cb88ed59a2 Parse ACPI tables for NUMA information without allocating from the heap 2026-07-03 20:19:46 +05:30
Wildan M 372cd19b6f Remove irq from handles on close 2026-07-02 08:41:11 +07:00
R Aadarsh aa7e7d2f44 Fix the bug in RxsdtIter that caused u32 pointers to be used regardless of ACPI table kind 2026-07-01 10:36:07 -06:00
R Aadarsh a03c545f3c Fix build failure for ARM 2026-07-01 10:36:07 -06:00
R Aadarsh a2a3df33c6 Split acpi::init to perform two stage initialisation 2026-07-01 10:36:07 -06:00
Ibuki Omatsu 6c3d5d28c6 refactor: Move fd allocation logic into userspace 2026-07-01 08:02:47 -06:00
R Aadarsh 8171dc616b Fix panic due to using uninitialised NUMA_NODES 2026-06-21 14:30:07 +05:30
R Aadarsh 2ad76496c4 * Store addresses as pointers
* Remove lots of unsafe code by initialising in the closure passed to
  `call_once`

* Remove `NUMBER_OF_DOMAINS` as size can always be inferred from the
  hashmap's len
2026-06-21 14:03:49 +05:30
R Aadarsh 4106dcbbfa Gate behind a feature flag 2026-06-21 14:03:49 +05:30
R Aadarsh 969c905d8e Account for the case when distance information is not available 2026-06-21 14:03:49 +05:30
R Aadarsh 9ecc75029c * Correctly put cpus and memories for adoption
* Test on x86_64 (works)
2026-06-21 14:03:49 +05:30
R Aadarsh 16c59588b0 * Fix endianness
* Remove ITS affinity and numa
2026-06-21 14:03:49 +05:30
R Aadarsh ee2a61088e * Parse SLIT for distance information
* Order by distance, reorganise domains into nodes
2026-06-21 14:03:49 +05:30
R Aadarsh 63d1171ffb Initial commit 2026-06-21 14:03:49 +05:30
Wildan M 002fff546d Clear cloexec flag on Dup2 2026-06-20 06:35:01 +07:00
Wildan M ed31b800c4 Revert "Use weak context for Proc" 2026-06-19 17:36:41 +07:00
Wildan M 622a4fb3cd Solve context leak when switching 2026-06-19 17:33:46 +07:00
Wildan M 101f090ef9 Fmt 2026-06-19 16:50:14 +07:00
Akshit Gaur b93260ed2d Migrating run_queue to BTreeMap 2026-06-18 10:39:33 +05:30
4lDO2 56947e1a0f Revert drop of kstack in exit_this_context. 2026-06-04 13:37:57 +02:00
4lDO2 bd6d9acd3c Compile on other arches. 2026-06-03 19:06:12 +02:00
4lDO2 c27568e1fe profiling: allow walking across syscall boundaries 2026-06-03 19:01:35 +02:00
4lDO2 42613ddc06 WIP: simultaneous NMI-based user+kernel profiling. 2026-06-03 19:01:35 +02:00
R Aadarsh f8bc19747a Make necessary changes to the kernel in order for relibc to support posix_spawn and posix_spawnp
* `syscall::sendfd`, now, when called with a `ContextHandle::FileTable` adds the fd to the filetable removing it from the calling process's filetable

* Files can now be added to, removed from another process, and can be duplicated using `ProcScheme::kcall`

* Files of another process with the flag O_CLOEXEC can now be closed by using `kcall`
2026-06-03 15:29:02 +05:30
4lDO2 8011f3f648 Simplify acpi scheme. 2026-06-02 16:23:08 +02:00
4lDO2 6fc2d32497 Remove redundant methods from KernelScheme. 2026-06-02 11:24:37 +02:00
4lDO2 da3d235af5 remove syscall debug for removed syscalls 2026-06-02 11:24:37 +02:00
4lDO2 3e210ff169 Remove 5 obsolete syscalls. 2026-06-02 11:24:37 +02:00
Wildan M 8701e8165b Fix compilation for aarch64 after rust update 2026-05-31 06:55:02 +07:00
4lDO2 cee451af38 Use ArrayVec for kcall fd nums, 8% better perf! 2026-05-31 20:24:57 +02:00
Wildan M 973ac667e3 Use syscall time helper functions 2026-05-30 12:29:38 +07:00
Wildan M a47b3a8d57 Add timeout for events 2026-05-30 13:44:31 -06:00
Wildan M ec1395b554 Wrap unmap loop with handle_notify_files 2026-05-30 08:40:49 -06:00
Akshit Gaur 58283f63fe EEVDF 2026-05-30 08:39:48 -06:00
Ibuki Omatsu e847768f2b feat: Implement multiple fds variant for call and std_fs_call 2026-05-29 13:07:36 +02:00
bjorn3 91ab8301f2 Fix warnings after updating rustc
Couple of features got stabilized, cpuid was made safe and there is a
new lint for function item to integer casts.
2026-05-27 20:53:10 +02:00
Jeremy Soller d254309fdb Support nightly 2026-05-24 2026-05-25 17:41:48 -06:00
Wildan M f70905d439 Resolve warnings 2026-05-23 00:04:34 +07:00
Wildan M 40e76875d7 Prevent kstack from leaking 2026-05-20 13:35:47 +07:00
Wildan M 805f921e10 Use weak context for Proc and Futex 2026-05-20 12:57:37 +07:00
Wildan M 7c653c5182 Possible fix to race condition to EBADF 2026-05-15 22:46:03 +07:00
Wildan M 8c9def2d73 Lazily clean up futex 2026-05-13 20:49:02 +07:00
Wildan M ff11f47404 Add futex, pipe, timeout subscribers 2026-05-13 10:46:38 +07:00
Wildan M bd44956e96 Capture event stat, change stat source for contexts 2026-05-12 12:24:49 +07:00
Wildan M 97bd0fb4a6 Don't compare QueueKey data to fix epoll ctl del 2026-05-10 17:33:04 +07:00
bjorn3 3dab161d30 Copy the flags set from physmap MemoryType over on scheme mmap
Propagating flags like uncachable or writecombining is necessary both
for correctness and for performance.
2026-05-06 21:05:16 +02:00
Speedy_Lex 678a8c5631 Fail softly on bad RSDP 2026-05-05 19:35:33 +02:00
Speedy_Lex 6b55ffea38 Make rsdp pointer NonNull 2026-05-05 19:35:33 +02:00
Speedy_Lex 6af9afb75d Fix check
Co-Author: 4lDO2
2026-05-05 19:35:33 +02:00
Speedy_Lex 6e539f9cd9 Fix bit check in src/profiling.rs 2026-05-05 19:35:33 +02:00
Speedy_Lex f49c7d991a RSDP validation and fixing a few clippy lints 2026-05-05 19:35:31 +02:00
Wildan M 51f32e9edb Allow cd to sys scheme 2026-05-02 18:25:44 +07:00
Wildan M 85c98314a9 Unwrap select_next_context result 2026-05-02 06:23:13 -06:00
Wildan M abb429d0c5 Revert "Split wait queue mutex" 2026-05-02 05:55:27 +07:00
Wildan M a297bfcc82 Use smallvec for memory and notify_files 2026-04-30 22:00:35 +07:00
Wildan M 1070efaec8 Solve some lock ordering 2026-04-30 21:59:19 +07:00
Wildan M 3914801f1e Speed up vector removal 2026-04-30 21:59:19 +07:00
Wildan M 00232b456c Optimize new mmap grant 2026-04-30 11:12:01 -06:00
Wildan M fb137f8001 Avoid reaccessing AddrSpace when switching 2026-04-30 11:09:59 -06:00
Wildan M 844f393ae8 Downgrade context sigcontrol to read 2026-04-29 21:48:31 +07:00
Wildan M ba28216ae8 Downgrade locks to read 2026-04-29 21:26:44 +07:00
Wildan M ab08d47aa8 Add commented out switch debug print 2026-04-29 11:21:20 +07:00
Wildan M e7ac009f31 Fix deadlock on contended switch 2026-04-29 11:21:02 +07:00
Wildan M fd5a04a121 Use status helpers 2026-04-29 11:20:43 +07:00
Wildan M baf329c120 Fix dead contexts clobber idle pools 2026-04-29 11:20:21 +07:00
Wildan M 866dfad0af Lower WaitQueue incoming lock level 2026-04-27 06:51:45 -06:00
Wildan M b8615790ea Lock wait queue together when receive_into_user 2026-04-27 06:51:45 -06:00
Wildan M 746c158465 Split wait queue mutex 2026-04-27 06:51:45 -06:00
Wildan M b3a6154445 Move dst_space_lock lower to Solve AddrSpaceWrapper lock 2026-04-27 06:50:20 -06:00
Wildan M 8dcb508413 Make AddrSpaceWrapper lock lower without solving borrow checker 2026-04-27 06:50:20 -06:00
Wildan M 2bca47923c Avoid reaccessing AddrSpace when switching 2026-04-27 02:18:42 +07:00
Wildan M c2b20abc03 Avoid locking current context on capture_inner 2026-04-27 01:54:43 +07:00
Wildan M e9f50698dd Remove ContextRef upgrade 2026-04-26 15:37:40 +07:00
Wildan M 2df7467d13 Use weak ContextRef for run contexts 2026-04-26 12:08:24 +07:00
Wildan M ea1d915bbc Make wake up optional 2026-04-26 07:15:10 +07:00
Wildan M 643726852b Reduce deadlock cap 2026-04-26 06:49:55 +07:00
Wildan M 0534ab6377 Replace enqueue with dedicated idle contexts 2026-04-26 06:49:55 +07:00
Wildan M de7926e05e Do not push idle context to queue 2026-04-26 06:49:54 +07:00
Wildan M 7adceb6e80 Add idle context 2026-04-26 06:49:54 +07:00
bjorn3 7827cb6c78 Unify context list again now that we have a run queue
This simplifies code and ensures that exiting a context will properly
remove it from the list of contexts.
2026-04-26 06:49:54 +07:00
Wildan M af1bc5d5e2 Fix relibc CI 2026-04-25 09:48:34 -06:00
Wildan M 58660a9170 Handle AddrSpace munmap 2026-04-24 17:52:05 +07:00
Wildan M f773d3e50d don't loop from idle to kernel context 2026-04-23 16:40:12 +07:00
Wildan M 8262fa7da9 Don't account idle time 2026-04-23 16:33:15 +07:00
Wildan M 2ca610193b Add kernel version to relibc CI test 2026-04-20 10:50:42 +07:00
Wildan Mubarok df07d65c05 Apply 1 suggestion(s) to 1 file(s)
Co-authored-by: bjorn3 <4397-bjorn3@users.noreply.gitlab.redox-os.org>
2026-04-19 08:46:05 -06:00
Wildan M bbfbe30445 Exclude PhysBorrowed from counting shared memory 2026-04-19 08:46:05 -06:00
Wildan M aee49d747a Update relibc test in CI 2026-04-19 16:52:29 +07:00
aarch e80379e6c6 Actually switch to Sv39 2026-04-18 18:49:21 +02:00
aarch f7c48049f5 RISCV64: Change VA scheme to Sv39 for real hardware support + Sv57 definitions 2026-04-18 09:46:34 -06:00
bjorn3 30b967022f Fix a couple of warnings 2026-04-17 20:20:16 +02:00
Akshit Gaur 976756991a Deficit Weighted Round Robin Scheduler 2026-04-17 06:52:03 -06:00
Wildan M 4531e15ba1 Add shared memory stats to contexts 2026-04-16 09:53:30 +07:00
bjorn3 219d707362 Introduce HandleMap helper type 2026-04-13 20:51:24 +02:00
bjorn3 f673afa839 Fix a duplicate log
This got moved into allocate, but forgot to save the change.
2026-04-13 20:22:18 +02:00
bjorn3 2174f86543 Fix debugger 2026-04-13 19:43:44 +02:00
bjorn3 4929783030 Improve fdstat 2026-04-13 19:43:44 +02:00
bjorn3 3a2200198a Always compile the code of sys_fdstat 2026-04-13 19:43:44 +02:00
bjorn3 3ff7872cd6 Fix warnings for sys_fdstat 2026-04-13 19:43:44 +02:00
bjorn3 38f36d406b Use cfg!() instead of #[cfg] for most profiling code
This makes it less likely that it breaks again in the future as most
code gets checked by the compiler even when profiling support is not
enabled.
2026-04-13 19:43:43 +02:00
Jacob Lorentzon 142871660e profiling: infer number of CPUs dynamically 2026-04-13 06:44:27 -06:00
bjorn3 2405a7ebb3 Move kmain and kmain_ap to startup/mod.rs 2026-04-12 18:41:00 +02:00
bjorn3 572bb4ce1f Avoid re-exporting arch specific modules in the crate root 2026-04-12 18:25:52 +02:00
Jacob Lorentzon 141c87650f Fix profiling and add check to CI 2026-04-12 06:51:26 -06:00
bjorn3 2f39aade30 Use mmap_anywhere in a couple of places 2026-04-10 20:23:01 +02:00
bjorn3 f792faf571 Avoid a Once for event::REGISTRY 2026-04-10 20:22:58 +02:00
bjorn3 a46f37976b Use div_ceil in LogicalCpuSet Display impl 2026-04-10 20:22:58 +02:00
bjorn3 aab33e46c3 Fix a couple of warnings 2026-04-10 20:22:26 +02:00
Wildan M 8f54fd8cb2 Fix displaying affinity in sys/context 2026-04-09 15:24:36 -06:00
bjorn3 654ee6ca3e size_of and align_of are part of the prelude nowadays 2026-04-09 15:23:34 -06:00
bjorn3 2e784dfe46 Remove unused feature gate 2026-04-09 15:23:34 -06:00
bjorn3 89a29f4e56 Reduce usage of wildcard imports 2026-04-09 15:23:34 -06:00
bjorn3 b0b0ec2d71 Deduplicate definition of FLAG_SINGLESTEP between x86 and x86_64 2026-04-09 15:23:34 -06:00
bjorn3 e98e12780e Inline BorrowedHtBuf::tail 2026-04-09 15:23:34 -06:00
bjorn3 bdf82a958a Use call instead of call_inner for fmap_inner 2026-04-09 15:23:34 -06:00
Wildan M cd3b18068f Improve mem precision in sys/context 2026-04-09 15:22:38 -06:00
Wildan M ce08b60502 Solve lock token and contexts for fdstat and debugger 2026-04-09 15:22:38 -06:00
Wildan M 0ad905f26e Fix sys stats to reveal contexts in all CPU 2026-04-09 15:22:38 -06:00
Speedy_Lex ee1260363c Fix many clippy lints 2026-04-08 19:40:41 +01:00
bjorn3 b7456d5bcc Avoid PHYS_OFFSET in dtb/serial.rs 2026-04-04 21:53:34 +02:00
bjorn3 d029ccfe20 Deduplicate a bunch of serial port initialization between arm64 and riscv 2026-04-04 16:36:30 +02:00
bjorn3 bbb9d98570 Unconditionally compile part of the DTB code 2026-04-04 14:01:19 +02:00
bjorn3 8eefc8a6a6 Remove unused dependency 2026-04-04 13:52:26 +02:00
bjorn3 f339467372 Remove dead_code lint allow for ACPI 2026-04-04 13:50:48 +02:00
bjorn3 62f220b1b9 Use cfg! rather than #[cfg] for ACPI enabling 2026-04-04 13:49:07 +02:00
bjorn3 49d005b450 Use RmmA::phys_to_virt instead of PHYS_OFFSET in the acpi code 2026-04-04 13:33:26 +02:00
bjorn3 2fba663274 Fix expect message 2026-04-04 13:14:14 +02:00
bjorn3 7aa7aa463f Use map_device_memory where possible 2026-04-04 13:10:05 +02:00
bjorn3 dee230ffca Use map_linearly in many places 2026-04-04 13:10:04 +02:00
bjorn3 a1b6bd965e Fix rmm example 2026-04-04 12:02:07 +02:00
bjorn3 50c68cd746 Remove ACPI search from the kernel
The bootloader provides the RSDP address to the kernel. If the
bootloader can't find it, there is no RSDP.
2026-04-04 11:50:24 +02:00
bjorn3 1352fafd00 Remove unused InactiveFlusher 2026-04-03 22:15:00 +02:00
bjorn3 ab4abf63c9 Deduplicate Page and other paging related things between architectures 2026-04-03 22:15:00 +02:00
bjorn3 b805336cfc Fix a bunch of warnings 2026-04-03 22:15:00 +02:00
bjorn3 3cbce1b9ac Move BSP_READY and AP_READY to platform-independent code 2026-04-02 20:29:36 +02:00
bjorn3 0f540e6f15 Don't physmap the kernel itself
We don't actually need to and this is a bit safer against memory corruption.
2026-04-02 20:29:36 +02:00
bjorn3 49eb21ce0e Use KERNEL_OFFSET from linker script 2026-04-02 20:29:36 +02:00
bjorn3 dc7e823f70 Deduplicate kernel page flags 2026-04-02 20:29:36 +02:00
bjorn3 980f1c6af8 Remove unused and deduplicate identical arch specific consts 2026-04-02 20:29:36 +02:00
bjorn3 10b1ae2ecc Remove unused arch consts 2026-04-02 20:29:36 +02:00
bjorn3 2ce7621a80 Fix a bunch of warnings masked by #[allow(unused)] 2026-04-02 20:29:36 +02:00
Wildan M d835a3d8f0 Solve all borrow checker leaving some violation 2026-04-01 08:42:18 -06:00
Wildan M a42ec44dbf Partially solve borrow rules 2026-04-01 08:42:18 -06:00
Wildan M 3161a44c25 Solve borrow rules for memory.rs 2026-04-01 08:42:18 -06:00
Wildan M 55e6fe9add Remove remnants of AddrSpace::used_by 2026-04-01 08:42:18 -06:00
Wildan M ca2a7048d0 Move spin loop hint to crate lock 2026-04-01 08:42:18 -06:00
Wildan M 3b5a0e4c60 Apply ordered lock to AddrSpaceWrapper without solving borrow checker 2026-04-01 08:42:18 -06:00
Wildan M 2989b5375f Add deadlock debug to AddrSpaceWrapper 2026-04-01 08:42:18 -06:00
Akshit Gaur 004509587d Fix ForceKill 2026-04-01 13:58:27 +05:30
Wildan M 6e0143cf0d Store context to per cpu 2026-03-31 15:29:47 +07:00
bjorn3 efa6b00189 rmm: Remove magic constants for x86 PAT indices 2026-03-30 22:18:10 +02:00
bjorn3 c8879531ae rmm: Add device_memory and uncachable flags to PageFlags 2026-03-30 20:34:45 +02:00
bjorn3 e311b41821 rmm: Make it a bit easier to change the MAIR_EL1 config on arm64 2026-03-30 20:34:45 +02:00
bjorn3 a5fd001dcb Use PageFlags::write_combining instead of custom flag 2026-03-30 20:34:45 +02:00
bjorn3 c0065bc893 rmm: Add some comments to init_pat 2026-03-30 20:34:44 +02:00
bjorn3 6b00f4ca25 Move MAIR_EL1 initialization to rmm
Rmm needs to know the exact MAIR_EL1 configuration to produce the
correct bits in the page table.
2026-03-30 19:26:41 +02:00
bjorn3 6e5c25b7a0 Move PAT initialization to rmm
Rmm needs to know the exact PAT configuration to produce the correct
bits in the page table.
2026-03-30 18:59:42 +02:00
bjorn3 c4b064ea44 Move arch specific EntryFlags into rmm 2026-03-30 18:49:15 +02:00
bjorn3 04645353f2 rmm: Fix EmulateArch compilation 2026-03-30 18:46:53 +02:00
bjorn3 8b217edac0 Fix two unsafe block related warnings 2026-03-30 18:42:38 +02:00
bjorn3 2fc2d5897a Fix a couple of unused import warnings 2026-03-30 18:38:25 +02:00
bjorn3 675ba2ea51 rmm: Make a couple more methods safe 2026-03-29 17:00:36 +02:00
bjorn3 c51aa1ef86 rmm: Make a couple of methods safe 2026-03-29 14:16:53 +02:00
bjorn3 a5aeea9cfc rmm: Remove PageMapper::{map,unmap}
There is already (un)map_phys.
2026-03-29 14:16:53 +02:00
bjorn3 a876d66648 rmm: Reduce visibility of PageTable methods
This disallows direct manipulation of the page tables. Only manipulation
through PageMapper is allowed.
2026-03-29 14:16:53 +02:00
bjorn3 abf710b4a2 Move handling of kernel page table entry copying to RMM
This way it can ensure those page table entries never get unmapped,
ensuring they are kept in sync between all processes.
2026-03-29 14:16:53 +02:00
bjorn3 604e1729cb Rustfmt 2026-03-29 14:16:53 +02:00
bjorn3 882007f827 Remove unused UserSlice::read_u64
This fixes a warning. It can always be re-introduced if we ever need it.
2026-03-29 14:16:36 +02:00
bjorn3 f5aff74fc9 Explicitly ignore field of PageQueueEntry::Other
This fixes a warning
2026-03-29 14:16:35 +02:00
bjorn3 b5603422be Check at compile time that KernelMapper is writable if necessary 2026-03-28 23:22:19 +01:00
bjorn3 0d578775f9 rmm: Indicate which PageMapper methods can allocate 2026-03-28 22:51:32 +01:00
bjorn3 d02312055e rmm: Couple of minor cleanups 2026-03-28 22:35:26 +01:00
bjorn3 3593c53146 rmm: Remove Arch::init
No architectures implement it.
2026-03-28 22:07:48 +01:00
bjorn3 db85237114 rmm: Partially hard code main.rs to EmulateArch 2026-03-28 22:06:24 +01:00
bjorn3 d06ade297d rmm: Remove fallback impl of invalidate_all
It doesn't work on all non-x86 architectures.
2026-03-28 22:02:34 +01:00
bjorn3 a913414c7f rmm: Nicer formatting of unsafe blocks 2026-03-28 22:00:43 +01:00
bjorn3 cc20bcd405 rmm: Fix warnings on x86 2026-03-28 21:57:51 +01:00
bjorn3 a3843f8fb5 rmm: Assert constants at compile time 2026-03-28 21:57:41 +01:00
bjorn3 5c480806be Add rmm to the workspace 2026-03-28 21:39:34 +01:00
bjorn3 ef508cc0ba Add 'rmm/' from commit 'e543cbe621b21875549c9d12a73810633f3d0c63'
git-subtree-dir: rmm
git-subtree-mainline: 76b0691e14
git-subtree-split: e543cbe621
2026-03-28 20:44:33 +01:00
bjorn3 76b0691e14 Remove rmm submodule 2026-03-28 20:43:48 +01:00
bjorn3 f8d93023dd Fix a couple of warnings 2026-03-28 17:07:33 +01:00
Philipp Bartsch 5865ec0790 /scheme/sys/cpu: Add aarch64 feature detection
This only lists features from ID_AA64ISAR0_EL1 and ID_AA64ISAR1_EL1.
For other features one would have to evaluate more registers.
2026-03-26 22:15:03 +01:00
Philipp Bartsch 2d5e2b39f5 Drop extra debug print 2026-03-26 00:49:33 +01:00
Philipp Bartsch a60cc25015 Update aarch64 implementers list
Two vendors were missing compared to ARM's official list.

https://developer.arm.com/documentation/ddi0601/2025-12/AArch64-Registers/MIDR-EL1--Main-ID-Register
2026-03-26 00:49:11 +01:00
Ron Williams fde164b2a0 Revert "Deficit based Weighted Round Robin Scheduler"
This reverts commit b7dabfc3c2.
2026-03-22 18:44:41 +00:00
Akshit Gaur b7dabfc3c2 Deficit based Weighted Round Robin Scheduler 2026-03-22 07:00:31 -06:00
Wildan M 74895c4f0f Fix ecpect file 2026-03-17 19:30:17 +07:00
Wildan M c70035865e Fix expect files 2026-03-17 19:24:10 +07:00
Wildan M 727f9658ed Fix CI sysroot 2026-03-17 18:57:21 +07:00
Wildan M bbcb3d19be Try using uname, fix relibc 2026-03-17 18:44:28 +07:00
Wildan M 65bd8e3264 Add boot check to CI 2026-03-17 18:32:51 +07:00
Wildan M 52d9fcc962 Try use relibc tests 2026-03-17 18:20:47 +07:00
Wildan M d317f84cd4 Change uname to kernel commit, Fix CI build 2026-03-17 17:51:29 +07:00
Connor-GH d81ba0645b /scheme/sys/uname: use commit hash instead of time for reproducibility 2026-03-15 17:21:46 -05:00
Connor-GH ea47151757 /scheme/sys/uname: include the "version" info
With this change, we use the recently-added `COOKBOOK_TIME_IDENT`
environment variable at compile time to get the "version" info for the
uname scheme. This field is unspecified by POSIX what it should have,
but most kernels (including Linux, XNU, NetBSD, etc.) put the build
time here.
2026-03-15 15:53:02 -05:00
Wildan M 44b6a58032 Add more context to deadlock debug messages 2026-03-14 08:49:40 -06:00
Ibuki.O 3934ea454d feat: Implement translation of std_fs_call to each function 2026-03-14 11:37:07 +09:00
Connor-GH 8f468ec106 syscall: remove comment about test vs bt x86 instructions
According to Agner Fog's documentation
(https://agner.org/optimize/instruction_tables.pdf), the following information
is true:

These instructions have identical latency and throughput, except for Zen
5, which lists `test` as having reciprocal throughput of 0.25 cycles,
and `bt` having reciprocal throughput of 0.33 cycles. This rules out the
`bt` instruction for being the ideal instruction.

The other `test` instructions were removed as candidates because,
regardless of the size of the memory fetched at the address, at least 64
bytes will need to be fetched because it will be stored in the cache
line. The WORD and DWORD cases can be ruled out because we cannot assume
that `rsp + 16` or `rsp + 17` will not be on a 64-byte alignment
boundary, which would cause two cachelines to be essentially filled with
garbage we don't care about. The best case scenario is that we only need
to fill one cache line with garbage, which is what the BYTE version does
every time.
2026-03-12 09:41:29 -05:00
Wildan M 84754dfc5d Solve borrow checking by downgrading waitqueue lock 2026-03-11 09:42:06 +07:00
Wildan M f07725682f Add ordered lock for WaitQueue mutex without solving borrow check 2026-03-11 09:24:45 +07:00
Wildan M 60573e24f3 Solve borrow checking by downgrading condition.wait lock 2026-03-11 09:07:52 +07:00
Wildan M 046c8ced0d Add lock token to pipe queue without solving borrow checker 2026-03-11 08:12:07 +07:00
Wildan M 7ebb5f2a3d Solve borrow checking by downgrading locks 2026-03-11 08:00:48 +07:00
Wildan M 44f2214971 Partially solve borrow checking with WaitQueue 2026-03-11 07:27:21 +07:00
Wildan M 771ebdb39f Partially solve borrow checking with PreemptGuard L1 2026-03-11 06:34:37 +07:00
Wildan M 73c2df9e33 Add lock token to user states, without solving borrow check 2026-03-10 23:56:15 +07:00
Wildan M eeb03bdcb1 Revert "Add ordered lock for WaitQueue mutex"
This reverts commit 735c68ec30.
2026-03-10 12:11:09 +07:00
Wildan M d5ed9d8007 Optimize context spawn and init 2026-03-10 05:59:35 +07:00
Wildan M c4e86bfffd Change time offset to RwLock 2026-03-10 05:58:26 +07:00
Wildan M 7fa253cf6a Add deadlock detection 2026-03-09 16:32:11 +07:00
Wildan M 6307446ede Solve borrow rules to LockedFdTbl 2026-03-09 15:57:38 +07:00
Wildan M 8412321568 Add lock token to FdTbl without borrow check 2026-03-09 13:12:19 +07:00
Wildan M 206f82709a Demote LockedFileDescription to solve borrow rules 2026-03-09 12:29:24 +07:00
Wildan M 8f270795da Partialy solve borrow checking 2026-03-09 11:47:07 +07:00
Wildan M f40b84a5cc Add lock token to FileDescription, without borrow check 2026-03-09 11:23:51 +07:00
bjorn3 6085c8935c Remove unused WaitQueue::receive method 2026-03-07 21:44:29 +01:00
bjorn3 6a10af6f77 Fully remove the broken support for unmounting schemes
It has been broken since we moved namespaces into userspace. Fixing it
can be done entirely inside userspace. Either by introducing a SYS_CALL
for the root capability or by treating closing the last fd as unmount.
2026-03-07 21:42:46 +01:00
Wildan M fd9c651410 Do not allocate on unneeded Vec 2026-03-07 09:15:20 -07:00
Wildan M 547722767a Optimize sys/stat a bit 2026-03-07 20:42:25 +07:00
Wildan M a5adc0cc69 Avoid heap allocation on event 2026-03-07 06:33:52 -07:00
bjorn3 4ccc521156 Show grant flags in the debugger 2026-03-07 12:19:40 +01:00
bjorn3 ea847f428f Fix compilation with the debugger feature enabled 2026-03-07 12:19:24 +01:00
auronandace 4c734e461a prefer saturating methods over direct arithetic 2026-03-05 10:58:45 +00:00
auronandace fc6ffd59ff avoid direct indexing in MemoryMap register function 2026-03-03 17:22:44 +00:00
auronandace 14b8c2b0c1 enforce two lints and collapse some ifs 2026-03-03 14:51:32 +00:00
auronandace f0f158e5d6 eliminate 2 unwraps in syscall fs 2026-03-02 17:11:51 -07:00
auronandace f7b0f5ec37 eliminate an unwrap in gdt for x86_shared 2026-03-02 10:56:28 +00:00
Ibuki Omatsu 4faa1bad45 feat: Implment std_fs_call kfstatvfs handling to memory scheme 2026-02-28 08:06:47 -07:00
Marsman 507d899587 fix: validate timespec in nanosleep 2026-02-28 07:02:30 +00:00
Wildan M fbe129918c Handle address release on flink 2026-02-27 15:43:19 +07:00
Wildan M 1b74bea620 EventQueue may dropped at trigger_inner 2026-02-27 15:29:58 +07:00
Wildan M 2e759a9cc5 Prevent drop on BorrowedHtBuf 2026-02-27 13:54:05 +07:00
Wildan M 437f762339 Prevent drop on WaitCondition 2026-02-27 12:34:13 +07:00
Wildan M 159e67f26d Add lock token for global REGISTRY 2026-02-27 11:16:57 +07:00
Wildan M c72e0a67f9 Prevent drop on AddrSpace 2026-02-27 10:47:45 +07:00
Jeremy Soller d34090f352 Accurately strip ANSI escape sequences in graphical debug display 2026-02-26 10:33:46 -07:00
Wildan M ac0bd2af74 Fix compilation 2026-02-26 04:33:10 +07:00
Anhad Singh ba94676fe4 chore: update redox_syscall
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-02-25 08:21:36 -07:00
Anhad Singh 8eb6d22ab4 misc(scheme/user): remove some debug logs
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-02-25 08:21:36 -07:00
Anhad Singh 955b4b2a1c feat(stdfscall): flocking
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-02-25 08:21:36 -07:00
Wildan M 14349d1649 Propagate ordered lock of event trigger 2026-02-25 11:42:31 +07:00
Wildan M 3c2b1a11c5 Add ordered lock for time offset mutex 2026-02-25 11:42:17 +07:00
Wildan M 735c68ec30 Add ordered lock for WaitQueue mutex 2026-02-25 09:48:13 +07:00
auronandace bf396c7f61 replace manual stripping 2026-02-23 15:49:32 +00:00
auronandace 8138826200 avoid direct indexing in wait_condition 2026-02-23 06:34:20 -07:00
auronandace 7770a9452c avoid direct indexing futexes 2026-02-23 11:57:28 +00:00
auronandace a19be5da11 avoid direct indexing in AlignedBox 2026-02-22 13:43:37 +00:00
auronandace aeb75d577f add assert to ensure both arrays are equal length 2026-02-21 20:37:08 +00:00
auronandace 8689e31674 remove an instance of direct indexing 2026-02-21 15:28:55 +00:00
auronandace df469ddcb3 apply is_multiple_of lint 2026-02-21 08:39:26 +00:00
auronandace 02a68d3c87 change static_mut_refs back to warn 2026-02-20 16:06:16 +00:00
auronandace 28ba26cc2b move lints to Cargo.toml file 2026-02-20 15:59:27 +00:00
Anhad Singh fc60dcced0 misc(main): add feature btree_cursors
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-02-21 00:59:24 +11:00
Anhad Singh a8699a7e72 feat(memory): handle grant merges when mutating
This commit fixes the following panic when running nodejs:
```
KERNEL PANIC: panicked at src/context/memory.rs:267:18:
grant cannot magically disappear while we hold the lock!
  FP ffff80002021f650: PC ffffffff8005e45b
    FFFFFFFF8005E2E0+017B
    kernel::panic::panic_handler_inner
  FP ffff80002021f730: PC ffffffff80057559
  FP ffff80002021f740: PC ffffffff8009a0ff
  FP ffff80002021f770: PC ffffffff8009c214
  FP ffff80002021f7d0: PC ffffffff80010997
    FFFFFFFF8000FDD0+0BC7
    kernel::context::memory::AddrSpaceWrapper::mprotect
  FP ffff80002021fd40: PC ffffffff8008cb0b
    FFFFFFFF8008CA40+00CB
    kernel::syscall::process::mprotect
  FP ffff80002021fd70: PC ffffffff8006ce6c
    FFFFFFFF8006CBE0+028C
    kernel::syscall::syscall
  FP ffff80002021fe90: PC ffffffff8008d3cf
    FFFFFFFF8008D320+00AF
    __inner_syscall_instruction
  FP ffff80002021ff50: PC ffffffff800830c3
    FFFFFFFF80083080+0043
    kernel::arch::x86_64::interrupt::syscall::syscall_instruction
  00007ffffffffaf0: GUARD PAGE
CPU #1, CID 0xffffff7f8015b910
NAME: /usr/bin/node, DEBUG ID: 74
SYSCALL: mprotect(0x203C0000, 262144, Some(MapFlags(0x0)))
HALT
```

The grant did not magically disappear. When going through the
`grant_span_res` regions, the function adds (and removes) grants to the
`self.grants` tree. The insertion and deletion functions also merge
adjacent grants together when possible. This is an issue since we can no
longer use the keys we established before we started iterating. This
commit modifies the places where `remove` is used in this fashion to use
`remove_containing` instead. The `remove_containing` function will
remove the grant that *contains* the page.

Should it be done this way (requires unstable feature `btree_cursors`)?

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-02-21 00:59:24 +11:00
auronandace 6853592ce4 add precedence clippy lint 2026-02-20 13:15:32 +00:00
Anhad Singh b85c2d7889 misc(rmm): update submodule
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-02-20 00:26:47 +11:00
Jeremy Soller e543cbe621 Merge branch 'master' into 'master'
feat(mapper/remap_with_full): conditional remap

See merge request redox-os/rmm!20
2026-02-19 06:23:39 -07:00
Anhad Singh 124b74e816 fix(context/memory): Grant::remap delegate write
`Grant::remap` should not directly mark entries as writeable because the
entry could be private and requires Copy-On-Write (COW) handling. This
bug fixes the random panics that occur when running programs that
incorrectly mark private memory regions as writeable. This also
inadvertently caused other systems to crash. This is because The Zeroed
Frame is mapped instead of allocating a new zeroed memory region every
time. Only after the first write is the frame actually allocated. This
means that with this bug one could remap a freshly mmap'ed ANONYMOUS
region with the write flag and rewrite the contents of The Zeroed Frame,
which is a big problem. This means that any program that allocated
memory with the ANONYMOUS flag after this would not receive zeroed
memory.

Example of `make` hitting this bug when the shared `ld.so` patches are
applied:
```
....
[page at 0x48bd000] is mapped to the zeroed frame with PageFlags { present: true, write: false, executable: false, user: true, bits: 0x8000000000000005 }
[page at 0x49b1000] is mapped to the zeroed frame with PageFlags { present: true, write: true, executable: false, user: true, bits: 0x8000000000000007 }
[page at 0x49b2000] is mapped to the zeroed frame with PageFlags { present: true, write: true, executable: false, user: true, bits: 0x8000000000000007 }
[page at 0x49b3000] is mapped to the zeroed frame with PageFlags { present: true, write: true, executable: false, user: true, bits: 0x8000000000000007 }
[page at 0x49b4000] is mapped to the zeroed frame with PageFlags { present: true, write: true, executable: false, user: true, bits: 0x8000000000000007 }
0x43ff000..0x49b5000 :: MapFlags(PROT_WRITE | PROT_READ)
[page at 0x49b5000] is mapped to the zeroed frame with PageFlags { present: true, write: false, executable: false, user: true, bits: 0x8000000000000005 }
[page at 0x49b6000] is mapped to the zeroed frame with PageFlags { present: true, write: false, executable: false, user: true, bits: 0x8000000000000005 }
....
```

and causing the following crash:

```
Page fault: 0000000000001718 P | WR | US
RFLAG: 0000000000010202
CS:    000000000000002b
RIP:   00000000004125fd
RSP:   00007fffffffdd80
SS:    0000000000000023
FSBASE  00000000003f6000
GSBASE  0000000000000000
KGSBASE ffff80007a800000
RAX:   0000000000001718
RCX:   0000000000000000
RDX:   ffffffffffffffff
RDI:   000000000043b5a0
RSI:   00000000004537e0
R8:    0000000000000030
R9:    000000000043b5a0
R10:   0000000000000030
R11:   00000000000000ff
RBX:   0000000000000000
RBP:   00007fffffffddb0
R12:   000000000043b5a0
R13:   00000000004537e0
R14:   00000000004537e0
R15:   000000000043b5a0
  FP 00007fffffffddb0: PC 000000000042614a
  FP 00007fffffffde40: PC 0000000000411ae9
  FP 00007fffffffde80: PC 0000000000417187
  FP 00007fffffffdee0: PC 0000000000411d39
  FP 00007fffffffdf90: PC 000000000041207d
  FP 00007fffffffe020: PC 000000000040bc4c
  FP 00007fffffffe0c0: PC 000000000040c7c9
  FP 00007fffffffe0f0: PC 00000000004276ba
  FP 00007fffffffe1a0: PC 0000000000428087
  FP 00007fffffffe210: PC 000000000041eb6a
  FP 00007fffffffe400: PC 00000000004205c3
  FP 00007fffffffe490: PC 00000000004208dd
  FP 00007fffffffe4d0: PC 000000000040747e
  FP 00007ffffffffd60: PC 000000000092111c
  <Invalid next frame pointer 0x0000000000438490; stack walk ended>
  FP ffff80001b5bfe80: PC ffffffff80046dad
    FFFFFFFF80046BD0+01DD
    kernel::arch::x86_shared::interrupt::exception::page::inner
  FP ffff80001b5bff50: PC ffffffff8003ffbb
    FFFFFFFF8003FF84+0037
    kernel::arch::x86_shared::interrupt::exception::page
  00007fffffffddb0: GUARD PAGE
kernel::context::signal:INFO -- UNHANDLED EXCEPTION, CPU #1, PID 6548, NAME /usr/bin/make, CONTEXT 0xffffff7f8013fdc0
```

Also the crash info would vary every time you run the program since the
contents of The Zeroed Frame would have been mutated. Sneaky bug :^)

This also fixes the crashes that happen when running node.js (and maybe
other programs): https://gitlab.redox-os.org/redox-os/relibc/-/issues/229

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-02-19 19:54:14 +11:00
Anhad Singh d82ba37de8 feat(mapper/remap_with_full): conditional remap
This commit modifies the transform function (`f`) argument of
`remap_with_full` to return an `Option`. This allows the caller to skip
remaps based on the previous frame and page flags. It can alternatively
be done by first translating the address and then remapping based on
that but that would mean we have to walk the page tables twice :|

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-02-19 19:50:00 +11:00
Anhad Singh f299c885e6 feat(lib): implement Debug for PhysicalAddress
Make it consistent with the debug output for `VirtualAddress`

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-02-19 19:32:10 +11:00
Ibuki Omatsu 5a8858ff81 refactor: Initialize sys schem resources when they are first accessed. 2026-02-12 06:24:43 -07:00
Jeremy Soller 934162f35a Implement stdfscall 2026-02-11 12:12:49 -07:00
bjorn3 858b712df5 Use naked_asm!() instead of global_asm!() where possible 2026-02-09 22:28:38 +01:00
bjorn3 d51fe0c7e0 Avoid concat!() in inline asm
It is no longer necessary in modern rustc versions.
2026-02-09 22:12:20 +01:00
bjorn3 6bd204e1a3 Remove always true supports_on_close field 2026-02-08 17:23:50 +01:00
bjorn3 4c2c2b6757 Remove Option from State::Waiting.fds 2026-02-08 17:08:59 +01:00
bjorn3 0576db1fb4 Inline UserInner::call and rename call_extended to call 2026-02-08 13:01:14 +01:00
bjorn3 3d1188cf1e Introduce Response::as_regular 2026-02-08 12:54:04 +01:00
bjorn3 99ff55ee1b Demux results as soon as we receive them from a user scheme 2026-02-08 12:50:53 +01:00
bjorn3 f88cbf96ee Remove unnecessary clones and pass CallerCtx to call() 2026-02-08 12:46:08 +01:00
bjorn3 5c6af01a9a Remove two unnecessary uses of spin::Once 2026-02-07 13:14:48 +01:00
bjorn3 e14a20aae2 Mark two functions as private 2026-02-07 12:59:24 +01:00
bjorn3 4e41ed987a Fix /scheme/sys/context header 2026-02-07 12:31:42 +01:00
bjorn3 2f8a3b3d67 Remove unused SchemeNamespace type 2026-02-06 22:05:42 +01:00
bjorn3 f334e760bb Remove ens field from Context
It is no longer used due to the capability rework.
2026-02-06 22:00:18 +01:00
bjorn3 9f218c5b3a Fix assertion in Args::args() 2026-02-06 21:07:16 +01:00
bjorn3 7ff1898765 Fix a couple of warnings 2026-02-06 20:54:42 +01:00
bjorn3 6ddd0a9098 Replace scheme::schemes() with scheme::get_scheme()
We never need to iterate over all schemes. We only ever need to access
individual schemes.
2026-02-06 20:54:42 +01:00
bjorn3 ace9038720 Reduce visibility of a couple of methods 2026-02-06 20:34:16 +01:00
Jeremy Soller 2055a205f1 Remove legacy path message 2026-01-29 10:12:04 -07:00
Ibuki Omatsu 5ac00f5533 Remove namespace management from the kernel. 2026-01-20 20:43:34 -07:00
Jeremy Soller 1c850605d0 Only read time once during context switch 2026-01-20 14:18:33 -07:00
Jeremy Soller 81a49d211b Fix potential preempt guard deadlock 2026-01-20 13:58:31 -07:00
Anhad Singh 7d42e8d966 fix(switch): deadlock
During the snapshot shown, interrupts would be _disabled_ on both CPUs and both
would have have the _same_ address space (i.e.
`PercpuBlock::current().current_addrsp`).

```rs
// CPU 0                                                                                             CPU 1 (inside `context::switch()`)
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// let guard = current_addrsp.acquire_write()
// let flusher = Flusher::with_cpu_set(&addrsp.used_by, &current_addrsp.tlb_ack);
// ...
// drop(flusher); // Flusher::flush()
//     // send IPI to CPU 1 as it is in the `active_set`
//     shootdown_tlb_ipi(Some(1));
//                                                                                                    percpu::switch_arch_hook();
//     // spin until TLB shootdown IPI has been acknowledged by CPU 1                                 // acquire_read() to remove the CPU from the `used_by` set in `prev_addrsp`
//     while ackword < affected_cpu_count                                                             prev_addrsp.acquire_read()
//         PercpuBlock::current().maybe_handle_tlb_shootdown();
//         spin_loop();
//     }
// drop(guard);
```

Now CPU 0 will spin _until_ CPU 1 has acknowledged the IPI. However, CPU 1 has
interrupts disabled and is in the middle of a context switch. To complete the
context switch it needs to remove itself from the `used_by` set in
`prev_addrsp` (which is the current address space atm). To do that it needs to
`acquire_read()` lock but it cannot since it is held by CPU 0 and won't release
it until CPU 1 has acknowledged the IPI; creating a deadlock.

Also note:

```rs
// src/context/memory.rs
// NOTE: Lock must be held, which must be guaranteed by the caller.
pub fn flush(&mut self) {
```

Here is some output from GDB to back this up:

```
pwndbg> info threads
  Id   Target Id                    Frame
  1    Thread 1.1 (CPU#0 [running]) core::sync::atomic::atomic_compare_exchange_weak<usize> (dst=0xffffff7f801972f0, old=0, new=1, success=core::sync::atomic::Ordering::Acquire, failure=core::sync::atomic::Ordering::Relaxed)
    at /mnt/redox/prefix/x86_64-unknown-redox/sysroot/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:4100
  2    Thread 1.2 (CPU#1 [running]) kernel::context::memory::Flusher::flush (self=0xffff80004212f4b8) at src/context/memory.rs:2827
  3    Thread 1.3 (CPU#2 [running]) spin::rwlock::RwLock<kernel::context::context::Context, spin::relax::Spin>::write<kernel::context::context::Context, spin::relax::Spin> (self=0xffffff7f801a99c0)
    at /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spin-0.9.8/src/rwlock.rs:239
* 4    Thread 1.4 (CPU#3 [running]) 0xffffffff80059cf9 in kernel::context::memory::AddrSpaceWrapper::acquire_read (self=0xffffff7f80188110)
    at /mnt/redox/prefix/x86_64-unknown-redox/sysroot/lib/rustlib/src/rust/library/core/src/../../stdarch/crates/core_arch/src/x86/sse2.rs:25
pwndbg> p kernel::context::arch::CONTEXT_SWITCH_LOCK
$1 = core::sync::atomic::AtomicBool {
  v: core::cell::UnsafeCell<u8> {
    value: 1
  }
}
pwndbg> p (*kernel::percpu::ALL_PERCPU_BLOCKS[0].p.value).wants_tlb_shootdown.v.value
$2 = 0
pwndbg> p (*kernel::percpu::ALL_PERCPU_BLOCKS[1].p.value).wants_tlb_shootdown.v.value
$3 = 0
pwndbg> p (*kernel::percpu::ALL_PERCPU_BLOCKS[2].p.value).wants_tlb_shootdown.v.value
$4 = 1
pwndbg> p (*kernel::percpu::ALL_PERCPU_BLOCKS[3].p.value).wants_tlb_shootdown.v.value
$5 = 0
pwndbg> p (*kernel::percpu::ALL_PERCPU_BLOCKS[3].p.value).current_addrsp
$6 = core::cell::RefCell<core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>> {
  borrow: core::cell::Cell<isize> {
    value: core::cell::UnsafeCell<isize> {
      value: 0
    }
  },
  value: core::cell::UnsafeCell<core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>> {
    value: core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>::Some(alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global> {
        ptr: core::ptr::non_null::NonNull<alloc::sync::ArcInner<kernel::context::memory::AddrSpaceWrapper>> {
          pointer: 0xffffff7f80188100
        },
        phantom: core::marker::PhantomData<alloc::sync::ArcInner<kernel::context::memory::AddrSpaceWrapper>>,
        alloc: alloc::alloc::Global
      })
  }
}
pwndbg> p (*kernel::percpu::ALL_PERCPU_BLOCKS[2].p.value).current_addrsp
$7 = core::cell::RefCell<core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>> {
  borrow: core::cell::Cell<isize> {
    value: core::cell::UnsafeCell<isize> {
      value: 0
    }
  },
  value: core::cell::UnsafeCell<core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>> {
    value: core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>::Some(alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global> {
        ptr: core::ptr::non_null::NonNull<alloc::sync::ArcInner<kernel::context::memory::AddrSpaceWrapper>> {
          pointer: 0xffffff7f80188100
        },
        phantom: core::marker::PhantomData<alloc::sync::ArcInner<kernel::context::memory::AddrSpaceWrapper>>,
        alloc: alloc::alloc::Global
      })
  }
}
pwndbg> p (*kernel::percpu::ALL_PERCPU_BLOCKS[1].p.value).current_addrsp
$8 = core::cell::RefCell<core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>> {
  borrow: core::cell::Cell<isize> {
    value: core::cell::UnsafeCell<isize> {
      value: 0
    }
  },
  value: core::cell::UnsafeCell<core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>> {
    value: core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>::Some(alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global> {
        ptr: core::ptr::non_null::NonNull<alloc::sync::ArcInner<kernel::context::memory::AddrSpaceWrapper>> {
          pointer: 0xffffff7f80188100
        },
        phantom: core::marker::PhantomData<alloc::sync::ArcInner<kernel::context::memory::AddrSpaceWrapper>>,
        alloc: alloc::alloc::Global
      })
  }
}
pwndbg> p (*kernel::percpu::ALL_PERCPU_BLOCKS[0].p.value).current_addrsp
$9 = core::cell::RefCell<core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>> {
  borrow: core::cell::Cell<isize> {
    value: core::cell::UnsafeCell<isize> {
      value: 0
    }
  },
  value: core::cell::UnsafeCell<core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>> {
    value: core::option::Option<alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global>>::Some(alloc::sync::Arc<kernel::context::memory::AddrSpaceWrapper, alloc::alloc::Global> {
        ptr: core::ptr::non_null::NonNull<alloc::sync::ArcInner<kernel::context::memory::AddrSpaceWrapper>> {
          pointer: 0xffffff7f80133ac8
        },
        phantom: core::marker::PhantomData<alloc::sync::ArcInner<kernel::context::memory::AddrSpaceWrapper>>,
        alloc: alloc::alloc::Global
      })
  }
}
```

```
pwndbg> thread 4
[Switching to thread 4 (Thread 1.4)]
25	in /mnt/redox/prefix/x86_64-unknown-redox/sysroot/lib/rustlib/src/rust/library/core/src/../../stdarch/crates/core_arch/src/x86/sse2.rs
pwndbg> info threads
  Id   Target Id                    Frame
  1    Thread 1.1 (CPU#0 [running]) core::sync::atomic::atomic_compare_exchange_weak<usize> (dst=0xffffff7f801972f0, old=0, new=1, success=core::sync::atomic::Ordering::Acquire, failure=core::sync::atomic::Ordering::Relaxed)
    at /mnt/redox/prefix/x86_64-unknown-redox/sysroot/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:4100
  2    Thread 1.2 (CPU#1 [running]) kernel::context::memory::Flusher::flush (self=0xffff80004212f4b8) at src/context/memory.rs:2827
  3    Thread 1.3 (CPU#2 [running]) spin::rwlock::RwLock<kernel::context::context::Context, spin::relax::Spin>::write<kernel::context::context::Context, spin::relax::Spin> (self=0xffffff7f801a99c0)
    at /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spin-0.9.8/src/rwlock.rs:239
* 4    Thread 1.4 (CPU#3 [running]) 0xffffffff80059cf9 in kernel::context::memory::AddrSpaceWrapper::acquire_read (self=0xffffff7f80188110)
    at /mnt/redox/prefix/x86_64-unknown-redox/sysroot/lib/rustlib/src/rust/library/core/src/../../stdarch/crates/core_arch/src/x86/sse2.rs:25
pwndbg> thread 4
[Switching to thread 4 (Thread 1.4)]
25	in /mnt/redox/prefix/x86_64-unknown-redox/sysroot/lib/rustlib/src/rust/library/core/src/../../stdarch/crates/core_arch/src/x86/sse2.rs
pwndbg> bt
```

This is *after* everything freezes.

For relibc tests, if I run `while true; do
/root/relibc-tests/pthread/once; done` it eventually does freeze up and
does so at the same location:

```
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ THREADS (4 TOTAL) ]──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  ► 1   "" stopped: 0xffffffff800750a2 <kernel::context::switch::switch+1282>
    4   "" stopped: 0xffffffff80074d5a <kernel::context::switch::switch+442>
    3   "" stopped: 0xffffffff80059cf9 <kernel::context::context::Context::set_addr_space+217>
    2   "" stopped: 0xffffffff80020839 <kernel::context::memory::Flusher::flush+361>
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
```

Related: https://gitlab.redox-os.org/redox-os/kernel/-/issues/175

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-01-19 15:21:13 +11:00
Pascal Reich a919d2626b Inline Documentation Fixes 2026-01-10 16:19:34 -07:00
Jeremy Soller ea06685903 Do not allow recursively registering the same event queue 2026-01-09 12:08:16 -07:00
Anhad Singh a245e49e75 fix(syscalls/futex): premature timeout
Previously, if a futex with a timeout was woken up (even via
`futex_wake`), it was treated as though the timeout had expired. When
the timeout expires, the scheduler sets `wake` to `None` and unblocks
the process. Hence if `wake` is `None` and if a timeout was given to
futex, it has expired. Otherwise the process was woken up by
`futex_wake`.

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-01-07 14:45:01 +11:00
Anhad Singh 5ccd2414af fix(context/memory): incorrect remaining_src_span
The `AddrSpaceWrapper::r#move` is used by `mremap` to move, expand or
shrink existing mappings.

`src_span.count`: Size of old region in pages
`new_page_count`: Size of new region in pages

Fixes the following panic when running `cargo`:

```
KERNEL PANIC: panicked at src/context/memory.rs:1969:9:
assertion failed: self.info.can_extract(false)
  FP ffff80000cbbf2c0: PC ffffffff8004ced5
    FFFFFFFF8004CD50+0185
    kernel::panic::panic_handler_inner
  FP ffff80000cbbf3a0: PC ffffffff8004ac99
  FP ffff80000cbbf3b0: PC ffffffff800a34df
  FP ffff80000cbbf3e0: PC ffffffff800a34b4
  FP ffff80000cbbf430: PC ffffffff8001c029
    FFFFFFFF8001BF10+0119
    kernel::context::memory::Grant::extract
  FP ffff80000cbbf4a0: PC ffffffff800181ac
    FFFFFFFF80016D30+147C
    kernel::context::memory::AddrSpaceWrapper::move
  FP ffff80000cbbfd30: PC ffffffff80037c08
    FFFFFFFF80035660+25A8
    kernel::syscall::syscall
  FP ffff80000cbbfe90: PC ffffffff8008efbf
    FFFFFFFF8008EF10+00AF
    __inner_syscall_instruction
  FP ffff80000cbbff50: PC ffffffff80085d33
    FFFFFFFF80085CF0+0043
    kernel::arch::x86_64::interrupt::syscall::syscall_instruction
  0000000000004455: GUARD PAGE
CPU #2, CID 0xffffff7f80133690
NAME: /scheme/initfs/bin/redoxfs, DEBUG ID: 43
SYSCALL: mremap(0x2177F000, 0x8000, 0x0, 0xC7000, 0x60000)
HALT
```

```
mremap_flags = MremapFlags(
    0x0,
)
prot_flags = MapFlags(
    PROT_WRITE | PROT_READ,
)
```

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2026-01-03 22:56:03 +11:00
Wildan M 92132132c1 Implement clock_getres and handle path to time scheme 2025-12-21 05:24:13 +07:00
Ibuki Omatsu e30ed9ab6a Introduce syscall6. Add unlinkat and remove unlink and rmdir. 2025-12-17 18:31:04 -07:00
Anhad Singh d9eae6bb75 fix(sync/wait_condition): deadlock in WaitCondition::wait
Instead of using a simple switch to determine if preemption is enabled
(`is_preemptable: bool`), a counter is used instead. This handles the
case where a function holding a `PreemptGuard` calls another function
that creates a new `PreemptGuard`.

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2025-12-15 13:05:29 +11:00
bjorn3 62a572a0f0 Use compiler-builtins for the memcpy family of functions 2025-12-14 16:38:04 +01:00
bjorn3 c089667ade Remove support for the legacy packet user schemes 2025-12-13 15:52:30 +01:00
bjorn3 3091f40c13 Warn against opening a legacy scheme version 2025-12-13 15:12:01 +01:00
Wildan M e06f908b1b Add CI workflow 2025-12-11 01:07:33 +07:00
bjorn3 3bf880e008 Correctly handle MAP_FIXED with a zero address 2025-12-09 23:09:19 +01:00
bjorn3 5a11067f10 Support non-fixed and anonymous remote mmap 2025-12-09 20:55:19 +01:00
Jeremy Soller d33fc3b5b0 Merge branch 'mmu_flags' into 'master'
Set RISCV MMU marker flags by default

See merge request redox-os/rmm!18
2025-12-09 06:28:44 -07:00
aarch 5b149b7fe4 Set RISCV MMU marker flags by default 2025-12-09 06:28:44 -07:00
bjorn3 58a362844a Add a binary variant for the filetable read operation
This is a lot easier to parse in no_alloc scenarios than the current
textual format. This would help with moving the cloexec handling from
relibc to redox-rt.
2025-12-08 21:55:03 +01:00
Anhad Singh ac713a061c misc(scheme/user): treat all spurious wakeups as signal
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2025-11-28 15:24:32 +11:00
Anhad Singh 45aae5f963 misc(scheme/user): use preempt guard
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2025-11-27 16:23:31 +11:00
Anhad Singh b2c9e5defd misc(scheme/user): unblock the process *after* setting the state
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2025-11-27 16:21:03 +11:00
Anhad Singh 4ff82ad8b5 fix(scheme/user): deadlocks inside call_extended_inner
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2025-11-27 14:39:14 +11:00
Jeremy Soller 27465b6132 Make CPU announcements debug level 2025-11-23 07:41:09 -07:00
Jeremy Soller 7ffc046d46 Enable serial interrupts on aarch64 ACPI 2025-11-21 08:39:38 -07:00
Jeremy Soller e3cafc975f Format 2025-11-17 17:41:04 -07:00
Jeremy Soller 91ba44e2fa Implement F_DUPFD_CLOEXEC 2025-11-17 17:40:39 -07:00
aarch 2bdc5d2109 Implement kfpath for dtb kernel scheme 2025-11-15 17:45:39 +00:00
Jeremy Soller e14f935063 Ensure pipe is_alive is set before triggering event or condition 2025-11-14 20:59:44 -07:00
Jeremy Soller 2d9f2015d0 Add upper table fds to kernel.proc filetable 2025-11-14 15:06:37 -07:00
Jeremy Soller 42f9f04188 Require kfpath implementation, add to acpi scheme 2025-11-14 14:19:33 -07:00
Jeremy Soller 61ad67fbfe Improve display of upper table in iostat 2025-11-14 13:55:55 -07:00
4lDO2 33dbf2458e only clear RC_USED_NOT_FREE with freelist locked 2025-11-14 20:06:18 +01:00
4lDO2 96552163f6 Clear RC_USED_NOT_FREE even for contention case. 2025-11-14 20:06:18 +01:00
4lDO2 dc33c67997 Fix potential refcount underflow from fetch_sub. 2025-11-14 20:06:18 +01:00
Jeremy Soller cbea1aca3d Implement kfpath on more schemes 2025-11-14 11:36:49 -07:00
Jeremy Soller 64ea4251ee Debug SYS_MREMAP 2025-11-13 15:55:02 -07:00
Jeremy Soller e6edef2d8e Downgrade addrspace outside futex loop 2025-11-12 10:34:18 -07:00
Jeremy Soller 7834392dba Use hashmap for futex 2025-11-12 08:03:24 -07:00
Jeremy Soller f9d9a3414b Update rmm 2025-11-12 07:37:14 -07:00
Jeremy Soller 409a1c02f5 Derive Hash for PhysicalAddress 2025-11-12 07:36:54 -07:00
4lDO2 70256a5b2f Revert "Fix i686 using cmpxchg8b-based AtomicU64 for stats."
This reverts commit 21f2d8f3e4.
2025-11-12 11:07:09 +01:00
4lDO2 21f2d8f3e4 Fix i686 using cmpxchg8b-based AtomicU64 for stats. 2025-11-12 10:59:51 +01:00
bjorn3 00fdfaf11c Remove -Csoft-float from clippy.sh
It doesn't do anything and will be removed in a future rustc version.
Usage was already removed from the Makefile previously.
2025-11-11 13:40:48 +00:00
Jeremy Soller 01ec650b1e Add support for userspace stack traces using usercopy 2025-11-10 08:54:06 -07:00
Jeremy Soller c66423cec6 Sort target json and allow AtomicU64 on i586/i686 2025-11-10 08:53:47 -07:00
Jeremy Soller 531dfaa3e1 Format 2025-11-06 22:14:25 -07:00
Jeremy Soller 8ae1ced55d Recursively trigger event queues 2025-11-06 22:14:13 -07:00
Jeremy Soller c3437ab6eb Ignore any opens with event: or time: 2025-11-06 09:15:52 -07:00
Jeremy Soller 60af085356 Improve cpu stat accuracy 2025-11-03 20:42:08 -07:00
Jeremy Soller aa50069e15 Remove unnecessary log 2025-11-01 20:49:06 -06:00
Jeremy Soller 91b835d29f Reduce logging significantly 2025-11-01 20:24:11 -06:00
Jeremy Soller 64f2314e2c Fix makefile ifeq 2025-11-01 14:02:34 -06:00
bjorn3 301f163112 Handle building for i586-unknown-redox 2025-11-01 19:30:40 +01:00
bjorn3 65273ea898 Replace all Arc::try_new with Arc::new
The global allocator panics when out of memory rather than returning an
errors. In addition there are plenty of other places where we don't
handle allocation failure anyway. At some point in the future we should
systematically handle out of memory conditions, but until then let's not
pretend we do and get rid of the usage of the unstable allocator_api
feature that is unlikely to get stabilized any time soon.
2025-10-26 12:44:52 -06:00
bjorn3 e101629377 Inline a bunch of functions in KernelMapper 2025-10-26 12:44:52 -06:00
bjorn3 85b5487b5b Couple minor cleanups to the global allocator 2025-10-26 12:44:52 -06:00
bjorn3 3b1fd27431 Remove byteorder dependency 2025-10-26 12:43:08 -06:00
bjorn3 bc3a59abb3 Minor simplification to profiling::nmi_handler 2025-10-26 18:27:29 +01:00
bjorn3 0f7b16d89d Partially use cfg!() rather than #[cfg] for controlling the profiling module
This only adds a pointer worth of overhead per cpu core in the
PerCpuBlock struct.

Also fix a bunch of unsafe_op_in_unsafe_fn warnings in the profiling
code.
2025-10-26 18:27:29 +01:00
bjorn3 53640e67b7 Remove rustc_cfg dependency 2025-10-26 16:32:42 +01:00
bjorn3 8367462abe Update rmm submodule 2025-10-26 16:25:01 +01:00
Jeremy Soller 7e14945bc5 Merge branch 'stable' into 'master'
Remove all nighly feature gates

See merge request redox-os/rmm!17
2025-10-26 09:18:30 -06:00
bjorn3 4b89feab41 Fix a couple of dead code warnings 2025-10-26 12:07:56 +01:00
bjorn3 075d52f153 Fix example binary 2025-10-26 11:58:43 +01:00
bjorn3 e6d42dda19 Fix compilation of EmulateArch 2025-10-26 11:55:42 +01:00
bjorn3 5b5bbe5643 Remove VirtualAddress::is_canonical
This way the last remaining feature gate can be removed. It also matches
how other architectures handle this functionality.
2025-10-25 20:02:55 +02:00
bjorn3 e371f47f51 Remove let_chain feature gate
It is now stable.
2025-10-25 20:01:32 +02:00
bjorn3 1498376360 Unify generic irq handling between x86 and x86_64 2025-10-25 19:44:03 +02:00
bjorn3 3652b693ba Remove usage of iterator_try_collect 2025-10-25 11:34:55 -06:00
bjorn3 164c890830 Remove thread_local feature gate
We use the PerCpuBlock instead of ELF TLS
2025-10-25 11:34:55 -06:00
bjorn3 cb718f767a Remove a bunch of unused __*_start/end symbols 2025-10-25 19:20:01 +02:00
bjorn3 e8acd82074 Directly define __usercopy_{start,end} in the usercopy functions
As opposed to requiring a linker script
2025-10-25 19:12:27 +02:00
bjorn3 cc01d14d3b Unconditionally enable sys_stat 2025-10-25 18:52:07 +02:00
bjorn3 a57c8e410d Avoid warnings from rust-analyzer for the panic handler
Rust-analyzer runs cargo check --all-targets which also checks the test
configuration where previously there would be a bunch of warnings for
unused things due to the panic handler being configured out.
2025-10-19 14:30:53 +02:00
bjorn3 021cdf47f4 Fix a bunch of warnings 2025-10-19 14:27:43 +02:00
bjorn3 9d5ad06b30 Move some code from the trampoline to global_asm!() 2025-10-19 06:23:39 -06:00
bjorn3 4b16e66164 Set arm64 exception handler before entering the rust world 2025-10-19 06:23:39 -06:00
bjorn3 d31e552d08 Set riscv exception handler before entering the rust world 2025-10-19 06:23:39 -06:00
bjorn3 ff65afd003 Don't depend on the stack setup by the bootloader
This way we can choose our own size for the stack and don't have to
identity map it manually. Also this way the bootloader doesn't have to
change the stack pointer right before calling into the kernel (which it
currently does in an unsound way)
2025-10-19 06:23:39 -06:00
bjorn3 b7a69a26ba Reduce indentation in madt x86 init 2025-10-19 06:23:39 -06:00
bjorn3 7ea41f4fee Remove no longer necessary lint allow 2025-10-19 11:49:14 +02:00
bjorn3 b09659ac25 Remove unnecessary unsafe blocks in naked functions 2025-10-19 11:48:46 +02:00
Jeremy Soller 3c3eaa0004 Enable sys_stat by default for sysinfo 2025-10-12 15:49:35 -06:00
Jeremy Soller c9653525a0 Fix compilation with sys_stat feature 2025-10-12 15:45:50 -06:00
Speedy_Lex 0931a7f49f Resolve a huge portion of the clippy lints 2025-10-06 06:30:23 -06:00
Jeremy Soller db8fb14614 Fix compilation on other archs 2025-10-04 11:58:04 -06:00
Jeremy Soller 18bf5d904b Fix aarch64 kernel target 2025-10-04 11:53:51 -06:00
Jeremy Soller e635e7a911 Fix i686 kernel target 2025-10-04 11:53:01 -06:00
Jeremy Soller f7fa2491ac Add rust-toolchain.toml 2025-10-04 09:18:10 -06:00
Jeremy Soller 84385222e2 Use x86-softfloat rustc-abi for x86_64 target 2025-10-04 08:21:00 -06:00
4lDO2 8d50ebd69d Fix target spec int vs string. 2025-10-04 16:12:54 +02:00
Speedy_Lex ea812e8f2a Run cargo fmt 2025-10-04 01:06:15 +02:00
Speedy_Lex d38002969c Fixes for rust update 2025-10-04 00:55:26 +02:00
bjorn3 bc9273057d Remove a bunch of double references from AddrSpaceWrapper::move 2025-10-03 20:53:26 +02:00
bjorn3 db5e6184af Remove unnecessary add_ref in ProcScheme::kfmap
Grant::allocated_shared_one_page already adds a reference. This fixes a
memory leak
2025-09-27 19:44:26 +02:00
bjorn3 6445f04ac4 Avoid overwriting expected count for special frames used by multiple contexts 2025-09-26 23:38:30 +02:00
bjorn3 4db2c919ef Nicer printing of frame refcount mismatch 2025-09-26 23:28:01 +02:00
bjorn3 cd761ee679 Handle all cases in foreach_addrsp 2025-09-26 23:28:01 +02:00
bjorn3 12f908b1ba Take sighandler frames into account during the integrity check 2025-09-26 23:28:01 +02:00
bjorn3 4c85131e36 Always take syscall_head/tail into account during the integrity check
Previously it wouldn't be taken into account if currently used by the
kernel.
2025-09-26 23:28:01 +02:00
bjorn3 ede9a47f9c Move .bss and .data tests to inline asm
If .bss is not properly cleared or .data is incorrectly cleared, there
is no way to tell what will happen if we try to run Rust code.
2025-09-25 09:46:17 -06:00
bjorn3 ac35b7984a Fix kernel debugger 2025-09-25 17:26:31 +02:00
Jeremy Soller 0203ad750a Fix compilation on aarch64/riscv64gc 2025-09-23 13:46:44 -06:00
Jeremy Soller 4526acc259 Drop comment about fixed multi_core issues 2025-09-23 13:09:32 -06:00
Jeremy Soller b0d5fa0993 Copy all higher PML4 entries in setup_new_utable (fixes some AMD CPUs) 2025-09-23 13:09:12 -06:00
Jeremy Soller 89c182cca1 Restore return in percpu::switch_arch_hook 2025-09-23 13:08:34 -06:00
Jeremy Soller b6a5245556 Require passing loopback test for hard-coded serial 2025-09-23 11:33:37 -06:00
Jeremy Soller 6ce2101cf4 Do not mark soc ranges as device memory 2025-09-23 10:31:34 -06:00
Jeremy Soller 5dc6f7c3ba lock ordering 2025-09-22 07:48:48 -06:00
bjorn3 e7358e3e5b Deduplicate a bunch of things that use KernelArgs between archs 2025-09-20 19:10:19 +02:00
bjorn3 3f385ba79d Unify KernelArgs type between architectures 2025-09-20 19:10:19 +02:00
bjorn3 c35c17c67e Merge display.rs into debug.rs 2025-09-20 17:59:19 +02:00
bjorn3 b36deffa61 Replace scrolling with wraparound in graphical debug
Inspired by how Haiku does printing for its kernel debugger, this commit
gets rid of the scrolling when the bootlog reaches the end of the screen
and instead wraps around to the start of the screen. Between the last
written line and the first visible written line there is always a blank
line to provide visual separation.

Getting rid of the scrolling significantly simplifies the implementation
of graphical debug and removes the need for double buffering for
performance as we no longer need to read back the framebuffer when
scrolling which is very expensive on write-combining memory like the
framebuffer.
2025-09-20 17:15:02 +02:00
bjorn3 84ac36ca2f Inline DebugDisplay::write_char 2025-09-20 15:42:08 +02:00
bjorn3 3db8bf878e Remove workaround for Meteor Lake having an AP with hardware cpu id 0 2025-09-20 15:33:08 +02:00
bjorn3 f58bcd584e Separate logical and hardware cpu ids 2025-09-20 15:33:08 +02:00
bjorn3 3a47c3becc Move most HPET logs to the trace log level
This significantly reduces the amount of boot logs produced by the
kernel by default on x86. With this the full kernel boot logs now fit on
a single screen on my system.
2025-09-20 15:21:54 +02:00
bjorn3 99b626845d Cleanup after removing INIT_THREAD 2025-09-20 15:21:38 +02:00
Jeremy Soller 229a5de6ff Remove INIT_THREAD 2025-09-19 20:30:26 -06:00
Jeremy Soller 7abe4e1051 Remove slab allocator 2025-09-19 20:29:53 -06:00
Jeremy Soller eb69d37323 Apply 1 suggestion(s) to 1 file(s)
Co-authored-by: bjorn3 <4397-bjorn3@users.noreply.gitlab.redox-os.org>
2025-09-19 06:43:19 -06:00
Elle Rhumsaa 8255e74ffd fixup: scheme: remove unnecessary braces
Removes unnecessary braces to fix compilation error.

Signed-off-by: Elle Rhumsaa <elle@weathered-steel.dev>
2025-09-19 06:43:19 -06:00
Elle Rhumsaa 0022bd448c dtb: remove allocation for in-memory DTB
Replaces the `Once<Vec<u8>>` with `Once<&'static [u8]>` to avoid an
unnecessary allocation.

Adds some basic documentation.

Signed-off-by: Elle Rhumsaa <elle@weathered-steel.dev>
2025-09-19 06:43:19 -06:00
bjorn3 68526b2af5 Use naked asm for riscv exception handler 2025-09-18 17:29:50 +02:00
bjorn3 081efd6cfa Allocate IDT for APs on the BSP and statically allocate BSP IDT
This allows them to be immediately installed by kstart/kstart_ap without
having to wait for the page tables to be set up correctly. This removes
the initial IDT.
2025-09-17 21:03:36 +02:00
bjorn3 e81db007b7 Couple of cleanups to the IDT handling 2025-09-17 21:03:36 +02:00
bjorn3 742a7f4492 Remove Option around IDTs HashMap 2025-09-17 21:03:36 +02:00
Jeremy Soller 2bf580b260 Reimplement iostat 2025-09-16 20:39:06 -06:00
bjorn3 25d526e9a1 Inline load_segments 2025-09-16 19:58:56 +02:00
bjorn3 647c87c5a0 Allocate PCR for APs on the BSP
This allows them to be immediately installed by kstart_ap without having
to wait for the page tables to be set up correctly. This removes the
initial GDT.
2025-09-16 19:57:31 +02:00
bjorn3 dbe25b78e3 Make it possible to change KernelArgsAp without changing the trampolines 2025-09-16 19:33:07 +02:00
bjorn3 019564ee0e Statically allocate PCR for the BSP 2025-09-15 22:01:15 +02:00
bjorn3 4884d749af Make PercpuBlock const constructable 2025-09-15 19:00:03 +02:00
bjorn3 3329a41121 Unify set_tss_stack and set_userspace_io_allowed signatures between x86 and x86_64 2025-09-15 18:37:27 +02:00
bjorn3 05e344bd9e Unify tss alignment method between x86 and x86_64 2025-09-15 18:23:29 +02:00
bjorn3 9a14f9a80d Unify gdt handling between x86 and x86_64 2025-09-14 20:30:57 +02:00
bjorn3 d1c7177038 Remove unused macro 2025-09-14 20:21:46 +02:00
bjorn3 200aeac2ba Reduce visibility of a couple of idt things 2025-09-14 19:10:09 +02:00
bjorn3 d3b17177b2 Avoid allocating during panics and infer kernel image size without explicitly storing it 2025-09-14 13:11:13 +02:00
bjorn3 9f71f02532 Reduce indentation in stack_trace 2025-09-13 21:34:02 +02:00
bjorn3 6334977090 Inline symbol_trace into strack_trace 2025-09-13 21:34:02 +02:00
bjorn3 30bbafdfa4 Use the object crate for panic backtraces
This increases the kernel image size by about 16kb, but in return
significantly simplifies things.
2025-09-13 21:34:02 +02:00
bjorn3 ad4ea619e8 Fix interrupt race condition on arm64 and riscv64 2025-09-13 20:29:32 +02:00
bjorn3 9e37ccaae8 Fix enable_and_halt on arm64
I accidentally used nop instead of wfi
2025-09-13 19:07:01 +02:00
bjorn3 83b4538d7c Merge two asm blocks
There is no guarantee they will be atomic otherwise
2025-09-13 18:55:16 +02:00
bjorn3 61db2b2ad5 Use core::hint::spin_loop() where possible 2025-09-13 18:55:16 +02:00
bjorn3 711ea9a4ed Move system76_ec::init() into serial::init() 2025-09-13 18:55:16 +02:00
bjorn3 5a6117b5ae Replace the log crate with a custom logging system
This avoids the need to explicitly set a logger early during boot, which
reduces the amount of moving parts that could go wrong slightly. And it
cuts the kernel image size by 13kb.
2025-09-13 18:55:16 +02:00
Jeremy Soller 8a2aa411e2 Explicitly scope all locks, fixing multi_core hangs. Allow contexts on any CPU 2025-09-13 10:10:07 -06:00
bjorn3 da6f7adb42 Use HashMap rather than BTreeMap for scheme handles
According to the comments this previously wasn't done due to hashbrown
not having a const constructor. While it is true that HashMap::new() is
not const, HashMap::with_hasher() is const. HashMap::new() becoming
const is likely blocked on const traits.

This shrinks the kernel image by about 35kb.
2025-09-13 12:00:37 +02:00
bjorn3 9aef07372e Make insert_global panic on errors
All callers unwrap the result anyway
2025-09-12 19:56:14 +02:00
bjorn3 6ae6f571c7 Use cfg!() rather than #[cfg] for configuring lpss_debug 2025-09-12 19:36:17 +02:00
bjorn3 92e5397efa Introduce SerialKind::NotPresent 2025-09-12 19:36:17 +02:00
bjorn3 2394db2dc5 Move most of the arch debug::Writer impls into a common location 2025-09-12 19:36:17 +02:00
bjorn3 fbbe24c82b Use writeln!() rather than print!() + concat!() in println!()
This fixes using format arg captures
2025-09-12 19:36:17 +02:00
bjorn3 b3522b19e6 Replace a writeln!() with println!() 2025-09-12 19:36:16 +02:00
bjorn3 a782c1f9e1 Fix warning about unused function 2025-09-12 19:03:39 +02:00
bjorn3 8aa08e1e3d Unconditionally enable serial_debug on arm64 and riscv64 2025-09-12 18:59:48 +02:00
bjorn3 520453f779 Move x86 serial port assignment to the init function 2025-09-12 18:46:11 +02:00
bjorn3 31cbb3b361 Remove duplicate serial port initialization on x86 2025-09-12 18:41:42 +02:00
bjorn3 7a4dd1a1a9 Use SerialKind on x86 2025-09-12 18:40:21 +02:00
bjorn3 f0eea47896 Fix compilation with lpss_debug feature enabled 2025-09-12 18:33:16 +02:00
bjorn3 eb06f5676f Unify SerialKind between arm64 and riscv64 2025-09-12 18:19:15 +02:00
bjorn3 6ca9a9a806 Move uart_pl011.rs to src/devices 2025-09-12 18:02:30 +02:00
bjorn3 f9a4178898 Always enable graphical_debug
We already gracefully handle a missing framebuffer.
2025-09-11 21:41:30 +02:00
bjorn3 9a2203076a Merge aarch64 and x86/x86_64 debugger implementations
And make the debugger partially work on riscv64.
2025-09-11 20:02:56 +02:00
bjorn3 e131bf219d Merge x86 and x86_64 debugger implementations 2025-09-11 20:02:56 +02:00
bjorn3 d1668e232a Begin deduplicating debugger code between architectures 2025-09-11 20:02:56 +02:00
bjorn3 40605e643e Move stac/clac for SMAP in debugger to just around the stack read loop
This fixes a crash when returning from the debugger on x86_64.
2025-09-11 20:02:56 +02:00
bjorn3 26dd87b1ff Fix debugger feature on arm64
And fix unsafe_op_in_unsafe_fn warnings
2025-09-11 20:02:56 +02:00
bjorn3 38188b0640 Expand a macro invocation 2025-09-10 18:45:13 +02:00
bjorn3 786c9eabcb Share print! and println! between architectures 2025-09-10 18:40:30 +02:00
bjorn3 1268472103 Move arch::x86_64::cpuid into arch::x86_shared::cpuid 2025-09-10 18:35:36 +02:00
bjorn3 ad6c6c5e41 Share external interrupt handlers between x86 and x86_64 2025-09-10 18:31:28 +02:00
bjorn3 5e6d681fcb Share exception interrupt handlers between x86 and x86_64 2025-09-10 18:25:22 +02:00
bjorn3 d6c5d0d268 Move semicolons 2025-09-10 18:25:09 +02:00
bjorn3 35a0f2d440 Remove usage of array_chunks
It has been removed in newer rustc versions
2025-09-10 18:00:02 +02:00
bjorn3 a3700fa446 Remove the unsafe block from the inner function in interrupt!() 2025-09-10 18:00:02 +02:00
Elle Rhumsaa cec902e6be main: refactor unsafe block for C offsets
Uses the `&raw const` syntax to convert the pointer location of static
offsets from C.
2025-09-10 14:55:36 +00:00
bjorn3 fe1c2f460e Fix a bunch of errors and warnings after moving to the 2024 edition 2025-09-10 16:44:36 +02:00
bjorn3 cea93f7647 cargo fix --edition & rustfmt
Or to be precise:
RUST_TARGET_PATH=$(pwd)/targets cargo fix --edition \
--target targets/x86_64-unknown-kernel.json \
--target targets/i686-unknown-kernel.json \
--target targets/aarch64-unknown-kernel.json \
--target targets/riscv64-unknown-kernel.json \
-Zbuild-std=core,alloc --allow-dirty --bin kernel
cargo fmt
2025-09-10 16:44:36 +02:00
bjorn3 ff48830c0b Update rmm submodule 2025-09-10 16:44:33 +02:00
Jeremy Soller 5f983a02fe Merge branch 'edition_2024' into 'master'
Update to the 2024 edition

See merge request redox-os/rmm!16
2025-09-10 08:40:36 -06:00
bjorn3 08c00a434d Update to the 2024 edition
On newer rustc versions let_chain is only allowed with the 2024 edition.
2025-09-10 15:37:19 +02:00
4lDO2 dd366f01c4 Make ForceKilled meaningful, += Dead && SIGKILL. 2025-09-10 13:22:29 +02:00
Paul Sajna 172a0ffd02 remove dtb unwraps 2025-09-07 22:53:39 -07:00
Jeremy Soller 53c3342e9f snps,dw-apb-uart is usually 32-bit mmio 2025-09-07 20:41:28 -06:00
Jeremy Soller f1492729d2 riscv64: support snps,dw-apb-uart serial 2025-09-07 20:36:05 -06:00
bjorn3 5658fc258b Disable debugger feature by default
It currently doesn't compile on aarch64
2025-09-07 13:35:22 +02:00
bjorn3 c404598296 Use cfg!() rather than #[cfg] for the cfg in map_memory 2025-09-07 13:26:04 +02:00
bjorn3 e42fc3811f Fix compiling with profiling feature enabled 2025-09-07 13:20:19 +02:00
bjorn3 b7566e66bd Fix 32bit x86 2025-09-07 13:00:40 +02:00
bjorn3 48f3592bf3 Mostly use cfg!() rather than #[cfg] for controlling syscall_debug
This only adds 40 bytes overhead per cpu core in the PerCpuBlock struct.
2025-09-07 12:38:57 +02:00
bjorn3 fefede0d67 Use cfg!() rather than #[cfg] for controlling self_modifying 2025-09-07 12:30:33 +02:00
bjorn3 b5822ac118 Mostly use cfg!() rather than #[cfg] for controlling sys_stat
This only adds 48 bytes overhead per cpu core in the PerCpuBlock struct.
Also fixes compilation with sys_stat enabled on x86_64.
2025-09-07 12:27:04 +02:00
bjorn3 0a58e9e806 Allow cfg(dtb) for check-cfg 2025-09-07 12:03:37 +02:00
bjorn3 f05be85966 Use cfg!() rather than #[cfg] for controlling multi_core 2025-09-07 12:02:16 +02:00
bjorn3 d6e9022c4a Rustfmt 2025-09-06 17:10:32 +02:00
bjorn3 869a664172 Remove allow(unexpected_cfgs) 2025-09-06 17:06:31 +02:00
bjorn3 cf019ab9a5 Remove some unused unsafe blocks 2025-09-06 16:51:05 +02:00
bjorn3 c4c605630a Remove an allow(unused) for the elf module 2025-09-06 16:49:45 +02:00
bjorn3 7975d2aa8f Remove Unique
It is only used for AlignedBox which can just directly implement Send
and Sync. Additionally make the Send and Sync impls more restrictive by
requiring the inner type to be Send cq Sync, previously AlignedBox was
always Send and Sync, which is not sound.
2025-09-06 16:23:30 +02:00
bjorn3 afed3bc84b Fix a couple of warnings 2025-09-06 16:17:05 +02:00
bjorn3 7f63a5c8f0 Don't mark irq_trigger as no_mangle 2025-09-01 17:19:09 +00:00
Jeremy Soller c6f38f05e4 Disable multi_core again (for demo) 2025-08-28 10:00:16 -06:00
Wildan Mubarok 7d91390f04 Detect if ARM virtual timer should be used 2025-08-16 12:58:09 +00:00
Wildan Mubarok e071bdcef4 Use ARM virtual timer to fix HVF acceleration 2025-08-16 11:20:48 +00:00
Wildan M 39cb82d91d Optimize graphical debug scrolling 2025-08-09 18:30:51 +07:00
lebakassemmerl 6bf8c0c26c fix build-error on aarch64 and probably on riscv 2025-08-04 20:39:02 +02:00
Wildan Mubarok 1ff46c8482 Fix Linter CI 2025-08-04 06:34:31 -06:00
Jeremy Soller af7591bc26 Clarify vector number in IPI 2025-08-03 20:56:18 -06:00
Jeremy Soller 5d06ad4e6a Ensure that APIC ID is uses for all IPIs, enable multi_core feature 2025-08-03 20:53:58 -06:00
Jeremy Soller b4f566dab2 Rebuild if Cargo.toml or Cargo.lock change 2025-08-03 16:04:49 -06:00
Wildan Mubarok c67fc7b099 Backfill aarch64 serial log 2025-07-31 03:22:52 +00:00
Ibuki Omatsu e3d8ae1b79 feat: Introduce FdTbl and make Context.files use it for separate file tables. 2025-07-30 15:33:06 -06:00
Darley Barreto 66ea2b46ee Adding openat syscall 2025-07-13 06:43:20 -06:00
bjorn3 caf5fa955b Fix freeing of phys_contiguous frames
Previously the deallocation would be rounded to the next power of two
preventing partial deallocation. But more importantly previously trying
to free phys_contiguous frames while another processes still borrows
them. Now this should just cause the deallocation to be delayed.
2025-07-06 16:13:13 +02:00
bjorn3 08ea1da2f9 Trigger read event for user schemes when an fd is closed 2025-07-05 17:54:19 +02:00
bjorn3 7a440bcd67 Merge close and on_close scheme calls 2025-07-05 16:59:08 +02:00
bjorn3 48ad866d02 Add some explanation to the multi_core todo 2025-06-28 20:16:29 +02:00
bjorn3 751803553f Unify paging between x86 and x86_64 2025-06-28 20:09:16 +02:00
bjorn3 ba66388ca7 Unify rmm.rs between x86 and x86_64 2025-06-28 20:03:06 +02:00
bjorn3 b06aa61676 Remove reference to no longer existing 3dnow target feature
This silences a lot of warnings.
2025-06-28 19:58:15 +02:00
bjorn3 219dedda32 Unify start.rs between x86 and x86_64 2025-06-28 19:57:52 +02:00
bjorn3 ba051b781f Shorten the message about the RSDP 2025-06-28 19:37:56 +02:00
bjorn3 1864f12913 Make the HPET debug logs more compact 2025-06-28 19:37:56 +02:00
bjorn3 2a2139c46e Fix a couple of warnings 2025-06-28 19:37:56 +02:00
bjorn3 e77257bb6e Remove unused core_intrinsics feature gate 2025-06-28 19:37:56 +02:00
Ibuki Omatsu 90643abbad feat: Store caller's PID in Sqe during SYS_CALL 2025-06-25 08:44:51 -06:00
Wildan Mubarok fa907f02ae Move aarch64 interrupt init func 2025-06-25 08:37:50 -06:00
Jeremy Soller f32d018d85 Format 2025-06-13 20:26:41 -06:00
Jeremy Soller 5b88d1a845 Debug using pid 2025-06-13 20:26:35 -06:00
Jeremy Soller 22cc551450 Sort /scheme/sys files 2025-06-13 20:26:21 -06:00
Ivan Tan e67cca7bce raspi3b+: sloved programs can not be waken up on time from sleep 2025-05-19 15:27:35 +08:00
Ivan Tan f5aeb0b43a implement monotonic for aarch64 2025-05-13 15:30:45 +08:00
Jeremy Soller 407c0c1403 Disable syscall debug 2025-05-06 08:21:09 -06:00
Jeremy Soller d712ff5158 Add flink 2025-05-03 12:25:46 -06:00
4lDO2 4a1cd73da4 Fix same-thread scheme use-after-free. 2025-04-26 16:33:10 +02:00
bjorn3 03ebb3491b Show pid of process on unhandled exceptions 2025-04-24 20:53:50 +02:00
bjorn3 8e6ff4341e Don't crash on GICv3
Serial input is still broken though.
2025-04-21 16:56:12 +02:00
bjorn3 75edd1d34c Fix infinite panicking when panicking during early boot 2025-04-21 16:44:27 +02:00
4lDO2 9be617132a Fix 'sys:exe' as required by libstd. 2025-04-20 14:09:31 +02:00
4lDO2 98999e76b2 Fix sendfd error handling. 2025-04-20 13:57:37 +02:00
4lDO2 952b1483d8 Pass the sendfd arg: u64 to userspace. 2025-04-20 12:36:33 +02:00
4lDO2 f7d413e1bb Use redox-os/syscall for git dep. 2025-04-19 19:23:57 +02:00
4lDO2 e6df56cf1b Use saner debug IDs for kmain. 2025-04-19 16:30:49 +02:00
4lDO2 6ed49d2ecb Reduce outdated header in sys/context. 2025-04-19 16:30:49 +02:00
4lDO2 1e3e961b78 Simplify context debug names. 2025-04-19 16:30:49 +02:00
4lDO2 22afbde451 Fix being_sigkilled todo! 2025-04-19 16:30:49 +02:00
4lDO2 1227f2222e Fix compilation on riscv64gc. 2025-04-19 16:30:48 +02:00
4lDO2 4d49f1a8e4 Refer to NLnet funding. 2025-04-19 16:30:48 +02:00
4lDO2 9447986889 Remove ksignal from aarch64. 2025-04-19 16:30:48 +02:00
4lDO2 b13ef6ada3 Fix i686. 2025-04-19 16:30:48 +02:00
4lDO2 2e6122bc7e Allow procmgr to recognize unhandled exceptions. 2025-04-19 16:30:48 +02:00
4lDO2 020b8ad415 Compile on aarch64. 2025-04-19 16:30:48 +02:00
4lDO2 10c53aef10 Remove RtSigInfo import. 2025-04-19 16:30:48 +02:00
4lDO2 10ef631fc3 Remove WaitMap from existence. 2025-04-19 16:30:48 +02:00
4lDO2 f3af1be69f Never return from ForceKill caller. 2025-04-19 16:30:48 +02:00
4lDO2 3a17f50ea8 Remove ContextHandle::Signal. 2025-04-19 16:30:47 +02:00
4lDO2 fa6dee36da Report all being_sigkilled contexts as Dead. 2025-04-19 16:30:47 +02:00
4lDO2 5df7031eb1 Add Interrupt ContextVerb. 2025-04-19 16:30:47 +02:00
4lDO2 ab11e6b346 Support stopping contexts, by procmgr. 2025-04-19 16:30:47 +02:00
4lDO2 2f977bbc52 Support getting intra-page off and mapping sig [tp]ctl. 2025-04-19 16:30:47 +02:00
4lDO2 e002d0be33 Remove commented-out syscalls and SigState.rtqs 2025-04-19 16:30:47 +02:00
4lDO2 cb1a838f05 Start moving kill to procmgr. 2025-04-19 16:30:47 +02:00
4lDO2 d0e09d9e87 Remove SYS_IOPL and SYS_VIRTTOPHYS debug. 2025-04-19 16:30:47 +02:00
4lDO2 ef78ac57b0 Add fd-based virttophys replacement. 2025-04-19 16:30:47 +02:00
4lDO2 b4b2ac312b Add interface for setting iopl. 2025-04-19 16:30:46 +02:00
4lDO2 2815800164 Support reading context status. 2025-04-19 16:30:46 +02:00
4lDO2 7b06ca16b1 Make thread kill API async. 2025-04-19 16:30:46 +02:00
4lDO2 f40ec48b3e Send event on thread death. 2025-04-19 16:30:46 +02:00
4lDO2 db5931504d Remove nonexisted import. 2025-04-19 16:30:46 +02:00
4lDO2 ce77a018ec Reach init again, with proc mgr. 2025-04-19 16:30:46 +02:00
4lDO2 a9fb2dcb93 Simplify proc scheme security. 2025-04-19 16:30:46 +02:00
4lDO2 0ccc825bfb Patch syscall. 2025-04-19 16:30:46 +02:00
4lDO2 a78d36f7f2 Reach init in userspace. 2025-04-19 16:30:46 +02:00
4lDO2 6d1a3e9a4c Convert Handle::Context -> Handle. 2025-04-19 16:30:45 +02:00
4lDO2 2a5bd36899 Reimplement context creation. 2025-04-19 16:30:45 +02:00
4lDO2 8883818501 Make kernel compile. 2025-04-19 16:30:45 +02:00
4lDO2 1d5f8fd46d Move proc code to userspace. 2025-04-19 16:30:42 +02:00
Andrey Turkin 1b9fcbf593 riscv: Remove SBI logger
SBI needs a physical address; it used to work before because of the buggy code by sheer chance.
Rather than trying to fix it the right way (find a mapping from virtual to physical both before
and after RMM) let's just throw it away. Serial logger works just fine for the early init logging.
2025-04-19 10:03:35 +03:00
Jeremy Soller e5f4795024 Fix riscv64 ABI 2025-04-17 20:01:14 -06:00
Jeremy Soller fab76e7dca Fix compilation on riscv64 2025-04-17 15:34:24 -06:00
4lDO2 5d41cd7c53 Remove unimplemented itimer scheme. 2025-04-13 18:13:00 +02:00
bjorn3 f5f877ca22 Fix saving and restoring of float registers on arm64 2025-04-12 17:11:04 +02:00
Jeremy Soller a926baefaf aarch64 fp_load/fp_save do not need to be naked
There is a bug with LLVM and Rust causing naked functions to not support
target_enable directives.

https://github.com/rust-lang/rust/issues/136280
2025-04-12 08:14:38 -06:00
Jeremy Soller 551443d641 Revert "aarch64 must have fp-armv8 feature to use some instructions"
This reverts commit a24192235e.
2025-04-12 08:05:55 -06:00
Jeremy Soller 0140e2a382 Fix compilation of emergency_stop on x86 2025-04-11 20:55:56 -06:00
Jeremy Soller a24192235e aarch64 must have fp-armv8 feature to use some instructions 2025-04-11 18:26:09 -06:00
Jeremy Soller 25f422b53f Update data layout for aarch64 2025-04-11 18:20:35 -06:00
4lDO2 f4d643e87c Fixes for netstack cancellation to work. 2025-04-10 19:32:41 +00:00
bjorn3 8f589f7b88 Disable graphical debug only once writing to the fd
This allows obtaining an fd for this before calling setrens while doing
the actual disabling after calling it.
2025-04-06 17:13:26 +02:00
4lDO2 81374e6f7b Add support for CallFlags::CONSUME. 2025-04-06 15:50:32 +02:00
Jeremy Soller ceccc40a1d Disable multi_core feature 2025-04-04 14:25:26 -06:00
4lDO2 ef5de94150 Use sys scheme for kstop rather than signals. 2025-03-31 14:59:00 +02:00
4lDO2 92fcb4472b Use more reliable triple fault for emerg..._reset. 2025-03-31 14:58:05 +02:00
4lDO2 3ae117b812 Outsource x86 RTC handling to rtcd. 2025-03-30 15:28:25 +02:00
Jeremy Soller ce60a7939e Update redox_syscall in Cargo.lock 2025-03-20 10:50:39 -06:00
bjorn3 23fd308745 Reduce verbosity of debug logs during booting
A bunch of things are now printed a bit more compactly or without
interleaving of logs on a single line. Also a bunch of not that useful
logs are no longer printed by default at all.
2025-03-15 20:52:06 +01:00
bjorn3 81210b9ed0 Update and re-enable the legacy scheme deprecation warnings
I've tested booting, several cosmic apps and netsurf as not causing any
warning with the new set of exclusions and all my recent MR's merged.
2025-03-13 18:51:37 +01:00
Jacob Lorentzon 4607576006 Implement bidirectional SYS_CALL support 2025-03-03 23:21:56 +00:00
Ribbon 8f24d894eb Fix a typo on the documentation command in the README 2025-03-03 07:41:42 +00:00
Ron Williams ba613ce628 Nanosleep: Return time remaining after interrupt 2025-02-26 21:00:23 +00:00
Majoneza 06f2c93140 chore: validate_region return PageSpan
Changed validate_region function to return PageSpan instead of a tuple. All the code
using validate_region function was updated to use PageSpan as well.
2025-02-25 23:38:38 +01:00
Vincent Berthier 2da88c18c0 Add the sys:stat scheme 2025-02-22 14:27:10 +00:00
4lDO2 84632ab708 Disable warning when opening "old" schemes. 2025-02-21 16:56:53 +01:00
4lDO2 ef0758b9cc Always use close message when available. 2025-02-21 16:50:16 +01:00
4lDO2 7295777985 Add one-way close message for schemes. 2025-02-21 15:56:05 +01:00
4lDO2 f044ffb03b Remove stable #![feature] and most x86_64 static mut. 2025-02-21 14:16:58 +01:00
4lDO2 09eaf12201 Add optional fdstat sys scheme statistic. 2025-02-19 11:55:18 +01:00
Anhad Singh 79de74bf3a fix(scheme/itimer): wrong chunk size
Chunk size of the scheme (`size_of::<ITimerScheme>() == 0`) was being
provided instead of `size_of::<ITimerSpec>()`. This resulted in a kernel
panic (division by zero) when kread was called for this scheme.

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2025-01-16 03:10:01 +00:00
Jeremy Soller 7a530cf0ec Update dependencies 2025-01-14 15:59:14 -07:00
Jeremy Soller 668a123b9a Switch to naked_asm 2025-01-14 15:59:07 -07:00
Ribbon 495c3708f3 Document how to contribute and do development in the README 2025-01-09 12:00:00 +00:00
Andrey Turkin 7db6667e6b Better parsing of IRQ specifications in DTB
Fixes Raspberry 3B+ DTB parsing (as generated by Qemu)
2024-12-18 21:11:46 +03:00
Andrey Turkin 7f38f51b20 dtb: Apply bus mappings 2024-12-18 21:11:46 +03:00
Zhouqi Jiang 52763e7e70 arch: riscv64: use sbi-rt crate to process SBI calls, save code sizes 2024-12-18 14:06:08 +00:00
Anhad Singh d4797bbf50 chore: update redox_syscall
Signed-off-by: Anhad Singh <andypython@protonmail.com>
2024-12-12 13:34:49 +11:00
Anhad Singh af36ae12b0 fix(mremap): fix referencing
Before it was first add_ref'ed by `borrow_frame_enforce_rw_allocated`,
manually and then by `allocated_shared_one_page`.

Now it is only done by `borrow_frame_enforce_rw_allocated` and does not
get unref-ed as take() is called on the returned `RaiiFrame`.

Now the page is manually mapped and an `Allocated` type grant is
constructed (synonymous to `MAP_PRIVATE`). Before by using `allocated_shared_one_page`
an `AllocatedShared` provided grant was constructed (synonymous to
`MAP_SHARED`), which was wrong as the TCB would've not got CoW-ed
after fork(), making the Tcb malformed.

Signed-off-by: Anhad Singh <andypython@protonmail.com>
2024-12-11 16:37:01 +11:00
Anhad Singh 08231eb4df feat(mremap): KEEP_OLD
Signed-off-by: Anhad Singh <andypython@protonmail.com>
Co-authored-by: @4lDO2
2024-12-11 16:08:08 +11:00
Andrey Turkin 7af6dd1f88 Restore riscv,plic0 compatible check 2024-11-07 05:09:24 +03:00
Andrey Turkin 9fe8f759af Fix formatting and a warning 2024-11-06 12:13:13 +03:00
Andrey Turkin ee89d02282 Change PLIC compatible string from riscv,plic0 to sifive,plic-1.0.0
Former one is deprecated and apparently only used by QEMU. Latter is used by QEMU as well as others.
2024-11-06 12:09:36 +03:00
Jeremy Soller 99fbdf426c Fix assumption that CPU ID must equal APIC ID 2024-11-04 14:46:46 -07:00
Andrey Turkin 7b1d135057 Use redoxer for CI jobs 2024-11-01 06:51:13 +03:00
Jeremy Soller 4db9673e2a Support SPCR and clean up device memory allocation 2024-10-31 10:53:58 -06:00
Arthur Paulino e19c1404f7 chore: enrich context/switch
* Add documentation and more code comments to `src/context/switch.rs`
* Eliminate a `context.wake.expect(...)` where `context.wake.is_some()`
* Eliminate a TODO item about updating contexts' timestamps in `switch_to`
* Eliminate a dangling `else { continue }` at the end of the loop that iterates
  on contexts
2024-10-31 10:22:21 +00:00
Jeremy Soller df9db9291a Fix AP CPU ID on newer Intel CPUs 2024-10-30 21:09:06 -06:00
Jeremy Soller 9b6d1549b5 Support GTDT for aarch64 2024-10-30 18:17:11 -06:00
Jeremy Soller 34a6a441f1 Initial aarch64 ACPI support 2024-10-30 16:16:24 -06:00
Jeremy Soller b221bb6c51 Make it possible to boot aarch64 with invalid DTB 2024-10-30 12:34:50 -06:00
Jeremy Soller 4dd6a26742 Make it possible to compile acpi system on any arch 2024-10-30 11:43:21 -06:00
Jeremy Soller 939c9567ee Support 16550 uarts for aarch64 debug output 2024-10-29 14:06:00 -06:00
Jeremy Soller 161e578f29 Use null driver for unknown IRQ controllers on aarch64 2024-10-29 08:01:38 -06:00
Jeremy Soller 380532aea5 Improve reliability of aarch64 startup code 2024-10-29 08:00:57 -06:00
Jeremy Soller 15b0133b7b Add arm,gic-400 support to GIC driver 2024-10-29 08:00:17 -06:00
Jeremy Soller e4e55103ad Remove old aarch64 asm code 2024-10-29 07:59:12 -06:00
Arthur Paulino ea0356b26a Address minor warts
* Mention the need to have `nasm` available on the PATH in the README
* Replace the deprecated `hide_parse_errors` by `show_parse_errors` in `rustfmt.toml`
* Mark unused variables in `src/scheme/proc.rs`
2024-10-27 18:14:12 -03:00
Andrey Turkin 8dcf850919 Update rmm 2024-10-23 04:06:26 +03:00
Jeremy Soller 63669069f4 Merge branch 'bump_fix' into 'master'
Fix a bump allocator error

See merge request redox-os/rmm!15
2024-10-22 21:26:17 +00:00
Andrey Turkin 91ccf4e6aa Fix a bump allocator error 2024-10-22 22:14:39 +03:00
Andrey Turkin 505425bec9 Expose riscv64/aarch64 legacy irqs (requiring remapping) to the irq scheme 2024-10-22 20:26:40 +03:00
Andrey Turkin cba02a26fa Rework irqchip to support risc-v irqs, and add risc-v irq chips handling 2024-10-22 19:16:21 +03:00
Andrey Turkin 906259c024 Pull irqchip from aarch64 code into more generic place 2024-10-21 19:56:32 +03:00
Jeremy Soller 6a731d0c84 Delete syscall directory 2024-10-20 07:31:35 -06:00
Andrey Turkin 1921c6814b Initial RISC-V implementation
Has no IRQ handling yet
2024-10-20 16:24:21 +03:00
Andrey Turkin db32f5f7a3 Move some conditionally compiled code from common files into arch-gated files 2024-10-19 21:59:14 +03:00
Andrey Turkin 55041e2eeb Use a custom config flag to conditionally compile DTB-specific areas
Would be great if we could use a feature instead, but Cargo can't do target-specific defaults features
2024-10-19 21:03:43 +03:00
Andrey Turkin 0a6a90415a Refactor initial memory paging 2024-10-19 08:44:46 +03:00
James 3fbd52a212 Made a change in context to the way arrays are resized. Slight change to the logic but resize_with should be slightly more efficient 2024-10-15 21:24:32 +11:00
Ron Williams 865122e92f Fix serial console login 2024-10-10 18:45:14 +00:00
4lDO2 0965c1e22b Allow aarch64 test to fail. 2024-10-07 10:20:51 +02:00
4lDO2 8d4ee26ff1 Fix profiling && + toggle support via debug scheme. 2024-10-07 10:20:51 +02:00
Dmitry Mottl dc1ba28f91 Updates .helix config to the new file format 2024-10-01 14:36:11 +00:00
4lDO2 ad16b747ea Restrict auto-fcntl to non-v2 schemes. 2024-09-27 21:36:22 +02:00
IncompententPirate fc5d246b30 remove wrapper functions 2024-09-26 22:34:55 +00:00
Andrey Turkin 14eb140f7a Refactor panic stack walking 2024-09-26 19:22:21 +03:00
Andrey Turkin 755694494b Factor KernelMapper out of arch
Same implementation on all the platforms. Also remove mutable Deref as it allowed circumventing RO check
2024-09-25 21:51:39 +03:00
4lDO2 539dc5a24e Remove SYS_UMASK. 2024-09-25 19:55:39 +02:00
Andrey Turkin d08861e586 Upgrade fdt library to the very latest
The new helpers remove a lot of boilerplace. Unfortunately some rough edges still remain (in particular issue gh#12 which renders interrupts() helper useless)
2024-09-25 06:51:02 +03:00
4lDO2 32e114885b Update RMM. 2024-09-24 19:33:27 +02:00
4lDO2 0a3ce63d40 Update syscall 2024-09-24 19:18:23 +02:00
4lDO2 71538efc06 Allow thread exit to optionally deallocate stack. 2024-09-24 19:18:23 +02:00
4lDO2 9a0192fc94 Prevent duplicate idempotent signals. 2024-09-24 19:18:23 +02:00
4lDO2 fcb2e2be3a Pass si_uid and si_pid to kill signals. 2024-09-24 19:18:23 +02:00
4lDO2 7def7ce6e3 Extend size of sig{en,de}queue payload. 2024-09-24 19:18:22 +02:00
4lDO2 54b1fbe453 Implement queued signals.
This currently needs to be done in the kernel for synchronization
reasons, but it's possible all delivery parts can later be moved to
userspace.
2024-09-24 19:18:22 +02:00
4lDO2 6d9cf30445 WIP: realtime signals 2024-09-24 19:18:20 +02:00
Andrey Turkin dbbbfcf48a Update RMM 2024-09-24 19:23:08 +03:00
Jeremy Soller edb3a87578 Merge branch 'riscv' into 'master'
Fixes and changes to make RISC-V paging work

See merge request redox-os/rmm!14
2024-09-24 12:51:39 +00:00
Andrey Turkin ed8bcfca1f Add write combining page flags where applicable 2024-09-24 08:26:02 +03:00
Andrey Turkin 192dd8283f RISC-V: implement TLB flush 2024-09-24 08:26:01 +03:00
Andrey Turkin f51cd00f00 Remove read/write flags from common PDE flags.
RISC-V convention marks PDE with no read/write/execute, so we can't have none of this flags set there. Remove their setting from PDE handling code and instead set them as appropriate in arch-specific defaults.

Also enable both readonly and readwrite flags to be non-zero (as long as their intersection completely masks both of them), as required for RISC-V PTE handling.
2024-09-24 08:24:18 +03:00
Andrey Turkin a96ea6f5f3 Allow physical address bits be anywhere in PTE entry
Before this commit, RMM assumed base physical address was presented in PTE as is, i.e. physical page address was shifted exactly to PAGE_SHIFT, so physical address can be extracted from PTE by simply masking off some bits and can be placed in PTE by simple addition/OR.

This is not the case for RISC-V which has 4Kb base page so 12 bits PAGE_SHIFT, yet physical page address is only shifted 10 bits in PTE.

This commit removes this assumption.

 NOTE: This commit changes meaning of constants:
 * ENTRY_ADDRESS_SIZE from "total physical size in bytes" to "total physical size in PAGES"
 * ENTRY_ADDRESS_MASK from "mask of physical bits in PTE" to "mask of physical bits starting at bit 0"
2024-09-23 08:47:27 +03:00
Andrey Turkin b7d3acf606 Separate leaf page and directory pages USER flag
This is required for RISC-V. Privileged spec says:

> For non-leaf PTEs, the D, A, and U bits are reserved for future standard use.
> Until their use is defined by a standard extension, they must be cleared by software
> for forward compatibility.

QEMU fails address translation if it sees any of these flags set on non-leaf page entry.
2024-09-23 08:47:23 +03:00
4lDO2 b485b1b3ea Update RMM. 2024-09-22 15:22:01 +02:00
Jeremy Soller bb27f57228 Merge branch 'fix_bump' into 'master'
Fix bump allocator initialization

See merge request redox-os/rmm!13
2024-09-22 13:20:33 +00:00
4lDO2 d95ea6598f Fix bump allocator. 2024-09-22 10:27:06 +02:00
4lDO2 960e79b107 Treat broken pipes as IO-capable in fevent. 2024-09-19 10:41:40 +02:00
4lDO2 ce9f699f8f Add unit tests to CI. 2024-09-17 23:10:36 +02:00
4lDO2 d498eefb2f Disable userspace feature in redox-syscall.
This prevents the kernel from being able to accidentally call itself
using the syscall instruction.
2024-09-17 19:24:26 +02:00
4lDO2 ef499f81fc Support compiling for host, allowing unit tests. 2024-09-17 19:24:23 +02:00
4lDO2 a0d0eac8aa Optimally divide responsibility for borrow free.
This appears to slightly improve performance.
2024-09-14 10:49:40 +02:00
4lDO2 031fdea089 Discard empty names in root scheme getdents. 2024-09-13 15:26:24 +02:00
4lDO2 97ea7ea6ec Disable syscall debug 2024-09-12 10:29:11 +02:00
4lDO2 e3e05ebca8 Fix root scheme order by using indexmap (tmp). 2024-09-11 22:09:29 +02:00
4lDO2 97f60de4ef WIP: Add getdents opaque_id 2024-09-11 22:09:29 +02:00
4lDO2 339271b4d7 Add getdents syscall, and switch schemes to it. 2024-09-11 22:09:26 +02:00
Kamil Koczurek 548fd63264 tsc: calculate elapsed ticks using saturating_sub
RDTSC readouts might not actually be monotonically increasing due to
desynchronization between CPU cores, so checked_sub was causing a kernel
panic.
2024-09-10 14:16:38 +02:00
4lDO2 652cdc7ef2 Replace repr(packed) with repr(C, packed). 2024-09-08 20:56:50 +02:00
4lDO2 5f9a587968 Convert repr(packed) to repr(C, packed). 2024-09-08 20:48:05 +02:00
4lDO2 815ac3da4a Revert "Fix possible UB in rmm::init."
This reverts commit 4626c74b78.
2024-09-08 20:22:46 +02:00
4lDO2 9673fa26b6 Expand Cargo features to separate lines.
This is much more diff- and by extension rebase-friendly.
2024-09-08 00:09:49 +02:00
4lDO2 4626c74b78 Fix possible UB in rmm::init.
I tested compiling the kernel with a more recent rustc, and this
triggered UB. Don't know for sure why there was an invalid entry passed
to the kernel, but it did.
2024-09-07 23:14:55 +02:00
Jeremy Soller 0c99e1bd0a Set xcr0 in all cases 2024-09-06 20:08:40 -06:00
Jeremy Soller 1c00450127 Use 64-bit versions of xsave and xrstor 2024-09-04 21:22:10 -06:00
4lDO2 09e7e66e00 Move scheme borrow unmap to cqe write. 2024-09-04 19:23:21 +02:00
4lDO2 181df19b24 Update rmm 2024-09-04 19:23:19 +02:00
Andrey Turkin a558860e88 Fix BSS sanity check
mark the canaries mutable so they go into data and bss and not in rodata
2024-09-04 10:55:20 +03:00
Andrey Turkin 7a9a5f024f Validate bootstrap memory allocation 2024-09-04 10:55:16 +03:00
Andrey Turkin ba154c0387 Fix a debug-build assertion
A range of usable memory could be small enough not to have any MAX_ORDER sized frames.
2024-09-04 10:55:11 +03:00
Andrey Turkin d2ebc7ff05 Wholesale fix of warnings
Pretty straightforward changes. This commit tries to avoid making any non-trivial fixes.
2024-09-04 10:55:01 +03:00
Jacob Lorentzon 643d7400db Implement paravirtualized KVM TSC support 2024-09-03 21:20:06 +00:00
bjorn3 d43eb74da3 Use softfloat abi in the target spec for aarch64
This allows removing the -Csoft-float argument when building.
2024-09-03 14:30:11 +00:00
Jeremy Soller ea4cfb2cbf Merge branch 'fix' into 'master'
Revived tests

See merge request redox-os/rmm!12
2024-09-02 21:16:38 +00:00
4lDO2 441385ddb2 Always map the kernel itself using global pages.
This avoids TLB stalls after context switching, that are very visible
from flamegraphs.
2024-08-31 10:44:54 +02:00
Ron Williams 19cd3ad287 Fix APIC reference in profiling.rs 2024-08-26 21:06:47 -07:00
Ron Williams 12eca4a0f5 Comment out error message for old scheme path 2024-08-26 11:51:01 -07:00
Ron Williams 47799a896d Don't warn about path for COSMIC apps 2024-08-24 11:49:49 -07:00
bjorn3 0876bed222 Remove a couple of exceptions from the deprecated scheme syntax warning 2024-08-19 19:13:42 +02:00
bjorn3 d4b979fb21 Log a deprecation message for usage of the legacy scheme syntax 2024-08-18 22:05:51 +02:00
Jeremy Soller 5cb6af6b8c Fix aarch64 build 2024-08-01 13:00:59 -06:00
bjorn3 f55da93b33 Fix building for AArch64
I broke this in !321
2024-08-01 20:45:59 +02:00
bjorn3 8f186a692f Allow writing messages to debug: without preserving them in sys:log
This would allow logd to write all received log messages to debug:
without causing an infinite loop when it at the same time reads all
messages in sys:log.
2024-07-25 12:49:43 +02:00
4lDO2 4158d899b5 Probably fix TLB shootdown "diagonal" livelock.
Diagonal as in

Thread A        Thread B
Send to B       Send to A
Wait for B      Wait for A.

I haven't reproduced this bug, but this should fix it, since the wait
steps now checks the local percpu block for pending TLB shootdowns onto
itself.
2024-07-24 22:48:56 +02:00
4lDO2 49b94047a8 Fix significant memory leak. 2024-07-24 22:48:56 +02:00
bjorn3 e7a46c3422 Let userspace control when graphical_debug gets disabled
Rather than disabling it right before entering userspace. This allows
showing debug messages while the graphics subsystem hasn't initialized
yet.
2024-07-24 20:59:40 +02:00
bjorn3 34cab9edba Fix typos and call graphical_debug::init_heap on arm64 2024-07-24 18:48:27 +02:00
bjorn3 98c28a3d60 Store a raw pointer in Display for the framebuffer 2024-07-24 17:45:31 +02:00
bjorn3 befd5175bb Limit visibilities 2024-07-24 17:10:35 +02:00
bjorn3 ebc4aeac85 Enable graphical_debug for aarch64
This doesn't give any issues both for UEFI boot (with framebuffer
present) and U-Boot boot (without framebuffer present).
2024-07-24 17:03:29 +02:00
bjorn3 e0855d0cb6 Fix typo 2024-07-22 16:47:35 +02:00
bjorn3 d3ccba0943 Avoid int2ptr cast in DebugDisplay 2024-07-22 14:26:44 +02:00
bjorn3 a89f93ff00 Move all drawing code from Display to DebugDisplay 2024-07-22 14:22:15 +02:00
bjorn3 dc36d18812 Remove unnecessary discard of return value in debug::Writer 2024-07-22 14:15:20 +02:00
4lDO2 51c4be10e0 Allow waitpid to be interrupted. 2024-07-20 23:17:31 +02:00
4lDO2 005635083d Fix thread cleanup during active file ops.
This fixes a bug where the window of `viewer` does not exit, due to a
leaked file descriptor.
2024-07-20 22:14:54 +02:00
4lDO2 29170ccbc7 Fix sigchld test. 2024-07-18 19:38:47 +02:00
4lDO2 05bde858f9 Fix SIGCONT deadlock. 2024-07-18 16:47:16 +02:00
4lDO2 daa11c911f Fix syscall debug, more success in sigchld test. 2024-07-18 16:14:07 +02:00
4lDO2 c54195f10d Ensure process signals can also interrupt. 2024-07-17 17:31:05 +02:00
4lDO2 2d50055dfb WIP: support thread/process-specific kill. 2024-07-17 15:29:05 +02:00
4lDO2 3c540efb00 Support sending signals to individual threads. 2024-07-16 22:06:21 +02:00
4lDO2 8de850e7e9 Ensure all threads stop in exit(). 2024-07-16 20:33:37 +02:00
4lDO2 79bbf79656 Fix some proc scheme FIXMEs. 2024-07-16 20:28:17 +02:00
4lDO2 cc465c008b Remove rustc hack. 2024-07-16 19:52:18 +02:00
4lDO2 bda12fe55e Print MXCSR in the SIMD exception handler. 2024-07-16 13:14:42 +02:00
4lDO2 cde108439c Fix kill deadlock. 2024-07-16 13:05:42 +02:00
4lDO2 6bd01513c5 Simplify and improve thread/process cleanup. 2024-07-15 18:08:43 +02:00
4lDO2 a3dedb0639 Do proper resource cleanup for thread exit too. 2024-07-15 18:08:43 +02:00
4lDO2 8259ed281c Boot to desktop with process/context changes. 2024-07-15 18:08:43 +02:00
4lDO2 40f5c01586 Flatten syscall match statement. 2024-07-15 18:08:43 +02:00
4lDO2 e67c040f69 WIP: Separate process status from context status. 2024-07-15 18:08:43 +02:00
4lDO2 7fbe5c72e9 Use strong references in context set. 2024-07-15 18:08:42 +02:00
4lDO2 80fe891c6e WIP: Replace ContextId with direct Arcs. 2024-07-15 18:08:42 +02:00
4lDO2 038ff03996 Fix waitpid and improve debug. 2024-07-15 18:08:42 +02:00
4lDO2 0de23a1141 Use correct context for proc scheme 'new-thread'. 2024-07-15 18:08:42 +02:00
4lDO2 4202bc3ba0 WIP: add new-thread 2024-07-15 18:08:42 +02:00
4lDO2 208d74899a Fix fork & process creation, now boots to desktop. 2024-07-15 18:08:42 +02:00
4lDO2 25974bec6e It compiles. 2024-07-15 18:08:42 +02:00
4lDO2 de1bd46c84 Make proc scheme almost compile. 2024-07-15 18:08:42 +02:00
4lDO2 89d532a267 Fix half of proc scheme errors. 2024-07-15 18:08:42 +02:00
4lDO2 89d1d49a4e Fix most code except proc scheme. 2024-07-15 18:08:41 +02:00
4lDO2 8f452b0b0f WIP: continue the process transition 2024-07-15 18:08:41 +02:00
4lDO2 0da2fce64a Separate context and process IDs. 2024-07-15 18:08:41 +02:00
4lDO2 74b824f40f Add rustfmt to CI. 2024-07-15 17:54:27 +02:00
4lDO2 d94baa2712 Run rustfmt. 2024-07-15 17:50:18 +02:00
4lDO2 f3532f4549 Fix static mut ref warnings. 2024-07-15 17:48:46 +02:00
4lDO2 5e7db80285 Fix a bunch of warnings. 2024-07-15 17:48:45 +02:00
4lDO2 c86f107344 Switch back to upstream syscall submodule. 2024-07-15 17:20:58 +02:00
4lDO2 9259a36f5e Run more of sigchld test correctly. 2024-07-15 17:20:58 +02:00
4lDO2 5abbcd8e34 Send SIGCHLD to parent after child stop/exit. 2024-07-15 17:20:57 +02:00
4lDO2 d70ad544e6 Fix SIGKILL and allow SYS_EXIT to pass 16 bits. 2024-07-15 17:20:57 +02:00
4lDO2 8f3e40a99e Fix aarch64 compilation. 2024-07-15 17:20:57 +02:00
4lDO2 465128da26 Don't block nanosleep/futex <= signals are pending. 2024-07-15 17:20:57 +02:00
4lDO2 9198ee7e52 Reimplement shutdown and restart. 2024-07-15 17:20:57 +02:00
4lDO2 4dba818c83 Check pending unblocked signals before blocking.
This is not a perfect solution, since the kernel technically already has
all the information it needs to synchronize this between the kill()
invocation and the time WaitCondition::wait is called, but it should not
have any noticeable performance impact.
2024-07-15 17:20:57 +02:00
4lDO2 e9de24c097 Only return EINTR in kill() if self was killed. 2024-07-15 17:20:57 +02:00
4lDO2 965f5879b7 Never clear sig pending bits in the kernel. 2024-07-15 17:20:57 +02:00
4lDO2 ae8e13525f Remove is_pending flag, read word directly instead. 2024-07-15 17:20:57 +02:00
4lDO2 f91b90445d Force userspace to do post-syscall EINTR check. 2024-07-15 17:20:56 +02:00
4lDO2 e8060b259d Only save ip and 'archdep' regs when signalling. 2024-07-15 17:20:56 +02:00
4lDO2 12cfcfc6f2 TMP: change syscall gitmodule to fork 2024-07-15 17:20:56 +02:00
4lDO2 93a3401df4 Fix bug causing raise() to not deliver any signals. 2024-07-15 17:20:56 +02:00
4lDO2 13720f59d5 Make signals masked when clear rather than set. 2024-07-15 17:20:56 +02:00
4lDO2 87046b77c7 Compile on aarch64. 2024-07-15 17:20:56 +02:00
4lDO2 c1ce1d76f9 Compile on i686. 2024-07-15 17:20:56 +02:00
4lDO2 5b25e2cda7 Fix excp_handler deadlock. 2024-07-15 17:20:56 +02:00
4lDO2 b94904a660 Use correct addrsp when setting sighandler. 2024-07-15 17:20:56 +02:00
4lDO2 cc406804c0 Don't double-clear is_pending flag. 2024-07-15 17:20:55 +02:00
4lDO2 35aa24800b Implement correct context sig unblocking behavior. 2024-07-15 17:20:55 +02:00
4lDO2 93f0573b5d Use improved signal control struct defs. 2024-07-15 17:20:55 +02:00
4lDO2 d6e0eef065 Implement signal delivery code (untested). 2024-07-15 17:20:55 +02:00
4lDO2 9b68d4de80 Fix add_ref(Shared) refcounting bug. 2024-07-15 17:20:55 +02:00
4lDO2 7d5b2e6c21 Prevent infinite userspace crash loops. 2024-07-15 17:20:55 +02:00
4lDO2 55fe58adf6 WIP: implement kill syscall prototype 2024-07-15 17:20:55 +02:00
4lDO2 639ba74a7e Fix kernel compilation. 2024-07-15 17:20:55 +02:00
4lDO2 295cc820e6 WIP: userspace signal handling 2024-07-15 17:20:55 +02:00
Andrey Turkin 198151a355 Make sure aarch64 kernel doesn't use any FP registers 2024-07-13 12:06:50 +00:00
Andrey Turkin 9c639af217 Fix debug assertion bug 2024-07-12 23:15:33 +03:00
Andrey Turkin 7c0995ee24 Revived tests
Also fixed debug build failure on i686, and reformatted the code
2024-07-12 21:10:37 +03:00
Andrey Turkin 2663873d45 Fix Dtb scheme reads 2024-07-09 09:52:16 +03:00
4lDO2 a80dc4dc9c Try fixing CI. 2024-06-25 12:58:53 +02:00
4lDO2 c73e2ffecf Add Makefile.
This will both improve CI, and decouple the kernel build script from
cookbook.
2024-06-25 12:46:02 +02:00
Jeremy Soller 15c7e10d52 Implement kreadoff for dtb scheme 2024-06-24 11:57:20 -06:00
4lDO2 d4997150d8 Temporarily suppress some cases of EINVAL for unknown SKMSGs. 2024-06-15 15:12:04 +02:00
4lDO2 6aa5ed020e Add missing fevent impl for RootScheme. 2024-06-15 12:29:05 +02:00
4lDO2 10714a4659 Make explicit flags optional for SYS_{READ,WRITE}2. 2024-06-14 13:58:10 +02:00
4lDO2 dd8661bcb3 Add debug print for SYS_READ2/SYS_WRITE2. 2024-06-14 13:57:56 +02:00
Jacob Lorentzon bf0fc66ac1 Improved scheme protocol. 2024-06-14 11:31:51 +00:00
4lDO2 e9ba024aaa Remove redundant .cargo/config
All options are already set by ../recipe.toml, and removing this file
will make Cargo stop complaining about missing -Zbuild-std when for
example compiling RMM for the host arch.
2024-06-10 11:52:59 +02:00
Jeremy Soller 81e6fc70d2 Enable use of MmapMode::Cow 2024-06-05 12:56:29 -06:00
Jeremy Soller 593959a7c3 Allow fp-armv8 in order to compile for aarch64 on new nightly 2024-05-11 14:45:44 -06:00
Jeremy Soller c9698b5d2d Update to new nightly 2024-05-11 14:13:41 -06:00
Jeremy Soller e7d00a8e05 Add driver for arm,gic-v3 2024-05-08 11:24:46 -06:00
Jeremy Soller 9e3688b507 Revert "Support arm,gic-v3"
This reverts commit e33015a5f8.
2024-05-07 15:24:50 -06:00
Jeremy Soller e33015a5f8 Support arm,gic-v3 2024-05-07 15:20:34 -06:00
4lDO2 7f409d46bf Fix futex wakeup when CoW has occurred. 2024-04-28 15:17:32 +02:00
Jeremy Soller 3ad6427e28 Disable AP if it has the same ID as BSP 2024-04-13 10:01:36 -06:00
Jeremy Soller 5b5b2dbc97 Debug messages during device init 2024-04-13 09:34:00 -06:00
4lDO2 0060dd326b Update rmm 2024-04-12 16:25:58 +02:00
4lDO2 99fcfc5fae Skip insufficiently large bump alloc regions. 2024-04-11 22:02:44 +02:00
4lDO2 161a92c9c2 Forbid strong fdtbl refs after setting context's.
This fixes a possible file table leak if a filetable contains an fd
referring (strongly) to the filetable itself. Now, it will automatically
be downgraded to a weak reference after it becomes a context's active
file table.

TODO: maybe support consuming a context's filetable to get a strong
reference back, provided it's exclusively owned.
2024-04-10 21:49:43 +02:00
Jeremy Soller e4246d6704 Re-enable sys:log 2024-04-10 10:38:46 -06:00
4lDO2 3fc9103826 Fix altreloc remap, always NOP-fill padding bytes.
This fixes a very rare (requires that an altreloc span two pages) kernel
crash where it writes past the region that was remapped as RWX, thus
triggering an in-kernel "wrote without write access" page fault.

Additionally, this fixes the logic for unavailable features. It fixes
the short-circuit that would forget to remap the memory back from RWX to
R-X. NOP bytes are also now replaced with multi-byte NOP regardless of
whether the CPU supports the given feature.
2024-04-10 16:16:37 +02:00
Jacob Lorentzon cd3f937861 Make futex timeout absolute, and properly return ETIMEDOUT 2024-04-05 20:31:03 +00:00
4lDO2 fbaa93e8fa Fix profiling stack trace bp bounds checking. 2024-04-04 15:45:47 +02:00
4lDO2 68e072aac9 Return correct fevent flags in PipeScheme.
This fixes a Cargo deadlock.
2024-04-02 15:04:39 +02:00
4lDO2 ed075474b0 Fix syscall_debug feature. 2024-03-31 14:40:57 +02:00
4lDO2 2f1551a6bb Mark allocated p2frame used *before* freelist unlock. 2024-03-26 17:07:37 +01:00
Jeremy Soller 168692f09d x86: use initial_top for tss stack 2024-03-25 14:15:43 -06:00
4lDO2 c17279f5bf Allocate kernel stacks using the frame allocator. 2024-03-25 16:31:16 +01:00
4lDO2 9253e16240 Fix kernel stack sizes, other arches. 2024-03-25 16:29:07 +01:00
4lDO2 b5523df187 Only support power-of-two frame allocations. 2024-03-24 14:40:15 +01:00
4lDO2 b2d52d6736 Implement allocator free/used bookkeeping. 2024-03-24 14:27:25 +01:00
4lDO2 12282439b6 Reduce dead code, fix aarch64. 2024-03-23 23:51:12 +01:00
4lDO2 e6dc0e96f0 Fix aarch64. 2024-03-23 19:16:53 +01:00
4lDO2 7261dccb72 Fix i686. 2024-03-23 16:54:47 +01:00
4lDO2 1b3e024f7d Fix profiling code. 2024-03-23 15:52:18 +01:00
4lDO2 299a829ff3 Remove debug code. 2024-03-22 17:21:17 +01:00
4lDO2 676368f5d2 Fix booting to desktop. 2024-03-22 16:35:29 +01:00
4lDO2 c0f3b6ccca Fix refcount assert 2024-03-22 13:32:14 +01:00
4lDO2 660acb4d94 Improve debugging 2024-03-22 13:32:14 +01:00
4lDO2 343f89f240 Fix unaligned section end append_pages. 2024-03-22 13:32:14 +01:00
4lDO2 baf46a3555 Far more progress 2024-03-22 13:32:13 +01:00
4lDO2 f4d270c7ce Ensure freelist does not contain used pages. 2024-03-22 13:31:24 +01:00
4lDO2 a847e4745c More progress 2024-03-22 13:31:24 +01:00
4lDO2 d2dc3302a7 Remove RefCount::Zero.
Only the allocator is allowed to switch between 0 and 1. Refcounts above
1 are however controlled by the virtual memory system.
2024-03-22 13:31:22 +01:00
4lDO2 3a8821e73b Hopefully fix most UB 2024-03-22 13:28:21 +01:00
4lDO2 08784e7166 More progress 2024-03-22 13:27:50 +01:00
4lDO2 c349e4cd83 Fix allocate_frames_complex 2024-03-22 13:26:03 +01:00
4lDO2 4fccc4b87b Some of userspace now boots! 2024-03-22 13:26:03 +01:00
4lDO2 bb01f0af66 More allocation progress 2024-03-22 13:26:03 +01:00
4lDO2 cfe153eb85 Fix section creation. 2024-03-22 13:25:57 +01:00
4lDO2 fe7244a8cd Ensure both set_next and set_prev are called. 2024-03-22 13:25:08 +01:00
4lDO2 2ba9ff720c Doubly-linked list. 2024-03-22 13:25:07 +01:00
4lDO2 0e8c187a50 WIP: Implement more of deallocate_p2frame. 2024-03-22 13:21:52 +01:00
4lDO2 fc19d63af9 Store aligned addrs rather than PFNs in Frame. 2024-03-22 13:19:19 +01:00
4lDO2 fd86bb4860 Try to naturally align sections. 2024-03-22 13:18:07 +01:00
4lDO2 d5b1ad2cd5 WIP: Improve allocation performance 2024-03-22 13:17:59 +01:00
Jeremy Soller 8f09b4aa06 Do not use HPET on i686 2024-03-19 20:44:47 -06:00
4lDO2 66eb3361d3 Use saved regs instead of costly context.syscall. 2024-03-19 11:33:55 +01:00
4lDO2 4862977fa5 Optimize syscall fast path without tracing. 2024-03-18 20:38:11 +01:00
4lDO2 33f0fa8709 Fix IOBITMAP_SIZE type. 2024-03-18 14:34:32 +01:00
4lDO2 ff0bd96abd Improve readability 2024-03-18 14:26:00 +01:00
4lDO2 f7900df0e2 Update syscall 2024-03-18 10:27:51 +01:00
4lDO2 d62aada7ad Replace iopl with either empty or full PIO bitmap. 2024-03-18 10:27:51 +01:00
bjorn3 de137fe58d Fix acpi::init call for i686 2024-03-17 19:34:14 +01:00
bjorn3 e1f4bf4356 Misc arm device tree fixes 2024-03-17 19:28:58 +01:00
4lDO2 c583745ede Update syscall 2024-03-16 17:49:32 +01:00
4lDO2 4a3dc2dadd Fix the SIGKILL fd leak bug. 2024-03-16 17:49:32 +01:00
4lDO2 8e19da338b Fix kstop and kreset. 2024-03-16 17:49:31 +01:00
4lDO2 b97e733d94 Boot to desktop on aarch64. 2024-03-16 17:49:31 +01:00
4lDO2 57c3119a83 Fix i686 triple fault by always initializing int stack. 2024-03-16 17:49:31 +01:00
4lDO2 7d8ee58df3 Fix aarch64 link step. 2024-03-16 17:49:31 +01:00
4lDO2 5ff26ca967 Remove paste dependency completely. 2024-03-16 17:49:31 +01:00
4lDO2 5ecba176f4 Compile on aarch64. 2024-03-16 17:49:31 +01:00
4lDO2 776a140212 Fix rax being overwritten, and compile on i686. 2024-03-16 17:49:31 +01:00
4lDO2 239bd317e9 Fix signal ordering wrt syscall return. 2024-03-16 17:49:31 +01:00
4lDO2 13bc46a30b WIP: Implement scheme call cancelation. 2024-03-16 17:49:31 +01:00
4lDO2 e57573c428 Ensure signals can't start new contexts too early. 2024-03-16 17:49:30 +01:00
4lDO2 e012d6cfca Fix altstack calculation typo. 2024-03-16 17:49:30 +01:00
4lDO2 c7da5a438c Replace incorrect interrupt IA32-isms.
The code incorrectly documents and states that SS and RSP are
conditionally pushed, based on whether the privilege level changed. This
is correct on IA-32, but wrong on x86-64.
2024-03-16 17:49:30 +01:00
4lDO2 6d1e436d29 Remove some dead code. 2024-03-16 17:49:30 +01:00
4lDO2 0cf2ce632a Only call sig handler in switch, not after EINTR. 2024-03-16 17:49:30 +01:00
4lDO2 6bf8238fb1 Unset procmask for kmain. 2024-03-16 17:49:30 +01:00
4lDO2 5ac0be7ec1 Start with full procmask, fix signal delivery. 2024-03-16 17:49:30 +01:00
4lDO2 5336cbd9e5 Improve signal interfaces and implementation. 2024-03-16 17:49:30 +01:00
4lDO2 10256b331c Ensure only the kernel can return EINTR. 2024-03-16 17:49:26 +01:00
bjorn3 04f689cee7 Accept a single RSDP from the bootloader 2024-03-15 11:43:27 +01:00
bjorn3 08bb2537b5 Remove the deprecated bootstrap_entry field from KernelArgs 2024-03-15 10:59:58 +01:00
bjorn3 502016815d Avoid unaligned access in the XsdtIter
The pointers in the XSDT table are only 4 byte aligned.
2024-03-15 10:53:45 +01:00
bjorn3 d5e1188b8e Remove doc feature 2024-03-15 09:55:27 +01:00
bjorn3 672e36f401 Force the zero page of the kernel to be part of a segment
This will be necessary for limine and likely multiboot support. See the
comment in the linker scripts.
2024-03-14 21:22:13 +01:00
bjorn3 b5f94a5a2e Fix bug in the unmapping code
Previously trying to funmap an address after the start of the grant
would result in an overflow only caught when compiling the kernel with
debug assertions enabled.
2024-03-14 12:15:43 +01:00
bjorn3 e81113349c Fix get_page_info for frames in the last memory section 2024-03-13 19:41:24 +01:00
bjorn3 ecbc2b7e8d Directly read the bootstrap entry point from the initfs header 2024-03-11 14:26:08 +01:00
bjorn3 fb66a8628f Use PAGE_SIZE instead of hard coded constant 2024-03-10 21:39:55 +01:00
bjorn3 616c7d4398 Load the bootstrap blob at 4096 instead of 0
This way the NULL page can stay unmapped and the bootstrap code can
avoid UB when reading the initfs header (which is at the start of the
bootstrap code.
2024-03-10 21:14:46 +01:00
4lDO2 ec58d6c541 Compile on aarch64 as well. 2024-03-05 10:40:54 +01:00
4lDO2 d38d8b66bd Fix i686 compilation. 2024-03-05 10:26:57 +01:00
4lDO2 b35c9d1e62 Properly free phys-contiguous grants, TLB-delayed. 2024-03-04 19:03:01 +01:00
4lDO2 4e392d05e4 Delay cow() dealloc until after TLB shootdown. 2024-03-04 19:03:01 +01:00
4lDO2 fa3e2a24d4 Optimize TLB flushing. 2024-03-04 19:03:01 +01:00
4lDO2 716f147cd4 Fix synchronization so acid tlb succeeds! 2024-03-04 19:03:01 +01:00
4lDO2 846d914a55 Improve synchronization. 2024-03-04 19:03:01 +01:00
4lDO2 1f8d7bc67c Always check shootdown reqs when locking addrsp. 2024-03-04 19:03:01 +01:00
4lDO2 3a592b9079 Use regular non-NMI IPIs for TLB shootdown. 2024-03-04 19:03:00 +01:00
4lDO2 3a915c7fd5 Fix lock/guard mismatch, move r#move to wrapper. 2024-03-04 19:03:00 +01:00
4lDO2 b5efaceb51 Fix more synchronization. 2024-03-04 19:03:00 +01:00
4lDO2 098cdd6067 Fix flusher, currently only with -smp 1 2024-03-04 19:03:00 +01:00
4lDO2 79381249a2 Implement a TLB shootdown draft. 2024-03-04 19:03:00 +01:00
4lDO2 6bf90f9eee Build the foundation for TLB shootdown. 2024-03-04 19:03:00 +01:00
4lDO2 156017a25d Refactor: wrap RwLock<AddrSpace>. 2024-03-04 19:03:00 +01:00
4lDO2 749df4c869 Fail successfully with todo! 2024-03-04 19:03:00 +01:00
4lDO2 bb30530ea0 Track which CPUs are using any given AddrSpace. 2024-03-04 19:03:00 +01:00
4lDO2 0c6c857012 Improve LogicalCpu{Id,Set}, make set atomic.
Technically there should be an atomic and nonatomic set type, but perf
should be the same, as the nonatomic one would only be used when setting
the sched_affinity.
2024-03-04 19:02:56 +01:00
Jeremy Soller 15cbb40802 Format 2024-02-28 12:10:17 -07:00
Jeremy Soller 8390277eb2 Fix affinity alignment 2024-02-28 12:10:06 -07:00
bjorn3 e08eadf64a Don't pass CallerCtx in file_op_generic
It isn't used by any of the callers.
2024-02-25 21:05:21 +01:00
bjorn3 24187b5f80 Move set_tss_stack call to switch_to 2024-02-25 20:10:49 +01:00
bjorn3 96f1a14115 Remove some dead code 2024-02-25 20:06:22 +01:00
bjorn3 52f4aaf741 Avoid unaligned access for serial over x86 io port 2024-02-25 18:36:41 +01:00
bjorn3 782ec87f27 Fix UB in the locking code of context switching
The spin crate considers it UB to call force_write_unlock while there is
a threads trying to obtain a read lock on the same rwlock.

This also switches to the spinning_lot crate for the context rwlock as
it has support for a write guard keeping a reference to the rwlock using
an Arc instead of a reference.
2024-02-25 17:07:41 +01:00
bjorn3 449abb8925 Share bootstrap_mem between all archs 2024-02-25 15:53:04 +01:00
bjorn3 e23f0ed66b Share idt.rs between x86 and x86_64 2024-02-25 15:49:29 +01:00
bjorn3 f92b4c9608 Unify cpuid between x86 and x86_64 and don't return an Option
Systems without cpuid support aren't supported anyway.
2024-02-25 15:07:31 +01:00
bjorn3 eecfbb19d2 Share the functions in interrupt/mod.rs between x86 and x86_64 2024-02-25 14:48:28 +01:00
bjorn3 fbe2980b3d Share interrupt/ipi.rs between x86 and x86_64 2024-02-25 14:48:15 +01:00
bjorn3 62614db9ac Share interrupt/trace.rs between x86 and x86_64 2024-02-25 14:48:12 +01:00
bjorn3 c1d0c11a1b Fix typo in irq.rs 2024-02-25 14:31:52 +01:00
bjorn3 3610dd7e03 Remove unused interrupt handler 2024-02-25 14:31:28 +01:00
bjorn3 e9e3b4487d Reduce the difference of idt.rs between x86 and x86_64 2024-02-25 14:31:28 +01:00
Jeremy Soller 39c20720ee Fix compilation on x86_64 2024-02-16 22:05:57 -07:00
Jeremy Soller e4eb4031bd Fix APIC offsets for x86 32-bit 2024-02-16 22:02:47 -07:00
Jeremy Soller 6c6fc18f8e Format 2024-02-16 21:40:42 -07:00
Jeremy Soller 86589aa7fa Only switch to idle process when no other processes can run 2024-02-13 14:46:21 -07:00
Jeremy Soller 98f12fd750 Hack to workaround hangs by pinning to one cpu 2024-02-10 09:18:57 -07:00
Ron Williams 9331452bdb Use RedoxPath::as_parts. redox-path from crates.io 2024-02-09 15:05:45 +00:00
Ron Williams eeee40ae0c update unlink for new path format 2024-02-01 00:50:33 -08:00
Ivan Tan e7d47d10c6 aarch64: fix compile error 2024-01-27 23:29:37 +08:00
bjorn3 58314e6a47 Share a whole lot more code between x86 and x86_64 2024-01-25 13:34:04 +00:00
bjorn3 785975089b Dedup the last remaining piece of code in the driver module between x86 and x86_64 2024-01-25 13:34:04 +00:00
bjorn3 0d86348e41 Dedup the apic code between x86 and x86_64 2024-01-25 13:34:04 +00:00
bjorn3 86fb4208f2 Dedup some more code between x86 and x86_64 2024-01-25 13:34:04 +00:00
bjorn3 0d092d7921 Dedup code for most x86 and x86_64 device drivers 2024-01-25 13:34:04 +00:00
bjorn3 9404e9f892 Mark the sections used by alternative!() as allocated
This prevents the linker from discarding any function which uses the
alternative!() macro which would result in runtime relocation crashing.
2024-01-25 11:51:34 +01:00
bjorn3 5e71f6f9df Correctly mark unaligned write as such to avoid UB 2024-01-24 19:43:34 +01:00
bjorn3 fa58f5887e The kernel now works fine without optimizations
It is relatively slow without optimizations, but it is still usable.
2024-01-24 14:15:09 +01:00
bjorn3 3085b31336 Ensure __altrelocs_start is correctly aligned 2024-01-24 14:13:27 +01:00
bjorn3 732fad0593 Fix disabling the self_modifying feature 2024-01-24 14:13:18 +01:00
bjorn3 e5c93ae334 Fix some UB and debug assertions
The UB has been found by rustc's new UB checks with debug assertions
enabled.
2024-01-24 13:51:20 +01:00
Jeremy Soller 87ee68998c Handle new path format 2024-01-18 12:35:32 -07:00
Jeremy Soller 0e58953259 Update redox-path 2024-01-18 11:22:23 -07:00
Jeremy Soller 0fde840f83 Add redox-path submodule 2024-01-18 11:15:04 -07:00
Jeremy Soller 45f1c4e29e Add rustfmt from relibc and apply it with cargo fmt 2024-01-17 13:52:01 -07:00
Jeremy Soller 73897bd83d scheme/pipe: allow removing fevent 2024-01-08 16:59:48 -07:00
Jeremy Soller d18c316012 Add session ID 2024-01-08 14:43:11 -07:00
4lDO2 5e75df56c5 More BumpAllocator APIs. 2023-12-18 11:16:15 +01:00
4lDO2 ed455915ca Allow arbitrary bump allocation size. 2023-12-18 11:16:11 +01:00
4lDO2 529c491fa0 Allow disabling profiling at compile time. 2023-12-17 00:49:28 +01:00
4lDO2 fac0e783ef Refactor profiling code. 2023-12-17 00:49:28 +01:00
4lDO2 99ad6a0a2c Support toggling profiling. 2023-12-17 00:49:28 +01:00
4lDO2 0f27d55c0a Advance profiling buffer correctly. 2023-12-17 00:49:28 +01:00
4lDO2 14abf0cbc6 Exclude kmain from profile. 2023-12-17 00:49:27 +01:00
4lDO2 f973bc4128 Profiling 2023-12-17 00:49:24 +01:00
Jeremy Soller a285863335 Update syscall 2023-12-16 11:12:21 -07:00
Jeremy Soller 364896c6e7 Update syscall 2023-12-16 11:10:28 -07:00
4lDO2 dae3726057 Update syscall 2023-12-15 15:14:40 +01:00
4lDO2 ee3aafa1d9 Remove PhysBorrowed hacks. 2023-12-15 15:14:40 +01:00
4lDO2 52df9dd1bc Remove the AddrSpace ref when exiting, not reaping. 2023-12-15 15:14:40 +01:00
4lDO2 d4a120188f Ensure PhysBorrowed iff !alloc-owned, vice versa.
This is allowed now that the old physalloc/physfree syscalls have been
removed.
2023-12-15 15:14:40 +01:00
4lDO2 eda462fd11 Remove SYS_PHYSMAP. 2023-12-15 15:14:40 +01:00
4lDO2 875a130843 Remove SYS_PHYSALLOC* and SYS_PHYSFREE. 2023-12-15 15:14:40 +01:00
4lDO2 a42e406569 Fix contiguous mmap. 2023-12-15 15:14:40 +01:00
4lDO2 cd19831ffb Improved options for memory: files. 2023-12-15 15:14:40 +01:00
4lDO2 77400f63ee Add a memory: file for phys-contiguous mmaps. 2023-12-15 15:14:36 +01:00
Ivan Tan ebf96fa843 aarch64: fix dtb scheme 2023-12-14 03:34:37 +00:00
Jeremy Soller 1cc5804333 Allow CPUs to take any context 2023-12-13 17:20:43 -07:00
Jeremy Soller 4386e0716d Missed change for last commit 2023-12-13 17:20:21 -07:00
Jeremy Soller fbaa4306e3 Add unblock_no_ipi function and use in context switch 2023-12-13 17:19:43 -07:00
bjorn3 2d065083df Use HashMap instead of BTreeMap where possible
This shrinks the kernel from 905840 bytes to 862408 bytes.
2023-12-13 19:55:20 +01:00
4lDO2 78beae5c92 Fix aarch64 2023-12-13 11:08:12 +01:00
4lDO2 d531c6f1bf Context switch correctly in UserInner::call. 2023-12-13 11:08:12 +01:00
4lDO2 6b642d62a6 Disable trigger_debugger again. 2023-12-13 11:08:12 +01:00
4lDO2 88508a2cb7 Remove as_user_inner. 2023-12-13 11:08:12 +01:00
4lDO2 3a35338aa7 Remove as_{filetable,sigaction,addrspace}. 2023-12-13 11:08:12 +01:00
4lDO2 f3ce5b167d Make proc: and thisproc: global. 2023-12-13 11:08:11 +01:00
4lDO2 3be015ce4d Make sys: global. 2023-12-13 11:08:11 +01:00
4lDO2 fe0e3103f4 Make itimer: global. 2023-12-13 11:08:11 +01:00
4lDO2 87b0c568a0 Make time: global. 2023-12-13 11:08:11 +01:00
4lDO2 f6002e839d Centralize global scheme constructors. 2023-12-13 11:08:11 +01:00
4lDO2 ce313ba28d Add global scheme IDs to map, for now. 2023-12-13 11:08:11 +01:00
4lDO2 d9c2443ae3 Make irq: a GlobalScheme. 2023-12-13 11:08:11 +01:00
4lDO2 10e86ea89d Hardcode global scheme IDs. 2023-12-13 11:08:11 +01:00
4lDO2 679c26c03b s/Arc<dyn KernelScheme>/enum, but deref as dyn. 2023-12-13 11:08:07 +01:00
Jeremy Soller d7d824552b Merge branch 'derive_hash_virtual_address' into 'master'
Derive Hash for VirtualAddress

See merge request redox-os/rmm!11
2023-12-13 00:10:02 +00:00
bjorn3 aad492f805 Derive Hash for VirtualAddress 2023-12-12 22:21:22 +01:00
bjorn3 a7165f822f Switch from the memoffset crate to the offset_of feature
The memoffset crate requires const_refs_to_cell to work in const
contexts. This feature has some known issues around it's semantics. The
offset_of feature however is currently on track for stabilization.
2023-12-12 20:21:31 +00:00
bjorn3 2aea52a94b Remove the sole usage of the const_option feature 2023-12-12 20:21:31 +00:00
bjorn3 82a87be7d5 Avoid usage of the unstable Allocator trait
And also optimize init_sections to use the fact that allocate_frames
returns zeroed frames.
2023-12-12 20:21:31 +00:00
bjorn3 5bce3a5bb5 Move -z max-page-size from the target spec to the cookbook 2023-12-12 18:15:05 +01:00
bjorn3 3188a44b23 Don't use target_family="redox" for the kernel
This cfg is meant for redox userspace programs.
2023-12-12 18:14:18 +01:00
bjorn3 2e689eb5d4 Remove unnecessary no_mangle and extern "C" from the panic handler
#[panic_handler] handles all linkage related details.
2023-12-12 15:01:29 +00:00
bjorn3 c99e582c86 Use the default panicking alloc error handler 2023-12-12 15:01:29 +00:00
bjorn3 6b1c154847 Use kernel_executable_offsets on AArch64 and x86 2023-12-12 15:01:29 +00:00
bjorn3 017702d3d2 Remove a lot of dead code 2023-12-12 15:01:29 +00:00
bjorn3 00d0b8fb6b Remove all pub from main.rs
This will cause rustc to emit warnings for all unused items.
2023-12-12 15:01:29 +00:00
bjorn3 5ce7d1df8a Remove unnecessary extern crate item
This was only necessary in the 2015 edition
2023-12-12 15:01:29 +00:00
bjorn3 6045b0cc59 Remove unused feature gates 2023-12-12 15:01:29 +00:00
Jeremy Soller 4e3103a48a x86: fix enter/exit gs and usercopy asm 2023-12-11 15:25:54 -07:00
Ivan Tan 1f1a57e1f7 support userspace program ioremapping device memory 2023-12-11 16:07:53 +00:00
Ivan Tan 9b6197d686 aarch64: code clean up 2023-12-11 16:07:53 +00:00
Ivan Tan a8329956ca support raspi3b+ serial && uart interrupt 2023-12-11 16:07:53 +00:00
Ivan Tan 44b14f994a fix qemu-arm64 run error 2023-12-11 16:07:53 +00:00
Ivan Tan 1c1c541f0e bringup raspi3b+, add device memory, disable uart init 2023-12-11 16:07:53 +00:00
Ivan Tan bfbf435546 draft: aarch64: add irq_bcm2835. Need refactoring 2023-12-11 16:07:53 +00:00
Ivan Tan 9a5b9798ca remove qemu-aarch64-virt hard code 2023-12-11 16:07:53 +00:00
Ivan Tan ed68c98b42 aarch64: add irq-bcm2836 for raspi3b+ && refactor irq module 2023-12-11 16:07:53 +00:00
Ivan Tan b65a7e9103 move gic into irqchip module 2023-12-11 16:07:53 +00:00
Ivan Tan 01d0e9a4b5 aarch64: add irqchip module to initialize all irq chip. 2023-12-11 16:07:53 +00:00
Ivan Tan 78a8568932 update dtb syscall scheme to kernelscheme 2023-12-11 16:07:53 +00:00
Ribbon 4f98319a92 Improve the README and fix the docs badge link 2023-12-07 15:32:45 +00:00
Ron Williams 02087065c1 don't panic when adding an existing name to a namespace 2023-11-15 22:18:50 +00:00
4lDO2 036a4bdee4 Replace syscall::Scheme with KernelScheme. 2023-11-15 20:00:47 +01:00
4lDO2 192d663d84 Forbid / in scheme names. 2023-11-09 14:40:20 +01:00
Ron Williams 29803e7865 setrens: always ignore -1 2023-11-08 23:29:08 -08:00
4lDO2 431dba9563 Update syscall 2023-10-19 17:07:17 +02:00
4lDO2 2d04b76a2c Close sendfd file descriptor unless consumed. 2023-10-14 15:38:21 +02:00
4lDO2 2f2e76c0ca Inform SYS_SENDFD scheme if the fd was exclusive. 2023-10-14 14:56:40 +02:00
4lDO2 1546a4a08f Implement SYS_SENDFD and SKMSG_FOBTAINFD. 2023-10-14 12:44:38 +02:00
4lDO2 da491fd5fc Disable sys:trigger_debugger by default. 2023-10-08 11:21:59 +02:00
4lDO2 6f6f69c728 Fix test instruction reg length in paranoid swapgs. 2023-10-08 11:21:23 +02:00
bjorn3 d819277d56 Make rustc directly invoke the linker 2023-10-03 09:53:37 +02:00
bjorn3 b9299224ea Move debuginfo option to Cargo.toml 2023-10-03 09:39:14 +02:00
Enver Balalic 750e566a27 Get aarch64 to compile
Fixes enough errors to get the kernel to compile
2023-10-01 23:55:24 +02:00
4lDO2 c481f6b5d4 Track state for all UserScheme calls. 2023-09-30 12:53:37 +02:00
Jeremy Soller e794f2fe9b Fix panic when there is no xsave support 2023-09-18 15:01:39 -06:00
Ivan Tan eb0d48ac81 aarch64: add dtb scheme 2023-09-18 20:45:23 +00:00
Ivan Tan a76cbc9f31 aarch64: trap msr, mrs or system instruction 2023-09-18 20:45:23 +00:00
4lDO2 5eace9997a Compile successfully on i686 as well. 2023-09-16 10:48:25 +02:00
4lDO2 0b9c5bbf49 Pass both original and padded length in altrelocs. 2023-09-16 10:33:09 +02:00
4lDO2 ed3d2d7832 Allow disabling overwrite-based optimizations. 2023-09-14 16:44:12 +02:00
4lDO2 ce0d474cb9 Fail if a feature is force-enabled but unsupported. 2023-09-14 16:28:14 +02:00
4lDO2 dfc372d241 Replace with rdgsbase dynamically in paranoid ISRs. 2023-09-14 14:43:46 +02:00
4lDO2 d90aeef62e Fix nop-filling code. 2023-09-14 14:34:04 +02:00
4lDO2 dde8f78903 Support XSAVE, XSAVEOPT, and AVX2. 2023-09-14 10:54:30 +02:00
4lDO2 38e669c807 Dynamic fsgsbase support, enable by default. 2023-09-14 09:25:30 +02:00
4lDO2 f581c71c7c Allow code-overwriting optimizations, use for smap. 2023-09-14 08:38:49 +02:00
4lDO2 dd30ae109a Ensure altcode/data/features sections are kept. 2023-09-14 08:38:08 +02:00
4lDO2 e005619b78 Add alternative! macro. 2023-09-12 21:43:37 +02:00
4lDO2 f028b77412 Use config.toml instead of x86_* Cargo feature. 2023-09-12 21:19:06 +02:00
4lDO2 c210e59a75 Add a config.toml to the kernel. 2023-09-12 21:13:58 +02:00
4lDO2 9fd2488d64 Use a compact push+jump table for IRQs. 2023-09-10 21:42:02 +02:00
Jeremy Soller 5c4961d139 Update Cargo.lock 2023-09-09 12:31:14 -06:00
Jeremy Soller 4cd76ea9e3 arch/x86: sync LogicalCpuId changes 2023-09-09 12:31:04 -06:00
Jeremy Soller a4d0960b3f Update redox syscall 2023-09-08 11:16:53 -06:00
4lDO2 6d65a93606 Remove live scheme. 2023-09-08 01:57:34 +00:00
Jeremy Soller 40a3601ca5 Update syscall 2023-09-07 16:17:57 -06:00
4lDO2 eeb0d8c1e6 Unify Interrupt{,Error}Stack. 2023-09-06 22:45:29 +02:00
4lDO2 c4a5abb34a Remove AtomicSchemeId. 2023-09-06 09:22:59 +02:00
4lDO2 126c7b7d8a Pass scheme ID to UserInner cleaner. 2023-09-06 09:21:53 +02:00
4lDO2 0d4f3125cd Use Once<SchemeId> for debug:, simplify other Once. 2023-09-06 08:58:59 +02:00
4lDO2 27d350955a Replace atomic with Once<SchemeId> for irq: 2023-09-06 08:49:37 +02:00
4lDO2 2862f7abb5 Once<SchemeId> for serio, simplify queue globals. 2023-09-06 08:48:22 +02:00
4lDO2 16cb32b178 Make WaitQueue::new() const fn. 2023-09-06 08:47:52 +02:00
4lDO2 68b03d69c0 Downgrade int_like const fn default to trait. 2023-09-06 08:46:58 +02:00
4lDO2 f025ece614 Replace from/into with get/new when necessary. 2023-09-06 08:38:10 +02:00
4lDO2 9d742387ac Replace int_like from/into with get/new, impl From. 2023-09-06 08:37:13 +02:00
4lDO2 45d1c256ea Add LogicalCpuSet as a sched affinity mask. 2023-09-04 21:57:54 +02:00
4lDO2 3b725b2c27 Add logical CPU ID newtype, switch to u32. 2023-09-04 21:27:48 +02:00
4lDO2 45e1eb7ba4 Set IA32_TSC_AUX if present. 2023-09-04 21:07:30 +02:00
4lDO2 303c96494c Improve sysretq checks. 2023-09-03 15:50:28 +02:00
4lDO2 ad02f5cbba Remove SYS_PIPE2. 2023-09-01 17:17:15 +02:00
Jeremy Soller da6e9fd8d1 Merge branch 'ivan/raspi3b' into 'master'
aarch64: init serial port by parsing dtb file

See merge request redox-os/kernel!241
2023-08-12 13:40:24 +00:00
Ivan Tan ca6699a11e aarch64: init serial port by parsing dtb file 2023-08-12 12:45:50 +08:00
Jeremy Soller 4d7d86d47c Merge branch 'mvk2' into 'master'
Set relocation-model=static

Closes #107

See merge request redox-os/kernel!240
2023-08-12 00:57:46 +00:00
4lDO2 cbd02a8489 Set relocation-model=static 2023-08-12 00:57:45 +00:00
Jeremy Soller 652aa4f1ac Merge branch 'no_more_tls' into 'master'
Replace #[thread_local]

See merge request redox-os/kernel!239
2023-08-09 14:18:16 +00:00
4lDO2 de23cd447e Fix aarch64 build. 2023-08-08 12:01:43 +02:00
4lDO2 28d4e60beb Set relocation-model=static for i686. 2023-08-08 12:01:43 +02:00
4lDO2 0dd464d428 Unset TLS model on i686. 2023-08-08 12:01:42 +02:00
4lDO2 ca92eda5e6 Remove TLS on aarch64 too. 2023-08-08 12:01:42 +02:00
4lDO2 ed2febb289 Disable thread-local storage entirely. 2023-08-08 12:01:42 +02:00
4lDO2 a78d6e42f8 Stop using #[thread_local] on x86_*. 2023-08-08 12:01:42 +02:00
4lDO2 bdd5c954dc Move PIT_TICKS to context::switch. 2023-08-08 12:01:42 +02:00
4lDO2 0c90802ae0 Fix RaiiFrame deallocation. 2023-08-08 11:57:57 +02:00
Jeremy Soller 5cabe38a78 Merge branch 'mmu' into 'master'
Demand paging

See merge request redox-os/kernel!238
2023-08-07 15:36:58 +00:00
4lDO2 4688090dea Fix RaiiFrame typo. 2023-08-03 16:46:42 +02:00
4lDO2 8f98d5b987 Extend mremap, eager mappings for real hardware. 2023-08-03 12:37:58 +02:00
4lDO2 8af63e3aae Update syscall 2023-08-03 11:50:02 +02:00
4lDO2 c7714992f3 Fix clone_grant_using_fmap test. 2023-08-02 14:17:26 +02:00
4lDO2 2070fa44b7 Fix warnings. 2023-08-02 13:07:49 +02:00
4lDO2 05a9530ac7 Temporarily disable CoW fmaps. 2023-08-01 17:29:36 +02:00
4lDO2 ef879b35ba Update RMM. 2023-08-01 15:52:34 +02:00
Jeremy Soller a992ae89ed Merge branch 'mmu' into 'master'
Demand paging related improvements

See merge request redox-os/rmm!10
2023-08-01 13:51:37 +00:00
4lDO2 34708bd1be Temporarily disable MAP_LAZY. 2023-08-01 15:44:41 +02:00
4lDO2 fe88b23d09 Use a single cow zeroed page for RO maps + eager mapping. 2023-08-01 13:11:00 +02:00
4lDO2 1e670645e4 Bypass kernel heap for storing PageInfo.
Since these are stored in arrays that are typically 512 KiB each
(i.e. which in turn typically store metadata for 128 MiB), they will
certainly be a page-size multiple, and large contiguous allocations are
allowed at least at boot time. Not only is the linked-list allocator
less efficient for that, but this change will also help reduce TLB
overhead.
2023-08-01 11:22:42 +02:00
4lDO2 8a8c04685e Merge adjacent frame sections. 2023-08-01 10:55:01 +02:00
4lDO2 0cdfb886c0 Fix debugger for x86_64, disable sc debug. 2023-07-28 13:40:00 +02:00
4lDO2 86aba2dbe5 Better VirtualAddress Debug impl. 2023-07-28 13:39:32 +02:00
4lDO2 b5937b7b91 Set aarch64 "not global" flag by default. 2023-07-28 13:38:39 +02:00
4lDO2 e28fef09e3 Improve aarch64 debugger. 2023-07-28 13:23:44 +02:00
4lDO2 d16569110e Don't mess up x18 in aarch64 exc handler. 2023-07-28 12:56:55 +02:00
4lDO2 ce35deed4b Support aarch64 page consistency checking. 2023-07-28 12:38:25 +02:00
4lDO2 f454df38eb Fix get_page_info. 2023-07-28 10:47:18 +02:00
4lDO2 ec9c24f841 WIP: aarch64 2023-07-27 19:05:33 +02:00
4lDO2 8b7fc8a468 Compile and mostly run properly on i686. 2023-07-27 16:45:36 +02:00
4lDO2 f4bdb5388e Remove AtomicU64 requirement for starting APs. 2023-07-27 16:44:52 +02:00
4lDO2 885f88b777 Fix futex for non-AtomicU64-capable targets. 2023-07-27 16:44:26 +02:00
4lDO2 25d26b3b93 Arch-independent x86-modeled page fault handler. 2023-07-27 15:56:45 +02:00
4lDO2 7a3b453fbb Declare __usercopy_{start,end} as functions. 2023-07-27 15:34:33 +02:00
4lDO2 4d2cd6ce0f Remove redundant log msg. 2023-07-27 15:25:51 +02:00
4lDO2 a4a84775d6 Fix MMAP_PREP order. 2023-07-26 22:31:56 +02:00
4lDO2 d6e1732d44 Stop using feature(arbitrary_self_types). 2023-07-25 11:22:36 +02:00
4lDO2 3cfec39b47 Pass MunmapFlags to scheme. 2023-07-25 10:52:24 +02:00
4lDO2 c9aa5ca851 WIP: Add SYS_MREMAP. 2023-07-25 10:52:24 +02:00
4lDO2 2660c3e07a WIP: Pin fmap grants that are borrowed too.
This might not be the most ideal solution, since a GiB grant can be
EBUSY blocked if a single page is used by an indefinitely-blocking
UserScheme. But, the alternatives would impose lots of additional
complexity, such as increasing the PageInfo size, adding more
refcounting arrays to grants, etc.
2023-07-25 10:52:24 +02:00
4lDO2 e054a5b211 Add debugger checks for correct CoW page flags. 2023-07-25 10:52:24 +02:00
4lDO2 37579601b2 Remove one level of indirection in get_page_info. 2023-07-25 10:52:24 +02:00
4lDO2 e2b736140f Make PageInfo atomic once again. 2023-07-25 10:52:24 +02:00
4lDO2 d58ddc35fe Complete PageInfo cleanup.
This enables proper CoW ^ shared enforcement, so that e.g. acquiring a
new CoW page from already shared memory, or vice versa, will enforce
that they aren't both simultaneously.
2023-07-25 10:52:23 +02:00
4lDO2 0f1b5b9b6f WIP: Make cow/shared refcounts mutually exclusive. 2023-07-25 10:52:23 +02:00
4lDO2 113cb5ed4e Ensure pages cannot be both CoW and shared. 2023-07-25 10:52:23 +02:00
4lDO2 d3ecedefd9 Notify schemes when mmaps are unmapped. 2023-07-25 10:52:23 +02:00
4lDO2 02f04752e8 Use proper locks for PageInfo. 2023-07-25 10:52:23 +02:00
4lDO2 7bdf5e9af3 Pass unaligned length to scheme for fmap. 2023-07-25 10:52:23 +02:00
4lDO2 afa3d7dc7b Support anonymous MAP_SHARED mmaps. 2023-07-25 10:52:23 +02:00
4lDO2 70b4d99c96 Implement MAP_FIXED without MAP_FIXED_NOREPLACE. 2023-07-25 10:52:23 +02:00
4lDO2 f0341280f7 Fix frame deallocation. 2023-07-25 10:52:23 +02:00
4lDO2 3a80528d13 Fix MAP_LAZY mappings. 2023-07-25 10:52:23 +02:00
4lDO2 cbec83215a Lazy-evaluate pages returned by fmap. 2023-07-25 10:52:22 +02:00
4lDO2 9182722f84 WIP: Allow listing address space grants again. 2023-07-25 10:52:22 +02:00
4lDO2 0466e87e59 Error if scheme fmap returns unaligned address. 2023-07-25 10:52:22 +02:00
4lDO2 ba62c0606e Pin PhysBorrowed head/tail UserScheme grants too. 2023-07-25 10:52:22 +02:00
4lDO2 329d60848c WIP: Support CoW fmap. 2023-07-25 10:52:22 +02:00
4lDO2 b24cf821c2 Support transferring grants again. 2023-07-25 10:52:22 +02:00
4lDO2 55f1829e77 Call funmap if applicable. 2023-07-25 10:52:22 +02:00
4lDO2 4ec8712fb0 Adjust fmap offsets in Grant::extract. 2023-07-25 10:52:22 +02:00
4lDO2 c5eb44d968 Increase refcount for borrowed fmap too. 2023-07-25 10:52:22 +02:00
4lDO2 b3a6a6744a Pin grants that are used in UserScheme. 2023-07-25 10:52:22 +02:00
4lDO2 954a8d00fe Make page fault handler recursive.
This is probably a bad idea, but it works for now, and can only cause
problems, if grants that borrow grants that borrow grants etc., are
used.
2023-07-25 10:52:21 +02:00
4lDO2 da6f6a316c Return only one grant, External, for Grant::borrow. 2023-07-25 10:52:21 +02:00
4lDO2 b5430359d8 Forbid scheme calls with non-RAM physmapped memory. 2023-07-25 10:52:21 +02:00
4lDO2 43c433a3f0 Remove FmapCtxt. 2023-07-25 10:52:21 +02:00
4lDO2 bf6ad5c41a Disable debugging again. 2023-07-25 10:52:21 +02:00
4lDO2 8553bc7a59 WIP: Support userspace-backed borrowing mmaps. 2023-07-25 10:52:21 +02:00
4lDO2 024f3e3828 Fix deadlock, booting to shell works now. 2023-07-25 10:52:21 +02:00
4lDO2 ad78dcc5a1 WIP: Rudimentary MAP_SHARED fmap implementation. 2023-07-25 10:52:21 +02:00
4lDO2 afa61601c4 Add ContextStatus::HardBlocked. 2023-07-25 10:52:21 +02:00
4lDO2 23fede5db0 Remove scheme funmap methods. 2023-07-25 10:52:20 +02:00
4lDO2 0c365f54e6 WIP: FmapBorrowed. 2023-07-25 10:52:20 +02:00
4lDO2 20c3adf38d WIP: Start rewriting fmap impl. 2023-07-25 10:52:20 +02:00
4lDO2 99975c0e42 WIP: Ensure that Grant::borrow does not borrow nonpresent grants. 2023-07-25 10:52:20 +02:00
4lDO2 dffc8ec9fc Do not expect PageInfo for PhysMap grants. 2023-07-25 10:52:20 +02:00
4lDO2 20a84decdf Fix MemoryScheme fmap. 2023-07-25 10:52:20 +02:00
4lDO2 15ce84164b Reminder that borrow does handle "lack of grant". 2023-07-25 10:52:20 +02:00
4lDO2 50e2f51ab3 Remove outdated #[must_use]. 2023-07-25 10:52:20 +02:00
4lDO2 f7bffacef0 Implement Drop for AddrSpace. 2023-07-25 10:52:20 +02:00
4lDO2 829d2276fb Remove Context::vfork.
Since clone is no longer exists as a syscall, it makes little sense to
manage vfork in the kernel. Implementing vfork in userspace would still
be possible.
2023-07-25 10:52:20 +02:00
4lDO2 e34a3cee42 Fix mmap/munmap, invert borrowed/owned refcount. 2023-07-25 10:52:19 +02:00
4lDO2 45ec3ecc70 Track Allocated and CoW External the same way. 2023-07-25 10:52:19 +02:00
4lDO2 7aca53753e Call init_mm from correct function. 2023-07-25 10:52:19 +02:00
4lDO2 a599d9b389 WIP: Store PageInfo in separate data structure. 2023-07-25 10:52:19 +02:00
4lDO2 760fc2ba5a WIP: Global page info structs. 2023-07-25 10:52:19 +02:00
4lDO2 593e21d95e Support schemes. 2023-07-25 10:52:19 +02:00
4lDO2 f53a1ffd53 Remove proc:pid/memory. 2023-07-25 10:52:19 +02:00
4lDO2 0a5b6ce656 Reach proc:memory access in userspace. 2023-07-25 10:52:19 +02:00
4lDO2 11fdb3bb46 Copy on writes to CoW pages. 2023-07-25 10:52:19 +02:00
4lDO2 565db7694f Add cow_refcount. 2023-07-25 10:52:19 +02:00
4lDO2 276f051d19 Further userspace progress, fix RMM bug. 2023-07-25 10:52:18 +02:00
4lDO2 8cfbc39b9f Get further in userspace. 2023-07-25 10:52:18 +02:00
4lDO2 490e1b2777 WIP: Track grant ownership. 2023-07-25 10:52:18 +02:00
4lDO2 e7d94ddff5 WIP: Lazy zeroed mapping and page fault handler. 2023-07-25 10:52:18 +02:00
4lDO2 8dfa73db35 Post-refactor fixes. 2023-07-25 10:52:18 +02:00
4lDO2 34b4512dbd Refactor Grants.
Page alignment is now verified at compile time, for example.
2023-07-25 10:52:13 +02:00
4lDO2 d4b5899c53 Remove allocator_owned hack. 2023-07-25 10:49:55 +02:00
Jeremy Soller 5cc05a281e Merge branch 'less_unstable_use' into 'master'
Reduce usage of unstable features

See merge request redox-os/kernel!230
2023-07-24 19:18:53 +00:00
Jeremy Soller c61fd1837a Merge branch 'fix_mmap' into 'master'
Fix fmap typo and remove warning.

See merge request redox-os/kernel!237
2023-07-18 18:04:42 +00:00
4lDO2 c130b18ee7 Fix fmap typo and remove warning. 2023-07-18 16:54:44 +02:00
Jeremy Soller 16912bca82 Merge branch 'replace_physmap' into 'master'
Alternative physmap via memory:physical@<mem type>.

See merge request redox-os/kernel!236
2023-07-17 16:48:32 +00:00
4lDO2 8e22e69c94 Add remap_with{,_full}. 2023-07-17 13:31:51 +02:00
4lDO2 0aa7fea250 Fix remap bug: require present before remapping. 2023-07-17 13:31:46 +02:00
Jeremy Soller eaab222011 Merge branch 'fix_is_global' into 'master'
Fix is_global.

See merge request redox-os/rmm!9
2023-07-16 16:36:55 +00:00
4lDO2 339984e49b Fix is_global. 2023-07-16 18:32:34 +02:00
4lDO2 37eb577ada Support physmap via memory:physical@<mem type>. 2023-07-15 00:28:56 +02:00
Jeremy Soller 5a9a38a948 Merge branch 'fix' into 'master'
Set space in copy_and_capture_tail.

See merge request redox-os/kernel!235
2023-07-14 13:30:42 +00:00
4lDO2 797c81eb3b Set space in copy_and_capture_tail. 2023-07-14 12:51:26 +02:00
bjorn3 e73e42be66 Replace intrinsics::abort() call in switch_finish_hook with safer abort mechanism
abort will still run the illegal instruction interrupt handler which may
not be safe.
2023-07-10 17:03:36 +02:00
bjorn3 7500ffaa5a Remove uses of the arbitrary_self_types feature 2023-07-10 17:03:36 +02:00
bjorn3 174e38a851 Remove all uses of concat_idents!() 2023-07-10 17:03:34 +02:00
bjorn3 437b70838f Replace uses of atomic_* intrinsics with Atomic* types 2023-07-10 17:02:01 +02:00
bjorn3 0d01f7be57 Use core::ptr wrappers instead of the unstable volatile_* intrinsics 2023-07-10 17:02:01 +02:00
bjorn3 6803c2c33c Remove a couple of unused feature gates 2023-07-10 17:02:01 +02:00
Jeremy Soller c1b28af544 Merge branch 'fix_debug_scheme' into 'master'
Fix debug: scheme.

See merge request redox-os/kernel!233
2023-07-10 14:29:52 +00:00
4lDO2 f700958642 Fix debug: scheme. 2023-07-10 16:26:52 +02:00
Jeremy Soller 4d6b4c24a9 Merge branch 'better_percpu' into 'master'
Simplify x86_64 percpu and GSBASE calculation

See merge request redox-os/kernel!222
2023-07-10 14:13:12 +00:00
4lDO2 3ded84c945 Simplify x86_64 percpu and GSBASE calculation 2023-07-10 14:13:12 +00:00
Jeremy Soller 5c99d73bbe Merge branch 'no_static_mut_thread_local' into 'master'
Avoid static mut thread locals

See merge request redox-os/kernel!228
2023-07-10 14:03:41 +00:00
Jeremy Soller 6440f2dcbc Merge branch 'fix_live' into 'master'
Fix live scheme

See merge request redox-os/kernel!232
2023-07-07 13:34:10 +00:00
4lDO2 9e6dfc82d0 Fix live scheme. 2023-07-07 15:00:46 +02:00
Jeremy Soller 6fca481a0a Merge branch 'mm' into 'master'
Usercopy migration

Closes #82 and #115

See merge request redox-os/kernel!219
2023-07-06 13:03:21 +00:00
4lDO2 56f88e80c2 Usercopy migration 2023-07-06 13:03:21 +00:00
Jeremy Soller b1d0851a7b Merge branch 'sys_scheme_remove_indirection' into 'master'
Replace Box<dyn Fn> with fn in sys: scheme.

See merge request redox-os/kernel!231
2023-07-06 12:56:13 +00:00
4lDO2 fa7d1c821f Replace Box<dyn Fn> with fn in sys: scheme. 2023-07-05 17:08:00 +02:00
bjorn3 56b16ce897 Avoid static mut thread locals
Instead use UnsafeCell inside the thread locals.
2023-07-05 14:50:17 +02:00
Jeremy Soller 846aa32f21 Merge branch 'panic_abort' into 'master'
Build the kernel with panic=abort

See merge request redox-os/kernel!229
2023-07-04 18:00:53 +00:00
Jeremy Soller 74e74ce633 Merge branch 'no_idtr_thread_local' into 'master'
Move IDTR thread local to a stack variable

See merge request redox-os/kernel!227
2023-07-04 17:30:43 +00:00
bjorn3 8c0be73224 Build the kernel with panic=abort
This reduces the kernel size and avoids the need to define the
eh_personality lang item.
2023-07-04 19:14:36 +02:00
bjorn3 13733fb943 Move IDTR thread local to a stack variable 2023-07-04 12:17:52 +02:00
Jeremy Soller acefb8888e Merge branch 'pipe_scheme' into 'master'
Improved pipe scheme.

Closes #84

See merge request redox-os/kernel!226
2023-06-27 13:35:14 +00:00
4lDO2 5abf16a51e Improved pipe scheme. 2023-06-26 13:54:13 +02:00
Jeremy Soller 7269f9c6f1 Merge branch 'fix_df' into 'master'
Always clear DF when entering the kernel

See merge request redox-os/kernel!223
2023-06-18 12:54:19 +00:00
4lDO2 416269eeaf Always clear DF when entering the kernel. 2023-06-18 14:47:00 +02:00
Jeremy Soller 78a8173f62 Merge branch 'aarch64-stuff' into 'master'
More aarch64 stuff

See merge request redox-os/kernel!221
2023-06-13 13:49:25 +00:00
uuuvn a5d4ccba57 More aarch64 stuff 2023-06-13 10:15:47 +00:00
Jeremy Soller 2849510892 Copy HPET divide by zero workaround to x86 arch 2023-06-12 09:19:34 -06:00
Jeremy Soller 503a21d461 Merge branch 'aarch64-stuff' into 'master'
Improve aarch64 code + memory management and crush some bugs

See merge request redox-os/kernel!220
2023-06-12 15:17:51 +00:00
uuuvn 63290429b2 Improve aarch64 code + memory management and crush some bugs 2023-06-12 14:46:02 +00:00
Jeremy Soller e24e8485ba Merge branch 'aarch64-stuff' into 'master'
Add GLOBAL flag and prettify some stuff

See merge request redox-os/rmm!8
2023-06-12 12:12:09 +00:00
uuuvn d89e6008e8 Add GLOBAL flag and prettify some stuff 2023-06-12 10:23:40 +00:00
Jeremy Soller 0ae3958a8c Merge branch 'fix-lsp-helix' into 'master'
Fix LSP in helix

See merge request redox-os/kernel!218
2023-06-10 12:18:52 +00:00
uuuvn ffe9bb8593 Fix LSP in helix 2023-06-10 08:50:25 +00:00
Jeremy Soller 0deb0d79e1 Merge branch 'file_forwarding_v2' into 'master'
Allow schemes to return external file descriptors

See merge request redox-os/kernel!215
2023-06-08 12:02:35 +00:00
4lDO2 aa1420d599 Update syscall. 2023-06-08 11:11:20 +02:00
Jeremy Soller 37746c0743 Merge branch 'fix-aarch64' into 'master'
Fix aarch64

See merge request redox-os/kernel!217
2023-06-07 13:42:02 +00:00
uuuvn d502418e49 Fix aarch64 2023-06-06 15:36:30 +00:00
Jeremy Soller a9bdb51deb Merge branch 'master' into 'master'
Update README.md: add command to build docs

See merge request redox-os/kernel!216
2023-06-05 23:03:28 +00:00
Florian Meißner 33bdf8e5b6 Update README.md: add command to build docs 2023-06-05 19:14:42 +00:00
4lDO2 ce77703146 Move forwarded files rather than copying them. 2023-06-02 14:50:44 +02:00
4lDO2 b1d4f55e0a Use kopen and kdup in syscall handlers. 2023-06-02 14:50:44 +02:00
4lDO2 c7ba937bbf Support forwarding in UserScheme. 2023-06-02 14:50:40 +02:00
Jeremy Soller da5063375e Merge branch 'context_name' into 'master'
Remove one level of indirection for Context::name.

See merge request redox-os/kernel!214
2023-05-30 13:36:48 +00:00
4lDO2 58c0c5d040 Remove one level of indirection for Context::name. 2023-05-27 14:27:34 +02:00
Jeremy Soller 34894e3d73 Merge branch 'fix_aarch64' into 'master'
Fix unaligned_references error on aarch64

See merge request redox-os/kernel!213
2023-05-06 16:37:06 +00:00
4lDO2 a451c0aa1b Fix aarch64 build. 2023-05-06 17:49:39 +02:00
Jeremy Soller 89d560e6e5 Merge branch 'fix-sigreturn-dos' into 'master'
Fix kernel DoS via sigreturn from non-signal context

See merge request redox-os/kernel!211
2023-05-04 12:32:24 +00:00
uuuvn 4621cd674d Fix kernel DoS via sigreturn from non-signal context 2023-05-04 15:58:05 +04:00
Jeremy Soller 3a6732eaad Merge branch 'updated_rustc_and_futex_fixes' into 'master'
Fixes for futex and newer rustc

See merge request redox-os/kernel!209
2023-05-02 22:11:53 +00:00
Jeremy Soller 37ba7c63b4 Merge branch 'qemu_hpet_bug' into 'master'
Qemu hpet bug

See merge request redox-os/kernel!210
2023-05-02 16:19:01 +00:00
Andrew Mackenzie d3a2fe7083 Qemu hpet bug 2023-05-02 16:19:01 +00:00
4lDO2 50b877d1aa Remove ignored unaligned_references exception. 2023-04-30 18:13:55 +02:00
4lDO2 c604d6b051 Make IDT #[repr(C)]. 2023-04-30 18:13:27 +02:00
4lDO2 99ffc370e8 Work around repr(packed) but not fixing UB. 2023-04-30 18:11:34 +02:00
4lDO2 a5168b4442 Fix warnings. 2023-04-30 18:11:20 +02:00
4lDO2 45f031b50d Improve clone_entry lock granularity. 2023-04-30 17:54:05 +02:00
4lDO2 6c3f577f05 Also translate the 12-bit page offset in SYS_FUTEX. 2023-04-30 17:53:17 +02:00
4lDO2 62eab8a2fe Retry rather than panic if clone_entry is unset. 2023-04-09 12:04:08 +02:00
Jeremy Soller 4bf307d88e Merge branch 'fix_mem_fns' into 'master'
Fix memcpy, memmove, memset, and memcmp.

Closes #99

See merge request redox-os/kernel!208
2023-04-01 21:17:54 +00:00
4lDO2 78557eff18 Fix memcpy, memmove, memset, and memcmp. 2023-04-01 21:30:10 +02:00
Jeremy Soller 42de1f3e9c Merge branch 'master' into 'master'
Add QEMU tip.

See merge request redox-os/kernel!206
2023-03-14 15:25:59 +00:00
Jeremy Soller 295bcbdac8 Update redox_syscall 2023-03-14 09:25:17 -06:00
Ribbon 32300c2d9e Add QEMU tip. 2023-03-12 15:16:05 +00:00
Jeremy Soller 6fb14edcb0 Merge branch 'context-switch-optimization' into 'master'
Context switch optimization

See merge request redox-os/kernel!205
2023-03-09 21:33:27 +00:00
Jeremy Soller 12688a929e Context switch optimization
- Contexts for other CPUs will never be evaluated for switch
- Running contexts will never be evaluated for switch
- Arc::clone is only called for previous and next context when there is a context to switch to
- Lots of cleanup to the switch function
2023-03-09 14:30:12 -07:00
Jeremy Soller 3bf381caf8 Do not panic if ACPI is not available 2023-03-03 18:56:23 -07:00
Jeremy Soller 11e6dd7b24 Merge branch 'master' into 'master'
Improve text organization.

See merge request redox-os/kernel!202
2023-02-28 14:11:38 +00:00
Ribbon f1b45f658f Improve text organization. 2023-02-28 12:46:34 +00:00
Jeremy Soller 4b3337e479 Merge branch 'master' into 'master'
Kernel notes (moved from CONTRIBUTING).

See merge request redox-os/kernel!201
2023-02-28 12:27:09 +00:00
Ribbon 2c593fb0b9 Move from CONTRIBUTING to kernel README. 2023-02-28 08:10:33 +00:00
Jeremy Soller 12d5830097 Merge branch 'pin_kmain_contexts' into 'master'
Pin kmain contexts

Closes #111

See merge request redox-os/kernel!200
2023-02-27 16:22:46 +00:00
4lDO2 b73922bc95 Also fix outdated-#![feature(...)] warnings. 2023-02-24 23:16:57 +01:00
4lDO2 ac913e49f9 Pin kmain contexts to corresponding CPUs. 2023-02-24 23:05:11 +01:00
Jeremy Soller 87e1689b56 Merge branch 'sched_affinity' into 'master'
Support scheduler CPU affinity.

See merge request redox-os/kernel!199
2023-02-15 15:44:39 +00:00
4lDO2 8d14d54fa9 Support scheduler CPU affinity. 2023-02-15 14:50:01 +01:00
Jeremy Soller cb58500b68 Update for new Rust 2023-02-11 14:50:55 -07:00
Jeremy Soller 7aeb9f0ac8 Remove rust-toolchain 2023-02-11 14:50:26 -07:00
Jeremy Soller 55fd7dfff7 Add centiseconds to context time 2023-01-30 10:51:32 -07:00
Jeremy Soller e5c3be86cd Ensure unmounting is read from atomic in all cases 2023-01-12 07:33:54 -07:00
Jeremy Soller 85e0a7c368 Record mappings in funmap with page aligned size, always 2022-12-21 18:29:15 -07:00
Jeremy Soller 523d00eeac Make it possible to track syscall time when debugging 2022-12-19 10:11:59 -07:00
Jeremy Soller d298459686 Add sys:irq 2022-11-18 14:18:06 -07:00
Jeremy Soller 1e81c9d78b Fix compilation without ACPI feature 2022-11-16 13:53:04 -07:00
Jeremy Soller 111606ccdc Increase PIT divisor again to reduce wasted interrupt handling time 2022-11-15 11:50:23 -07:00
Jeremy Soller 33aa263deb Fixes for hpet counter read, choose better PIT divisor 2022-11-14 13:58:55 -07:00
Jeremy Soller 2052cc8cdc Allow arch to provide higher precision time 2022-11-14 11:12:44 -07:00
Jeremy Soller 31868077f0 Use u128 for time, store CPU time of processes 2022-11-14 10:10:17 -07:00
Jeremy Soller ee6c9f4020 Fix compilation on i686 2022-11-11 13:23:07 -07:00
Jeremy Soller 8e0f54cb31 Clippy fixes 2022-11-11 13:19:14 -07:00
Jeremy Soller 515a03b870 Fix warnings 2022-11-11 12:51:07 -07:00
Jeremy Soller 6bef3afee6 Support bootloader stride 2022-09-16 12:29:38 -06:00
Jeremy Soller 3bef7d7bad Simplify ps2 interrupts to reduce latency to reading bytes 2022-09-08 10:33:31 -06:00
Jeremy Soller f5bdae2d0c Reduce schreduler time slices to reduce latency 2022-09-07 18:21:30 -06:00
Jeremy Soller 07ed93225e 0.3.4: Update syscall to matching version 2022-08-31 16:15:25 -06:00
Jeremy Soller 6753251af3 Do not allow mmap with page_count 0 2022-08-31 16:14:27 -06:00
Jeremy Soller 21108d57fe Update syscall 2022-08-30 10:33:22 -06:00
Jeremy Soller 7fbe5112ca Allow physmap with unaligned size 2022-08-29 09:41:35 -06:00
Jeremy Soller 1b3c6a957d Add aarch64 debugger 2022-08-28 09:27:38 -06:00
Jeremy Soller 8d8437a5d3 Update rmm 2022-08-28 09:19:17 -06:00
Jeremy Soller 81b03cc693 Improve aarch64 tlb flushing 2022-08-28 09:19:07 -06:00
Jeremy Soller 91b5d64c22 Use current address space for proc kfmap workaround 2022-08-27 18:05:20 -06:00
Jeremy Soller 2278fd7fe1 Workaround to ensure proc kfmap does not try to map kernel memory 2022-08-27 10:55:52 -06:00
Jeremy Soller 1fadde3ee8 Eliminate deadlock in capture_inner 2022-08-27 07:48:47 -06:00
Jeremy Soller 6f6648c4d2 Disable HPET use on x86 2022-08-26 11:13:53 -06:00
Jeremy Soller 6dbb85d4c9 Static mapping of some CPU devices outside of physmap 2022-08-26 11:08:13 -06:00
Jeremy Soller 27bb8e44dd Do not allow phys_to_virt overflow 2022-08-26 11:07:21 -06:00
Jeremy Soller 002425d625 Fix trampoline on x86 2022-08-26 08:24:04 -06:00
Jeremy Soller 33b8fcecfb Sync x86_64 trampoline with bootloader 2022-08-26 08:08:24 -06:00
Jeremy Soller fb1bdf7c3e Ignore null bytes from pl011 uart 2022-08-25 20:10:35 -06:00
Jeremy Soller 6a3fc5a68a Send SIGSEGV on aarch64 exception 2022-08-25 20:00:53 -06:00
Jeremy Soller 80b8382cd7 Fix aarch64 kfx size 2022-08-25 18:40:19 -06:00
Jeremy Soller 82ac7a66f7 Only save preserved regs in aarch64 context switch 2022-08-25 18:23:51 -06:00
Jeremy Soller 52434b359c Disable building aarch64 asm 2022-08-25 18:12:43 -06:00
Jeremy Soller ff738074d2 Cleanup aarch64 code 2022-08-25 15:46:27 -06:00
Jeremy Soller afd82ba4bb Save/restore aarch64 FPU regs 2022-08-25 09:30:53 -06:00
Jeremy Soller 31680bf5b9 Do not set tpidr_el0 from kernel 2022-08-25 08:46:26 -06:00
Jeremy Soller b3b5bb8a91 Simplify handling of aarch64 env regs 2022-08-25 08:12:07 -06:00
Jeremy Soller f7e8026494 Set aarch64 thread pointers 2022-08-24 19:21:36 -06:00
Jeremy Soller 545a561a26 Set ptrace regs for aarch64 2022-08-24 19:03:30 -06:00
Jeremy Soller 84704353af Support address space change on aarch64 2022-08-24 18:54:42 -06:00
Jeremy Soller 6d3fa8b374 Enable clone_handler on aarch64 2022-08-24 15:50:10 -06:00
Jeremy Soller b20a71113c Implement aarch64 switch_to_inner using naked function 2022-08-24 13:24:37 -06:00
Jeremy Soller fb34e4eddf Partially implement stack trace on aarch64 2022-08-24 12:34:31 -06:00
Jeremy Soller 0ed9f03317 Use push/pop scratch for aarch64 signal handler 2022-08-24 12:29:48 -06:00
Jeremy Soller 613968dc30 Use push/pop scratch for x86 signal handler 2022-08-24 11:39:31 -06:00
Jeremy Soller 113a7164bb Use push/pup scratch for x86_64 signal handler 2022-08-24 11:11:50 -06:00
Jeremy Soller 310a0dda08 Some aarch64 register struct updates 2022-08-24 08:56:57 -06:00
Jeremy Soller bb12da2b68 Update syscall 2022-08-24 08:53:37 -06:00
Jeremy Soller 54d9d011aa Use framebuffer virtual address 2022-08-23 20:07:30 -06:00
Jeremy Soller 2b8af1cf07 Ignore areas outside 1GiB and combine memory areas on x86 2022-08-23 15:41:29 -06:00
Jeremy Soller aa51e9812d Use PAT flags on x86 2022-08-22 19:54:14 -06:00
Jeremy Soller f3e23af9ec Update rmm 2022-08-22 18:49:42 -06:00
Jeremy Soller 61ba2e6c8e Fix unmap_parents 2022-08-22 18:49:32 -06:00
Jeremy Soller 06d952979f Implement debugger for x86 2022-08-22 08:41:35 -06:00
Jeremy Soller 58104649db Set limits for x86 GDT entries 2022-08-21 14:56:59 -06:00
Jeremy Soller 538ad9e57f Remove debug message when writing x86 EnvRegisters 2022-08-21 13:22:58 -06:00
Jeremy Soller d3fbbd5918 Pre-allocate x86 kernel PD entries 2022-08-21 13:21:59 -06:00
Jeremy Soller 0d4ff5d4f3 Add functions for accessing mapper allocator 2022-08-21 13:20:44 -06:00
Jeremy Soller bdba700c21 Disable syscall debugging 2022-08-20 21:52:09 -06:00
Jeremy Soller 76a46c54b8 Fix stack selector on x86 2022-08-20 21:51:21 -06:00
Jeremy Soller c750ee26a8 Implement setting FS/GS offset on x86 2022-08-20 21:21:32 -06:00
Jeremy Soller 01e4bc899e Fix compilation on x86 2022-08-20 18:11:57 -06:00
Jeremy Soller d3f42989c9 Fix compilation on x86_64 2022-08-20 14:51:05 -06:00
Jeremy Soller 9dd069c8ca Support proc partially with aarch64 2022-08-20 14:45:45 -06:00
Jeremy Soller 9b8abfc5d7 Copy exception handlers from early_init 2022-08-20 13:48:13 -06:00
Jeremy Soller 44d5e6573a Updated utable switching code for aarch64 2022-08-20 13:31:20 -06:00
Jeremy Soller fe7def2797 Update to use TableKind on x86_64 2022-08-20 13:16:23 -06:00
Jeremy Soller 01df1c20da Use TableKind everywhere 2022-08-20 13:06:52 -06:00
Jeremy Soller 3911fc616a Update rmm 2022-08-20 13:01:01 -06:00
Jeremy Soller df733ed571 Use TableKind for most table operations 2022-08-20 13:00:48 -06:00
Jeremy Soller 849b854bd0 Implement usermode for aarch64 2022-08-20 09:34:12 -06:00
Jeremy Soller c7e5466bd7 Fix aarch64 switch_to_inner functino definition 2022-08-20 09:15:26 -06:00
Jeremy Soller 157dbc7b4d Convert aarch64 context switching to asm macro 2022-08-20 09:08:14 -06:00
Jeremy Soller 9ca2484079 Get aarch64 kernel to boot to the point of needing context switch 2022-08-19 21:40:04 -06:00
Jeremy Soller 82ad6e2fa7 Remove devmap region from aarch64, use physmap instead 2022-08-19 21:01:10 -06:00
Jeremy Soller ba64d82818 Make kstart the aarch64 entry point 2022-08-19 21:00:47 -06:00
Jeremy Soller 97b4d31355 Match aarch64 PHYS_OFFSET with x86_64 2022-08-19 20:54:02 -06:00
Jeremy Soller c5eb435d79 Match PHYS_OFFSET accross archs 2022-08-19 20:53:15 -06:00
Jeremy Soller a1411353a9 Update rmm 2022-08-19 19:52:39 -06:00
Jeremy Soller e05868e1dc Improve aarch64 paging instructions 2022-08-19 19:52:00 -06:00
Jeremy Soller 49fcafac45 Fix building on aarch64 2022-08-19 16:12:42 -06:00
Jeremy Soller 38361661e6 Add proc scheme stubs for aarch64 2022-08-19 16:00:35 -06:00
Jeremy Soller 80fc1d7fd4 Remove phys_offset stack hack 2022-08-18 15:03:35 -06:00
Jeremy Soller 6b2439f1b9 Improved 32-bit x86 support 2022-08-18 14:57:15 -06:00
Jeremy Soller c09be1770b Use registers for switch_to_inner instead of stack 2022-08-18 09:09:11 -06:00
Jeremy Soller 472081f8ba Save/restore GS segment on interrupt 2022-08-17 21:13:35 -06:00
Jeremy Soller bd9ee98ba9 Use same code for clone_handler on 32-bit and 64-bit x86 2022-08-17 14:40:30 -06:00
Jeremy Soller d47ba636a0 Support x86 in proc scheme 2022-08-17 14:32:12 -06:00
Jeremy Soller 679662c99e Name bootstrap process 2022-08-17 13:25:13 -06:00
Jeremy Soller 4bd137f36e Fixes for x86 32-bit 2022-08-17 10:48:23 -06:00
Jeremy Soller 1eda828877 Merge branch 'userspace_cwd' into 'master'
Remove SYS_CHMOD and cwd related syscalls/files.

See merge request redox-os/kernel!198
2022-08-16 09:17:37 +00:00
4lDO2 67c0b911b4 Update syscall 2022-08-16 10:45:04 +02:00
4lDO2 c3c135cb1d Remove chmod from UserScheme 2022-08-13 19:44:44 +02:00
4lDO2 431407aff0 Remove SYS_CHMOD and cwd related syscalls/files. 2022-08-13 19:44:44 +02:00
Jeremy Soller ac70c76922 Fix TSS and IDT structures on 32-bit x86 2022-08-12 09:03:56 -06:00
Jeremy Soller 9c78219a6a Use 32-bit TSS for x86 32-bit 2022-08-12 08:44:05 -06:00
Jeremy Soller d33ff704ba Implement usermode for x86 32-bit 2022-08-12 08:21:49 -06:00
Jeremy Soller 4602b81a2f Fix debugger when dumping kernel threads 2022-08-03 11:08:49 -06:00
Jeremy Soller 3ba1b018b7 Warn but otherwise allow unaligned sizes in funmap 2022-08-03 11:08:18 -06:00
Jeremy Soller 7a390c2a1d Sync some paging code for aarch64 with x86_64 2022-08-01 08:25:33 -06:00
Jeremy Soller 2191308d15 setup_new_utable for aarch64 2022-07-29 18:58:19 -06:00
Jeremy Soller 358abbd40f Fix copy paste error and update rmm 2022-07-29 18:53:27 -06:00
Jeremy Soller e9950ee6da Fix more warnings 2022-07-29 18:53:12 -06:00
Jeremy Soller 07015d17ba Sync x86 and x86_64 2022-07-29 18:49:55 -06:00
Jeremy Soller 166e1e304b Update syscall 2022-07-29 18:39:34 -06:00
Jeremy Soller 62c62c4e7c Update rmm 2022-07-29 18:38:12 -06:00
Jeremy Soller 23d4995e50 Fix warnings 2022-07-29 18:37:37 -06:00
Jeremy Soller 5d55d4eb87 Fix warnings 2022-07-29 18:33:54 -06:00
Jeremy Soller cc6c974c91 Bump kernel to 0.3.0 to match syscall 2022-07-29 18:18:27 -06:00
Jeremy Soller be12d0f1bd Add initial i686 arch module 2022-07-29 18:12:49 -06:00
Jeremy Soller 9b74fb3ff1 Update syscall 2022-07-29 18:07:44 -06:00
Jeremy Soller e99cbcf5d2 Fixes for compiling aarch64 2022-07-29 18:06:53 -06:00
Jeremy Soller 897cd4c9f4 Add graphical_debug module 2022-07-29 15:57:02 -06:00
Jeremy Soller 0c80643077 Make graphical_debug arch independent and fix lots of warnings 2022-07-29 15:56:44 -06:00
Jeremy Soller 87acffe859 Fix kernel TLS permissions in INIT_GDT 2022-07-29 09:28:13 -06:00
Jeremy Soller 4d1c41232b Support inner_physmap on 32-bit systems 2022-07-29 09:27:54 -06:00
Jeremy Soller 059f2a0d07 Support ContextList::spawn on i686 2022-07-29 09:27:35 -06:00
Jeremy Soller a1d9edee52 Use Mutex<u64> instead of AtomicU64 for user scheme packet ID 2022-07-29 09:25:40 -06:00
Jeremy Soller bf9e630f65 Fix building proc scheme on non-x86_64 2022-07-29 09:25:17 -06:00
Jeremy Soller f0d3e3281c Use acpi on i686 2022-07-28 08:22:55 -06:00
Jeremy Soller 8db4596f73 Use x86 crate on i686 as well 2022-07-28 08:22:26 -06:00
Jeremy Soller fdb4ad8e88 Only build debugger on x86_64 for now 2022-07-28 08:21:31 -06:00
Jeremy Soller 8d5ca62499 Add linker and target for i686 2022-07-28 08:20:49 -06:00
Jeremy Soller a45a7c696e Merge branch 'fix-bootstrap' into 'master'
Fix bootstrap

See merge request redox-os/kernel!196
2022-07-28 13:38:27 +00:00
4lDO2 f3faf33e3f Add a workaround to treat bootstrap mem as owned. 2022-07-28 14:17:02 +02:00
4lDO2 ca4525462d Return right number of bytes written for addrspace. 2022-07-28 14:16:07 +02:00
4lDO2 2d935ca6d3 Update cargo.lock 2022-07-27 18:01:58 +02:00
Jeremy Soller 7fcdd8f6e2 Merge branch 'userspace_fexec' into 'master'
Userspace fexec

See merge request redox-os/kernel!195
2022-07-27 15:40:58 +00:00
4lDO2 e58bf714d8 Update rmm and syscall 2022-07-27 17:39:16 +02:00
4lDO2 5700899e9a Merge branch 'migrate_kernel_to_rmm' into 'master'
Add necessary functionality for migrating kernel paging code to RMM

See merge request redox-os/rmm!6
2022-07-27 15:10:52 +00:00
4lDO2 99362f98d2 Add a better interface for modifying addrspaces. 2022-07-27 10:52:52 +02:00
4lDO2 939feacdc5 Add fn for validating user memory range bounds. 2022-07-27 10:52:46 +02:00
4lDO2 5bbfdcda6b Add mmap-min-addr and support unmapping parent PTs. 2022-07-27 10:52:45 +02:00
4lDO2 0720db2265 Remove SYS_EXEC debug code. 2022-07-27 10:52:29 +02:00
4lDO2 308c2cc711 Support modifying processes' sigactions.
This is, other than vfork, the last piece of functionality that the
previous clone() offered (CLONE_SIGHAND) which previously was not
implemented.
2022-07-27 10:52:29 +02:00
4lDO2 b766501896 Fix deadlock while starting APs. 2022-07-27 10:52:29 +02:00
4lDO2 bf82387f3b Fix KernelMapper unlocking code. 2022-07-27 10:52:29 +02:00
4lDO2 e60321d4a0 Partial: migrate remaining parts to RMM. 2022-07-27 10:52:23 +02:00
4lDO2 dc8ce1c22b Partial: migrate context handling code to RMM. 2022-07-27 10:52:23 +02:00
4lDO2 c912d9e0db Partial: migrate syscall handling code to RMM. 2022-07-27 10:52:23 +02:00
4lDO2 6589083238 Partial: Migrate schemes to RMM. 2022-07-27 10:52:23 +02:00
4lDO2 486d296d6d Remove old x86_64 paging code, migrate to RMM. 2022-07-27 10:52:23 +02:00
4lDO2 302e55098c Migrate misc x86_64 parts to RMM. 2022-07-27 10:52:23 +02:00
4lDO2 2bb019bc44 Partial: migrate debugger, add consistency check. 2022-07-27 10:52:23 +02:00
4lDO2 648b0edb41 Partial: migrate allocator to RMM. 2022-07-27 10:52:23 +02:00
4lDO2 0aec4d3341 Partial: migrate ACPI to RMM. 2022-07-27 10:52:23 +02:00
4lDO2 8970ce1fe7 Benefit from addrspace abstraction in switch. 2022-07-27 10:52:22 +02:00
4lDO2 1cdd462244 Move the initfs scheme to userspace. 2022-07-27 10:52:22 +02:00
4lDO2 351d77ad9b Improve floating point handling. 2022-07-27 10:52:22 +02:00
4lDO2 94578efd1e Use alloc_zeroed when allocating FX. 2022-07-27 10:52:22 +02:00
4lDO2 db3b834f19 Also inherit pgid, umask, sigmask. 2022-07-27 10:52:22 +02:00
4lDO2 4aea0cfd0c Fix AddrSpace memory leak. 2022-07-27 10:52:22 +02:00
4lDO2 b141cdaad2 Fail if funmap's length isn't page size divisible. 2022-07-27 10:52:22 +02:00
4lDO2 60e3e0af34 Flush less frequently in funmap. 2022-07-27 10:52:22 +02:00
4lDO2 549c023398 Return correct bytes written in proc:X/addrspace. 2022-07-27 10:52:22 +02:00
4lDO2 59d74689dc Copy filetable more efficiently. 2022-07-27 10:52:22 +02:00
4lDO2 0b67997c7b Fix "id == current" check in set_addr_space. 2022-07-27 10:52:21 +02:00
4lDO2 240d91f951 Set address space/files when closing, not writing.
This fixes file descriptor leaks. Suppose relibc is just about to set
the address space. For this, it needs to write the address space fd to
the selection fd. To avoid having to close them in the kernel, it rather
memorizes what the file descriptors refer to internally, and then do the
actual operation when they are gone, i.e. when closing.
2022-07-27 10:52:19 +02:00
4lDO2 fa48c7aa97 Deduplicate code for transferring/creating grants. 2022-07-27 10:52:11 +02:00
4lDO2 cb40eb3792 Support reading all grants and transferring grants. 2022-07-27 10:52:10 +02:00
4lDO2 b50495bfa5 WIP: Support clone in userspace
Everything seems to work for the most part, but now there are tons of
daemons which rely on syscall::clone, which is now implemented in relibc
:(
2022-07-27 10:52:04 +02:00
4lDO2 283ada82a0 WIP: Remove SYS_CLONE (to be done in userspace). 2022-07-27 10:52:03 +02:00
4lDO2 563121596d Fix running on multi_core.
Turns out the problem all along was that the ActivePageTable was never
dropped in usermode_bootstrap. So as soon as any other hardware thread
tried to do page table business, it deadlocked!
2022-07-27 10:51:45 +02:00
4lDO2 6e5015dcab WIP: Add necessary interfaces for setuid/setgid. 2022-07-27 10:51:45 +02:00
4lDO2 37f9b292f1 Add kfmap to fix properly reobtaining grants. 2022-07-27 10:51:45 +02:00
4lDO2 de28cc4918 Add a Scheme supertrait for kernel-only methods. 2022-07-27 10:51:45 +02:00
4lDO2 31c4bc8a1c Remove kernel support for fmap_old and funmap_old. 2022-07-27 10:51:45 +02:00
4lDO2 23f49414bd Fix phys offset, lock grants correctly. 2022-07-27 10:51:45 +02:00
4lDO2 15b029de36 Fix everything all the way to booting to desktop. 2022-07-27 10:51:45 +02:00
4lDO2 e6e1348072 Implement exec, and change UserGrant allocator. 2022-07-27 10:51:44 +02:00
4lDO2 f7f722f81c Don't use identity mapping for ACPI.
This is so that any process can use pointers to ACPI tables, since they
now point to the universally-accessible KERNEL_OFFSET+physaddr virtual
addresses.
2022-07-27 10:51:44 +02:00
4lDO2 846318e716 WIP: Attempt implementing fexec in userspace. 2022-07-27 10:51:43 +02:00
4lDO2 67edfbfc42 Remove the unused USER_HEAP_PML4. 2022-07-27 10:50:53 +02:00
4lDO2 9462df03e7 Add support for unmapping parents.
Currently, this uses a relatively naive method of simply scanning the
512 entries for the PRESENT flag. But, unless the optimizer cannot, it
can be reduced to calculating the bitwise OR of every entry and then
checking that.

If this turns out to be too slow, which it might be when unmapping lots
of pages, then we can (1) either fall back to using a counter like the
old paging code did, or even better (2) use the now-1:1 grants tree to
check if it became empty. Putting the grants code in RMM might be
suboptimal, so instead we can add "unmap_range" and have the kernel
paging code take the offset of the next grant, if any, and then possibly
unmap entire P1s/P2s/P3s -- whatever is in the page tables within that
range.

Note that I am fairly certain that method (1) was the cause of the
visually notorious orbital memory corruption bug.
2022-07-27 10:49:49 +02:00
4lDO2 229ae5da40 Add remaining interfaces to user RMM for user mem. 2022-07-27 10:49:49 +02:00
4lDO2 efc67a2012 Use wrapped flags for PageEntry. 2022-07-27 10:49:49 +02:00
4lDO2 fad6afa7d8 Flush on Drop, unless explicitly ignored. 2022-07-27 10:49:49 +02:00
4lDO2 7a209c83c9 Implement Debug for X8664Arch. 2022-07-27 10:49:49 +02:00
4lDO2 c847b1e2a8 Implement FrameAllocator for mutable refs of impls. 2022-07-27 10:49:49 +02:00
4lDO2 2f16dddf25 Add a page flusher trait. 2022-07-27 10:49:49 +02:00
Jeremy Soller 76d29bac78 Update rmm 2022-07-26 20:16:47 -06:00
Jeremy Soller 0944b17983 Add initial x86 32-bit support 2022-07-26 20:13:55 -06:00
Jeremy Soller ec284ca8e3 Update rust-toolchain 2022-07-26 19:01:42 -06:00
Jeremy Soller ac38e62398 Update syscall 2022-07-26 15:30:51 -06:00
Jeremy Soller b5a9301706 Map live disk only if not already mapped 2022-04-26 12:01:55 -06:00
Jeremy Soller 65bbd50416 Update kernel version to match syscall version 2022-04-26 08:28:05 -06:00
Jeremy Soller e88e7d6df1 Fix HPET on real hardware with better debugging 2022-04-25 15:08:09 -06:00
Jeremy Soller 6f83a0800a Set graphical_debug by default 2022-04-25 08:47:10 -06:00
Jeremy Soller 6e98736c94 Do not map live disk twice 2022-04-25 08:43:51 -06:00
Jeremy Soller 7205dd7463 Unmap xAPIC page if already mapped 2022-04-12 20:17:27 -06:00
Jeremy Soller 8f06672153 Merge branch 'external-initfs' into 'master'
External initfs

See merge request redox-os/kernel!192
2022-04-11 21:09:08 +00:00
4lDO2 df37b1f634 External initfs 2022-04-11 21:09:08 +00:00
Jeremy Soller dc9e6eaf0c Merge branch 'clone_grant_using_fmap_v2' into 'master'
Fix "clone grant using fmap"

See merge request redox-os/kernel!193
2022-04-11 20:19:41 +00:00
4lDO2 4d7da495f5 Fix "clone grant using fmap"
This does the same as the previous MR, but fixes the issue where the
parent process got the mapping (and at the wrong address) and not the
child process.
2022-04-11 21:31:36 +02:00
4lDO2 e72fd5a0e4 Fix a kernel deadlock in empty().
For more information, see https://gitlab.redox-os.org/4lDO2/kernel/-/commit/b3b5d1b864eec030d53ccd2ab907c68958f140aa
2022-04-09 13:38:59 +02:00
Jeremy Soller 87b3bef06c Revert "Merge branch 'clone_grant_using_fmap' into 'master'"
This reverts merge request !190
2022-03-30 14:54:49 +00:00
Jeremy Soller 37ebef2d35 Merge branch 'pipe_list_const_fn' into 'master'
Move more of `pipe:`'s initialization to compile time.

See merge request redox-os/kernel!182
2022-03-30 13:54:27 +00:00
Jeremy Soller cbc2902852 Merge branch 'context_list_const_fn' into 'master'
Pre-initialize the context list at compile time.

See merge request redox-os/kernel!181
2022-03-30 13:53:57 +00:00
Jeremy Soller c5c5b33b6a Merge branch 'clone_grant_using_fmap' into 'master'
Clone grant using fmap

See merge request redox-os/kernel!190
2022-03-30 13:53:08 +00:00
4lDO2 b9c34b3c05 Merge branch 'update-toolchain-2022' into 'master'
Update to latest toolchain.

See merge request redox-os/kernel!191
2022-03-27 09:17:09 +00:00
4lDO2 51e339c973 Update rmm and syscall. 2022-03-24 15:55:16 +01:00
Jeremy Soller 507f7ccd4a Merge branch 'update-toolchain-2022' into 'master'
Update to latest toolchain.

See merge request redox-os/rmm!5
2022-03-23 18:06:11 +00:00
4lDO2 a5f4e9a52a Update syscall. 2022-03-19 22:09:17 +01:00
4lDO2 8644f82b48 Remove unused Xargo.toml. 2022-03-19 22:09:03 +01:00
4lDO2 6255bea143 Update to latest toolchain.
Multi-core is slightly broken when using the latest version of spin
(0.9.2). I believe this is because Once used to do SeqCst loads/stores
everywhere, which might have made any possible data race much harder to
come by.
2022-03-12 17:10:36 +01:00
Jeremy Soller 80376a95dc Improve graphical debug performance 2022-03-08 07:36:01 -07:00
Jeremy Soller 150717f18e Enable local apic error interrupt on all processors 2022-03-07 13:56:46 -07:00
Jeremy Soller b62496f50e Debug HPET init 2022-03-07 13:56:17 -07:00
4lDO2 e2648005ba Update to latest toolchain. 2022-03-06 11:34:22 +01:00
Jeremy Soller 7e2e7b8c21 Log reasons why HPET not used 2022-03-02 08:43:11 -07:00
Jeremy Soller ae3bdea4bc Update raw-cpuid 2022-03-01 18:12:06 -07:00
Jeremy Soller d234df37c9 Improve RMM logging 2022-03-01 17:57:03 -07:00
Jeremy Soller fe468aa1ab Improvements for graphical debug and system76 EC debug 2022-03-01 16:25:15 -07:00
Jeremy Soller 2b5aa1f375 Cleanup of graphical debug to allow it to run much earlier 2022-03-01 15:50:26 -07:00
Jeremy Soller ae0d48d9ab Identity map ACPI 2022-03-01 12:52:06 -07:00
Jeremy Soller 47c3bbe13a Update syscall 2022-03-01 09:28:17 -07:00
Jeremy Soller 81e700708d Get memory areas as argument instead of from hardcoded pointer 2022-02-14 11:52:02 -07:00
Jeremy Soller 933b3b8fc0 Respect min flag to allocate_frames_complex 2022-02-14 10:29:12 -07:00
Jeremy Soller c1aa76bf3c Fill in st_dev in fstat 2022-02-14 09:57:24 -07:00
Jeremy Soller 52ad689d37 Notify debug: readers of new input after all input is processed 2022-02-14 08:49:34 -07:00
Jeremy Soller 1aae949fc4 Support for getting live disk from bootloader 2022-02-10 15:49:34 -07:00
Jeremy Soller 9e6664fb82 Fix additional page mapping in graphical debug 2022-02-10 14:48:52 -07:00
Jeremy Soller 7d9a33c63a Add debugger (dumps all kernel state) 2022-02-10 14:10:04 -07:00
Jeremy Soller f92fe90069 Use requested page table in trampoline 2022-02-07 17:49:23 -07:00
Jeremy Soller 1b2a28a4f0 Use FRAMEBUFFER variables for graphical debug 2022-02-07 17:38:52 -07:00
Jeremy Soller 413238a0a6 Prevent re-use of real mode areas, adjust areas instead of panic 2022-02-07 16:36:05 -07:00
Jeremy Soller b109263e77 Ensure ACPI RSDPs are not re-used 2022-02-05 19:59:02 -07:00
Jeremy Soller 308c5ad3d9 Make sure kernel, stack, and env are identity mapped 2022-02-04 11:16:54 -07:00
Jeremy Soller 941f59283b Map kernel to KERNEL_OFFSET, remove bump_offset 2022-02-03 20:21:00 -07:00
Jeremy Soller 5104437423 WIP: changes for rust bios bootloader 2022-02-03 17:15:28 -07:00
Jeremy Soller bbc4a4aefe workaround for crash on graphical debug finish 2022-01-28 09:47:47 -07:00
Jeremy Soller 3f2a9f7f0a Fix graphical debug feature 2022-01-28 09:15:03 -07:00
4lDO2 a3356c3fdd Clone grant using fmap 2021-12-30 11:27:44 +01:00
Jeremy Soller 0ab4529eaa Make register dumps lowercase 2021-12-01 09:53:33 -07:00
Jeremy Soller cd3dcf153e Do not print interpreter 2021-12-01 08:40:11 -07:00
Jeremy Soller 63fcc204cb x86 paging refactor for debugger 2021-11-30 20:56:55 -07:00
Jeremy Soller 77b8215a66 Getter for Grant region, remove set_mapped, and make region_mut private 2021-11-30 20:06:45 -07:00
Jeremy Soller 4f259e3589 Workaround for thread race conditions 2021-11-30 18:03:34 -07:00
Jeremy Soller 515cab03eb Fix a number of warnings 2021-11-29 20:01:27 -07:00
Jeremy Soller 61279db991 Remove no_threaded_syscalls feature 2021-10-27 20:48:16 -06:00
Jeremy Soller 61d8b0ff32 Fix allocator race condition 2021-10-27 20:29:00 -06:00
Jeremy Soller 063881d2ca Show context name and syscall when panicking 2021-10-27 20:28:40 -06:00
Jeremy Soller 9ea278997c Disable threaded syscalls until threaded allocation issues are solved 2021-10-20 20:05:47 -06:00
Jeremy Soller 64f1533d6f Implement anonymous fmap 2021-09-22 21:04:04 -06:00
Jeremy Soller 17309754d6 Merge branch 'no-more-recursive-mapping' into 'master'
No more recursive mapping

See merge request redox-os/kernel!187
2021-08-13 02:13:07 +00:00
4lDO2 307fcf3ad7 Remove now unused TLS struct. 2021-08-11 17:46:40 +02:00
4lDO2 d6e1797620 Make Mapper::map fallible. 2021-08-11 17:46:40 +02:00
4lDO2 df145ea0a9 Utilize linear_phys_to_virt where applicable. 2021-08-11 17:46:40 +02:00
4lDO2 16a31b0cd1 Add linear_phys_to_virt and vice versa.
However, since not all platforms will allow the entire physical address
space to be simultaneously mapped to part of the virtual address space,
we may still require some dynamic mapping.
2021-08-11 17:46:40 +02:00
4lDO2 5f4978a6dc Return ENOMEM rather than panicking for PML4 alloc. 2021-08-11 17:46:40 +02:00
4lDO2 67cc6799bd Fix possible UB by checking for null allocating FX.
Namely, the global allocator API in Rust, actually only returns a null
pointer on failure, rather than wrapping it in a Result, which AllocRef
does. Since Box::from_raw(null) is direct UB, this can in theory lead to
very strange behavior.
2021-08-11 17:46:40 +02:00
4lDO2 465c461b60 WIP: Stop using recursive mapping.
Note that this is very preliminary, and I merely got my already freezing
kernel branch not to triple fault, but I would probably apply this patch
to upstream.

What is changed here, is that rather than relying on recursive mapping
for accessing page table frames, it now uses linear translation
(virt=phys+KERNEL_OFFSET). The only problem is that the paging code now
makes assumptions that the entire physical address space remains mapped,
which is not necessarily the case on x86_64 architecturally, even though
systems with RAM more than a PML4 are very rare. We'd probably lazily
(but linearly) map physical address space using huge pages.
2021-08-11 17:46:33 +02:00
Jeremy Soller 0c3542ff51 Store funmap data with the context's grants 2021-08-10 20:46:30 -06:00
Jeremy Soller f94dc3beb8 Allow current process to access its own proc data 2021-08-10 16:33:49 -06:00
Jeremy Soller 0b1445f8bd Merge branch 'fix_interrupt_handlers' into 'master'
Fix TLS in paranoid interrupt handlers

See merge request redox-os/kernel!186
2021-08-09 21:19:39 +00:00
4lDO2 1a80351a2c Fix TLS in paranoid entries. 2021-08-09 14:25:15 +02:00
4lDO2 41d5a2a786 Use naked functions in syscall inst handler too. 2021-08-06 18:08:04 +02:00
4lDO2 d7a1c6255b Fix possible race condition in paranoid ISRs.
Additionally, because it turned out to be infeasible to rely on
link-time constants in global_asm! code, I have also converted the
interrupt handlers to naked fns. This removes the proc-macro-reliant
"paste" dependency, but inserts a tiny ud2 at the end of every ISR.
2021-08-06 17:34:56 +02:00
4lDO2 1047728f35 Only set process regs for faults from ring 3.
This fixes a deadlock that might occur if a page fault is triggered
while a lock to the current context is held.
2021-08-06 15:41:38 +02:00
4lDO2 862265f150 Merge branch 'fsgsbase' into 'master'
FSGSBASE and user-controlled TLS

See merge request redox-os/kernel!185
2021-08-06 13:22:45 +00:00
4lDO2 25a82eeb1b Update syscall again. 2021-08-06 15:09:32 +02:00
4lDO2 57a1e37535 Update syscall. 2021-08-06 14:46:47 +02:00
4lDO2 87241a9d3c Pass AT_PHDR via a grant rather than the stack. 2021-08-01 14:57:41 +02:00
4lDO2 3eedbeb14d WIP: Let userspace manage fsbase/gsbase and TLS. 2021-08-01 12:09:22 +02:00
4lDO2 0968e4f87e Support fsgsbase at compile time. 2021-07-31 10:12:59 +02:00
Jeremy Soller 9c3cf84453 Merge branch 'futex_wait64' into 'master'
Add support for full 64-bit futex words

See merge request redox-os/kernel!183
2021-07-11 22:14:10 +00:00
4lDO2 6993c98e0f Update rmm and syscall. 2021-07-12 00:10:48 +02:00
Jeremy Soller 37e88ff4d3 Merge branch 'virt_is_canonical' into 'master'
Add Arch::virt_is_valid

See merge request redox-os/rmm!4
2021-07-11 21:33:34 +00:00
4lDO2 bbe6b4650a Futex: check for lower-half addrs manually. 2021-07-08 16:08:02 +02:00
4lDO2 6bc59e7013 Remove virt_kind, impl virt_is_valid() for riscv.
All there is left now is AArch64.
2021-07-08 16:06:51 +02:00
4lDO2 bcfd7b175e Update rmm. 2021-07-08 13:47:16 +02:00
4lDO2 b75c329a27 Add virt_kind and virt_is_valid for emulation. 2021-07-08 13:35:51 +02:00
4lDO2 9e9d025bb5 Add support for FUTEX_WAIT64. 2021-07-08 13:28:46 +02:00
4lDO2 32caee3095 Add arch functions for checking canonical addrs. 2021-07-08 13:27:08 +02:00
4lDO2 e92ff831b7 Move more of pipe:s init to compile time. 2021-07-05 11:54:11 +02:00
4lDO2 f2926f5f25 Pre-initialize the context list at compile time. 2021-07-05 11:30:08 +02:00
Jeremy Soller b973c5db95 Merge branch 'dont-hardcode-reg-offsets' into 'master'
Use offset_of! in context::arch::switch_to.

See merge request redox-os/kernel!180
2021-06-21 19:06:56 +00:00
4lDO2 3e5cf387d5 Use offset_of! in context::arch::switch_to.
This is definitely better than hardcoding the offsets!
2021-06-21 10:16:41 +02:00
4lDO2 6039026349 Merge branch 'update_toolchain' into 'master'
Update toolchain

See merge request redox-os/kernel!179
2021-06-18 15:15:15 +00:00
4lDO2 ecfcedb9bf Remove explicit .intel_syntax directive.
It is now default, and the new compiler generated a lot of warnings now
that Intel syntax has (luckily) become the default.
2021-06-18 09:20:13 +02:00
4lDO2 1cf5f5ea22 Update dependencies to work with latest nightly. 2021-06-17 22:42:54 +02:00
4lDO2 2dc899dc3b Update paste and align interrupt handlers. 2021-06-17 22:42:50 +02:00
4lDO2 7594dd60d2 Remove compare_and_swap from int_like!. 2021-06-17 22:42:44 +02:00
4lDO2 7d4defa5e5 Use weak CAS and use abort() in context::switch.
Previously context::switch used compare_and_swap for acquiring the
global context switch lock, but given its deprecation in more recent
Rust versions, it has been replaced with compare_exchange_weak (which
can be further optimized on some architectures).

It also replaces panic!() with abort() in switch_finish_hook, because
unwinding from assembly is not that fun.
2021-06-17 22:42:38 +02:00
4lDO2 cc6f792a03 Use options(noreturn) in all naked functions. 2021-06-17 22:42:31 +02:00
4lDO2 dc5f1fe055 Update toolchain. 2021-06-17 22:42:23 +02:00
4lDO2 c66956ca2a Remove unused #![feature(const_fn)]. 2021-06-17 18:42:03 +02:00
Jeremy Soller d3cf4db47b Prerequisites for risv64 support 2021-05-12 20:23:53 -06:00
Jeremy Soller 0a79c17307 Show meaning of CODE on page fault 2021-05-10 11:34:14 -06:00
Jeremy Soller 8130e4752b Map TSS using RMM 2021-05-07 09:13:25 -06:00
Jeremy Soller 77f6887fbc Debug use of memory map and env data 2021-05-07 08:54:36 -06:00
Jeremy Soller 38f7884e21 Improvements for aarch64 serial driver on real hardware 2021-05-06 21:25:15 -06:00
Jeremy Soller 2c474f98f9 Merge branch 'higher_half_percpu' into 'master'
Put the KPCRs in high memory, in their own PML4.

See merge request redox-os/kernel!173
2021-05-06 19:25:16 +00:00
4lDO2 36b3a4a49e Add KERNEL_PERCPU_PML4 on AArch64. 2021-05-06 21:22:48 +02:00
4lDO2 558109a9cb Put the KPCRs in high memory, in their own PML4.
This also removes the need to do another semi-expensive remap when
cloning processes, since the KPCRs (for kernel TLS) are no longer stored
in the user PML4.
2021-05-06 21:21:37 +02:00
Jeremy Soller 2e38fab913 Do not hardcode aarch64 uart 2021-05-06 13:16:50 -06:00
Jeremy Soller c4617c0bce Merge branch 'outsource-most-acpi' into 'master'
Move most of ACPI to userspace

See merge request redox-os/kernel!175
2021-05-06 18:36:06 +00:00
4lDO2 3eacbdda2a Remove unnecessary exit() diff. 2021-05-06 19:49:58 +02:00
4lDO2 fd97fa80bb Move pid back to inner scope in exit() handler. 2021-05-06 19:49:58 +02:00
4lDO2 a771ca699a Move all DMAR parsing to userspace.
We may also want to do this with the MADT and the HPET tables, and let
user drivers specify what the tables mean independent of ACPI. That is,
adding an interface for registering new CPUs, and specifying the main
timer IRQ.
2021-05-06 19:49:58 +02:00
4lDO2 e816d4801f Remove the empty fadt module. 2021-05-06 19:49:58 +02:00
4lDO2 9b4ce0d0cc WIP: Fix userspace ACPI shutdown. 2021-05-06 19:49:58 +02:00
4lDO2 b2e131b57b Fix ACPI scheme fevent warning. 2021-05-06 19:49:58 +02:00
4lDO2 7ac5bdbae0 WIP: Implement userspace-driven shutdown. 2021-05-06 19:49:58 +02:00
4lDO2 64b2dd238a Rename the kernel ACPI scheme to kernel/acpi:. 2021-05-06 19:49:57 +02:00
4lDO2 bea6747643 Move all AML code to userspace.
Currently, there are some things that need to be set up by userspace
that the kernel previously did. These include telling firmware when the
I/O APIC is used, and most importantly, shutting down the system.

The former is not particularly important, but for the latter I think
that we could implement this using a "shutdown pipe". Essentially it
will be a file that triggers an event shutting down, which would be used
to notify to acpid that the kernel is requesting a shutdown.
2021-05-06 19:49:57 +02:00
Jeremy Soller 28d1d7e847 Update version to 0.2.8 2021-05-05 21:21:57 -06:00
Jeremy Soller 46a364471c Re-init aarch64 serial port for interrupts 2021-05-05 20:46:51 -06:00
Jeremy Soller 11a3315255 Re-enable acpi feature and gate it for x86_64 only 2021-05-04 08:33:00 -06:00
Jeremy Soller ac8c7834ef Update linked branch of rmm and syscall 2021-05-04 08:14:43 -06:00
Jeremy Soller bdccce4a1b Update rmm and syscall 2021-05-04 08:12:18 -06:00
Jeremy Soller c81c4de223 Add method to get TableKind from VirtualAddress 2021-05-04 08:10:44 -06:00
Jeremy Soller 5e47692b8d Support more operations on PageFlags 2021-05-04 08:10:44 -06:00
Jeremy Soller 2f74326384 Add riscv64 sv39 and sv48 2021-05-04 08:10:34 -06:00
Jeremy Soller 3dc08c878f Fix aarch64 switch_to function 2021-05-04 08:07:44 -06:00
Jeremy Soller b9a89f2160 More fixes for building aarch64 2021-05-03 22:07:40 -06:00
Jeremy Soller 8f50785781 Fixes for building aarch64 2021-05-03 21:57:45 -06:00
Jeremy Soller c646cb76e5 Update rmm 2021-05-03 21:29:44 -06:00
Jeremy Soller 8d61c79b23 Use RMM TableKind and fix x86_64 compilation 2021-05-03 21:15:46 -06:00
Jeremy Soller 2aa4d8caf5 Merge remote-tracking branch 'origin/aarch64-rebase' into riscv64 2021-05-03 20:52:59 -06:00
Jeremy Soller 17c261553b Fixes for building x86_64 2021-05-03 20:43:18 -06:00
Jeremy Soller dfdb562e6b Use RMM PhysicalAddress 2021-05-03 20:33:31 -06:00
Jeremy Soller 9f0532b1d5 Remove unused flags from old EntryFlags 2021-05-03 17:29:55 -06:00
Jeremy Soller b9448274fc Switch to using RMM PageFlags 2021-05-03 17:28:08 -06:00
Jeremy Soller 826180659c Update rmm and syscall 2021-05-03 17:16:59 -06:00
Jeremy Soller ff8cb8abe8 Enforce must_use 2021-05-03 15:02:32 -06:00
Jeremy Soller dd0616cc8f Use RMM for TLB flushing 2021-05-03 12:42:16 -06:00
Jeremy Soller 29460e0bff Use RMM for some arch-specific paging functions 2021-05-03 12:14:49 -06:00
Jeremy Soller c46d148e26 Fix tests for aarch64 2021-05-02 21:25:27 -06:00
Jeremy Soller ad39568fe9 Fix unwrapping stack when there are kernel addresses (and there always are) 2021-05-02 19:53:31 -06:00
4lDO2 af17eeec3a Give schemes a dangling address for empty slices.
This allows schemes to avoid checking the length against zero before
constructing a slice from pointer+len that the kernel gave.
Additionally, the address is now non-canonical on x86, meaning that
userspace will fail instead of continuing with UB, if they would ever
forget to check the length.
2021-04-29 07:40:50 -06:00
Jeremy Soller 73c77d756d Print context name in exception 2021-04-28 21:15:21 -06:00
Jeremy Soller 37e6951501 Print CPU and PID when exception occurs 2021-04-28 20:59:52 -06:00
Jeremy Soller d331f72f2a Use UTF-8 for all paths 2021-04-28 20:06:07 -06:00
Jeremy Soller 8fcd375bd9 Switch Context::grants to RwLock 2021-04-28 20:04:27 -06:00
Jeremy Soller 41bea0086f Switch Context::actions to RwLock 2021-04-28 20:03:29 -06:00
Jeremy Soller 83dea72a50 Switch Context::files to RwLock 2021-04-28 20:03:25 -06:00
Jeremy Soller c7aba8fdfd Switch Context::cwd to using RwLock 2021-04-28 20:03:18 -06:00
Jeremy Soller a9bee0bbdc Require UTF-8 for context name 2021-04-28 20:03:12 -06:00
Jeremy Soller b26c3e0ae9 Make context name a RwLock 2021-04-28 20:03:05 -06:00
Jeremy Soller f90033e0e1 Use PHYS_OFFSET instead of KERNEL_OFFSET to refer to the physmap 2021-04-13 20:38:54 -06:00
Jeremy Soller afca4da382 Update syscall 2021-04-13 19:34:38 -06:00
Jeremy Soller 959a917ba2 Update RMM 2021-04-13 19:34:27 -06:00
Jeremy Soller 7fd1218465 Merge remote-tracking branch 'origin/aarch64-rebase' 2021-04-13 19:12:48 -06:00
Jeremy Soller 5fe8dcf6af Merge branch 'chown-perms' into 'master'
UserScheme: permission check EUID and EGID before proceeding with chown

See merge request redox-os/kernel!176
2021-03-21 13:02:41 +00:00
Joshua Abraham ee6493d02e UserScheme: permission check EUID and EGID before proceeding with chown
Fixes redox#1327.
2021-03-20 20:42:02 -05:00
Jeremy Soller 47048102ef Fix typo in ContextList 2021-03-02 19:57:44 -07:00
Jeremy Soller b8e47f6b8f Merge branch 'fix-invalid-grant-state' into 'master'
Fix "Grant should not exist" errors.

See merge request redox-os/kernel!174
2021-03-02 13:30:03 +00:00
4lDO2 031496ff0d Fix "Grant should not exist" errors.
This is done by making sure that when empty() is called on a context,
the grants Arc will be replaced with a new unused Arc, hence
decrementing the refcount. Previously this was only done when the
context was actually reaped, but since there is no guarantee as far as I
am aware about when this must happen, the grants could be completely
leaked, leading to the error.
2021-02-27 15:36:12 +01:00
Jeremy Soller f873fc7e1a Merge branch '4lDO2/kernel-use_gs_for_tls' 2021-02-23 09:21:00 -07:00
Jeremy Soller ba330ffc9a Merge branch 'fix-utf8-userspace-ub' into 'master'
Give schemes a dangling address for empty slices, fixing UB in userspace

See merge request redox-os/kernel!172
2021-02-23 16:17:30 +00:00
4lDO2 ad58ca1de6 Give schemes a dangling address for empty slices.
This allows schemes to avoid checking the length against zero before
constructing a slice from pointer+len that the kernel gave.
Additionally, the address is now non-canonical on x86, meaning that
userspace will fail instead of continuing with UB, if they would ever
forget to check the length.
2021-02-20 17:20:30 +01:00
4lDO2 bdc925d275 Use GS for TLS!
Previously, the kernel used the regular FS segment for Thread-Local
Storage. The problem however, is that userspace code also uses FS for
TLS, meaning that the kernel would have to switch the FS segment between
user and kernel, _upon every syscall_. This is obviously suboptimal for
performance (especially with fast syscalls such as futex, nanosleep, or
yield).

I had to search LLVM for hours, just to find out that the insertion of
the memory load with FS was actually done in the linker, so I added a
flag for that.

I haven't done any proper benchmarking, but the boot process seems to
have gotten much faster!
2021-02-17 14:44:45 +01:00
Jeremy Soller a283160c14 Merge branch 'sysretq-fix2' into 'master'
FIX: Forbid lower-half noncanonical addresses too.

See merge request redox-os/kernel!170
2021-02-17 13:32:26 +00:00
4lDO2 1988583e23 Forbid lower-half noncanonical addresses too. 2021-02-17 13:00:07 +01:00
Jeremy Soller 98af1405e6 Merge branch 'sysretq-fix' into 'master'
Fix mistyped instructions in sysretq

See merge request redox-os/kernel!169
2021-02-15 19:12:05 +00:00
4lDO2 a4b3af34a5 Use correct jump instruction. 2021-02-15 20:05:00 +01:00
4lDO2 c19581282d Use the correct add instruction when popping CS. 2021-02-15 20:02:35 +01:00
Jeremy Soller 2a9b7a0fc8 Merge branch 'sysretq' into 'master'
Use faster sysretq when returning from system calls

See merge request redox-os/kernel!168
2021-02-15 18:59:19 +00:00
4lDO2 8eb58891aa Simplify sysretq code. 2021-02-15 19:53:49 +01:00
4lDO2 5b2df9f504 Document why usermode() can omit rcx check. 2021-02-15 19:53:49 +01:00
4lDO2 ff33090fd0 Check whether RCX is canonical in sysretq. 2021-02-15 19:53:41 +01:00
4lDO2 a183953ee8 Motivate usage of the IST without SWAPGS involved. 2021-02-15 19:53:37 +01:00
4lDO2 a3583a10ce Only swapgs when leaving/entering userspace code. 2021-02-15 19:53:37 +01:00
4lDO2 05db0f5977 Temporarily fix sysretq by swapping gs 4 times.
In order words, it swaps gs both directly at the start of the syscall
handler, then swaps it back, and the at the end of the syscall handler.
I cannot tell for sure why this is necessary, but probably since some
interrupt handler will execute swapgs in the wrong order or something.
2021-02-15 19:53:37 +01:00
4lDO2 1a8016b985 Give NMI, #DF, and #MC handlers a special stack.
This is done by allocating an extra 64 KiB per CPU, and putting it in
the Interrupt Stack Table.
2021-02-15 19:53:37 +01:00
4lDO2 5a638691e0 Treat GS as always pointing to TSS in kernel space. 2021-02-15 19:53:37 +01:00
4lDO2 c913c3be80 Use sysretq in usermode(). 2021-02-15 19:53:24 +01:00
4lDO2 a8dc3fcaf1 Begin using sysretq in the system call handler. 2021-02-15 19:53:01 +01:00
Jeremy Soller 6db78cce24 Use UTF-8 for all paths 2021-02-14 13:45:03 -07:00
Jeremy Soller 11b5e2fe59 Merge branch 'switch_to_safer' into 'master'
Prevent possible UB, and use naked functions correctly.

See merge request redox-os/kernel!167
2021-02-13 22:42:18 +00:00
4lDO2 a706a0dae4 Rewrite signal_handler_wrapper as single asm block.
The reason for these types of rewrites, is that more recent Rust
compilers have started to deprecate naked functions that consist of more
than only a single asm block, as they can trigger all sorts of UB.
2021-02-13 21:55:40 +01:00
4lDO2 47c3b2269f Fix context switching.
Previously there was a triple fault, due to a combination of reasons
(e.g. rsp and rbp being ordered in the struct and in the assembly).

Now, the locks will be held __all the way until the new context__ has
been switched to, which completely eliminates any possibility that the
"pcid fault" originates here.

While I am unsure whether this will work, this could also be an
opportunity to be able to remove CONTEXT_SWITCH_LOCK fully.
2021-02-13 21:55:40 +01:00
4lDO2 ef4270e473 WIP: Attempt to rewrite switch_to in assembly.
This is due to a warning in more recent compilers, which forbid anything
but a single inline assembly block, in naked functions. It does
unfortunately triple fault right now, but I hope I may be able to fix it
soon.
2021-02-13 21:55:36 +01:00
Jeremy Soller c19bd573b5 Switch Context::grants to RwLock 2021-02-13 13:06:13 -07:00
Jeremy Soller 2611985a38 Switch Context::actions to RwLock 2021-02-13 13:01:20 -07:00
Jeremy Soller bfaf8438a1 Switch Context::files to RwLock 2021-02-13 12:57:53 -07:00
Jeremy Soller 55d2467420 Switch Context::cwd to using RwLock 2021-02-13 12:24:19 -07:00
Jeremy Soller cd6ede84fe Fix warnings from futex changes 2021-02-13 12:16:55 -07:00
Jeremy Soller 238702f7d1 Require UTF-8 for context name 2021-02-13 12:16:47 -07:00
Jeremy Soller b9f4a915ea Make context name a RwLock 2021-02-13 11:10:21 -07:00
Jeremy Soller 76d8c1074c Merge branch 'futex-fix' into 'master'
Use physical addresses internally in futex, and fix a context switching data race

See merge request redox-os/kernel!166
2021-02-13 17:52:09 +00:00
4lDO2 6f3fc3a4f4 Make cpu_id_opt non-mutable. 2021-02-03 18:10:39 +01:00
4lDO2 44527a8340 Fix a very annoying multi_core data race*.
So, when I first introduced io_uring, it was not compiled with the
`multi_core` kernel feature, mainly to make development easier (I
thought). However, since io_uring allows multiple simultaneous system
calls, we cannot longer make the in-kernel contexts block, for example
when receiving a message from a pipe, if there can be multiple such
requests simultaneously.

This has required me to change WaitCondition into allowing multiple
simultaneous tasks; although, it introduces a potential race condition:
since a future can only return Pending and not block directly before
releasing the lock (condvar logic), we need some way to make sure that
nothing happens after the context finds out that it has to wait, and the
actual waiting. If a message is pushed in between, and the waker is
called (Context::unblock), just before it was going to block itself,
then we miss the message, and potentially cause a deadlock.

Fortunately, in order to block and unblock contexts, we need to
exclusively lock the context. So, what we can do to ensure that waking
while running is no longer a no-op, is to introduce a "wake flag", which
is set only if the context is currently running, and Runnable.

But, this still caused all weird kinds of hard-to-debug problems, with
arbitrary CPU exceptions and possibly memory corruption. The reason for
this, is that the context switching logic uses really unsafe operations,
which is why context switching (at the moment) requires an exclusive
lock. Before this commit, it would modify the `running` field after the
lock had been released, which obviously can cause a data race, when the
regular context waker code that is run within a system call, locks the
context but not the global switching lock.

The solution was to make sure that the locks were held, all the way
until the actual switching, which was done in assembly. There can still
be a race condition here, since it modifies memory containing registers
after the lock has been released, even if it may be behind &mut on
another context, which can be UB, but it has not contributed to any
actual bugs... yet.

* I have not yet done that rigorous testing, but it appears to work well
enough, and I have not encountered the bug after like 10 tries.
2021-02-03 18:06:42 +01:00
4lDO2 fec8f4aa0c Use physical addresses internally for futexes.
This solves a bug, that allows processes in different address spaces to
be the target of a futex wakeup call, even though that process is in
another address space!
2021-02-03 18:06:42 +01:00
Jeremy Soller 31887bf532 Merge branch 'floating-point-fixups' into 'aarch64-rebase'
Floating point fixups

See merge request redox-os/kernel!165
2021-01-28 17:02:32 +00:00
Robin Randhawa 1e10cac3e1 aarch64: Increase storage for FP context to consider AArch64's needs
Brute-forcing this at present. Would be better to wrap this
conditionally for the architecture.
2021-01-28 16:51:50 +00:00
Robin Randhawa afca6ab31c aarch64: Fix incorrect FP save/restore 2021-01-28 16:50:07 +00:00
Jeremy Soller a06636b77f Update syscall 2021-01-27 10:44:52 -07:00
Jeremy Soller f8f1596f67 Merge branch 'add-floating-point-support' into 'aarch64-rebase'
Add floating point support

See merge request redox-os/kernel!164
2021-01-27 17:43:57 +00:00
Robin Randhawa 4dbfaf3ec1 Nit: Add missing close brace in code comment 2021-01-27 17:19:37 +00:00
Robin Randhawa 1462fe8638 aarch64: context: Align with x86_64 code 2021-01-27 17:17:59 +00:00
Robin Randhawa 3afa0f0895 aarch64: Basic Floating-point/SIMD support 2021-01-27 17:17:11 +00:00
Robin Randhawa 00723c4ac2 aarch64: Make IRQs use the exception macros 2021-01-26 19:37:23 +00:00
Jeremy Soller 9621c64991 Update syscall 2021-01-26 11:46:09 -07:00
Jeremy Soller 81c33a3f6a Merge branch 'aarch64-base' into 'aarch64-rebase'
Misc exception handling fixups

See merge request redox-os/kernel!163
2021-01-26 18:41:53 +00:00
Robin Randhawa 28dfc0f46b aarch64: Basic exception handlers 2021-01-26 18:18:19 +00:00
Robin Randhawa 4a215c7c2c aarch64: exception management and clone fixups 2021-01-26 18:17:09 +00:00
Jeremy Soller fa62b48285 Merge branch 'fixes-for-grant-maps-and-others' into 'aarch64-rebase'
Fixes for grant maps and others

See merge request redox-os/kernel!162
2021-01-22 15:15:08 +00:00
Robin Randhawa 78d1cd1798 syscall: process: empty: Use user-space specific page table 2021-01-21 11:53:35 +00:00
Robin Randhawa 6cacbb47f6 scheme: user: Use user-space specific pagt table 2021-01-21 11:53:07 +00:00
Robin Randhawa 591775874b ptrace: with_context_memory: use user-space specific page table 2021-01-21 11:50:56 +00:00
Robin Randhawa 65448c2d48 aarch64: context: memory: Grant::map_inactive: Bugfix
When mapping one (from) virtual address range to another (to) virtual
address range, be mindful of which mapper type to use for each range.

Before this, the same mapper type was used for both ranges. This meant
that if from and to were different (as in not both kernel virtual
addresses or user virtual addresses) then it would appear that either
from or to was not mapped previously and the kernel would panic.
2021-01-21 11:41:26 +00:00
Robin Randhawa 75870a655f aarch64: context: Add separate kspace and uspace page table getters 2021-01-21 11:40:02 +00:00
Robin Randhawa 3da345867a aarch64: paging: Derive Debug, PartialEq for VirtualAddressType
This makes asserts on VirtualAddressType equality possible.
2021-01-21 11:38:46 +00:00
Robin Randhawa 452196b81f aarch64: consts: Use the same USER_TLS_SIZE as x86_64 2021-01-21 11:37:32 +00:00
Jeremy Soller d76298b3f8 Merge branch 'wip-clone-and-misc-fixes' into 'aarch64-rebase'
Wip clone and misc fixes

See merge request redox-os/kernel!161
2021-01-18 23:00:00 +00:00
Robin Randhawa f1db56f026 aarch64: clone: Further uspace and kspace mods 2021-01-18 21:55:42 +00:00
Robin Randhawa 9429032cec aarch64: clone: Further clone_ret + tpidr_el0 fixes 2021-01-18 21:53:04 +00:00
Robin Randhawa fd0336692d aarch64: clone: Introduce kernel and user space specific mods
At present these are done 'wholesale' without any regard for x86_64.
That needs to change eventually.
2021-01-18 21:50:19 +00:00
Robin Randhawa c188a60871 aarch64: Fix clone_ret
FIXME: Explain the magic numbers here later.
2021-01-18 21:47:28 +00:00
Robin Randhawa 95bd8f2013 clone: Make stack manipulation arch specific 2021-01-17 10:26:49 +00:00
Robin Randhawa ae0aebd036 aarch64: clone: Return from clone syscall
No CLONE_STACK functionality yet.
2021-01-17 10:12:42 +00:00
Robin Randhawa 67ec6c23e7 aarch64: Move tpidr_el0 setup from spawn to switch 2021-01-17 10:09:03 +00:00
Robin Randhawa 67d72532a9 aarch64: usermode: Remove tpidr_el0 manipulation
Was using the incorrect USER_TLS_OFFSET instead of USER_TCB_OFFSET. In
any case, this is better done in process::clone.
2021-01-17 10:06:04 +00:00
Robin Randhawa 3585f620b0 aarch64: clone: Fix incorrect stack offset in clone_ret 2021-01-17 10:03:50 +00:00
Robin Randhawa 208fb681f4 aarch64: vectors: Manage unhandled exceptions
So we can more clearly see when things go wrong.
2021-01-17 10:01:34 +00:00
Jeremy Soller 17fd135017 Merge branch 'pagetabletype-and-misc-fixes' into 'aarch64-rebase'
Pagetabletype and misc fixes

See merge request redox-os/kernel!158
2021-01-15 19:50:13 +00:00
Jeremy Soller e124fa171b Merge branch 'misc-fixes' into 'aarch64-rebase'
Misc fixes

See merge request redox-os/kernel!160
2021-01-15 19:43:23 +00:00
Robin Randhawa 5bc9dea242 aarch64: context::switch: update the CONTEXT_SWITCH_LOCK 2021-01-15 19:03:42 +00:00
Robin Randhawa 6677cfbf1e aarch64: Make interrupt::pause use nop so we can move ahead before interrupts are enabled 2021-01-15 19:02:43 +00:00
Robin Randhawa 825bc4a02d aarch64: spawn: split out arch specific mods 2021-01-15 09:12:30 -07:00
Robin Randhawa 14d79927af aarch64: Add a set_tcb method to setup tpidr_el0 2021-01-15 09:12:30 -07:00
Robin Randhawa ae3a55f5d1 Introduce a PageTableType enum to help distinguish User and Kernel Tables 2021-01-15 09:12:30 -07:00
Robin Randhawa 76129ddf75 aarch64: Mirror PRESENT and VALID bits in Page and Table descriptors 2021-01-15 15:54:25 +00:00
Robin Randhawa c5e077546a aarch64: spawn: split out arch specific mods 2021-01-15 15:51:47 +00:00
Robin Randhawa e0a7471cf8 aarch64: Add a set_tcb method to setup tpidr_el0 2021-01-15 15:50:00 +00:00
Robin Randhawa 9c3f6e3660 Introduce a PageTableType enum to help distinguish User and Kernel Tables 2021-01-15 15:49:04 +00:00
Jeremy Soller bdea7f553a Remove PRESENT flag from aarch64 descriptors 2021-01-15 06:57:02 -07:00
Jeremy Soller 5f8b004476 Fix typo in InterruptStack parameter 2021-01-15 06:56:36 -07:00
Robin Randhawa 252ec24905 aarch64: Use target-feature for NEON insn suppression and tpidr_el1 use 2021-01-15 06:09:42 -07:00
Robin Randhawa aa3839605f aarch64: Remove code-model from the JSON spec
We use a target-feature for this now.
2021-01-15 06:09:42 -07:00
Robin Randhawa ea21fba3aa build.rs: aarch64: Specify target for cc::Build
Oddly, not specifying this or using aarch64-unknown-none (which would be
the default that cc gets from the TARGET environment variable) both
fail to invoke the appropriate compiler to build the asm code.

Using aarch64-unknown-redox works but shouldn't really be needed. This
is perhaps because of some odd arrangement of KTARGET, TARGET, the
installed prefix toolchain and the kernel target JSON spec.

The early_init asm code shall be replaced by a pure Rust bootloader
eventually so let's move with this for the moment.
2021-01-15 06:09:42 -07:00
Robin Randhawa 02c37d3fae WIP: aarch64 rebase 2021-01-15 05:54:42 -07:00
Jeremy Soller 132d91d3aa Fixed page flags for aarch64 2021-01-14 15:54:51 -07:00
Jeremy Soller cb6b44d69e Use devmap offset for physmap on aarch64 2021-01-14 12:35:27 -07:00
Jeremy Soller 1214f3dcdc Add PageFlags to abstract differences between architectures 2021-01-14 10:01:36 -07:00
Jeremy Soller c5774c5529 Add TableKind for future use 2021-01-14 09:16:46 -07:00
Jeremy Soller dafd9cb3c4 Add ENTRY_FLAG_DEFAULT_PAGE and ENTRY_FLAG_DEFAULT_TABLE 2021-01-14 09:16:37 -07:00
Jeremy Soller fad48af985 WIP: aarch64 support 2021-01-13 10:47:35 -07:00
Jeremy Soller 5e10feeaeb Fix whitespace in linker file 2021-01-12 19:59:05 -07:00
Jeremy Soller 6c4c19a95c Move consts to arch 2021-01-12 19:57:42 -07:00
Jeremy Soller ed55b49093 Update aarch64 target to new Rust 2021-01-12 19:57:07 -07:00
Jeremy Soller ea6b1e7f8b Update redox_syscall to 0.2.4 2021-01-11 07:01:05 -07:00
Jeremy Soller 334584b3d5 Use rmm::PhysicalAddress and rmm::VirtualAddress directly 2021-01-09 21:16:11 -07:00
Jeremy Soller ccddabadf7 Make x86 specific dependencies, x86 specific 2021-01-09 20:12:59 -07:00
Jeremy Soller e771e6a4d9 Reduce duplication in context::switch 2020-12-27 20:03:13 -07:00
Jeremy Soller 9033902830 Better messaging about which timer is used 2020-12-23 10:33:09 -07:00
Jeremy Soller 04cc8a2d9c Simplify reserved memory hack 2020-12-23 09:55:03 -07:00
Jeremy Soller 7355ae1671 Hack to ensure kernel is mapped even if it uses reserved memory 2020-12-23 09:46:34 -07:00
Jeremy Soller b1c7b9638d Merge branch 'fix-repr-packed' into 'master'
Fix possible UB by implementing Copy and Clone manually for BuddyEntry.

See merge request redox-os/rmm!1
2020-12-20 16:08:31 +00:00
4lDO2 9a716604fc Implement Copy and Clone manually for BuddyEntry.
This fixes a warning that may in the future become an error, about the
possibility for unaligned references, since the derive macros apparently
rely on creating references to fields. Unaligned references are direct
UB.
2020-12-20 16:36:52 +01:00
Jeremy Soller cff858b455 Merge branch 'rmm' into 'master'
Support for RMM

See merge request redox-os/kernel!155
2020-11-27 16:49:39 +00:00
Jeremy Soller f5ac405db6 Support for RMM 2020-11-27 16:49:39 +00:00
Jeremy Soller cdbeecfffe Remove some warnings 2020-09-14 09:47:29 -06:00
Jeremy Soller 936352a049 FrameCount::new function 2020-09-14 09:47:23 -06:00
Jeremy Soller 8e0df608e2 Add allocator usage information 2020-09-14 09:41:56 -06:00
Jeremy Soller e94d7e7772 Rewrite buddy allocator 2020-09-14 09:41:42 -06:00
Jeremy Soller a775c9e987 Require Arch to implement Clone and Copy 2020-09-14 09:08:28 -06:00
Jeremy Soller a12be1b172 Keep track of last free page 2020-09-09 20:19:28 -06:00
Jeremy Soller f17a1b52bd Test multi-page allocation 2020-09-09 16:02:59 -06:00
Jeremy Soller 0c44dde349 Implement multi-page allocations in buddy allocator (poorly) 2020-09-09 16:02:44 -06:00
Jeremy Soller 711414223b Fix buddy map footer read address 2020-09-09 11:11:39 -06:00
Jeremy Soller fed3110ae8 Better unimplemented messages 2020-09-09 10:55:29 -06:00
Jeremy Soller 811dd09de4 Remove unused function for empty buddy allocator 2020-09-08 20:20:56 -06:00
Jeremy Soller fb88d1669f Add unmap function 2020-09-08 19:59:13 -06:00
Jeremy Soller e6d93d5743 Allow const creation of buddy allocator 2020-09-08 15:51:13 -06:00
Jeremy Soller 5990a04e13 Rename Mapper::active to Mapper:make_current 2020-09-08 15:13:01 -06:00
Jeremy Soller f97a80fecb Flush user table changes 2020-09-08 15:11:26 -06:00
Jeremy Soller e8ea483832 Add page flushing, add support for mapping anonymous pages 2020-09-08 14:56:57 -06:00
Jeremy Soller 6375c175f7 Do not zero tables when not necessary in buddy allocator 2020-09-08 13:52:45 -06:00
Jeremy Soller db7869d995 Add table function for mapper, to get inner page table 2020-09-08 13:52:22 -06:00
Jeremy Soller b4c8ab797d Zero all allocations 2020-09-08 12:41:46 -06:00
Jeremy Soller 8484d4447c Fix compilation using no_std 2020-09-08 11:16:59 -06:00
Jeremy Soller 1b58d2a956 Add FrameCount struct, improve zeroing page performance 2020-09-08 11:13:49 -06:00
Jeremy Soller a64e790471 Fix warnings 2020-09-08 10:54:59 -06:00
Jeremy Soller fcb64422c4 Add FrameAllocator trait, move frame allocator and mapper to library 2020-09-08 10:52:52 -06:00
Jeremy Soller 29945b84b1 no_std building support 2020-09-08 10:24:53 -06:00
Jeremy Soller d153af8b83 Fix calculation of free areas 2020-09-08 10:24:43 -06:00
Jeremy Soller 62da3afef5 Add clearing of freed pages in BuddyAllocator 2020-09-08 09:35:34 -06:00
Jeremy Soller 52a08e70fd Add buddy allocation 2020-09-08 09:27:40 -06:00
Jeremy Soller 57d66236b7 WIP buddy allocator free pages using bitmap 2020-09-07 22:02:52 -06:00
Jeremy Soller 4eb4f579df Set entry when performing allocation 2020-09-07 22:02:24 -06:00
Jeremy Soller 21d7f28fdc Allocate and clear buddy maps 2020-09-07 21:44:23 -06:00
Jeremy Soller d752c5c91e WIP: buddy allocator 2020-09-07 21:05:04 -06:00
Jeremy Soller 011212905d Add WIP slab allocator 2020-09-07 20:01:40 -06:00
Jeremy Soller d450cafad6 Add mapping functionality 2020-09-06 21:07:14 -06:00
Jeremy Soller 03d3264085 Add index_of function to PageTable 2020-09-06 21:06:58 -06:00
Jeremy Soller d9500dc24e Fix excess size of emulated memory, do not print emulated mapping 2020-09-06 21:06:41 -06:00
Jeremy Soller 2dc0853903 Add constants for sizes 2020-09-06 21:06:12 -06:00
Jeremy Soller 4bf43652c3 Only use offset mapping 2020-09-06 14:38:31 -06:00
Jeremy Soller d5111d429e Implement PHYS_OFFSET mapping 2020-09-06 14:30:50 -06:00
Jeremy Soller a40b26293b Do not use explicit register fo x86_64 table operations 2020-09-06 14:20:29 -06:00
Jeremy Soller 379294b59f Implement x86_64 arch functions 2020-09-06 14:18:01 -06:00
Jeremy Soller f801a40908 Add function for addresses 2020-09-06 14:17:49 -06:00
Jeremy Soller 5fc0a080ad Update nightly 2020-09-06 14:17:26 -06:00
Jeremy Soller a482e506c5 Use physical and virtual address abstraction for arch functions 2020-09-06 13:58:40 -06:00
Jeremy Soller ab07997bbe Add derives for physical and virtual addresses 2020-09-06 13:55:38 -06:00
Jeremy Soller 8efc425b07 Add phys_to_virt function 2020-09-06 13:54:58 -06:00
Jeremy Soller 023bb5811a Add definition of physical address size 2020-09-06 13:25:21 -06:00
Jeremy Soller 2df212f48d Add tests to ensure correct constant calculation 2020-09-06 13:00:01 -06:00
Jeremy Soller f5e8c031ca Move constants into Arch trait 2020-09-06 08:30:56 -06:00
Jeremy Soller 8c8e09d23e Refactor, use trait for arch differences 2020-09-05 21:02:27 -06:00
Jeremy Soller 58323aadd0 Implement recursive mapping 2020-09-05 19:00:32 -06:00
Jeremy Soller 556b777386 Define for page levels, enable recursive mapping by default 2020-09-04 21:19:57 -06:00
Jeremy Soller adad6bbe65 Add recursive mapping 2020-09-04 21:07:31 -06:00
Jeremy Soller a55e19868e Add abstraction for page table 2020-09-04 20:56:48 -06:00
Jeremy Soller a70bc00264 Improve machine read/write functions 2020-09-04 15:42:42 -06:00
Jeremy Soller 048298d65b Add README.md 2020-09-04 21:24:43 +00:00
Jeremy Soller 21dc9624d7 Add LICENSE 2020-09-04 21:23:23 +00:00
Jeremy Soller e7ae8e6812 init 2020-09-04 15:22:35 -06:00
Jeremy Soller 8b27de416b Update Cargo.lock 2020-08-27 10:26:56 -06:00
Jeremy Soller afa175f778 Merge branch 'jD91mZM2/kernel-remove-brk' into HEAD 2020-08-27 10:26:29 -06:00
Jeremy Soller 1baeb5a891 Format memory entries using hex 2020-08-27 09:43:39 -06:00
Jeremy Soller 8211e92c02 Merge branch 'master' of https://gitlab.redox-os.org/redox-os/kernel 2020-08-27 09:43:23 -06:00
Jeremy Soller 858dd6ef51 Update syscall 2020-08-27 09:43:15 -06:00
Jeremy Soller 45b48f8078 Merge branch 'fix-deprecate' into 'master'
Fix printing of deprecation warning

See merge request redox-os/kernel!151
2020-08-27 15:33:12 +00:00
Jeremy Soller 853b77e3a4 Unmap owned grants, use owned grants to calculate memory usage 2020-08-25 10:35:55 -06:00
Jeremy Soller 4e3df8b953 Merge branch 'aj-chdir-initfs-message' into 'master'
Add more descriptive error message for when initfs chdir fails

See merge request redox-os/kernel!150
2020-08-17 16:25:46 +00:00
Jeremy Soller 6ba3850042 Merge branch 'aj-logging' into 'master'
Use logging instead of println in src/lib.rs

See merge request redox-os/kernel!149
2020-08-17 16:18:08 +00:00
jD91mZM2 5fc6acacc4 Fix printing of deprecation warning 2020-08-17 15:25:14 +02:00
Aaron Janse dc6132dc06 elaborate error message for initfs chdir failure 2020-08-17 03:24:56 -07:00
Aaron Janse dfcf5be778 use logging instead of println 2020-08-17 02:55:40 -07:00
jD91mZM2 922b3d0437 Remove brk 2020-08-15 17:36:50 +02:00
Jeremy Soller 0590a71b87 Merge branch 'mynameissherlockholmes' into 'master'
Investigate why user heap isn't mapped

See merge request redox-os/kernel!147
2020-08-15 15:27:33 +00:00
jD91mZM2 da7b813fa9 Investigate why user heap isn't mapped
Took me way too long to spot this :D
2020-08-15 17:22:34 +02:00
Jeremy Soller e3814c1ca2 Merge branch 'deprecate-stuff' into 'master'
Deprecate the original fmap/funmap

See merge request redox-os/kernel!146
2020-08-14 15:20:36 +00:00
jD91mZM2 78e5c71103 Deprecate the original fmap/funmap
The cool thing here is that we're temporarily binary compatible with the
old stuff, so if anyone would use an old version of redox_syscall we can
easily find them with these prints.
2020-08-14 15:18:47 +02:00
Jeremy Soller 2057b889ae Merge branch 'log_experiment' into 'master'
Log experiment

See merge request redox-os/kernel!144
2020-08-09 13:01:39 +00:00
Wren Turkal 4c009530a8 Make x86_64 log writer not use println!.
This opens the door to completely elimnating println! usage from the
kernel.

Signed-off-by: Wren Turkal <wt@penguintechs.org>
2020-08-09 00:00:26 -07:00
Wren Turkal 5301057324 Convert some println -> log::info!.
Signed-off-by: Wren Turkal <wt@penguintechs.org>
2020-08-08 21:18:18 -07:00
Wren Turkal dafd2e9f98 Add a way to customize how logging is done.
Each architecture may have a different method to enable logging. Now
that can be customized with a function passed to the init_logger
function.

Also, provide a minimal x86_64 implementation.

This is the first commit where you can see logging coming from the log
crate.

Signed-off-by: Wren Turkal <wt@penguintechs.org>
2020-08-08 21:18:15 -07:00
Wren Turkal 29a9592e7b Re-export log::set_max_level.
Signed-off-by: Wren Turkal <wt@penguintechs.org>
2020-08-08 20:50:55 -07:00
Wren Turkal 50675842af Add logger init and initialize on x86_64.
Signed-off-by: Wren Turkal <wt@penguintechs.org>
2020-08-08 20:50:53 -07:00
Wren Turkal 03e60f7da6 Add log crate and add a generic logger.
This is the first step of integrating the log crate as the main way to
log messages from the kernel.

Also, reexport all log macros. This module should eventually be the
only logging API used in the kernel.

Signed-off-by: Wren Turkal <wt@penguintechs.org>
2020-08-08 20:48:41 -07:00
Jeremy Soller d8a0a8182d Merge branch 'add_debug_to_structs' into 'master'
Implement Debug for a couple structs.

See merge request redox-os/kernel!142
2020-08-08 12:55:53 +00:00
Jeremy Soller ad6035c7de Merge branch 'idiomatic-rust' into 'master'
Replace llvm_asm with asm

See merge request redox-os/kernel!141
2020-08-03 15:09:08 +00:00
jD91mZM2 bdc504f862 Update redox_syscall again 2020-08-03 16:08:15 +02:00
Wren Turkal efb5b47463 Implement Debug for a couple structs.
I am finding it useful to be able to pretty print Mappers and
ActivePageTable structs.

Signed-off-by: Wren Turkal <wt@penguintechs.org>
2020-08-02 22:13:24 -07:00
Jeremy Soller 1a8f47330e Add a message when user heap is not mapped, do not panic 2020-08-02 17:07:57 -06:00
Jeremy Soller ec1809e7c0 Add memory: to null namespace, temporarily 2020-08-02 17:05:17 -06:00
Jeremy Soller 6f3094cb2b Work around unmapping user heap 2020-08-02 16:33:56 -06:00
Jeremy Soller 220e53c24d Show CPU and PID in kernel panic 2020-08-02 12:12:59 -06:00
jD91mZM2 9ab778d649 Update redox_syscall 2020-08-01 16:53:39 +02:00
jD91mZM2 f07603902d Replace all llvm_asm! uses with asm! 2020-08-01 14:56:46 +02:00
Jeremy Soller c8263cc4bd Merge branch 'latest-rust' into 'master'
Support latest rust

See merge request redox-os/kernel!140
2020-08-01 12:22:17 +00:00
jD91mZM2 895c0c11da Use cargo for lto over manually entering rustflags 2020-08-01 13:19:12 +02:00
jD91mZM2 fbeb297949 Fix compilation since last rust
Thanks to @4lDO2 for all this. I just moved his changes to io_uring onto
the master branch of the kernel. I take no credit.
2020-08-01 13:00:52 +02:00
jD91mZM2 93856b43b9 s/\basm!/llvm_asm!/g 2020-08-01 12:31:56 +02:00
Jeremy Soller c8fb3792a9 Merge branch 'memory' into 'master'
Implement funmap2

See merge request redox-os/kernel!139
2020-07-30 13:36:59 +00:00
jD91mZM2 877259257c Update syscall submodule 2020-07-30 15:05:46 +02:00
jD91mZM2 55c3377c5c Use VirtualAddress wrapper in user.rs 2020-07-30 14:21:57 +02:00
jD91mZM2 3fca287bcc Remove debug prints 2020-07-30 13:21:17 +02:00
jD91mZM2 34194e2b79 Implement partial funmap-ing for user schemes 2020-07-30 13:08:03 +02:00
jD91mZM2 0ffa9b0be6 Track region instead of address in user.rs 2020-07-30 11:42:49 +02:00
jD91mZM2 9eb2aebd43 Implement unmapping multiple whole maps 2020-07-28 11:34:50 +02:00
jD91mZM2 639e603c4f WIP: Add funmap2 2020-07-25 22:29:21 +02:00
jD91mZM2 a811774c58 Add necessary functions for funmap2 2020-07-23 16:45:35 +02:00
jD91mZM2 ccc577b3a1 Abstract over finding nice addresses 2020-07-23 11:22:54 +02:00
jD91mZM2 57c167d2fa Make grants be a BTreeSet 2020-07-22 15:09:28 +02:00
Jeremy Soller 2f94031221 Merge branch 'auxv' into 'master'
Implement auxiliary vector

See merge request redox-os/kernel!136
2020-07-21 14:16:05 +00:00
jD91mZM2 9c41424d3a Apply suggestion to src/syscall/process.rs 2020-07-21 14:10:58 +00:00
jD91mZM2 2782a5a7a9 Apply suggestion to src/syscall/process.rs 2020-07-21 14:10:43 +00:00
jD91mZM2 5dc65a920f Add restrictions on fmap 2020-07-21 16:08:28 +02:00
jD91mZM2 cf709783d6 Reverse mod/syscall.rs 2020-07-20 11:17:36 +02:00
jD91mZM2 07baf70c7a Don't push interpreter as argv[0] 2020-07-20 11:09:56 +02:00
Jeremy Soller 854149ee97 Support for debugging to system76 EC 2020-07-19 10:24:15 -06:00
jD91mZM2 ff5354b5b5 Fix mmap when using out-of-place address 2020-07-18 15:03:23 +02:00
jD91mZM2 2d63009ba4 Add debug entry for fmap2 2020-07-18 13:40:12 +02:00
jD91mZM2 310a425c65 Merge branch 'master' into auxv 2020-07-18 12:19:11 +02:00
jD91mZM2 615e516585 Add extra assembler metadata 2020-07-16 17:13:30 +02:00
jD91mZM2 11f26140f5 Fix most MR concerns 2020-07-16 16:59:58 +02:00
jD91mZM2 895a4a5656 Deprecate int 0x80
Mainly because I think the code could be cleaner if we can remove
support entirely :)
2020-07-16 16:33:25 +02:00
jD91mZM2 4fbe86a9ce Fix random userspace page faults
I was an idiot and forgot rbx wasn't always backed up. As a result, we
should never ever write to it
2020-07-16 16:32:48 +02:00
jD91mZM2 acebd1a8d1 Merge remote-tracking branch 'origin/master' into global-asm 2020-07-16 15:35:42 +02:00
jD91mZM2 b00456dbb9 WIP: Continue trying to fix clone_ret 2020-07-16 13:46:53 +02:00
Jeremy Soller c78b69969f Include trampoline in kernel to fix multi_core on EFI 2020-07-15 21:46:15 -06:00
Jeremy Soller 1e44f157d0 Fix graphical_debug feature 2020-07-15 16:10:51 -06:00
jD91mZM2 145c1898be Merge branch 'master' into global-asm 2020-07-15 12:05:34 +02:00
jD91mZM2 3bb234009a WIP: Ensure clone_ret correctness 2020-07-15 11:43:17 +02:00
Jeremy Soller 93303af931 Merge branch 'catch-kernel-signal' into 'master'
Catch kernel signal

See merge request redox-os/kernel!135
2020-07-14 12:53:46 +00:00
Jeremy Soller 6b2302f92e Merge branch 'paging-packed-use-unsafe' into 'master'
Wrap borrows of page table entries in unsafe

See merge request redox-os/kernel!126
2020-07-14 12:53:21 +00:00
jD91mZM2 ca3ddcdeca Add TODOs for mapping PTI properly
I think we need to reimplement these functions in assembly :(
2020-07-14 09:14:16 +02:00
jD91mZM2 701c31cee0 Fix PTI compilation
It's broken on master anyway
2020-07-13 15:49:37 +02:00
jD91mZM2 5927743ff8 fixup! WIP: Rewrite interrupts as global assembly 2020-07-13 15:25:15 +02:00
jD91mZM2 aa3279455d Merge branch 'master' into auxv 2020-07-13 12:48:48 +02:00
jD91mZM2 ec2c42dc66 WIP: Work around fmap quirks 2020-07-13 12:48:29 +02:00
jD91mZM2 fbdfcd2ba0 WIP: Rewrite interrupts as global assembly
Because the way we were using inline assembly was technically incorrect
and breaking the laws of rust

This *finally* compiles. That doesn't mean it works!
2020-07-11 16:15:25 +02:00
jD91mZM2 4b8d2e45c6 Add AT_PHDR 2020-07-10 12:56:08 +02:00
jD91mZM2 3430eadc9a Add auxiliery vector 2020-07-10 12:34:32 +02:00
Jeremy Soller dbfc8ab188 Merge branch 'no_mprotect_crashes' into 'master'
Don't panic on mprotect for unmapped pages

See merge request redox-os/kernel!134
2020-07-09 12:01:33 +00:00
bjorn3 7b76ab3356 Don't panic on mprotect for unmapped pages 2020-07-09 11:03:02 +02:00
4lDO2 01041a5d8a Implement (mostly) fmap2 for memory: 2020-07-08 20:49:16 +02:00
jD91mZM2 56f55a3b97 Always save proccess registers
Not sure if this is going to be required, and I'm not sure if this will
hurt performance, y'know, *always* doing this.
2020-07-08 11:47:12 +02:00
jD91mZM2 103ed1b17f Make interrupt stack readable on kernel signals 2020-07-08 11:44:04 +02:00
Jeremy Soller 92cad589d9 Merge branch 'moar-gdb' into 'master'
Simplify EXEC catching + add signal handling

See merge request redox-os/kernel!132
2020-07-07 12:49:16 +00:00
jD91mZM2 184824234e Update submodule 2020-07-07 14:47:21 +02:00
jD91mZM2 039f7f5c83 Simplify EXEC catching
Instead of having a separate flag, let's reuse STOP_SINGLESTEP :)

I wasn't thinking enough when making this flag!
2020-07-07 14:16:42 +02:00
jD91mZM2 cdcb34486b Keep singlestep across signals 2020-07-07 13:32:10 +02:00
Jeremy Soller 77f3a17c14 Fix warnings in live: 2020-06-30 09:36:19 -06:00
Jeremy Soller d82eb57e9c Update live: to new seek function 2020-06-30 09:08:55 -06:00
Jeremy Soller 7989aa0327 Merge branch 'signed-seek' into 'master'
change seek sig to match posix - signed pos and result

See merge request redox-os/kernel!123
2020-06-27 13:26:53 +00:00
Graham MacDonald af63c9773c Merge remote-tracking branch 'origin/master' into signed-seek 2020-06-27 14:20:51 +01:00
Graham MacDonald 2d8b2d94b9 hopefully update syscall submodule 2020-06-27 14:10:15 +01:00
Jeremy Soller 35ca4c221e Merge branch 'proc-fexec' into 'master'
Changes required for GDB

See merge request redox-os/kernel!131
2020-06-25 13:06:45 +00:00
jD91mZM2 fed36d49e3 Bump submodule 2020-06-25 15:04:49 +02:00
jD91mZM2 4701838118 Fix RIP register on int3 2020-06-23 19:47:44 +02:00
jD91mZM2 7fc49eed74 ptrace: Allow stopping on fexec 2020-06-22 13:11:32 +02:00
Graham MacDonald aa1b11cc8a move calc_seek_offset* to syscall 2020-06-19 23:53:30 +01:00
Graham MacDonald 01f95b644d change seek sig to match posix - signed pos and result 2020-06-19 23:31:55 +01:00
jD91mZM2 e18a877995 Implement proc:<pid>/exe for getting exe name 2020-06-17 19:06:48 +02:00
Jeremy Soller fcea6e06dd Merge branch 'complex-physalloc' into 'master'
More complex physalloc

See merge request redox-os/kernel!127
2020-06-16 21:20:00 +00:00
4lDO2 003bd6a0d2 More complex physalloc 2020-06-16 21:20:00 +00:00
Jeremy Soller 654c0a7bbc Merge branch 'ptrace-sane-block' into 'master'
Ptrace sane block

See merge request redox-os/kernel!129
2020-06-16 12:10:47 +00:00
Jeremy Soller 484f4c13fe Merge branch 'moar-ptrace' into 'master'
Misc ptrace cleanup

See merge request redox-os/kernel!128
2020-06-16 12:09:26 +00:00
jD91mZM2 edcc39929d Fix unused import
I added that assert, because I managed to get an error I couldn't reproduce
2020-06-16 13:58:36 +02:00
jD91mZM2 9c891384ea Fix ptrace returning ENODEV when process exists 2020-06-16 13:42:04 +02:00
jD91mZM2 cbb17327aa ptrace: Block on read, not on write 2020-06-16 13:00:27 +02:00
jD91mZM2 12f632837a Misc proc code cleanup 2020-06-16 10:08:49 +02:00
jD91mZM2 4effb97c04 fixup! Fix acid test-bench issues 2020-06-16 09:28:42 +02:00
jD91mZM2 727217ad42 Fix acid test-bench issues 2020-06-15 17:14:52 +02:00
jD91mZM2 3420339c04 proc scheme: Rewrite try_stop_context 2020-06-15 15:08:59 +02:00
jD91mZM2 75872cc5f8 ptrace: Fix WaitCondition mutex 2020-06-13 16:05:57 +02:00
4lDO2 1c0e6c253f Fix test. 2020-06-11 16:11:46 +02:00
4lDO2 8117119d8e Wrap borrows of page table entries in unsafe.
This is safe because `Entry` is `#[repr(8)]` which is the minimum
alignment for qwords. Since the size of a qword is equal to that
alignment (8), they can also be borrowed from the array.
2020-06-11 16:05:00 +02:00
Jeremy Soller 5d53c65f0b Merge branch 'resolve-kernel-warnings' into 'master'
Fix various kernel warnings.

See merge request redox-os/kernel!125
2020-06-11 13:18:58 +00:00
Jeremy Soller b90233bc30 Merge branch 'paging-repr-packed' into 'master'
Use #[repr(packed)] with correct alignment for paging.

See merge request redox-os/kernel!124
2020-06-11 13:17:51 +00:00
4lDO2 e7d00d4735 Fix various kernel warnings. 2020-06-11 12:58:03 +02:00
4lDO2 c7b207f4dc Use #[repr(packed)] with correct align for paging. 2020-06-11 11:58:58 +02:00
Jeremy Soller 93e0db1aa3 Merge branch 'noacpi-fix' into 'master'
Fix conditional compilation without the acpi feature.

See merge request redox-os/kernel!122
2020-05-22 11:38:16 +00:00
4lDO2 3289b95a7a Fix conditional compilation without acpi feature. 2020-05-22 10:21:22 +02:00
Jeremy Soller 30b109d288 Update dependencies 2020-05-06 09:05:58 -06:00
Jeremy Soller 4245dff4d8 Merge branch 'separate-idt' of gitlab.redox-os.org:4lDO2/kernel 2020-05-06 08:58:10 -06:00
4lDO2 0585c2b4d9 Make the IDTs of APs visible to irq:. 2020-05-03 16:57:32 +02:00
4lDO2 9232736bf1 Rename some things, and fix a map insertion. 2020-05-03 16:57:32 +02:00
4lDO2 f4246deabf WIP: Use a different IDT for each processor. 2020-05-03 16:57:32 +02:00
4lDO2 0d1ca687fb Use the correct interrupt method for spurious IRQs. 2020-05-03 16:57:03 +02:00
4lDO2 1165445602 Add spurious IRQ handling, using a visible counter. 2020-05-03 16:56:50 +02:00
Jeremy Soller dd4e82f4ce Merge branch 'cpuid' into 'master'
bump raw-cpuid dep to avoid pulling in serde

See merge request redox-os/kernel!121
2020-05-02 17:41:05 +00:00
Graham MacDonald 0614d3298d bump raw-cpuid dep to avoid pulling in serde 2020-05-02 14:11:23 +01:00
Jeremy Soller 582e3fd8eb Unlock CONTEXT_SWITCH_LOCK after loading registers but before switch 2020-04-21 21:03:17 -06:00
Jeremy Soller c79f308f07 Unlock CONTEXT_SWITCH_LOCK after switch happens 2020-04-21 20:45:15 -06:00
Jeremy Soller 0bfd830f3c Work around spurious nanosleep wakes 2020-04-20 21:08:56 -06:00
Jeremy Soller dd0633a3d2 Kernel reading of ps2 bytes 2020-04-20 13:10:06 -06:00
Jeremy Soller 2fa85ed303 Remove unused import 2020-04-19 21:47:58 -06:00
Jeremy Soller fa58651b70 Add serio scheme, based on debug scheme, for supporting ps2 devices 2020-04-19 21:40:12 -06:00
Jeremy Soller 5fd8f0430b Cleanup debug scheme 2020-04-19 21:39:53 -06:00
Jeremy Soller 02abd58c10 Merge branch 'multi_core' into 'master'
Multi core

See merge request redox-os/kernel!118
2020-04-19 20:28:15 +00:00
Jeremy Soller e528aa8fdc Fix order of masking IRQ and eoi 2020-04-19 10:50:03 -06:00
Jeremy Soller abf971eaee Only require alignment of 4 bytes for rsdp 2020-04-19 08:49:42 -06:00
Jeremy Soller 315343be41 Add a way to snapshot context state 2020-04-19 08:46:50 -06:00
Jeremy Soller 123918ed43 Track the namespace that a description was opened from 2020-04-19 08:46:50 -06:00
Jeremy Soller 051a275c94 Remove unused import 2020-04-19 08:46:50 -06:00
Jeremy Soller 3c86af57b7 Allow contexts sharing process space to run on different CPUs 2020-04-19 08:46:50 -06:00
Jeremy Soller fdf46d8043 Fix multi_core livelocks and add livelock debugging 2020-04-19 08:46:50 -06:00
Jeremy Soller 9d67e3dc28 Merge branch 'ioapic' into 'master'
Support the I/O APIC alongside the 8259 PIC

See merge request redox-os/kernel!117
2020-04-19 13:02:42 +00:00
4lDO2 9413475119 Don't use the I/O APIC by default,
since this would require pcid to know the _PRT (PCI routing table) to
use and map the interrupt pins to the correct IRQs. xhcid is unaffected
by this though, since it uses MSI-X.

All ACPI handling will be done in userspace before the infrastructure
necessary would make sense (I don't think adding serde to the kernel
would be optimal, and how else would all of the ACPI namespace be
parsed?).
2020-04-19 13:25:43 +02:00
4lDO2 00312bdf32 Revert to old default-features. 2020-04-19 13:21:59 +02:00
4lDO2 3bc4b9a691 Allow the MADT to be read from userspace,
and fix a typo that prevented multiple tables from being listed
correctly.
2020-04-19 09:41:42 +02:00
4lDO2 02ca8edfc5 Execute AML code after IOAPIC init,
which tells the firmware that the I/O APIC is used rather than the 8259
PIC.
2020-04-19 09:41:40 +02:00
4lDO2 8c351e0768 Use the I/O APIC when applicable. 2020-04-19 09:41:09 +02:00
4lDO2 45fe040625 rustfmt. 2020-04-19 09:39:57 +02:00
4lDO2 d1ece2c811 Add a basic acpi: scheme, currently only for MCFG. 2020-04-19 09:39:57 +02:00
4lDO2 dc3452650c Execute AML code after IOAPIC init,
which tells the firmware that the I/O APIC is used rather than the 8259
PIC.
2020-04-18 23:17:37 +02:00
4lDO2 290098b5a4 impl Debug for AmlValue. 2020-04-18 18:21:04 +02:00
4lDO2 5490de9fd2 Fix a page fault. 2020-04-18 17:33:03 +02:00
4lDO2 de4b66150d Remove unnecessary kernel args. 2020-04-18 17:06:45 +02:00
4lDO2 f0b5d51793 Use the I/O APIC when applicable. 2020-04-18 16:36:18 +02:00
4lDO2 da6de394e4 Add a new backwards-compatible v2 boot protocol. 2020-04-18 11:28:11 +02:00
Jeremy Soller 5d4aa75133 Merge branch 'schemes-no-arc-box' into 'master'
Replace Arc<Box<dyn Scheme>> with Arc<dyn Scheme>.

See merge request redox-os/kernel!116
2020-04-11 12:09:20 +00:00
4lDO2 0e2e515dbd Replace Arc<Box<dyn Scheme>> with Arc<dyn Scheme>. 2020-04-11 12:29:35 +02:00
Jeremy Soller 0ccf3b4e53 Merge branch 'lapic' into 'master'
Extend the IRQ scheme to allow allocation of all available interrupt vectors.

See merge request redox-os/kernel!115
2020-04-04 12:54:44 +00:00
4lDO2 0fd24f6061 Cleanup. 2020-04-04 10:57:00 +02:00
4lDO2 b716ec4bc1 Remove currently unused APIC timer code. 2020-03-28 13:37:03 +01:00
4lDO2 d23ed0cfc3 Remove debug local APIC functions. 2020-03-28 13:37:03 +01:00
4lDO2 157a3e5c0d Improve MSI. 2020-03-28 13:37:03 +01:00
4lDO2 772003138d Add a backwards-compatible interface for more IRQs. 2020-03-28 13:37:03 +01:00
4lDO2 c154effd1c Get a working local apic timer. 2020-03-28 13:37:03 +01:00
4lDO2 c11d6d9e46 Update the x86 crate. 2020-03-28 13:37:03 +01:00
4lDO2 65e8abb449 Allow multiple processes to share IRQs.
I haven't been able to receive xhc interrupt anyway.
2020-03-28 13:37:03 +01:00
Jeremy Soller 53570f0164 Merge branch 'fix-warnings' into 'master'
Fix warnings

See merge request redox-os/kernel!114
2020-03-06 20:46:01 +00:00
Skallwar ae14eda866 Run rustfmt 2020-03-06 21:05:26 +01:00
Skallwar b82f596ef6 Fix unnecessary syntax 2020-03-06 21:02:20 +01:00
Skallwar 7671e92216 Fix borrow of packed field 2020-03-06 21:01:18 +01:00
Jeremy Soller b616fdb067 Keep track of ticks each context uses 2020-02-18 21:16:53 -07:00
Jeremy Soller d4d14c78c3 Ensure page table locking at runtime 2020-02-12 20:34:49 -07:00
Jeremy Soller b892603501 Require mutable context to perform page table modifications 2020-02-10 17:58:44 -07:00
Jeremy Soller 7721a0a4c6 Fix assignment of cpu_id 2020-02-09 11:05:02 -07:00
Jeremy Soller d42c1ba14e Remove unused feature 2020-02-09 09:50:48 -07:00
Jeremy Soller 388ab2c87d option -> opt 2020-02-09 09:50:40 -07:00
Jeremy Soller aec92c1617 Make PIT_TICKS thread_local 2020-02-09 09:49:49 -07:00
Jeremy Soller c860322cfc Merge branch 'master' of https://gitlab.redox-os.org/redox-os/kernel 2020-02-07 20:06:39 -07:00
Jeremy Soller 7658193271 Remove some warnings 2020-02-07 20:06:33 -07:00
Jeremy Soller 8eaa809b29 Merge branch 'master' into 'master'
Update README's debugging instructions

See merge request redox-os/kernel!113
2020-01-26 01:12:22 +00:00
Joshua Abraham 4a4d8601d1 Update README's debugging instructions 2020-01-25 20:03:57 -05:00
Jeremy Soller 64f962e02b Merge branch 'master' into 'master'
Fix deadlock in sys: scheme

See merge request redox-os/kernel!112
2020-01-25 23:07:24 +00:00
Joshua Abraham 6a48ae3d8b Fix deadlock in sys: scheme
This patch fixes a deadlock in the sys: scheme that is triggered
when the iostat resource() is called in the same scope where the RwLock
protecting the scheme's handles is write-locked.
2020-01-25 17:39:51 -05:00
Jeremy Soller 57a6359333 Do not add newline to sys:exe 2019-12-22 18:23:36 -07:00
Jeremy Soller 72ea559da4 Do not log mprotects 2019-12-06 19:59:18 -07:00
Jeremy Soller e13107b441 Remove warning 2019-11-13 19:41:34 -07:00
Jeremy Soller f7f4013cf0 Do not use COM3 or COM4 2019-11-13 19:39:45 -07:00
Jeremy Soller 90b113f047 Add lpss_debug 2019-11-13 19:33:21 -07:00
Jeremy Soller 331590e129 Support COM3 and COM4 2019-11-01 20:35:02 -06:00
Jeremy Soller c27a6c149b Support SerialPort<Mmio<u32>> 2019-11-01 20:34:03 -06:00
Jeremy Soller 752138de1d Merge branch 'nanosleep' into 'master'
implement remainder for nanosleep

See merge request redox-os/kernel!110
2019-10-08 19:01:15 +00:00
Timothy DeHerrera f75e1c4802 implement remaninder for nanosleep 2019-10-08 11:54:02 -06:00
Jeremy Soller af93866c41 Add more clippy lints 2019-10-06 11:15:01 -06:00
Jeremy Soller 63e2a835e0 Fix clippy.sh script and fix a number of clippy warnings 2019-10-06 11:04:06 -06:00
Jeremy Soller a57ea6a72b Merge branch 'ptrace-end' into 'master'
Final few ptrace changes

See merge request redox-os/kernel!109
2019-08-21 21:00:13 +00:00
jD91mZM2 ab1a12ad4a Remove deadlock-prone mutex in proc.rs
I believe this could cause a deadlock if a blocking I/O operation was
interrupted by a signal or otherwise, and decided to exit and close
all files. It's unlikely to happen, but it can happen nontheless. This
removes the mutex, but it's difficult to keep the code tidy. Hopefully
this is good enough.
2019-08-15 16:07:38 +02:00
jD91mZM2 cf0a7620df Add ptrace exit breakpoint
This will let you stop at process exit and inspect it right before the
process dies.
2019-08-15 14:23:54 +02:00
jD91mZM2 070f1fa913 Delete ptrace-related TODO 2019-08-15 12:26:29 +02:00
jD91mZM2 2544feb33f Disallow changing CS which contains CPL 2019-08-15 12:26:29 +02:00
Jeremy Soller 6160de495f Make multi_core require acpi 2019-08-12 19:33:50 -06:00
Jeremy Soller 3694395dfb Fix compilation of acpi feature 2019-08-12 19:33:03 -06:00
Jeremy Soller 8c6e1d0541 Update syscall 2019-07-31 18:30:57 -06:00
Jeremy Soller d28b578681 Merge branch 'ptrace-6' into 'master'
Ptrace overhaul & bitflags

See merge request redox-os/kernel!107
2019-07-31 20:29:54 +00:00
jD91mZM2 40449d32b5 Allow catching int3 2019-07-31 16:43:49 +02:00
jD91mZM2 ad5f3814fa Add way to ignore signals 2019-07-30 15:54:25 +02:00
jD91mZM2 62cd298202 Merge ProtFlags with MapFlags 2019-07-30 11:45:54 +02:00
jD91mZM2 a7b2bd22c1 More cleanup... 2019-07-27 15:39:09 +02:00
jD91mZM2 538ca49ee2 Suggestion: Switch to bitflags 2019-07-26 12:23:21 +02:00
jD91mZM2 0e2b0d0fd4 Fix a few details 2019-07-26 10:29:31 +02:00
jD91mZM2 3ac1416dba First step for ptrace overhaul 2019-07-24 21:42:33 +02:00
Jeremy Soller e95cb74d0b Resolve cross-scheme links 2019-07-23 21:06:16 -06:00
Jeremy Soller e570f35279 Update syscall 2019-07-23 20:04:43 -06:00
Jeremy Soller 3533cb3757 Merge branch 'ptrace-5' into 'master'
Drive ptrace into a wall, prepare for overhaul

See merge request redox-os/kernel!106
2019-07-24 02:04:06 +00:00
jD91mZM2 1137692809 WIP(ptrace): Allow setting RIP 2019-07-23 19:55:11 +02:00
jD91mZM2 a7da393cf5 WIP(ptrace): Better support for signals
Signals now cause an event, and there's a way to continue until the
next signal. I can see this being used for detection of `int3`
although I'm not entirely sure as it may prove being too late to stop
abortion of process.
2019-07-21 19:58:32 +02:00
jD91mZM2 7426e48105 WIP(ptrace): Extract repeated arch-specific code to ptrace module 2019-07-21 13:28:31 +02:00
jD91mZM2 4c2d8599d8 Add missing debug definitions
See [strace-redox#ea42589d](https://gitlab.redox-os.org/redox-os/strace-redox/commit/ea42589d36923e9c018a4d802a5cd0c3449d0e6c)
2019-07-21 10:06:28 +02:00
jD91mZM2 6a3825d408 WIP(ptrace): Only use non-signal stack when using a default handler
This is a curious problem and it's really hard to solve it in a way
that doesn't feel hacky. On one hand, of course you want to be able to
modify and intercept what happens when you use a signal, right? On the
other hand, changes made to the context (especially singlestepping)
while a signal is handled (such as `SIGSTOP`) are not preserved since
the stack is restored after the signal handler was invoked.

I think what we have in this change makes sense anyway, as we don't
really want users modifying registers and other data in the default
signal behavior that occurs **in kernel mode**. Also trying to use
`PTRACE_SINGLESTEP` will set the singlestep flag only if in a
user-mode signal handler, else it will set it on the instruction after
the signal handling, which I guess makes sense since it can't affect
the kernel-mode code that runs the default handler.

I don't know. Help. Pls.
2019-07-20 22:45:33 +02:00
jD91mZM2 8695ecd82b Fix sigaction Undefind Behavior
Rust does not allow a `fn`-pointer to be null. This fixes that, while
luckily doing it in a way that leaves system calls
backwards-compatible :)
2019-07-20 22:41:54 +02:00
jD91mZM2 be867ae5f1 WIP(ptrace): Add ptrace event system for catching child forks 2019-07-20 09:45:07 +02:00
jD91mZM2 3d44242407 WIP(ptrace): Finally add stronger security checks 2019-07-20 09:45:07 +02:00
jD91mZM2 e3d8f23c71 WIP(ptrace): Add dbg! macro and fix waitpid immediately after exit 2019-07-20 09:45:01 +02:00
Jeremy Soller 532ffe25cf Unmounting support 2019-07-18 21:00:36 -06:00
Jeremy Soller 113af69434 Remove scheme if closed 2019-07-18 20:58:06 -06:00
Jeremy Soller 4b2c15f0b9 Remove scheme by ID 2019-07-18 20:57:51 -06:00
Jeremy Soller 5af7f71a99 Fix warning 2019-07-18 20:57:41 -06:00
Jeremy Soller 5a42b6dd76 Add notify_signal method to WaitCondition to simulate being woken by a signal 2019-07-18 19:48:54 -06:00
Jeremy Soller 76e0ed2e37 Make all wait_map members public 2019-07-18 19:48:27 -06:00
Jeremy Soller bfc559a8a7 Merge branch 'master' of https://gitlab.redox-os.org/redox-os/kernel 2019-07-14 11:17:52 -06:00
Jeremy Soller 6e8729bac2 Disable RTC NMI and do not wait for an entire update cycle before reading time 2019-07-14 11:17:45 -06:00
Jeremy Soller cbc892d1d5 Merge branch 'ptrace-3' into 'master'
Ptrace memory reading and floating point registers support

See merge request redox-os/kernel!104
2019-07-07 17:07:05 +00:00
jD91mZM2 6fbb4fbae1 Ptrace memory reading and floating point registers support 2019-07-07 17:07:04 +00:00
Jeremy Soller 788526a3b3 Bare-bones ptracing functionality
Since even a very basic ptrace can be nice to have, I thought I would split
the, perhaps rather big, ptrace project up in multiple PRs to make as few
changes as necessary in each. This PR contains the initial registry modifying
bits and only a very basic security measure. Letting this out to the community
should be good for spotting bugs and maybe getting some hype ;)
2019-07-02 07:38:26 -06:00
Jeremy Soller 45ea634798 Revert "Merge branch 'ptrace' into 'master'"
This reverts merge request !103
2019-07-02 11:56:11 +00:00
Jeremy Soller 527353d377 Merge branch 'ptrace' into 'master'
Bare-bones ptracing functionality

See merge request redox-os/kernel!103
2019-07-01 22:50:19 +00:00
jD91mZM2 effe02bd45 Remove change I am faaairly certain I did NOT add :O
I'm guessing it's some issue after a rebase or something...
2019-07-01 22:50:19 +00:00
Jeremy Soller 42f977e7da Disable debug messages 2019-06-27 16:29:28 -06:00
Jeremy Soller 144ac70b12 Allow access to other thread's TLS with pointers 2019-06-23 20:21:22 -06:00
Jeremy Soller 78e79fc4d6 Merge branch '2018' into 'master'
Switch to 2018 edition

See merge request redox-os/kernel!102
2019-06-21 12:19:38 +00:00
jD91mZM2 fe705d9b63 Switch to 2018 edition
Most of this was generated by the absolutely extraordinary `cargo fix`
subcommand. There were still 2 errors and a few warnings to patch up,
but compared to the normal 600+ errors, I'd say the fixer did a damn
good job! I'm also amazed that I could still start the VM after this,
I half expected some kinds of runtime failure...
2019-06-21 12:12:01 +02:00
Jeremy Soller 1be77c2ab4 Store sigmask 2019-06-02 18:45:06 -06:00
Jeremy Soller fcd8ce7e1b Fix event logic for pipes 2019-04-28 13:32:24 -06:00
Jeremy Soller afa3f38310 Allow seek in root scheme directory listings 2019-04-27 08:13:20 -06:00
Jeremy Soller afab96fa06 Do not allow unreachable patterns (often a logic issue) 2019-04-27 08:10:49 -06:00
Jeremy Soller eecc9a442c Fix missing name override option when calling fexec_kernel 2019-04-15 21:01:19 -06:00
Jeremy Soller 126009f83c Keep process name when using interpreter 2019-04-15 21:00:42 -06:00
Jeremy Soller b66fef0479 Copy TCB if it was not initialized using kernel-allocated TLS 2019-04-15 20:47:27 -06:00
Jeremy Soller 6da3ab283e Clone grants 2019-04-15 20:47:03 -06:00
Jeremy Soller dc198cef6e Keep track of leaked grants and allow for cloning of grants 2019-04-15 20:42:41 -06:00
Jeremy Soller d432f7ce8c Add debugging for mprotect 2019-04-14 21:32:31 -06:00
Jeremy Soller 3a0671d20f Fix dropping grants without unmapping if they have no file descriptor (such as those from anonymous maps) 2019-04-14 19:23:23 -06:00
Jeremy Soller 339d68ac8d Remove debugging messages 2019-04-14 19:12:13 -06:00
Jeremy Soller 434e799f2a Place TCB at thread-specific location to avoid overlapping TCBs 2019-04-14 19:05:25 -06:00
Jeremy Soller 21e46b6a55 More cleanup of TLS mapping 2019-04-14 14:50:29 -06:00
Jeremy Soller 9762431a33 Cleanup TLS mapping 2019-04-13 22:00:27 -06:00
Jeremy Soller 8120131897 Add interpreter capability 2019-04-13 21:59:46 -06:00
Jeremy Soller dc28023be1 Remove unnecessary clone 2019-04-13 21:58:34 -06:00
Jeremy Soller 28cd51efed Update goblin 2019-04-13 21:57:58 -06:00
Jeremy Soller 58f9e5a801 0.1.54 - Add support for cache disable 2019-04-08 17:57:25 -06:00
Jeremy Soller f042bd5d07 Update for new rust 2019-04-07 10:57:33 -06:00
Jeremy Soller ff2ad4322a Update syscall 2019-04-07 10:51:51 -06:00
Jeremy Soller f36506613b Update funmap support 2019-04-06 20:13:55 -06:00
Jeremy Soller 4329aa4366 Update syscall 2019-04-06 18:58:34 -06:00
Jeremy Soller c8104a70b9 Merge branch 'prevent-race-condition' into 'master'
Lock resources before checking if we need to clean them.

See merge request redox-os/kernel!101
2019-04-01 15:38:00 +00:00
Noam Kleinburd 129d4e3ae5 Lock resources before checking if we need to clean them.
See the comments deleted by this commit for more details as to how
the race condition could effect the system.
2019-04-01 17:01:29 +03:00
Jeremy Soller e5cf6efa64 Support specification of stack with clone system call and CLONE_STACK flag 2019-03-31 14:35:45 -06:00
Jeremy Soller 9ccaed7103 Remove bochs breakpoint in kernel 2019-03-31 08:36:55 -06:00
Jeremy Soller ec66bf2ed1 Rerun build script if INITFS_FOLDER changes 2019-03-24 11:35:54 -06:00
Jeremy Soller d2095d8d0f Add in-memory logging, retrievable from sys:log 2019-03-17 09:31:34 -06:00
Jeremy Soller f7c9712977 Fix warning in irq scheme 2019-03-17 09:31:03 -06:00
Jeremy Soller e2a6233c12 New fevent functionality to prevent missing events 2019-03-13 13:57:07 -06:00
Jeremy Soller 483ee05ebc Fix unused import 2019-03-12 20:48:28 -06:00
Jeremy Soller a0e9f4a8a0 Use serial for debugging by default 2019-03-11 19:54:54 -06:00
Jeremy Soller b80f38b039 More debugging output options 2019-03-11 19:50:50 -06:00
Jeremy Soller 445b8ad96d Merge branch 'rustc-demangle' into 'master'
Use rustc-demangle in the stack traces

See merge request redox-os/kernel!100
2019-02-22 02:35:13 +00:00
Tibor Nagy 2ec775905a Use rustc-demangle in the stack traces 2019-02-14 15:54:17 +01:00
Jeremy Soller 6042cdb0a2 Remove unused import 2019-02-02 14:04:53 -07:00
Jeremy Soller b4575711c7 Fix logic error when cloning file descriptor in user scheme fmap 2019-02-02 08:11:07 -07:00
Jeremy Soller ca511b98f3 Add code to shut down QEMU with it's default ACPI settings, run cli hlt in loop 2019-02-01 20:12:06 -07:00
Jeremy Soller 504e93d11b Store file descriptor for mapped files until they are unmapped 2019-01-28 19:27:20 -07:00
Jeremy Soller 78d07d41cb FileDescriptor is now must_use 2019-01-28 19:26:50 -07:00
Jeremy Soller 613e5b45f7 Update dependencies 2019-01-20 19:47:50 -07:00
Jeremy Soller f6e2d44383 Add syscall setup to kstart_ap 2019-01-20 19:41:18 -07:00
Jeremy Soller 5c31c0991c 0.1.51 2019-01-20 19:37:55 -07:00
Jeremy Soller 36820c0346 Add somewhat magical code for syscall instruction 2019-01-20 19:35:52 -07:00
Jeremy Soller 931a7bb251 WIP: Support for syscall instruction 2019-01-20 15:49:18 -07:00
Jeremy Soller 30f1265c36 Add pages to use for head and tail of buffers in userscheme 2019-01-01 12:37:23 -07:00
Jeremy Soller 257e4a6eb5 WIP: improve speed of Grant::map_inactive
Use recursive page table address to calculate p4 entry
2019-01-01 12:28:45 -07:00
Jeremy Soller 8fcbf152eb Add mprotect 2018-12-31 21:04:21 -07:00
Jeremy Soller b18e322c3f WIP: itimer and sigprocmask 2018-12-28 21:53:40 -07:00
Jeremy Soller 0df93423a2 Add no_execute to heap now that mmap prot_exec is working 2018-12-28 19:57:51 -07:00
Jeremy Soller a31af81f8b Update fmap support 2018-12-28 15:35:21 -07:00
Jeremy Soller ef919f3d52 Implement EINTR for anything using wait_queue 2018-12-22 08:02:00 -07:00
Jeremy Soller 46a6325678 Update lock file 2018-12-14 20:08:21 -07:00
Jeremy Soller 69cbb548fb Mark heap executable for mesa (temporary) 2018-12-11 21:03:57 -07:00
Jeremy Soller 876e01e539 Update syscall 2018-12-11 21:03:40 -07:00
Jeremy Soller ecc0e747fc Prevent adding empty variables to environment 2018-12-02 19:25:28 -07:00
Jeremy Soller e356262f03 Correct init path 2018-12-02 19:14:13 -07:00
Jeremy Soller 69e3fe105d Update debugging to ignore clock_gettime 2018-12-02 16:31:24 -07:00
Jeremy Soller fe74ecee95 Update lock file 2018-12-01 09:28:14 -07:00
Jeremy Soller f443126dff Update syscall 2018-11-26 11:45:39 -07:00
Jeremy Soller 9af4d6a2e0 Fix compilation of graphical_debug feature and remove live feature warnings. 2018-11-21 19:38:14 -07:00
Jeremy Soller ee5c43ed45 Add umask to debug 2018-11-16 21:22:38 -07:00
Jeremy Soller 7e2a7d0cea Update lock file 2018-11-16 20:08:08 -07:00
Jeremy Soller efff2cb797 Update syscall to 0.1.42 2018-11-16 19:48:50 -07:00
Jeremy Soller 14c15d3bbb Update syscall 2018-11-16 19:45:13 -07:00
Jeremy Soller 4c38107055 Add umask 2018-11-16 19:43:37 -07:00
Jeremy Soller 885fe7d0ae update syscall 2018-11-12 20:55:49 -07:00
Jeremy Soller 5b31bf57be Update to latest rust 2018-11-08 17:25:57 -07:00
Jeremy Soller 120b4733ff Update for new rust 2018-11-08 17:11:06 -07:00
Jeremy Soller 1b091d3c9f Set name of process using full path of executable 2018-10-26 10:31:47 -06:00
Jeremy Soller 15313f98af Remove unnecessary dup implementations 2018-10-20 08:08:31 -06:00
Jeremy Soller 9570de21d1 Merge remote-tracking branch 'origin/relibc' 2018-10-14 16:43:54 -06:00
Jeremy Soller 3b1bf1bac1 Call TLB IPI when mapping grants 2018-09-25 20:58:24 -06:00
Jeremy Soller b08fa10277 Implement tlb IPI 2018-09-25 20:57:59 -06:00
Jeremy Soller f5fcbc12b8 Move ipi for pit to after EOI 2018-09-25 18:05:10 -06:00
Jeremy Soller e867326df1 Attempt to schedule other processors more often by waking them up with a context switch when a process is created 2018-09-25 18:01:38 -06:00
Jeremy Soller 0d510a4f74 Remove multi-core and acpi again 2018-09-23 11:44:34 -06:00
Jeremy Soller 7a97867868 Make multi-core support the default
Make IPIs less architecture specific
2018-09-23 10:40:55 -06:00
Jeremy Soller 22aa5f48d7 Merge branch 'master' into 'master'
Implement fmap for memory:

See merge request redox-os/kernel!93
2018-09-22 15:51:18 +00:00
Jeremy Soller a2ce83f60a Merge branch 'trace' into 'master'
trace: Break on RBP OVERFLOW

See merge request redox-os/kernel!96
2018-08-17 12:10:20 +00:00
Jeremy Soller 2ba21b33ad Merge branch 'relibc' into 'relibc'
Push null after argv

See merge request redox-os/kernel!97
2018-08-13 11:47:24 +00:00
jD91mZM2 1d817fa41d Push null after argv 2018-08-13 12:14:29 +02:00
Jeremy Soller 1718d28d39 Push null pointer to indicate end of environment 2018-08-12 08:30:12 -06:00
Jeremy Soller 69766ce3b9 Update syscall 2018-08-11 16:47:48 -06:00
Jeremy Soller 23f4c76ebb Fixes for launching init 2018-08-11 11:51:58 -06:00
Jeremy Soller 30e68f917e Remove env scheme and env field on context, fix all warnings 2018-08-11 11:34:32 -06:00
Jeremy Soller fe90664e33 Copy variables to USER_ARG_OFFSET 2018-08-11 11:18:45 -06:00
Jeremy Soller c7b3765d6f Remove execve, replace with fexec 2018-08-11 11:14:32 -06:00
Jeremy Soller a198cb22f5 Merge remote-tracking branch 'origin/master' into relibc 2018-08-11 09:03:35 -06:00
Ian Douglas Scott 8455d2bad4 trace: Break on RBP OVERFLOW
There's not point in continuing the loop once this occurs. It just
results in printing 'RBP OVERFLOW' repeatedly.
2018-08-08 12:35:04 -07:00
Jeremy Soller 875d89cef8 Merge branch 'master' into 'master'
Add more documentation to the redox kernel

See merge request redox-os/kernel!95
2018-07-30 12:28:11 +00:00
17liamnaddell 2de83eb932 fix small documentation bug 2018-07-21 21:46:11 -04:00
17liamnaddell 2c2a96a935 futex and slight changes 2018-07-21 21:41:47 -04:00
17liamnaddell c06f403dd2 second round of documentation 2018-07-21 20:48:33 -04:00
17liamnaddell 9d1fb3013d First round of documentation changes 2018-07-18 22:48:08 -04:00
jD91mZM2 55f2303d2c Implement fmap for memory: 2018-07-05 14:17:58 +02:00
Jeremy Soller b86672b81e Support for relibc 2018-07-03 19:42:23 -06:00
Jeremy Soller 054fc41beb Merge commit 'c28c147' 2018-06-19 18:18:36 -06:00
Jeremy Soller c28c147add Update to new dependencies 2018-06-19 18:17:16 -06:00
Jeremy Soller 9a7f04723b Merge branch 'fix-linked-list-allocator' into 'master'
Use older linked_list_allocator version

See merge request redox-os/kernel!92
2018-06-15 18:52:06 +00:00
Deepak Sirone 231cab75fe Use older linked_list_allocator verison 2018-06-15 23:46:07 +05:30
Jeremy Soller 3f08676e21 Merge branch 'fix-graphical-debug' into 'master'
Fix compilation error for graphical_debug

See merge request redox-os/kernel!91
2018-06-15 16:54:24 +00:00
Deepak Sirone ccbd858043 Fix compilation error for graphical_debug 2018-06-15 22:08:02 +05:30
Jeremy Soller 145785e206 Update links to gitlab 2018-06-12 12:30:44 -06:00
Jeremy Soller fc0db71dd4 Update syscall 2018-05-30 09:43:22 -06:00
Jeremy Soller 897b583360 Update lock file 2018-05-30 09:19:19 -06:00
Jeremy Soller 41bdb31645 Update syscall 2018-05-30 09:19:06 -06:00
Jeremy Soller 92ebd4d16a Merge branch 'master' of https://github.com/redox-os/kernel 2018-05-24 08:31:59 -06:00
Jeremy Soller 764f28ada5 Update cargo.lock 2018-05-24 08:31:52 -06:00
Jeremy Soller 3f2bd559bf Merge pull request #90 from jabedude/master
Fix TODO: Use triple fault to guarantee reboot
2018-05-22 06:33:20 -06:00
Josh Abraham aff0c339b4 Fix TODO: Use triple fault to guarantee reboot
Cause interrupt, since the IDT is dorked we can't find the INT 3
handler (double fault), and the double fault handler can't be
found (triple fault).
2018-05-21 17:14:58 -10:00
Jeremy Soller 5cfe3f822b Update syscall 2018-05-20 16:26:45 -06:00
Jeremy Soller 94c6550580 Reduce messages from fevent warning 2018-05-20 16:25:11 -06:00
Jeremy Soller 7d0f9a7ce8 Require correct event id return 2018-05-20 13:18:51 -06:00
Jeremy Soller 43a163d8d6 Debug scheme will return correct event id 2018-05-20 12:56:37 -06:00
Jeremy Soller 4ec46ee786 Send new flags to scheme 2018-05-20 12:48:22 -06:00
Jeremy Soller cb94d334ac Fix issue with debug fevent 2018-05-20 12:33:54 -06:00
Jeremy Soller 99a3bff2da WIP: New event system 2018-05-20 11:08:37 -06:00
Jeremy Soller 63351f4ca6 Fix documentation in pipe scheme 2018-05-20 07:18:13 -06:00
Jeremy Soller e01d397dc1 Return ECHILD if child process does not exist before blocking on it 2018-05-14 20:34:47 -06:00
Jeremy Soller d0b78cd8ff Remove stop print 2018-05-14 20:03:48 -06:00
Jeremy Soller be1e87922c Set rust_oom no_mangle 2018-04-28 22:08:23 -06:00
Jeremy Soller 48007b8f1e Update to new allocation API (WIP) 2018-04-28 22:07:43 -06:00
Jeremy Soller 36989e21f2 Merge branch 'master' of https://github.com/redox-os/kernel 2018-04-28 21:45:23 -06:00
Jeremy Soller c5752242d0 Update linked_list_allocator 2018-04-28 21:45:19 -06:00
Jeremy Soller a64522e580 Merge pull request #88 from raw-bin/aarch64
Add a toolchain target spec for AArch64
2018-04-16 06:39:10 -06:00
Robin Randhawa 19d4868e6c Add a toolchain target spec for AArch64 2018-04-16 15:36:59 +05:30
Jeremy Soller 9dc42102bf Merge pull request #87 from raw-bin/aarch64-redox-port-outline-doc
Add an outline document for a port of the Redox kernel to the Arm AAr…
2018-04-15 17:57:10 -06:00
Robin Randhawa 9a0f8391a6 Update status: Toolchain spec done
Also fix a typo with the device_crate URL.
2018-04-16 02:53:59 +05:30
Robin Randhawa 09a7eaea4b Add an outline document for a port of the Redox kernel to the Arm AArch64 architecture. 2018-04-14 14:10:51 +05:30
Jeremy Soller 9ddda9bbfb Ensure GDT and IDT state is sane before attempting to set up paging 2018-04-11 21:06:13 -06:00
Jeremy Soller f83f61b51a Enable graphical debug 2018-03-20 20:33:49 -06:00
Jeremy Soller d9ee3e05cc Merge pull request #86 from ids1024/sig0
kill: support signal number 0
2018-03-19 10:50:41 -06:00
Ian Douglas Scott 3b09c8f858 kill: support signal number 0
Tests process existence, but does not send a signal. Matches POSIX
behavior.
2018-03-18 21:52:48 -07:00
Jeremy Soller 6dfed91ac3 Fix index check for accessfield 2018-03-11 12:58:43 -06:00
Jeremy Soller 402266e3e4 Check length on more objects 2018-03-11 12:56:48 -06:00
Jeremy Soller 74e673e68d Return errors if data is too small when parsing acpi objects 2018-03-11 12:52:30 -06:00
Jeremy Soller 734622fb9a Fix mapping code for physbaseptr 2018-03-11 12:16:51 -06:00
Jeremy Soller 9c7c010cc0 Fix graphical debug sync error, add unmapping, map with write combine 2018-03-11 12:12:54 -06:00
Jeremy Soller 819f77daf3 Add support for graphical debug, to be used during ACPI phase 2018-03-11 11:36:58 -06:00
Jeremy Soller 133c433f60 Fix warning in context::switch 2018-03-11 11:35:41 -06:00
Jeremy Soller c020ce7d8a Fix delivery of signals when a signal uses the default handler, make context status update on every switch 2018-02-24 17:47:46 -07:00
Jeremy Soller 3af2964955 Add ACPI feature 2018-02-18 16:24:34 -07:00
Jeremy Soller 797d86b7a7 Remove debug message 2018-01-29 21:36:17 -07:00
Jeremy Soller 761fe30bf3 Add linked list allocator with automatic resizing
Fix memory leaks in exec
Remove warnings
2018-01-29 21:29:24 -07:00
Jeremy Soller 015b79430e Updates for new nightly 2018-01-28 14:59:01 -07:00
Jeremy Soller 50bbdd3f5e Update lock file 2018-01-28 14:45:52 -07:00
Jeremy Soller fdaf3c2fbc Merge pull request #76 from weclaw1/master
Use slab allocator for kernel heap
2018-01-28 14:16:23 -07:00
Jeremy Soller 86ef2c4eb3 Merge pull request #83 from biotty/memword
Operate on word size as possible
2018-01-25 06:57:54 -07:00
Christian Øien c2e972f21a Operate on word size as possible 2018-01-24 22:15:30 -06:00
Jeremy Soller f3205e6e34 Fix #81 by limiting arguments to 4095
Fix #79 by limiting mappable sections to the 2GB mark
2018-01-21 20:46:53 -07:00
Jeremy Soller dcb49be481 Fix potential overflows in validate_slice and validate_slice_mut, require memory to be userspace 2018-01-21 19:21:43 -07:00
Jeremy Soller 89df5e5343 Remove debugging print 2018-01-19 20:26:41 -07:00
Jeremy Soller fee95a0406 Disable PTI by default 2018-01-19 20:07:18 -07:00
Jeremy Soller dd0376ed69 Merge branch 'pti' 2018-01-19 20:06:59 -07:00
Robert Węcławski 3e06a37215 Use slab allocator for kernel heap 2018-01-17 23:31:27 +01:00
Jeremy Soller 1e17bfdd53 Merge pull request #75 from dlrobertson/master
Update debugging docs
2018-01-10 19:49:40 -07:00
Jeremy Soller 98fb50a086 Remove comment from linker file 2018-01-10 19:27:05 -07:00
Jeremy Soller 1e533b3ad5 Use fninit in start 2018-01-10 19:26:33 -07:00
Jeremy Soller 5b389c7ffa Update PTI patch to inline PTI functions 2018-01-10 17:25:31 -07:00
Dan Robertson a16b9230a8 Update debugging docs 2018-01-10 21:31:28 +00:00
Jeremy Soller d82ffd16cb WIP: Add per-cpu interrupt stack used before mapping kernel heap 2018-01-09 22:16:14 -07:00
Jeremy Soller 192a8ce793 Add rbx to saved registers in syscall stack 2018-01-09 21:46:48 -07:00
Jeremy Soller a6550341bb Add trampolines for PTI support 2018-01-08 22:31:50 -07:00
Jeremy Soller 670d7b00d3 Add PML4 constants 2018-01-08 20:32:27 -07:00
Jeremy Soller 32028f66fe Merge pull request #74 from wartman4404/master
Write hpet timer twice
2018-01-07 19:46:08 -07:00
wartman4404 4f90a0f5c1 Write hpet timer 0 twice to set accumulator and period
This allows booting with implementations that require them to be set separately.
Also, check for the availability of legacy-replacement mode and periodic interrupts before using hpet
2018-01-07 17:06:07 -06:00
Jeremy Soller 083c444a68 Implement waitpid on PGID 2018-01-05 20:31:15 -07:00
Jeremy Soller 9313909fe9 Fix stop signal by switching context after stopping 2018-01-04 09:03:41 -07:00
Jeremy Soller 49d5c33928 Add support for WCONTINUED and WUNTRACED
Fix issues with SIGCONT
2018-01-03 22:34:50 -07:00
Jeremy Soller b6878760c7 Use seperate stopped status 2018-01-03 21:33:56 -07:00
Jeremy Soller c912f42800 Fix TLS when forking, fix signal delivery to self 2018-01-03 21:33:24 -07:00
Jeremy Soller 7906f6891e Add support for stop/cont signals 2018-01-02 22:05:29 -07:00
Jeremy Soller 22aca69ac9 Use TLS alignment to fix https://github.com/redox-os/redox/issues/1124 2017-12-29 14:58:04 -07:00
Jeremy Soller caa607eb28 Merge pull request #70 from redox-os/clippy
Add clippy lints, action some clippy items
2017-12-27 21:32:23 -07:00
Jeremy Soller 059cc8078d Add frename 2017-12-27 20:19:37 -07:00
Jeremy Soller 58e1d92eb5 Add clippy lints, action some clippy items 2017-12-24 22:19:00 -07:00
Jeremy Soller e08f56a2de Merge pull request #69 from NilSet/check_namespace
Check if current namespace exists
2017-12-24 07:28:35 -07:00
Tommie Levy 04e1034088 Check if current namespace exists 2017-12-24 02:36:11 -05:00
Jeremy Soller 7bfe1739fd Merge pull request #67 from Arcterus/master
Move null and zero from kernel space to user space
2017-12-18 16:25:11 -07:00
Alex Lyon 66a5379ff6 Move null and zero from kernel space to user space 2017-12-18 14:33:06 -08:00
Jeremy Soller a9fa08fd72 Merge pull request #66 from weclaw1/page_table_optimization
Page table optimization
2017-12-17 19:19:15 -07:00
Robert Węcławski 3c466892de change assert to debug_assert 2017-12-17 20:29:35 +01:00
Robert Węcławski a8ecfc86dd Better comment and mask representation 2017-12-17 19:54:52 +01:00
Robert Węcławski 08a4c33b77 New entries are set to zero 2017-12-17 19:46:19 +01:00
Robert Węcławski 2d041bbb51 don't change counter in set_unused 2017-12-17 18:45:41 +01:00
Robert Węcławski 82bae0b314 entry::set doesn't reset counter, counter mask is a const 2017-12-17 18:22:27 +01:00
Robert Węcławski ab687852d3 Convert entry count to u64, remove unnecessary parentheses 2017-12-17 17:19:06 +01:00
Robert Węcławski a48ec82f20 Use unused bits 52-61 in first entry of each page table as counter for number of page table entries 2017-12-17 16:53:20 +01:00
Jeremy Soller c2644adf3d Improve multi_core support 2017-12-05 21:26:45 -07:00
Jeremy Soller cd54352f47 Merge branch 'master' of https://github.com/redox-os/kernel 2017-12-05 20:24:43 -07:00
Jeremy Soller dd7c61b830 Allow other processors to pick up work 2017-12-05 20:24:03 -07:00
Jeremy Soller 8ad13539dc Merge pull request #65 from dlrobertson/master
Add documentation on using gdb
2017-12-04 20:29:08 -07:00
Dan Robertson 2e6949e66d Add documentation on using gdb 2017-12-05 01:25:54 +00:00
Jeremy Soller 9b327ccba8 Update Cargo.lock 2017-12-03 08:53:47 -07:00
Jeremy Soller 45e8effa8a Merge pull request #64 from dlrobertson/master
Do not discard .debug section
2017-12-02 19:27:45 -07:00
Dan Robertson 025ec0def2 Do not discard .debug section
Do not discard the .debug section. If the builder would like to discard
this section, they can do so explicitly with objcopy.
2017-12-02 19:38:16 +00:00
Jeremy Soller 578c57840a 0.1.32 2017-11-28 21:48:28 -07:00
Jeremy Soller 789e290c9b Add fchown, fchmod 2017-11-28 21:48:10 -07:00
Jeremy Soller ed05564011 Remove SwitchResult, use out of band data to detect interruption
Update debugging code
2017-11-14 21:16:35 -07:00
Jeremy Soller da954096e0 Merge pull request #62 from xTibor/fix-nightly
Fix for the latest nightly
2017-11-14 20:28:03 -07:00
Jeremy Soller 9368b2ba4c Merge pull request #63 from pzmarzly/patch-1
elf.rs: do not inline constant from goblin library
2017-11-13 12:38:26 -07:00
Paweł Zmarzły 20f262c4ed elf.rs: do not inline constant from goblin library
SELFMAG is declared [here](https://github.com/m4b/goblin/blob/de8aecc8f1e7f3de7d66a1511d3976cdf0335e0c/src/elf/header.rs#L91).
2017-11-13 20:24:50 +01:00
Tibor Nagy eadade4c0f Fix for the latest nightly 2017-11-10 21:42:28 +01:00
Jeremy Soller 9e9f80ef13 Add futex timeout 2017-11-06 22:04:42 -07:00
Jeremy Soller 2de7bd7f79 Merge pull request #61 from sajattack/patch-1
add a LOC badge
2017-11-05 06:29:35 -07:00
Paul b5dac25d55 add a LOC badge 2017-11-05 00:30:20 -07:00
Jeremy Soller 1e553b744c Fix errors from waitpid 2017-10-29 16:02:54 -06:00
Jeremy Soller eebf12bec5 Fix returning too many errors from waitpid 2017-10-29 15:41:59 -06:00
Jeremy Soller 1f99d038c4 Make debug function never return error 2017-10-29 15:31:35 -06:00
Jeremy Soller ffad0f2ace Merge pull request #59 from xTibor/libcollections
Migrate from collections
2017-10-27 21:39:51 -06:00
Tibor Nagy e6b9f850d1 Migrate from collections 2017-10-28 02:42:08 +02:00
Jeremy Soller 8ec5d4726b Hack to allow rustc to wait on non-child process.
Add sys:syscall for seeing active system calls
2017-10-22 21:13:29 -06:00
Jeremy Soller ef70cd257c Uncomment AML value variant 2017-10-22 19:41:31 -06:00
Jeremy Soller 58c6ef0ecf Merge branch 'master' of https://github.com/redox-os/kernel 2017-10-21 20:30:26 -06:00
Jeremy Soller 51339cb8c9 Cleanup warnings
Implement interrupt on signal in pipe:
2017-10-21 20:30:20 -06:00
Jeremy Soller 62e0713d9b Merge pull request #58 from GabrielMajeri/update-bitflags
Update to `bitflags` version 1.0
2017-10-11 07:44:49 -06:00
Gabriel Majeri 305e7980d8 Update to bitflags 1.0 2017-10-11 15:59:14 +03:00
Jeremy Soller 31d742e6be Merge pull request #57 from redox-os/cap
Capability mode support using null namespace
2017-10-09 20:24:22 -06:00
Jeremy Soller e07c3ac0b9 Set init namespace to 1 2017-10-09 20:20:38 -06:00
Jeremy Soller 244069cf43 Implement a capability namespace with no available schemes 2017-10-09 20:12:08 -06:00
Jeremy Soller b023a715f9 Merge pull request #56 from jaje/externs
Deduplicate memcpy, memmove, memset and memcmp functions
2017-10-05 08:54:07 -06:00
Jan Jedelský 05dc9140a4 Update comment in externs.rs 2017-10-05 14:27:01 +02:00
Jan Jedelský 528ffa985a Deduplicate memcpy, memmove, memset and memcmp functions 2017-10-05 14:19:25 +02:00
Jeremy Soller c417f0cf00 Add target-c-int-width to x86_64 target 2017-10-04 18:25:59 -06:00
Jeremy Soller 808447cbfb Move location of live disk 2017-10-01 14:24:21 -06:00
Jeremy Soller 0794926493 Pass env to first function 2017-09-30 18:09:48 -06:00
Jeremy Soller 41ee250eea Reformat kernel arguments 2017-09-30 16:12:37 -06:00
Jeremy Soller ce87b7fc6c Allow listing of root scheme 2017-09-30 14:52:57 -06:00
Jeremy Soller 49ef95a156 Downgrade goblin 2017-09-26 20:04:48 -06:00
Jeremy Soller aa3c1515a0 Update README.md 2017-09-26 14:35:05 -06:00
Jeremy Soller 01a881243b hybrid -> micro 2017-09-26 14:15:01 -06:00
Jeremy Soller fcf8120eec Update features for latest nightly 2017-09-26 14:12:30 -06:00
Jeremy Soller bdff0dd004 Fix documentation 2017-09-26 13:57:16 -06:00
Jeremy Soller 9a9f5d17cb Update dependencies 2017-09-26 13:29:21 -06:00
Jeremy Soller 37c9250a52 Fix output of build script 2017-09-26 13:17:15 -06:00
Jeremy Soller 23e30c14a8 Create LICENSE 2017-09-26 12:57:43 -06:00
Jeremy Soller 735802366f Update README.md 2017-09-26 12:57:04 -06:00
Jeremy Soller 55ed5f81c3 Update README.md 2017-09-26 12:55:34 -06:00
Jeremy Soller 1fa963be45 Merge pull request #54 from L3nn0x/patch-1
Correct small bug in memcpy 32bits implementation
2017-09-20 07:52:41 -06:00
L3nn0x eebba9291a Update externs.rs
I'm not entirely sure about it, but the rest of the file treats 32 bits as groups of 4 so it makes sense that memcpy does the same.
2017-09-20 09:49:40 +01:00
Jeremy Soller d6b9768dc3 More efficient live filesystem method
Reduce kernel heap to 64 MB
Fix issue in build.rs
2017-09-19 20:21:04 -06:00
Jeremy Soller 1f81866afa Update dependencies 2017-09-19 19:28:43 -06:00
Jeremy Soller 5248ce70db Merge pull request #52 from ids1024/spin-override
Add temporary override for spin-rs
2017-09-19 17:22:11 -06:00
Ian Douglas Scott fee3561282 Add temporary override for spin-rs 2017-09-19 16:17:48 -07:00
Jeremy Soller bec9610947 Change unreachable to enosys 2017-09-17 16:49:34 -06:00
Jeremy Soller 5839641b41 Update debugging code 2017-09-17 09:40:29 -06:00
Jeremy Soller 18a911578c Merge pull request #51 from ids1024/debug_syscall
Add commented out system call debug printing code
2017-09-16 21:34:41 -06:00
Ian Douglas Scott 29a2b9fbcd Add commented out system call debug printing code 2017-09-16 20:25:54 -07:00
Jeremy Soller 6e8de21b7c Implement events on pipe
Add syscall name debugging
Update debugging code
2017-09-16 12:04:20 -06:00
Jeremy Soller 917d30c193 Fix the mapping of TLS - it will now be page aligned 2017-09-13 22:16:02 -06:00
Jeremy Soller a5f3e5057b Remove warnings
Improve error information
Cleanup interrupt macros
2017-09-13 21:32:08 -06:00
Jeremy Soller cf45bd34e1 Merge pull request #48 from CWood1/master
Fully implemented AML parser, some amendments to ACPI infrastructure
2017-08-31 17:53:16 -06:00
Connor Wood f0bc8cca23 Merge 2017-08-31 13:28:24 +01:00
Connor Wood 7145e2390c Converted DDB handle to integer and vice versa 2017-08-31 11:25:08 +01:00
Connor Wood 1cce42b691 Moved DDB handles over to using signature scheme 2017-08-31 11:07:01 +01:00
Connor Wood 1bcd8530d2 Stored signature to include OEM signature and OEM table ID 2017-08-31 10:52:59 +01:00
Connor Wood 5592484d07 Eliminated dead code 2017-08-30 19:09:08 +01:00
Connor Wood c3d07e4caa Refactored ACPI initialisation code to be better conducive to DDB Handle stuff 2017-08-30 19:03:39 +01:00
Connor Wood 9f55367906 Implemented notification API 2017-08-29 17:29:07 +01:00
Connor Wood d23241d800 Implemented copy 2017-08-29 12:25:41 +01:00
Connor Wood d75dfd3c20 Implemented externam 2017-08-29 12:02:03 +01:00
Connor Wood 71c5301448 Implemented concat 2017-08-29 11:32:48 +01:00
Connor Wood 60edb9da68 Implemented type checking and coersion upon store 2017-08-29 10:11:01 +01:00
Connor Wood b78f7139b9 Completed Get method 2017-08-29 09:38:36 +01:00
Jeremy Soller d487e1d23f Make syscall a submodule 2017-08-27 10:54:11 -06:00
Jeremy Soller 9fcaf30513 Fix PIT 2017-08-21 20:27:13 -06:00
Connor Wood d5d156a3d2 Implemented buffer field index modify 2017-08-19 15:10:47 +01:00
Jeremy Soller 81a931629f Merge pull request #47 from ids1024/exec
Support arguments in #!
2017-08-16 14:08:31 -06:00
Ian Douglas Scott f60d9fc969 Support arguments in #! 2017-08-16 12:30:20 -07:00
Connor Wood aa35967f72 Made index modification recursion resolve 2017-08-13 19:02:25 +02:00
Connor Wood f0a185741a Implemented recursive index modifications 2017-08-13 16:13:57 +02:00
Connor Wood 328a89c224 Completed context modify, aside from BufferFields and nested Indexes 2017-08-10 14:28:30 +02:00
Jeremy Soller 5c5e5da7c2 Update syscall crate 2017-08-09 21:06:00 -06:00
Jeremy Soller b43f1503b7 Merge pull request #46 from ids1024/dupfd
Implement F_DUPFD
2017-08-08 14:58:49 -06:00
Ian Douglas Scott 1623baa137 Implement F_DUPFD in fcntl 2017-08-08 10:59:11 -07:00
Ian Douglas Scott 9e2d39b5b8 Move duplication in dup() and dup2() to new function 2017-08-07 21:57:25 -07:00
Jeremy Soller 64d7d24174 Merge pull request #45 from ids1024/filelock
Prevent freezing due to double locking
2017-08-06 13:39:50 -06:00
Ian Douglas Scott ade6e0d421 Prevent freezing due to double locking 2017-08-06 12:08:50 -07:00
Jeremy Soller d8d78ffbef Update Cargo.lock 2017-08-02 19:06:59 -06:00
Jeremy Soller 8932daf04a Merge pull request #44 from ids1024/fifo
Use fifo flag for pipe
2017-08-02 12:41:48 -06:00
Ian Douglas Scott 2eab3ea6b0 Use fifo flag for pipe 2017-08-02 11:13:44 -07:00
Jeremy Soller b364d052f2 Merge pull request #43 from cookie545445/machdep
Move x86_64-specific code to arch/x86_64
2017-07-30 20:52:21 -06:00
Tommy Hudson 0e1d664bf0 Rearrange serial I/O code and make 16550 driver generic over T: Io 2017-07-30 20:54:36 +01:00
Tommy Hudson 621b657f87 Move x86_64-specific code to arch/x86_64 2017-07-30 15:46:34 +01:00
Connor Wood 94f27a1a9c Merge branch 'aml-namespace' of github.com:cwood1/kernel into aml-namespace 2017-07-30 13:38:50 +03:00
Connor Wood 41ce7fdf1f Implemented much of ctx::modify and ctx::get 2017-07-30 11:23:32 +03:00
Jeremy Soller 21d033a1a8 Update syscall 2017-07-29 08:17:28 -06:00
Connor Wood 6122b21997 Moved event signal/wait code into context 2017-07-29 12:57:53 +03:00
Connor Wood ab98746879 Moved lock manipulation into context 2017-07-29 12:39:08 +03:00
Jeremy Soller 2e66912ce1 Merge pull request #42 from ids1024/description
Use file descriptions, shared between file descriptors
2017-07-28 17:41:55 -06:00
Ian Douglas Scott 374213f155 F_GETFD and F_SETFD 2017-07-28 15:06:50 -07:00
Ian Douglas Scott 6b504a9493 Remove unused imports 2017-07-28 14:26:15 -07:00
Ian Douglas Scott 3756fb5606 Use file description alongside file descriptior, matching posix 2017-07-28 13:59:31 -07:00
Jeremy Soller 2261452492 Update to new nightly API 2017-07-26 20:58:40 -06:00
Jeremy Soller b474136af4 Add cargo.lock 2017-07-26 07:44:24 -06:00
Connor Wood f25df99a41 Implemented derefof 2017-07-25 14:48:07 +01:00
Connor Wood ada5ba6dbc Implemented condrefof 2017-07-25 13:12:42 +01:00
Connor Wood afc93f82a9 Implemented RefOf 2017-07-25 13:06:10 +01:00
Connor Wood 968fd30b0a Fixed object references 2017-07-25 11:51:43 +01:00
Connor Wood 8a5ec3a26b Implemented SizeOf 2017-07-25 11:37:49 +01:00
Connor Wood 0652bc8099 Implemented ToBuffer 2017-07-25 11:29:32 +01:00
Connor Wood 6df99953dc Implemented defBuffer 2017-07-25 11:25:29 +01:00
Connor Wood 1cd124a852 Fixed bank name issue 2017-07-25 10:36:56 +01:00
Connor Wood a115d21495 Converted all types to string 2017-07-24 19:02:09 +01:00
Connor Wood a5382534e6 Converted to integer fully 2017-07-24 18:53:21 +01:00
Connor Wood d7229d7132 Completed simple type conversions 2017-07-24 17:50:41 +01:00
Connor Wood fdcacd7d18 Implemented numerous "simple" type conversions 2017-07-24 17:27:01 +01:00
Connor Wood e7edaceec0 All conversions to BufferField, dependent on the conversion to Buffer 2017-07-24 16:15:18 +01:00
Connor Wood 9408e71dcd Converted BufferField into Buffer 2017-07-24 16:02:19 +01:00
Connor Wood 82762863df Converted string to buffer 2017-07-24 09:56:54 +01:00
Connor Wood c6ecf105ad Converted Integer to Buffer 2017-07-24 09:48:27 +01:00
Connor Wood a70b26555e Error handling in namespace path assembly 2017-07-24 09:21:53 +01:00
Connor Wood 59b176c24e Implemented path parent character "^" when calculating scope paths 2017-07-24 09:09:07 +01:00
Jeremy Soller a3b0c8ebff Merge pull request #40 from ids1024/components
Strip extra slashes from path
2017-07-23 20:23:40 -06:00
Ian Douglas Scott 1367c7814f Strip extra slashes from path
Fixes strange behavior like 'cd .//////; pwd'
2017-07-23 18:09:49 -07:00
Jeremy Soller ef8c120533 Prevent nested signals, fix check for PID > 0 2017-07-23 16:02:48 -06:00
Jeremy Soller 07262fd866 Implement sending signals to process groups. Modify max context value to fit inside of isize 2017-07-23 15:55:47 -06:00
Jeremy Soller d6848a1995 Add PGID 2017-07-23 14:47:41 -06:00
Connor Wood c79eb0eeab Implemented table API in full 2017-07-23 13:42:30 +01:00
Connor Wood 4288182106 Implemented Load 2017-07-23 10:34:50 +01:00
Jeremy Soller 6a061665e4 Use EINVAL instead of ENOENT 2017-07-22 13:21:15 -06:00
Jeremy Soller fc914e0cae Make it an error to supply a dup buffer to schemes that do not handle it 2017-07-22 12:54:28 -06:00
Connor Wood 82e814469c Shutdown on fatal error 2017-07-22 13:52:48 +01:00
Connor Wood 3c2b3b3f5e Fixed a bunch of warnings 2017-07-22 13:32:02 +01:00
Connor Wood 76316aa8d6 Implemented toHexString 2017-07-22 13:10:45 +01:00
Connor Wood 5873e553e9 Implemented toDecimalString 2017-07-22 12:56:53 +01:00
Connor Wood 797262df5c Several conversion operators 2017-07-22 12:48:23 +01:00
Connor Wood 79b6afd608 Implemented to integer 2017-07-22 12:12:31 +01:00
Connor Wood f8e433c4e7 Implemented sleep 2017-07-22 11:13:30 +01:00
Connor Wood ff23827155 Implemented stall 2017-07-22 11:02:53 +01:00
Connor Wood b7d9ad60bb Implemented Event synchronisation objects 2017-07-22 10:55:09 +01:00
Connor Wood b0b8a7e85d Handled mutexes 2017-07-22 10:06:20 +01:00
Connor Wood 8e98cdf971 Processed acquire mutex 2017-07-22 09:57:44 +01:00
Connor Wood 8412339ae9 Every context has an ID 2017-07-22 09:10:37 +01:00
Connor Wood 1938ca0435 Memory handler API 2017-07-21 14:11:29 +01:00
Connor Wood 0365b6f2b7 Created a function to control the global S state 2017-07-21 12:51:30 +01:00
Connor Wood 5c05b48921 GenericAddressStructure now handles reads and writes itself 2017-07-21 12:42:11 +01:00
Connor Wood 2256e0288b Removed spurious file 2017-07-21 12:04:36 +01:00
Connor Wood a14266fc82 Parallelized ACPI subsystem 2017-07-21 12:03:55 +01:00
Jeremy Soller 4ae6ed9d4c Pass syscall data to syscall, implement iopl 2017-07-19 14:51:12 -06:00
Jeremy Soller f7b961ddff Reduce scope of contexts lock 2017-07-18 22:02:22 -06:00
Jeremy Soller b4d502c763 Add reset code 2017-07-18 20:55:00 -06:00
Jeremy Soller 76aa3116d7 Merge pull request #39 from ids1024/uname
sys:uname
2017-07-18 18:48:35 -06:00
Ian Douglas Scott 2ab539d2e4 sys:uname 2017-07-18 15:42:42 -07:00
Connor Wood dba65f3128 Remove all namespace changes made within methods 2017-07-18 10:16:26 +01:00
Jeremy Soller c7664674d3 Update fs.rs 2017-07-17 21:25:20 -06:00
Connor Wood 258cab878c Implemented index references 2017-07-17 13:22:06 +01:00
Connor Wood c01a04148b Implemented method return values 2017-07-17 12:20:04 +01:00
Connor Wood d315914f29 Implmented method execution and method invocations 2017-07-17 11:54:19 +01:00
Connor Wood d38b1d7aa9 Implemented loop control 2017-07-17 11:26:33 +01:00
Connor Wood af80bfa258 Timer now returns monotonic counter 2017-07-15 10:51:59 +01:00
Connor Wood fe681d57a1 Implemented opcodes 2017-07-15 10:14:53 +01:00
Connor Wood eeea65f5c1 Implemented match 2017-07-15 10:14:53 +01:00
Connor Wood e0bd497bb8 Implemented further opcodes in full, added get to context 2017-07-15 10:14:53 +01:00
Connor Wood 38263bf700 Fixed number of bugs 2017-07-15 10:14:53 +01:00
Connor Wood 2a6bbeb584 Added object modification 2017-07-15 10:14:53 +01:00
Connor Wood 7527915027 Added a context manager 2017-07-15 10:14:53 +01:00
Connor Wood 6c74a02382 Refactored parser to execute in the parse step for efficiency and simplicity 2017-07-15 10:14:52 +01:00
Connor Wood f131cc6f1f Rolled parsing and execution steps into one for namespace modifiers 2017-07-15 10:14:52 +01:00
Connor Wood 5213d59237 Namespaces can now be concatenated, handling of SSDTs is now performed 2017-07-15 10:14:52 +01:00
Connor Wood 21c9d824cc Finalized ACPIType 2017-07-15 10:14:52 +01:00
Connor Wood a79e275cc0 Moved AccessType into namespace 2017-07-15 10:14:52 +01:00
Connor Wood 82124a59d5 Moved ConnectFieldBufferData to the namespace 2017-07-15 10:14:52 +01:00
Connor Wood 1babfb4b32 Moved ConnectFieldNameString into namespace 2017-07-15 10:14:52 +01:00
Connor Wood ee012a482b Moved DataRegion into namespace - more infrastructure required 2017-07-15 10:14:52 +01:00
Connor Wood 94b8bd19d6 Moved indexfield to namespace 2017-07-15 10:14:51 +01:00
Connor Wood 7911853951 Moved arbitrary length buffer field into namespace 2017-07-15 10:14:51 +01:00
Connor Wood f287638996 Moved BufferFields into namespace 2017-07-15 10:14:51 +01:00
Connor Wood 9ae9e3b190 Moved BankField to the namespace 2017-07-15 10:14:51 +01:00
Connor Wood 61776f7af8 Removed temporary files 2017-07-15 10:14:51 +01:00
Connor Wood 94b0e7de37 Moved Event to namespace 2017-07-15 10:14:51 +01:00
Connor Wood 9575c6fed3 Moved Mutex to namespace 2017-07-15 10:14:51 +01:00
Connor Wood e52d4c98a3 Moved PowerResource into namespace 2017-07-15 10:14:51 +01:00
Connor Wood b4ddaeadbb Moved Processor to namespace, and refactored namespace layout to use BTreeMap 2017-07-15 10:14:50 +01:00
Connor Wood 73562b3f56 Moved ComputationalData::String into namespace 2017-07-15 10:14:01 +01:00
Connor Wood c58aa38247 Moved DefDevice and DefThermalZone to namespace 2017-07-15 10:14:01 +01:00
Connor Wood 07cf7385e9 Moved Alias to the namespace 2017-07-15 10:14:01 +01:00
Jeremy Soller 1085fa3838 Merge pull request #38 from ids1024/espipe
Make seek on pipe return ESPIPE
2017-07-14 17:15:31 -06:00
Ian Douglas Scott 89f695dd28 Make seek on pipe return ESPIPE 2017-07-14 15:58:24 -07:00
Jeremy Soller ff9f2322a6 Merge pull request #37 from ids1024/cloexec
Make dup/dup2 clear cloexec
2017-07-14 12:56:28 -06:00
Ian Douglas Scott 09a4980442 Make dup/dup2 clear cloexec 2017-07-14 08:48:42 -07:00
Jeremy Soller 30385fec48 Merge pull request #36 from CWood1/hpet
HPET Driver
2017-07-14 08:32:52 -06:00
Connor Wood 0b6bde7c68 Moved PIT driver into kernel 2017-07-14 15:26:04 +01:00
Connor Wood 0bd6f11a4f Implemented HPET driver 2017-07-14 13:58:06 +01:00
Connor Wood 0cbdb2d0c0 Saved HPET table for global access 2017-07-14 10:39:50 +01:00
Connor Wood 387cd41e5e Implemented ACPI table 2017-07-14 10:36:27 +01:00
Jeremy Soller 56ba795845 Merge pull request #34 from ids1024/dup2
Make dup2() work if second file descriptor doesn't exist
2017-07-13 15:55:16 -06:00
Ian Douglas Scott 6f081f4bbd Make dup2() work if second file descriptor doesn't exist 2017-07-13 14:43:55 -07:00
Jeremy Soller 2c0cc3a8a1 Merge pull request #33 from ids1024/path
Pass relative, not canonicalized, path to script
2017-07-13 09:49:59 -06:00
Ian Douglas Scott f020fe2ac5 Pass relative, not canonicalized, path to script 2017-07-13 08:09:36 -07:00
Jeremy Soller 6981f0cd36 Merge pull request #32 from ids1024/process
Strip whitspaces after #!
2017-07-13 07:11:39 -06:00
Ian Douglas Scott b5da98396e Strip whitspaces after #!
Autotools configure scripts seem to use "#! /bin/sh"
2017-07-12 23:03:53 -07:00
Jeremy Soller 687f991ab4 Merge pull request #31 from ids1024/fstat
Implement fstat() for pipe scheme
2017-07-12 07:05:46 -06:00
Ian Douglas Scott f81a276536 Implement fstat() for pipe scheme 2017-07-11 21:26:35 -07:00
Jeremy Soller a03457a9eb Simpler debug message 2017-07-10 20:33:29 -06:00
Jeremy Soller a3493d16fd Allow simple signal delivery to PID 1 (the kernel idle process) 2017-07-10 20:28:10 -06:00
Jeremy Soller 268ba3ece7 Remove syscall replacement 2017-07-10 20:13:01 -06:00
Jeremy Soller a0b06a2835 Merge branch 'master' of https://github.com/redox-os/kernel 2017-07-10 20:09:01 -06:00
Jeremy Soller ab738cede5 Restore kernel parameters on sigreturn 2017-07-10 20:08:57 -06:00
Jeremy Soller 8f6268eef7 Merge pull request #30 from ids1024/pipe
Revert "pipe: make read() return when write end is closed"
2017-07-10 17:10:16 -06:00
Ian Douglas Scott 79a45a2580 Revert "pipe: make read() return when write end is closed"
This reverts commit 09a67641c6.
2017-07-10 11:15:45 -07:00
Jeremy Soller b5ff0aabd5 WIP: Signal handling 2017-07-09 21:34:38 -06:00
Jeremy Soller 7e52541f39 Implement passthrough of futimens 2017-07-09 15:43:26 -06:00
Jeremy Soller 3f40af0687 Update to new allocator API 2017-07-08 19:50:58 -06:00
Jeremy Soller 22e87d94d4 Merge pull request #29 from ids1024/pipe
pipe: make read() return when write end is closed
2017-07-08 06:56:36 -06:00
Connor Wood fa24650ca7 Implemented opcodes 2017-07-08 10:20:33 +01:00
Ian Douglas Scott 09a67641c6 pipe: make read() return when write end is closed 2017-07-07 21:05:38 -07:00
Connor Wood 59936e25e6 Implemented match 2017-07-07 11:39:08 +01:00
Connor Wood 00591235e1 Implemented further opcodes in full, added get to context 2017-07-07 10:37:09 +01:00
Jeremy Soller ae5a32cf98 Merge pull request #28 from ids1024/dup
Pass empty second argument to dup in exec
2017-07-06 18:29:07 -06:00
Ian Douglas Scott 074ce2e57d Pass empty second argument to dup in exec 2017-07-06 16:44:54 -07:00
Jeremy Soller d0c3a5d2aa Merge pull request #27 from ids1024/clone
Pass empty second argument to dup() call in clone
2017-07-06 05:54:59 -06:00
Ian Douglas Scott b2df8d676f Pass empty second argument to dup() call in clone
I don't know if this was there for a reason, but it was making the dup()
fail with tcpd, and I don't seem this being handled specially in redoxfs
or anywhere else.
2017-07-05 22:45:27 -07:00
Jeremy Soller d4e295a385 Revert syscall path 2017-07-05 21:46:40 -06:00
Jeremy Soller 0e8e1b5c4e WIP: Signal handling 2017-07-05 21:45:53 -06:00
Connor Wood 980065d4d6 Fixed number of bugs 2017-07-05 14:36:40 +01:00
Connor Wood def456a8e5 Added object modification 2017-07-03 11:11:07 +01:00
Connor Wood 50ac9d3abe Added a context manager 2017-07-03 10:31:01 +01:00
Connor Wood 590610f4a5 Refactored parser to execute in the parse step for efficiency and simplicity 2017-07-02 13:07:43 +01:00
Jeremy Soller a4c3afb446 Merge pull request #26 from ids1024/getppid
Implement getppid system call
2017-06-29 06:34:49 -06:00
Ian Douglas Scott dddd87c2c3 Implement getppid system call 2017-06-28 22:05:01 -07:00
Jeremy Soller 12d487ec9c Merge pull request #19 from bjorn3/fix_warnings
Fix most lint warnings, check multicore code even if disabled
2017-06-26 06:52:50 -06:00
bjorn3 2dcd563709 Merge branch 'master' into fix_warnings 2017-06-26 14:22:17 +02:00
Connor Wood f72f97ef36 Rolled parsing and execution steps into one for namespace modifiers 2017-06-23 14:02:40 +01:00
Connor Wood 9fb15e7e92 Namespaces can now be concatenated, handling of SSDTs is now performed 2017-06-22 19:12:40 +01:00
Connor Wood be1a75e472 Finalized ACPIType 2017-06-22 16:25:19 +01:00
Connor Wood c83cefee08 Moved AccessType into namespace 2017-06-22 15:43:00 +01:00
Connor Wood fb0e5137e8 Moved ConnectFieldBufferData to the namespace 2017-06-22 15:22:19 +01:00
Connor Wood c8eca653b8 Moved ConnectFieldNameString into namespace 2017-06-22 15:09:04 +01:00
Connor Wood 0a67ad4b23 Moved DataRegion into namespace - more infrastructure required 2017-06-22 13:34:05 +01:00
Connor Wood 443c1ac1f8 Moved indexfield to namespace 2017-06-22 12:45:58 +01:00
Connor Wood 94e391c9b6 Moved arbitrary length buffer field into namespace 2017-06-22 12:23:14 +01:00
Connor Wood cef562c832 Moved BufferFields into namespace 2017-06-22 12:16:30 +01:00
Connor Wood 12e7d1ad4d Moved BankField to the namespace 2017-06-22 12:02:17 +01:00
Connor Wood 2e64cea81f Removed temporary files 2017-06-21 20:54:29 +01:00
Connor Wood 312aff03c4 Moved Event to namespace 2017-06-21 20:50:08 +01:00
Connor Wood 19ccb3612b Moved Mutex to namespace 2017-06-21 20:27:46 +01:00
Connor Wood fceba822eb Moved PowerResource into namespace 2017-06-21 20:13:44 +01:00
Connor Wood 636d94fd20 Moved Processor to namespace, and refactored namespace layout to use BTreeMap 2017-06-21 20:02:05 +01:00
Jeremy Soller 0478e5f7fb Merge pull request #25 from ids1024/env
Make env: return ENOENT on non-existent; support unlink()
2017-06-20 17:06:13 -06:00
Ian Douglas Scott b9f659dadf Make env: return ENOENT on non-existent; support unlink() 2017-06-20 15:56:44 -07:00
Connor Wood 7095219316 Moved ComputationalData::String into namespace 2017-06-19 14:12:26 +01:00
Connor Wood 3ed94405aa Moved DefDevice and DefThermalZone to namespace 2017-06-19 13:49:37 +01:00
Connor Wood 190686a853 Moved Alias to the namespace 2017-06-19 13:33:20 +01:00
Jeremy Soller cd67aabd5a Switch collections::boxed for alloc::boxed 2017-06-18 20:05:19 -06:00
Jeremy Soller bbcd5197a4 Aml parser (#24)
* Initial parser proof of concept

* Added better error handling to the parser

* Refactored into a better directory structure

* Parse package length

* Implemented named string, scope op

* Properly bounds checked namestring

* Fixed namestring regressions

* Started work parsing DefRegionOp. NB: As TermArg is not yet implemented, a bug is present parsing the address offset and length. Additionally, a bug was fixed in NameString

* Completed DefOpRegion implementation. TermArg remains unimplemented, stubbed out

* Implemented TermArg parsing

* Implemented integer parts of computational data

* Implemented defField, and associated FieldList. FieldElement still remains stubbed

* Implmenented FieldElement

* Implmenented named field

* Parsed DefMethod

* Parsed ToHexString

* Parsed ToBuffer

* Parsed both subtract and sizeof

* Fixed size bug in sizeof parsing

* Parsed Store, fixed a parse bug where Target should be a SuperName not a TermArg

* Parsed while

* Parsed LLess

* Parsed DerefOf

* Parse Index

* Parse increment

* Parse device

* Parse device

* Parsed create dword field

* Parsed if/else block

* Properly parsed Target, rendered an AST from existing parse code, and stubbed out MethodInvocation parser method

* Implemented deferred loading, and deferred method invocation parses

* Parsed Or

* Fixed a bunch of off-by-one errors. Shows what I get for copying code around

* Parsed Return

* Fixed a boolean logic error in the handling of the extended instruction namespace

* Added DefBuffer to ComputationalData

* Removed a temporary file

* Parsed ReservedField

* Parsed DefPackage, DefAnd, and ComputationalData::String

* Parsed DefMutex

* Parsed DefAlias and RevisionOp

* Parsed DebugObj

* Parsed DefRefOf

* Parsed type 6 opcodes

* Added ObjectReference and DDBHandle to DataRefObj parsing

* Parsed DefVarPackage, in both Type2OpCode, and in DataObj

* Parsed DefBankField

* Parsed AccessField

* Parsed ConnectField

* Parsed CreateBitField

* Parsed CreateByteField

* Parsed CreateWordField

* Parsed CreateQWordField

* Parsed CreateField

* Parsed DefDataRegion

* Parsed DefEvent

* Parsed IndexField

* Parsed DefPowerRes

* Parsed DefProcessor

* Parsed DefThermalZone:

* Parsed ExtendedAccessField

* Parsed DefBreak, DefBreakPoint, DefContinue and DefNoop (all type 1 opcodes with no parameters and one byte)

* Parsed DefFatal

* Parsed DefLoad

* Parsed DefNotify

* Parsed DefRelease

* Parsed DefReset

* Parsed DefSignal

* Parsed DefSleep

* Parsed DefStall

* Parsed DefUnload

* Parsed DefAcquire

* Parsed DefAnd

* Parsed DefConcat

* Parsed ConcatRes

* Switched Concat and ConcatRes opcodes

* Parsed CondRefOf

* Parsed DefDecrement and DefCopyObject

* Parsed DefDivide, fixed length calculation bug in a bunch of parse routines

* Parsed DefFindSetLeftBit

* Parsed DefFindSetRightBit

* Parsed DefFromBCD

* Parsed DefLAnd

* Parsed DefLGreater

* Parsed LNot

* Parsed DefLOr

* Parsed DefLoadTable

* Parsed DefMatch

* Parsed DefMid

* Parsed DefMod

* Parsed DefMultiply

* Parsed DefNAnd

* Parsed DefNOr

* Parsed DefNot

* Parsed DefObjectType

* Parsed DefShiftLeft and DefShiftRight

* Parsed DefTimer

* Parsed DefToBCD, DefToDecimalString, DefToInteger and DefToString

* Parsed DefXor

* Parsed DefWait

* Implemented a parser, abstract syntax tree, and basic infrastructure for the AML subsystem of the ACPI module. The entire AML grammar is parsed and placed into an abstract syntax tree, with one exception: method invocations, rather than parsing, defer the load until later on in the process, due to the way the grammar works.

Still to be done:
 - Refactor the code: a lot of the parser is very repetitive, and could easily be refactored with the aid of macros. This would reduce the length and improve legibility, though not affect function.
 - More rigorous testing of parser: the parser has, thus far, only been tested on the DSDT in QEMU. There may be bugs present that are hidden.
 - Parse the SSDTs: the SSDTs should be parsed after the DSDT, and contain more AML bytecode to be treated as modifying the same namespace. Adding this would be simple, though not urgent.
 - Transform the AST into a concrete executable tree: the CET is what will hold all information necessary to execute control methods and evaluate namespace objects. While this could be done in the AST, due to the way AML is laid out this would be very inefficient and require a lot of repetitive transformations every time something is to be executed. Therefore, perform the transformations upfront.
 - Parse the deferred loads, and the method invocations contained within: Once the AST has been rendered into a CET, sufficient information will be present to parse method invocations and add those to the namespace.
 - Bytecode interpreter: Once the CET has been finalized with method invocation parsing, it can then be called and executed.
 - Control method executor: this should walk the namespace, locating the relevant control method, then calling the interpreter on it.
 - Namespace enumerator: the executor shall use this to walk the namespace, and it should also be publicly accessible to allow outside code to determine what devices are present in the system.
 - Memory accessor API: ACPI AML has a concept of memory access in certain device domains - for example, the PCI BAR registers. These are all device specific offsets, therefore device drivers, or more accurately bus drivers, should be capable of installing handlers to manage this memory access.
 - CET concatenation: The DSDT and SSDTs all affect the same namespace, therefore concatenating the resulting trees should be possible.
 - Type checking: some operations in AML are typed. This should be handled at tree transformation time or earlier, and could indeed done in the parse step with some modification to the parser. This is currently not the case.

* Initial parser proof of concept

* Added better error handling to the parser

* Refactored into a better directory structure

* Parse package length

* Implemented named string, scope op

* Properly bounds checked namestring

* Fixed namestring regressions

* Started work parsing DefRegionOp. NB: As TermArg is not yet implemented, a bug is present parsing the address offset and length. Additionally, a bug was fixed in NameString

* Completed DefOpRegion implementation. TermArg remains unimplemented, stubbed out

* Implemented TermArg parsing

* Implemented integer parts of computational data

* Implemented defField, and associated FieldList. FieldElement still remains stubbed

* Implmenented FieldElement

* Implmenented named field

* Parsed DefMethod

* Parsed ToHexString

* Parsed ToBuffer

* Parsed both subtract and sizeof

* Fixed size bug in sizeof parsing

* Parsed Store, fixed a parse bug where Target should be a SuperName not a TermArg

* Parsed while

* Parsed LLess

* Parsed DerefOf

* Parse Index

* Parse increment

* Parse device

* Parse device

* Parsed create dword field

* Parsed if/else block

* Properly parsed Target, rendered an AST from existing parse code, and stubbed out MethodInvocation parser method

* Implemented deferred loading, and deferred method invocation parses

* Parsed Or

* Fixed a bunch of off-by-one errors. Shows what I get for copying code around

* Parsed Return

* Fixed a boolean logic error in the handling of the extended instruction namespace

* Added DefBuffer to ComputationalData

* Removed a temporary file

* Parsed ReservedField

* Parsed DefPackage, DefAnd, and ComputationalData::String

* Parsed DefMutex

* Parsed DefAlias and RevisionOp

* Parsed DebugObj

* Parsed DefRefOf

* Parsed type 6 opcodes

* Added ObjectReference and DDBHandle to DataRefObj parsing

* Parsed DefVarPackage, in both Type2OpCode, and in DataObj

* Parsed DefBankField

* Parsed AccessField

* Parsed ConnectField

* Parsed CreateBitField

* Parsed CreateByteField

* Parsed CreateWordField

* Parsed CreateQWordField

* Parsed CreateField

* Parsed DefDataRegion

* Parsed DefEvent

* Parsed IndexField

* Parsed DefPowerRes

* Parsed DefProcessor

* Parsed DefThermalZone:

* Parsed ExtendedAccessField

* Parsed DefBreak, DefBreakPoint, DefContinue and DefNoop (all type 1 opcodes with no parameters and one byte)

* Parsed DefFatal

* Parsed DefLoad

* Parsed DefNotify

* Parsed DefRelease

* Parsed DefReset

* Parsed DefSignal

* Parsed DefSleep

* Parsed DefStall

* Parsed DefUnload

* Parsed DefAcquire

* Parsed DefAnd

* Parsed DefConcat

* Parsed ConcatRes

* Switched Concat and ConcatRes opcodes

* Parsed CondRefOf

* Parsed DefDecrement and DefCopyObject

* Parsed DefDivide, fixed length calculation bug in a bunch of parse routines

* Parsed DefFindSetLeftBit

* Parsed DefFindSetRightBit

* Parsed DefFromBCD

* Parsed DefLAnd

* Parsed DefLGreater

* Parsed LNot

* Parsed DefLOr

* Parsed DefLoadTable

* Parsed DefMatch

* Parsed DefMid

* Parsed DefMod

* Parsed DefMultiply

* Parsed DefNAnd

* Parsed DefNOr

* Parsed DefNot

* Parsed DefObjectType

* Parsed DefShiftLeft and DefShiftRight

* Parsed DefTimer

* Parsed DefToBCD, DefToDecimalString, DefToInteger and DefToString

* Parsed DefXor

* Parsed DefWait

* Implemented a parser, abstract syntax tree, and basic infrastructure for the AML subsystem of the ACPI module. The entire AML grammar is parsed and placed into an abstract syntax tree, with one exception: method invocations, rather than parsing, defer the load until later on in the process, due to the way the grammar works.

Still to be done:
 - Refactor the code: a lot of the parser is very repetitive, and could easily be refactored with the aid of macros. This would reduce the length and improve legibility, though not affect function.
 - More rigorous testing of parser: the parser has, thus far, only been tested on the DSDT in QEMU. There may be bugs present that are hidden.
 - Parse the SSDTs: the SSDTs should be parsed after the DSDT, and contain more AML bytecode to be treated as modifying the same namespace. Adding this would be simple, though not urgent.
 - Transform the AST into a concrete executable tree: the CET is what will hold all information necessary to execute control methods and evaluate namespace objects. While this could be done in the AST, due to the way AML is laid out this would be very inefficient and require a lot of repetitive transformations every time something is to be executed. Therefore, perform the transformations upfront.
 - Parse the deferred loads, and the method invocations contained within: Once the AST has been rendered into a CET, sufficient information will be present to parse method invocations and add those to the namespace.
 - Bytecode interpreter: Once the CET has been finalized with method invocation parsing, it can then be called and executed.
 - Control method executor: this should walk the namespace, locating the relevant control method, then calling the interpreter on it.
 - Namespace enumerator: the executor shall use this to walk the namespace, and it should also be publicly accessible to allow outside code to determine what devices are present in the system.
 - Memory accessor API: ACPI AML has a concept of memory access in certain device domains - for example, the PCI BAR registers. These are all device specific offsets, therefore device drivers, or more accurately bus drivers, should be capable of installing handlers to manage this memory access.
 - CET concatenation: The DSDT and SSDTs all affect the same namespace, therefore concatenating the resulting trees should be possible.
 - Type checking: some operations in AML are typed. This should be handled at tree transformation time or earlier, and could indeed done in the parse step with some modification to the parser. This is currently not the case.

* Partial refactor of AML code

* Further refactoring

* Fully refactored type 2 opcode selector

* Refactored type 6 opcode selector

* Further refactored Type 2 opcode parsing

* Implemented basic infrastructure in order to render the AST down to a namespace object

* Resolved scopes into the namespace

* Put OpRegion into namespace

* Rendered field parsing to the namespace object

* Methods now placed in namespace

* Moved DefName into the namespace

* Moved packages into the namespace

* Converted shutdown sequence to use AML parser

* Moved shutdown over to use AML parsing fully

* Removed the no longer needed DSDT code

* Better messages on unmapping failure

* Disable preemption until paging bug is fixed

* Refactor kernel mapping so that symbol table is mapped

* Add symbol lookup (still very WIP)

* Improve method of getting symbol name

* Reenable preemption

* Demangle symbols

* Fix overallocation

* Remove tilde files
2017-06-17 18:47:27 -06:00
Jeremy Soller 73a71a7d85 Increase size of kernel heap when live disk is loaded 2017-06-17 14:32:31 -06:00
Jeremy Soller 85c02365c9 Fix overallocation 2017-06-14 20:26:05 -06:00
Jeremy Soller c9cbdab9f1 Demangle symbols 2017-06-14 20:25:49 -06:00
Jeremy Soller 7ef2401db3 Reenable preemption 2017-06-14 20:25:38 -06:00
Jeremy Soller 9b19ab9439 Improve method of getting symbol name 2017-06-13 21:56:20 -06:00
Jeremy Soller acab23d1e1 Add symbol lookup (still very WIP) 2017-06-13 21:43:37 -06:00
Jeremy Soller d6354aeb56 Refactor kernel mapping so that symbol table is mapped 2017-06-13 20:42:04 -06:00
Jeremy Soller 8b05863ebb Disable preemption until paging bug is fixed 2017-06-13 19:10:32 -06:00
Jeremy Soller e3020db04f Better messages on unmapping failure 2017-06-11 08:40:27 -06:00
Jeremy Soller 8d89925842 Align ELF segments to avoid subtract overflow 2017-06-04 18:34:45 -06:00
Jeremy Soller 138463b74a Merge pull request #21 from ids1024/unique
Update for changes in std::ptr::Unique API
2017-06-02 20:56:01 -06:00
Ian Douglas Scott 3c5b262b0e Update for changes in std::ptr::Unique API 2017-05-21 13:44:10 -07:00
Jeremy Soller 4d2808a012 Remove free count print 2017-05-12 21:04:52 -06:00
Jeremy Soller 32b0c06314 Remove hardcoded live filesystem 2017-05-11 21:16:07 -06:00
Jeremy Soller 62d3f4bd93 Add Xargo support 2017-05-10 21:38:40 -06:00
bjorn3 586f249069 Add trailing newline to Cargo.toml 2017-04-29 17:52:55 +02:00
bjorn3 6f6f8f7391 Check multicore code even if disabled 2017-04-29 17:46:36 +02:00
bjorn3 37b4ac151b Fix some warnings 2017-04-29 17:45:43 +02:00
Jeremy Soller b3a25bd3a3 Merge pull request #14 from bjorn3/ls_root_scheme
Ls root scheme
2017-04-29 06:49:55 -06:00
Jeremy Soller d8630faccb Merge pull request #15 from bjorn3/remove_pit_ticks_assert
Remove PIT_TICKS assert
2017-04-29 06:40:28 -06:00
bjorn3 248cfa51ae Remove PIT_TICKS assert 2017-04-29 10:46:07 +02:00
bjorn3 ca8b6f522e Fix closing ls handle 2017-04-29 10:43:50 +02:00
bjorn3 8ffe704e7a Remove yet another unnecessary change 2017-04-28 18:44:37 +02:00
bjorn3 4441b750cf Remove unnecessary change 2017-04-28 18:43:39 +02:00
bjorn3 c9fdc4beae Make it working 2017-04-28 18:42:33 +02:00
bjorn3 4c006bca48 Remove UserOrListHandle 2017-04-28 16:18:41 +02:00
bjorn3 80afcc8879 Implement listing all schemes using : scheme 2017-04-28 15:40:15 +02:00
Jeremy Soller 0a457bdced Merge pull request #12 from InsidiousMind/fix-pit-not-context-switching
Fix PIT Interrupt Not Context Switching [irq]
2017-04-25 17:41:55 -06:00
Andrew Plaza 2fc4454f5e set PIT_TICKS to 0 in context::switch() 2017-04-25 16:59:14 -04:00
Andrew Plaza 5ba02ca940 Reset PIT_TICKS to 0 on context::switch, change condition for context::switch [irq]
Set the counter to 0 when context is to be switched in the PIT interrupt,
and change the condition for context switching from % 10 to >= 10.
2017-04-25 14:40:23 -04:00
Andrew Plaza 7127e14b5d Fix PIT Interrupt Not Context Switching [irq]
PIT interrupt should context switch or else all of redox crashes.
This will fix programs like the Snake game crashing all of Redox.
A global AtomicUSize counter was added, and a line to switch contexts
on every 10 PIT interrupts in irq.rs.
2017-04-24 22:07:32 -04:00
Jeremy Soller dd98bfec5c Fix typo in live scheme 2017-04-19 22:00:30 -06:00
Jeremy Soller efd64d55e1 Bug fixes for fcntl and o_cloexec
Add fcntl to schemes
Fix debug: hang
2017-04-19 21:56:09 -06:00
Jeremy Soller 40ff16e42d Add __rust_allocate_zeroed to work with newest nightly 2017-04-18 21:26:18 -06:00
Jeremy Soller d036c667a1 Perform cloexec logic in kernel 2017-04-16 12:49:54 -06:00
Jeremy Soller ea1150cd9b Implement CLOEXEC for root scheme and initfs 2017-04-15 22:35:05 -06:00
Jeremy Soller 9d39317f95 Fix issue where ppid changes during child close 2017-04-15 20:29:08 -06:00
Jeremy Soller 66120cf201 Fix deallocation issues by ignoring deallocation on temporary page 2017-04-15 19:56:48 -06:00
Jeremy Soller 800e6c6de7 Free page tables during unmap, if empty 2017-04-15 19:22:17 -06:00
Jeremy Soller 1e8df4b905 Add sys:iostat 2017-04-15 09:58:03 -06:00
Jeremy Soller a38f32c735 Add path implementation to most kernel schemes 2017-04-15 09:50:02 -06:00
Jeremy Soller 7b5873e460 Allow allocation of larger sizes 2017-04-14 21:17:31 -06:00
Jeremy Soller b3a3caf191 Fix memmove 2017-04-14 21:07:02 -06:00
Jeremy Soller 6fef10bcb1 Merge branch 'master' of https://github.com/redox-os/kernel 2017-04-14 20:59:32 -06:00
Jeremy Soller a9d92df5fa Implement frame recycler 2017-04-14 20:59:27 -06:00
Jeremy Soller 903432f057 Fix issue with reusing temporary page frame 2017-04-14 20:59:01 -06:00
Jeremy Soller 7c1d5d8306 Disable SMP startup, fix issue with reusing trampoline frame 2017-04-14 20:58:23 -06:00
Jeremy Soller 0a72d1cbd8 Merge pull request #11 from pi-pi3/faster-externs
A faster implementation of the memcpy family
2017-04-14 16:49:58 -06:00
pi_pi3 5c1e619063 Avoid multiplication in memcpy family functions
Instead of multiplying everything by 8[/4], now addition is used. That
way code is prettier.
2017-04-14 14:51:04 +02:00
pi_pi3 c4fc76f844 A faster implementation of the memcpy family
The default implementation of the memcpy, memmove, memset and memcmp
functions in the kernel file `extern.rs` uses a naive implementation
by copying, assigning or comparing bytes ony by one. This can be slow.
This commit proposes a reimplementation of those functions by copying,
assigning or comparing in group of 8 bytes by using the u64 type and
its respective pointers instead of u8. Alternative version for 32-bit
architectures are also supplied for future compatibility with x86.
Both version first copy whatever they can with wide word types. The
tail, i.e. the final few bytes that do not fit in a dword or qword
are then copied byte by byte.

Here is a comparison of copying 64kiB (65536 bytes) on stack:

x86_64-unknown-linux-gnu: (64-bit)
       | naive (ns) | fast (ns) | speedup (x)
-------|------------|-----------|------------
memcpy |   204430   |   32994   |   ~6.20
memmove|   202540   |   33186   |   ~6.10
memset |   163391   |   23884   |   ~6.84
memcmp |   205663   |   34385   |   ~5.98

i686-unknown-linux-gnu: (32-bit)
       | naive (ns) | fast (ns) | speedup (x)
-------|------------|-----------|------------
memcpy |   206297   |   66858   |   ~3.09
memmove|   204576   |   70326   |   ~2.91
memset |   165599   |   50227   |   ~3.30
memcmp |   204262   |   70572   |   ~2.89

Copying on the heap behaves simmilarly.

All tests performed on Intel i5 6600K (4x4.2GHz),
ArchLinux Kernel 4.8.12-3 x86_64.
2017-04-14 14:37:32 +02:00
Jeremy Soller 56a533fbbc Add linker flavor 2017-04-13 19:46:48 -06:00
Jeremy Soller 4204d9905e Merge branch 'master' of https://github.com/redox-os/kernel 2017-04-11 21:27:44 -06:00
Jeremy Soller c4fb60f216 Implement script file support 2017-04-11 21:27:39 -06:00
Jeremy Soller d9e95448a4 Merge pull request #10 from xTibor/fix_initfs
Fix the listing of `initfs:` directories
2017-04-11 06:23:28 -06:00
xTibor 1f5bea611d Fix the listing of initfs: directories
There was a bug at the `initfs` generation which made the listing of the contents of the `initfs:`subdirectories impossible from the command line.

The subdirectory listing data had the full paths of the files (like `bin/ahcid\nbin/bgad\n...`) when it should just only be the names of the files (`ahcid\nbgad\n...`)
2017-04-11 05:26:10 +02:00
Jeremy Soller e43f5dda81 Implement timeouts
Cleanup utf8 path error handling
2017-04-08 21:59:30 -06:00
Jeremy Soller b286e69c9d Fix shutdown by disabling APs 2017-04-07 21:49:32 -06:00
Jeremy Soller a7f35e14cc Cleanup debug scheme 2017-04-05 20:11:51 -06:00
Jeremy Soller d26a9ee990 Fix goblin include 2017-04-05 19:10:17 -06:00
Jeremy Soller e860c9efdc Merge pull request #9 from redox-os/refactor
Refactor
2017-04-05 17:36:36 -06:00
Jeremy Soller 2087544ea7 Move all files to src 2017-04-03 21:47:01 -06:00
Jeremy Soller ff93e9cb82 Cleanup some 2017-04-03 21:16:50 -06:00
Jeremy Soller be7f8d64e6 Increase kernel heap, use crates version of goblin 2017-04-01 21:10:55 -06:00
Jeremy Soller cbacd0eea7 Merge pull request #7 from AdamNiederer/patch-1
Fix spelling & grammar in README.md
2017-03-27 06:56:01 -06:00
Adam Niederer 0ae08c52f6 Fix spelling & grammar in README.md 2017-03-26 22:51:28 -04:00
Jeremy Soller 7817122662 Loop on serial input
Fix issue with serial and cascade interrupts not being ackd
2017-03-24 20:38:02 -06:00
Jeremy Soller 906ef94ffd Fix bug with sleep - wake is not cleared after it occurs
Do not initialize waitcondition with capacity
2017-03-21 20:30:46 -06:00
Jeremy Soller ffd7594971 Disable century register for now 2017-03-20 21:47:18 -06:00
Jeremy Soller 228cd79cd4 Refactor ACPI, implement poweroff correctly using the DSDT in ACPI 2017-03-19 16:45:19 -06:00
Jeremy Soller e726234bc6 Fix style of new ACPI code, reduce warnings 2017-03-19 09:34:54 -06:00
Jeremy Soller 643e1f6552 Merge pull request #6 from CWood1/rtc-century
Implemented reading from RTC Century counter in x86_64 arch, if available
2017-03-19 07:29:30 -06:00
Connor Wood f79424aeac Fully implemented reading the RTC century counter, and laid out initial infrastructure for ACPI information to be used across the kernel, in the x86_64 architecture.
- Implemented a global variable, ACPI_TABLE, behind a mutex, which contains the ACPI information pertinent to the rest of the kernel, currently solely containing a pointer to the FADT.
- Split device initialization into two categories - "core" devices, such as the PIC and local APIC, necessary for initializing the rest of the kernel, and "non-core" devices such as serial and RTC, which are to be initialized last.
- Checked for the presence of the century register, and consequentially read from, in the RTC code, now factored into the date calculation. The location of the register is pulled from the "century" field in the FADT.
- Modified page unmapping in the ACPI code, such that any tables to be stored globally (currently only the FADT) are not unmapped after reading, such that they can be stored in globally accessible pointers without causing page faults.
2017-03-18 16:08:45 +00:00
Connor Wood 661ebb6390 Saved FADT in a pointer accessible elsewhere in the kernel 2017-03-18 15:12:42 +00:00
Jeremy Soller 1d5c7d6a4e Merge branch 'master' of https://github.com/redox-os/kernel 2017-03-16 22:50:16 -06:00
Jeremy Soller 05bb497fe4 Use normal EOI mode 2017-03-16 22:50:09 -06:00
Jeremy Soller ab4193d4fc Merge pull request #5 from tones111/cpuid_panic
Prevent cpuid get_extended_function_info panic
2017-03-16 22:15:02 -06:00
Paul Sbarra d667fa61e6 Prevent cpuid get_extended_function_info panic
A kernel panic occurs on some CPUs (notably qemu-system-x86_64) when
calling rust-cpuid's get_extended_function_info.  This is fixed upstream
in commit c3ebfc553cdff98d19d29777fd85c4f9182bfb66 but has yet to make
it crates.io.

The panic can by triggered by running "ls sys:" from ion and causes
redox to become unresponsive.
2017-03-16 22:32:57 -05:00
Jeremy Soller 7dd8de777d Merge pull request #3 from kolipka/standalone_support
Remove hardcoded initfs folder
2017-02-27 11:18:03 -07:00
Konrad Lipner 5ccbd788f3 Remove hardcoded initfs folder
initfs folder should be specified in INITFS_FOLDER environment variable
As a result kernel module can be compiled on it's own.
2017-02-15 21:54:38 +01:00
Jeremy Soller b9793deb59 Disable secondary processors with hlt 2017-02-13 22:15:42 -07:00
Jeremy Soller 473a7b6832 USe auto-eoi mode, mask off interrupts that happen and allow userspace to clear the mask 2017-02-11 21:09:16 -07:00
Jeremy Soller 0e22ba24be Initialize PIC in Rust 2017-02-11 20:54:14 -07:00
Jeremy Soller 571b2aa2e7 Add reminder 2017-02-07 22:14:53 -07:00
Jeremy Soller 776bb83a70 Unstick system by acknowledging IRQs on boot 2017-02-07 22:14:28 -07:00
Jeremy Soller be43673df6 Merge pull request #2 from little-dude/master
remove unused #[macro_use]
2017-01-24 12:48:08 -07:00
Corentin Henry 4d2499e4d3 remove unused #[macro_use] 2017-01-24 11:14:12 -08:00
Jeremy Soller 0d3aa234ff Add target definitions 2017-01-16 10:10:16 -07:00
Jeremy Soller 04d9d6b40a Specify crates.io versions 2017-01-13 15:09:56 -07:00
Jeremy Soller 35c2297724 Fix from @yoric - incorrect initialization of spin loop 2017-01-11 13:59:10 -07:00
Jeremy Soller ed69fac232 Allow memory: to be accessed in all namespaces 2017-01-10 09:59:30 -07:00
Jeremy Soller ba4588e84f Simplify path parsing 2017-01-10 09:22:59 -07:00
Jeremy Soller 433746e13c Move skipping to loop encompasing entire path 2017-01-10 09:19:02 -07:00
Jeremy Soller e20135575c Refactor to move alloc_kernel in tree, and move io into syscall 2017-01-09 20:35:54 -07:00
Jeremy Soller 1c7b5680a4 Use syscall crate from git 2017-01-09 19:47:44 -07:00
Jeremy Soller 375e8addd2 Merge pull request #1 from cactorium/master
Allow for more complicated directory paths
2017-01-07 07:37:10 -07:00
Kelvin Ly b0cafc1890 Correctly handle relative paths starting from the root directory 2017-01-07 08:00:16 -05:00
Kelvin Ly 046d8ac0c5 Fix typo and add functionality to more properly handle the parent of the root of the filesystem 2017-01-07 00:49:45 -05:00
Kelvin Ly fc94bd411a Allow for more complicated directory paths 2017-01-07 00:41:32 -05:00
Jeremy Soller 06118a23dd Remove profiles 2017-01-04 16:33:51 -07:00
Jeremy Soller 882e64bdb9 Ignore Cargo.lock and target 2017-01-04 15:52:38 -07:00
Jeremy Soller 0c8ba636f4 Cleanup Redox repo, update Rust, remove old target 2017-01-03 15:55:00 -07:00
Jeremy Soller 04ed700216 Force flush of tables 2017-01-03 14:09:15 -07:00
Jeremy Soller 2cb8b1fd53 Use variable for temporary page location 2017-01-01 18:00:24 -07:00
Jeremy Soller 5ddd2ca458 Update coreutils, remove sys:memory 2016-12-28 17:22:10 -07:00
Jeremy Soller aebe7152ce Add memory scheme to live configuration 2016-12-28 12:42:54 -07:00
Jeremy Soller eb3f76f204 Add memory scheme, implement fstatvfs 2016-12-28 11:38:42 -07:00
Jeremy Soller 164648c200 Compile using real libstd, with no crate overrides 2016-12-27 16:47:08 -07:00
Jeremy Soller 515aa3671b Implement dup2. Add debugging lines. 2016-12-27 11:18:41 -07:00
Jeremy Soller 6c308ada46 Workaround for an issue where a leftover grant is not unmapped before reap 2016-12-13 20:41:43 -07:00
Jeremy Soller 4b5271b52b Remove debug message 2016-12-06 15:27:49 -07:00
Jeremy Soller a46a68b5c7 Use isohybrid to generate a USB stick friendly ISO
Add assertions to verify that grants are unmapped
Fix grant unmapping in exec and exit, thus fixing some crashes without network cards
2016-12-06 14:47:05 -07:00
Jeremy Soller 528ce22617 More path cleanup 2016-11-29 18:15:53 -07:00
Jeremy Soller ddac22a242 Cleanup path usage 2016-11-29 18:14:10 -07:00
Jeremy Soller cc9fd700cf Update to make libstd use redox_syscall 2016-11-28 18:14:21 -07:00
Jeremy Soller 2b302bd6ea Implement O_DIRECTORY, switch to open for mkdir 2016-11-25 18:24:38 -07:00
Jeremy Soller bbe2dd0ff4 Implement rfc 4 2016-11-25 12:09:54 -07:00
Jeremy Soller 5ef013eecf Fix warnings, increase size of fs 2016-11-19 20:23:25 -07:00
Jeremy Soller b17444e3ce Allow compiling both livedisk and harddrive 2016-11-19 20:19:41 -07:00
Jeremy Soller 6b084d3ff5 Allow initfs to be written 2016-11-18 08:46:11 -07:00
Jeremy Soller 71fbf2e8f4 Add statvfs 2016-11-18 08:44:03 -07:00
Jeremy Soller f2e15b81bd Update orbutils, fix warnings 2016-11-17 14:23:41 -07:00
Jeremy Soller a5f95cd2b1 Replace setuid, setgid with setreuid, setregid 2016-11-17 14:16:39 -07:00
Jeremy Soller 1fe0dae848 Cleanup zombies in container - show scheme namespace in context list 2016-11-17 12:24:46 -07:00
Jeremy Soller 93d43f7dbc Add signal support - exit on signal 2016-11-17 12:12:02 -07:00
Jeremy Soller 3da2ea9d9a More advanced setns syscall 2016-11-16 22:14:02 -07:00
Jeremy Soller c290fd78db Add ability to contain a process in a scheme sandbox 2016-11-16 20:54:38 -07:00
Jeremy Soller 0dd2befe4d Pass through fcntl 2016-11-15 17:09:28 -07:00
Jeremy Soller a9c7a4e773 Update to add chmod 2016-11-15 17:08:14 -07:00
Jeremy Soller 3e5a43d47d Update syscall and rust, add fcntl for permissions 2016-11-15 16:12:51 -07:00
Jeremy Soller 3363859cb7 FileHandle from in exec close 2016-11-15 14:09:08 -07:00
Jeremy Soller 7c35351dc2 Merge branch 'cap2' of https://github.com/Yoric/redox into Yoric-cap2 2016-11-15 14:05:43 -07:00
Jeremy Soller 41f8e349af Pass clone and exec to dup to identify dup location, make exec dup to implement cloexec 2016-11-14 20:55:31 -07:00
Jeremy Soller 7a241b28bf Add sys:exe to get current executable 2016-11-14 20:54:33 -07:00
Jeremy Soller 3469310a19 Add fcntl 2016-11-14 12:15:34 -07:00
Jeremy Soller a7bfe1232a Implement more test arch features 2016-11-14 11:04:31 -07:00
Jeremy Soller c3f38be7ca Use core intrinsics instead of memset 2016-11-14 10:50:00 -07:00
David Teller 53c2c7a332 Converting file handles into a new type FileHandle
Keeping file handles (and pids, and scheme id, ...) as usize is a
footgun. Let's remove it.
2016-11-14 07:46:43 +01:00
David Teller 008ca3c207 Converting pids into a new type ContextId
Keeping pid (and file descriptor, and scheme id, ...) as usize is a
footgun. Let's remove it.
2016-11-14 07:46:43 +01:00
David Teller 3aa2f2d0c4 Converting scheme ids into a new type SchemeId
Keeping scheme ids (and pids, and file handles, ...) as usize is a
footgun. Let's remove it.
2016-11-14 07:46:43 +01:00
David Teller c7735dd177 Introducing macros for defining SchemeId, Pid, ... 2016-11-14 07:46:43 +01:00
Jeremy Soller 99a15e791d Get CPU features 2016-11-07 13:56:02 -07:00
Jeremy Soller 25988d6b71 Add memory information 2016-11-07 12:47:32 -07:00
Jeremy Soller e3f7c9a692 Update scheme documentation 2016-11-04 13:38:40 -06:00
Jeremy Soller 194b674155 Add some documentation 2016-11-03 20:29:19 -06:00
Jeremy Soller e9ae9b190c Fix eventing in kernel 2016-11-03 16:02:44 -06:00
David Teller dcf0a21da2 Improving self-documentation of the implementation of Registry. (#732) 2016-11-03 09:06:44 -06:00
pythoneer 6b8b7c03ab increase process id range (#729) 2016-11-03 07:36:12 -06:00
Jeremy Soller 3fc5e52c64 Remove resource_sceme, Fix syscall crate name, add fmap 2016-11-02 19:48:25 -06:00
Jeremy Soller 190ccc2ef1 Fix #725 by checking mode in chdir 2016-11-01 14:49:51 -06:00
Jeremy Soller fb20ed5436 Add contributing and readme 2016-11-01 12:04:50 -06:00
Jeremy Soller dc53add6a9 Correct init process, allow waiting on any children, reap zombies in init 2016-11-01 11:04:53 -06:00
Jeremy Soller a33ddef38f remove take message 2016-10-31 22:12:10 -06:00
Jeremy Soller 7952e3ed63 Add null: and zero: 2016-10-31 21:54:56 -06:00
Jeremy Soller aad20b0e8b Remove debugging 2016-10-31 19:40:27 -06:00
Jeremy Soller fd71b5e3f1 Fixes for TLS 2016-10-31 19:09:22 -06:00
Jeremy Soller b98a814dfc Remove rd/wrfsbase 2016-10-31 18:04:28 -06:00
Jeremy Soller ed9c2b9d6c Smp (#23)
* Fire up multiple processors

* Use IPIs to wake up secondary processors

* Much better exception information

* Modifications to show more information on fault

* WIP: Use real libstd

* Add TLS (not complete)

* Add random function, export getpid, cleanup

* Do not spin APs until new context

* Update rust

* Update rust

* Use rd/wrfsbase

* Implement TLS

* Implement compiler builtins and update rust

* Update rust

* Back to Redox libstd

* Update rust
2016-10-31 10:49:00 -06:00
Jeremy Soller 1a1fb1f5e1 Redo networking (#22)
* Rewriting network functions

* Add buffer to dup
Fix non-blocking handling by triggering once on enabling events to read to EOF

* Modifications for UDP API

* Implement TCP client side

* Add active close

* Add DMAR parser

* Implement basic TCP listening. Need to improve the state machine

* Reduce debugging

* Fixes for close procedure

* Updates to fix path processing in libstd
2016-10-26 13:19:56 -06:00
David Teller 580f30e520 Documenting use of enable_and_halt(). (#21) 2016-10-24 16:03:03 -06:00
Jeremy Soller e7a4b786b0 Add CPU ID lock 2016-10-23 11:24:10 -06:00
Jeremy Soller c680f2531e Make all perCPU mappings available in all contexts - this will allow APs to pick up threads 2016-10-23 09:13:12 -06:00
Jeremy Soller ad152ad968 Remove unnecessary context switch in waitpid 2016-10-20 21:50:11 -06:00
Jeremy Soller a97aa95c23 Improve wait condition performance 2016-10-20 21:49:47 -06:00
Jeremy Soller 962836aa47 Do not block on IRQ read, add more debugging to RTL8168/9 2016-10-20 15:49:17 -06:00
Jeremy Soller 9c3a06b8f9 Add nonblocking root scheme 2016-10-20 12:31:39 -06:00
Jeremy Soller 71ff7af970 Send multiple events if there are multiple packets 2016-10-14 22:06:43 -06:00
Jeremy Soller 99fee86ef9 Significant improvements for events - switch to event queue in orbital 2016-10-14 20:12:21 -06:00
Jeremy Soller bc72488851 Allow O_NONBLOCK to be passed to pipe 2016-10-14 19:34:00 -06:00
Jeremy Soller f852450610 Add specification to vesad
Fix piping
Fix bug where resources are not closed
Add arpd
Remove question_mark features
2016-10-14 18:22:57 -06:00
Jeremy Soller 92b4514895 Fixes for updating submodules 2016-10-14 12:00:25 -06:00
Jeremy Soller c294b5b92c Disable orbital by default 2016-10-13 21:19:02 -06:00
Jeremy Soller 2fc605a88d Allow schemes to be listed 2016-10-13 21:13:37 -06:00
Jeremy Soller c484241e1c Add sys scheme to allow inspection of processes. WIP: Signals. 2016-10-13 21:00:51 -06:00
Jeremy Soller d778f0b040 Orbital (#16)
* Port previous ethernet scheme

* Add ipd

* Fix initfs rebuilds, use QEMU user networking addresses in ipd

* Add tcp/udp, netutils, dns, and network config

* Add fsync to network driver

* Add dns, router, subnet by default

* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks

* Add orbital server, WIP

* Add futex

* Add orbutils and orbital

* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad

* Add orbital assets

* Update orbital

* Update to add login manager

* Add blocking primitives, block for most things except waitpid, update orbital

* Wait in waitpid and IRQ, improvements for other waits

* Fevent in root scheme

* WIP: Switch to using fevent

* Reorganize

* Event based e1000d driver

* Superuser-only access to some network schemes, display, and disk

* Superuser root and irq schemes

* Fix orbital
2016-10-13 17:21:42 -06:00
Jeremy Soller 7841f3617a Time (#11)
* WIP: Time syscalls

* Count time from PIT using low tickrate

* Implement realtime

* Implement nanosleep with a tight loop
2016-10-06 20:50:14 -06:00
Jeremy Soller 7a96e6c9be Add pipe2 2016-10-06 18:46:24 -06:00
Jeremy Soller df87992af4 Add sudo command, add effective UID and GID, and groups file 2016-10-05 20:31:59 -06:00
Jeremy Soller 965941cd1c Implement unix permissions 2016-10-05 18:01:05 -06:00
Jeremy Soller ea4fa78f72 Merge branch 'encoded_syscall' 2016-10-05 15:43:35 -06:00
Jeremy Soller 82d2c49543 Add permissions to the filesystem, preliminary permissions to the syscalls 2016-10-05 14:24:08 -06:00
Jeremy Soller 4f73b7b5a5 Implement vfork 2016-09-28 21:33:54 -06:00
Jeremy Soller fc5a35d22a 64-bit stat size, read entire executable in one go 2016-09-28 20:42:03 -06:00
Jeremy Soller bfaa564afd Fix CWD without trainling slash 2016-09-28 11:52:29 -06:00
Jeremy Soller d50a1485a7 mkdir and rmdir 2016-09-28 11:26:49 -06:00
Jeremy Soller af5b43ca0b Fix dup 2016-09-28 11:22:01 -06:00
Jeremy Soller 62d151c9e8 Unlink syscall 2016-09-28 11:18:28 -06:00
Jeremy Soller f79570d42f Fix kernel user scheme fpath 2016-09-28 10:29:17 -06:00
Jeremy Soller 2c9a953295 Remove unnecessary slash 2016-09-26 17:39:58 -06:00
Jeremy Soller bc4f29d3c8 WIP: AHCI drivers and more memory syscalls 2016-09-26 17:00:06 -06:00
Jeremy Soller 5877c8ac16 Encode many of the file syscalls 2016-09-25 11:20:59 -06:00
Jeremy Soller 1e2e5a5d31 Event support - demonstration in example scheme 2016-09-23 17:54:39 -06:00
Jeremy Soller e390c2d00c WIP: Kevent 2016-09-23 15:47:53 -06:00
Jeremy Soller 3034daac31 Add env 2016-09-23 11:01:53 -06:00
Jeremy Soller 750a2c1f9d Fix path lookup 2016-09-22 21:27:33 -06:00
Jeremy Soller 879d582e44 Implement fpath in initfs 2016-09-22 21:13:17 -06:00
Jeremy Soller bbacabce4f Trim in env scheme, do not debug initfs 2016-09-22 20:49:28 -06:00
Jeremy Soller 733a812259 Folders in initfs 2016-09-22 20:26:33 -06:00
Jeremy Soller fcc701cf66 Bring in some coreutils 2016-09-22 19:38:09 -06:00
Jeremy Soller 35ad65bbda Enable SSE and FPU 2016-09-22 16:14:45 -06:00
Jeremy Soller 2e9697353c Add wnohang, make PS/2 driver write input to display scheme, which then passes it to the shell 2016-09-22 10:10:27 -06:00
Jeremy Soller 57b50ba819 Add login process. Remove debugging. Fix order of arguments 2016-09-22 08:43:22 -06:00
Jeremy Soller 10a6e148f0 WIP: Userspace console 2016-09-21 12:18:48 -06:00
Jeremy Soller ec240ef778 Clone grants 2016-09-20 22:14:08 -06:00
Jeremy Soller b01eb8e47b WIP: VESA driver. Make initfs generated by code 2016-09-20 21:52:45 -06:00
Jeremy Soller 2b6fae0138 Validate memory pointers 2016-09-20 18:03:14 -06:00
Jeremy Soller e2ec6fd220 Implement more system calls 2016-09-20 16:57:45 -06:00
Jeremy Soller 4ee9a6b492 Create example userspace scheme. Remove kernel duplication of syscalls, use syscall crate instead 2016-09-20 16:23:28 -06:00
Jeremy Soller 3ae7dc8d98 Grant to allow passing data to scheme handler 2016-09-20 14:50:04 -06:00
Jeremy Soller 863c59d3c2 Increase buffer size when reading executable, update libstd 2016-09-20 09:51:26 -06:00
Jeremy Soller eeb1cd0a52 Fix deadlock 2016-09-20 09:21:54 -06:00
Jeremy Soller 7a5d9d440c Implement user schemes. Example in pcid. Currently deadlocks in UserInner 2016-09-20 08:47:16 -06:00
Jeremy Soller 2f06e18743 WIP: User scheme 2016-09-19 21:24:54 -06:00
Jeremy Soller fcbc8951da Minimize locking in schemes. Reenable pcid and ion launch in init. WIP: Userspace schemes 2016-09-19 18:29:28 -06:00
Jeremy Soller fe234e4bf1 Remove warnings 2016-09-19 17:28:22 -06:00
Jeremy Soller 5276c76963 PS/2 driver convert to char 2016-09-19 10:24:19 -06:00
Jeremy Soller 298d999300 Seperate PS/2 keyboard and mouse driver 2016-09-19 09:43:30 -06:00
Jeremy Soller 4403e3e7ac Allow userspace to handle IRQs (WIP). Create basic keyboard handler 2016-09-18 20:17:08 -06:00
Jeremy Soller de53701ed9 Add mechanism to read IRQ count 2016-09-18 18:59:46 -06:00
Jeremy Soller af2f6fc6df Add fsync. Add env scheme, currently hardcoded to get ion to launch. Make serial IRQ send data to debug scheme 2016-09-18 17:55:35 -06:00
Jeremy Soller 8ba97b8cff Canonicalize paths in open 2016-09-18 12:54:10 -06:00
Jeremy Soller 4821357934 Complete execve - add argument support using safe ABI 2016-09-17 21:44:50 -06:00
Jeremy Soller 75016bfe39 Update libstd. Add CWD and associated syscalls. Remove debugging 2016-09-17 19:01:34 -06:00
Jeremy Soller c5afb10b00 Add exit status to status enum 2016-09-17 09:23:36 -06:00
Jeremy Soller 959ecdad04 Fix creation of kstack 2016-09-17 09:18:35 -06:00
Jeremy Soller 9bc242c179 Implement the typical use of waitpid 2016-09-16 18:50:47 -06:00
Jeremy Soller 5f570fa5b4 Allow cloning of files and memory 2016-09-16 18:27:54 -06:00
Jeremy Soller 91fc7c96ab work on shared memory accross threads 2016-09-16 17:51:27 -06:00
Jeremy Soller 236b2f0e04 Panic upon use of unsupported flags 2016-09-16 13:45:00 -06:00
Jeremy Soller 356ba325ea Collapse status of context into one status variable 2016-09-16 11:10:53 -06:00
Jeremy Soller 0f27cd24ce Organize context module 2016-09-16 10:44:52 -06:00
Jeremy Soller 5cbd30988c Do not have interrupts enabled during context switch 2016-09-15 08:40:16 -06:00
Jeremy Soller dee5b4dd9e Remove debugging 2016-09-15 08:39:20 -06:00
Jeremy Soller 1711303ef8 Fix implementation of clone and exec. Now the init process can load and execute the pci driver 2016-09-15 08:35:07 -06:00
Jeremy Soller 8607367058 WIP: Create new page table for clone 2016-09-14 22:21:52 -06:00
Jeremy Soller 1acb84afbb Higher-half kernel mapping. Unmap where possible, freeing up lower memory 2016-09-14 20:47:55 -06:00
Jeremy Soller 932026fed8 WIP: Copy usermode stack 2016-09-13 21:27:27 -06:00
Jeremy Soller b042f40847 Fix userspace clone by clobbering all variables on clone 2016-09-13 20:31:45 -06:00
Jeremy Soller d3ace7dcad Allow cloning of kernel threads. Userspace breaks potentially due to stack aliasing 2016-09-13 20:06:39 -06:00
Jeremy Soller d1c0e3b5da Use flush_all instead of flush for performance 2016-09-13 11:20:55 -06:00
Jeremy Soller efaeb22163 Map kernel TLS to general area 2016-09-12 15:02:03 -06:00
Jeremy Soller d4ca131391 cr3 in context 2016-09-12 12:21:34 -06:00
Jeremy Soller 70bf79a977 Implement exit, partly 2016-09-11 22:03:03 -06:00
Jeremy Soller 0bb1ad38c9 Clear memory on demand 2016-09-11 21:47:44 -06:00
Jeremy Soller db3255dd82 Add comments 2016-09-11 21:35:02 -06:00
Jeremy Soller 011c8f7f2b Cleanup heap management 2016-09-11 21:18:18 -06:00
Jeremy Soller efd41a857e Store context memory information 2016-09-11 21:04:34 -06:00
Jeremy Soller 86597331cc Allow exec, emulate clone by pretending to be child 2016-09-11 18:03:10 -06:00
Jeremy Soller cf27b3a3ad Fix close, add dup 2016-09-11 17:31:21 -06:00
Jeremy Soller 7a928a5f97 Improve init process, debug missing syscalls, fix error codes in syscall return 2016-09-11 16:48:58 -06:00
Jeremy Soller 038cf5aba1 PCI driver WIP 2016-09-11 15:56:48 -06:00
Jeremy Soller 9371120f0f Flush TLB correctly when remapping
Seperate mouse and keyboard structs in PS/2 driver
2016-09-11 15:02:35 -06:00
Jeremy Soller 9b17495dd6 Implement exec
Implement brk
2016-09-10 22:06:09 -06:00
Jeremy Soller 4692e9b267 Load init from initfs 2016-09-10 19:42:26 -06:00
Jeremy Soller c30f4208d4 Implement sched_yield, enable interrupts in userspace 2016-09-10 19:18:59 -06:00
Jeremy Soller 486bfea62c Remove debugging messages, launch elf on APs 2016-09-10 19:03:31 -06:00
Jeremy Soller 0d115508be Seperate kernel and userspace targets 2016-09-09 19:08:04 -06:00
Jeremy Soller 531497d7af Remove debug warnings 2016-09-09 17:30:22 -06:00
Jeremy Soller 3837b2606f Connect schemes so that they can be used 2016-09-08 20:06:33 -06:00
Jeremy Soller 7036ed4c63 Cleanup to use question mark 2016-09-08 19:31:26 -06:00
Jeremy Soller ef9a7c0988 Add syscall library, make init program Rust 2016-09-08 19:10:50 -06:00
Jeremy Soller 44e57773a3 Debug reads writes better, set up stdio for BSP 2016-09-07 21:32:09 -06:00
Jeremy Soller 7c0b17d070 Load a very simple ELF and launch it in usermode 2016-09-07 21:16:30 -06:00
Jeremy Soller 4b98fb8ca3 Improve efficiency of kernel console 2016-09-01 14:39:45 -06:00
Jeremy Soller 5c91017579 Draw on VESA for console using ransid 2016-09-01 11:51:33 -06:00
Jeremy Soller ac9a475ef5 Warnings removal 2016-09-01 11:14:47 -06:00
Jeremy Soller 6269f68b03 Fill in all exception and IRQ entries. Handle PIT, keyboard IRQs 2016-08-31 17:45:21 -06:00
ticki b8f1971329 Merge branch 'master' of github.com:redox-os/kernel 2016-08-31 17:02:47 +02:00
ticki 4966842d72 Add the Fd definition file.
Damn, I forgot to `git add` it.
2016-08-31 17:01:08 +02:00
Jeremy Soller 8c0191564f Add file descriptor type 2016-08-30 16:27:10 -06:00
Jeremy Soller 2ccc13d212 Merge branch 'master' of https://github.com/redox-os/kernel 2016-08-30 16:23:56 -06:00
Jeremy Soller 9bddf55e93 Improvements for context switching 2016-08-30 16:23:51 -06:00
ticki 9ca3559cc8 Newtype file descriptors.
To avoid various bugs regarding the typing of file descriptors, we
newtype them into a simple wrapper type.

- Document some stuff.
2016-08-29 11:58:31 +02:00
Jeremy Soller f2d2b233f3 Simple, unsafe context switch 2016-08-28 18:38:53 -06:00
Jeremy Soller 5c2b6878a6 Arm! 2016-08-25 17:03:01 -06:00
Jeremy Soller 24bfb2c81f Fix the build. Sorry 2016-08-24 19:30:14 -06:00
Jeremy Soller 84873532af Arch context in kernel context 2016-08-24 10:35:42 -06:00
Jeremy Soller aecfa50029 Initialize contexts, add getpid 2016-08-20 14:32:45 -06:00
Jeremy Soller 47280a921a Context list class, static context ID magic 2016-08-20 13:43:35 -06:00
Jeremy Soller 645524fdf5 Setup independent page tables, map heap to a single location 2016-08-19 14:53:16 -06:00
Jeremy Soller 74b40f0a25 Switch to goblin as executable parser 2016-08-19 07:57:24 -06:00
Jeremy Soller b46c7e71c0 Add syscall handler, still work in progress
Add elf files
2016-08-18 19:44:31 -06:00
Jeremy Soller 954af453dc Remove clone from context 2016-08-18 09:02:31 -06:00
Jeremy Soller 8fc113adef Refactor context list 2016-08-18 08:30:45 -06:00
Jeremy Soller 0bd1cda1b6 Cleanup schemes list, remove lazy_static 2016-08-18 08:10:08 -06:00
Jeremy Soller b9e721d4e1 Print out more useful information about AP and BSP, create kmain_ap 2016-08-17 19:38:04 -06:00
Jeremy Soller 996996b0a9 Keep track of AP count, allocate bigger AP stack, stack trace function 2016-08-17 19:34:33 -06:00
Jeremy Soller 1993e701dd Remove warnings 2016-08-17 16:54:48 -06:00
Jeremy Soller 9f79abe542 Lazy static init of schemes 2016-08-16 11:04:14 -06:00
Jeremy Soller 26397084f6 Cleanup, use spinlock for allocator 2016-08-15 15:01:24 -06:00
Jeremy Soller e0daabde05 GDT and IDT in kernel space
Paging constructs completed, remap kernel before jumping to kmain
Panic will do a stack trace
Remove SSE from none target
2016-08-15 14:34:20 -06:00
Jeremy Soller 7da6696a34 Add simple paging, use rust libcore and compile without sse 2016-08-15 11:30:14 -06:00
Jeremy Soller 74ccbaa4a6 Bump allocator 2016-08-14 22:05:32 -06:00
Jeremy Soller 38f1a4fb76 WIP: Schemes 2016-08-14 21:38:32 -06:00
Jeremy Soller 946fd79e83 Test for BadFile 2016-08-14 19:17:55 -06:00
Jeremy Soller dd280a5d1a Add stdout/stderr tests 2016-08-14 18:22:50 -06:00
Jeremy Soller f79d6ce12b Add context and file structs 2016-08-14 18:16:56 -06:00
Jeremy Soller 04a6a45fac WIP: Exec 2016-08-14 16:07:41 -06:00
Jeremy Soller 6cfa38c5ba Add syscall module 2016-08-14 15:58:35 -06:00
Jeremy Soller 621de7fa8a Add test architecture 2016-08-14 14:59:18 -06:00
ticki 916a87fb33 Merge branch 'master' of github.com:redox-os/kernel 2016-08-14 20:55:19 +02:00
ticki 2b50588c29 Interrupt tables.
We add lookup table for interrupt descriptions containing information
about the CPU exceptions etc.
2016-08-14 20:54:23 +02:00
Jeremy Soller faa2b3ac63 Add comment 2016-08-14 12:11:53 -06:00
Jeremy Soller 4cb9df8fa8 Move arch to seperate crate 2016-08-14 11:45:47 -06:00
ticki fb99ec7e6d Strongly typed virtual/physical memory seperation.
This minicommit introduces two newtpyes, `Physical` and `Virtual`,
respectively. These serves as a way to segregate the different forms of
addresses to avoid the issues we had in the old kernel.
2016-08-14 19:21:21 +02:00
ticki b2fe1799fd Rename the src directory to kernel. 2016-08-14 18:42:32 +02:00
279 changed files with 41633 additions and 13787 deletions
+5
View File
@@ -0,0 +1,5 @@
[build]
rustflags = [
# Kernel should preserve floating-point registers
"-Ctarget-feature=-sse,-sse2",
]
+2 -3
View File
@@ -1,4 +1,3 @@
target target
image.bin /config.toml
image .gitlab-ci-local/
image*
+74 -15
View File
@@ -1,31 +1,90 @@
image: "redoxos/redoxer" image: "redoxos/redoxer:latest"
variables:
GIT_SUBMODULE_STRATEGY: recursive
workflow: workflow:
rules: rules:
- if: '$CI_COMMIT_BRANCH == "master" && $CI_PROJECT_NAMESPACE == "redox-os"' - if: '$CI_PROJECT_NAMESPACE == "redox-os"'
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"' - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
stages: stages:
- build - build
- cross-build
- test - test
- other-features
# TODO: benchmarks and profiling (maybe manually enabled for relevant MRs)?
build:linux: x86_64:
stage: build stage: build
script: cargo +nightly build --verbose script:
- mkdir -p target/${ARCH}
- redoxer env make BUILD=target/${ARCH}
variables:
ARCH: "x86_64"
build:redox: aarch64:
stage: cross-build
image: "redoxos/redoxer:aarch64"
script:
- mkdir -p target/${ARCH}
- redoxer env make BUILD=target/${ARCH}
variables:
ARCH: "aarch64"
i586:
stage: cross-build
script:
- mkdir -p target/${ARCH}
- TARGET=${ARCH}-unknown-redox redoxer env make BUILD=target/${ARCH}
variables:
ARCH: "i586"
riscv64gc:
stage: cross-build
script:
- mkdir -p target/${ARCH}
- TARGET=${ARCH}-unknown-redox redoxer env make BUILD=target/${ARCH}
variables:
ARCH: "riscv64gc"
fmt:
stage: build stage: build
script: redoxer build --verbose script:
- rustup component add rustfmt
- rustfmt --check
test:linux: x86_64:boot:
stage: test stage: test
dependencies: needs: [x86_64]
- build:linux script:
script: cargo +nightly test --verbose - mkdir -p target/${ARCH}
- export COOKBOOK_SOURCE_IDENT=$CI_COMMIT_SHA
- redoxer env make BUILD=target/${ARCH}
- timeout -s KILL 9m redoxer exec --folder target/${ARCH}/:/usr/lib/boot uname -a
variables:
ARCH: "x86_64"
test:redox: x86_64:relibc:
stage: test stage: test
dependencies: needs: [x86_64]
- build:redox script:
# only run integration test as without KVM unit tests is super slow - redoxer pkg relibc-tests-bins
script: redoxer test --verbose -- --test '*' -- --nocapture - export COOKBOOK_SOURCE_IDENT=$CI_COMMIT_SHA
- mkdir -p target/${TARGET}/sysroot/{usr/lib/boot,root} target/${TARGET}/root
- redoxer env make BUILD=target/${TARGET}/sysroot/usr/lib/boot
- (cd target/${TARGET}/sysroot && mv home/user/relibc-tests/* root/)
- timeout -s KILL 9m redoxer exec --folder target/${TARGET}/sysroot/:/ make run
# It is fine if failing sometimes
allow_failure: true
variables:
TARGET: "x86_64-unknown-redox"
profiling-compile:
stage: other-features
allow_failure: true
script:
make check
variables:
ARCH: "x86_64"
KERNEL_CHECK_FEATURES: profiling
+4
View File
@@ -0,0 +1,4 @@
[submodule "redox-path"]
path = redox-path
url = https://gitlab.redox-os.org/redox-os/redox-path.git
branch = main
+2
View File
@@ -0,0 +1,2 @@
[editor]
auto-format = false
+13
View File
@@ -0,0 +1,13 @@
[[language]]
name = "rust"
[[language-server.rust-analyzer.config.cargo]]
extraEnv = ["RUST_TARGET_PATH=targets"]
# Select one of targets to make lsp work for your confguration
# Do not commit this change
# TODO: find a better way to do this
# target = "aarch64-unknown-kernel"
[[language-server.rust-analyzer.config.check]]
targets = ["x86_64-unknown-kernel", "i686-unknown-kernel", "aarch64-unknown-kernel"]
-21
View File
@@ -1,21 +0,0 @@
sudo: required
language: rust
rust:
- nightly
os:
- linux
- osx
dist: trusty
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
sudo apt-get install -qq pkg-config fuse libfuse-dev;
sudo modprobe fuse;
sudo chmod 666 /dev/fuse;
sudo chown root:$USER /etc/fuse.conf;
fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then
brew update;
brew install Caskroom/cask/osxfuse;
fi
notifications:
email: false
+79
View File
@@ -0,0 +1,79 @@
# Porting the core Redox kernel to arm AArch64: An outline
## Intro
This document is [my](https://github.com/raw-bin) attempt at:
* Capturing thinking on the work needed for a core Redox kernel port
* Sharing progress with the community as things evolve
* Creating a template that can be used for ports to other architectures
Core Redox kernel means everything needed to get to a non-graphical console-only multi-user shell.
Only the 64-bit execution state (AArch64) with the 64-bit instruction set architecture (A64) shall be supported for the moment. For more background/context read [this](https://developer.arm.com/products/architecture/a-profile/docs/den0024/latest/introduction).
This document is intended to be kept *live*. It will be updated to reflect the current state of work and any feedback received.
It is hard~futile to come up with a strict sequence of work for such ports but this document is a reasonable template to follow.
## Intended target platform
The primary focus is on [qemu's virt machine platform emulation for the AArch64 architecture](https://github.com/qemu/qemu/blob/master/hw/arm/virt.c#L127).
Targeting a virtual platform is a convenient way to bring up the mechanics of architectural support and makes the jump to silicon easier. The preferred boot chain for AArch64 (explained later) is well supported on this platform and boot-over-tftp from localhost makes the debug cycle very efficient.
Once the core kernel port is complete a similar follow on document will be created that is dedicated to silicon bring-up.
## Boot protocol elements
| Item | Notes |
|------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Linux kernel boot protocol for AArch64](https://www.kernel.org/doc/Documentation/arm64/booting.txt) | The linked document describes assumptions made from the bootloader which are field tested and worthwhile to have for Redox an AArch64. <br/> The intent is to consider most of the document except anything tied to the Linux kernel itself. |
| [Flattened Device Tree](https://elinux.org/Device_Tree_Reference) | FDT binary blobs supplied by the bootloader shall provide the Redox kernel with misc platform \{memory, interrupt, devicemem} maps. Qemu's virt machine platform synthetically creates an FDT blob at a specific address which is very handy. |
## Boot flow elements
The following table lists the boot flow in order.
| Item | Notes |
|-------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [ARM Trusted Firmware (TF-A)](https://github.com/ARM-software/arm-trusted-firmware) | TF-A is a de-facto standard reference firmware implementation and proven in the field. <br/> TF-A runs post power-on on Armv8-A implementations and eventually hands off to further stages of the boot flow.<br />For qemu's virt machine platform, it is essentially absent but I mean to rely on it heavily for silicon bring up hence mentioning it here. |
| [u-boot](https://www.denx.de/wiki/U-Boot) | u-boot will handle early console access, media access for fetching redox kernel images from non-volatile storage/misc disk subsystems/off the network. <br /> u-boot supports loading EFI applications. If EFI support to AArch64 Redox is added in the future that should essentially work out of the box. <br /> u-boot will load redox and FDT binary blobs into RAM and jump to the redox kernel. |
| Redox early-init stub | For AArch64, the redox kernel will contain an A64 assembly stub that will setup the MMU from scratch. This is akin to the [x86_64 redox bootloader](https://github.com/redox-os/bootloader/blob/master/x86_64/startup-x86_64.asm). <br /> This stub sets up identity maps for MMU initialization, maps the kernel image itself as well as the device memory for the UART console. At present this stub shall be a part of the kernel itself for simplicity. |
| Redox kstart entry | The early init stub hands off here. kstart will then re-init the MMU more comprehensively. |
## Supported devices
The following devices shall be supported. All necessary information specific to these devices will be provided to the redox kernel by the platform specific FDT binary blob.
| Device | Notes |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Generic Interrupt Controller v2](https://developer.arm.com/products/architecture/a-profile/docs/ihi0048/b/arm-generic-interrupt-controller-architecture-version-20-architecture-specification) | The GIC is an Arm-v8A architectural element and is supported by all architecturally compliant processor implementations. GICv2 is supported by qemu's virt machine emulation and most subsequent GIC implementations are backward compatible to GICv2. |
| [Generic Timer](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500d/BGBBIJCB.html) | The Generic Timer Architecture is an Arm-v8A architectural element and is implemented by all compliant processor implementations. It is supported by qemu. |
| [PrimeCell UART PL011](http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf) | The PL011 UART is supported by qemu and most ARM systems. |
## Intended development sequence and status
| Item | Description | Status | Notes |
|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------|
| Redox AArch64 toolchain | Create an usable redox AArch64 toolchain specification | Done | Using this JSON spec in isolated tests produces valid AArch64 soft float code |
| Stubbed kernel image | Stub out AArch64 kernel support using the existing x86_64 arch code as a template <br /> Modify redox kernel build glue and work iteratively to get a linkable (non-functional) image | Not done yet | |
| Boot flow | Create a self hosted u-boot -> redox kernel workflow <br /> Should obtain the stubbed image from a local TFTP server, load it into RAM and jump to it | Not done yet | |
| GDB Debug flow | Create a debug workflow centered around qemu's GDB stub <br /> This should allow connecting to qemu's GDB stub and debug u-boot/redox stub via a GDB client and single stepping through code | Not done yet | |
| Verify Redox entry | Verify that control reaches the redox kernel from u-boot | Not done yet | |
| AArch64 early init stub | Add support for raw asm code for early AArch64 init in the redox kernel <br /> Verify that this code is located appropriately in the link map and that control reaches this code from u-boot | Not done yet | |
| Basic DTB support | Integrate the [device_tree crate](https://mbr.github.io/device_tree-rs/device_tree/) <br /> Use the crate to access the qemu supplied DTB image and extract the memory map | Not done yet | |
| Basic UART support | Use the device_tree crate to get the UART address from the DTB image and set up the initial console <br /> This is a polling mode only setup | Not done yet | |
| Initial MMU support | Implement initial MMU support in the early init stub <br /> This forces the MMU into a clean state overriding any bootloader specific setup <br /> Create an identity map for MMU init <br /> Create a mapping for the kernel image <br /> Create a mapping for any devices needed at this stage (UART) | Not done yet | |
| kmain entry | Verify that kmain entry works post early MMU init | Not done yet | |
| Basic Redox MMU support | Get Redox to create a final set of mappings for everything <br /> Verify that this works as expected | Not done yet | |
| Basic libc support | Flesh out a basic set of libc calls as required for simple user-land apps | Not done yet | |
| userspace_init entry | Verify user-space entry and /sbin/init invocation | Not done yet | |
| Basic Interrupt controller support | Add a GIC driver <br /> Verify functionality | Not done yet | |
| Basic Timer support | Add a Generic Timer driver <br /> Verify functionality | Not done yet | |
| UART interrupt support | Add support for UART interrupts | Not done yet | |
| Task context switch support | Add context switching support <br /> Verify functionality | Not done yet | |
| Login shell | Iteratively add and verify multi-user login shell support | Not done yet | |
| Publish development branch on github | Work with the community to post work done after employer approval | Not done yet | |
| Break out the Bubbly | Drink copious quantities of alcohol to celebrate | Not done yet | |
| Silicon bring-up | Plan silicon bring-up | Not done yet | |
Generated
+193 -578
View File
@@ -3,105 +3,34 @@
version = 4 version = 4
[[package]] [[package]]
name = "aes" name = "ahash"
version = "0.8.4" version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cipher", "once_cell",
"cpufeatures", "version_check",
"zerocopy",
] ]
[[package]] [[package]]
name = "aho-corasick" name = "arrayvec"
version = "1.1.4" version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "anstream" name = "bit_field"
version = "1.0.0" version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]] [[package]]
name = "anstyle" name = "bitfield"
version = "1.0.14" version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
[[package]]
name = "anstyle-parse"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys",
]
[[package]]
name = "argon2"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73"
dependencies = [
"base64ct",
"blake2",
]
[[package]]
name = "assert_cmd"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aa3a22042e45de04255c7bf3626e239f450200fd0493c1e382263544b20aea6"
dependencies = [
"anstyle",
"bstr",
"libc",
"predicates",
"predicates-core",
"predicates-tree",
"wait-timeout",
]
[[package]]
name = "base64ct"
version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
@@ -116,40 +45,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
[[package]] [[package]]
name = "blake2" name = "cc"
version = "0.10.6" version = "1.2.66"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" checksum = "f5d6cac793997bd970000024b2934968efe83b382de4fdcf4fcb46b6ee4ad996"
dependencies = [ dependencies = [
"digest", "find-msvc-tools",
"shlex",
] ]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bstr"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79"
dependencies = [
"memchr",
"regex-automata",
"serde_core",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.4" version = "1.0.4"
@@ -157,252 +61,89 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]] [[package]]
name = "cfg_aliases" name = "equivalent"
version = "0.2.1" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]] [[package]]
name = "cipher" name = "fdt"
version = "0.4.4" version = "0.2.0-alpha1"
source = "git+https://github.com/repnop/fdt.git?rev=2fb1409edd1877c714a0aa36b6a7c5351004be54#2fb1409edd1877c714a0aa36b6a7c5351004be54"
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [ dependencies = [
"crypto-common", "ahash",
"inout",
] ]
[[package]] [[package]]
name = "colorchoice" name = "hashbrown"
version = "1.0.5" version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]] [[package]]
name = "cpufeatures" name = "indexmap"
version = "0.2.17" version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [ dependencies = [
"libc", "equivalent",
"hashbrown 0.17.1",
] ]
[[package]] [[package]]
name = "crypto-common" name = "kernel"
version = "0.1.7" version = "0.5.12+rb0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "defmt"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1"
dependencies = [
"bitflags 1.3.2",
"defmt-macros",
]
[[package]]
name = "defmt-macros"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8"
dependencies = [
"defmt-parser",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "defmt-parser"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
dependencies = [
"thiserror",
]
[[package]]
name = "difflib"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
[[package]]
name = "endian-num"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8f59926911ef34d1efb9ea1ee8ca78385df62ce700ccf2bcb149011bd226888"
[[package]]
name = "env_filter"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"jiff",
"log",
]
[[package]]
name = "fuser"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bb29a3ae32279fe3e79a958fe01899f5fb23eadccee919cf88e145b54ed9367"
dependencies = [
"libc",
"log",
"memchr",
"nix",
"page_size",
"smallvec",
"zerocopy",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "getrandom"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
dependencies = [
"cfg-if",
"libc",
"r-efi",
]
[[package]]
name = "humansize"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
dependencies = [
"libm",
]
[[package]]
name = "inout"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
dependencies = [
"generic-array",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "jiff"
version = "0.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccfe6121cbe750cf81efa362d85c0bde7ea298ec43092d3a193baca59cdbd634"
dependencies = [
"defmt",
"jiff-static",
"log",
"portable-atomic",
"portable-atomic-util",
"serde_core",
]
[[package]]
name = "jiff-static"
version = "0.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e165e897f662d428f3cd3828a919dbe067c2d42bb1031eede74ef9d27ecdedd2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "libc"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "libm"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "libredox"
version = "0.1.18+rb0.3.0"
dependencies = [ dependencies = [
"arrayvec",
"bitfield",
"bitflags 2.13.0", "bitflags 2.13.0",
"libc", "cc",
"plain", "fdt",
"hashbrown 0.14.5",
"linked_list_allocator",
"object",
"raw-cpuid",
"redox-path",
"redox_syscall", "redox_syscall",
"rmm",
"rustc-demangle",
"sbi-rt",
"slab",
"smallvec",
"spin",
"toml",
"x86",
] ]
[[package]] [[package]]
name = "log" name = "linked_list_allocator"
version = "0.4.33" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" checksum = "549ce1740e46b291953c4340adcd74c59bcf4308f4cac050fd33ba91b7168f4a"
dependencies = [
"spinning_top",
]
[[package]] [[package]]
name = "lz4_flex" name = "lock_api"
version = "0.11.6" version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "373f5eceeeab7925e0c1098212f2fbc4d416adec9d35051a6ab251e824c1854a" checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
"scopeguard",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
@@ -411,92 +152,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]] [[package]]
name = "nix" name = "object"
version = "0.29.0" version = "0.37.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
dependencies = [ dependencies = [
"bitflags 2.13.0", "memchr",
"cfg-if",
"cfg_aliases",
"libc",
] ]
[[package]] [[package]]
name = "numtoa" name = "once_cell"
version = "0.2.4" version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "page_size"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "parse-size"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b"
[[package]]
name = "plain"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
[[package]]
name = "portable-atomic"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
[[package]]
name = "portable-atomic-util"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
dependencies = [
"portable-atomic",
]
[[package]]
name = "predicates"
version = "3.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe"
dependencies = [
"anstyle",
"difflib",
"predicates-core",
]
[[package]]
name = "predicates-core"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144"
[[package]]
name = "predicates-tree"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2"
dependencies = [
"predicates-core",
"termtree",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
@@ -517,30 +185,19 @@ dependencies = [
] ]
[[package]] [[package]]
name = "r-efi" name = "raw-cpuid"
version = "6.0.0" version = "10.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
dependencies = [
[[package]] "bitflags 1.3.2",
name = "range-tree" ]
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384c2842d4e069d5ccacf5fe1dca4ef8d07a5444329715f0fc3c61813502d4d1"
[[package]] [[package]]
name = "redox-path" name = "redox-path"
version = "0.3.1" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717" checksum = "64072665120942deff5fd5425d6c1811b854f4939e7f1c01ce755f64432bbea7"
[[package]]
name = "redox-scheme"
version = "0.11.2+rb0.3.0"
dependencies = [
"libredox",
"redox_syscall",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
@@ -550,69 +207,48 @@ dependencies = [
] ]
[[package]] [[package]]
name = "redoxfs" name = "rmm"
version = "0.9.1+rb0.3.0" version = "0.1.0"
dependencies = [ dependencies = [
"aes",
"argon2",
"assert_cmd",
"base64ct",
"bitflags 2.13.0", "bitflags 2.13.0",
"endian-num",
"env_logger",
"fuser",
"getrandom 0.2.17",
"humansize",
"libc",
"libredox",
"log",
"lz4_flex",
"parse-size",
"range-tree",
"redox-path",
"redox-scheme",
"redox_syscall",
"seahash",
"termion",
"uuid",
"xts-mode",
] ]
[[package]] [[package]]
name = "regex" name = "rustc-demangle"
version = "1.12.4" version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
[[package]]
name = "sbi-rt"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fbaa69be1eedc61c426e6d489b2260482e928b465360576900d52d496a58bd0"
dependencies = [ dependencies = [
"aho-corasick", "sbi-spec",
"memchr",
"regex-automata",
"regex-syntax",
] ]
[[package]] [[package]]
name = "regex-automata" name = "sbi-spec"
version = "0.4.14" version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" checksum = "e6e36312fb5ddc10d08ecdc65187402baba4ac34585cb9d1b78522ae2358d890"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [ dependencies = [
"aho-corasick", "serde_core",
"memchr",
"regex-syntax",
] ]
[[package]]
name = "regex-syntax"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
[[package]]
name = "seahash"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]] [[package]]
name = "serde_core" name = "serde_core"
version = "1.0.228" version = "1.0.228"
@@ -633,6 +269,27 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "serde_spanned"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
dependencies = [
"serde",
]
[[package]]
name = "shlex"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[package]]
name = "slab"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.15.2" version = "1.15.2"
@@ -640,10 +297,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
[[package]] [[package]]
name = "subtle" name = "spin"
version = "2.6.1" version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "spinning_top"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
dependencies = [
"lock_api",
]
[[package]] [[package]]
name = "syn" name = "syn"
@@ -657,46 +326,45 @@ dependencies = [
] ]
[[package]] [[package]]
name = "termion" name = "toml"
version = "4.0.6" version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f44138a9ae08f0f502f24104d82517ef4da7330c35acd638f1f29d3cd5475ecb" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
dependencies = [ dependencies = [
"libc", "serde",
"numtoa", "serde_spanned",
"toml_datetime",
"toml_edit",
] ]
[[package]] [[package]]
name = "termtree" name = "toml_datetime"
version = "0.5.1" version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
[[package]]
name = "thiserror"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [ dependencies = [
"thiserror-impl", "serde",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "toml_edit"
version = "2.0.18" version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [ dependencies = [
"proc-macro2", "indexmap",
"quote", "serde",
"syn", "serde_spanned",
"toml_datetime",
"toml_write",
"winnow",
] ]
[[package]] [[package]]
name = "typenum" name = "toml_write"
version = "1.20.1" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
@@ -704,21 +372,6 @@ version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53"
dependencies = [
"getrandom 0.4.3",
]
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.5" version = "0.9.5"
@@ -726,65 +379,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "wait-timeout" name = "winnow"
version = "0.2.1" version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
dependencies = [ dependencies = [
"libc", "memchr",
] ]
[[package]] [[package]]
name = "wasi" name = "x86"
version = "0.11.1+wasi-snapshot-preview1" version = "0.47.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" checksum = "55b5be8cc34d017d8aabec95bc45a43d0f20e8b2a31a453cabc804fe996f8dca"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [ dependencies = [
"winapi-i686-pc-windows-gnu", "bit_field",
"winapi-x86_64-pc-windows-gnu", "bitflags 1.3.2",
] "raw-cpuid",
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "xts-mode"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cbddb7545ca0b9ffa7bdc653e8743303e1712687a6918ced25f2cdbed42520"
dependencies = [
"byteorder",
"cipher",
] ]
[[package]] [[package]]
@@ -806,3 +417,7 @@ dependencies = [
"quote", "quote",
"syn", "syn",
] ]
[[patch.unused]]
name = "libredox"
version = "0.1.18+rb0.3.0"
+122 -86
View File
@@ -1,101 +1,137 @@
[workspace]
resolver = "3"
members = [".", "rmm"]
[package] [package]
name = "redoxfs" name = "kernel"
description = "The Redox Filesystem" version = "0.5.12+rb0.3.0"
repository = "https://gitlab.redox-os.org/redox-os/redoxfs"
version = "0.9.1+rb0.3.0"
license-file = "LICENSE"
readme = "README.md"
authors = ["Jeremy Soller <jackpot51@gmail.com>", "vasilito <adminpupkin@gmail.com>"] authors = ["Jeremy Soller <jackpot51@gmail.com>", "vasilito <adminpupkin@gmail.com>"]
edition = "2021" build = "build.rs"
edition = "2024"
[lib] [build-dependencies]
name = "redoxfs" cc = "1.0"
path = "src/lib.rs" toml = "0.8"
[[bin]]
name = "redoxfs"
path = "src/bin/mount.rs"
doc = false
required-features = ["std"]
[[bin]]
name = "redoxfs-ar"
path = "src/bin/ar.rs"
doc = false
required-features = ["std"]
[[bin]]
name = "redoxfs-clone"
path = "src/bin/clone.rs"
doc = false
required-features = ["std"]
[[bin]]
name = "redoxfs-mkfs"
path = "src/bin/mkfs.rs"
doc = false
required-features = ["std"]
[[bin]]
name = "redoxfs-resize"
path = "src/bin/resize.rs"
doc = false
required-features = ["std"]
[dependencies] [dependencies]
aes = { version = "0.8", default-features = false } arrayvec = { version = "0.7.4", default-features = false }
argon2 = { version = "0.4", default-features = false, features = ["alloc"] } bitfield = "0.13.2"
base64ct = { version = "1", default-features = false }
bitflags = "2" bitflags = "2"
endian-num = "0.1" fdt = { git = "https://github.com/repnop/fdt.git", rev = "2fb1409edd1877c714a0aa36b6a7c5351004be54" }
env_logger = { version = "0.11", optional = true } hashbrown = { version = "0.14.3", default-features = false, features = ["ahash", "inline-more"] }
getrandom = { version = "0.2.5", optional = true } linked_list_allocator = "0.9.0"
humansize = { version = "2", optional = true } redox-path = "0.2.0"
libc = "0.2" redox_syscall = { path = "../syscall", default-features = false }
log = { version = "0.4.14", default-features = false, optional = true } rmm = { path = "rmm", default-features = false }
lz4_flex = { version = "0.11", default-features = false, features = ["checked-decode"] } slab = { version = "0.4", default-features = false }
parse-size = { version = "1", optional = true } smallvec = { version = "1.15.1", default-features = false }
range-tree = { version = "0.1", optional = true } spin = { version = "0.9.8" }
redox_syscall = { path = "../syscall" }
seahash = { version = "4.1.0", default-features = false }
termion = { version = "4", optional = true }
uuid = { version = "1.4", default-features = false }
xts-mode = { version = "0.5", default-features = false }
[features] [dependencies.object]
default = ["std", "log", "fuse"] version = "0.37.1"
fuse = [ default-features = false
"fuser", features = ["read_core", "elf"]
"std",
]
std = [
"env_logger",
"getrandom",
"humansize",
"libredox",
"parse-size",
"range-tree",
"termion",
"uuid/v4",
"redox_syscall/std",
"redox-scheme",
]
[target.'cfg(not(target_os = "redox"))'.dependencies] [dependencies.rustc-demangle]
fuser = { version = "0.16", optional = true } version = "0.1.16"
default-features = false
[target.'cfg(target_os = "redox")'.dependencies] [lints.clippy]
libredox = { path = "../libredox", optional = true } # Overflows are very, very bad in kernel code as it may provide an attack vector for
redox-path = "0.3.0" # userspace applications, and it is only checked in debug builds
redox-scheme = { path = "../redox-scheme", optional = true } # TODO: address occurrences and then deny
arithmetic_side_effects = "warn"
cast_ptr_alignment = "warn" # TODO: address occurrences and then deny
identity_op = "allow" # Used to allow stuff like 1 << 0 and 1 * 1024 * 1024
if_same_then_else = "allow" # Useful for adding comments about different branches
# Indexing a slice can cause panics and that is something we always want to avoid
# in kernel code. Use .get and return an error instead
# TODO: address occurrences and then deny
indexing_slicing = "warn"
many_single_char_names = "allow" # Useful in the syscall function
module_inception = "allow" # Used for context::context
# Not implementing default is sometimes useful in the case something has significant cost
# to allocate. If you implement default, it can be allocated without evidence using the
# ..Default::default() syntax. Not fun in kernel space
new_without_default = "allow"
not_unsafe_ptr_arg_deref = "deny"
or_fun_call = "allow" # Used to make it nicer to return errors, for example, .ok_or(Error::new(ESRCH))
precedence = "deny"
ptr_cast_constness = "deny"
too_many_arguments = "allow" # This is needed in some cases, like for syscall
# Avoid panicking in the kernel without information about the panic. Use expect
# TODO: address occurrences and then deny
unwrap_used = "warn"
[lints.rust] [lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] } static_mut_refs = "warn" # FIXME deny once all occurrences are fixed
# This is usually a serious issue - a missing import of a define where it is interpreted
# as a catch-all variable in a match, for example
unreachable_patterns = "deny"
unused_must_use = "deny" # Ensure that all must_use results are used
[dev-dependencies] [target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dependencies]
assert_cmd = "2.0.17" raw-cpuid = "10.2.0"
x86 = { version = "0.47.0", default-features = false }
[target.'cfg(any(target_arch = "riscv64", target_arch = "riscv32"))'.dependencies]
sbi-rt = "0.0.3"
[features]
default = [
"acpi",
#"debugger",
"multi_core",
"serial_debug",
"self_modifying",
"x86_kvm_pv",
#"busy_panic",
#"drop_panic",
#"syscall_debug"
]
# Activates some limited code-overwriting optimizations, based on CPU features.
self_modifying = []
acpi = []
lpss_debug = []
multi_core = ["acpi"]
profiling = []
#TODO: remove when threading issues are fixed
pti = []
drop_panic = []
busy_panic = []
qemu_debug = []
serial_debug = []
system76_ec_debug = []
x86_kvm_pv = []
debugger = ["syscall_debug"]
syscall_debug = []
sys_fdstat = []
[profile.dev]
# Avoids having to define the eh_personality lang item and reduces kernel size
panic = "abort"
[profile.release]
# Avoids having to define the eh_personality lang item and reduces kernel size
panic = "abort"
#lto = true
debug = "full"
# Red Bear OS Phase J: see local/sources/base/Cargo.toml for
# the rationale. Both the kernel and the base workspace need
# the libredox override so that the libredox::error::Error
# type is the same compile-time type as syscall::Error. With
# the local libredox fork at local/sources/libredox/ using
# the local syscall fork at local/sources/syscall/, the
# libredox::error::Error (re-exported from the local syscall)
# and syscall::Error (also the local syscall) are now the
# same type, so `?` conversions in scheme-utils / daemon
# compile cleanly.
[patch.crates-io] [patch.crates-io]
redox_syscall = { path = "../syscall" } # Local fork dependency rule: every crate with a local fork MUST resolve through it.
libredox = { path = "../libredox" } libredox = { path = "../libredox" }
redox-scheme = { path = "../redox-scheme" } redox_syscall = { path = "../syscall" }
+2 -2
View File
@@ -1,6 +1,6 @@
The MIT License (MIT) MIT License
Copyright (c) 2016 Jeremy Soller Copyright (c) 2017 Jeremy Soller
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+58 -29
View File
@@ -1,37 +1,66 @@
UNAME := $(shell uname) .PHONY: all check
ifeq ($(UNAME),Darwin) SOURCE:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
FUMOUNT=umount BUILD?=$(CURDIR)
else ifeq ($(UNAME),FreeBSD) export RUST_TARGET_PATH=$(SOURCE)/targets
FUMOUNT=sudo umount
ifeq ($(TARGET),)
ARCH?=$(shell uname -m)
else else
# Detect which version of the fusermount binary is available. ARCH?=$(shell echo "$(TARGET)" | cut -d - -f1)
ifneq (, $(shell which fusermount3))
FUMOUNT=fusermount3 -u
else
FUMOUNT=fusermount -u
endif
endif endif
image.bin: ifeq ($(ARCH),riscv64gc)
cargo build --release --bin redoxfs-mkfs override ARCH:=riscv64
dd if=/dev/zero of=image.bin bs=1048576 count=1024 GNU_TARGET=riscv64-unknown-redox
target/release/redoxfs-mkfs image.bin else ifeq ($(ARCH),i686)
override ARCH:=i586
GNU_TARGET=i686-unknown-redox
else
GNU_TARGET=$(ARCH)-unknown-redox
endif
mount: image.bin FORCE
mkdir -p image
cargo build --release --bin redoxfs
target/release/redoxfs image.bin image
unmount: FORCE all: $(BUILD)/kernel $(BUILD)/kernel.sym
sync
-${FUMOUNT} image
rm -rf image
clean: FORCE LD_SCRIPT=$(SOURCE)/linkers/$(ARCH).ld
sync LOCKFILE=$(SOURCE)/Cargo.lock
-${FUMOUNT} image MANIFEST=$(SOURCE)/Cargo.toml
rm -rf image image.bin TARGET_SPEC=$(RUST_TARGET_PATH)/$(ARCH)-unknown-kernel.json
cargo clean
FORCE: KERNEL_CARGO_FEATURES?=
$(BUILD)/kernel.all: $(LD_SCRIPT) $(LOCKFILE) $(MANIFEST) $(TARGET_SPEC) $(shell find $(SOURCE) -name "*.rs" -type f)
cargo rustc \
--bin kernel \
--manifest-path "$(MANIFEST)" \
--target "$(TARGET_SPEC)" \
--release \
-Z build-std=core,alloc -Zbuild-std-features=compiler-builtins-mem -Z json-target-spec \
--features=$(KERNEL_CARGO_FEATURES) \
-- \
-C link-arg=-T -Clink-arg="$(LD_SCRIPT)" \
-C link-arg=-z -Clink-arg=max-page-size=0x1000 \
--emit link="$(BUILD)/kernel.all"
$(BUILD)/kernel.sym: $(BUILD)/kernel.all
$(GNU_TARGET)-objcopy \
--only-keep-debug \
"$(BUILD)/kernel.all" \
"$(BUILD)/kernel.sym"
$(BUILD)/kernel: $(BUILD)/kernel.all
$(GNU_TARGET)-objcopy \
--strip-debug \
"$(BUILD)/kernel.all" \
"$(BUILD)/kernel"
KERNEL_CHECK_FEATURES?=
check:
cargo check \
--bin kernel \
--manifest-path "$(MANIFEST)" \
--target "$(TARGET_SPEC)" \
-Z build-std=core,alloc -Zbuild-std-features=compiler-builtins-mem -Z json-target-spec \
--features=$(KERNEL_CHECK_FEATURES)
+78 -50
View File
@@ -1,53 +1,81 @@
# RedoxFS # Kernel
This is the default filesystem of Redox OS inspired by [ZFS](https://docs.freebsd.org/en/books/handbook/zfs/) and adapted to a microkernel architecture. Redox OS Microkernel
(It's a replacement for [TFS](https://gitlab.redox-os.org/redox-os/tfs))
Current features:
- Compatible with Redox and Linux (FUSE)
- Copy-on-write
- Data/metadata checksums
- Transparent encryption
- Standard Unix file attributes
- File/directory size limit up to 193TiB (212TB)
- File/directory quantity limit up to 4 billion per 193TiB (2^32 - 1 = 4294967295)
- MIT licensed
- Disk encryption fully supported by the Redox bootloader, letting it load the kernel off an encrypted partition.
Being MIT licensed, RedoxFS can be bundled on GPL-licensed operating systems (Linux, for example).
### Install RedoxFS
```sh
cargo install redoxfs
```
You can also build RedoxFS from this repository.
### Configure your storage device to allow rootless usage
If you are on Linux you need root permission to acess block devices (storage), but it's recommended to run RedoxFS as rootless.
To do that you need to configure your storage device permission to your user with the following command:
```sh
sudo setfacl -m u:your-username:rw /path/to/disk
```
### Create, mount and customize your RedoxFS partition
See [the instructions in the book](https://doc.redox-os.org/book/redoxfs.html) for RedoxFS tooling usage.
Currently RedoxFS tooling are:
- `redoxfs` mount a RedoxFS disk
- `redoxfs-ar` write files to a RedoxFS disk
- `redoxfs-clone` clone a RedoxFS disk
- `redoxfs-mkfs` create an empty RedoxFS disk
- `redoxfs-resize` resize a RedoxFS disk
[![docs](https://img.shields.io/badge/docs-master-blue.svg)](https://docs.rs/redox_syscall/latest/syscall/)
[![SLOCs counter](https://tokei.rs/b1/github/redox-os/kernel?category=code)](https://github.com/XAMPPRocky/tokei)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
[![crates.io](http://meritbadge.herokuapp.com/redoxfs)](https://crates.io/crates/redoxfs)
[![docs.rs](https://docs.rs/redoxfs/badge.svg)](https://docs.rs/redoxfs) ## Requirements
* [`nasm`](https://nasm.us/) needs to be available on the PATH at build time.
## Building The Documentation
Use this command:
```sh
cargo doc --open --target x86_64-unknown-none
```
## Debugging
### QEMU
Running [QEMU](https://www.qemu.org) with the `-s` flag will set up QEMU to listen on port `1234` for a GDB client to connect to it. To debug the redox kernel run.
```sh
make qemu gdb=yes
```
This will start a virtual machine with and listen on port `1234` for a GDB or LLDB client.
### GDB
If you are going to use [GDB](https://www.gnu.org/software/gdb/), run these commands to load debug symbols and connect to your running kernel:
```
(gdb) symbol-file build/kernel.sym
(gdb) target remote localhost:1234
```
### LLDB
If you are going to use [LLDB](https://lldb.llvm.org/), run these commands to start debugging:
```
(lldb) target create -s build/kernel.sym build/kernel
(lldb) gdb-remote localhost:1234
```
After connecting to your kernel you can set some interesting breakpoints and `continue`
the process. See your debuggers man page for more information on useful commands to run.
## Notes
- Always use `foo.get(n)` instead of `foo[n]` and try to cover for the possibility of `Option::None`. Doing the regular way may work fine for applications, but never in the kernel. No possible panics should ever exist in kernel space, because then the whole OS would just stop working.
- If you receive a kernel panic in QEMU, use `pkill qemu-system` to kill the frozen QEMU process.
## How To Contribute
To learn how to contribute to this system component you need to read the following document:
- [CONTRIBUTING.md](https://gitlab.redox-os.org/redox-os/redox/-/blob/master/CONTRIBUTING.md)
## Development
To learn how to do development with this system component inside the Redox build system you need to read the [Build System](https://doc.redox-os.org/book/build-system-reference.html) and [Coding and Building](https://doc.redox-os.org/book/coding-and-building.html) pages.
### How To Build
To build this system component you need to download the Redox build system, you can learn how to do it on the [Building Redox](https://doc.redox-os.org/book/podman-build.html) page.
This is necessary because they only work with cross-compilation to a Redox virtual machine, but you can do some testing from Linux.
## Funding - _Unix-style Signals and Process Management_
This project is funded through [NGI Zero Core](https://nlnet.nl/core), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program. Learn more at the [NLnet project page](https://nlnet.nl/project/RedoxOS-Signals).
[<img src="https://nlnet.nl/logo/banner.png" alt="NLnet foundation logo" width="20%" />](https://nlnet.nl)
[<img src="https://nlnet.nl/image/logos/NGI0_tag.svg" alt="NGI Zero Logo" width="20%" />](https://nlnet.nl/core)
+100
View File
@@ -0,0 +1,100 @@
#![allow(clippy::unwrap_used)] // the build script can panic
use std::{env, path::Path, process::Command};
use toml::Table;
fn parse_kconfig(arch: &str) -> Option<()> {
println!("cargo:rerun-if-changed=config.toml");
assert!(Path::new("config.toml.example").try_exists().unwrap());
if !Path::new("config.toml").try_exists().unwrap() {
std::fs::copy("config.toml.example", "config.toml").unwrap();
}
let config_str = std::fs::read_to_string("config.toml").unwrap();
let root: Table = toml::from_str(&config_str).unwrap();
let altfeatures = root
.get("arch")?
.as_table()
.unwrap()
.get(arch)?
.as_table()
.unwrap()
.get("features")?
.as_table()
.unwrap();
#[expect(clippy::format_collect)] // TODO: remove once version is bumped
let features_list = altfeatures
.keys()
.map(|feat| format!(", {feat:?}"))
.collect::<String>();
println!("cargo::rustc-check-cfg=cfg(cpu_feature_always, values(\"\"{features_list}))");
println!("cargo::rustc-check-cfg=cfg(cpu_feature_auto, values(\"\"{features_list}))");
println!("cargo::rustc-check-cfg=cfg(cpu_feature_never, values(\"\"{features_list}))");
let self_modifying = env::var("CARGO_FEATURE_SELF_MODIFYING").is_ok();
for (name, value) in altfeatures {
let mut choice = value.as_str().unwrap();
assert!(matches!(choice, "always" | "never" | "auto"));
if !self_modifying && choice == "auto" {
choice = "never";
}
println!("cargo:rustc-cfg=cpu_feature_{choice}=\"{name}\"");
}
Some(())
}
fn main() {
println!("cargo::rustc-env=TARGET={}", env::var("TARGET").unwrap());
println!("cargo::rustc-check-cfg=cfg(dtb)");
let out_dir = env::var("OUT_DIR").unwrap();
let arch_str = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
match &*arch_str {
"aarch64" => {
println!("cargo::rustc-cfg=dtb");
}
"x86" => {
println!("cargo::rerun-if-changed=src/asm/x86/trampoline.asm");
let status = Command::new("nasm")
.arg("-f")
.arg("bin")
.arg("-o")
.arg(format!("{}/trampoline", out_dir))
.arg("src/asm/x86/trampoline.asm")
.status()
.expect("failed to run nasm");
if !status.success() {
panic!("nasm failed with exit status {}", status);
}
}
"x86_64" => {
println!("cargo::rerun-if-changed=src/asm/x86_64/trampoline.asm");
let status = Command::new("nasm")
.arg("-f")
.arg("bin")
.arg("-o")
.arg(format!("{}/trampoline", out_dir))
.arg("src/asm/x86_64/trampoline.asm")
.status()
.expect("failed to run nasm");
if !status.success() {
panic!("nasm failed with exit status {}", status);
}
}
"riscv64" => {
println!("cargo::rustc-cfg=dtb");
}
_ => (),
}
let _ = parse_kconfig(&arch_str);
}
Executable
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -e
export RUST_TARGET_PATH="${PWD}/targets"
export RUSTFLAGS="-C debuginfo=2"
cargo clippy --lib --release --target x86_64-unknown-none "$@"
+7
View File
@@ -0,0 +1,7 @@
[arch.x86_64.features]
smap = "auto"
fsgsbase = "auto"
xsave = "auto"
xsaveopt = "auto"
# vim: ft=toml
-4
View File
@@ -1,4 +0,0 @@
target
corpus
artifacts
coverage
-858
View File
@@ -1,858 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aes"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
"once_cell",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "arbitrary"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
dependencies = [
"derive_arbitrary",
]
[[package]]
name = "argon2"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73"
dependencies = [
"base64ct",
"blake2",
]
[[package]]
name = "base64ct"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "blake2"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
dependencies = [
"digest",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
dependencies = [
"jobserver",
"libc",
"once_cell",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "cpufeatures"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "derive_arbitrary"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
[[package]]
name = "endian-num"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad847bb2094f110bbdd6fa564894ca4556fd978958e93985420d680d3cb6d14"
[[package]]
name = "env_filter"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"jiff",
"log",
]
[[package]]
name = "errno"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "fastrand"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]]
name = "fuser"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bb29a3ae32279fe3e79a958fe01899f5fb23eadccee919cf88e145b54ed9367"
dependencies = [
"libc",
"log",
"memchr",
"nix",
"page_size",
"smallvec",
"zerocopy",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "humansize"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
dependencies = [
"libm",
]
[[package]]
name = "inout"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
dependencies = [
"generic-array",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "jiff"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ad87c89110f55e4cd4dc2893a9790820206729eaf221555f742d540b0724a0"
dependencies = [
"jiff-static",
"log",
"portable-atomic",
"portable-atomic-util",
"serde",
]
[[package]]
name = "jiff-static"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d076d5b64a7e2fe6f0743f02c43ca4a6725c0f904203bfe276a5b3e793103605"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "jobserver"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
dependencies = [
"libc",
]
[[package]]
name = "libc"
version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libfuzzer-sys"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7"
dependencies = [
"arbitrary",
"cc",
"once_cell",
]
[[package]]
name = "libm"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "libredox"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616"
dependencies = [
"bitflags",
"libc",
"redox_syscall 0.7.0",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "lz4_flex"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "nix"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags",
"cfg-if",
"cfg_aliases",
"libc",
]
[[package]]
name = "numtoa"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f"
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "page_size"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "parse-size"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b"
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "range-tree"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384c2842d4e069d5ccacf5fe1dca4ef8d07a5444329715f0fc3c61813502d4d1"
[[package]]
name = "redox-path"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
[[package]]
name = "redox-scheme"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cea2668a5932f878a4298a1d7f8950249bbbb77120fb263da252c589152f5ea"
dependencies = [
"libredox",
"redox_syscall 0.6.0",
]
[[package]]
name = "redox_syscall"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_syscall"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_termios"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb"
[[package]]
name = "redoxfs"
version = "0.8.4"
dependencies = [
"aes",
"argon2",
"base64ct",
"bitflags",
"endian-num",
"env_logger",
"fuser",
"getrandom",
"humansize",
"libc",
"libredox",
"log",
"lz4_flex",
"parse-size",
"range-tree",
"redox-path",
"redox-scheme",
"redox_syscall 0.6.0",
"seahash",
"termion",
"uuid",
"xts-mode",
]
[[package]]
name = "redoxfs-fuzz"
version = "0.0.0"
dependencies = [
"anyhow",
"arbitrary",
"fuser",
"libfuzzer-sys",
"nix",
"redoxfs",
"tempfile",
]
[[package]]
name = "regex"
version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "rustix"
version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]]
name = "seahash"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "syn"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tempfile"
version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if",
"fastrand",
"rustix",
"windows-sys 0.52.0",
]
[[package]]
name = "termion"
version = "4.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3669a69de26799d6321a5aa713f55f7e2cd37bd47be044b50f2acafc42c122bb"
dependencies = [
"libc",
"libredox",
"numtoa",
"redox_termios",
]
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
dependencies = [
"getrandom",
]
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "xts-mode"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cbddb7545ca0b9ffa7bdc653e8743303e1712687a6918ced25f2cdbed42520"
dependencies = [
"byteorder",
"cipher",
]
[[package]]
name = "zerocopy"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
-30
View File
@@ -1,30 +0,0 @@
[package]
name = "redoxfs-fuzz"
version = "0.0.0"
publish = false
edition = "2021"
[features]
default = []
log = []
[package.metadata]
cargo-fuzz = true
[dependencies]
anyhow = "1.0.86"
arbitrary = { version = "1.3.2", features = ["derive"] }
fuser = { version = "0.16" }
libfuzzer-sys = "0.4"
nix = { version = "0.29.0", features = ["fs"] }
tempfile = "3.10.1"
[dependencies.redoxfs]
path = ".."
[[bin]]
name = "fuse_fuzz_target"
path = "fuzz_targets/fuse_fuzz_target.rs"
test = false
doc = false
bench = false
-338
View File
@@ -1,338 +0,0 @@
//! Fuzzer that exercises random file system operations against a FUSE-mounted redoxfs.
#![no_main]
use anyhow::{ensure, Result};
use fuser;
use libfuzzer_sys::{arbitrary::Arbitrary, fuzz_target, Corpus};
use nix::sys::statvfs::statvfs;
use std::{
fs::{self, File, FileTimes, OpenOptions},
io::{Read, Seek, SeekFrom, Write},
os::unix::fs::{self as unix_fs, PermissionsExt},
path::{Path, PathBuf},
thread,
time::{Duration, SystemTime, UNIX_EPOCH},
};
use tempfile;
use redoxfs::{mount::fuse::Fuse, DiskSparse, FileSystem};
/// Maximum size for files and buffers. Chosen arbitrarily with fuzzing performance in mind.
const MAX_SIZE: u64 = 10_000_000;
/// Limit on the number of remounts in a single test case. Chosen arbitrarily with fuzzing
/// performance in mind: remounts are costly.
const MAX_MOUNT_SEQUENCES: usize = 3;
/// An operation to be performed by the fuzzer.
#[derive(Arbitrary, Clone, Debug)]
enum Operation {
Chown {
path: PathBuf,
uid: Option<u32>,
gid: Option<u32>,
},
CreateDir {
path: PathBuf,
},
HardLink {
original: PathBuf,
link: PathBuf,
},
Metadata {
path: PathBuf,
},
Read {
path: PathBuf,
},
ReadDir {
path: PathBuf,
},
ReadLink {
path: PathBuf,
},
RemoveDir {
path: PathBuf,
},
RemoveFile {
path: PathBuf,
},
Rename {
from: PathBuf,
to: PathBuf,
},
SeekRead {
path: PathBuf,
seek_pos: u64,
buf_size: usize,
},
SeekWrite {
path: PathBuf,
seek_pos: u64,
buf_size: usize,
},
SetLen {
path: PathBuf,
size: u64,
},
SetPermissions {
path: PathBuf,
readonly: Option<bool>,
mode: Option<u32>,
},
SetTimes {
path: PathBuf,
accessed_since_epoch: Option<Duration>,
modified_since_epoch: Option<Duration>,
},
Statvfs {},
SymLink {
original: PathBuf,
link: PathBuf,
},
Write {
path: PathBuf,
buf_size: usize,
},
}
/// Parameters for mounting the file system and operations to be performed afterwards.
#[derive(Arbitrary, Clone, Debug)]
struct MountSequence {
cleanup: bool,
operations: Vec<Operation>,
}
/// The whole input to a single fuzzer invocation.
#[derive(Arbitrary, Clone, Debug)]
struct TestCase {
disk_size: u64,
reserved_size: u64,
mount_sequences: Vec<MountSequence>,
}
/// Creates the disk for backing the Redoxfs.
fn create_disk(temp_path: &Path, disk_size: u64) -> DiskSparse {
let disk_path = temp_path.join("disk.img");
DiskSparse::create(disk_path, disk_size).unwrap()
}
/// Creates an empty Redoxfs.
fn create_redoxfs(disk: DiskSparse, reserved_size: u64) -> bool {
let password = None;
let reserved = vec![0; reserved_size as usize];
let ctime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
FileSystem::create_reserved(
disk,
password,
&reserved,
ctime.as_secs(),
ctime.subsec_nanos(),
)
.is_ok()
}
/// Mounts an existing Redoxfs, runs the callback and performs the unmount.
fn with_redoxfs_mount<F>(temp_path: &Path, disk: DiskSparse, cleanup: bool, callback: F)
where
F: FnOnce(&Path) + Send + 'static,
{
let password = None;
let block = None;
let mut fs = FileSystem::open(disk, password, block, cleanup).unwrap();
let mount_path = temp_path.join("mount");
fs::create_dir_all(&mount_path).unwrap();
let mut session = fuser::Session::new(Fuse { fs: &mut fs }, &mount_path, &[]).unwrap();
let mut unmounter = session.unmount_callable();
let join_handle = thread::spawn(move || {
callback(&mount_path);
unmounter.unmount().unwrap();
});
session.run().unwrap();
join_handle.join().unwrap();
}
fn get_path_within_fs(fs_path: &Path, path_to_add: &Path) -> Result<PathBuf> {
ensure!(path_to_add.is_relative());
ensure!(path_to_add
.components()
.all(|c| c != std::path::Component::ParentDir));
Ok(fs_path.join(path_to_add))
}
fn do_operation(fs_path: &Path, op: &Operation) -> Result<()> {
match op {
Operation::Chown { path, uid, gid } => {
let path = get_path_within_fs(fs_path, path)?;
unix_fs::chown(path, *uid, *gid)?;
}
Operation::CreateDir { path } => {
let path = get_path_within_fs(fs_path, path)?;
fs::create_dir(path)?;
}
Operation::HardLink { original, link } => {
let original = get_path_within_fs(fs_path, original)?;
let link = get_path_within_fs(fs_path, link)?;
fs::hard_link(original, link)?;
}
Operation::Metadata { path } => {
let path = get_path_within_fs(fs_path, path)?;
fs::metadata(path)?;
}
Operation::Read { path } => {
let path = get_path_within_fs(fs_path, path)?;
fs::read(path)?;
}
Operation::ReadDir { path } => {
let path = get_path_within_fs(fs_path, path)?;
let _ = fs::read_dir(path)?.count();
}
Operation::ReadLink { path } => {
let path = get_path_within_fs(fs_path, path)?;
fs::read_link(path)?;
}
Operation::RemoveDir { path } => {
let path = get_path_within_fs(fs_path, path)?;
fs::remove_dir(path)?;
}
Operation::RemoveFile { path } => {
let path = get_path_within_fs(fs_path, path)?;
fs::remove_file(path)?;
}
Operation::Rename { from, to } => {
let from = get_path_within_fs(fs_path, from)?;
let to = get_path_within_fs(fs_path, to)?;
fs::rename(from, to)?;
}
Operation::SeekRead {
path,
seek_pos,
buf_size,
} => {
ensure!(*buf_size as u64 <= MAX_SIZE);
let path = get_path_within_fs(fs_path, path)?;
let mut file = File::open(path)?;
file.seek(SeekFrom::Start(*seek_pos))?;
let mut buf = vec![0; *buf_size];
file.read(&mut buf)?;
}
Operation::SeekWrite {
path,
seek_pos,
buf_size,
} => {
ensure!(*seek_pos <= MAX_SIZE);
ensure!(*buf_size as u64 <= MAX_SIZE);
let path = get_path_within_fs(fs_path, path)?;
let mut file = OpenOptions::new().write(true).open(path)?;
file.seek(SeekFrom::Start(*seek_pos))?;
let buf = vec![0; *buf_size];
file.write(&buf)?;
}
Operation::SetLen { path, size } => {
let path = get_path_within_fs(fs_path, path)?;
let file = OpenOptions::new().write(true).open(path)?;
file.set_len(*size)?;
}
Operation::SetPermissions {
path,
readonly,
mode,
} => {
let path = get_path_within_fs(fs_path, path)?;
let metadata = fs::metadata(&path)?;
let mut perms = metadata.permissions();
if let Some(readonly) = readonly {
perms.set_readonly(*readonly);
}
if let Some(mode) = mode {
perms.set_mode(*mode);
}
fs::set_permissions(path, perms)?;
}
Operation::SetTimes {
path,
accessed_since_epoch,
modified_since_epoch,
} => {
let path = get_path_within_fs(fs_path, path)?;
let file = File::options().write(true).open(path)?;
let mut times = FileTimes::new();
if let Some(accessed_since_epoch) = accessed_since_epoch {
if let Some(accessed) = UNIX_EPOCH.checked_add(*accessed_since_epoch) {
times = times.set_accessed(accessed);
}
}
if let Some(modified_since_epoch) = modified_since_epoch {
if let Some(modified) = UNIX_EPOCH.checked_add(*modified_since_epoch) {
times = times.set_modified(modified);
}
}
file.set_times(times)?;
}
Operation::Statvfs {} => {
statvfs(fs_path)?;
}
Operation::SymLink { original, link } => {
let original = get_path_within_fs(fs_path, original)?;
let link = get_path_within_fs(fs_path, link)?;
unix_fs::symlink(original, link)?;
}
Operation::Write { path, buf_size } => {
ensure!(*buf_size as u64 <= MAX_SIZE);
let path = get_path_within_fs(fs_path, path)?;
let buf = vec![0; *buf_size];
fs::write(path, &buf)?;
}
}
Ok(())
}
fuzz_target!(|test_case: TestCase| -> Corpus {
if test_case.disk_size > MAX_SIZE
|| test_case.reserved_size > MAX_SIZE
|| test_case.mount_sequences.len() > MAX_MOUNT_SEQUENCES
{
return Corpus::Reject;
}
let temp_dir = tempfile::Builder::new()
.prefix("fuse_fuzz_target")
.tempdir()
.unwrap();
#[cfg(feature = "log")]
eprintln!("create fs");
let disk = create_disk(temp_dir.path(), test_case.disk_size);
if !create_redoxfs(disk, test_case.reserved_size) {
// File system creation failed (e.g., due to insufficient space) so we bail out, still
// exercising this code path is useful.
return Corpus::Keep;
}
for mount_seq in test_case.mount_sequences.iter() {
#[cfg(feature = "log")]
eprintln!("mount fs: path {:?}, size{}", temp_dir.path(), test_case.disk_size);
let disk = create_disk(temp_dir.path(), test_case.disk_size);
let operations = mount_seq.operations.clone();
with_redoxfs_mount(temp_dir.path(), disk, mount_seq.cleanup, move |fs_path| {
for operation in operations.iter() {
#[cfg(feature = "log")]
eprintln!("do operation {operation:?}");
let _result = do_operation(fs_path, operation);
#[cfg(feature = "log")]
eprintln!("operation result {:?}", _result.err());
}
});
#[cfg(feature = "log")]
eprintln!("unmounted fs");
}
Corpus::Keep
});
+55
View File
@@ -0,0 +1,55 @@
ENTRY(kstart)
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
KERNEL_OFFSET = 0xFFFFFF0000000000;
SECTIONS {
. = KERNEL_OFFSET;
. += SIZEOF_HEADERS;
/* Force the zero page to be part of a segment by creating a
* dummy section in the zero page.
* Limine will map the segment with the lowest vaddr value at
* 0xFFFFFFFF80000000 even if the segment has a higher vaddr.
* As such without the zero page being part of a segment, the
* kernel would be loaded at an offset from the expected
* location. As the redox kernel is not currently relocatable,
* this would result in a crash. A similar issue likely exists
* with multiboot/multiboot2 and the paddr of the segment.
*/
.dummy ALIGN(8) : AT(ADDR(.dummy) - KERNEL_OFFSET) {}
. = ALIGN(4096);
.text : AT(ADDR(.text) - KERNEL_OFFSET) {
__text_start = .;
*(.text*)
. = ALIGN(4096);
__text_end = .;
}
.rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
__rodata_start = .;
*(.rodata*)
. = ALIGN(4096);
__rodata_end = .;
}
.data : AT(ADDR(.data) - KERNEL_OFFSET) {
*(.data*)
. = ALIGN(4096);
*(.bss*)
. = ALIGN(4096);
}
__end = .;
/DISCARD/ : {
*(.comment*)
*(.eh_frame*)
*(.gcc_except_table*)
*(.note*)
*(.rel.eh_frame*)
}
}
+51
View File
@@ -0,0 +1,51 @@
ENTRY(kstart)
OUTPUT_FORMAT(elf32-i386)
KERNEL_OFFSET = 0xC0000000;
SECTIONS {
. = KERNEL_OFFSET;
. += SIZEOF_HEADERS;
/* Force the zero page to be part of a segment by creating a
* dummy section in the zero page.
* Limine will map the segment with the lowest vaddr value at
* 0xFFFFFFFF80000000 even if the segment has a higher vaddr.
* As such without the zero page being part of a segment, the
* kernel would be loaded at an offset from the expected
* location. As the redox kernel is not currently relocatable,
* this would result in a crash. A similar issue likely exists
* with multiboot/multiboot2 and the paddr of the segment.
*/
.dummy : AT(ADDR(.dummy) - KERNEL_OFFSET) {}
.text ALIGN(4K) : AT(ADDR(.text) - KERNEL_OFFSET) {
__text_start = .;
*(.text*)
}
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET) {
__text_end = .;
__rodata_start = .;
*(.rodata*)
}
.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_OFFSET) {
__rodata_end = .;
*(.data*)
. = ALIGN(4K);
*(.bss*)
. = ALIGN(4K);
}
__end = .;
/DISCARD/ : {
*(.comment*)
*(.eh_frame*)
*(.gcc_except_table*)
*(.note*)
*(.rel.eh_frame*)
}
}
+61
View File
@@ -0,0 +1,61 @@
ENTRY(kstart)
OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv" )
KERNEL_OFFSET = 0xFFFFFFFF80000000;
SECTIONS {
. = KERNEL_OFFSET;
. += SIZEOF_HEADERS;
/* Force the zero page to be part of a segment by creating a
* dummy section in the zero page.
* Linker will map the segment with the lowest vaddr value at
* 0xFFFFFFFF80000000 even if the segment has a higher vaddr.
* As such without the zero page being part of a segment, the
* kernel would be loaded at an offset from the expected
* location. As the redox kernel is not currently relocatable,
* this would result in a crash. A similar issue likely exists
* with multiboot/multiboot2 and the paddr of the segment.
*/
.dummy ALIGN(8) : AT(ADDR(.dummy) - KERNEL_OFFSET) {}
. = ALIGN(4096);
.text : AT(ADDR(.text) - KERNEL_OFFSET) {
__text_start = .;
*(.early_init.text*)
. = ALIGN(4096);
*(.text*)
. = ALIGN(4096);
__text_end = .;
}
.rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
__rodata_start = .;
*(.rodata*)
. = ALIGN(4096);
__rodata_end = .;
}
.data : AT(ADDR(.data) - KERNEL_OFFSET) {
*(.data*)
*(.sdata*)
. = ALIGN(4096);
*(.got*)
. = ALIGN(4096);
*(.bss*)
*(.sbss*)
. = ALIGN(4096);
}
__end = .;
/DISCARD/ : {
*(.comment*)
*(.eh_frame*)
*(.gcc_except_table*)
*(.note*)
*(.rel.eh_frame*)
}
}
+60
View File
@@ -0,0 +1,60 @@
ENTRY(kstart)
OUTPUT_FORMAT(elf64-x86-64)
KERNEL_OFFSET = 0xFFFFFFFF80000000;
SECTIONS {
. = KERNEL_OFFSET;
. += SIZEOF_HEADERS;
/* Force the zero page to be part of a segment by creating a
* dummy section in the zero page.
* Limine will map the segment with the lowest vaddr value at
* 0xFFFFFFFF80000000 even if the segment has a higher vaddr.
* As such without the zero page being part of a segment, the
* kernel would be loaded at an offset from the expected
* location. As the redox kernel is not currently relocatable,
* this would result in a crash. A similar issue likely exists
* with multiboot/multiboot2 and the paddr of the segment.
*/
.dummy : AT(ADDR(.dummy) - KERNEL_OFFSET) {}
.text ALIGN(4K) : AT(ADDR(.text) - KERNEL_OFFSET) {
__text_start = .;
*(.text*)
}
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET) {
__text_end = .;
__rodata_start = .;
*(.rodata*)
__altcode_start = .;
KEEP(*(.altcode*))
__altcode_end = .;
. = ALIGN(8);
__altrelocs_start = .;
KEEP(*(.altrelocs*))
__altrelocs_end = .;
__altfeatures_start = .;
KEEP(*(.altfeatures*))
__altfeatures_end = .;
}
.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_OFFSET) {
__rodata_end = .;
*(.data*)
. = ALIGN(4K);
*(.bss*)
}
__end = .;
/DISCARD/ : {
*(.comment*)
*(.eh_frame*)
*(.gcc_except_table*)
*(.note*)
*(.rel.eh_frame*)
}
}
BIN
View File
Binary file not shown.
+16
View File
@@ -0,0 +1,16 @@
[package]
name = "rmm"
version = "0.1.0"
authors = ["Jeremy Soller <jeremy@system76.com>"]
edition = "2024"
[dependencies]
bitflags = "2"
[features]
std = []
[[bin]]
name = "rmm"
path = "src/main.rs"
required-features = ["std"]
+4
View File
@@ -0,0 +1,4 @@
# Redox Memory Management
This is a Rust crate to provide abstractions for hardware memory management. It
also contains a mechanism for testing memory management with software emulation.
+296
View File
@@ -0,0 +1,296 @@
use core::{marker::PhantomData, mem};
use crate::{
Arch, BumpAllocator, FrameAllocator, FrameCount, FrameUsage, PhysicalAddress, VirtualAddress,
};
#[repr(transparent)]
struct BuddyUsage(u8);
#[repr(C, packed)]
struct BuddyEntry<A> {
base: PhysicalAddress,
size: usize,
// Number of first free page
skip: usize,
// Count of used pages
used: usize,
phantom: PhantomData<A>,
}
impl<A> Clone for BuddyEntry<A> {
fn clone(&self) -> Self {
*self
}
}
impl<A> Copy for BuddyEntry<A> {}
impl<A: Arch> BuddyEntry<A> {
fn empty() -> Self {
Self {
base: PhysicalAddress::new(0),
size: 0,
skip: 0,
used: 0,
phantom: PhantomData,
}
}
#[inline(always)]
fn pages(&self) -> usize {
self.size >> A::PAGE_SHIFT
}
fn usage_pages(&self) -> usize {
let bytes = self.pages() * mem::size_of::<BuddyUsage>();
// Round bytes used for usage to next page
(bytes + A::PAGE_OFFSET_MASK) >> A::PAGE_SHIFT
}
unsafe fn usage_addr(&self, page: usize) -> Option<VirtualAddress> {
if page < self.pages() {
let phys = self.base.add(page * mem::size_of::<BuddyUsage>());
Some(A::phys_to_virt(phys))
} else {
None
}
}
unsafe fn usage(&self, page: usize) -> Option<BuddyUsage> {
unsafe {
let addr = self.usage_addr(page)?;
Some(A::read(addr))
}
}
#[expect(clippy::unit_arg)]
unsafe fn set_usage(&self, page: usize, usage: BuddyUsage) -> Option<()> {
unsafe {
let addr = self.usage_addr(page)?;
Some(A::write(addr, usage))
}
}
}
pub struct BuddyAllocator<A> {
table_virt: VirtualAddress,
phantom: PhantomData<A>,
}
impl<A: Arch> BuddyAllocator<A> {
const BUDDY_ENTRIES: usize = A::PAGE_SIZE / mem::size_of::<BuddyEntry<A>>();
pub unsafe fn new(mut bump_allocator: BumpAllocator<A>) -> Option<Self> {
unsafe {
// Allocate buddy table
let table_phys = bump_allocator.allocate_one()?;
let table_virt = A::phys_to_virt(table_phys);
for i in 0..(A::PAGE_SIZE / mem::size_of::<BuddyEntry<A>>()) {
let virt = table_virt.add(i * mem::size_of::<BuddyEntry<A>>());
A::write(virt, BuddyEntry::<A>::empty());
}
let allocator = Self {
table_virt,
phantom: PhantomData,
};
// Add areas to buddy table, combining areas when possible, and skipping frames used
// by the bump allocator
let mut offset = bump_allocator.offset();
for old_area in bump_allocator.areas().iter() {
let mut area = *old_area;
if offset >= area.size {
offset -= area.size;
continue;
} else if offset > 0 {
area.base = area.base.add(offset);
area.size -= offset;
offset = 0;
}
for i in 0..(A::PAGE_SIZE / mem::size_of::<BuddyEntry<A>>()) {
let virt = table_virt.add(i * mem::size_of::<BuddyEntry<A>>());
let mut entry = A::read::<BuddyEntry<A>>(virt);
let inserted = if area.base.add(area.size) == { entry.base } {
// Combine entry at start
entry.base = area.base;
entry.size += area.size;
true
} else if area.base == entry.base.add(entry.size) {
// Combine entry at end
entry.size += area.size;
true
} else if entry.size == 0 {
// Create new entry
entry.base = area.base;
entry.size = area.size;
true
} else {
false
};
if inserted {
A::write(virt, entry);
break;
}
}
}
//TODO: sort areas?
// Allocate buddy maps
for i in 0..Self::BUDDY_ENTRIES {
let virt = table_virt.add(i * mem::size_of::<BuddyEntry<A>>());
let mut entry = A::read::<BuddyEntry<A>>(virt);
// Only set up entries that have enough space for their own usage map
let usage_pages = entry.usage_pages();
if entry.pages() > usage_pages {
// Mark all usage bytes as unused
let usage_start = entry.usage_addr(0)?;
for page in 0..usage_pages {
A::write_bytes(usage_start.add(page << A::PAGE_SHIFT), 0, A::PAGE_SIZE);
}
// Mark bytes used for usage as used
for page in 0..usage_pages {
entry.set_usage(page, BuddyUsage(1))?;
}
}
// Skip the pages used for usage
entry.skip = usage_pages;
// Set used pages to pages used for usage
entry.used = usage_pages;
// Write updated entry
A::write(virt, entry);
}
Some(allocator)
}
}
}
unsafe impl<A: Arch> FrameAllocator for BuddyAllocator<A> {
fn allocate(&mut self, count: FrameCount) -> Option<PhysicalAddress> {
unsafe {
if self.table_virt.data() == 0 {
return None;
}
for entry_i in 0..Self::BUDDY_ENTRIES {
let virt = self
.table_virt
.add(entry_i * mem::size_of::<BuddyEntry<A>>());
let mut entry = A::read::<BuddyEntry<A>>(virt);
let mut free_page = entry.skip;
let mut free_count = 0;
for page in entry.skip..entry.pages() {
let usage = entry.usage(page)?;
if usage.0 == 0 {
free_count += 1;
if free_count == count.data() {
break;
}
} else {
free_page = page + 1;
free_count = 0;
}
}
if free_count == count.data() {
for page in free_page..free_page + free_count {
// Update usage
let mut usage = entry.usage(page)?;
usage.0 += 1;
entry.set_usage(page, usage);
// Zero page
let page_phys = entry.base.add(page << A::PAGE_SHIFT);
let page_virt = A::phys_to_virt(page_phys);
A::write_bytes(page_virt, 0, A::PAGE_SIZE);
}
// Update skip if necessary
if entry.skip == free_page {
entry.skip = free_page + free_count;
}
// Update used page count
entry.used += free_count;
// Write updated entry
A::write(virt, entry);
return Some(entry.base.add(free_page << A::PAGE_SHIFT));
}
}
None
}
}
unsafe fn free(&mut self, base: PhysicalAddress, count: FrameCount) {
unsafe {
if self.table_virt.data() == 0 {
return;
}
let size = count.data() * A::PAGE_SIZE;
for i in 0..Self::BUDDY_ENTRIES {
let virt = self.table_virt.add(i * mem::size_of::<BuddyEntry<A>>());
let mut entry = A::read::<BuddyEntry<A>>(virt);
if base >= { entry.base } && base.add(size) <= entry.base.add(entry.size) {
let start_page = (base.data() - { entry.base }.data()) >> A::PAGE_SHIFT;
for page in start_page..start_page + count.data() {
let mut usage = entry.usage(page).expect("failed to get usage during free");
if usage.0 > 0 {
usage.0 -= 1;
} else {
panic!("tried to free already free frame");
}
// If page was freed
if usage.0 == 0 {
// Update skip if necessary
if page < entry.skip {
entry.skip = page;
}
// Update used page count
entry.used -= 1;
}
entry
.set_usage(page, usage)
.expect("failed to set usage during free");
}
// Write updated entry
A::write(virt, entry);
return;
}
}
}
}
fn usage(&self) -> FrameUsage {
unsafe {
let mut total = 0;
let mut used = 0;
for i in 0..Self::BUDDY_ENTRIES {
let virt = self.table_virt.add(i * mem::size_of::<BuddyEntry<A>>());
let entry = A::read::<BuddyEntry<A>>(virt);
total += entry.size >> A::PAGE_SHIFT;
used += entry.used;
}
FrameUsage::new(FrameCount::new(used), FrameCount::new(total))
}
}
}
+79
View File
@@ -0,0 +1,79 @@
use core::marker::PhantomData;
use crate::{Arch, FrameAllocator, FrameCount, FrameUsage, MemoryArea, PhysicalAddress};
#[derive(Debug)]
pub struct BumpAllocator<A> {
orig_areas: (&'static [MemoryArea], usize),
cur_areas: (&'static [MemoryArea], usize),
_marker: PhantomData<fn() -> A>,
}
impl<A: Arch> BumpAllocator<A> {
pub fn new(mut areas: &'static [MemoryArea], mut offset: usize) -> Self {
while let Some(first) = areas.first()
&& first.size <= offset
{
offset -= first.size;
areas = &areas[1..];
}
Self {
orig_areas: (areas, offset),
cur_areas: (areas, offset),
_marker: PhantomData,
}
}
pub fn areas(&self) -> &'static [MemoryArea] {
self.orig_areas.0
}
/// Returns one semifree and the fully free areas. The offset is the number of bytes after
/// which the first area is free.
pub fn free_areas(&self) -> (&'static [MemoryArea], usize) {
self.cur_areas
}
pub fn abs_offset(&self) -> PhysicalAddress {
let (areas, off) = self.cur_areas;
areas
.first()
.map_or(PhysicalAddress::new(0), |a| a.base.add(off))
}
pub fn offset(&self) -> usize {
(self.usage().total().data() - self.usage().free().data()) * A::PAGE_SIZE
}
}
unsafe impl<A: Arch> FrameAllocator for BumpAllocator<A> {
fn allocate(&mut self, count: FrameCount) -> Option<PhysicalAddress> {
unsafe {
let req_size = count.data() * A::PAGE_SIZE;
let block = loop {
let area = self.cur_areas.0.first()?;
let off = self.cur_areas.1;
if area.size - off < req_size {
self.cur_areas = (&self.cur_areas.0[1..], 0);
continue;
}
self.cur_areas.1 += req_size;
break area.base.add(off);
};
A::write_bytes(A::phys_to_virt(block), 0, req_size);
Some(block)
}
}
unsafe fn free(&mut self, _address: PhysicalAddress, _count: FrameCount) {
unimplemented!("BumpAllocator::free not implemented");
}
fn usage(&self) -> FrameUsage {
let total = self.orig_areas.0.iter().map(|a| a.size).sum::<usize>() - self.orig_areas.1;
let free = self.cur_areas.0.iter().map(|a| a.size).sum::<usize>() - self.cur_areas.1;
FrameUsage::new(
FrameCount::new((total - free) / A::PAGE_SIZE),
FrameCount::new(total / A::PAGE_SIZE),
)
}
}
+83
View File
@@ -0,0 +1,83 @@
use crate::PhysicalAddress;
pub use self::{buddy::*, bump::*};
mod buddy;
mod bump;
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct FrameCount(usize);
impl FrameCount {
pub fn new(count: usize) -> Self {
Self(count)
}
pub fn data(&self) -> usize {
self.0
}
}
#[derive(Debug)]
pub struct FrameUsage {
used: FrameCount,
total: FrameCount,
}
impl FrameUsage {
pub fn new(used: FrameCount, total: FrameCount) -> Self {
Self { used, total }
}
pub fn used(&self) -> FrameCount {
self.used
}
pub fn free(&self) -> FrameCount {
FrameCount(self.total.0 - self.used.0)
}
pub fn total(&self) -> FrameCount {
self.total
}
}
pub unsafe trait FrameAllocator {
fn allocate(&mut self, count: FrameCount) -> Option<PhysicalAddress>;
unsafe fn free(&mut self, address: PhysicalAddress, count: FrameCount);
fn allocate_one(&mut self) -> Option<PhysicalAddress> {
self.allocate(FrameCount::new(1))
}
unsafe fn free_one(&mut self, address: PhysicalAddress) {
unsafe {
self.free(address, FrameCount::new(1));
}
}
fn usage(&self) -> FrameUsage;
}
unsafe impl<T> FrameAllocator for &mut T
where
T: FrameAllocator,
{
fn allocate(&mut self, count: FrameCount) -> Option<PhysicalAddress> {
T::allocate(self, count)
}
unsafe fn free(&mut self, address: PhysicalAddress, count: FrameCount) {
unsafe { T::free(self, address, count) }
}
fn allocate_one(&mut self) -> Option<PhysicalAddress> {
T::allocate_one(self)
}
unsafe fn free_one(&mut self, address: PhysicalAddress) {
unsafe { T::free_one(self, address) }
}
fn usage(&self) -> FrameUsage {
T::usage(self)
}
}
+3
View File
@@ -0,0 +1,3 @@
pub use self::frame::*;
mod frame;
+153
View File
@@ -0,0 +1,153 @@
use core::arch::asm;
use crate::{Arch, PhysicalAddress, TableKind, VirtualAddress};
#[derive(Clone, Copy)]
pub struct AArch64Arch;
impl Arch for AArch64Arch {
const KERNEL_SEPARATE_TABLE: bool = true;
const PAGE_SHIFT: usize = 12; // 4096 bytes
const PAGE_ENTRY_SHIFT: usize = 9; // 512 entries, 8 bytes each
const PAGE_LEVELS: usize = 4; // L0, L1, L2, L3
//TODO
const ENTRY_ADDRESS_WIDTH: usize = 40;
const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT
| 1 << 1 // Page flag
| 1 << 10 // Access flag
| Self::ENTRY_FLAG_NO_GLOBAL;
const ENTRY_FLAG_DEFAULT_TABLE: usize
= Self::ENTRY_FLAG_PRESENT
| Self::ENTRY_FLAG_READWRITE
| 1 << 1 // Table flag
| 1 << 10 // Access flag
;
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
const ENTRY_FLAG_READONLY: usize = 1 << 7;
const ENTRY_FLAG_READWRITE: usize = 0;
const ENTRY_FLAG_PAGE_USER: usize = 1 << 6;
// This sets both userspace and privileged execute never
//TODO: Separate the two?
const ENTRY_FLAG_NO_EXEC: usize = 0b11 << 53;
const ENTRY_FLAG_EXEC: usize = 0;
const ENTRY_FLAG_GLOBAL: usize = 0;
const ENTRY_FLAG_NO_GLOBAL: usize = 1 << 11;
const ENTRY_FLAG_DEVICE_MEMORY: usize = MEM_ATTR_DEVICE_nGnRnE << 2;
const ENTRY_FLAG_UNCACHEABLE: usize = MEM_ATTR_NC << 2;
const ENTRY_FLAG_WRITE_COMBINING: usize = MEM_ATTR_NC << 2;
const PHYS_OFFSET: usize = 0xFFFF_8000_0000_0000;
#[inline(always)]
fn invalidate(address: VirtualAddress) {
unsafe {
asm!("
dsb ishst
tlbi vaae1is, {}
dsb ish
isb
", in(reg) (address.data() >> Self::PAGE_SHIFT));
}
}
#[inline(always)]
fn invalidate_all() {
unsafe {
asm!(
"
dsb ishst
tlbi vmalle1is
dsb ish
isb
"
);
}
}
#[inline(always)]
fn table(table_kind: TableKind) -> PhysicalAddress {
let address: usize;
match table_kind {
TableKind::User => {
unsafe { asm!("mrs {0}, ttbr0_el1", out(reg) address) };
}
TableKind::Kernel => {
unsafe { asm!("mrs {0}, ttbr1_el1", out(reg) address) };
}
}
PhysicalAddress::new(address)
}
#[inline(always)]
unsafe fn set_table(table_kind: TableKind, address: PhysicalAddress) {
unsafe {
match table_kind {
TableKind::User => {
asm!("msr ttbr0_el1, {0}", in(reg) address.data());
}
TableKind::Kernel => {
asm!("msr ttbr1_el1, {0}", in(reg) address.data());
}
}
Self::invalidate_all();
}
}
fn virt_is_valid(_address: VirtualAddress) -> bool {
//TODO: what makes an address valid on aarch64?
true
}
}
#[cfg_attr(not(target_arch = "aarch64"), allow(unused))]
const MEM_ATTR_WB: usize = 0;
const MEM_ATTR_NC: usize = 1;
#[allow(non_upper_case_globals)]
const MEM_ATTR_DEVICE_nGnRnE: usize = 2;
/// Setup Memory Access Indirection Register
#[cfg(target_arch = "aarch64")]
#[inline(always)]
pub unsafe fn init_mair() {
// https://github.com/freebsd/freebsd-src/blob/d15733065c4221dcd5bb3622d225760f271f6fc9/sys/arm64/include/armreg.h#L1986-L1991
const fn mair_attr(attr: u64, idx: usize) -> u64 {
attr << (idx * 8)
}
#[allow(non_upper_case_globals)]
const MAIR_DEVICE_nGnRnE: u64 = 0x00;
#[allow(non_upper_case_globals)]
const _MAIR_DEVICE_nGnRE: u64 = 0x04;
const MAIR_NORMAL_NC: u64 = 0x44;
const _MAIR_NORMAL_WT: u64 = 0xbb;
const MAIR_NORMAL_WB: u64 = 0xff;
unsafe {
let val: u64 = const {
mair_attr(MAIR_DEVICE_nGnRnE, MEM_ATTR_DEVICE_nGnRnE)
| mair_attr(MAIR_NORMAL_NC, MEM_ATTR_NC)
| mair_attr(MAIR_NORMAL_WB, MEM_ATTR_WB)
};
asm!("msr mair_el1, {}", in(reg) val);
}
}
const _: () = {
assert!(AArch64Arch::PAGE_SIZE == 4096);
assert!(AArch64Arch::PAGE_OFFSET_MASK == 0xFFF);
assert!(AArch64Arch::PAGE_ADDRESS_SHIFT == 48);
assert!(AArch64Arch::PAGE_ADDRESS_SIZE == 0x0001_0000_0000_0000);
assert!(AArch64Arch::PAGE_ADDRESS_MASK == 0x0000_FFFF_FFFF_F000);
assert!(AArch64Arch::PAGE_ENTRY_SIZE == 8);
assert!(AArch64Arch::PAGE_ENTRIES == 512);
assert!(AArch64Arch::PAGE_ENTRY_MASK == 0x1FF);
assert!(AArch64Arch::PAGE_NEGATIVE_MASK == 0xFFFF_0000_0000_0000);
assert!(AArch64Arch::ENTRY_ADDRESS_SIZE == 0x0000_0100_0000_0000);
assert!(AArch64Arch::ENTRY_ADDRESS_MASK == 0x0000_00FF_FFFF_FFFF);
assert!(AArch64Arch::ENTRY_FLAGS_MASK == 0xFFF0_0000_0000_0FFF);
assert!(AArch64Arch::PHYS_OFFSET == 0xFFFF_8000_0000_0000);
};
+355
View File
@@ -0,0 +1,355 @@
extern crate std;
use std::{boxed::Box, collections::BTreeMap, marker::PhantomData, mem, ptr, sync::Mutex, vec};
use crate::{
arch::x86_64::X8664Arch, page::PageFlags, Arch, MemoryArea, PageEntry, PhysicalAddress,
TableKind, VirtualAddress, MEGABYTE,
};
#[derive(Clone, Copy)]
pub struct EmulateArch;
impl EmulateArch {
pub unsafe fn init() -> &'static [MemoryArea] {
unsafe {
// Create machine with PAGE_ENTRIES pages offset mapped (2 MiB on x86_64)
let mut machine = Machine::new(MEMORY_SIZE);
// PML4 index 256 (PHYS_OFFSET) link to PDP
let pml4 = 0;
let pdp = pml4 + Self::PAGE_SIZE;
let flags = Self::ENTRY_FLAG_READWRITE | Self::ENTRY_FLAG_PRESENT;
machine.write_phys::<usize>(
PhysicalAddress::new(pml4 + 256 * Self::PAGE_ENTRY_SIZE),
pdp | flags,
);
// PDP link to PD
let pd = pdp + Self::PAGE_SIZE;
machine.write_phys::<usize>(PhysicalAddress::new(pdp), pd | flags);
// PD link to PT
let pt = pd + Self::PAGE_SIZE;
machine.write_phys::<usize>(PhysicalAddress::new(pd), pt | flags);
// PT links to frames
for i in 0..Self::PAGE_ENTRIES {
let page = i * Self::PAGE_SIZE;
machine.write_phys::<usize>(
PhysicalAddress::new(pt + i * Self::PAGE_ENTRY_SIZE),
page | flags,
);
}
*MACHINE.lock().unwrap() = Some(machine);
// Set table to pml4
EmulateArch::set_table(TableKind::Kernel, PhysicalAddress::new(pml4));
&MEMORY_AREAS
}
}
}
impl Arch for EmulateArch {
const KERNEL_SEPARATE_TABLE: bool = false;
const PAGE_SHIFT: usize = X8664Arch::PAGE_SHIFT;
const PAGE_ENTRY_SHIFT: usize = X8664Arch::PAGE_ENTRY_SHIFT;
const PAGE_LEVELS: usize = X8664Arch::PAGE_LEVELS;
const ENTRY_ADDRESS_SHIFT: usize = X8664Arch::ENTRY_ADDRESS_SHIFT;
const ENTRY_FLAG_DEFAULT_PAGE: usize = X8664Arch::ENTRY_FLAG_DEFAULT_PAGE;
const ENTRY_FLAG_DEFAULT_TABLE: usize = X8664Arch::ENTRY_FLAG_DEFAULT_TABLE;
const ENTRY_FLAG_PRESENT: usize = X8664Arch::ENTRY_FLAG_PRESENT;
const ENTRY_FLAG_READONLY: usize = X8664Arch::ENTRY_FLAG_READONLY;
const ENTRY_FLAG_READWRITE: usize = X8664Arch::ENTRY_FLAG_READWRITE;
const ENTRY_FLAG_PAGE_USER: usize = X8664Arch::ENTRY_FLAG_PAGE_USER;
const ENTRY_FLAG_NO_EXEC: usize = X8664Arch::ENTRY_FLAG_NO_EXEC;
const ENTRY_FLAG_EXEC: usize = X8664Arch::ENTRY_FLAG_EXEC;
const PHYS_OFFSET: usize = X8664Arch::PHYS_OFFSET;
const ENTRY_FLAG_GLOBAL: usize = X8664Arch::ENTRY_FLAG_GLOBAL;
const ENTRY_FLAG_NO_GLOBAL: usize = X8664Arch::ENTRY_FLAG_NO_GLOBAL;
const ENTRY_ADDRESS_WIDTH: usize = X8664Arch::ENTRY_ADDRESS_WIDTH;
const ENTRY_FLAG_DEVICE_MEMORY: usize = X8664Arch::ENTRY_FLAG_DEVICE_MEMORY;
const ENTRY_FLAG_UNCACHEABLE: usize = X8664Arch::ENTRY_FLAG_UNCACHEABLE;
const ENTRY_FLAG_WRITE_COMBINING: usize = X8664Arch::ENTRY_FLAG_WRITE_COMBINING;
#[inline(always)]
unsafe fn read<T>(address: VirtualAddress) -> T {
MACHINE.lock().unwrap().as_ref().unwrap().read(address)
}
#[inline(always)]
unsafe fn write<T>(address: VirtualAddress, value: T) {
MACHINE
.lock()
.unwrap()
.as_mut()
.unwrap()
.write(address, value)
}
#[inline(always)]
unsafe fn write_bytes(address: VirtualAddress, value: u8, count: usize) {
MACHINE
.lock()
.unwrap()
.as_mut()
.unwrap()
.write_bytes(address, value, count)
}
#[inline(always)]
fn invalidate(address: VirtualAddress) {
MACHINE
.lock()
.unwrap()
.as_mut()
.unwrap()
.invalidate(address);
}
#[inline(always)]
fn invalidate_all() {
MACHINE.lock().unwrap().as_mut().unwrap().invalidate_all();
}
#[inline(always)]
fn table(_table_kind: TableKind) -> PhysicalAddress {
MACHINE.lock().unwrap().as_mut().unwrap().get_table()
}
#[inline(always)]
unsafe fn set_table(_table_kind: TableKind, address: PhysicalAddress) {
MACHINE.lock().unwrap().as_mut().unwrap().set_table(address);
}
fn virt_is_valid(_address: VirtualAddress) -> bool {
// TODO: Don't see why an emulated arch would have any problems with canonicalness...
true
}
}
const MEMORY_SIZE: usize = 64 * MEGABYTE;
static MEMORY_AREAS: [MemoryArea; 2] = [
MemoryArea {
base: PhysicalAddress::new(EmulateArch::PAGE_SIZE * 4), // Initial PML4, PDP, PD, and PT wasted
size: MEMORY_SIZE / 2 - EmulateArch::PAGE_SIZE * 4,
},
// Second area for debugging
MemoryArea {
base: PhysicalAddress::new(MEMORY_SIZE / 2),
size: MEMORY_SIZE / 2,
},
];
static MACHINE: Mutex<Option<Machine<EmulateArch>>> = Mutex::new(None);
struct Machine<A> {
memory: Box<[u8]>,
map: BTreeMap<VirtualAddress, PageEntry<A>>,
table_addr: PhysicalAddress,
phantom: PhantomData<A>,
}
impl<A: Arch> Machine<A> {
fn new(memory_size: usize) -> Self {
Self {
memory: vec![0; memory_size].into_boxed_slice(),
map: BTreeMap::new(),
table_addr: PhysicalAddress::new(0),
phantom: PhantomData,
}
}
fn read_phys<T>(&self, phys: PhysicalAddress) -> T {
let size = mem::size_of::<T>();
if phys.add(size).data() <= self.memory.len() {
unsafe { ptr::read(self.memory.as_ptr().add(phys.data()) as *const T) }
} else {
panic!(
"read_phys: 0x{:X} size 0x{:X} outside of memory",
phys.data(),
size
);
}
}
fn write_phys<T>(&mut self, phys: PhysicalAddress, value: T) {
let size = mem::size_of::<T>();
if phys.add(size).data() <= self.memory.len() {
unsafe {
ptr::write(self.memory.as_mut_ptr().add(phys.data()) as *mut T, value);
}
} else {
panic!(
"write_phys: 0x{:X} size 0x{:X} outside of memory",
phys.data(),
size
);
}
}
fn write_phys_bytes(&mut self, phys: PhysicalAddress, value: u8, count: usize) {
if phys.add(count).data() <= self.memory.len() {
unsafe {
ptr::write_bytes(self.memory.as_mut_ptr().add(phys.data()), value, count);
}
} else {
panic!(
"write_phys_bytes: 0x{:X} count 0x{:X} outside of memory",
phys.data(),
count
);
}
}
fn translate(&self, virt: VirtualAddress) -> Option<(PhysicalAddress, PageFlags<A>)> {
let virt_data = virt.data();
let page = virt_data & A::PAGE_ADDRESS_MASK;
let offset = virt_data & A::PAGE_OFFSET_MASK;
let entry = self.map.get(&VirtualAddress::new(page))?;
Some((entry.address().ok()?.add(offset), entry.flags()))
}
fn read<T>(&self, virt: VirtualAddress) -> T {
//TODO: allow reading past page boundaries
let virt_data = virt.data();
let size = mem::size_of::<T>();
if (virt_data & A::PAGE_ADDRESS_MASK) != ((virt_data + (size - 1)) & A::PAGE_ADDRESS_MASK) {
panic!(
"read: 0x{:X} size 0x{:X} passes page boundary",
virt_data, size
);
}
if let Some((phys, _flags)) = self.translate(virt) {
self.read_phys(phys)
} else {
panic!("read: 0x{:X} size 0x{:X} not present", virt_data, size);
}
}
fn write<T>(&mut self, virt: VirtualAddress, value: T) {
//TODO: allow writing past page boundaries
let virt_data = virt.data();
let size = mem::size_of::<T>();
if (virt_data & A::PAGE_ADDRESS_MASK) != ((virt_data + (size - 1)) & A::PAGE_ADDRESS_MASK) {
panic!(
"write: 0x{:X} size 0x{:X} passes page boundary",
virt_data, size
);
}
if let Some((phys, flags)) = self.translate(virt) {
if flags.has_write() {
self.write_phys(phys, value);
} else {
panic!("write: 0x{:X} size 0x{:X} not writable", virt_data, size);
}
} else {
panic!("write: 0x{:X} size 0x{:X} not present", virt_data, size);
}
}
fn write_bytes(&mut self, virt: VirtualAddress, value: u8, count: usize) {
//TODO: allow writing past page boundaries
let virt_data = virt.data();
if (virt_data & A::PAGE_ADDRESS_MASK) != ((virt_data + (count - 1)) & A::PAGE_ADDRESS_MASK)
{
panic!(
"write_bytes: 0x{:X} count 0x{:X} passes page boundary",
virt_data, count
);
}
if let Some((phys, flags)) = self.translate(virt) {
if flags.has_write() {
self.write_phys_bytes(phys, value, count);
} else {
panic!(
"write_bytes: 0x{:X} count 0x{:X} not writable",
virt_data, count
);
}
} else {
panic!(
"write_bytes: 0x{:X} count 0x{:X} not present",
virt_data, count
);
}
}
fn invalidate(&mut self, _address: VirtualAddress) {
unimplemented!("EmulateArch::invalidate not implemented");
}
//TODO: cleanup
fn invalidate_all(&mut self) {
self.map.clear();
// PML4
let a4 = self.table_addr.data();
for i4 in 0..A::PAGE_ENTRIES {
let e3 = self.read_phys::<usize>(PhysicalAddress::new(a4 + i4 * A::PAGE_ENTRY_SIZE));
let f3 = e3 & A::ENTRY_FLAGS_MASK;
if f3 & A::ENTRY_FLAG_PRESENT == 0 {
continue;
}
// Page directory pointer
let a3 = ((e3 >> A::ENTRY_ADDRESS_SHIFT) & A::ENTRY_ADDRESS_MASK) << A::PAGE_SHIFT;
for i3 in 0..A::PAGE_ENTRIES {
let e2 =
self.read_phys::<usize>(PhysicalAddress::new(a3 + i3 * A::PAGE_ENTRY_SIZE));
let f2 = e2 & A::ENTRY_FLAGS_MASK;
if f2 & A::ENTRY_FLAG_PRESENT == 0 {
continue;
}
// Page directory
let a2 = ((e2 >> A::ENTRY_ADDRESS_SHIFT) & A::ENTRY_ADDRESS_MASK) << A::PAGE_SHIFT;
for i2 in 0..A::PAGE_ENTRIES {
let e1 =
self.read_phys::<usize>(PhysicalAddress::new(a2 + i2 * A::PAGE_ENTRY_SIZE));
let f1 = e1 & A::ENTRY_FLAGS_MASK;
if f1 & A::ENTRY_FLAG_PRESENT == 0 {
continue;
}
// Page table
let a1 =
((e1 >> A::ENTRY_ADDRESS_SHIFT) & A::ENTRY_ADDRESS_MASK) << A::PAGE_SHIFT;
for i1 in 0..A::PAGE_ENTRIES {
let e = self
.read_phys::<usize>(PhysicalAddress::new(a1 + i1 * A::PAGE_ENTRY_SIZE));
let f = e & A::ENTRY_FLAGS_MASK;
if f & A::ENTRY_FLAG_PRESENT == 0 {
continue;
}
// Page
let page = (i4 << 39) | (i3 << 30) | (i2 << 21) | (i1 << 12);
//println!("map 0x{:X} to 0x{:X}, 0x{:X}", page, a, f);
self.map
.insert(VirtualAddress::new(page), PageEntry::from_data(e));
}
}
}
}
}
fn get_table(&self) -> PhysicalAddress {
self.table_addr
}
fn set_table(&mut self, address: PhysicalAddress) {
self.table_addr = address;
self.invalidate_all();
}
}
+93
View File
@@ -0,0 +1,93 @@
use core::ptr;
use crate::{PhysicalAddress, TableKind, VirtualAddress};
//TODO: Support having all page tables compile on all architectures
#[cfg(target_pointer_width = "64")]
pub mod aarch64;
#[cfg(all(feature = "std", target_pointer_width = "64"))]
pub mod emulate;
#[cfg(target_pointer_width = "64")]
pub mod riscv64;
#[cfg(target_pointer_width = "32")]
pub mod x86;
#[cfg(target_pointer_width = "64")]
pub mod x86_64;
mod x86_shared;
pub trait Arch: Clone + Copy {
/// Does the architecture use a separate page table for the kernel.
///
/// If false, the page table entries corresponding to the top half of the
/// address space will be copied into the top level of every page table
/// and will never be unmapped when unmapping pages.
const KERNEL_SEPARATE_TABLE: bool;
const PAGE_SHIFT: usize;
const PAGE_ENTRY_SHIFT: usize;
const PAGE_LEVELS: usize;
const ENTRY_ADDRESS_WIDTH: usize; // Number of bits of physical address in PTE
const ENTRY_ADDRESS_SHIFT: usize = Self::PAGE_SHIFT; // Offset of physical address in PTE
const ENTRY_FLAG_DEFAULT_PAGE: usize;
const ENTRY_FLAG_DEFAULT_TABLE: usize;
const ENTRY_FLAG_PRESENT: usize;
const ENTRY_FLAG_READONLY: usize;
const ENTRY_FLAG_READWRITE: usize;
const ENTRY_FLAG_PAGE_USER: usize; // Leaf table user page flag
const ENTRY_FLAG_TABLE_USER: usize = Self::ENTRY_FLAG_PAGE_USER; // Directory user page table flag
const ENTRY_FLAG_NO_EXEC: usize;
const ENTRY_FLAG_EXEC: usize;
const ENTRY_FLAG_GLOBAL: usize;
const ENTRY_FLAG_NO_GLOBAL: usize;
const ENTRY_FLAG_DEVICE_MEMORY: usize;
const ENTRY_FLAG_UNCACHEABLE: usize;
const ENTRY_FLAG_WRITE_COMBINING: usize;
const PHYS_OFFSET: usize;
const PAGE_SIZE: usize = 1 << Self::PAGE_SHIFT;
const PAGE_OFFSET_MASK: usize = Self::PAGE_SIZE - 1;
const PAGE_ADDRESS_SHIFT: usize = Self::PAGE_LEVELS * Self::PAGE_ENTRY_SHIFT + Self::PAGE_SHIFT;
const PAGE_ADDRESS_SIZE: u64 = 1 << (Self::PAGE_ADDRESS_SHIFT as u64);
const PAGE_ADDRESS_MASK: usize = (Self::PAGE_ADDRESS_SIZE - (Self::PAGE_SIZE as u64)) as usize;
const PAGE_ENTRY_SIZE: usize = 1 << (Self::PAGE_SHIFT - Self::PAGE_ENTRY_SHIFT);
const PAGE_ENTRIES: usize = 1 << Self::PAGE_ENTRY_SHIFT;
const PAGE_ENTRY_MASK: usize = Self::PAGE_ENTRIES - 1;
const PAGE_NEGATIVE_MASK: usize = !(Self::PAGE_ADDRESS_SIZE - 1) as usize;
const ENTRY_ADDRESS_SIZE: usize = 1 << Self::ENTRY_ADDRESS_WIDTH; // size of addressable physical memory, in pages
const ENTRY_ADDRESS_MASK: usize = Self::ENTRY_ADDRESS_SIZE - 1; // Mask of physical address, starting at 0th bit
const ENTRY_FLAGS_MASK: usize = !(Self::ENTRY_ADDRESS_MASK << Self::ENTRY_ADDRESS_SHIFT);
#[inline(always)]
unsafe fn read<T>(address: VirtualAddress) -> T {
unsafe { ptr::read(address.data() as *const T) }
}
#[inline(always)]
unsafe fn write<T>(address: VirtualAddress, value: T) {
unsafe { ptr::write(address.data() as *mut T, value) }
}
#[inline(always)]
unsafe fn write_bytes(address: VirtualAddress, value: u8, count: usize) {
unsafe { ptr::write_bytes(address.data() as *mut u8, value, count) }
}
fn invalidate(address: VirtualAddress);
fn invalidate_all();
fn table(table_kind: TableKind) -> PhysicalAddress;
unsafe fn set_table(table_kind: TableKind, address: PhysicalAddress);
#[inline(always)]
fn phys_to_virt(phys: PhysicalAddress) -> VirtualAddress {
match phys.data().checked_add(Self::PHYS_OFFSET) {
Some(some) => VirtualAddress::new(some),
None => panic!("phys_to_virt({:#x}) overflow", phys.data()),
}
}
fn virt_is_valid(address: VirtualAddress) -> bool;
}
+7
View File
@@ -0,0 +1,7 @@
pub use sv39::RiscV64Sv39Arch;
pub use sv48::RiscV64Sv48Arch;
pub use sv57::RiscV64Sv57Arch;
mod sv39;
mod sv48;
mod sv57;
+124
View File
@@ -0,0 +1,124 @@
use core::arch::asm;
use crate::{Arch, PhysicalAddress, TableKind, VirtualAddress};
#[derive(Clone, Copy)]
pub struct RiscV64Sv39Arch;
pub const ACCESSED: usize = 1 << 6;
pub const DIRTY: usize = 1 << 7;
impl Arch for RiscV64Sv39Arch {
const KERNEL_SEPARATE_TABLE: bool = false;
const PAGE_SHIFT: usize = 12; // 4096 bytes
const PAGE_ENTRY_SHIFT: usize = 9; // 512 entries, 8 bytes each
const PAGE_LEVELS: usize = 3; // L0, L1, L2
const ENTRY_ADDRESS_WIDTH: usize = 44;
const ENTRY_ADDRESS_SHIFT: usize = 10;
const ENTRY_FLAG_DEFAULT_PAGE: usize =
Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READONLY | ACCESSED | DIRTY;
const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT;
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
const ENTRY_FLAG_READONLY: usize = 1 << 1;
const ENTRY_FLAG_READWRITE: usize = 3 << 1;
const ENTRY_FLAG_PAGE_USER: usize = 1 << 4;
const ENTRY_FLAG_TABLE_USER: usize = 0;
const ENTRY_FLAG_NO_EXEC: usize = 0;
const ENTRY_FLAG_EXEC: usize = 1 << 3;
const ENTRY_FLAG_GLOBAL: usize = 1 << 5;
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_UNCACHEABLE: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_WRITE_COMBINING: usize = 0; // FIXME use Svpbmt
const PHYS_OFFSET: usize = 0xFFFF_FFC0_0000_0000;
#[inline(always)]
fn invalidate(address: VirtualAddress) {
unsafe { asm!("sfence.vma {}", in(reg) address.data()) };
}
#[inline(always)]
fn invalidate_all() {
unsafe { asm!("sfence.vma") };
}
#[inline(always)]
fn table(_table_kind: TableKind) -> PhysicalAddress {
let satp: usize;
unsafe { asm!("csrr {0}, satp", out(reg) satp) };
PhysicalAddress::new(
(satp & Self::ENTRY_ADDRESS_MASK) << Self::PAGE_SHIFT, // Convert from PPN
)
}
#[inline(always)]
unsafe fn set_table(_table_kind: TableKind, address: PhysicalAddress) {
let satp = (8 << 60) | // Sv39 MODE
(address.data() >> Self::PAGE_SHIFT); // Convert to PPN (TODO: ensure alignment)
unsafe {
asm!("csrw satp, {0}", in(reg) satp);
Self::invalidate_all();
}
}
fn virt_is_valid(address: VirtualAddress) -> bool {
let mask = !((Self::PAGE_ADDRESS_SIZE as usize - 1) >> 1);
let masked = address.data() & mask;
masked == mask || masked == 0
}
}
const _: () = {
assert!(RiscV64Sv39Arch::PAGE_SIZE == 4096);
assert!(RiscV64Sv39Arch::PAGE_OFFSET_MASK == 0xFFF);
assert!(RiscV64Sv39Arch::PAGE_ADDRESS_SHIFT == 39);
assert!(RiscV64Sv39Arch::PAGE_ADDRESS_SIZE == 0x0000_0080_0000_0000);
assert!(RiscV64Sv39Arch::PAGE_ADDRESS_MASK == 0x0000_007F_FFFF_F000);
assert!(RiscV64Sv39Arch::PAGE_ENTRY_SIZE == 8);
assert!(RiscV64Sv39Arch::PAGE_ENTRIES == 512);
assert!(RiscV64Sv39Arch::PAGE_ENTRY_MASK == 0x1FF);
assert!(RiscV64Sv39Arch::PAGE_NEGATIVE_MASK == 0xFFFF_FF80_0000_0000);
assert!(RiscV64Sv39Arch::ENTRY_ADDRESS_SIZE == 0x0000_1000_0000_0000);
assert!(RiscV64Sv39Arch::ENTRY_ADDRESS_MASK == 0x0000_0FFF_FFFF_FFFF);
assert!(RiscV64Sv39Arch::ENTRY_FLAGS_MASK == 0xFFC0_0000_0000_03FF);
assert!(RiscV64Sv39Arch::PHYS_OFFSET == 0xFFFF_FFC0_0000_0000);
};
#[cfg(test)]
mod tests {
use super::RiscV64Sv39Arch;
use crate::Arch;
#[test]
fn is_canonical() {
use super::VirtualAddress;
#[track_caller]
fn yes(addr: usize) {
assert!(RiscV64Sv39Arch::virt_is_valid(VirtualAddress::new(addr)));
}
#[track_caller]
fn no(addr: usize) {
assert!(!RiscV64Sv39Arch::virt_is_valid(VirtualAddress::new(addr)));
}
yes(0xFFFF_FFFF_FFFF_FFFF);
yes(0xFFFF_FFF0_1337_1337);
no(0x0000_0F00_0000_0000);
no(0x1337_0000_0000_0000);
no(1 << 38);
yes(1 << 37);
// Check for off-by-one errors.
yes(0xFFFF_FFC0_0000_0000 | (1 << 37));
yes(0xFFFF_FFE0_0000_0000 | (1 << 37));
no(0xFFFF_FF80_0000_0000 | (1 << 37));
}
}
+118
View File
@@ -0,0 +1,118 @@
use core::arch::asm;
use crate::{Arch, PhysicalAddress, TableKind, VirtualAddress};
#[derive(Clone, Copy)]
pub struct RiscV64Sv48Arch;
impl Arch for RiscV64Sv48Arch {
const KERNEL_SEPARATE_TABLE: bool = false;
const PAGE_SHIFT: usize = 12; // 4096 bytes
const PAGE_ENTRY_SHIFT: usize = 9; // 512 entries, 8 bytes each
const PAGE_LEVELS: usize = 4; // L0, L1, L2, L3
const ENTRY_ADDRESS_WIDTH: usize = 44;
const ENTRY_ADDRESS_SHIFT: usize = 10;
const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READONLY;
const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT;
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
const ENTRY_FLAG_READONLY: usize = 1 << 1;
const ENTRY_FLAG_READWRITE: usize = 3 << 1;
const ENTRY_FLAG_PAGE_USER: usize = 1 << 4;
const ENTRY_FLAG_TABLE_USER: usize = 0;
const ENTRY_FLAG_NO_EXEC: usize = 0;
const ENTRY_FLAG_EXEC: usize = 1 << 3;
const ENTRY_FLAG_GLOBAL: usize = 1 << 5;
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_UNCACHEABLE: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_WRITE_COMBINING: usize = 0; // FIXME use Svpbmt
const PHYS_OFFSET: usize = 0xFFFF_8000_0000_0000;
#[inline(always)]
fn invalidate(address: VirtualAddress) {
unsafe { asm!("sfence.vma {}", in(reg) address.data()) };
}
#[inline(always)]
fn invalidate_all() {
unsafe { asm!("sfence.vma") };
}
#[inline(always)]
fn table(_table_kind: TableKind) -> PhysicalAddress {
let satp: usize;
unsafe { asm!("csrr {0}, satp", out(reg) satp) };
PhysicalAddress::new(
(satp & Self::ENTRY_ADDRESS_MASK) << Self::PAGE_SHIFT, // Convert from PPN
)
}
#[inline(always)]
unsafe fn set_table(_table_kind: TableKind, address: PhysicalAddress) {
let satp = (9 << 60) | // Sv48 MODE
(address.data() >> Self::PAGE_SHIFT); // Convert to PPN (TODO: ensure alignment)
unsafe {
asm!("csrw satp, {0}", in(reg) satp);
Self::invalidate_all();
}
}
fn virt_is_valid(address: VirtualAddress) -> bool {
// RISC-V SV48 uses 48-bit sign-extended addresses, identical to 4-level paging on x86_64.
let mask = !((Self::PAGE_ADDRESS_SIZE as usize - 1) >> 1);
let masked = address.data() & mask;
masked == mask || masked == 0
}
}
const _: () = {
assert!(RiscV64Sv48Arch::PAGE_SIZE == 4096);
assert!(RiscV64Sv48Arch::PAGE_OFFSET_MASK == 0xFFF);
assert!(RiscV64Sv48Arch::PAGE_ADDRESS_SHIFT == 48);
assert!(RiscV64Sv48Arch::PAGE_ADDRESS_SIZE == 0x0001_0000_0000_0000);
assert!(RiscV64Sv48Arch::PAGE_ADDRESS_MASK == 0x0000_FFFF_FFFF_F000);
assert!(RiscV64Sv48Arch::PAGE_ENTRY_SIZE == 8);
assert!(RiscV64Sv48Arch::PAGE_ENTRIES == 512);
assert!(RiscV64Sv48Arch::PAGE_ENTRY_MASK == 0x1FF);
assert!(RiscV64Sv48Arch::PAGE_NEGATIVE_MASK == 0xFFFF_0000_0000_0000);
assert!(RiscV64Sv48Arch::ENTRY_ADDRESS_SIZE == 0x0000_1000_0000_0000);
assert!(RiscV64Sv48Arch::ENTRY_ADDRESS_MASK == 0x0000_0FFF_FFFF_FFFF);
assert!(RiscV64Sv48Arch::ENTRY_FLAGS_MASK == 0xFFC0_0000_0000_03FF);
assert!(RiscV64Sv48Arch::PHYS_OFFSET == 0xFFFF_8000_0000_0000);
};
#[cfg(test)]
mod tests {
use super::RiscV64Sv48Arch;
use crate::Arch;
#[test]
fn is_canonical() {
use super::VirtualAddress;
// Close to identical when compared to x86_64 test.
fn yes(address: usize) {
assert!(RiscV64Sv48Arch::virt_is_valid(VirtualAddress::new(address)));
}
fn no(address: usize) {
assert!(!RiscV64Sv48Arch::virt_is_valid(VirtualAddress::new(
address
)));
}
yes(0xFFFF_8000_1337_1337);
yes(0xFFFF_FFFF_FFFF_FFFF);
yes(0x0000_0000_0000_0042);
yes(0x0000_7FFF_FFFF_FFFF);
no(0x1337_0000_0000_0000);
no(0x1337_8000_0000_0000);
no(0x0000_8000_0000_0000);
}
}
+116
View File
@@ -0,0 +1,116 @@
use core::arch::asm;
use crate::{Arch, PhysicalAddress, TableKind, VirtualAddress};
#[derive(Clone, Copy)]
pub struct RiscV64Sv57Arch;
impl Arch for RiscV64Sv57Arch {
const KERNEL_SEPARATE_TABLE: bool = false;
const PAGE_SHIFT: usize = 12; // 4096 bytes
const PAGE_ENTRY_SHIFT: usize = 9; // 512 entries, 8 bytes each
const PAGE_LEVELS: usize = 5; // L0, L1, L2, L3, L4
const ENTRY_ADDRESS_WIDTH: usize = 44;
const ENTRY_ADDRESS_SHIFT: usize = 10;
const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READONLY;
const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT;
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
const ENTRY_FLAG_READONLY: usize = 1 << 1;
const ENTRY_FLAG_READWRITE: usize = 3 << 1;
const ENTRY_FLAG_PAGE_USER: usize = 1 << 4;
const ENTRY_FLAG_TABLE_USER: usize = 0;
const ENTRY_FLAG_NO_EXEC: usize = 0;
const ENTRY_FLAG_EXEC: usize = 1 << 3;
const ENTRY_FLAG_GLOBAL: usize = 1 << 5;
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_UNCACHEABLE: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_WRITE_COMBINING: usize = 0; // FIXME use Svpbmt
const PHYS_OFFSET: usize = 0xFF00_0000_0000_0000;
#[inline(always)]
fn invalidate(address: VirtualAddress) {
unsafe { asm!("sfence.vma {}", in(reg) address.data()) };
}
#[inline(always)]
fn invalidate_all() {
unsafe { asm!("sfence.vma") };
}
#[inline(always)]
fn table(_table_kind: TableKind) -> PhysicalAddress {
let satp: usize;
unsafe { asm!("csrr {0}, satp", out(reg) satp) };
PhysicalAddress::new(
(satp & Self::ENTRY_ADDRESS_MASK) << Self::PAGE_SHIFT, // Convert from PPN
)
}
#[inline(always)]
unsafe fn set_table(_table_kind: TableKind, address: PhysicalAddress) {
let satp = (10 << 60) | // Sv57 MODE
(address.data() >> Self::PAGE_SHIFT); // Convert to PPN (TODO: ensure alignment)
unsafe {
asm!("csrw satp, {0}", in(reg) satp);
Self::invalidate_all();
}
}
fn virt_is_valid(address: VirtualAddress) -> bool {
let mask = !((Self::PAGE_ADDRESS_SIZE as usize - 1) >> 1);
let masked = address.data() & mask;
masked == mask || masked == 0
}
}
const _: () = {
assert!(RiscV64Sv57Arch::PAGE_SIZE == 4096);
assert!(RiscV64Sv57Arch::PAGE_OFFSET_MASK == 0xFFF);
assert!(RiscV64Sv57Arch::PAGE_ADDRESS_SHIFT == 57);
assert!(RiscV64Sv57Arch::PAGE_ADDRESS_SIZE == 0x0200_0000_0000_0000);
assert!(RiscV64Sv57Arch::PAGE_ADDRESS_MASK == 0x01FF_FFFF_FFFF_F000);
assert!(RiscV64Sv57Arch::PAGE_ENTRY_SIZE == 8);
assert!(RiscV64Sv57Arch::PAGE_ENTRIES == 512);
assert!(RiscV64Sv57Arch::PAGE_ENTRY_MASK == 0x1FF);
assert!(RiscV64Sv57Arch::PAGE_NEGATIVE_MASK == 0xFE00_0000_0000_0000);
assert!(RiscV64Sv57Arch::ENTRY_ADDRESS_SIZE == 0x0000_1000_0000_0000);
assert!(RiscV64Sv57Arch::ENTRY_ADDRESS_MASK == 0x0000_0FFF_FFFF_FFFF);
assert!(RiscV64Sv57Arch::ENTRY_FLAGS_MASK == 0xFFC0_0000_0000_03FF);
assert!(RiscV64Sv57Arch::PHYS_OFFSET == 0xFF00_0000_0000_0000);
};
#[cfg(test)]
mod tests {
use super::RiscV64Sv57Arch;
use crate::Arch;
#[test]
fn is_canonical() {
use super::VirtualAddress;
fn yes(address: usize) {
assert!(RiscV64Sv57Arch::virt_is_valid(VirtualAddress::new(address)));
}
fn no(address: usize) {
assert!(!RiscV64Sv57Arch::virt_is_valid(VirtualAddress::new(
address
)));
}
yes(0xFF00_0000_1337_1337);
yes(0xFFFF_FFFF_FFFF_FFFF);
yes(0x0000_0000_0000_0042);
yes(0x00FF_FFFF_FFFF_FFFF);
no(0x1337_0000_0000_0000);
no(0x1337_8000_0000_0000);
no(0x0F00_0000_0000_0000);
}
}
+80
View File
@@ -0,0 +1,80 @@
//TODO: USE PAE
use core::arch::asm;
use crate::{Arch, PhysicalAddress, TableKind, VirtualAddress};
#[derive(Clone, Copy)]
pub struct X86Arch;
impl Arch for X86Arch {
const KERNEL_SEPARATE_TABLE: bool = false;
const PAGE_SHIFT: usize = 12; // 4096 bytes
const PAGE_ENTRY_SHIFT: usize = 10; // 1024 entries, 4 bytes each
const PAGE_LEVELS: usize = 2; // PD, PT
const ENTRY_ADDRESS_WIDTH: usize = 20;
const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT;
const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READWRITE;
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
const ENTRY_FLAG_READONLY: usize = 0;
const ENTRY_FLAG_READWRITE: usize = 1 << 1;
const ENTRY_FLAG_PAGE_USER: usize = 1 << 2;
// Not used: const ENTRY_FLAG_HUGE: usize = 1 << 7;
const ENTRY_FLAG_GLOBAL: usize = 1 << 8;
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
const ENTRY_FLAG_NO_EXEC: usize = 0; // NOT AVAILABLE UNLESS PAE IS USED!
const ENTRY_FLAG_EXEC: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = PAT_UC_;
const ENTRY_FLAG_UNCACHEABLE: usize = PAT_UC_;
const ENTRY_FLAG_WRITE_COMBINING: usize = PAT_WC;
const PHYS_OFFSET: usize = 0x8000_0000;
#[inline(always)]
fn invalidate(address: VirtualAddress) {
unsafe { asm!("invlpg [{0}]", in(reg) address.data()) };
}
#[inline(always)]
fn invalidate_all() {
unsafe { Self::set_table(TableKind::User, Self::table(TableKind::User)) };
}
#[inline(always)]
fn table(_table_kind: TableKind) -> PhysicalAddress {
let address: usize;
unsafe { asm!("mov {0}, cr3", out(reg) address) };
PhysicalAddress::new(address)
}
#[inline(always)]
unsafe fn set_table(_table_kind: TableKind, address: PhysicalAddress) {
unsafe { asm!("mov cr3, {0}", in(reg) address.data()) };
}
fn virt_is_valid(_address: VirtualAddress) -> bool {
// On 32-bit x86, every virtual address is valid
true
}
}
pub use super::x86_shared::*;
const _: () = {
assert!(X86Arch::PAGE_SIZE == 4096);
assert!(X86Arch::PAGE_OFFSET_MASK == 0xFFF);
assert!(X86Arch::PAGE_ADDRESS_SHIFT == 32);
assert!(X86Arch::PAGE_ADDRESS_SIZE == 0x0000_0001_0000_0000);
assert!(X86Arch::PAGE_ADDRESS_MASK == 0xFFFF_F000);
assert!(X86Arch::PAGE_ENTRY_SIZE == 4);
assert!(X86Arch::PAGE_ENTRIES == 1024);
assert!(X86Arch::PAGE_ENTRY_MASK == 0x3FF);
assert!(X86Arch::PAGE_NEGATIVE_MASK == 0x0000_0000_0000);
assert!(X86Arch::ENTRY_ADDRESS_SIZE == 0x0000_0000_0010_0000);
assert!(X86Arch::ENTRY_ADDRESS_MASK == 0x000F_FFFF);
assert!(X86Arch::ENTRY_FLAGS_MASK == 0x0000_0FFF);
assert!(X86Arch::PHYS_OFFSET == 0x8000_0000);
};
+107
View File
@@ -0,0 +1,107 @@
use core::arch::asm;
use crate::{Arch, PhysicalAddress, TableKind, VirtualAddress};
#[derive(Clone, Copy, Debug)]
pub struct X8664Arch;
impl Arch for X8664Arch {
const KERNEL_SEPARATE_TABLE: bool = false;
const PAGE_SHIFT: usize = 12; // 4096 bytes
const PAGE_ENTRY_SHIFT: usize = 9; // 512 entries, 8 bytes each
const PAGE_LEVELS: usize = 4; // PML4, PDP, PD, PT
const ENTRY_ADDRESS_WIDTH: usize = 40;
const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT;
const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READWRITE;
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
const ENTRY_FLAG_READONLY: usize = 0;
const ENTRY_FLAG_READWRITE: usize = 1 << 1;
const ENTRY_FLAG_PAGE_USER: usize = 1 << 2;
// Not used: const ENTRY_FLAG_HUGE: usize = 1 << 7;
const ENTRY_FLAG_GLOBAL: usize = 1 << 8;
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
const ENTRY_FLAG_NO_EXEC: usize = 1 << 63;
const ENTRY_FLAG_EXEC: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = PAT_UC_;
const ENTRY_FLAG_UNCACHEABLE: usize = PAT_UC_;
const ENTRY_FLAG_WRITE_COMBINING: usize = PAT_WC;
const PHYS_OFFSET: usize = Self::PAGE_NEGATIVE_MASK + (Self::PAGE_ADDRESS_SIZE >> 1) as usize; // PML4 slot 256 and onwards
#[inline(always)]
fn invalidate(address: VirtualAddress) {
unsafe { asm!("invlpg [{0}]", in(reg) address.data()) };
}
#[inline(always)]
fn invalidate_all() {
unsafe { Self::set_table(TableKind::User, Self::table(TableKind::User)) };
}
#[inline(always)]
fn table(_table_kind: TableKind) -> PhysicalAddress {
let address: usize;
unsafe { asm!("mov {0}, cr3", out(reg) address) };
PhysicalAddress::new(address)
}
#[inline(always)]
unsafe fn set_table(_table_kind: TableKind, address: PhysicalAddress) {
unsafe { asm!("mov cr3, {0}", in(reg) address.data()) };
}
fn virt_is_valid(address: VirtualAddress) -> bool {
// On x86_64, an address is valid if and only if it is canonical. It may still point to
// unmapped memory, but will always be valid once translated via the page table has
// suceeded.
let masked = address.data() & 0xFFFF_8000_0000_0000;
// TODO: 5-level paging
masked == 0xFFFF_8000_0000_0000 || masked == 0
}
}
pub use super::x86_shared::*;
const _: () = {
assert!(X8664Arch::PAGE_SIZE == 4096);
assert!(X8664Arch::PAGE_OFFSET_MASK == 0xFFF);
assert!(X8664Arch::PAGE_ADDRESS_SHIFT == 48);
assert!(X8664Arch::PAGE_ADDRESS_SIZE == 0x0001_0000_0000_0000);
assert!(X8664Arch::PAGE_ADDRESS_MASK == 0x0000_FFFF_FFFF_F000);
assert!(X8664Arch::PAGE_ENTRY_SIZE == 8);
assert!(X8664Arch::PAGE_ENTRIES == 512);
assert!(X8664Arch::PAGE_ENTRY_MASK == 0x1FF);
assert!(X8664Arch::PAGE_NEGATIVE_MASK == 0xFFFF_0000_0000_0000);
assert!(X8664Arch::ENTRY_ADDRESS_SIZE == 0x0000_0100_0000_0000);
assert!(X8664Arch::ENTRY_ADDRESS_MASK == 0x0000_00FF_FFFF_FFFF);
assert!(X8664Arch::ENTRY_FLAGS_MASK == 0xFFF0_0000_0000_0FFF);
assert!(X8664Arch::PHYS_OFFSET == 0xFFFF_8000_0000_0000);
};
#[cfg(test)]
mod tests {
use super::{VirtualAddress, X8664Arch};
use crate::Arch;
#[test]
fn is_canonical() {
fn yes(address: usize) {
assert!(X8664Arch::virt_is_valid(VirtualAddress::new(address)));
}
fn no(address: usize) {
assert!(!X8664Arch::virt_is_valid(VirtualAddress::new(address)));
}
yes(0xFFFF_8000_1337_1337);
yes(0xFFFF_FFFF_FFFF_FFFF);
yes(0x0000_0000_0000_0042);
yes(0x0000_7FFF_FFFF_FFFF);
no(0x1337_0000_0000_0000);
no(0x1337_8000_0000_0000);
no(0x0000_8000_0000_0000);
}
}
+37
View File
@@ -0,0 +1,37 @@
#![expect(clippy::identity_op)]
// Page attribute table is indexed by PAT(7) PCD(4) PWT(3)
pub(crate) const _PAT_WB: usize = (0b0 << 7) + (0b00 << 3);
pub(crate) const _PAT_WT: usize = (0b0 << 7) + (0b01 << 3);
pub(crate) const PAT_UC_: usize = (0b0 << 7) + (0b10 << 3); // UC-
pub(crate) const _PAT_UC: usize = (0b0 << 7) + (0b11 << 3); // UC
pub(crate) const PAT_WC: usize = (0b1 << 7) + (0b00 << 3);
/// Setup page attribute table
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[inline(always)]
pub unsafe fn init_pat() {
unsafe {
let uncacheable = 0; // UC
let write_combining = 1; // WC
let write_through = 4; // WT
let _write_protected = 5; // WP
let write_back = 6; // WB
let uncached = 7; // UC- (overridable by WC MTRR)
let pat0 = write_back;
let pat1 = write_through;
let pat2 = uncached;
let pat3 = uncacheable;
let pat4 = write_combining;
let pat5 = pat1;
let pat6 = pat2;
let pat7 = pat3;
let msr = 631; // IA32_PAT
let low = u32::from_be_bytes([pat3, pat2, pat1, pat0]);
let high = u32::from_be_bytes([pat7, pat6, pat5, pat4]);
core::arch::asm!("wrmsr", in("ecx") msr, in("eax") low, in("edx") high);
}
}
+97
View File
@@ -0,0 +1,97 @@
#![no_std]
#![allow(clippy::new_without_default)]
pub use crate::{allocator::*, arch::*, page::*};
mod allocator;
mod arch;
mod page;
pub const KILOBYTE: usize = 1024;
pub const MEGABYTE: usize = KILOBYTE * 1024;
pub const GIGABYTE: usize = MEGABYTE * 1024;
#[cfg(target_pointer_width = "64")]
pub const TERABYTE: usize = GIGABYTE * 1024;
/// Specific table to be used, needed on some architectures
//TODO: Use this throughout the code
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum TableKind {
/// Userspace page table
User,
/// Kernel page table
Kernel,
}
/// Physical memory address
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct PhysicalAddress(usize);
impl PhysicalAddress {
#[inline(always)]
pub const fn new(address: usize) -> Self {
Self(address)
}
#[inline(always)]
pub fn data(&self) -> usize {
self.0
}
#[expect(clippy::should_implement_trait)]
#[inline(always)]
pub fn add(self, offset: usize) -> Self {
Self(self.0 + offset)
}
}
impl core::fmt::Debug for PhysicalAddress {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "[phys {:#0x}]", self.data())
}
}
/// Virtual memory address
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct VirtualAddress(usize);
impl VirtualAddress {
#[inline(always)]
pub const fn new(address: usize) -> Self {
Self(address)
}
#[inline(always)]
pub fn data(&self) -> usize {
self.0
}
#[expect(clippy::should_implement_trait)]
#[inline(always)]
pub fn add(self, offset: usize) -> Self {
Self(self.0 + offset)
}
#[inline(always)]
pub fn kind(&self) -> TableKind {
if (self.0 as isize) < 0 {
TableKind::Kernel
} else {
TableKind::User
}
}
}
impl core::fmt::Debug for VirtualAddress {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "[virt {:#0x}]", self.data())
}
}
#[derive(Clone, Copy, Debug)]
pub struct MemoryArea {
pub base: PhysicalAddress,
pub size: usize,
}
+309
View File
@@ -0,0 +1,309 @@
#![cfg(target_pointer_width = "64")]
use rmm::{
emulate::EmulateArch, Arch, BuddyAllocator, BumpAllocator, Flusher, FrameAllocator, FrameCount,
MemoryArea, PageFlags, PageFlushAll, PageMapper, PageTable, PhysicalAddress, TableKind,
VirtualAddress, GIGABYTE, KILOBYTE, MEGABYTE, TERABYTE,
};
use std::marker::PhantomData;
pub fn format_size(size: usize) -> String {
if size >= 2 * TERABYTE {
format!("{} TB", size / TERABYTE)
} else if size >= 2 * GIGABYTE {
format!("{} GB", size / GIGABYTE)
} else if size >= 2 * MEGABYTE {
format!("{} MB", size / MEGABYTE)
} else if size >= 2 * KILOBYTE {
format!("{} KB", size / KILOBYTE)
} else {
format!("{} B", size)
}
}
#[allow(dead_code)]
unsafe fn dump_tables<A: Arch>(table: PageTable<A>) {
unsafe {
let level = table.level();
for i in 0..A::PAGE_ENTRIES {
if level == 0 {
if let Some(entry) = table.entry(i) {
if entry.present() {
let base = table.entry_base(i).unwrap();
println!(
"0x{:X}: 0x{:X}",
base.data(),
entry.address().unwrap().data()
);
}
}
} else {
if let Some(next) = table.next(i) {
dump_tables(next);
}
}
}
}
}
pub struct SlabNode<A> {
next: PhysicalAddress,
count: usize,
phantom: PhantomData<A>,
}
impl<A: Arch> SlabNode<A> {
pub fn new(next: PhysicalAddress, count: usize) -> Self {
Self {
next,
count,
phantom: PhantomData,
}
}
pub fn empty() -> Self {
Self::new(PhysicalAddress::new(0), 0)
}
pub unsafe fn insert(&mut self, phys: PhysicalAddress) {
unsafe {
let virt = A::phys_to_virt(phys);
A::write(virt, self.next);
self.next = phys;
self.count += 1;
}
}
pub unsafe fn remove(&mut self) -> Option<PhysicalAddress> {
unsafe {
if self.count > 0 {
let phys = self.next;
let virt = A::phys_to_virt(phys);
self.next = A::read(virt);
self.count -= 1;
Some(phys)
} else {
None
}
}
}
}
pub struct SlabAllocator<A> {
//TODO: Allow allocations up to maximum pageable size
nodes: [SlabNode<A>; 4],
phantom: PhantomData<A>,
}
impl<A: Arch> SlabAllocator<A> {
pub unsafe fn new(areas: &'static [MemoryArea], offset: usize) -> Self {
unsafe {
let mut allocator = Self {
nodes: [
SlabNode::empty(),
SlabNode::empty(),
SlabNode::empty(),
SlabNode::empty(),
],
phantom: PhantomData,
};
// Add unused areas to free lists
let mut area_offset = offset;
for area in areas.iter() {
if area_offset < area.size {
let area_base = area.base.add(area_offset);
let area_size = area.size - area_offset;
allocator.free(area_base, area_size);
area_offset = 0;
} else {
area_offset -= area.size;
}
}
allocator
}
}
pub unsafe fn allocate(&mut self, size: usize) -> Option<PhysicalAddress> {
unsafe {
for level in 0..A::PAGE_LEVELS - 1 {
let level_shift = level * A::PAGE_ENTRY_SHIFT + A::PAGE_SHIFT;
let level_size = 1 << level_shift;
if size <= level_size {
if let Some(base) = self.nodes[level].remove() {
self.free(base.add(size), level_size - size);
return Some(base);
}
}
}
None
}
}
//TODO: This causes fragmentation, since neighbors are not identified
//TODO: remainders less than PAGE_SIZE will be lost
pub unsafe fn free(&mut self, mut base: PhysicalAddress, mut size: usize) {
unsafe {
for level in (0..A::PAGE_LEVELS - 1).rev() {
let level_shift = level * A::PAGE_ENTRY_SHIFT + A::PAGE_SHIFT;
let level_size = 1 << level_shift;
while size >= level_size {
println!("Add {:X} {}", base.data(), format_size(level_size));
self.nodes[level].insert(base);
base = base.add(level_size);
size -= level_size;
}
}
}
}
pub unsafe fn remaining(&mut self) -> usize {
let mut remaining = 0;
for level in (0..A::PAGE_LEVELS - 1).rev() {
let level_shift = level * A::PAGE_ENTRY_SHIFT + A::PAGE_SHIFT;
let level_size = 1 << level_shift;
remaining += self.nodes[level].count * level_size;
}
remaining
}
}
unsafe fn new_tables<A: Arch>(areas: &'static [MemoryArea]) {
unsafe {
// First, calculate how much memory we have
let mut size = 0;
for area in areas.iter() {
size += area.size;
}
println!("Memory: {}", format_size(size));
// Create a basic allocator for the first pages
let mut bump_allocator = BumpAllocator::<A>::new(areas, 0);
{
// Map all physical areas at PHYS_OFFSET
let mut mapper = PageMapper::<A, _>::create(TableKind::Kernel, &mut bump_allocator)
.expect("failed to create Mapper");
for area in areas.iter() {
for i in 0..area.size / A::PAGE_SIZE {
let phys = area.base.add(i * A::PAGE_SIZE);
let (_, flush) = mapper
.map_linearly(phys, PageFlags::<A>::new().write(true))
.expect("failed to map page to frame");
flush.ignore(); // Not the active table
}
}
// Use the new table
mapper.make_current();
}
// Create the physical memory map
let offset = bump_allocator.offset();
println!("Permanently used: {}", format_size(offset));
let mut allocator = BuddyAllocator::<A>::new(bump_allocator).unwrap();
for i in 0..16 {
{
let phys_opt = allocator.allocate_one();
println!("page {}: {:X?}", i, phys_opt);
if i % 3 == 0 {
if let Some(phys) = phys_opt {
println!("free {}: {:X?}", i, phys_opt);
allocator.free_one(phys);
}
}
}
{
let phys_opt = allocator.allocate(FrameCount::new(16));
println!("page*16 {}: {:X?}", i, phys_opt);
if i % 2 == 0 {
if let Some(phys) = phys_opt {
println!("free*16 {}: {:X?}", i, phys_opt);
allocator.free(phys, FrameCount::new(16));
}
}
}
}
let mut mapper = PageMapper::<A, _>::current(TableKind::Kernel, &mut allocator);
let mut flush_all = PageFlushAll::new();
for i in 0..16 {
let virt = VirtualAddress::new(MEGABYTE + i * A::PAGE_SIZE);
let phys = mapper
.allocator_mut()
.allocate_one()
.expect("failed to map page");
let flush = mapper
.map_phys(virt, phys, PageFlags::<A>::new().user(true).write(true))
.expect("failed to map page");
flush_all.consume(flush);
}
flush_all.flush();
let mut flush_all = PageFlushAll::new();
for i in 0..16 {
let virt = VirtualAddress::new(MEGABYTE + i * A::PAGE_SIZE);
let (old, _, flush) = mapper.unmap_phys(virt).expect("failed to unmap page");
mapper.allocator_mut().free_one(old);
flush_all.consume(flush);
}
flush_all.flush();
let usage = allocator.usage();
println!("Allocator usage:");
println!(
" Used: {}",
format_size(usage.used().data() * A::PAGE_SIZE)
);
println!(
" Free: {}",
format_size(usage.free().data() * A::PAGE_SIZE)
);
println!(
" Total: {}",
format_size(usage.total().data() * A::PAGE_SIZE)
);
}
}
fn main() {
unsafe {
let areas = EmulateArch::init();
// Debug table
//dump_tables(PageTable::<A>::top());
new_tables::<EmulateArch>(areas);
//dump_tables(PageTable::<A>::top());
for i in &[1, 2, 4, 8, 16, 32] {
let phys = PhysicalAddress::new(i * MEGABYTE);
let virt = EmulateArch::phys_to_virt(phys);
// Test read
println!(
"0x{:X} (0x{:X}) = 0x{:X}",
virt.data(),
phys.data(),
EmulateArch::read::<u8>(virt)
);
// Test write
EmulateArch::write::<u8>(virt, 0x5A);
// Test read
println!(
"0x{:X} (0x{:X}) = 0x{:X}",
virt.data(),
phys.data(),
EmulateArch::read::<u8>(virt)
);
}
}
}
+59
View File
@@ -0,0 +1,59 @@
use core::marker::PhantomData;
use crate::{Arch, PageFlags, PhysicalAddress};
#[derive(Clone, Copy, Debug)]
pub struct PageEntry<A> {
data: usize,
phantom: PhantomData<A>,
}
impl<A: Arch> PageEntry<A> {
#[inline(always)]
pub fn new(address: usize, flags: usize) -> Self {
let data = (((address >> A::PAGE_SHIFT) & A::ENTRY_ADDRESS_MASK) << A::ENTRY_ADDRESS_SHIFT)
| flags;
Self::from_data(data)
}
#[inline(always)]
pub fn from_data(data: usize) -> Self {
Self {
data,
phantom: PhantomData,
}
}
#[inline(always)]
pub fn data(&self) -> usize {
self.data
}
#[inline(always)]
pub fn address(&self) -> Result<PhysicalAddress, PhysicalAddress> {
let addr = PhysicalAddress(
((self.data >> A::ENTRY_ADDRESS_SHIFT) & A::ENTRY_ADDRESS_MASK) << A::PAGE_SHIFT,
);
if self.present() {
Ok(addr)
} else {
Err(addr)
}
}
#[inline(always)]
pub fn flags(&self) -> PageFlags<A> {
unsafe { PageFlags::from_data(self.data & A::ENTRY_FLAGS_MASK) }
}
#[inline(always)]
pub fn set_flags(&mut self, flags: PageFlags<A>) {
self.data &= !A::ENTRY_FLAGS_MASK;
self.data |= flags.data();
}
#[inline(always)]
pub fn present(&self) -> bool {
self.data & A::ENTRY_FLAG_PRESENT != 0
}
}
+157
View File
@@ -0,0 +1,157 @@
use core::{fmt, marker::PhantomData};
use crate::Arch;
#[derive(Clone, Copy)]
pub struct PageFlags<A> {
data: usize,
arch: PhantomData<A>,
}
impl<A: Arch> PageFlags<A> {
#[inline(always)]
pub fn new() -> Self {
unsafe {
Self::from_data(
// Flags set to present, kernel space, read-only, no-execute by default
A::ENTRY_FLAG_DEFAULT_PAGE
| A::ENTRY_FLAG_READONLY
| A::ENTRY_FLAG_NO_EXEC
| A::ENTRY_FLAG_NO_GLOBAL,
)
}
}
#[inline(always)]
pub fn new_table() -> Self {
unsafe {
Self::from_data(
// Flags set to present, kernel space, read-only, no-execute by default
A::ENTRY_FLAG_DEFAULT_TABLE | A::ENTRY_FLAG_NO_EXEC | A::ENTRY_FLAG_NO_GLOBAL,
)
}
}
#[inline(always)]
pub unsafe fn from_data(data: usize) -> Self {
Self {
data,
arch: PhantomData,
}
}
#[inline(always)]
pub fn data(&self) -> usize {
self.data
}
#[must_use]
#[inline(always)]
pub fn custom_flag(mut self, flag: usize, value: bool) -> Self {
if value {
self.data |= flag;
} else {
self.data &= !flag;
}
self
}
#[must_use]
#[inline(always)]
pub fn device_memory(self, value: bool) -> Self {
self.custom_flag(A::ENTRY_FLAG_DEVICE_MEMORY, value)
}
#[must_use]
#[inline(always)]
pub fn uncacheable(self, value: bool) -> Self {
self.custom_flag(A::ENTRY_FLAG_UNCACHEABLE, value)
}
#[must_use]
#[inline(always)]
pub fn write_combining(self, value: bool) -> Self {
self.custom_flag(A::ENTRY_FLAG_WRITE_COMBINING, value)
}
#[inline(always)]
pub fn has_flag(&self, flag: usize) -> bool {
self.data & flag == flag
}
#[inline(always)]
pub fn has_present(&self) -> bool {
self.has_flag(A::ENTRY_FLAG_PRESENT)
}
#[must_use]
#[inline(always)]
pub fn user(self, value: bool) -> Self {
self.custom_flag(A::ENTRY_FLAG_PAGE_USER, value)
}
#[inline(always)]
pub fn has_user(&self) -> bool {
self.has_flag(A::ENTRY_FLAG_PAGE_USER)
}
#[must_use]
#[inline(always)]
pub fn write(self, value: bool) -> Self {
// Architecture may use readonly or readwrite, or both, support either
if value {
self.custom_flag(A::ENTRY_FLAG_READONLY | A::ENTRY_FLAG_READWRITE, false)
.custom_flag(A::ENTRY_FLAG_READWRITE, true)
} else {
self.custom_flag(A::ENTRY_FLAG_READONLY | A::ENTRY_FLAG_READWRITE, false)
.custom_flag(A::ENTRY_FLAG_READONLY, true)
}
}
#[inline(always)]
pub fn has_write(&self) -> bool {
// Architecture may use readonly or readwrite, or both, support either
self.data & (A::ENTRY_FLAG_READONLY | A::ENTRY_FLAG_READWRITE) == A::ENTRY_FLAG_READWRITE
}
#[must_use]
#[inline(always)]
pub fn execute(self, value: bool) -> Self {
//TODO: write xor execute?
// Architecture may use no exec or exec, support either
self.custom_flag(A::ENTRY_FLAG_NO_EXEC, !value)
.custom_flag(A::ENTRY_FLAG_EXEC, value)
}
#[inline(always)]
pub fn has_execute(&self) -> bool {
// Architecture may use no exec or exec, support either
self.data & (A::ENTRY_FLAG_NO_EXEC | A::ENTRY_FLAG_EXEC) == A::ENTRY_FLAG_EXEC
}
#[must_use]
#[inline(always)]
pub fn global(self, value: bool) -> Self {
// Architecture may use global or non global, support either
self.custom_flag(A::ENTRY_FLAG_NO_GLOBAL, !value)
.custom_flag(A::ENTRY_FLAG_GLOBAL, value)
}
#[inline(always)]
pub fn is_global(&self) -> bool {
// Architecture may use global or non global, support either
self.data & (A::ENTRY_FLAG_GLOBAL | A::ENTRY_FLAG_NO_GLOBAL) == A::ENTRY_FLAG_GLOBAL
}
}
impl<A: Arch> fmt::Debug for PageFlags<A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PageFlags")
.field("present", &self.has_present())
.field("write", &self.has_write())
.field("executable", &self.has_execute())
.field("user", &self.has_user())
.field("bits", &format_args!("{:#0x}", self.data))
.finish()
}
}
+71
View File
@@ -0,0 +1,71 @@
use core::{marker::PhantomData, mem};
use crate::{Arch, VirtualAddress};
pub trait Flusher<A> {
fn consume(&mut self, flush: PageFlush<A>);
}
#[must_use = "The page table must be flushed, or the changes unsafely ignored"]
pub struct PageFlush<A> {
virt: VirtualAddress,
phantom: PhantomData<A>,
}
impl<A: Arch> PageFlush<A> {
pub fn new(virt: VirtualAddress) -> Self {
Self {
virt,
phantom: PhantomData,
}
}
pub fn flush(self) {
A::invalidate(self.virt);
}
#[expect(clippy::forget_non_drop)]
pub unsafe fn ignore(self) {
mem::forget(self);
}
}
// TODO: Might remove Drop and add #[must_use] again, but ergonomically I prefer being able to pass
// a flusher, and have it dropped by the end of the function it is passed to, in order to flush.
pub struct PageFlushAll<A: Arch> {
phantom: PhantomData<fn() -> A>,
}
impl<A: Arch> PageFlushAll<A> {
pub fn new() -> Self {
Self {
phantom: PhantomData,
}
}
pub fn flush(self) {}
pub unsafe fn ignore(self) {
mem::forget(self);
}
}
impl<A: Arch> Drop for PageFlushAll<A> {
fn drop(&mut self) {
A::invalidate_all();
}
}
impl<A: Arch> Flusher<A> for PageFlushAll<A> {
fn consume(&mut self, flush: PageFlush<A>) {
unsafe {
flush.ignore();
}
}
}
impl<A: Arch, T: Flusher<A> + ?Sized> Flusher<A> for &mut T {
fn consume(&mut self, flush: PageFlush<A>) {
<T as Flusher<A>>::consume(self, flush)
}
}
impl<A: Arch> Flusher<A> for () {
fn consume(&mut self, _: PageFlush<A>) {}
}
+269
View File
@@ -0,0 +1,269 @@
use core::marker::PhantomData;
use crate::{
Arch, FrameAllocator, PageEntry, PageFlags, PageFlush, PageTable, PhysicalAddress, TableKind,
VirtualAddress,
};
pub struct PageMapper<A, F> {
table_kind: TableKind,
table_addr: PhysicalAddress,
allocator: F,
_phantom: PhantomData<fn() -> A>,
}
impl<A: Arch, F> PageMapper<A, F> {
unsafe fn new(table_kind: TableKind, table_addr: PhysicalAddress, allocator: F) -> Self {
Self {
table_kind,
table_addr,
allocator,
_phantom: PhantomData,
}
}
pub unsafe fn current(table_kind: TableKind, allocator: F) -> Self {
unsafe {
let table_addr = A::table(table_kind);
Self::new(table_kind, table_addr, allocator)
}
}
pub fn is_current(&self) -> bool {
self.table().phys() == A::table(self.table_kind)
}
pub unsafe fn make_current(&self) {
unsafe {
A::set_table(self.table_kind, self.table_addr);
}
}
pub fn table(&self) -> PageTable<A> {
// SAFETY: The only way to initialize a PageMapper is via new(), and we assume it upholds
// all necessary invariants for this to be safe.
unsafe { PageTable::new(VirtualAddress::new(0), self.table_addr, A::PAGE_LEVELS - 1) }
}
pub fn allocator(&self) -> &F {
&self.allocator
}
pub fn allocator_mut(&mut self) -> &mut F {
&mut self.allocator
}
fn visit<T>(
&self,
virt: VirtualAddress,
f: impl FnOnce(&mut PageTable<A>, usize) -> T,
) -> Option<T> {
let mut table = self.table();
loop {
let i = table.index_of(virt)?;
if table.level() == 0 {
return Some(f(&mut table, i));
} else {
table = unsafe { table.next(i)? };
}
}
}
pub fn translate(&self, virt: VirtualAddress) -> Option<(PhysicalAddress, PageFlags<A>)> {
let entry = self.visit(virt, |p1, i| unsafe { p1.entry(i) })??;
Some((entry.address().ok()?, entry.flags()))
}
pub unsafe fn remap_with_full(
&mut self,
virt: VirtualAddress,
f: impl FnOnce(PhysicalAddress, PageFlags<A>) -> Option<(PhysicalAddress, PageFlags<A>)>,
) -> Option<(PageFlags<A>, PhysicalAddress, PageFlush<A>)> {
unsafe {
self.visit(virt, |p1, i| {
let old_entry = p1.entry(i)?;
let old_phys = old_entry.address().ok()?;
let old_flags = old_entry.flags();
let (new_phys, new_flags) = f(old_phys, old_flags)?;
// TODO: Higher-level PageEntry::new interface?
let new_entry = PageEntry::new(new_phys.data(), new_flags.data());
p1.set_entry(i, new_entry);
Some((old_flags, old_phys, PageFlush::new(virt)))
})
.flatten()
}
}
pub unsafe fn remap_with(
&mut self,
virt: VirtualAddress,
map_flags: impl FnOnce(PageFlags<A>) -> PageFlags<A>,
) -> Option<(PageFlags<A>, PhysicalAddress, PageFlush<A>)> {
unsafe {
self.remap_with_full(virt, |same_phys, old_flags| {
Some((same_phys, map_flags(old_flags)))
})
}
}
pub unsafe fn remap(
&mut self,
virt: VirtualAddress,
flags: PageFlags<A>,
) -> Option<PageFlush<A>> {
unsafe { self.remap_with(virt, |_| flags).map(|(_, _, flush)| flush) }
}
}
impl<A: Arch, F: FrameAllocator> PageMapper<A, F> {
pub unsafe fn create(table_kind: TableKind, mut allocator: F) -> Option<Self> {
unsafe {
let table_addr = allocator.allocate_one()?;
let mut table = Self::new(table_kind, table_addr, allocator);
match (table_kind, A::KERNEL_SEPARATE_TABLE) {
(TableKind::Kernel, false) => {
// Pre-allocate all kernel top-level page table entries so that when
// the page table is copied, these entries are synced between processes.
for i in A::PAGE_ENTRIES / 2..A::PAGE_ENTRIES {
let phys = table
.allocator
.allocate_one()
.expect("failed to map page table");
let flags = A::ENTRY_FLAG_DEFAULT_TABLE;
table
.table()
.set_entry(i, PageEntry::new(phys.data(), flags));
}
}
(TableKind::User, false) => {
// Copy higher half (kernel) mappings
let active_ktable = PageMapper::current(TableKind::Kernel, ());
for i in A::PAGE_ENTRIES / 2..A::PAGE_ENTRIES {
if let Some(entry) = active_ktable.table().entry(i) {
table.table().set_entry(i, entry);
}
}
}
(_, true) => {
// There is a separate page table for the kernel. No need to copy the kernel
// mappings to the user page table.
}
}
Some(table)
}
}
pub unsafe fn map_phys(
&mut self,
virt: VirtualAddress,
phys: PhysicalAddress,
flags: PageFlags<A>,
) -> Option<PageFlush<A>> {
unsafe {
//TODO: verify virt and phys are aligned
//TODO: verify flags have correct bits
let entry = PageEntry::new(phys.data(), flags.data());
let mut table = self.table();
loop {
let i = table.index_of(virt)?;
if table.level() == 0 {
//TODO: check for overwriting entry
table.set_entry(i, entry);
return Some(PageFlush::new(virt));
}
let next = match table.next(i) {
Some(some) => some,
None => {
let next_phys = self.allocator.allocate_one()?;
//TODO: correct flags?
let flags = A::ENTRY_FLAG_DEFAULT_TABLE
| if virt.kind() == TableKind::User {
A::ENTRY_FLAG_TABLE_USER
} else {
0
};
table.set_entry(i, PageEntry::new(next_phys.data(), flags));
table.next(i)?
}
};
table = next;
}
}
}
pub unsafe fn map_linearly(
&mut self,
phys: PhysicalAddress,
flags: PageFlags<A>,
) -> Option<(VirtualAddress, PageFlush<A>)> {
unsafe {
let virt = A::phys_to_virt(phys);
self.map_phys(virt, phys, flags).map(|flush| (virt, flush))
}
}
pub unsafe fn unmap_phys(
&mut self,
virt: VirtualAddress,
) -> Option<(PhysicalAddress, PageFlags<A>, PageFlush<A>)> {
//TODO: verify virt is aligned
let mut table = self.table();
let unmap_parents = A::KERNEL_SEPARATE_TABLE || table.index_of(virt)? < A::PAGE_ENTRIES / 2; // Is a userspace mapping
unsafe {
unmap_phys_inner(virt, &mut table, unmap_parents, &mut self.allocator)
.map(|(pa, pf)| (pa, pf, PageFlush::new(virt)))
}
}
}
unsafe fn unmap_phys_inner<A: Arch>(
virt: VirtualAddress,
table: &mut PageTable<A>,
unmap_parents: bool,
allocator: &mut impl FrameAllocator,
) -> Option<(PhysicalAddress, PageFlags<A>)> {
unsafe {
let i = table.index_of(virt)?;
if table.level() == 0 {
let entry_opt = table.entry(i);
table.set_entry(i, PageEntry::new(0, 0));
let entry = entry_opt?;
return Some((entry.address().ok()?, entry.flags()));
}
let mut subtable = table.next(i)?;
let res = unmap_phys_inner(virt, &mut subtable, unmap_parents, allocator)?;
if unmap_parents {
// TODO: Use a counter? This would reduce the remaining number of available bits, but could be
// faster (benchmark is needed).
let is_still_populated = (0..A::PAGE_ENTRIES)
.map(|j| subtable.entry(j).expect("must be within bounds"))
.any(|e| e.present());
if !is_still_populated {
allocator.free_one(subtable.phys());
table.set_entry(i, PageEntry::new(0, 0));
}
}
Some(res)
}
}
impl<A, F: core::fmt::Debug> core::fmt::Debug for PageMapper<A, F> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("PageMapper")
.field("frame", &self.table_addr)
.field("allocator", &self.allocator)
.finish()
}
}
+7
View File
@@ -0,0 +1,7 @@
pub use self::{entry::*, flags::*, flush::*, mapper::*, table::*};
mod entry;
mod flags;
mod flush;
mod mapper;
mod table;
+105
View File
@@ -0,0 +1,105 @@
use core::{fmt, marker::PhantomData};
use crate::{page::PageEntry, Arch, PhysicalAddress, VirtualAddress};
pub struct PageTable<A> {
base: VirtualAddress,
phys: PhysicalAddress,
level: usize,
phantom: PhantomData<A>,
}
impl<A: Arch> PageTable<A> {
pub(super) unsafe fn new(base: VirtualAddress, phys: PhysicalAddress, level: usize) -> Self {
Self {
base,
phys,
level,
phantom: PhantomData,
}
}
pub fn base(&self) -> VirtualAddress {
self.base
}
pub fn phys(&self) -> PhysicalAddress {
self.phys
}
pub fn level(&self) -> usize {
self.level
}
pub fn entry_base(&self, i: usize) -> Option<VirtualAddress> {
if i < A::PAGE_ENTRIES {
let level_shift = self.level * A::PAGE_ENTRY_SHIFT + A::PAGE_SHIFT;
Some(self.base.add(i << level_shift))
} else {
None
}
}
unsafe fn entry_virt(&self, i: usize) -> Option<VirtualAddress> {
if i < A::PAGE_ENTRIES {
Some(A::phys_to_virt(self.phys).add(i * A::PAGE_ENTRY_SIZE))
} else {
None
}
}
pub unsafe fn entry(&self, i: usize) -> Option<PageEntry<A>> {
unsafe {
let addr = self.entry_virt(i)?;
Some(PageEntry::from_data(A::read::<usize>(addr)))
}
}
pub(super) unsafe fn set_entry(&mut self, i: usize, entry: PageEntry<A>) -> Option<()> {
unsafe {
let addr = self.entry_virt(i)?;
A::write::<usize>(addr, entry.data());
Some(())
}
}
pub(super) fn index_of(&self, address: VirtualAddress) -> Option<usize> {
// Canonicalize address first
let address = VirtualAddress::new(address.data() & A::PAGE_ADDRESS_MASK);
let level_shift = self.level * A::PAGE_ENTRY_SHIFT + A::PAGE_SHIFT;
// Intentionally wraps around at last-level table to get all-ones mask on architectures
// where addressable physical address space covers entire usized space (e.g. x86)
let level_mask = A::PAGE_ENTRIES
.wrapping_shl(level_shift as u32)
.wrapping_sub(1);
if address >= self.base && address <= self.base.add(level_mask) {
Some((address.data() >> level_shift) & A::PAGE_ENTRY_MASK)
} else {
None
}
}
pub unsafe fn next(&self, i: usize) -> Option<Self> {
if self.level == 0 {
return None;
}
unsafe {
Some(PageTable::new(
self.entry_base(i)?,
self.entry(i)?.address().ok()?,
self.level - 1,
))
}
}
pub fn debug_entries(&self, f: impl Fn(fmt::Arguments<'_>)) {
for i in 0..A::PAGE_ENTRIES {
if let Some(entry) = unsafe { self.entry(i) }
&& entry.present()
{
f(format_args!("{}: {:X}", i, entry.data()));
}
}
}
}
+3
View File
@@ -0,0 +1,3 @@
[toolchain]
channel = "nightly-2026-05-24"
components = ["rust-src"]
+22
View File
@@ -0,0 +1,22 @@
blank_lines_lower_bound = 0 # default
blank_lines_upper_bound = 1 # default
brace_style = "SameLineWhere" # default
disable_all_formatting = false # default
edition = "2024"
style_edition = "2015"
empty_item_single_line = true # default
fn_single_line = false # default
force_explicit_abi = true # default
format_strings = false # default
hard_tabs = false # default
show_parse_errors = true # default
imports_granularity = "Crate" # default = Preserve
imports_indent = "Block" # default
imports_layout = "Mixed" # default
indent_style = "Block" # default
max_width = 100 # default
newline_style = "Unix" # default = Auto
skip_children = false # default
tab_spaces = 4 # default
trailing_comma = "Vertical" # default
where_single_line = false # default
+291
View File
@@ -0,0 +1,291 @@
//! ACPI Firmware ACPI Control Structure (FACS) parser.
//!
//! Per ACPI 6.5 §5.2.10. The FACS contains the firmware waking
//! vector that the platform firmware jumps to on S3 wake.
//! This is the memory location the S3 resume trampoline in
//! `arch/x86_shared/s3_resume.rs` must be written to.
//!
//! This is a comprehensive parser matching Linux 7.1's
//! `struct acpi_table_facs` in `include/acpi/actbl.h`:
//!
//! ```c
//! struct acpi_table_facs {
//! char signature[4]; // ASCII table signature
//! u32 length; // Length of structure, in bytes
//! u32 hardware_signature; // Hardware configuration signature
//! u32 firmware_waking_vector; // 32-bit FW waking vector
//! u32 global_lock; // Global Lock for shared hardware
//! u32 flags; // Flags
//! u64 xfirmware_waking_vector; // 64-bit FW waking vector (ACPI 2.0+)
//! u8 version; // Version of this table (ACPI 2.0+)
//! u8 reserved[3]; // Reserved
//! u32 ospm_flags; // Flags set by OSPM (ACPI 4.0+)
//! u8 reserved1[24]; // Reserved (ACPI 4.0+)
//! };
//! ```
//!
//! We also model the corresponding flag constants:
//! - `ACPI_GLOCK_PENDING` (1 << 0)
//! - `ACPI_GLOCK_OWNED` (1 << 1)
//! - `ACPI_FACS_S4_BIOS_PRESENT` (1 << 0)
//! - `ACPI_FACS_64BIT_WAKE` (1 << 1)
//! - `ACPI_FACS_64BIT_ENVIRONMENT` (1 << 0)
//!
//! Hardware-agnostic: the FACS layout is standardized by the ACPI
//! spec. Only the field values (specifically the waking vector)
//! vary per platform.
use core::sync::atomic::AtomicPtr;
use crate::acpi::sdt::Sdt;
/// Linux 7.1 compatibility: matching `struct acpi_table_facs`.
///
/// The struct is `repr(C, packed)` to match the wire layout
/// exactly. The kernel reads the bytes via direct pointer
/// access.
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
pub struct FacsStruct {
/// SDT header (signature, length, revision, checksum,
/// oem_id, oem_table_id, oem_revision, creator_id,
/// creator_revision). Same as other ACPI tables.
pub header: super::sdt::Sdt,
/// Hardware configuration signature. Used by firmware to
/// detect a cold boot vs a resume (the value differs
/// across boots because of system-specific information).
/// Red Bear OS doesn't currently use this — the kernel's
/// S3 magic value is in `s3_resume::S3State.saved_magic`.
pub hardware_signature: u32,
/// 32-bit firmware waking vector. Legacy field used by
/// firmware that runs in 32-bit mode after S3 wake. The
/// platform firmware jumps to this address on a wake
/// event.
pub firmware_waking_vector: u32,
/// Global Lock for shared hardware resources. Acquired by
/// the OS before reading/writing the FACS (or any other
/// ACPI table that requires synchronization with firmware).
/// The kernel currently doesn't use this — we read/write
/// the FACS without taking the global lock. Future work:
/// take the global lock in `read()` and `write()` if
/// multi-core S3 support is added.
pub global_lock: u32,
/// Flags. Bit 0 = S4BIOS support is present. Bit 1 = 64-bit
/// wake vector is supported (ACPI 4.0+).
pub flags: u32,
/// 64-bit firmware waking vector. Used by firmware that
/// runs in 64-bit mode after S3 wake. This is what the
/// kernel's S3 trampoline is written to. (ACPI 2.0+.)
pub xfirmware_waking_vector: u64,
/// FACS version. The FACS was introduced in ACPI 1.0; the
/// 64-bit wake vector was added in ACPI 2.0. (ACPI 2.0+.)
pub version: u8,
/// Reserved. Must be zero. Three bytes.
pub reserved: [u8; 3],
/// OSPM-set flags. Bit 0 = 64-bit wake environment is
/// required (ACPI 4.0+).
pub ospm_flags: u32,
/// Reserved. Must be zero. 24 bytes. (ACPI 4.0+.)
pub reserved1: [u8; 24],
}
/// FACS flag constants (mirrors Linux 7.1's `actbl.h`).
///
/// Used in the `flags` field. Bit 0 = S4BIOS support is
/// present. Bit 1 = 64-bit wake vector is supported.
pub mod facs_flags {
/// `ACPI_FACS_S4_BIOS_PRESENT` (bit 0). The S4BIOS_REQ
/// signal is supported.
pub const S4_BIOS_PRESENT: u32 = 1 << 0;
/// `ACPI_FACS_64BIT_WAKE` (bit 1). The 64-bit wake vector
/// is supported (i.e., `xfirmware_waking_vector` is valid).
pub const WAKE_64BIT: u32 = 1 << 1;
}
/// FACS OSPM flag constants (mirrors Linux 7.1's `actbl.h`).
///
/// Used in the `ospm_flags` field. Bit 0 = 64-bit wake
/// environment is required.
pub mod facs_ospm_flags {
/// `ACPI_FACS_64BIT_ENVIRONMENT` (bit 0). The firmware
/// uses the 64-bit waking vector on S3 wake.
pub const WAKE_64BIT_ENVIRONMENT: u32 = 1 << 0;
}
/// FACS Global Lock flag constants (mirrors Linux 7.1's
/// `actbl.h`). Used in the `global_lock` field.
pub mod facs_glock_flags {
/// `ACPI_GLOCK_PENDING` (bit 0). The global lock is
/// pending (firmware requested it).
pub const PENDING: u32 = 1 << 0;
/// `ACPI_GLOCK_OWNED` (bit 1). The global lock is
/// currently owned.
pub const OWNED: u32 = 1 << 1;
}
/// FACS instance pointer. Set by `init` when the FACS is
/// discovered during ACPI table parsing. Used by the
/// `SetS3WakingVector` AcPiVerb and the `firmware_waking_vector_*`
/// functions below.
static FACS_PTR: AtomicPtr<FacsStruct> = AtomicPtr::new(core::ptr::null_mut());
/// Phase II.X.W: Initialize the FACS parser. Called from the
/// kernel's acpi init after all SDTs are loaded. Reads the
/// FACS from the SDT table and stores the pointer for later
/// use by the `SetS3WakingVector` AcPiVerb.
///
/// # Safety
/// `sdt` must be a valid pointer to a validated SDT whose
/// signature is "FACS" and whose length is at least 64
/// bytes (the minimum size of the FACS structure for ACPI
/// 4.0+ with `ospm_flags` and `reserved1`).
pub fn init(sdt: &Sdt) {
if &sdt.signature != b"FACS" {
return;
}
// The minimum FACS size depends on the version:
// - ACPI 1.0: 32 bytes (just the header + hardware_signature
// + firmware_waking_vector + global_lock)
// - ACPI 2.0: 40 bytes (adds flags + xfirmware_waking_vector)
// - ACPI 4.0: 64 bytes (adds version + reserved + ospm_flags
// + reserved1)
// We require 64 bytes to support all fields.
if sdt.length() < 64 {
return;
}
FACS_PTR.store(
sdt.data_address() as *mut FacsStruct,
core::sync::atomic::Ordering::Release,
);
}
/// Phase II.X.W: Get the FACS structure. Returns `None` if
/// the FACS is not available.
pub fn get() -> Option<&'static FacsStruct> {
let ptr = FACS_PTR.load(core::sync::atomic::Ordering::Acquire);
if ptr.is_null() {
None
} else {
// SAFETY: FACS_PTR was set by `init` after verifying
// sdt.length() >= 64. The pointer is to firmware memory
// which doesn't change.
Some(unsafe { &*ptr })
}
}
/// Phase II.X.W: Read the 32-bit firmware waking vector.
/// Returns 0 if the FACS is not available.
pub fn firmware_waking_vector() -> u32 {
self::get()
.map(|f| f.firmware_waking_vector)
.unwrap_or(0)
}
/// Phase II.X.W: Read the 64-bit firmware waking vector.
/// Returns 0 if the FACS is not available.
pub fn x_firmware_waking_vector() -> u64 {
self::get()
.map(|f| f.xfirmware_waking_vector)
.unwrap_or(0)
}
/// Phase II.X.W: Write the 32-bit firmware waking vector.
/// The kernel's S3 trampoline is written here so the legacy
/// 32-bit firmware wake path works.
///
/// Returns true on success, false if the FACS is not
/// available.
pub fn set_firmware_waking_vector_32(addr: u32) -> bool {
let ptr = FACS_PTR.load(core::sync::atomic::Ordering::Acquire);
if ptr.is_null() {
return false;
}
// SAFETY: FACS_PTR was set by `init` after verifying
// sdt.length() >= 64. The `firmware_waking_vector` field
// is at offset 36 (after the 36-byte SDT header). The
// memory is page-aligned (firmware memory) and writable.
unsafe {
let waking_vector_ptr = (ptr as *mut u8).add(36) as *mut u32;
core::ptr::write_unaligned(waking_vector_ptr, addr);
}
true
}
/// Phase II.X.W: Write the 64-bit firmware waking vector.
/// The kernel's S3 trampoline is written here so the modern
/// 64-bit firmware wake path works.
///
/// Returns true on success, false if the FACS is not
/// available.
pub fn set_x_firmware_waking_vector_64(addr: u64) -> bool {
let ptr = FACS_PTR.load(core::sync::atomic::Ordering::Acquire);
if ptr.is_null() {
return false;
}
// SAFETY: FACS_PTR was set by `init` after verifying
// sdt.length() >= 64. The `xfirmware_waking_vector` field
// is at offset 40. The memory is page-aligned and
// writable.
unsafe {
let x_waking_vector_ptr = (ptr as *mut u8).add(40) as *mut u64;
core::ptr::write_unaligned(x_waking_vector_ptr, addr);
}
true
}
/// Phase II.X.W: Write the 64-bit firmware waking vector
/// (preferred over the 32-bit version on 64-bit systems).
/// Equivalent to `set_x_firmware_waking_vector_64`.
pub fn set_waking_vector(addr: u64) -> bool {
set_x_firmware_waking_vector_64(addr)
}
/// Phase II.X.W: Read the FACS version. Returns 0 if the
/// FACS is not available.
pub fn version() -> u8 {
self::get().map(|f| f.version).unwrap_or(0)
}
/// Phase II.X.W: Read the FACS hardware signature. Returns 0
/// if the FACS is not available.
pub fn hardware_signature() -> u32 {
self::get()
.map(|f| f.hardware_signature)
.unwrap_or(0)
}
/// Phase II.X.W: Read the FACS flags. Returns 0 if the FACS
/// is not available.
///
/// See `facs_flags::*` for the bit definitions.
pub fn flags() -> u32 {
self::get().map(|f| f.flags).unwrap_or(0)
}
/// Phase II.X.W: Read the FACS OSPM flags. Returns 0 if the
/// FACS is not available.
///
/// See `facs_ospm_flags::*` for the bit definitions.
pub fn ospm_flags() -> u32 {
self::get().map(|f| f.ospm_flags).unwrap_or(0)
}
/// Phase II.X.W: Read the FACS global lock. Returns 0 if the
/// FACS is not available.
///
/// See `facs_glock_flags::*` for the bit definitions.
pub fn global_lock() -> u32 {
self::get().map(|f| f.global_lock).unwrap_or(0)
}
/// Phase II.X.W: Read the reserved bytes. Returns `None` if
/// the FACS is not available.
pub fn reserved() -> Option<[u8; 3]> {
self::get().map(|f| f.reserved)
}
/// Phase II.X.W: Read the ACPI 4.0+ reserved bytes. Returns
/// `None` if the FACS is not available.
pub fn reserved1() -> Option<[u8; 24]> {
self::get().map(|f| f.reserved1)
}
+132
View File
@@ -0,0 +1,132 @@
//! ACPI Fixed ACPI Description Table (FADT) parser.
//!
//! Per ACPI 6.5 §5.2.9. The FADT contains the hardware register
//! addresses used by the kernel for ACPI sleep state entry (S3/S5)
//! and the SCI interrupt. This module parses the fields the
//! kernel needs (PM1a_CNT, PM1a_STS for the sleep entry path,
//! and x_firmware_ctrl / firmware_ctrl for the FACS address).
//!
//! Hardware-agnostic: the FADT layout is standardized by the ACPI
//! spec; only the field values vary per platform.
use core::sync::atomic::{AtomicU16, AtomicU32, AtomicU64};
use crate::acpi::sdt::Sdt;
/// Phase II: PM1a_CNT port. Read from the FADT at boot, written
/// by `enter_s3()` to enter S3 (SLP_TYP|SLP_EN bits). Also used
/// by S5 entry (set_global_s_state in acpid).
pub static PM1A_CONTROL_PORT: AtomicU16 = AtomicU16::new(0);
/// Phase II: PM1a_STS port. Used by `enter_s3()` to clear
/// WAK_STS (bit 15) before writing SLP_TYP|SLP_EN.
pub static PM1A_STATUS_PORT: AtomicU16 = AtomicU16::new(0);
/// Phase II.X.W: 32-bit FACS address (FADT offset 36,
/// `firmware_ctrl` field). Used as a fallback when
/// `x_firmware_ctrl` (offset 140, ACPI 2.0+) is not present
/// (i.e., for ACPI 1.0 systems).
pub static FIRMWARE_CTRL: AtomicU32 = AtomicU32::new(0);
/// Phase II.X.W: 64-bit FACS address (FADT offset 140,
/// `x_firmware_ctrl` field, ACPI 2.0+). The kernel's FACS
/// parser uses this to find the FACS for writing the
/// `xfirmware_waking_vector` on S3 entry.
pub static X_FIRMWARE_CTRL: AtomicU64 = AtomicU64::new(0);
/// FADT signature bytes ("FACP").
const FADT_SIGNATURE: [u8; 4] = *b"FACP";
/// FADT fixed offsets for the fields we read. These match
/// the ACPI 6.5 §5.2.9 Table 5.6 layout.
mod offsets {
/// PM1a_STS (PM1 Status Register) Block 0 Address.
/// 32-bit General-Purpose Event Register Block 0 Address.
pub const PM1A_STS: usize = 48;
/// PM1a_CNT (PM1 Control Register) Block 0 Address.
/// 32-bit General-Purpose Event Register Block 0 Address.
pub const PM1A_CNT: usize = 56;
/// `firmware_ctrl`: 32-bit Firmware ACPI Control
/// Structure address. ACPI 1.0+.
pub const FIRMWARE_CTRL_32: usize = 36;
/// `x_firmware_ctrl`: 64-bit Firmware ACPI Control
/// Structure address. ACPI 2.0+.
pub const X_FIRMWARE_CTRL_64: usize = 140;
/// FADT minimum size for ACPI 2.0+ (i.e., enough to
/// include `x_firmware_ctrl` at offset 140).
pub const FADT_MIN_SIZE_ACPI_2_0: usize = 148;
/// FADT minimum size for ACPI 1.0.
pub const FADT_MIN_SIZE_ACPI_1_0: usize = 76;
}
/// Parse the FADT from the given SDT bytes and extract the
/// PM1a_CNT, PM1a_STS, and FACS-address fields. Called once at
/// boot after the ACPI table discovery finds the FADT.
///
/// The FADT layout is variable (different sizes for ACPI 1.0 vs
/// 6.5+). We only need the first ~148 bytes which contain the
/// fixed-register addresses. Reference: ACPI 6.5 §5.2.9.
pub fn init(sdt: &Sdt) {
if &sdt.signature != &FADT_SIGNATURE {
return;
}
// SAFETY: We trust the ACPI table discovery code to have
// verified the FADT checksum. The FADT fields are at fixed
// offsets (per the ACPI spec); reading them as u32/u64 is
// safe because all of them are at 4-byte or 8-byte aligned
// offsets on x86_64.
let data = sdt.data_address() as *const u8;
unsafe {
// PM1a_CNT is at offset 56 in the FADT (ACPI 6.5 §5.2.9
// Table 5.6). 32-bit General-Purpose Event Register Block 0
// Address.
let pm1a_cnt = core::ptr::read_unaligned(data.add(offsets::PM1A_CNT) as *const u32);
// PM1a_STS is at offset 48 in the FADT.
let pm1a_sts = core::ptr::read_unaligned(data.add(offsets::PM1A_STS) as *const u32);
// Convert u32 to u16 (port numbers are 16-bit). The low
// 16 bits are the IO port; the high 16 bits are the
// address-space ID which we ignore (always IO on x86).
PM1A_CONTROL_PORT.store(
(pm1a_cnt & 0xFFFF) as u16,
core::sync::atomic::Ordering::Release,
);
PM1A_STATUS_PORT.store(
(pm1a_sts & 0xFFFF) as u16,
core::sync::atomic::Ordering::Release,
);
// Phase II.X.W: 32-bit FACS address (FADT offset 36,
// `firmware_ctrl` field). ACPI 1.0+.
let firmware_ctrl = core::ptr::read_unaligned(
data.add(offsets::FIRMWARE_CTRL_32) as *const u32,
);
FIRMWARE_CTRL.store(firmware_ctrl, core::sync::atomic::Ordering::Release);
// Phase II.X.W: 64-bit FACS address (FADT offset 140,
// `x_firmware_ctrl` field). ACPI 2.0+. We require the
// FADT to be at least 148 bytes to have this field
// (the field is at offset 140, which is 8 bytes for the
// u64, so the minimum FADT size is 148 bytes).
if sdt.length() >= offsets::FADT_MIN_SIZE_ACPI_2_0 as u32 {
let x_firmware_ctrl = core::ptr::read_unaligned(
data.add(offsets::X_FIRMWARE_CTRL_64) as *const u64,
);
X_FIRMWARE_CTRL.store(x_firmware_ctrl, core::sync::atomic::Ordering::Release);
}
}
}
/// Phase II.X.W: 32-bit FACS address (FADT offset 36,
/// `firmware_ctrl` field). Returns 0 if the FADT has not
/// been initialized.
pub fn firmware_ctrl() -> u32 {
FIRMWARE_CTRL.load(core::sync::atomic::Ordering::Acquire)
}
/// Phase II.X.W: 64-bit FACS address (FADT offset 140,
/// `x_firmware_ctrl` field). Returns 0 if the FADT has not
/// been initialized or the FADT is too short to have the
/// field.
pub fn x_firmware_ctrl() -> u64 {
X_FIRMWARE_CTRL.load(core::sync::atomic::Ordering::Acquire)
}
+64
View File
@@ -0,0 +1,64 @@
use alloc::boxed::Box;
use super::{find_sdt, sdt::Sdt};
use crate::{
arch::device::generic_timer::GenericTimer,
dtb::irqchip::{register_irq, IRQ_CHIP},
};
#[derive(Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct Gtdt {
pub header: Sdt,
pub cnt_control_base: u64,
_reserved: u32,
pub secure_el1_timer_gsiv: u32,
pub secure_el1_timer_flags: u32,
pub non_secure_el1_timer_gsiv: u32,
pub non_secure_el1_timer_flags: u32,
pub virtual_el1_timer_gsiv: u32,
pub virtual_el1_timer_flags: u32,
pub el2_timer_gsiv: u32,
pub el2_timer_flags: u32,
pub cnt_read_base: u64,
pub platform_timer_count: u32,
pub platform_timer_offset: u32,
/*TODO: we don't need these yet, and they cause short tables to fail parsing
pub virtual_el2_timer_gsiv: u32,
pub virtual_el2_timer_flags: u32,
*/
//TODO: platform timer structure (at platform timer offset, with platform timer count)
}
impl Gtdt {
pub fn init() {
let gtdt_sdt = find_sdt("GTDT");
let gtdt = if gtdt_sdt.len() == 1 {
match Gtdt::new(gtdt_sdt[0]) {
Some(gtdt) => gtdt,
None => {
warn!("Failed to parse GTDT");
return;
}
}
} else {
warn!("Unable to find GTDT");
return;
};
let gsiv = gtdt.non_secure_el1_timer_gsiv;
info!("generic_timer gsiv = {}", gsiv);
let mut timer = GenericTimer::new();
timer.init();
register_irq(gsiv, Box::new(timer));
unsafe { IRQ_CHIP.irq_enable(gsiv as u32) };
}
pub fn new(sdt: &'static Sdt) -> Option<&'static Gtdt> {
if &sdt.signature == b"GTDT" && sdt.length as usize >= size_of::<Gtdt>() {
Some(unsafe { &*((sdt as *const Sdt) as *const Gtdt) })
} else {
None
}
}
}
+121
View File
@@ -0,0 +1,121 @@
use core::ptr::{self, read_volatile, write_volatile};
#[cfg(not(target_arch = "x86"))]
use crate::memory::{RmmA, RmmArch};
use crate::{find_one_sdt, memory::PhysicalAddress};
use super::{sdt::Sdt, GenericAddressStructure, ACPI_TABLE};
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
pub struct Hpet {
pub header: Sdt,
pub hw_rev_id: u8,
pub comparator_descriptor: u8,
pub pci_vendor_id: u16,
pub base_address: GenericAddressStructure,
pub hpet_number: u8,
pub min_periodic_clk_tick: u16,
pub oem_attribute: u8,
}
impl Hpet {
pub fn init() {
let hpet = Hpet::new(find_one_sdt!("HPET"));
if let Some(hpet) = hpet {
debug!(" HPET: {:X}", hpet.hpet_number);
let mut hpet_t = ACPI_TABLE.hpet.write();
*hpet_t = Some(hpet);
}
}
pub fn new(sdt: &'static Sdt) -> Option<Hpet> {
if &sdt.signature == b"HPET" && sdt.length as usize >= size_of::<Hpet>() {
let s = unsafe { ptr::read((sdt as *const Sdt) as *const Hpet) };
if s.base_address.address_space == 0 {
unsafe { s.map() };
Some(s)
} else {
warn!(
"HPET has unsupported address space {}",
s.base_address.address_space
);
None
}
} else {
None
}
}
}
//TODO: x86 use assumes only one HPET and only one GenericAddressStructure
#[cfg(target_arch = "x86")]
impl Hpet {
pub unsafe fn map(&self) {
unsafe {
use crate::memory::{Frame, KernelMapper, Page, PageFlags, VirtualAddress};
let frame = Frame::containing(PhysicalAddress::new(self.base_address.address as usize));
let page = Page::containing_address(VirtualAddress::new(crate::HPET_OFFSET));
KernelMapper::lock_rw()
.map_phys(
page.start_address(),
frame.base(),
PageFlags::new().write(true).device_memory(true),
)
.expect("failed to map memory for GenericAddressStructure")
.flush();
}
}
pub unsafe fn read_u64(&self, offset: usize) -> u64 {
unsafe { read_volatile((crate::HPET_OFFSET + offset) as *const u64) }
}
pub unsafe fn write_u64(&mut self, offset: usize, value: u64) {
unsafe {
write_volatile((crate::HPET_OFFSET + offset) as *mut u64, value);
}
}
}
#[cfg(not(target_arch = "x86"))]
impl Hpet {
pub unsafe fn map(&self) {
unsafe {
crate::memory::map_device_memory(
PhysicalAddress::new(self.base_address.address as usize),
crate::memory::PAGE_SIZE,
);
}
}
pub unsafe fn read_u64(&self, offset: usize) -> u64 {
unsafe {
read_volatile(
RmmA::phys_to_virt(PhysicalAddress::new(
self.base_address.address as usize + offset,
))
.data() as *const u64,
)
}
}
pub unsafe fn write_u64(&mut self, offset: usize, value: u64) {
unsafe {
write_volatile(
RmmA::phys_to_virt(PhysicalAddress::new(
self.base_address.address as usize + offset,
))
.data() as *mut u64,
value,
);
}
}
}
+97
View File
@@ -0,0 +1,97 @@
use alloc::{boxed::Box, vec::Vec};
use super::{Madt, MadtEntry};
use crate::{
arch::device::irqchip::{
gic::{GenericInterruptController, GicCpuIf, GicDistIf},
gicv3::{GicV3, GicV3CpuIf},
},
dtb::irqchip::{IrqChipItem, IRQ_CHIP},
memory::{map_device_memory, PhysicalAddress, PAGE_SIZE},
};
pub(super) fn init(madt: Madt) {
let mut gicd_opt = None;
let mut giccs = Vec::new();
for madt_entry in madt.iter() {
debug!(" {:#x?}", madt_entry);
match madt_entry {
MadtEntry::Gicc(gicc) => {
giccs.push(gicc);
}
MadtEntry::Gicd(gicd) => {
if gicd_opt.is_some() {
warn!("Only one GICD should be present on a system, ignoring this one");
} else {
gicd_opt = Some(gicd);
}
}
_ => {}
}
}
let Some(gicd) = gicd_opt else {
warn!("No GICD found");
return;
};
let mut gic_dist_if = GicDistIf::default();
unsafe {
let phys = PhysicalAddress::new(gicd.physical_base_address as usize);
let virt = map_device_memory(phys, PAGE_SIZE);
gic_dist_if.init(virt.data());
};
info!("{:#x?}", gic_dist_if);
match gicd.gic_version {
1 | 2 => {
for gicc in giccs {
let mut gic_cpu_if = GicCpuIf::default();
unsafe {
let phys = PhysicalAddress::new(gicc.physical_base_address as usize);
let virt = map_device_memory(phys, PAGE_SIZE);
gic_cpu_if.init(virt.data())
};
info!("{:#x?}", gic_cpu_if);
let gic = GenericInterruptController {
gic_dist_if,
gic_cpu_if,
irq_range: (0, 0),
};
let chip = IrqChipItem {
phandle: 0,
parents: Vec::new(),
children: Vec::new(),
ic: Box::new(gic),
};
unsafe { IRQ_CHIP.irq_chip_list.chips.push(chip) };
//TODO: support more GICCs
break;
}
}
3 => {
for gicc in giccs {
let mut gic_cpu_if = GicV3CpuIf;
unsafe { gic_cpu_if.init() };
info!("{:#x?}", gic_cpu_if);
let gic = GicV3 {
gic_dist_if,
gic_cpu_if,
//TODO: get GICRs
gicrs: Vec::new(),
irq_range: (0, 0),
};
let chip = IrqChipItem {
phandle: 0,
parents: Vec::new(),
children: Vec::new(),
ic: Box::new(gic),
};
unsafe { IRQ_CHIP.irq_chip_list.chips.push(chip) };
//TODO: support more GICCs
break;
}
}
_ => {
warn!("unsupported GIC version {}", gicd.gic_version);
}
}
unsafe { IRQ_CHIP.init(None) };
}
+9
View File
@@ -0,0 +1,9 @@
use super::Madt;
pub(super) fn init(madt: Madt) {
for madt_entry in madt.iter() {
debug!(" {:#x?}", madt_entry);
}
warn!("MADT not yet handled on this platform");
}
+160
View File
@@ -0,0 +1,160 @@
use core::{
hint,
sync::atomic::{AtomicU8, Ordering},
};
use crate::{
arch::{
device::local_apic::the_local_apic,
start::{kstart_ap, KernelArgsAp},
},
cpu_set::LogicalCpuId,
memory::{
allocate_p2frame, Frame, KernelMapper, Page, PageFlags, PhysicalAddress, RmmA, RmmArch,
VirtualAddress, PAGE_SIZE,
},
startup::AP_READY,
};
use super::{Madt, MadtEntry};
const TRAMPOLINE: usize = 0x8000;
static TRAMPOLINE_DATA: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/trampoline"));
pub(super) fn init(madt: Madt) {
let local_apic = unsafe { the_local_apic() };
let me = local_apic.id();
if local_apic.x2 {
debug!(" X2APIC {}", me.get());
} else {
debug!(" XAPIC {}: {:>08X}", me.get(), local_apic.address);
}
if cfg!(not(feature = "multi_core")) {
return;
}
// Map trampoline
let trampoline_frame = Frame::containing(PhysicalAddress::new(TRAMPOLINE));
let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
let (result, page_table_physaddr) = unsafe {
//TODO: do not have writable and executable!
let mut mapper = KernelMapper::lock_rw();
let result = mapper
.map_phys(
trampoline_page.start_address(),
trampoline_frame.base(),
PageFlags::new().execute(true).write(true),
)
.expect("failed to map trampoline");
(result, mapper.table().phys().data())
};
result.flush();
// Write trampoline, make sure TRAMPOLINE page is free for use
for (i, val) in TRAMPOLINE_DATA.iter().enumerate() {
unsafe {
(*((TRAMPOLINE as *mut u8).add(i) as *const AtomicU8)).store(*val, Ordering::SeqCst);
}
}
unsafe {
let preliminary_cpu_count = madt.iter().filter(|e| matches!(e, MadtEntry::LocalApic(entry) if u32::from(entry.id) == me.get() || entry.flags & 1 == 1)).count();
crate::profiling::allocate(preliminary_cpu_count as u32);
}
for madt_entry in madt.iter() {
debug!(" {:x?}", madt_entry);
if let MadtEntry::LocalApic(ap_local_apic) = madt_entry {
if u32::from(ap_local_apic.id) == me.get() {
debug!(" This is my local APIC");
} else if ap_local_apic.flags & 1 == 1 {
let cpu_id = LogicalCpuId::next();
// Allocate a stack
let stack_start = RmmA::phys_to_virt(
allocate_p2frame(4)
.expect("no more frames in acpi stack_start")
.base(),
)
.data();
let stack_end = stack_start + (PAGE_SIZE << 4);
let pcr_ptr = crate::arch::gdt::allocate_and_init_pcr(cpu_id, stack_end);
let idt_ptr = crate::arch::idt::allocate_and_init_idt(cpu_id);
let args = KernelArgsAp {
stack_end: stack_end as *mut u8,
cpu_id,
pcr_ptr,
idt_ptr,
};
let ap_ready = (TRAMPOLINE + 8) as *mut u64;
let ap_args_ptr = unsafe { ap_ready.add(1) };
let ap_page_table = unsafe { ap_ready.add(2) };
let ap_code = unsafe { ap_ready.add(3) };
// Set the ap_ready to 0, volatile
unsafe {
ap_ready.write(0);
ap_args_ptr.write(&args as *const _ as u64);
ap_page_table.write(page_table_physaddr as u64);
#[expect(clippy::fn_to_numeric_cast)]
ap_code.write(kstart_ap as u64);
// TODO: Is this necessary (this fence)?
core::arch::asm!("");
};
AP_READY.store(false, Ordering::SeqCst);
// Send INIT IPI
{
let mut icr = 0x4500;
if local_apic.x2 {
icr |= u64::from(ap_local_apic.id) << 32;
} else {
icr |= u64::from(ap_local_apic.id) << 56;
}
local_apic.set_icr(icr);
}
// Send START IPI
{
let ap_segment = (TRAMPOLINE >> 12) & 0xFF;
let mut icr = 0x4600 | ap_segment as u64;
if local_apic.x2 {
icr |= u64::from(ap_local_apic.id) << 32;
} else {
icr |= u64::from(ap_local_apic.id) << 56;
}
local_apic.set_icr(icr);
}
// Wait for trampoline ready
while unsafe { (*ap_ready.cast::<AtomicU8>()).load(Ordering::SeqCst) } == 0 {
hint::spin_loop();
}
while !AP_READY.load(Ordering::SeqCst) {
hint::spin_loop();
}
RmmA::invalidate_all();
}
}
}
// Unmap trampoline
let (_frame, _, flush) = unsafe {
KernelMapper::lock_rw()
.unmap_phys(trampoline_page.start_address())
.expect("failed to unmap trampoline page")
};
flush.flush();
}
+240
View File
@@ -0,0 +1,240 @@
use core::cell::SyncUnsafeCell;
use super::sdt::Sdt;
use crate::find_one_sdt;
/// The Multiple APIC Descriptor Table
#[derive(Clone, Copy, Debug)]
pub struct Madt {
sdt: &'static Sdt,
pub local_address: u32,
pub flags: u32,
}
#[cfg(target_arch = "aarch64")]
#[path = "arch/aarch64.rs"]
mod arch;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[path = "arch/x86.rs"]
mod arch;
#[cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))]
#[path = "arch/other.rs"]
mod arch;
static MADT: SyncUnsafeCell<Option<Madt>> = SyncUnsafeCell::new(None);
pub fn madt() -> Option<&'static Madt> {
unsafe { &*MADT.get() }.as_ref()
}
pub const FLAG_PCAT: u32 = 1;
impl Madt {
pub fn init() {
let madt = Madt::new(find_one_sdt!("APIC"));
if let Some(madt) = madt {
// safe because no APs have been started yet.
unsafe { MADT.get().write(Some(madt)) };
debug!(" APIC: {:>08X}: {}", madt.local_address, madt.flags);
arch::init(madt);
}
}
pub fn new(sdt: &'static Sdt) -> Option<Madt> {
if &sdt.signature == b"APIC" && sdt.data_len() >= 8 {
//Not valid if no local address and flags
let local_address = unsafe { (sdt.data_address() as *const u32).read_unaligned() };
let flags = unsafe {
(sdt.data_address() as *const u32)
.offset(1)
.read_unaligned()
};
Some(Madt {
sdt,
local_address,
flags,
})
} else {
None
}
}
pub fn iter(&self) -> MadtIter {
MadtIter {
sdt: self.sdt,
i: 8, // Skip local controller address and flags
}
}
}
/// MADT Local APIC
#[derive(Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct MadtLocalApic {
/// Processor ID
pub processor: u8,
/// Local APIC ID
pub id: u8,
/// Flags. 1 means that the processor is enabled
pub flags: u32,
}
/// MADT I/O APIC
#[derive(Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct MadtIoApic {
/// I/O APIC ID
pub id: u8,
/// reserved
_reserved: u8,
/// I/O APIC address
pub address: u32,
/// Global system interrupt base
pub gsi_base: u32,
}
/// MADT Interrupt Source Override
#[derive(Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct MadtIntSrcOverride {
/// Bus Source
pub bus_source: u8,
/// IRQ Source
pub irq_source: u8,
/// Global system interrupt base
pub gsi_base: u32,
/// Flags
pub flags: u16,
}
/// MADT GICC
#[derive(Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct MadtGicc {
_reserved: u16,
pub cpu_interface_number: u32,
pub acpi_processor_uid: u32,
pub flags: u32,
pub parking_protocol_version: u32,
pub performance_interrupt_gsiv: u32,
pub parked_address: u64,
pub physical_base_address: u64,
pub gicv: u64,
pub gich: u64,
pub vgic_maintenance_interrupt: u32,
pub gicr_base_address: u64,
pub mpidr: u64,
pub processor_power_efficiency_class: u8,
_reserved2: u8,
pub spe_overflow_interrupt: u16,
//TODO: optional field introduced in ACPI 6.5: pub trbe_interrupt: u16,
}
/// MADT GICD
#[derive(Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct MadtGicd {
_reserved: u16,
pub gic_id: u32,
pub physical_base_address: u64,
pub system_vector_base: u32,
pub gic_version: u8,
_reserved2: [u8; 3],
}
/// MADT Entries
#[derive(Debug)]
#[allow(dead_code)]
pub enum MadtEntry {
LocalApic(&'static MadtLocalApic),
InvalidLocalApic(usize),
IoApic(&'static MadtIoApic),
InvalidIoApic(usize),
IntSrcOverride(&'static MadtIntSrcOverride),
InvalidIntSrcOverride(usize),
Gicc(&'static MadtGicc),
InvalidGicc(usize),
Gicd(&'static MadtGicd),
InvalidGicd(usize),
Unknown(u8),
}
pub struct MadtIter {
sdt: &'static Sdt,
i: usize,
}
impl Iterator for MadtIter {
type Item = MadtEntry;
fn next(&mut self) -> Option<Self::Item> {
if self.i + 1 < self.sdt.data_len() {
let entry_type = unsafe { *(self.sdt.data_address() as *const u8).add(self.i) };
let entry_len =
unsafe { *(self.sdt.data_address() as *const u8).add(self.i + 1) } as usize;
if self.i + entry_len <= self.sdt.data_len() {
let item = match entry_type {
0x0 => {
if entry_len == size_of::<MadtLocalApic>() + 2 {
MadtEntry::LocalApic(unsafe {
&*((self.sdt.data_address() + self.i + 2) as *const MadtLocalApic)
})
} else {
MadtEntry::InvalidLocalApic(entry_len)
}
}
0x1 => {
if entry_len == size_of::<MadtIoApic>() + 2 {
MadtEntry::IoApic(unsafe {
&*((self.sdt.data_address() + self.i + 2) as *const MadtIoApic)
})
} else {
MadtEntry::InvalidIoApic(entry_len)
}
}
0x2 => {
if entry_len == size_of::<MadtIntSrcOverride>() + 2 {
MadtEntry::IntSrcOverride(unsafe {
&*((self.sdt.data_address() + self.i + 2)
as *const MadtIntSrcOverride)
})
} else {
MadtEntry::InvalidIntSrcOverride(entry_len)
}
}
0xB => {
if entry_len >= size_of::<MadtGicc>() + 2 {
MadtEntry::Gicc(unsafe {
&*((self.sdt.data_address() + self.i + 2) as *const MadtGicc)
})
} else {
MadtEntry::InvalidGicc(entry_len)
}
}
0xC => {
if entry_len >= size_of::<MadtGicd>() + 2 {
MadtEntry::Gicd(unsafe {
&*((self.sdt.data_address() + self.i + 2) as *const MadtGicd)
})
} else {
MadtEntry::InvalidGicd(entry_len)
}
}
_ => MadtEntry::Unknown(entry_type),
};
self.i += entry_len;
Some(item)
} else {
None
}
} else {
None
}
}
}
+255
View File
@@ -0,0 +1,255 @@
//! # ACPI
//! Code to parse the ACPI tables
use alloc::{boxed::Box, string::String, vec::Vec};
use core::ptr::NonNull;
use hashbrown::HashMap;
use spin::{Once, RwLock};
use crate::memory::{KernelMapper, PageFlags, PhysicalAddress, RmmA, RmmArch};
use self::{hpet::Hpet, madt::Madt, rsdp::Rsdp, rsdt::Rsdt, rxsdt::Rxsdt, sdt::Sdt, xsdt::Xsdt};
#[cfg(target_arch = "aarch64")]
mod gtdt;
pub mod fadt;
pub mod facs;
pub mod hpet;
pub mod madt;
mod rsdp;
mod rsdt;
mod rxsdt;
pub mod sdt;
#[cfg(target_arch = "aarch64")]
mod spcr;
mod xsdt;
unsafe fn map_linearly(addr: PhysicalAddress, len: usize, mapper: &mut crate::memory::PageMapper) {
unsafe {
let base = PhysicalAddress::new(crate::memory::round_down_pages(addr.data()));
let aligned_len = crate::memory::round_up_pages(len + (addr.data() - base.data()));
for page_idx in 0..aligned_len / crate::memory::PAGE_SIZE {
let (_, flush) = mapper
.map_linearly(
base.add(page_idx * crate::memory::PAGE_SIZE),
PageFlags::new(),
)
.expect("failed to linearly map SDT");
flush.flush();
}
}
}
pub fn get_sdt(sdt_address: PhysicalAddress, mapper: &mut KernelMapper<true>) -> &'static Sdt {
let sdt;
unsafe {
const SDT_SIZE: usize = size_of::<Sdt>();
map_linearly(sdt_address, SDT_SIZE, mapper);
sdt = &*(RmmA::phys_to_virt(sdt_address).data() as *const Sdt);
map_linearly(
sdt_address.add(SDT_SIZE),
sdt.length as usize - SDT_SIZE,
mapper,
);
}
sdt
}
#[repr(C, packed)]
#[derive(Clone, Copy, Debug, Default)]
pub struct GenericAddressStructure {
pub address_space: u8,
pub bit_width: u8,
pub bit_offset: u8,
pub access_size: u8,
pub address: u64,
}
pub enum RxsdtEnum {
Rsdt(Rsdt),
Xsdt(Xsdt),
}
impl Rxsdt for RxsdtEnum {
fn iter(&self) -> Box<dyn Iterator<Item = PhysicalAddress>> {
match self {
Self::Rsdt(rsdt) => <Rsdt as Rxsdt>::iter(rsdt),
Self::Xsdt(xsdt) => <Xsdt as Rxsdt>::iter(xsdt),
}
}
}
pub static RXSDT_ENUM: Once<RxsdtEnum> = Once::new();
/// Parse the ACPI tables to gather CPU, interrupt, and timer information
pub unsafe fn init(already_supplied_rsdp: Option<NonNull<u8>>) {
unsafe {
{
let mut sdt_ptrs = SDT_POINTERS.write();
*sdt_ptrs = Some(HashMap::new());
}
// Search for RSDP
let rsdp_opt = Rsdp::get_rsdp(already_supplied_rsdp);
if let Some(rsdp) = rsdp_opt {
debug!("SDT address: {:#x}", rsdp.sdt_address().data());
let rxsdt = get_sdt(rsdp.sdt_address(), &mut KernelMapper::lock_rw());
let rxsdt = if let Some(rsdt) = Rsdt::new(rxsdt) {
let mut initialized = false;
let rsdt = RXSDT_ENUM.call_once(|| {
initialized = true;
RxsdtEnum::Rsdt(rsdt)
});
if !initialized {
error!("RXSDT_ENUM already initialized");
}
rsdt
} else if let Some(xsdt) = Xsdt::new(rxsdt) {
let mut initialized = false;
let xsdt = RXSDT_ENUM.call_once(|| {
initialized = true;
RxsdtEnum::Xsdt(xsdt)
});
if !initialized {
error!("RXSDT_ENUM already initialized");
}
xsdt
} else {
warn!("UNKNOWN RSDT OR XSDT SIGNATURE");
return;
};
// TODO: Don't touch ACPI tables in kernel?
for sdt in rxsdt.iter() {
get_sdt(sdt, &mut KernelMapper::lock_rw());
}
for sdt_address in rxsdt.iter() {
let sdt = &*(RmmA::phys_to_virt(sdt_address).data() as *const Sdt);
let signature = get_sdt_signature(sdt);
if let Some(ref mut ptrs) = *(SDT_POINTERS.write()) {
ptrs.insert(signature, sdt);
}
}
// TODO: Enumerate processors in userspace, and then provide an ACPI-independent interface
// to initialize enumerated processors to userspace?
Madt::init();
//TODO: support this on any arch
// SPCR must be initialized after MADT for interrupt controllers
#[cfg(target_arch = "aarch64")]
spcr::Spcr::init();
// TODO: Let userspace setup HPET, and then provide an interface to specify which timer to
// use?
Hpet::init();
#[cfg(target_arch = "aarch64")]
gtdt::Gtdt::init();
// Phase II: parse the FADT to extract the PM1a_CNT
// and PM1a_STS port addresses used by the S3 entry
// path. Hardware-agnostic — works on any platform
// with a working FADT.
if let Some(fadt_sdts) = find_sdt("FACP").first() {
fadt::init(fadt_sdts);
} else {
warn!("ACPI: no FADT (FACP) found, S3 entry path disabled");
}
// Phase II.X.W: parse the FACS to extract the
// xfirmware_waking_vector. This is the address the
// platform firmware jumps to on S3 wake. The kernel's
// S3 resume trampoline in arch/x86_shared/s3_resume.rs
// is written to this address by acpid via the
// SetS3WakingVector AcPiVerb.
//
// The FACS is found via the FADT's x_firmware_ctrl
// field (64-bit) or firmware_ctrl field (32-bit).
// The FADT parser caches the FACS address. We use
// the FADT's x_firmware_ctrl to find the FACS SDT.
let facs_addr = fadt::x_firmware_ctrl();
if facs_addr != 0 {
// SAFETY: The FACS address is a physical
// address stored in the FADT. The boot-time page
// table maps the FACS into the kernel's address
// space (firmware tables are below 4GB on x86_64).
let facs_sdt = unsafe { &*(facs_addr as *const Sdt) };
facs::init(facs_sdt);
} else {
let facs_addr = fadt::firmware_ctrl() as u64;
if facs_addr != 0 {
// SAFETY: same as above.
let facs_sdt =
unsafe { &*(facs_addr as *const Sdt) };
facs::init(facs_sdt);
} else {
warn!("ACPI: no FACS found (neither x_firmware_ctrl nor firmware_ctrl), S3 resume path disabled");
}
}
} else {
error!("NO RSDP FOUND");
}
}
}
pub type SdtSignature = (String, [u8; 6], [u8; 8]);
pub static SDT_POINTERS: RwLock<Option<HashMap<SdtSignature, &'static Sdt>>> = RwLock::new(None);
pub fn find_sdt(name: &str) -> Vec<&'static Sdt> {
let mut sdts: Vec<&'static Sdt> = vec![];
if let Some(ref ptrs) = *(SDT_POINTERS.read()) {
for (signature, sdt) in ptrs {
if signature.0 == name {
sdts.push(sdt);
}
}
}
sdts
}
#[macro_export]
macro_rules! find_one_sdt {
($name:expr) => {{
use $crate::acpi::find_sdt;
match find_sdt($name).as_slice() {
[] => {
println!("Unable to find {}", $name);
return;
}
[x] => *x,
x => {
println!("{} {} found, expected 1", x.len(), $name);
return;
}
}
}};
}
pub fn get_sdt_signature(sdt: &'static Sdt) -> SdtSignature {
let signature =
String::from_utf8(sdt.signature.to_vec()).expect("Error converting signature to string");
(signature, sdt.oem_id, sdt.oem_table_id)
}
pub struct Acpi {
pub hpet: RwLock<Option<Hpet>>,
}
pub static ACPI_TABLE: Acpi = Acpi {
hpet: RwLock::new(None),
};
+62
View File
@@ -0,0 +1,62 @@
use core::ptr::NonNull;
use rmm::PhysicalAddress;
/// RSDP
#[derive(Copy, Clone, Debug)]
#[repr(C, packed)]
pub struct Rsdp {
signature: [u8; 8],
_checksum: u8,
_oemid: [u8; 6],
revision: u8,
rsdt_address: u32,
length: u32,
xsdt_address: u64,
_extended_checksum: u8,
_reserved: [u8; 3],
}
impl Rsdp {
pub unsafe fn get_rsdp(already_supplied_rsdp: Option<NonNull<u8>>) -> Option<Rsdp> {
already_supplied_rsdp.and_then(|rsdp_ptr: NonNull<u8>| {
let rsdp: Rsdp = unsafe { rsdp_ptr.cast().read() };
if rsdp.signature != *b"RSD PTR " {
error!("RSDP signature check failed");
return None;
}
let mut sum: u8 = 0;
for i in 0..20 {
sum = sum.wrapping_add(unsafe { rsdp_ptr.add(i).read() });
}
if sum != 0 {
error!("RSDP checksum failed");
return None;
}
if rsdp.revision >= 2 {
let mut sum: u8 = 0;
for i in 0..rsdp.length as usize {
sum = sum.wrapping_add(unsafe { rsdp_ptr.add(i).read() });
}
if sum != 0 {
error!("XSDP checksum failed");
return None;
}
}
Some(rsdp)
})
}
/// Get the RSDT or XSDT address
pub fn sdt_address(&self) -> PhysicalAddress {
PhysicalAddress::new(if self.revision >= 2 {
self.xsdt_address as usize
} else {
self.rsdt_address as usize
})
}
}
+52
View File
@@ -0,0 +1,52 @@
use alloc::boxed::Box;
use core::convert::TryFrom;
use rmm::PhysicalAddress;
use super::{rxsdt::Rxsdt, sdt::Sdt};
#[derive(Debug)]
pub struct Rsdt(&'static Sdt);
impl Rsdt {
pub fn new(sdt: &'static Sdt) -> Option<Rsdt> {
if &sdt.signature == b"RSDT" {
Some(Rsdt(sdt))
} else {
None
}
}
pub fn as_slice(&self) -> &[u8] {
let length =
usize::try_from(self.0.length).expect("expected 32-bit length to fit within usize");
unsafe { core::slice::from_raw_parts(self.0 as *const _ as *const u8, length) }
}
}
impl Rxsdt for Rsdt {
fn iter(&self) -> Box<dyn Iterator<Item = PhysicalAddress>> {
Box::new(RsdtIter { sdt: self.0, i: 0 })
}
}
pub struct RsdtIter {
sdt: &'static Sdt,
i: usize,
}
impl Iterator for RsdtIter {
type Item = PhysicalAddress;
fn next(&mut self) -> Option<Self::Item> {
if self.i < self.sdt.data_len() / size_of::<u32>() {
let item = unsafe {
(self.sdt.data_address() as *const u32)
.add(self.i)
.read_unaligned()
};
self.i += 1;
Some(PhysicalAddress::new(item as usize))
} else {
None
}
}
}
+6
View File
@@ -0,0 +1,6 @@
use alloc::boxed::Box;
use rmm::PhysicalAddress;
pub trait Rxsdt {
fn iter(&self) -> Box<dyn Iterator<Item = PhysicalAddress>>;
}
+42
View File
@@ -0,0 +1,42 @@
#[derive(Copy, Clone, Debug)]
#[repr(C, packed)]
pub struct Sdt {
pub signature: [u8; 4],
pub length: u32,
pub revision: u8,
pub checksum: u8,
pub oem_id: [u8; 6],
pub oem_table_id: [u8; 8],
pub oem_revision: u32,
pub creator_id: u32,
pub creator_revision: u32,
}
impl Sdt {
/// Get the address of this tables data
pub fn data_address(&self) -> usize {
self as *const _ as usize + size_of::<Sdt>()
}
/// Get the total length of the table (including the SDT
/// header), in bytes. The SDT is `#[repr(C, packed)]` so
/// direct field access requires an unaligned read.
pub fn length(&self) -> u32 {
// SAFETY: The Sdt is `#[repr(C, packed)]` and the
// `length` field is at offset 4 (after the 4-byte
// signature), aligned to a 4-byte boundary. The address
// is a valid pointer to the SDT; reading 4 bytes from
// offset 4 is safe.
unsafe {
let p = self as *const Self as *const u8;
core::ptr::read_unaligned(p.add(4) as *const u32)
}
}
/// Get the length of this tables data
pub fn data_len(&self) -> usize {
let total_size = self.length as usize;
let header_size = size_of::<Sdt>();
total_size.saturating_sub(header_size)
}
}
+140
View File
@@ -0,0 +1,140 @@
use super::{find_sdt, sdt::Sdt, GenericAddressStructure};
use crate::{
arch::device::serial::COM1,
devices::{serial::SerialKind, uart_pl011},
log::LOG,
memory::{map_device_memory, PhysicalAddress, PAGE_SIZE},
};
const INTERRUPT_TYPE_8259: u8 = 1 << 0;
const INTERRUPT_TYPE_APIC: u8 = 1 << 1;
const INTERRUPT_TYPE_SAPIC: u8 = 1 << 2;
const INTERRUPT_TYPE_GIC: u8 = 1 << 3;
const INTERRUPT_TYPE_PLIC: u8 = 1 << 4;
#[derive(Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct Spcr {
pub header: Sdt,
pub interface_type: u8,
_reserved: [u8; 3],
pub base_address: GenericAddressStructure,
pub interrupt_type: u8,
pub irq: u8,
pub gsiv: u32,
pub configured_baud_rate: u8,
pub parity: u8,
pub stop_bits: u8,
pub flow_control: u8,
pub terminal_type: u8,
pub language: u8,
pub pci_device_id: u16,
pub pci_vendor_id: u16,
pub pci_bus: u8,
pub pci_device: u8,
pub pci_function: u8,
pub pci_flags: u32,
pub pci_segment: u8,
/*TODO: these fields are optional based on the table revision
pub uart_clock_frequency: u32,
pub precise_baud_rate: u32,
pub namespace_string_length: u16,
pub namespace_string_offset: u16,
*/
// namespace_string
}
impl Spcr {
pub fn init() {
let spcr_sdt = find_sdt("SPCR");
let spcr = if spcr_sdt.len() == 1 {
match Spcr::new(spcr_sdt[0]) {
Some(spcr) => spcr,
None => {
warn!("Failed to parse SPCR");
return;
}
}
} else {
warn!("Unable to find SPCR");
return;
};
if spcr.base_address.address == 0 {
// Serial disabled
return;
}
let serial_was_empty = !matches!(*COM1.lock(), SerialKind::NotPresent);
if spcr.header.revision >= 2 {
match spcr.interface_type {
3 => {
// PL011
if spcr.base_address.address_space == 0
&& spcr.base_address.bit_width == 32
&& spcr.base_address.bit_offset == 0
&& spcr.base_address.access_size == 3
{
let virt = unsafe {
map_device_memory(
PhysicalAddress::new(spcr.base_address.address as usize),
PAGE_SIZE,
)
};
let serial_port = uart_pl011::SerialPort::new(virt.data(), false);
*COM1.lock() = SerialKind::Pl011(serial_port);
//TODO: enable IRQ on more platforms and interrupt types
if (spcr.interrupt_type & INTERRUPT_TYPE_GIC) == INTERRUPT_TYPE_GIC {
#[cfg(target_arch = "aarch64")]
unsafe {
crate::arch::device::serial::init_acpi(spcr.gsiv);
}
}
} else {
warn!(
"SPCR unsuppoted address for PL011 {:#x?}",
spcr.base_address
);
}
}
//TODO: support more types!
unsupported => {
warn!(
"SPCR revision {} unsupported interface type {}",
spcr.header.revision, unsupported
);
}
}
} else if spcr.header.revision == 1 {
match spcr.interface_type {
//TODO: support more types!
unsupported => {
warn!("SPCR revision 1 unsupported interface type {}", unsupported);
}
}
} else {
warn!("SPCR unsupported revision {}", spcr.header.revision);
}
let mut serial_port = COM1.lock();
if serial_was_empty && !matches!(*serial_port, SerialKind::NotPresent) {
// backfill logs since the heap is loaded
if let Some(ref mut early_log) = *LOG.lock() {
let (s1, s2) = early_log.read();
if !s1.is_empty() {
serial_port.write(s1);
}
if !s2.is_empty() {
serial_port.write(s2);
}
}
}
}
pub fn new(sdt: &'static Sdt) -> Option<&'static Spcr> {
if &sdt.signature == b"SPCR" && sdt.length as usize >= size_of::<Spcr>() {
Some(unsafe { &*((sdt as *const Sdt) as *const Spcr) })
} else {
None
}
}
}
+50
View File
@@ -0,0 +1,50 @@
use alloc::boxed::Box;
use core::convert::TryFrom;
use rmm::PhysicalAddress;
use super::{rxsdt::Rxsdt, sdt::Sdt};
#[derive(Debug)]
pub struct Xsdt(&'static Sdt);
impl Xsdt {
pub fn new(sdt: &'static Sdt) -> Option<Xsdt> {
if &sdt.signature == b"XSDT" {
Some(Xsdt(sdt))
} else {
None
}
}
pub fn as_slice(&self) -> &[u8] {
let length =
usize::try_from(self.0.length).expect("expected 32-bit length to fit within usize");
unsafe { core::slice::from_raw_parts(self.0 as *const _ as *const u8, length) }
}
}
impl Rxsdt for Xsdt {
fn iter(&self) -> Box<dyn Iterator<Item = PhysicalAddress>> {
Box::new(XsdtIter { sdt: self.0, i: 0 })
}
}
pub struct XsdtIter {
sdt: &'static Sdt,
i: usize,
}
impl Iterator for XsdtIter {
type Item = PhysicalAddress;
fn next(&mut self) -> Option<Self::Item> {
if self.i < self.sdt.data_len() / size_of::<u64>() {
let item = unsafe {
core::ptr::read_unaligned((self.sdt.data_address() as *const u64).add(self.i))
};
self.i += 1;
Some(PhysicalAddress::new(item as usize))
} else {
None
}
}
}
-394
View File
@@ -1,394 +0,0 @@
use alloc::{collections::BTreeSet, vec::Vec};
use core::{fmt, mem, ops, slice};
use endian_num::Le;
use crate::{BlockAddr, BlockLevel, BlockMeta, BlockPtr, BlockTrait, Node, TreePtr, BLOCK_SIZE};
pub const ALLOC_LIST_ENTRIES: usize =
(BLOCK_SIZE as usize - mem::size_of::<BlockPtr<AllocList>>()) / mem::size_of::<AllocEntry>();
pub const RELEASE_LIST_ENTRIES: usize = (BLOCK_SIZE as usize
- mem::size_of::<BlockPtr<ReleaseList>>())
/ mem::size_of::<TreePtr<Node>>();
/// The RedoxFS block allocator. This struct manages all "data" blocks in RedoxFS
/// (i.e, all blocks that aren't reserved or part of the header chain).
///
/// [`Allocator`] can allocate blocks of many "levels"---that is, it can
/// allocate multiple consecutive [`BLOCK_SIZE`] blocks in one operation.
///
/// This reduces the amount of memory that the [`Allocator`] uses:
/// Instead of storing the index of each free [`BLOCK_SIZE`] block,
/// the `levels` array can keep track of higher-level blocks, splitting
/// them when a smaller block is requested.
///
/// Higher-level blocks also allow us to more efficiently allocate memory
/// for large files.
#[derive(Clone, Default)]
pub struct Allocator {
/// This array keeps track of all free blocks of each level,
/// and is initialized using the AllocList chain when we open the filesystem.
///
/// Every element of the outer array represents a block level:
/// - item 0: free level 0 blocks (with size [`BLOCK_SIZE`])
/// - item 1: free level 1 blocks (with size 2*[`BLOCK_SIZE`])
/// - item 2: free level 2 blocks (with size 4*[`BLOCK_SIZE`])
/// ...and so on.
///
/// Each inner array contains a list of free block indices,
levels: Vec<BTreeSet<u64>>,
}
impl Allocator {
pub fn levels(&self) -> &Vec<BTreeSet<u64>> {
&self.levels
}
/// Count the number of free [`BLOCK_SIZE`] available to this [`Allocator`].
pub fn free(&self) -> u64 {
let mut free = 0;
for level in 0..self.levels.len() {
let level_size = 1 << level;
free += self.levels[level].len() as u64 * level_size;
}
free
}
/// Find a free block of the given level, mark it as "used", and return its address.
/// Returns [`None`] if there are no free blocks with this level.
pub fn allocate(&mut self, meta: BlockMeta) -> Option<BlockAddr> {
// First, find the lowest level with a free block
let mut free_opt = None;
{
let mut level = meta.level.0;
// Start searching at the level we want. Smaller levels are too small!
while level < self.levels.len() {
if let Some(&index) = self.levels[level].first() {
// Find the index closest to the start of the filesystem
free_opt = match free_opt {
Some((free_level, free_index)) if free_index <= index => {
Some((free_level, free_index))
}
_ => Some((level, index)),
};
}
level += 1;
}
}
// If a free block was found, split it until we find a usable block of the right level.
// The left side of the split block is kept free, and the right side is allocated.
let (mut level, index) = free_opt?;
self.levels[level].remove(&index);
while level > meta.level.0 {
level -= 1;
let level_size = 1 << level;
self.levels[level].insert(index + level_size);
}
Some(unsafe { BlockAddr::new(index, meta) })
}
/// Try to allocate the exact block specified, making all necessary splits.
/// Returns [`None`] if this some (or all) of this block is already allocated.
///
/// Note that [`BlockAddr`] encodes the blocks location _and_ level.
pub fn allocate_exact(&mut self, exact_addr: BlockAddr) -> Option<BlockAddr> {
// This function only supports level 0 right now
assert_eq!(exact_addr.level().0, 0);
let exact_index = exact_addr.index();
let mut index_opt = None;
// Go from the highest to the lowest level
for level in (0..self.levels.len()).rev() {
let level_size = 1 << level;
// Split higher block if found
if let Some(index) = index_opt.take() {
self.levels[level].insert(index);
self.levels[level].insert(index + level_size);
}
// Look for matching block and remove it
for &start in self.levels[level].iter() {
if start <= exact_index {
let end = start + level_size;
if end > exact_index {
self.levels[level].remove(&start);
index_opt = Some(start);
break;
}
}
}
}
Some(unsafe { BlockAddr::new(index_opt?, exact_addr.meta()) })
}
/// Deallocate the given block, marking it "free" so that it can be re-used later.
pub fn deallocate(&mut self, addr: BlockAddr) {
// When we deallocate, we check if block we're deallocating has a free sibling.
// If it does, we join the two to create one free block in the next (higher) level.
//
// We repeat this until we no longer have a sibling to join.
let mut index = addr.index();
let mut level = addr.level().0;
loop {
while level >= self.levels.len() {
self.levels.push(BTreeSet::new());
}
let level_size = 1 << level;
let next_size = level_size << 1;
let mut found = false;
// look at all free blocks in the current level...
for &level_index in self.levels[level].iter() {
// - the block we just freed aligns with the next largest block, and
// - the second block we're looking at is the right sibling of this block
if index % next_size == 0 && index + level_size == level_index {
// "alloc" the next highest block, repeat deallocation process.
self.levels[level].remove(&level_index);
found = true;
break;
// - the index of this block doesn't align with the next largest block, and
// - the block we're looking at is the left neighbor of this block
} else if level_index % next_size == 0 && level_index + level_size == index {
// "alloc" the next highest block, repeat deallocation process.
self.levels[level].remove(&level_index);
index = level_index; // index moves to left block
found = true;
break;
}
}
// We couldn't find a higher block,
// deallocate this one and finish
if !found {
self.levels[level].insert(index);
return;
}
// repeat deallocation process on the
// higher-level block we just created.
level += 1;
}
}
}
#[repr(C, packed)]
#[derive(Clone, Copy, Default, Debug)]
pub struct AllocEntry {
/// The index of the first block this [`AllocEntry`] refers to
index: Le<u64>,
/// The number of blocks after (and including) `index` that are are free or used.
/// If negative, they are used; if positive, they are free.
count: Le<i64>,
}
impl AllocEntry {
pub fn new(index: u64, count: i64) -> Self {
Self {
index: index.into(),
count: count.into(),
}
}
pub fn allocate(addr: BlockAddr) -> Self {
Self::new(addr.index(), -addr.level().blocks::<i64>())
}
pub fn deallocate(addr: BlockAddr) -> Self {
Self::new(addr.index(), addr.level().blocks::<i64>())
}
pub fn index(&self) -> u64 {
self.index.to_ne()
}
pub fn count(&self) -> i64 {
self.count.to_ne()
}
pub fn is_null(&self) -> bool {
self.count() == 0
}
}
/// A node in the allocation chain.
#[repr(C, packed)]
pub struct AllocList {
/// A pointer to the previous AllocList.
/// If this is the null pointer, this is the first element of the chain.
pub prev: BlockPtr<AllocList>,
/// Allocation entries.
pub entries: [AllocEntry; ALLOC_LIST_ENTRIES],
}
unsafe impl BlockTrait for AllocList {
fn empty(level: BlockLevel) -> Option<Self> {
if level.0 == 0 {
Some(Self {
prev: BlockPtr::default(),
entries: [AllocEntry::default(); ALLOC_LIST_ENTRIES],
})
} else {
None
}
}
}
impl fmt::Debug for AllocList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let prev = self.prev;
let entries: Vec<&AllocEntry> = self
.entries
.iter()
.filter(|entry| entry.count() > 0)
.collect();
f.debug_struct("AllocList")
.field("prev", &prev)
.field("entries", &entries)
.finish()
}
}
impl ops::Deref for AllocList {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(
self as *const AllocList as *const u8,
mem::size_of::<AllocList>(),
) as &[u8]
}
}
}
impl ops::DerefMut for AllocList {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(
self as *mut AllocList as *mut u8,
mem::size_of::<AllocList>(),
) as &mut [u8]
}
}
}
/// A list of nodes pending release.
#[repr(C, packed)]
pub struct ReleaseList {
/// A pointer to the previous ReleaseList.
/// If this is the null pointer, this is the first element of the chain.
pub prev: BlockPtr<ReleaseList>,
/// Allocation entries.
pub entries: [TreePtr<Node>; RELEASE_LIST_ENTRIES],
}
unsafe impl BlockTrait for ReleaseList {
fn empty(level: BlockLevel) -> Option<Self> {
if level.0 == 0 {
Some(Self {
prev: BlockPtr::default(),
entries: [TreePtr::<Node>::default(); RELEASE_LIST_ENTRIES],
})
} else {
None
}
}
}
impl fmt::Debug for ReleaseList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let prev = self.prev;
let entries: Vec<_> = self
.entries
.iter()
.filter(|entry| !entry.is_null())
.map(|entry| entry.id())
.collect();
f.debug_struct("ReleaseList")
.field("prev", &prev)
.field("entries", &entries)
.finish()
}
}
impl ops::Deref for ReleaseList {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(
self as *const ReleaseList as *const u8,
mem::size_of::<ReleaseList>(),
) as &[u8]
}
}
}
impl ops::DerefMut for ReleaseList {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(
self as *mut ReleaseList as *mut u8,
mem::size_of::<ReleaseList>(),
) as &mut [u8]
}
}
}
#[test]
fn alloc_node_size_test() {
assert_eq!(mem::size_of::<AllocList>(), crate::BLOCK_SIZE as usize);
}
#[test]
fn release_node_size_test() {
assert_eq!(mem::size_of::<ReleaseList>(), crate::BLOCK_SIZE as usize);
}
#[test]
fn allocator_test() {
let mut alloc = Allocator::default();
assert_eq!(alloc.allocate(BlockMeta::default()), None);
alloc.deallocate(unsafe { BlockAddr::new(1, BlockMeta::default()) });
assert_eq!(
alloc.allocate(BlockMeta::default()),
Some(unsafe { BlockAddr::new(1, BlockMeta::default()) })
);
assert_eq!(alloc.allocate(BlockMeta::default()), None);
for addr in 1023..2048 {
alloc.deallocate(unsafe { BlockAddr::new(addr, BlockMeta::default()) });
}
assert_eq!(alloc.levels.len(), 11);
for level in 0..alloc.levels.len() {
if level == 0 {
assert_eq!(alloc.levels[level], [1023].into());
} else if level == 10 {
assert_eq!(alloc.levels[level], [1024].into());
} else {
assert_eq!(alloc.levels[level], [0u64; 0].into());
}
}
for addr in 1023..2048 {
assert_eq!(
alloc.allocate(BlockMeta::default()),
Some(unsafe { BlockAddr::new(addr, BlockMeta::default()) })
);
}
assert_eq!(alloc.allocate(BlockMeta::default()), None);
assert_eq!(alloc.levels.len(), 11);
for level in 0..alloc.levels.len() {
assert_eq!(alloc.levels[level], [0u64; 0].into());
}
}
+50
View File
@@ -0,0 +1,50 @@
use crate::memory::KernelMapper;
use core::{
alloc::{GlobalAlloc, Layout},
ptr::NonNull,
};
use linked_list_allocator::Heap;
use spin::Mutex;
static HEAP: Mutex<Option<Heap>> = Mutex::new(None);
pub struct Allocator;
impl Allocator {
pub unsafe fn init(offset: usize, size: usize) {
unsafe {
*HEAP.lock() = Some(Heap::new(offset, size));
}
}
}
unsafe impl GlobalAlloc for Allocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
unsafe {
while let Some(ref mut heap) = *HEAP.lock() {
match heap.allocate_first_fit(layout) {
Ok(ptr) => return ptr.as_ptr(),
Err(()) => {
let size = heap.size();
super::map_heap(
&mut KernelMapper::lock_rw(),
crate::kernel_heap_offset() + size,
super::KERNEL_HEAP_SIZE,
);
heap.extend(super::KERNEL_HEAP_SIZE);
}
}
}
panic!("__rust_allocate: heap not initialized");
}
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
unsafe {
HEAP.lock()
.as_mut()
.expect("heap not initialized")
.deallocate(NonNull::new_unchecked(ptr), layout)
}
}
}
+48
View File
@@ -0,0 +1,48 @@
use crate::memory::{KernelMapper, Page, PageFlags, VirtualAddress};
use rmm::{Flusher, FrameAllocator, PageFlushAll};
pub use self::linked_list::Allocator;
mod linked_list;
/// Size of kernel heap
const KERNEL_HEAP_SIZE: usize = ::rmm::MEGABYTE;
unsafe fn map_heap(mapper: &mut KernelMapper<true>, offset: usize, size: usize) {
let mut flush_all = PageFlushAll::new();
let heap_start_page = Page::containing_address(VirtualAddress::new(offset));
let heap_end_page = Page::containing_address(VirtualAddress::new(offset + size - 1));
for page in Page::range_inclusive(heap_start_page, heap_end_page) {
let phys = mapper
.allocator_mut()
.allocate_one()
.expect("failed to allocate kernel heap");
let flush = unsafe {
mapper
.map_phys(
page.start_address(),
phys,
PageFlags::new()
.write(true)
.global(cfg!(not(feature = "pti"))),
)
.expect("failed to map kernel heap")
};
flush_all.consume(flush);
}
flush_all.flush();
}
pub unsafe fn init() {
unsafe {
let offset = crate::kernel_heap_offset();
let size = KERNEL_HEAP_SIZE;
// Map heap pages
map_heap(&mut KernelMapper::lock_rw(), offset, size);
// Initialize global heap
Allocator::init(offset, size);
}
}
+15
View File
@@ -0,0 +1,15 @@
// Because the memory map is so important to not be aliased, it is defined here, in one place
// The lower 256 PML4 entries are reserved for userspace
// Each PML4 entry references up to 512 GB of memory
// The second from the top (510) PML4 is reserved for the kernel
/// The size of a single PML4
pub const PML4_SIZE: usize = 0x0000_0080_0000_0000;
/// Offset to kernel heap
#[inline(always)]
pub fn kernel_heap_offset() -> usize {
crate::kernel_executable_offsets::KERNEL_OFFSET() - PML4_SIZE
}
/// End offset of the user image, i.e. kernel start
pub const USER_END_OFFSET: usize = 256 * PML4_SIZE;
+19
View File
@@ -0,0 +1,19 @@
use spin::MutexGuard;
use crate::{arch::device::serial::COM1, devices::serial::SerialKind};
pub struct Writer<'a> {
serial: MutexGuard<'a, SerialKind>,
}
impl<'a> Writer<'a> {
pub fn new() -> Writer<'a> {
Writer {
serial: COM1.lock(),
}
}
pub fn write(&mut self, buf: &[u8]) {
self.serial.write(buf);
}
}
+277
View File
@@ -0,0 +1,277 @@
use core::fmt::{Result, Write};
use crate::arch::device::cpu::registers::{control_regs, id_regs};
pub mod registers;
bitfield::bitfield! {
pub struct MachineId(u32);
get_implementer, _: 31, 24;
get_variant, _: 23, 20;
get_architecture, _: 19, 16;
get_part_number, _: 15, 4;
get_revision, _: 3, 0;
}
enum ImplementerID {
Unknown,
Arm,
Broadcom,
Cavium,
Digital,
Fujitsu,
Infineon,
Motorola,
Nvidia,
AMCC,
Qualcomm,
Marvell,
Intel,
Ampere,
}
const IMPLEMENTERS: [&'static str; 14] = [
"Unknown", "Arm", "Broadcom", "Cavium", "Digital", "Fujitsu", "Infineon", "Motorola", "Nvidia",
"AMCC", "Qualcomm", "Marvell", "Intel", "Ampere",
];
enum VariantID {
Unknown,
}
const VARIANTS: [&'static str; 1] = ["Unknown"];
enum ArchitectureID {
Unknown,
V4,
V4T,
V5,
V5T,
V5TE,
V5TEJ,
V6,
}
const ARCHITECTURES: [&'static str; 8] =
["Unknown", "v4", "v4T", "v5", "v5T", "v5TE", "v5TEJ", "v6"];
enum PartNumberID {
Unknown,
Thunder,
Foundation,
CortexA35,
CortexA53,
CortexA55,
CortexA57,
CortexA72,
CortexA73,
CortexA75,
}
const PART_NUMBERS: [&'static str; 10] = [
"Unknown",
"Thunder",
"Foundation",
"Cortex-A35",
"Cortex-A53",
"Cortex-A55",
"Cortex-A57",
"Cortex-A72",
"Cortex-A73",
"Cortex-A75",
];
enum RevisionID {
Unknown,
Thunder1_0,
Thunder1_1,
}
const REVISIONS: [&'static str; 3] = ["Unknown", "Thunder-1.0", "Thunder-1.1"];
struct CpuInfo {
implementer: &'static str,
variant: &'static str,
architecture: &'static str,
part_number: &'static str,
revision: &'static str,
aa64isar0: id_regs::AA64Isar0,
aa64isar1: id_regs::AA64Isar1,
}
impl CpuInfo {
fn new() -> CpuInfo {
let midr = unsafe { control_regs::midr() };
let midr = MachineId(midr);
let implementer = match midr.get_implementer() {
0x41 => IMPLEMENTERS[ImplementerID::Arm as usize],
0x42 => IMPLEMENTERS[ImplementerID::Broadcom as usize],
0x43 => IMPLEMENTERS[ImplementerID::Cavium as usize],
0x44 => IMPLEMENTERS[ImplementerID::Digital as usize],
0x46 => IMPLEMENTERS[ImplementerID::Fujitsu as usize],
0x49 => IMPLEMENTERS[ImplementerID::Infineon as usize],
0x4d => IMPLEMENTERS[ImplementerID::Motorola as usize],
0x4e => IMPLEMENTERS[ImplementerID::Nvidia as usize],
0x50 => IMPLEMENTERS[ImplementerID::AMCC as usize],
0x51 => IMPLEMENTERS[ImplementerID::Qualcomm as usize],
0x56 => IMPLEMENTERS[ImplementerID::Marvell as usize],
0x69 => IMPLEMENTERS[ImplementerID::Intel as usize],
0xc0 => IMPLEMENTERS[ImplementerID::Ampere as usize],
_ => IMPLEMENTERS[ImplementerID::Unknown as usize],
};
let variant = match midr.get_variant() {
_ => VARIANTS[VariantID::Unknown as usize],
};
let architecture = match midr.get_architecture() {
0b0001 => ARCHITECTURES[ArchitectureID::V4 as usize],
0b0010 => ARCHITECTURES[ArchitectureID::V4T as usize],
0b0011 => ARCHITECTURES[ArchitectureID::V5 as usize],
0b0100 => ARCHITECTURES[ArchitectureID::V5T as usize],
0b0101 => ARCHITECTURES[ArchitectureID::V5TE as usize],
0b0110 => ARCHITECTURES[ArchitectureID::V5TEJ as usize],
0b0111 => ARCHITECTURES[ArchitectureID::V6 as usize],
_ => ARCHITECTURES[ArchitectureID::Unknown as usize],
};
let part_number = match midr.get_part_number() {
0x0a1 => PART_NUMBERS[PartNumberID::Thunder as usize],
0xd00 => PART_NUMBERS[PartNumberID::Foundation as usize],
0xd04 => PART_NUMBERS[PartNumberID::CortexA35 as usize],
0xd03 => PART_NUMBERS[PartNumberID::CortexA53 as usize],
0xd05 => PART_NUMBERS[PartNumberID::CortexA55 as usize],
0xd07 => PART_NUMBERS[PartNumberID::CortexA57 as usize],
0xd08 => PART_NUMBERS[PartNumberID::CortexA72 as usize],
0xd09 => PART_NUMBERS[PartNumberID::CortexA73 as usize],
0xd0a => PART_NUMBERS[PartNumberID::CortexA75 as usize],
_ => PART_NUMBERS[PartNumberID::Unknown as usize],
};
let revision = match part_number {
"Thunder" => {
let val = match midr.get_revision() {
0x00 => REVISIONS[RevisionID::Thunder1_0 as usize],
0x01 => REVISIONS[RevisionID::Thunder1_1 as usize],
_ => REVISIONS[RevisionID::Unknown as usize],
};
val
}
_ => REVISIONS[RevisionID::Unknown as usize],
};
let aa64isar0 = id_regs::aa64isar0();
let aa64isar1 = id_regs::aa64isar1();
CpuInfo {
implementer,
variant,
architecture,
part_number,
revision,
aa64isar0,
aa64isar1,
}
}
}
pub fn cpu_info<W: Write>(w: &mut W) -> Result {
let cpuinfo = CpuInfo::new();
writeln!(w, "Implementer: {}", cpuinfo.implementer)?;
writeln!(w, "Variant: {}", cpuinfo.variant)?;
writeln!(w, "Architecture version: {}", cpuinfo.architecture)?;
writeln!(w, "Part Number: {}", cpuinfo.part_number)?;
writeln!(w, "Revision: {}", cpuinfo.revision)?;
// Print detected CPU features.
// Follow the naming convention estabilished by `std::arch::is_aarch64_feature_detected`.
write!(w, "Features:")?;
// ID_AA64ISAR0_EL1
if cpuinfo.aa64isar0.has_feat_rng() {
write!(w, " rand")?;
}
if cpuinfo.aa64isar0.has_feat_flagm() {
write!(w, " flagm")?;
}
if cpuinfo.aa64isar0.has_feat_flagm2() {
write!(w, " flagm2")?;
}
if cpuinfo.aa64isar0.has_feat_fhm() {
write!(w, " fhm")?;
}
if cpuinfo.aa64isar0.has_feat_dotprod() {
write!(w, " dotprod")?;
}
if cpuinfo.aa64isar0.has_feat_sm3() && cpuinfo.aa64isar0.has_feat_sm4() {
write!(w, " sm4")?;
}
if cpuinfo.aa64isar0.has_feat_sha512() && cpuinfo.aa64isar0.has_feat_sha3() {
write!(w, " sha3")?;
}
if cpuinfo.aa64isar0.has_feat_rdm() {
write!(w, " rdm")?;
}
if cpuinfo.aa64isar0.has_feat_lse() {
write!(w, " lse")?;
}
if cpuinfo.aa64isar0.has_feat_lse128() {
write!(w, " lse128")?;
}
if cpuinfo.aa64isar0.has_feat_crc() {
write!(w, " crc")?;
}
if cpuinfo.aa64isar0.has_feat_sha1() && cpuinfo.aa64isar0.has_feat_sha256() {
write!(w, " sha2")?;
}
if cpuinfo.aa64isar0.has_feat_aes() && cpuinfo.aa64isar0.has_feat_pmull() {
write!(w, " aes")?;
}
// ID_AA64ISAR1_EL1
if cpuinfo.aa64isar1.has_feat_i8mm() {
write!(w, " i8mm")?;
}
if cpuinfo.aa64isar1.has_feat_bf16() {
write!(w, " bf16")?;
}
if cpuinfo.aa64isar1.has_feat_sb() {
write!(w, " sb")?;
}
if cpuinfo.aa64isar1.has_feat_frintts() {
write!(w, " frintts")?;
}
if cpuinfo.aa64isar1.gpi() != 0 || cpuinfo.aa64isar1.gpa() != 0 {
write!(w, " pacg")?;
}
if cpuinfo.aa64isar1.has_feat_lrcpc() {
write!(w, " rcpc")?;
}
if cpuinfo.aa64isar1.has_feat_lrcpc2() {
write!(w, " rcpc2")?;
}
if cpuinfo.aa64isar1.has_feat_lrcpc3() {
write!(w, " rcpc3")?;
}
if cpuinfo.aa64isar1.has_feat_fcma() {
write!(w, " fcma")?;
}
if cpuinfo.aa64isar1.has_feat_jscvt() {
write!(w, " jsconv")?;
}
if cpuinfo.aa64isar1.api() != 0 || cpuinfo.aa64isar1.apa() != 0 {
write!(w, " paca")?;
}
if cpuinfo.aa64isar1.has_feat_dpb() {
write!(w, " dpb")?;
}
if cpuinfo.aa64isar1.has_feat_dpb2() {
write!(w, " dpb2")?;
}
writeln!(w)?;
Ok(())
}
@@ -0,0 +1,167 @@
#![allow(unused)]
//! Functions to read and write control registers.
use core::arch::asm;
pub unsafe fn ttbr0_el1() -> u64 {
unsafe {
let ret: u64;
asm!("mrs {}, ttbr0_el1", out(reg) ret);
ret
}
}
pub unsafe fn ttbr0_el1_write(val: u64) {
unsafe {
asm!("msr ttbr0_el1, {}", in(reg) val);
}
}
pub unsafe fn ttbr1_el1() -> u64 {
unsafe {
let ret: u64;
asm!("mrs {}, ttbr1_el1", out(reg) ret);
ret
}
}
pub unsafe fn ttbr1_el1_write(val: u64) {
unsafe {
asm!("msr ttbr1_el1, {}", in(reg) val);
}
}
pub unsafe fn tpidr_el0() -> u64 {
unsafe {
let ret: u64;
asm!("mrs {}, tpidr_el0", out(reg) ret);
ret
}
}
pub unsafe fn tpidr_el0_write(val: u64) {
unsafe {
asm!("msr tpidr_el0, {}", in(reg) val);
}
}
pub unsafe fn tpidr_el1() -> u64 {
unsafe {
let ret: u64;
asm!("mrs {}, tpidr_el1", out(reg) ret);
ret
}
}
pub unsafe fn tpidr_el1_write(val: u64) {
unsafe {
asm!("msr tpidr_el1, {}", in(reg) val);
}
}
pub unsafe fn tpidrro_el0() -> u64 {
unsafe {
let ret: u64;
asm!("mrs {}, tpidrro_el0", out(reg) ret);
ret
}
}
pub unsafe fn tpidrro_el0_write(val: u64) {
unsafe {
asm!("msr tpidrro_el0, {}", in(reg) val);
}
}
pub unsafe fn esr_el1() -> u32 {
unsafe {
let ret: u32;
asm!("mrs {0:w}, esr_el1", out(reg) ret);
ret
}
}
pub unsafe fn vhe_present() -> bool {
unsafe {
let mut mmfr1: u64;
asm!("mrs {}, id_aa64mmfr1_el1", out(reg) mmfr1);
// The VHE (Virtualization Host Extensions) field is in bits [7:4].
let vhe_field = (mmfr1 >> 4) & 0b1111;
vhe_field != 0
}
}
pub unsafe fn cntfrq_el0() -> u32 {
unsafe {
let ret: usize;
asm!("mrs {}, cntfrq_el0", out(reg) ret);
ret as u32
}
}
pub unsafe fn ptmr_ctrl() -> u32 {
unsafe {
let ret: usize;
asm!("mrs {}, cntp_ctl_el0", out(reg) ret);
ret as u32
}
}
pub unsafe fn ptmr_ctrl_write(val: u32) {
unsafe {
asm!("msr cntp_ctl_el0, {}", in(reg) val as usize);
}
}
pub unsafe fn ptmr_tval() -> u32 {
unsafe {
let ret: usize;
asm!("mrs {0}, cntp_tval_el0", out(reg) ret);
ret as u32
}
}
pub unsafe fn ptmr_tval_write(val: u32) {
unsafe {
asm!("msr cntp_tval_el0, {}", in(reg) val as usize);
}
}
pub unsafe fn vtmr_ctrl() -> u32 {
unsafe {
let ret: usize;
asm!("mrs {}, cntv_ctl_el0", out(reg) ret);
ret as u32
}
}
pub unsafe fn vtmr_ctrl_write(val: u32) {
unsafe {
asm!("msr cntv_ctl_el0, {}", in(reg) val as usize);
}
}
pub unsafe fn vtmr_tval() -> u32 {
unsafe {
let ret: usize;
asm!("mrs {0}, cntv_tval_el0", out(reg) ret);
ret as u32
}
}
pub unsafe fn vtmr_tval_write(val: u32) {
unsafe {
asm!("msr cntv_tval_el0, {}", in(reg) val as usize);
}
}
pub unsafe fn midr() -> u32 {
unsafe {
let ret: usize;
asm!("mrs {}, midr_el1", out(reg) ret);
ret as u32
}
}
@@ -0,0 +1,151 @@
//! Functions and bitfield definitions for `ID_AA64*` system registers. (e.g. `ID_AA64ISAR0_EL1`)
use core::arch::asm;
bitfield::bitfield! {
pub struct AA64Isar0(u64);
impl Debug;
pub rndr, _: 63, 60;
pub tlb, _: 59, 56;
pub ts, _: 55, 52;
pub fhm, _: 51, 48;
pub dp, _: 47, 44;
pub sm4, _: 43, 40;
pub sm3, _: 39, 36;
pub sha3, _: 35, 32;
pub rdm, _: 31, 28;
pub atomic, _: 23, 20;
pub crc32, _: 19, 16;
pub sha2, _: 15, 12;
pub sha1, _: 11, 8;
pub aes, _: 7, 4;
}
bitfield::bitfield! {
pub struct AA64Isar1(u64);
impl Debug;
pub ls64, _: 63, 60;
pub xs, _: 59, 56;
pub i8mm, _: 55, 52;
pub dgh, _: 51, 48;
pub bf16, _: 47, 44;
pub specres, _: 43, 40;
pub sb, _: 39, 36;
pub frintts, _: 35, 32;
pub gpi, _: 31, 28;
pub gpa, _: 27, 24;
pub lrcpc, _: 23, 20;
pub fcma, _: 19, 16;
pub jscvt, _: 15, 12;
pub api, _: 11, 8;
pub apa, _: 7, 4;
pub dpb, _: 3, 0;
}
impl AA64Isar0 {
pub fn has_feat_rng(&self) -> bool {
self.rndr() == 0b0001
}
pub fn has_feat_flagm(&self) -> bool {
self.ts() == 0b0001
}
pub fn has_feat_flagm2(&self) -> bool {
self.ts() == 0b0010
}
pub fn has_feat_fhm(&self) -> bool {
self.fhm() == 0b0001
}
pub fn has_feat_dotprod(&self) -> bool {
self.dp() == 0b0001
}
pub fn has_feat_sm4(&self) -> bool {
self.sm4() == 0b0001
}
pub fn has_feat_sm3(&self) -> bool {
self.sm3() == 0b0001
}
pub fn has_feat_sha3(&self) -> bool {
self.sha3() == 0b0001
}
pub fn has_feat_rdm(&self) -> bool {
self.rdm() == 0b0001
}
pub fn has_feat_lse(&self) -> bool {
self.atomic() == 0b0010
}
pub fn has_feat_lse128(&self) -> bool {
self.atomic() == 0b0011
}
/// The current Arm Architecture Registers Manual calls it FEAT_CRC32,
/// but everyone else seems to call it FEAT_CRC.
pub fn has_feat_crc(&self) -> bool {
self.crc32() == 0b0001
}
pub fn has_feat_sha256(&self) -> bool {
self.sha2() == 0b0001
}
pub fn has_feat_sha512(&self) -> bool {
self.sha2() == 0b0010
}
pub fn has_feat_sha1(&self) -> bool {
self.sha1() == 0b0001
}
pub fn has_feat_aes(&self) -> bool {
self.aes() == 0b0001
}
pub fn has_feat_pmull(&self) -> bool {
self.aes() == 0b0010
}
}
impl AA64Isar1 {
pub fn has_feat_i8mm(&self) -> bool {
self.i8mm() == 0b0001
}
pub fn has_feat_bf16(&self) -> bool {
self.bf16() == 0b0001
}
pub fn has_feat_sb(&self) -> bool {
self.sb() == 0b0001
}
pub fn has_feat_frintts(&self) -> bool {
self.frintts() == 0b0001
}
pub fn has_feat_lrcpc(&self) -> bool {
self.lrcpc() == 0b0001
}
pub fn has_feat_lrcpc2(&self) -> bool {
self.lrcpc() == 0b0010
}
pub fn has_feat_lrcpc3(&self) -> bool {
self.lrcpc() == 0b0011
}
pub fn has_feat_fcma(&self) -> bool {
self.fcma() == 0b0001
}
pub fn has_feat_jscvt(&self) -> bool {
self.jscvt() == 0b0011
}
pub fn has_feat_dpb(&self) -> bool {
self.dpb() == 0b0001
}
pub fn has_feat_dpb2(&self) -> bool {
self.dpb() == 0b0010
}
}
pub fn aa64isar0() -> AA64Isar0 {
let ret: u64;
unsafe {
asm!("mrs {}, ID_AA64ISAR0_EL1", out(reg) ret);
}
AA64Isar0(ret)
}
pub fn aa64isar1() -> AA64Isar1 {
let ret: u64;
unsafe {
asm!("mrs {}, ID_AA64ISAR1_EL1", out(reg) ret);
}
AA64Isar1(ret)
}
@@ -0,0 +1,2 @@
pub mod control_regs;
pub mod id_regs;
+145
View File
@@ -0,0 +1,145 @@
use alloc::boxed::Box;
use super::ic_for_chip;
use crate::{
arch::device::cpu::registers::control_regs,
context::{self, timeout},
dtb::{
get_interrupt,
irqchip::{register_irq, InterruptHandler, IRQ_CHIP},
},
scheme::irq::irq_trigger,
sync::CleanLockToken,
time,
};
use fdt::Fdt;
bitflags! {
struct TimerCtrlFlags: u32 {
const ENABLE = 1 << 0;
const IMASK = 1 << 1;
const ISTATUS = 1 << 2;
}
}
pub unsafe fn init(fdt: &Fdt) {
unsafe {
let mut timer = GenericTimer::new();
timer.init();
if let Some(node) = fdt.find_compatible(&["arm,armv7-timer"]) {
let irq = get_interrupt(fdt, &node, 1).unwrap();
debug!("irq = {:?}", irq);
if let Some(ic_idx) = ic_for_chip(&fdt, &node) {
//PHYS_NONSECURE_PPI only
let virq = IRQ_CHIP.irq_chip_list.chips[ic_idx]
.ic
.irq_xlate(irq)
.unwrap();
info!("generic_timer virq = {}", virq);
register_irq(virq as u32, Box::new(timer));
IRQ_CHIP.irq_enable(virq as u32);
} else {
error!("Failed to find irq parent for generic timer");
}
}
}
}
pub struct GenericTimer {
pub use_virtual_timer: bool,
pub clk_freq: u32,
pub reload_count: u32,
}
impl GenericTimer {
pub fn new() -> Self {
Self {
use_virtual_timer: false,
clk_freq: 0,
reload_count: 0,
}
}
pub fn init(&mut self) {
self.use_virtual_timer = unsafe { !control_regs::vhe_present() };
debug!(
"generic_timer use_virtual_timer = {:?}",
self.use_virtual_timer
);
let clk_freq = unsafe { control_regs::cntfrq_el0() };
self.clk_freq = clk_freq;
self.reload_count = clk_freq / 100;
self.reload_count();
}
fn read_tmr_ctrl(&self) -> TimerCtrlFlags {
TimerCtrlFlags::from_bits_truncate(if self.use_virtual_timer {
unsafe { control_regs::vtmr_ctrl() }
} else {
unsafe { control_regs::ptmr_ctrl() }
})
}
fn write_tmr_ctrl(&self, ctrl: TimerCtrlFlags) {
if self.use_virtual_timer {
unsafe { control_regs::vtmr_ctrl_write(ctrl.bits()) };
} else {
unsafe { control_regs::ptmr_ctrl_write(ctrl.bits()) };
}
}
#[allow(unused)]
fn disable(&self) {
let mut ctrl = self.read_tmr_ctrl();
ctrl.remove(TimerCtrlFlags::ENABLE);
self.write_tmr_ctrl(ctrl);
}
#[allow(unused)]
pub fn set_irq(&mut self) {
let mut ctrl = self.read_tmr_ctrl();
ctrl.remove(TimerCtrlFlags::IMASK);
self.write_tmr_ctrl(ctrl);
}
pub fn clear_irq(&mut self) {
let mut ctrl = self.read_tmr_ctrl();
if ctrl.contains(TimerCtrlFlags::ISTATUS) {
ctrl.insert(TimerCtrlFlags::IMASK);
self.write_tmr_ctrl(ctrl);
}
}
pub fn reload_count(&mut self) {
if self.use_virtual_timer {
unsafe { control_regs::vtmr_tval_write(self.reload_count) };
} else {
unsafe { control_regs::ptmr_tval_write(self.reload_count) };
}
let mut ctrl = self.read_tmr_ctrl();
ctrl.insert(TimerCtrlFlags::ENABLE);
ctrl.remove(TimerCtrlFlags::IMASK);
self.write_tmr_ctrl(ctrl);
}
}
impl InterruptHandler for GenericTimer {
fn irq_handler(&mut self, irq: u32, token: &mut CleanLockToken) {
self.clear_irq();
{
*time::OFFSET.write(token.token()) += self.clk_freq as u128;
}
timeout::trigger(token);
context::switch::tick(token);
unsafe {
// FIXME add_irq accepts a u8 as irq number
// PercpuBlock::current().stats.add_irq(irq);
irq_trigger(irq.try_into().unwrap(), token);
IRQ_CHIP.irq_eoi(irq);
}
self.reload_count();
}
}
+288
View File
@@ -0,0 +1,288 @@
use super::InterruptController;
use crate::{
dtb::{
get_mmio_address,
irqchip::{InterruptHandler, IrqCell, IrqDesc},
},
sync::CleanLockToken,
};
use core::ptr::{read_volatile, write_volatile};
use fdt::{node::FdtNode, Fdt};
use syscall::{
error::{Error, EINVAL},
Result,
};
static GICD_CTLR: u32 = 0x000;
static GICD_TYPER: u32 = 0x004;
static GICD_ISENABLER: u32 = 0x100;
static GICD_ICENABLER: u32 = 0x180;
static GICD_IPRIORITY: u32 = 0x400;
static GICD_ITARGETSR: u32 = 0x800;
static GICD_ICFGR: u32 = 0xc00;
static GICC_EOIR: u32 = 0x0010;
static GICC_IAR: u32 = 0x000c;
static GICC_CTLR: u32 = 0x0000;
static GICC_PMR: u32 = 0x0004;
pub struct GenericInterruptController {
pub gic_dist_if: GicDistIf,
pub gic_cpu_if: GicCpuIf,
pub irq_range: (usize, usize),
}
impl GenericInterruptController {
pub fn new() -> Self {
let gic_dist_if = GicDistIf::default();
let gic_cpu_if = GicCpuIf::default();
GenericInterruptController {
gic_dist_if,
gic_cpu_if,
irq_range: (0, 0),
}
}
pub fn parse(fdt: &Fdt) -> Result<(usize, usize, usize, usize)> {
if let Some(node) = fdt.find_compatible(&["arm,cortex-a15-gic", "arm,gic-400"]) {
return GenericInterruptController::parse_inner(fdt, &node);
} else {
return Err(Error::new(EINVAL));
}
}
fn parse_inner(fdt: &Fdt, node: &FdtNode) -> Result<(usize, usize, usize, usize)> {
//assert address_cells == 0x2, size_cells == 0x2
let reg = node.reg().unwrap();
let mut regs = (0, 0, 0, 0);
let mut idx = 0;
for chunk in reg {
if chunk.size.is_none() {
break;
}
let addr = get_mmio_address(fdt, node, &chunk).unwrap();
match idx {
0 => (regs.0, regs.1) = (addr, chunk.size.unwrap()),
2 => (regs.2, regs.3) = (addr, chunk.size.unwrap()),
_ => break,
}
idx += 2;
}
if idx == 4 {
Ok(regs)
} else {
Err(Error::new(EINVAL))
}
}
}
impl InterruptHandler for GenericInterruptController {
fn irq_handler(&mut self, _irq: u32, token: &mut CleanLockToken) {}
}
impl InterruptController for GenericInterruptController {
fn irq_init(
&mut self,
fdt_opt: Option<&Fdt>,
irq_desc: &mut [IrqDesc; 1024],
ic_idx: usize,
irq_idx: &mut usize,
) -> Result<()> {
if let Some(fdt) = fdt_opt {
let (dist_addr, _dist_size, cpu_addr, _cpu_size) =
match GenericInterruptController::parse(fdt) {
Ok(regs) => regs,
Err(err) => return Err(err),
};
unsafe {
self.gic_dist_if.init(crate::PHYS_OFFSET + dist_addr);
self.gic_cpu_if.init(crate::PHYS_OFFSET + cpu_addr);
}
}
let idx = *irq_idx;
let cnt = if self.gic_dist_if.nirqs > 1024 {
1024
} else {
self.gic_dist_if.nirqs as usize
};
let mut i: usize = 0;
//only support linear irq map now.
while i < cnt && (idx + i < 1024) {
irq_desc[idx + i].basic.ic_idx = ic_idx;
irq_desc[idx + i].basic.ic_irq = i as u32;
irq_desc[idx + i].basic.used = true;
i += 1;
}
info!("gic irq_range = ({}, {})", idx, idx + cnt);
self.irq_range = (idx, idx + cnt);
*irq_idx = idx + cnt;
Ok(())
}
fn irq_ack(&mut self) -> u32 {
unsafe { self.gic_cpu_if.irq_ack() }
}
fn irq_eoi(&mut self, irq_num: u32) {
unsafe { self.gic_cpu_if.irq_eoi(irq_num) }
}
fn irq_enable(&mut self, irq_num: u32) {
unsafe { self.gic_dist_if.irq_enable(irq_num) }
}
fn irq_disable(&mut self, irq_num: u32) {
unsafe { self.gic_dist_if.irq_disable(irq_num) }
}
fn irq_xlate(&self, irq_data: IrqCell) -> Result<usize> {
let off = match irq_data {
IrqCell::L3(0, irq, _flags) => irq as usize + 32, // SPI
IrqCell::L3(1, irq, _flags) => irq as usize + 16, // PPI
_ => return Err(Error::new(EINVAL)),
};
return Ok(off + self.irq_range.0);
}
fn irq_to_virq(&self, hwirq: u32) -> Option<usize> {
if hwirq >= self.gic_dist_if.nirqs {
None
} else {
Some(self.irq_range.0 + hwirq as usize)
}
}
}
#[derive(Debug, Default)]
pub struct GicDistIf {
pub address: usize,
pub ncpus: u32,
pub nirqs: u32,
}
impl GicDistIf {
pub unsafe fn init(&mut self, addr: usize) {
unsafe {
self.address = addr;
// Disable IRQ Distribution
self.write(GICD_CTLR, 0);
let typer = self.read(GICD_TYPER);
self.ncpus = ((typer & (0x7 << 5)) >> 5) + 1;
self.nirqs = ((typer & 0x1f) + 1) * 32;
info!(
"gic: Distributor supports {:?} CPUs and {:?} IRQs",
self.ncpus, self.nirqs
);
// Set all SPIs to level triggered
for irq in (32..self.nirqs).step_by(16) {
self.write(GICD_ICFGR + ((irq / 16) * 4), 0);
}
// Disable all SPIs
for irq in (32..self.nirqs).step_by(32) {
self.write(GICD_ICENABLER + ((irq / 32) * 4), 0xffff_ffff);
}
// Affine all SPIs to CPU0 and set priorities for all IRQs
for irq in 0..self.nirqs {
if irq > 31 {
let ext_offset = GICD_ITARGETSR + (4 * (irq / 4));
let int_offset = irq % 4;
let mut val = self.read(ext_offset);
val |= 0b0000_0001 << (8 * int_offset);
self.write(ext_offset, val);
}
let ext_offset = GICD_IPRIORITY + (4 * (irq / 4));
let int_offset = irq % 4;
let mut val = self.read(ext_offset);
val |= 0b0000_0000 << (8 * int_offset);
self.write(ext_offset, val);
}
// Enable IRQ group 0 and group 1 non-secure distribution
self.write(GICD_CTLR, 0x3);
}
}
pub unsafe fn irq_enable(&mut self, irq: u32) {
unsafe {
let offset = GICD_ISENABLER + (4 * (irq / 32));
let shift = 1 << (irq % 32);
let mut val = self.read(offset);
val |= shift;
self.write(offset, val);
}
}
pub unsafe fn irq_disable(&mut self, irq: u32) {
unsafe {
let offset = GICD_ICENABLER + (4 * (irq / 32));
let shift = 1 << (irq % 32);
let mut val = self.read(offset);
val |= shift;
self.write(offset, val);
}
}
unsafe fn read(&self, reg: u32) -> u32 {
unsafe {
let val = read_volatile((self.address + reg as usize) as *const u32);
val
}
}
unsafe fn write(&mut self, reg: u32, value: u32) {
unsafe {
write_volatile((self.address + reg as usize) as *mut u32, value);
}
}
}
#[derive(Debug, Default)]
pub struct GicCpuIf {
pub address: usize,
}
impl GicCpuIf {
pub unsafe fn init(&mut self, addr: usize) {
unsafe {
self.address = addr;
// Enable CPU0's GIC interface
self.write(GICC_CTLR, 1);
// Set CPU0's Interrupt Priority Mask
self.write(GICC_PMR, 0xff);
}
}
unsafe fn irq_ack(&mut self) -> u32 {
unsafe {
let irq = self.read(GICC_IAR) & 0x1ff;
if irq == 1023 {
panic!("irq_ack: got ID 1023!!!");
}
irq
}
}
unsafe fn irq_eoi(&mut self, irq: u32) {
unsafe {
self.write(GICC_EOIR, irq);
}
}
unsafe fn read(&self, reg: u32) -> u32 {
unsafe {
let val = read_volatile((self.address + reg as usize) as *const u32);
val
}
}
unsafe fn write(&mut self, reg: u32, value: u32) {
unsafe {
write_volatile((self.address + reg as usize) as *mut u32, value);
}
}
}
+196
View File
@@ -0,0 +1,196 @@
use alloc::vec::Vec;
use core::arch::asm;
use fdt::{node::NodeProperty, Fdt};
use super::{gic::GicDistIf, InterruptController};
use crate::{
dtb::{
get_mmio_address,
irqchip::{InterruptHandler, IrqCell, IrqDesc},
},
sync::CleanLockToken,
};
use syscall::{
error::{Error, EINVAL},
Result,
};
#[derive(Debug)]
pub struct GicV3 {
pub gic_dist_if: GicDistIf,
pub gic_cpu_if: GicV3CpuIf,
pub gicrs: Vec<(usize, usize)>,
//TODO: GICC, GICH, GICV?
pub irq_range: (usize, usize),
}
impl GicV3 {
pub fn new() -> Self {
GicV3 {
gic_dist_if: GicDistIf::default(),
gic_cpu_if: GicV3CpuIf,
gicrs: Vec::new(),
irq_range: (0, 0),
}
}
pub fn parse(&mut self, fdt: &Fdt) -> Result<()> {
let Some(node) = fdt.find_compatible(&["arm,gic-v3"]) else {
return Err(Error::new(EINVAL));
};
// Clear current registers
//TODO: deinit?
self.gic_dist_if.address = 0;
self.gicrs.clear();
// Get number of GICRs
let gicrs = node
.property("#redistributor-regions")
.and_then(NodeProperty::as_usize)
.unwrap_or(1);
// Read registers
let mut chunks = node.reg().unwrap();
if let Some(gicd) = chunks.next()
&& let Some(addr) = get_mmio_address(fdt, &node, &gicd)
{
unsafe {
self.gic_dist_if.init(crate::PHYS_OFFSET + addr);
}
}
for _ in 0..gicrs {
if let Some(gicr) = chunks.next() {
self.gicrs.push((
get_mmio_address(fdt, &node, &gicr).unwrap(),
gicr.size.unwrap(),
));
}
}
if self.gic_dist_if.address == 0 || self.gicrs.is_empty() {
Err(Error::new(EINVAL))
} else {
Ok(())
}
}
}
impl InterruptHandler for GicV3 {
fn irq_handler(&mut self, _irq: u32, token: &mut CleanLockToken) {}
}
impl InterruptController for GicV3 {
fn irq_init(
&mut self,
fdt_opt: Option<&Fdt>,
irq_desc: &mut [IrqDesc; 1024],
ic_idx: usize,
irq_idx: &mut usize,
) -> Result<()> {
if let Some(fdt) = fdt_opt {
self.parse(fdt)?;
}
info!("{:X?}", self);
unsafe {
self.gic_cpu_if.init();
}
let idx = *irq_idx;
let cnt = if self.gic_dist_if.nirqs > 1024 {
1024
} else {
self.gic_dist_if.nirqs as usize
};
let mut i: usize = 0;
//only support linear irq map now.
while i < cnt && (idx + i < 1024) {
irq_desc[idx + i].basic.ic_idx = ic_idx;
irq_desc[idx + i].basic.ic_irq = i as u32;
irq_desc[idx + i].basic.used = true;
i += 1;
}
info!("gic irq_range = ({}, {})", idx, idx + cnt);
self.irq_range = (idx, idx + cnt);
*irq_idx = idx + cnt;
Ok(())
}
fn irq_ack(&mut self) -> u32 {
let irq_num = unsafe { self.gic_cpu_if.irq_ack() };
irq_num
}
fn irq_eoi(&mut self, irq_num: u32) {
unsafe { self.gic_cpu_if.irq_eoi(irq_num) }
}
fn irq_enable(&mut self, irq_num: u32) {
unsafe { self.gic_dist_if.irq_enable(irq_num) }
}
fn irq_disable(&mut self, irq_num: u32) {
unsafe { self.gic_dist_if.irq_disable(irq_num) }
}
fn irq_xlate(&self, irq_data: IrqCell) -> Result<usize> {
let off = match irq_data {
IrqCell::L3(0, irq, _flags) => irq as usize + 32, // SPI
IrqCell::L3(1, irq, _flags) => irq as usize + 16, // PPI
_ => return Err(Error::new(EINVAL)),
};
return Ok(off + self.irq_range.0);
}
fn irq_to_virq(&self, hwirq: u32) -> Option<usize> {
if hwirq >= self.gic_dist_if.nirqs {
None
} else {
Some(self.irq_range.0 + hwirq as usize)
}
}
}
#[derive(Debug)]
pub struct GicV3CpuIf;
impl GicV3CpuIf {
pub unsafe fn init(&mut self) {
unsafe {
// Enable system register access
{
let value = 1_usize;
asm!("msr icc_sre_el1, {}", in(reg) value);
}
// Set control register
{
let value = 0_usize;
asm!("msr icc_ctlr_el1, {}", in(reg) value);
}
// Enable non-secure group 1
{
let value = 1_usize;
asm!("msr icc_igrpen1_el1, {}", in(reg) value);
}
// Set CPU0's Interrupt Priority Mask
{
let value = 0xFF_usize;
asm!("msr icc_pmr_el1, {}", in(reg) value);
}
}
}
unsafe fn irq_ack(&mut self) -> u32 {
unsafe {
let mut irq: usize;
asm!("mrs {}, icc_iar1_el1", out(reg) irq);
irq &= 0x1ff;
if irq == 1023 {
panic!("irq_ack: got ID 1023!!!");
}
irq as u32
}
}
unsafe fn irq_eoi(&mut self, irq: u32) {
unsafe {
asm!("msr icc_eoir1_el1, {}", in(reg) irq as usize);
}
}
}
@@ -0,0 +1,299 @@
use core::ptr::{read_volatile, write_volatile};
use fdt::{node::FdtNode, Fdt};
use super::InterruptController;
use crate::{
dtb::{
get_interrupt, get_mmio_address,
irqchip::{InterruptHandler, IrqCell, IrqDesc, IRQ_CHIP},
},
sync::CleanLockToken,
};
use syscall::{
error::{Error, EINVAL},
Result,
};
#[inline(always)]
fn ffs(num: u32) -> u32 {
let mut x = num;
if x == 0 {
return 0;
}
let mut r = 1;
if (x & 0xffff) == 0 {
x >>= 16;
r += 16;
}
if (x & 0xff) == 0 {
x >>= 8;
r += 8;
}
if (x & 0xf) == 0 {
x >>= 4;
r += 4;
}
if (x & 0x3) == 0 {
x >>= 2;
r += 2;
}
if (x & 0x1) == 0 {
r += 1;
}
r
}
const PENDING_0: u32 = 0x0;
const PENDING_1: u32 = 0x4;
const PENDING_2: u32 = 0x8;
const ENABLE_0: u32 = 0x18;
const ENABLE_1: u32 = 0x10;
const ENABLE_2: u32 = 0x14;
const DISABLE_0: u32 = 0x24;
const DISABLE_1: u32 = 0x1c;
const DISABLE_2: u32 = 0x20;
pub struct Bcm2835ArmInterruptController {
pub address: usize,
pub irq_range: (usize, usize),
}
impl Bcm2835ArmInterruptController {
pub fn new() -> Self {
Bcm2835ArmInterruptController {
address: 0,
irq_range: (0, 0),
}
}
pub fn parse(fdt: &Fdt) -> Result<(usize, usize, Option<usize>)> {
if let Some(node) = fdt.find_compatible(&["brcm,bcm2836-armctrl-ic"]) {
return unsafe { Bcm2835ArmInterruptController::parse_inner(fdt, &node) };
} else {
return Err(Error::new(EINVAL));
}
}
unsafe fn parse_inner(fdt: &Fdt, node: &FdtNode) -> Result<(usize, usize, Option<usize>)> {
unsafe {
//assert address_cells == 0x1, size_cells == 0x1
let mem = node.reg().unwrap().nth(0).unwrap();
let base = get_mmio_address(fdt, node, &mem).unwrap();
let size = mem.size.unwrap() as u32;
let mut ret_virq = None;
if let Some(interrupt_parent) = node.property("interrupt-parent") {
let phandle = interrupt_parent.as_usize().unwrap() as u32;
let irq = get_interrupt(fdt, node, 0).unwrap();
let ic_idx = IRQ_CHIP.phandle_to_ic_idx(phandle).unwrap();
//PHYS_NONSECURE_PPI only
let virq = IRQ_CHIP.irq_chip_list.chips[ic_idx]
.ic
.irq_xlate(irq)
.unwrap();
info!(
"register bcm2835arm_ctrl as ic_idx {}'s child virq = {}",
ic_idx, virq
);
ret_virq = Some(virq);
}
Ok((base as usize, size as usize, ret_virq))
}
}
unsafe fn init(&mut self) {
unsafe {
debug!("IRQ BCM2835 INIT");
//disable all interrupt
self.write(DISABLE_0, 0xffff_ffff);
self.write(DISABLE_1, 0xffff_ffff);
self.write(DISABLE_2, 0xffff_ffff);
debug!("IRQ BCM2835 END");
}
}
unsafe fn read(&self, reg: u32) -> u32 {
unsafe {
let val = read_volatile((self.address + reg as usize) as *const u32);
val
}
}
unsafe fn write(&mut self, reg: u32, value: u32) {
unsafe {
write_volatile((self.address + reg as usize) as *mut u32, value);
}
}
}
impl InterruptController for Bcm2835ArmInterruptController {
fn irq_init(
&mut self,
fdt_opt: Option<&Fdt>,
irq_desc: &mut [IrqDesc; 1024],
ic_idx: usize,
irq_idx: &mut usize,
) -> Result<()> {
let (base, _size, _virq) = match Bcm2835ArmInterruptController::parse(fdt_opt.unwrap()) {
Ok((a, b, c)) => (a, b, c),
Err(_) => return Err(Error::new(EINVAL)),
};
unsafe {
self.address = base + crate::PHYS_OFFSET;
self.init();
let idx = *irq_idx;
let cnt = 3 << 5; //3 * 32 irqs, basic == 8, reg1 = 32, reg2 = 32
let mut i: usize = 0;
//only support linear irq map now.
while i < cnt && (idx + i < 1024) {
irq_desc[idx + i].basic.ic_idx = ic_idx;
irq_desc[idx + i].basic.ic_irq = i as u32;
irq_desc[idx + i].basic.used = true;
i += 1;
}
info!("bcm2835 irq_range = ({}, {})", idx, idx + cnt);
self.irq_range = (idx, idx + cnt);
*irq_idx = idx + cnt;
}
Ok(())
}
fn irq_ack(&mut self) -> u32 {
//TODO: support smp self.read(LOCAL_IRQ_PENDING + 4 * cpu)
let sources = unsafe { self.read(PENDING_0) };
let pending_num = ffs(sources) - 1;
let fast_irq = [
7 + 32,
9 + 32,
10 + 32,
18 + 32,
19 + 32,
21 + 64,
22 + 64,
23 + 64,
24 + 64,
25 + 64,
30 + 64,
];
//fast irq
if pending_num >= 10 && pending_num <= 20 {
return fast_irq[(pending_num - 10) as usize];
}
let pending_num = ffs(sources & 0x3ff) - 1;
match pending_num {
num @ 0..=7 => return num,
8 => {
let sources1 = unsafe { self.read(PENDING_1) };
let irq_0_31 = ffs(sources1) - 1;
return irq_0_31 + 32;
}
9 => {
let sources2 = unsafe { self.read(PENDING_2) };
let irq_32_63 = ffs(sources2) - 1;
return irq_32_63 + 64;
}
num => {
error!(
"unexpected irq pending in BASIC PENDING: 0x{}, sources = 0x{:08x}",
num, sources
);
return num;
}
}
}
fn irq_eoi(&mut self, _irq_num: u32) {}
fn irq_enable(&mut self, irq_num: u32) {
debug!("bcm2835 enable {} {}", irq_num, irq_num & 0x1f);
match irq_num {
num @ 0..=31 => {
let val = 1 << num;
unsafe {
self.write(ENABLE_0, val);
}
}
num @ 32..=63 => {
let val = 1 << (num & 0x1f);
unsafe {
self.write(ENABLE_1, val);
}
}
num @ 64..=95 => {
let val = 1 << (num & 0x1f);
unsafe {
self.write(ENABLE_2, val);
}
}
_ => return,
}
}
fn irq_disable(&mut self, irq_num: u32) {
match irq_num {
num @ 0..=31 => {
let val = 1 << num;
unsafe {
self.write(DISABLE_0, val);
}
}
num @ 32..=63 => {
let val = 1 << (num & 0x1f);
unsafe {
self.write(DISABLE_1, val);
}
}
num @ 64..=95 => {
let val = 1 << (num & 0x1f);
unsafe {
self.write(DISABLE_2, val);
}
}
_ => return,
}
}
fn irq_xlate(&self, irq_data: IrqCell) -> Result<usize> {
//assert interrupt-cells == 0x2
match irq_data {
IrqCell::L2(bank, irq) => {
//TODO: check bank && irq
let hwirq = (bank as usize) << 5 | (irq as usize);
let off = hwirq + self.irq_range.0;
Ok(off)
}
_ => Err(Error::new(EINVAL)),
}
}
fn irq_to_virq(&self, hwirq: u32) -> Option<usize> {
if hwirq > 95 {
None
} else {
Some(self.irq_range.0 + hwirq as usize)
}
}
}
impl InterruptHandler for Bcm2835ArmInterruptController {
fn irq_handler(&mut self, _irq: u32, token: &mut CleanLockToken) {
unsafe {
let irq = self.irq_ack();
if let Some(virq) = self.irq_to_virq(irq)
&& virq < 1024
{
if let Some(handler) = &mut IRQ_CHIP.irq_desc[virq].handler {
handler.irq_handler(virq as u32, token);
}
} else {
error!("unexpected irq num {}", irq);
}
self.irq_eoi(irq);
}
}
}
@@ -0,0 +1,231 @@
use super::InterruptController;
use crate::{
arch::device::{ROOT_IC_IDX, ROOT_IC_IDX_IS_SET},
dtb::{
get_mmio_address,
irqchip::{InterruptHandler, IrqCell, IrqDesc},
},
sync::CleanLockToken,
};
use core::{
arch::asm,
ptr::{read_volatile, write_volatile},
sync::atomic::Ordering,
};
use fdt::{node::FdtNode, Fdt};
use syscall::{
error::{Error, EINVAL},
Result,
};
const LOCAL_CONTROL: u32 = 0x000;
const LOCAL_PRESCALER: u32 = 0x008;
const LOCAL_GPU_ROUTING: u32 = 0x00C;
const LOCAL_TIMER_INT_CONTROL0: u32 = 0x040;
const LOCAL_IRQ_PENDING: u32 = 0x060;
const LOCAL_IRQ_CNTPNSIRQ: u32 = 0x1;
const LOCAL_IRQ_GPU_FAST: u32 = 0x8;
const LOCAL_IRQ_PMU_FAST: u32 = 0x9;
const LOCAL_IRQ_LAST: u32 = LOCAL_IRQ_PMU_FAST;
#[inline(always)]
fn ffs(num: u32) -> u32 {
let mut x = num;
if x == 0 {
return 0;
}
let mut r = 1;
if (x & 0xffff) == 0 {
x >>= 16;
r += 16;
}
if (x & 0xff) == 0 {
x >>= 8;
r += 8;
}
if (x & 0xf) == 0 {
x >>= 4;
r += 4;
}
if (x & 0x3) == 0 {
x >>= 2;
r += 2;
}
if (x & 0x1) == 0 {
r += 1;
}
r
}
pub struct Bcm2836ArmInterruptController {
pub address: usize,
pub irq_range: (usize, usize),
pub active_cpu: u32,
}
impl Bcm2836ArmInterruptController {
pub fn new() -> Self {
Bcm2836ArmInterruptController {
address: 0,
irq_range: (0, 0),
active_cpu: 0,
}
}
pub fn parse(fdt: &Fdt) -> Result<(usize, usize)> {
if let Some(node) = fdt.find_compatible(&["brcm,bcm2836-l1-intc"]) {
return Bcm2836ArmInterruptController::parse_inner(fdt, &node);
} else {
return Err(Error::new(EINVAL));
}
}
fn parse_inner(fdt: &Fdt, node: &FdtNode) -> Result<(usize, usize)> {
//assert address_cells == 0x1, size_cells == 0x1
let reg = node.reg().unwrap().nth(0).unwrap();
let addr = get_mmio_address(fdt, node, &reg).unwrap();
Ok((addr, reg.size.unwrap()))
}
unsafe fn init(&mut self) {
unsafe {
debug!("IRQ BCM2836 INIT");
//init local timer freq
self.write(LOCAL_CONTROL, 0x0);
self.write(LOCAL_PRESCALER, 0x8000_0000);
//routing all irq to core
self.write(LOCAL_GPU_ROUTING, self.active_cpu);
debug!("routing all irq to core {}", self.active_cpu);
debug!("IRQ BCM2836 END");
}
}
unsafe fn read(&self, reg: u32) -> u32 {
unsafe {
let val = read_volatile((self.address + reg as usize) as *const u32);
val
}
}
unsafe fn write(&mut self, reg: u32, value: u32) {
unsafe {
write_volatile((self.address + reg as usize) as *mut u32, value);
}
}
}
impl InterruptHandler for Bcm2836ArmInterruptController {
fn irq_handler(&mut self, _irq: u32, token: &mut CleanLockToken) {}
}
impl InterruptController for Bcm2836ArmInterruptController {
fn irq_init(
&mut self,
fdt_opt: Option<&Fdt>,
irq_desc: &mut [IrqDesc; 1024],
ic_idx: usize,
irq_idx: &mut usize,
) -> Result<()> {
let (base, _size) = match Bcm2836ArmInterruptController::parse(fdt_opt.unwrap()) {
Ok((a, b)) => (a, b),
Err(_) => return Err(Error::new(EINVAL)),
};
unsafe {
self.address = base + crate::PHYS_OFFSET;
let cpuid: usize;
asm!("mrs {}, mpidr_el1", out(reg) cpuid);
self.active_cpu = cpuid as u32 & 0x3;
self.init();
let idx = *irq_idx;
let cnt = LOCAL_IRQ_LAST as usize;
let mut i: usize = 0;
//only support linear irq map now.
while i < cnt && (idx + i < 1024) {
irq_desc[idx + i].basic.ic_idx = ic_idx;
irq_desc[idx + i].basic.ic_irq = i as u32;
irq_desc[idx + i].basic.used = true;
i += 1;
}
info!("bcm2836 irq_range = ({}, {})", idx, idx + cnt);
self.irq_range = (idx, idx + cnt);
*irq_idx = idx + cnt;
}
//raspi 3b+ dts doesn't follow the rule to set root parent interrupt controller
//so we should set it manually.
ROOT_IC_IDX.store(ic_idx, Ordering::Relaxed);
ROOT_IC_IDX_IS_SET.store(1, Ordering::Relaxed);
Ok(())
}
fn irq_ack(&mut self) -> u32 {
let cpuid: usize;
unsafe {
asm!("mrs {}, mpidr_el1", out(reg) cpuid);
}
let cpu = cpuid as u32 & 0x3;
let sources: u32 = unsafe { self.read(LOCAL_IRQ_PENDING + 4 * cpu) };
ffs(sources) - 1
}
fn irq_eoi(&mut self, _irq_num: u32) {}
fn irq_enable(&mut self, irq_num: u32) {
debug!("bcm2836 enable {}", irq_num);
match irq_num {
LOCAL_IRQ_CNTPNSIRQ => unsafe {
let cpuid: usize;
asm!("mrs {}, mpidr_el1", out(reg) cpuid);
let cpu = cpuid as u32 & 0x3;
let mut reg_val = self.read(LOCAL_TIMER_INT_CONTROL0 + 4 * cpu);
reg_val |= 0x2;
self.write(LOCAL_TIMER_INT_CONTROL0 + 4 * cpu, reg_val);
},
LOCAL_IRQ_GPU_FAST => {
//GPU IRQ always enable
}
_ => {
//ignore
}
}
}
fn irq_disable(&mut self, irq_num: u32) {
match irq_num {
LOCAL_IRQ_CNTPNSIRQ => unsafe {
let cpuid: usize;
asm!("mrs {}, mpidr_el1", out(reg) cpuid);
let cpu = cpuid as u32 & 0x3;
let mut reg_val = self.read(LOCAL_TIMER_INT_CONTROL0 + 4 * cpu);
reg_val &= !0x2;
self.write(LOCAL_TIMER_INT_CONTROL0 + 4 * cpu, reg_val);
},
LOCAL_IRQ_GPU_FAST => {
//GPU IRQ always enable
}
_ => {
//ignore
}
}
}
fn irq_xlate(&self, irq_data: IrqCell) -> Result<usize> {
//assert interrupt-cells == 0x2
match irq_data {
IrqCell::L2(irq, _) => Ok(irq as usize + self.irq_range.0),
_ => Err(Error::new(EINVAL)),
}
}
fn irq_to_virq(&self, hwirq: u32) -> Option<usize> {
if hwirq > LOCAL_IRQ_LAST {
None
} else {
Some(self.irq_range.0 + hwirq as usize)
}
}
}
+41
View File
@@ -0,0 +1,41 @@
use crate::dtb::irqchip::{InterruptController, IRQ_CHIP};
use alloc::boxed::Box;
use fdt::{node::FdtNode, Fdt};
pub(crate) mod gic;
pub(crate) mod gicv3;
mod irq_bcm2835;
mod irq_bcm2836;
mod null;
pub(crate) fn new_irqchip(ic_str: &str) -> Option<Box<dyn InterruptController>> {
if ic_str.contains("arm,gic-v3") {
Some(Box::new(gicv3::GicV3::new()))
} else if ic_str.contains("arm,cortex-a15-gic") || ic_str.contains("arm,gic-400") {
Some(Box::new(gic::GenericInterruptController::new()))
} else if ic_str.contains("brcm,bcm2836-l1-intc") {
Some(Box::new(irq_bcm2836::Bcm2836ArmInterruptController::new()))
} else if ic_str.contains("brcm,bcm2836-armctrl-ic") {
Some(Box::new(irq_bcm2835::Bcm2835ArmInterruptController::new()))
} else {
warn!("no driver for interrupt controller {:?}", ic_str);
//TODO: return None and handle it properly
Some(Box::new(null::Null))
}
}
pub(crate) fn ic_for_chip(fdt: &Fdt, node: &FdtNode) -> Option<usize> {
if let Some(_) = node.property("interrupts-extended") {
error!("multi-parented device not supported");
None
} else if let Some(irqc_phandle) = node
.property("interrupt-parent")
.or(fdt.root().property("interrupt-parent"))
.and_then(|f| f.as_usize())
{
unsafe { IRQ_CHIP.phandle_to_ic_idx(irqc_phandle as u32) }
} else {
error!("no irq parent found");
None
}
}
+41
View File
@@ -0,0 +1,41 @@
use fdt::Fdt;
use syscall::{
error::{Error, EINVAL},
Result,
};
use super::InterruptController;
use crate::{
dtb::irqchip::{InterruptHandler, IrqCell, IrqDesc},
sync::CleanLockToken,
};
pub struct Null;
impl InterruptHandler for Null {
fn irq_handler(&mut self, _irq: u32, token: &mut CleanLockToken) {}
}
impl InterruptController for Null {
fn irq_init(
&mut self,
_fdt_opt: Option<&Fdt>,
_irq_desc: &mut [IrqDesc; 1024],
_ic_idx: usize,
_irq_idx: &mut usize,
) -> Result<()> {
Ok(())
}
fn irq_ack(&mut self) -> u32 {
unimplemented!()
}
fn irq_eoi(&mut self, _irq_num: u32) {}
fn irq_enable(&mut self, _irq_num: u32) {}
fn irq_disable(&mut self, _irq_num: u32) {}
fn irq_xlate(&self, _irq_data: IrqCell) -> Result<usize> {
Err(Error::new(EINVAL))
}
fn irq_to_virq(&self, _hwirq: u32) -> Option<usize> {
None
}
}
+60
View File
@@ -0,0 +1,60 @@
use crate::info;
use core::sync::atomic::{AtomicUsize, Ordering};
use fdt::Fdt;
pub mod cpu;
pub mod generic_timer;
pub mod irqchip;
pub mod rtc;
pub mod serial;
use crate::dtb::irqchip::IRQ_CHIP;
use irqchip::ic_for_chip;
pub static ROOT_IC_IDX: AtomicUsize = AtomicUsize::new(0);
pub static ROOT_IC_IDX_IS_SET: AtomicUsize = AtomicUsize::new(0);
unsafe fn init_root_ic(fdt: &Fdt) {
unsafe {
let is_set = ROOT_IC_IDX_IS_SET.load(Ordering::Relaxed);
if is_set != 0 {
let ic_idx = ROOT_IC_IDX.load(Ordering::Relaxed);
info!("Already selected {} as root ic", ic_idx);
return;
}
let root_irqc_phandle = fdt
.root()
.property("interrupt-parent")
.unwrap()
.as_usize()
.unwrap();
let ic_idx = IRQ_CHIP
.phandle_to_ic_idx(root_irqc_phandle as u32)
.unwrap();
info!("select {} as root ic", ic_idx);
ROOT_IC_IDX.store(ic_idx, Ordering::Relaxed);
}
}
pub unsafe fn init_devicetree(fdt: &Fdt) {
unsafe {
info!("IRQCHIP INIT");
crate::dtb::irqchip::init(&fdt);
init_root_ic(&fdt);
info!("GIT INIT");
generic_timer::init(fdt);
info!("SERIAL INIT");
serial::init(fdt);
info!("RTC INIT");
rtc::init(fdt);
}
}
pub struct ArchPercpuMisc;
impl ArchPercpuMisc {
pub const fn default() -> Self {
Self
}
}
+41
View File
@@ -0,0 +1,41 @@
use crate::{dtb::get_mmio_address, sync::CleanLockToken, time};
use core::ptr::read_volatile;
static RTC_DR: usize = 0x000;
pub unsafe fn init(fdt: &fdt::Fdt) {
if let Some(node) = fdt.find_compatible(&["arm,pl031"]) {
match node
.reg()
.and_then(|mut iter| iter.next())
.and_then(|region| get_mmio_address(fdt, &node, &region))
{
Some(phys) => {
let mut rtc = Pl031rtc { phys };
info!("PL031 RTC at {:#x}", rtc.phys);
let mut token = unsafe { CleanLockToken::new() };
*time::START.lock(token.token()) = (rtc.time() as u128) * time::NANOS_PER_SEC;
}
None => {
warn!("No PL031 RTC registers");
}
}
} else {
warn!("No PL031 RTC found");
}
}
struct Pl031rtc {
pub phys: usize,
}
impl Pl031rtc {
unsafe fn read(&self, reg: usize) -> u32 {
unsafe { read_volatile((crate::PHYS_OFFSET + self.phys + reg) as *const u32) }
}
pub fn time(&mut self) -> u64 {
let seconds = unsafe { self.read(RTC_DR) } as u64;
seconds
}
}
+59
View File
@@ -0,0 +1,59 @@
use alloc::boxed::Box;
use fdt::Fdt;
pub use crate::dtb::serial::COM1;
use crate::{
arch::device::irqchip::ic_for_chip,
dtb::{
get_interrupt,
irqchip::{register_irq, InterruptHandler, IRQ_CHIP},
},
scheme::irq::irq_trigger,
sync::CleanLockToken,
};
pub struct Com1Irq {}
impl InterruptHandler for Com1Irq {
fn irq_handler(&mut self, irq: u32, token: &mut CleanLockToken) {
COM1.lock().receive(token);
unsafe {
// FIXME add_irq accepts a u8 as irq number
// PercpuBlock::current().stats.add_irq(irq);
irq_trigger(irq.try_into().unwrap(), token);
IRQ_CHIP.irq_eoi(irq);
}
}
}
pub unsafe fn init(fdt: &Fdt) {
unsafe {
//TODO: find actual serial device, not just any PL011
if let Some(node) = fdt.find_compatible(&["arm,pl011"]) {
let irq = get_interrupt(fdt, &node, 0).unwrap();
if let Some(ic_idx) = ic_for_chip(&fdt, &node) {
let virq = IRQ_CHIP.irq_chip_list.chips[ic_idx]
.ic
.irq_xlate(irq)
.unwrap();
info!("serial_port virq = {}", virq);
register_irq(virq as u32, Box::new(Com1Irq {}));
IRQ_CHIP.irq_enable(virq as u32);
} else {
error!("serial port irq parent not found");
}
}
COM1.lock().enable_irq();
}
}
pub unsafe fn init_acpi(irq: u32) {
unsafe {
//TODO: what should chip index be?
let virq = IRQ_CHIP.irq_chip_list.chips[0].ic.irq_to_virq(irq).unwrap();
info!("serial_port virq = {}", virq);
register_irq(virq as u32, Box::new(Com1Irq {}));
IRQ_CHIP.irq_enable(virq as u32);
COM1.lock().enable_irq();
}
}
+236
View File
@@ -0,0 +1,236 @@
use ::syscall::Exception;
use rmm::VirtualAddress;
use crate::{
context::signal::excp_handler,
exception_stack,
memory::{ArchIntCtx, GenericPfFlags},
sync::CleanLockToken,
syscall,
};
use super::InterruptStack;
exception_stack!(synchronous_exception_at_el1_with_sp0, |stack| {
println!("Synchronous exception at EL1 with SP0");
stack.trace();
loop {}
});
fn exception_code(esr: usize) -> u8 {
((esr >> 26) & 0x3f) as u8
}
fn iss(esr: usize) -> u32 {
(esr & 0x01ff_ffff) as u32
}
unsafe fn far_el1() -> usize {
unsafe {
let ret: usize;
core::arch::asm!("mrs {}, far_el1", out(reg) ret);
ret
}
}
unsafe fn instr_data_abort_inner(
stack: &mut InterruptStack,
from_user: bool,
instr_not_data: bool,
_from: &str,
) -> bool {
unsafe {
let iss = iss(stack.iret.esr_el1);
let fsc = iss & 0x3F;
//dbg!(fsc);
let was_translation_fault = fsc >= 0b000100 && fsc <= 0b000111;
//let was_permission_fault = fsc >= 0b001101 && fsc <= 0b001111;
let write_not_read_if_data = iss & (1 << 6) != 0;
let mut flags = GenericPfFlags::empty();
flags.set(GenericPfFlags::PRESENT, !was_translation_fault);
// TODO: RMW instructions may "involve" writing to (possibly invalid) memory, but AArch64
// doesn't appear to require that flag to be set if the read alone would trigger a fault.
flags.set(
GenericPfFlags::INVOLVED_WRITE,
write_not_read_if_data && !instr_not_data,
);
flags.set(GenericPfFlags::INSTR_NOT_DATA, instr_not_data);
flags.set(GenericPfFlags::USER_NOT_SUPERVISOR, from_user);
let faulting_addr = VirtualAddress::new(far_el1());
//dbg!(faulting_addr, flags, from);
crate::memory::page_fault_handler(stack, flags, faulting_addr).is_ok()
}
}
unsafe fn cntfrq_el0() -> usize {
unsafe {
let ret: usize;
core::arch::asm!("mrs {}, cntfrq_el0", out(reg) ret);
ret
}
}
unsafe fn cntpct_el0() -> usize {
unsafe {
let ret: usize;
core::arch::asm!("mrs {}, cntpct_el0", out(reg) ret);
ret
}
}
unsafe fn cntvct_el0() -> usize {
unsafe {
let ret: usize;
core::arch::asm!("mrs {}, cntvct_el0", out(reg) ret);
ret
}
}
unsafe fn instr_trapped_msr_mrs_inner(
stack: &mut InterruptStack,
_from_user: bool,
_instr_not_data: bool,
_from: &str,
) -> bool {
unsafe {
let iss = iss(stack.iret.esr_el1);
// let res0 = (iss & 0x1C0_0000) >> 22;
let op0 = (iss & 0x030_0000) >> 20;
let op2 = (iss & 0x00e_0000) >> 17;
let op1 = (iss & 0x001_c000) >> 14;
let crn = (iss & 0x000_3c00) >> 10;
let rt = (iss & 0x000_03e0) >> 5;
let crm = (iss & 0x000_001e) >> 1;
let dir = iss & 0x000_0001;
/*
print!("iss=0x{:x}, res0=0b{:03b}, op0=0b{:02b}\n
op2=0b{:03b}, op1=0b{:03b}, crn=0b{:04b}\n
rt=0b{:05b}, crm=0b{:04b}, dir=0b{:b}\n",
iss, res0, op0, op2, op1, crn, rt, crm, dir);
*/
match (op0, op1, crn, crm, op2, dir) {
//MRS <Xt>, CNTFRQ_EL0
(0b11, 0b011, 0b1110, 0b0000, 0b000, 0b1) => {
let reg_val = cntfrq_el0();
stack.store_reg(rt as usize, reg_val);
//skip faulting instruction, A64 instructions are always 32-bits
stack.iret.elr_el1 += 4;
return true;
}
//MRS <Xt>, CNTPCT_EL0
(0b11, 0b011, 0b1110, 0b0000, 0b001, 0b1) => {
let reg_val = cntpct_el0();
stack.store_reg(rt as usize, reg_val);
//skip faulting instruction, A64 instructions are always 32-bits
stack.iret.elr_el1 += 4;
return true;
}
//MRS <Xt>, CNTVCT_EL0
(0b11, 0b011, 0b1110, 0b0000, 0b010, 0b1) => {
let reg_val = cntvct_el0();
stack.store_reg(rt as usize, reg_val);
//skip faulting instruction, A64 instructions are always 32-bits
stack.iret.elr_el1 += 4;
return true;
}
_ => {}
}
false
}
}
exception_stack!(synchronous_exception_at_el1_with_spx, |stack| {
unsafe {
if !pf_inner(
stack,
exception_code(stack.iret.esr_el1),
"sync_exc_el1_spx",
) {
println!("Synchronous exception at EL1 with SPx");
if exception_code(stack.iret.esr_el1) == 0b100101 {
let far_el1 = far_el1();
println!("FAR_EL1 = 0x{:08x}", far_el1);
} else if exception_code(stack.iret.esr_el1) == 0b100100 {
let far_el1 = far_el1();
println!("USER FAR_EL1 = 0x{:08x}", far_el1);
}
stack.trace();
loop {}
}
}
});
unsafe fn pf_inner(stack: &mut InterruptStack, ty: u8, from: &str) -> bool {
unsafe {
match ty {
// "Data Abort taken from a lower Exception level"
0b100100 => instr_data_abort_inner(stack, true, false, from),
// "Data Abort taken without a change in Exception level"
0b100101 => instr_data_abort_inner(stack, false, false, from),
// "Instruction Abort taken from a lower Exception level"
0b100000 => instr_data_abort_inner(stack, true, true, from),
// "Instruction Abort taken without a change in Exception level"
0b100001 => instr_data_abort_inner(stack, false, true, from),
// "Trapped MSR, MRS or System instruction execution in AArch64 state"
0b011000 => instr_trapped_msr_mrs_inner(stack, true, true, from),
_ => return false,
}
}
}
exception_stack!(synchronous_exception_at_el0, |stack| {
unsafe {
match exception_code(stack.iret.esr_el1) {
0b010101 => {
let scratch = &stack.scratch;
let mut token = CleanLockToken::new();
let ret = syscall::syscall(
scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4,
scratch.x5, &mut token,
);
stack.scratch.x0 = ret;
}
ty => {
if !pf_inner(stack, ty as u8, "sync_exc_el0") {
error!(
"FATAL: Not an SVC induced synchronous exception (ty={:b})",
ty
);
println!("FAR_EL1: {:#0x}", far_el1());
//crate::debugger::debugger(None);
stack.trace();
excp_handler(Exception {
kind: 0, // TODO
});
}
}
}
}
});
exception_stack!(unhandled_exception, |stack| {
println!("Unhandled exception");
stack.trace();
loop {}
});
impl ArchIntCtx for InterruptStack {
fn ip(&self) -> usize {
self.iret.elr_el1
}
fn recover_and_efault(&mut self) {
// Set the return value to nonzero to indicate usercopy failure (EFAULT), and emulate the
// return instruction by setting the return pointer to the saved LR value.
self.iret.elr_el1 = self.preserved.x30;
self.scratch.x0 = 1;
}
}
+420
View File
@@ -0,0 +1,420 @@
use crate::{panic, syscall::IntRegisters};
#[derive(Default)]
#[repr(C, packed)]
pub struct ScratchRegisters {
pub x0: usize,
pub x1: usize,
pub x2: usize,
pub x3: usize,
pub x4: usize,
pub x5: usize,
pub x6: usize,
pub x7: usize,
pub x8: usize,
pub x9: usize,
pub x10: usize,
pub x11: usize,
pub x12: usize,
pub x13: usize,
pub x14: usize,
pub x15: usize,
pub x16: usize,
pub x17: usize,
pub x18: usize,
pub _padding: usize,
}
impl ScratchRegisters {
pub fn dump(&self) {
println!("X0: {:>016X}", { self.x0 });
println!("X1: {:>016X}", { self.x1 });
println!("X2: {:>016X}", { self.x2 });
println!("X3: {:>016X}", { self.x3 });
println!("X4: {:>016X}", { self.x4 });
println!("X5: {:>016X}", { self.x5 });
println!("X6: {:>016X}", { self.x6 });
println!("X7: {:>016X}", { self.x7 });
println!("X8: {:>016X}", { self.x8 });
println!("X9: {:>016X}", { self.x9 });
println!("X10: {:>016X}", { self.x10 });
println!("X11: {:>016X}", { self.x11 });
println!("X12: {:>016X}", { self.x12 });
println!("X13: {:>016X}", { self.x13 });
println!("X14: {:>016X}", { self.x14 });
println!("X15: {:>016X}", { self.x15 });
println!("X16: {:>016X}", { self.x16 });
println!("X17: {:>016X}", { self.x17 });
println!("X18: {:>016X}", { self.x18 });
}
}
#[derive(Default)]
#[repr(C, packed)]
pub struct PreservedRegisters {
//TODO: is X30 a preserved register?
pub x19: usize,
pub x20: usize,
pub x21: usize,
pub x22: usize,
pub x23: usize,
pub x24: usize,
pub x25: usize,
pub x26: usize,
pub x27: usize,
pub x28: usize,
pub x29: usize,
pub x30: usize,
}
impl PreservedRegisters {
pub fn dump(&self) {
println!("X19: {:>016X}", { self.x19 });
println!("X20: {:>016X}", { self.x20 });
println!("X21: {:>016X}", { self.x21 });
println!("X22: {:>016X}", { self.x22 });
println!("X23: {:>016X}", { self.x23 });
println!("X24: {:>016X}", { self.x24 });
println!("X25: {:>016X}", { self.x25 });
println!("X26: {:>016X}", { self.x26 });
println!("X27: {:>016X}", { self.x27 });
println!("X28: {:>016X}", { self.x28 });
println!("X29: {:>016X}", { self.x29 });
println!("X30: {:>016X}", { self.x30 });
}
}
#[derive(Default)]
#[repr(C, packed)]
pub struct IretRegisters {
// occurred
// The exception vector disambiguates at which EL the interrupt
pub sp_el0: usize, // Shouldn't be used if interrupt occurred at EL1
pub esr_el1: usize,
pub spsr_el1: usize,
pub elr_el1: usize,
}
impl IretRegisters {
pub fn dump(&self) {
println!("ELR_EL1: {:>016X}", { self.elr_el1 });
println!("SPSR_EL1: {:>016X}", { self.spsr_el1 });
println!("ESR_EL1: {:>016X}", { self.esr_el1 });
println!("SP_EL0: {:>016X}", { self.sp_el0 });
}
}
#[derive(Default)]
#[repr(C, packed)]
pub struct InterruptStack {
pub iret: IretRegisters,
pub scratch: ScratchRegisters,
pub preserved: PreservedRegisters,
}
impl InterruptStack {
pub fn init(&mut self) {}
pub fn frame_pointer(&self) -> usize {
self.preserved.x29
}
pub fn stack_pointer(&self) -> usize {
self.iret.sp_el0
}
pub fn set_stack_pointer(&mut self, sp: usize) {
self.iret.sp_el0 = sp;
}
pub fn sig_archdep_reg(&self) -> usize {
self.scratch.x0
}
pub fn set_instr_pointer(&mut self, ip: usize) {
self.iret.elr_el1 = ip;
}
pub fn instr_pointer(&self) -> usize {
self.iret.elr_el1
}
pub fn set_arg1(&mut self, arg_opt: Option<usize>) {
if let Some(arg) = arg_opt {
self.scratch.x1 = arg;
}
}
pub fn dump(&self) {
self.iret.dump();
self.scratch.dump();
self.preserved.dump();
}
pub fn trace(&self) {
self.dump();
unsafe {
panic::user_stack_trace(&self);
panic::stack_trace();
}
}
/// Saves all registers to a struct used by the proc:
/// scheme to read/write registers.
pub fn save(&self, all: &mut IntRegisters) {
/*TODO: aarch64 registers
all.elr_el1 = self.iret.elr_el1;
all.spsr_el1 = self.iret.spsr_el1;
all.esr_el1 = self.iret.esr_el1;
all.sp_el0 = self.iret.sp_el0;
all.padding = 0;
*/
all.x30 = self.preserved.x30;
all.x29 = self.preserved.x29;
all.x28 = self.preserved.x28;
all.x27 = self.preserved.x27;
all.x26 = self.preserved.x26;
all.x25 = self.preserved.x25;
all.x24 = self.preserved.x24;
all.x23 = self.preserved.x23;
all.x22 = self.preserved.x22;
all.x21 = self.preserved.x21;
all.x20 = self.preserved.x20;
all.x19 = self.preserved.x19;
all.x18 = self.scratch.x18;
all.x17 = self.scratch.x17;
all.x16 = self.scratch.x16;
all.x15 = self.scratch.x15;
all.x14 = self.scratch.x14;
all.x13 = self.scratch.x13;
all.x12 = self.scratch.x12;
all.x11 = self.scratch.x11;
all.x10 = self.scratch.x10;
all.x9 = self.scratch.x9;
all.x8 = self.scratch.x8;
all.x7 = self.scratch.x7;
all.x6 = self.scratch.x6;
all.x5 = self.scratch.x5;
all.x4 = self.scratch.x4;
all.x3 = self.scratch.x3;
all.x2 = self.scratch.x2;
all.x1 = self.scratch.x1;
all.x0 = self.scratch.x0;
}
/// Loads all registers from a struct used by the proc:
/// scheme to read/write registers.
pub fn load(&mut self, all: &IntRegisters) {
/*TODO: aarch64 registers
self.iret.elr_el1 = all.elr_el1;
self.iret.spsr_el1 = all.spsr_el1;
self.iret.esr_el1 = all.esr_el1;
self.iret.sp_el0 = all.sp_el0;
*/
self.preserved.x30 = all.x30;
self.preserved.x29 = all.x29;
self.preserved.x28 = all.x28;
self.preserved.x27 = all.x27;
self.preserved.x26 = all.x26;
self.preserved.x25 = all.x25;
self.preserved.x24 = all.x24;
self.preserved.x23 = all.x23;
self.preserved.x22 = all.x22;
self.preserved.x21 = all.x21;
self.preserved.x20 = all.x20;
self.preserved.x19 = all.x19;
self.scratch.x18 = all.x18;
self.scratch.x17 = all.x17;
self.scratch.x16 = all.x16;
self.scratch.x15 = all.x15;
self.scratch.x14 = all.x14;
self.scratch.x13 = all.x13;
self.scratch.x12 = all.x12;
self.scratch.x11 = all.x11;
self.scratch.x10 = all.x10;
self.scratch.x9 = all.x9;
self.scratch.x8 = all.x8;
self.scratch.x7 = all.x7;
self.scratch.x6 = all.x6;
self.scratch.x5 = all.x5;
self.scratch.x4 = all.x4;
self.scratch.x3 = all.x3;
self.scratch.x2 = all.x2;
self.scratch.x1 = all.x1;
self.scratch.x0 = all.x0;
}
/// Store a specific generic registers
pub fn store_reg(&mut self, idx: usize, val: usize) {
match idx {
0 => self.scratch.x0 = val,
1 => self.scratch.x1 = val,
2 => self.scratch.x2 = val,
3 => self.scratch.x3 = val,
4 => self.scratch.x4 = val,
5 => self.scratch.x5 = val,
6 => self.scratch.x6 = val,
7 => self.scratch.x7 = val,
8 => self.scratch.x8 = val,
9 => self.scratch.x9 = val,
10 => self.scratch.x10 = val,
11 => self.scratch.x11 = val,
12 => self.scratch.x12 = val,
13 => self.scratch.x13 = val,
14 => self.scratch.x14 = val,
15 => self.scratch.x15 = val,
16 => self.scratch.x16 = val,
17 => self.scratch.x17 = val,
18 => self.scratch.x18 = val,
19 => self.preserved.x19 = val,
20 => self.preserved.x20 = val,
21 => self.preserved.x21 = val,
22 => self.preserved.x22 = val,
23 => self.preserved.x23 = val,
24 => self.preserved.x24 = val,
25 => self.preserved.x25 = val,
26 => self.preserved.x26 = val,
27 => self.preserved.x27 = val,
28 => self.preserved.x28 = val,
29 => self.preserved.x29 = val,
30 => self.preserved.x30 = val,
_ => {}
}
}
//TODO
pub fn set_singlestep(&mut self, _singlestep: bool) {}
}
#[macro_export]
macro_rules! push_scratch {
() => {
"
// Push scratch registers
str x18, [sp, #-16]!
stp x16, x17, [sp, #-16]!
stp x14, x15, [sp, #-16]!
stp x12, x13, [sp, #-16]!
stp x10, x11, [sp, #-16]!
stp x8, x9, [sp, #-16]!
stp x6, x7, [sp, #-16]!
stp x4, x5, [sp, #-16]!
stp x2, x3, [sp, #-16]!
stp x0, x1, [sp, #-16]!
"
};
}
#[macro_export]
macro_rules! pop_scratch {
() => {
"
// Pop scratch registers
ldp x0, x1, [sp], #16
ldp x2, x3, [sp], #16
ldp x4, x5, [sp], #16
ldp x6, x7, [sp], #16
ldp x8, x9, [sp], #16
ldp x10, x11, [sp], #16
ldp x12, x13, [sp], #16
ldp x14, x15, [sp], #16
ldp x16, x17, [sp], #16
ldr x18, [sp], #16
"
};
}
#[macro_export]
macro_rules! push_preserved {
() => {
"
// Push preserved registers
stp x29, x30, [sp, #-16]!
stp x27, x28, [sp, #-16]!
stp x25, x26, [sp, #-16]!
stp x23, x24, [sp, #-16]!
stp x21, x22, [sp, #-16]!
stp x19, x20, [sp, #-16]!
"
};
}
#[macro_export]
macro_rules! pop_preserved {
() => {
"
// Pop preserved registers
ldp x19, x20, [sp], #16
ldp x21, x22, [sp], #16
ldp x23, x24, [sp], #16
ldp x25, x26, [sp], #16
ldp x27, x28, [sp], #16
ldp x29, x30, [sp], #16
"
};
}
#[macro_export]
macro_rules! push_special {
() => {
"
mrs x14, spsr_el1
mrs x15, elr_el1
stp x14, x15, [sp, #-16]!
mrs x14, sp_el0
mrs x15, esr_el1
stp x14, x15, [sp, #-16]!
"
};
}
#[macro_export]
macro_rules! pop_special {
() => {
"
ldp x14, x15, [sp], 16
msr esr_el1, x15
msr sp_el0, x14
ldp x14, x15, [sp], 16
msr elr_el1, x15
msr spsr_el1, x14
"
};
}
#[macro_export]
macro_rules! exception_stack {
($name:ident, |$stack:ident| $code:block) => {
#[unsafe(naked)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn $name(stack: &mut $crate::arch::aarch64::interrupt::InterruptStack) {
unsafe extern "C" fn inner($stack: &mut $crate::arch::aarch64::interrupt::InterruptStack) {
$code
}
core::arch::naked_asm!(
// Backup all userspace registers to stack
push_preserved!(),
push_scratch!(),
push_special!(),
// Call inner function with pointer to stack
"mov x29, sp",
"mov x0, sp",
"bl {}",
// Restore all userspace registers
pop_special!(),
pop_scratch!(),
pop_preserved!(),
"eret",
sym inner,
);
}
};
}
#[unsafe(naked)]
pub unsafe extern "C" fn enter_usermode() -> ! {
core::arch::naked_asm!(
"blr x28",
// Restore all userspace registers
pop_special!(),
pop_scratch!(),
pop_preserved!(),
"eret",
);
}
+56
View File
@@ -0,0 +1,56 @@
use crate::{arch::device::ROOT_IC_IDX, dtb::irqchip::IRQ_CHIP, sync::CleanLockToken};
use core::sync::atomic::Ordering;
// use crate::percpu::PercpuBlock;
unsafe fn irq_ack() -> (u32, Option<usize>) {
unsafe {
let ic = &mut IRQ_CHIP.irq_chip_list.chips[ROOT_IC_IDX.load(Ordering::Relaxed)].ic;
let irq = ic.irq_ack();
(irq, ic.irq_to_virq(irq))
}
}
exception_stack!(irq_at_el0, |_stack| {
unsafe {
let mut token = CleanLockToken::new();
let (irq, virq) = irq_ack();
if let Some(virq) = virq
&& virq < 1024
{
IRQ_CHIP.trigger_virq(virq as u32, &mut token);
} else {
println!("unexpected irq num {}", irq);
}
}
});
exception_stack!(irq_at_el1, |_stack| {
unsafe {
let mut token = CleanLockToken::new();
let (irq, virq) = irq_ack();
if let Some(virq) = virq
&& virq < 1024
{
IRQ_CHIP.trigger_virq(virq as u32, &mut token);
} else {
println!("unexpected irq num {}", irq);
}
}
});
/*
pub unsafe fn irq_handler_gentimer(irq: u32) {
GENTIMER.clear_irq();
{
*time::OFFSET.lock() += GENTIMER.clk_freq as u128;
}
timeout::trigger();
context::switch::tick();
trigger(irq);
GENTIMER.reload_count();
}
*/
+49
View File
@@ -0,0 +1,49 @@
//! Interrupt instructions
use core::arch::asm;
#[macro_use]
pub mod handler;
pub mod exception;
pub mod irq;
pub mod syscall;
pub mod trace;
pub use self::handler::InterruptStack;
/// Clear interrupts
#[inline(always)]
pub unsafe fn disable() {
unsafe {
asm!("msr daifset, #2");
}
}
/// Set interrupts and halt
/// This will atomically wait for the next interrupt
/// Performing enable followed by halt is not guaranteed to be atomic, use this instead!
#[inline(always)]
pub unsafe fn enable_and_halt() {
unsafe {
asm!("wfi", "msr daifclr, #2", "nop");
}
}
/// Set interrupts and nop
/// This will enable interrupts and allow the IF flag to be processed
/// Simply enabling interrupts does not gurantee that they will trigger, use this instead!
#[inline(always)]
pub unsafe fn enable_and_nop() {
unsafe {
asm!("msr daifclr, #2", "nop");
}
}
/// Halt instruction
#[inline(always)]
pub unsafe fn halt() {
unsafe {
asm!("wfi");
}
}
+49
View File
@@ -0,0 +1,49 @@
#[unsafe(no_mangle)]
pub unsafe extern "C" fn do_exception_unhandled() {}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn do_exception_synchronous() {}
#[allow(dead_code)]
#[repr(C, packed)]
pub struct SyscallStack {
pub elr_el1: usize,
pub padding: usize,
pub tpidr: usize,
pub tpidrro: usize,
pub rflags: usize,
pub esr: usize,
pub sp: usize,
pub lr: usize,
pub fp: usize,
pub x28: usize,
pub x27: usize,
pub x26: usize,
pub x25: usize,
pub x24: usize,
pub x23: usize,
pub x22: usize,
pub x21: usize,
pub x20: usize,
pub x19: usize,
pub x18: usize,
pub x17: usize,
pub x16: usize,
pub x15: usize,
pub x14: usize,
pub x13: usize,
pub x12: usize,
pub x11: usize,
pub x10: usize,
pub x9: usize,
pub x8: usize,
pub x7: usize,
pub x6: usize,
pub x5: usize,
pub x4: usize,
pub x3: usize,
pub x2: usize,
pub x1: usize,
pub x0: usize,
}
pub use super::handler::enter_usermode;
+32
View File
@@ -0,0 +1,32 @@
use core::arch::asm;
pub struct StackTrace {
pub fp: usize,
pub pc_ptr: *const usize,
}
impl StackTrace {
#[inline(always)]
pub unsafe fn start() -> Option<Self> {
unsafe {
let fp: usize;
asm!("mov {}, fp", out(reg) fp);
let pc_ptr = fp.checked_add(size_of::<usize>())?;
Some(StackTrace {
fp,
pc_ptr: pc_ptr as *const usize,
})
}
}
pub unsafe fn next(self) -> Option<Self> {
unsafe {
let fp = *(self.fp as *const usize);
let pc_ptr = fp.checked_add(size_of::<usize>())?;
Some(StackTrace {
fp: fp,
pc_ptr: pc_ptr as *const usize,
})
}
}
}
+30
View File
@@ -0,0 +1,30 @@
#[derive(Clone, Copy, Debug)]
#[repr(u8)]
pub enum IpiKind {
Wakeup = 0x40,
Tlb = 0x41,
}
#[derive(Clone, Copy, Debug)]
#[repr(u8)]
pub enum IpiTarget {
Other = 3,
}
#[inline(always)]
pub fn ipi(_kind: IpiKind, _target: IpiTarget) {
if cfg!(not(feature = "multi_core")) {
return;
}
// FIXME implement
}
#[inline(always)]
pub fn ipi_single(_kind: IpiKind, _target: &crate::percpu::PercpuBlock) {
if cfg!(not(feature = "multi_core")) {
return;
}
// FIXME implement
}
+23
View File
@@ -0,0 +1,23 @@
use crate::{
cpu_set::LogicalCpuId,
memory::{RmmA, RmmArch},
percpu::PercpuBlock,
};
impl PercpuBlock {
pub fn current() -> &'static Self {
unsafe { &*(crate::arch::device::cpu::registers::control_regs::tpidr_el1() as *const Self) }
}
}
#[cold]
pub unsafe fn init(cpu_id: LogicalCpuId) {
unsafe {
let frame = crate::memory::allocate_frame().expect("failed to allocate percpu memory");
let virt = RmmA::phys_to_virt(frame.base()).data() as *mut PercpuBlock;
virt.write(PercpuBlock::init(cpu_id));
crate::arch::device::cpu::registers::control_regs::tpidr_el1_write(virt as u64);
}
}
+71
View File
@@ -0,0 +1,71 @@
/// Constants like memory locations
pub mod consts;
/// Debugging support
pub mod debug;
/// Devices
pub mod device;
/// Interrupt instructions
pub mod interrupt;
/// Inter-processor interrupts
pub mod ipi;
/// Miscellaneous
pub mod misc;
/// Paging
pub mod paging;
/// Initialization and start function
pub mod start;
/// Stop function
pub mod stop;
// Interrupt vectors
pub mod vectors;
pub mod time;
pub use ::rmm::aarch64::AArch64Arch as CurrentRmmArch;
pub use arch_copy_to_user as arch_copy_from_user;
#[unsafe(naked)]
pub unsafe extern "C" fn arch_copy_to_user(dst: usize, src: usize, len: usize) -> u8 {
// x0, x1, x2
core::arch::naked_asm!(
"
.global __usercopy_start
__usercopy_start:
mov x4, x0
mov x0, 0
2:
cmp x2, 0
b.eq 3f
ldrb w3, [x1]
strb w3, [x4]
add x4, x4, 1
add x1, x1, 1
sub x2, x2, 1
b 2b
3:
ret
.global __usercopy_end
__usercopy_end:
"
);
}
pub const KFX_SIZE: usize = 1024;
// This function exists as the KFX size is dynamic on x86_64.
pub fn kfx_size() -> usize {
KFX_SIZE
}
+7
View File
@@ -0,0 +1,7 @@
/// Initialize MAIR
#[cold]
pub unsafe fn init() {
unsafe {
rmm::aarch64::init_mair();
}
}
+148
View File
@@ -0,0 +1,148 @@
//! This function is where the kernel sets up IRQ handlers
//! It is incredibly unsafe, and should be minimal in nature
//! It must create the IDT with the correct entries, those entries are
//! defined in other files inside of the `arch` module
use core::{arch::naked_asm, cell::SyncUnsafeCell, slice};
use fdt::Fdt;
use crate::{
allocator,
arch::{device, paging},
devices::graphical_debug,
dtb,
startup::KernelArgs,
};
/// Test of zero values in BSS.
static mut BSS_TEST_ZERO: usize = 0;
/// Test of non-zero values in data.
static mut DATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF;
#[repr(C, align(16))]
struct StackAlign<T>(T);
static STACK: SyncUnsafeCell<StackAlign<[u8; 128 * 1024]>> =
SyncUnsafeCell::new(StackAlign([0; 128 * 1024]));
// FIXME use extern "custom"
#[unsafe(naked)]
#[unsafe(no_mangle)]
extern "C" fn kstart() {
naked_asm!("
// BSS should already be zero
adrp x9, {bss_test_zero}
ldr x9, [x9, :lo12:{bss_test_zero}]
cbnz x9, .Lkstart_crash
adrp x9, {data_test_nonzero}
ldr x9, [x9, :lo12:{data_test_nonzero}]
cbz x9, .Lkstart_crash
adrp x1, {stack}
add x1, x1, :lo12:{stack}
mov x2, {stack_size}-16
add sp, x1, x2
// Setup interrupt handlers
ldr x9, =exception_vector_base
msr vbar_el1, x9
mov lr, 0
b {start}
.Lkstart_crash:
mov x9, 0
br x9
",
bss_test_zero = sym BSS_TEST_ZERO,
data_test_nonzero = sym DATA_TEST_NONZERO,
stack = sym STACK,
stack_size = const size_of_val(&STACK),
start = sym start,
);
}
/// The entry to Rust, all things must be initialized
unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! {
unsafe {
let bootstrap = {
let args = args_ptr.read();
// Set up graphical debug
graphical_debug::init(args.env());
// Get hardware descriptor data
//TODO: use env {DTB,RSDT}_{BASE,SIZE}?
let hwdesc_data = if args.hwdesc_base != 0 {
Some(slice::from_raw_parts(
(crate::PHYS_OFFSET + args.hwdesc_base as usize) as *const u8,
args.hwdesc_size as usize,
))
} else {
None
};
let dtb_res = hwdesc_data
.ok_or(fdt::FdtError::BadPtr)
.and_then(|data| Fdt::new(data));
// Try to find serial port prior to logging
if let Ok(dtb) = &dtb_res {
dtb::serial::init_early(dtb);
}
info!("Redox OS starting...");
args.print();
// Initialize RMM
crate::startup::memory::init(&args, None, None);
// Initialize paging
paging::init();
crate::arch::misc::init(crate::cpu_set::LogicalCpuId::new(0));
// Setup kernel heap
allocator::init();
// Activate memory logging
crate::log::init();
// Initialize devices
match dtb_res {
Ok(dtb) => {
dtb::init(hwdesc_data.map(|slice| (slice.as_ptr() as usize, slice.len())));
device::init_devicetree(&dtb);
}
Err(err) => {
dtb::init(None);
warn!("failed to parse DTB: {}", err);
#[cfg(feature = "acpi")]
{
crate::acpi::init(args.acpi_rsdp());
}
}
}
args.bootstrap()
};
crate::startup::kmain(bootstrap);
}
}
#[repr(C, packed)]
#[allow(unused)]
pub struct KernelArgsAp {
cpu_id: u64,
page_table: u64,
stack_start: u64,
stack_end: u64,
}
/// Entry to rust for an AP
#[allow(unused)]
pub unsafe extern "C" fn kstart_ap(_args_ptr: *const KernelArgsAp) -> ! {
loop {}
}
+33
View File
@@ -0,0 +1,33 @@
use crate::sync::CleanLockToken;
use core::arch::asm;
pub unsafe fn kreset() -> ! {
unsafe {
println!("kreset");
asm!("hvc #0",
in("x0") 0x8400_0009_usize,
options(noreturn),
)
}
}
pub unsafe fn emergency_reset() -> ! {
unsafe {
asm!("hvc #0",
in("x0") 0x8400_0009_usize,
options(noreturn),
)
}
}
pub unsafe fn kstop(_token: &mut CleanLockToken) -> ! {
unsafe {
println!("kstop");
asm!("hvc #0",
in("x0") 0x8400_0008_usize,
options(noreturn),
)
}
}
+18
View File
@@ -0,0 +1,18 @@
use crate::{sync::CleanLockToken, time::NANOS_PER_SEC};
pub fn monotonic_absolute(_token: &mut CleanLockToken) -> u128 {
//TODO: aarch64 generic timer counter
let ticks: usize;
unsafe { core::arch::asm!("mrs {}, cntpct_el0", out(reg) ticks) };
let freq: usize;
unsafe { core::arch::asm!("mrs {}, cntfrq_el0", out(reg) freq) };
ticks as u128 * NANOS_PER_SEC / freq as u128
}
pub fn monotonic_resolution() -> u128 {
let freq: usize;
unsafe { core::arch::asm!("mrs {}, cntfrq_el0", out(reg) freq) };
NANOS_PER_SEC / freq as u128
}
+112
View File
@@ -0,0 +1,112 @@
core::arch::global_asm!(
"
// Exception vector stubs
//
// Unhandled exceptions spin in a wfi loop for the moment
// This can be macro-ified
.globl exception_vector_base
.align 11
exception_vector_base:
// Synchronous
.align 7
__vec_00:
b synchronous_exception_at_el1_with_sp0
b __vec_00
// IRQ
.align 7
__vec_01:
b irq_at_el1
b __vec_01
// FIQ
.align 7
__vec_02:
b unhandled_exception
b __vec_02
// SError
.align 7
__vec_03:
b unhandled_exception
b __vec_03
// Synchronous
.align 7
__vec_04:
b synchronous_exception_at_el1_with_spx
b __vec_04
// IRQ
.align 7
__vec_05:
b irq_at_el1
b __vec_05
// FIQ
.align 7
__vec_06:
b unhandled_exception
b __vec_06
// SError
.align 7
__vec_07:
b unhandled_exception
b __vec_07
// Synchronous
.align 7
__vec_08:
b synchronous_exception_at_el0
b __vec_08
// IRQ
.align 7
__vec_09:
b irq_at_el0
b __vec_09
// FIQ
.align 7
__vec_10:
b unhandled_exception
b __vec_10
// SError
.align 7
__vec_11:
b unhandled_exception
b __vec_11
// Synchronous
.align 7
__vec_12:
b unhandled_exception
b __vec_12
// IRQ
.align 7
__vec_13:
b unhandled_exception
b __vec_13
// FIQ
.align 7
__vec_14:
b unhandled_exception
b __vec_14
// SError
.align 7
__vec_15:
b unhandled_exception
b __vec_15
.align 7
exception_vector_end:
"
);
+27
View File
@@ -0,0 +1,27 @@
#[cfg(target_arch = "aarch64")]
#[macro_use]
pub mod aarch64;
#[cfg(target_arch = "aarch64")]
pub use self::aarch64::*;
#[cfg(target_arch = "x86")]
#[macro_use]
pub mod x86;
#[cfg(target_arch = "x86")]
pub use self::x86::*;
#[cfg(target_arch = "x86_64")]
#[macro_use]
pub mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use self::x86_64::*;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[macro_use]
mod x86_shared;
#[cfg(target_arch = "riscv64")]
#[macro_use]
pub mod riscv64;
#[cfg(target_arch = "riscv64")]
pub use self::riscv64::*;

Some files were not shown because too many files have changed in this diff Show More