diff --git a/crates/adapter-riscv/src/boot/caps.rs b/crates/adapter-riscv/src/boot/caps.rs index 1206acf..a6d18d5 100644 --- a/crates/adapter-riscv/src/boot/caps.rs +++ b/crates/adapter-riscv/src/boot/caps.rs @@ -22,37 +22,85 @@ pub fn grant_all( .with(types::permission::Permission::Read) .with(types::permission::Permission::Execute); - let storage_ep = kern().create_endpoint() + let storage_ep = kern() + .create_endpoint() .unwrap_or_else(|_| crate::halt(uart, "storage endpoint failed")); - kern().grant_capability(init_pid, domain::resource::Resource::Process(storage_pid), all_perms) + kern() + .grant_capability( + init_pid, + domain::resource::Resource::Process(storage_pid), + all_perms, + ) .unwrap_or_else(|_| crate::halt(uart, "grant failed")); - kern().grant_capability(init_pid, domain::resource::Resource::Endpoint(storage_ep), all_perms) + kern() + .grant_capability( + init_pid, + domain::resource::Resource::Endpoint(storage_ep), + all_perms, + ) .unwrap_or_else(|_| crate::halt(uart, "grant failed")); - kern().grant_capability(storage_pid, domain::resource::Resource::Endpoint(storage_ep), ipc_perms) + kern() + .grant_capability( + storage_pid, + domain::resource::Resource::Endpoint(storage_ep), + ipc_perms, + ) .unwrap_or_else(|_| crate::halt(uart, "grant failed")); - let display_ep = kern().create_endpoint() + let display_ep = kern() + .create_endpoint() .unwrap_or_else(|_| crate::halt(uart, "display endpoint failed")); - kern().grant_capability(display_pid, domain::resource::Resource::Endpoint(display_ep), ipc_perms) + kern() + .grant_capability( + display_pid, + domain::resource::Resource::Endpoint(display_ep), + ipc_perms, + ) .unwrap_or_else(|_| crate::halt(uart, "grant failed")); - kern().grant_capability(init_pid, domain::resource::Resource::Endpoint(display_ep), all_perms) + kern() + .grant_capability( + init_pid, + domain::resource::Resource::Endpoint(display_ep), + all_perms, + ) .unwrap_or_else(|_| crate::halt(uart, "grant failed")); - kern().grant_capability(init_pid, domain::resource::Resource::Process(display_pid), all_perms) + kern() + .grant_capability( + init_pid, + domain::resource::Resource::Process(display_pid), + all_perms, + ) .unwrap_or_else(|_| crate::halt(uart, "grant failed")); - let input_ep = kern().create_endpoint() + let input_ep = kern() + .create_endpoint() .unwrap_or_else(|_| crate::halt(uart, "input endpoint failed")); - kern().grant_capability(input_pid, domain::resource::Resource::Endpoint(input_ep), ipc_perms) + kern() + .grant_capability( + input_pid, + domain::resource::Resource::Endpoint(input_ep), + ipc_perms, + ) .unwrap_or_else(|_| crate::halt(uart, "grant failed")); - kern().grant_capability(init_pid, domain::resource::Resource::Endpoint(input_ep), all_perms) + kern() + .grant_capability( + init_pid, + domain::resource::Resource::Endpoint(input_ep), + all_perms, + ) .unwrap_or_else(|_| crate::halt(uart, "grant failed")); - kern().grant_capability(init_pid, domain::resource::Resource::Process(input_pid), all_perms) + kern() + .grant_capability( + init_pid, + domain::resource::Resource::Process(input_pid), + all_perms, + ) .unwrap_or_else(|_| crate::halt(uart, "grant failed")); uart.write_str("k-os: capabilities granted\n"); diff --git a/crates/adapter-riscv/src/boot/hardware.rs b/crates/adapter-riscv/src/boot/hardware.rs index 99b5a08..f1d38d4 100644 --- a/crates/adapter-riscv/src/boot/hardware.rs +++ b/crates/adapter-riscv/src/boot/hardware.rs @@ -1,6 +1,6 @@ use crate::hw::uart::Uart; use crate::hw::virtio_blk::VirtioBlk; -use crate::{board, kernel_cell::KernelCell, mmu, platform, trap, KERNEL}; +use crate::{KERNEL, board, kernel_cell::KernelCell, mmu, platform, trap}; unsafe extern "C" { static _bss_start: u8; diff --git a/crates/adapter-riscv/src/boot/loader.rs b/crates/adapter-riscv/src/boot/loader.rs index 08ce788..fd28ece 100644 --- a/crates/adapter-riscv/src/boot/loader.rs +++ b/crates/adapter-riscv/src/boot/loader.rs @@ -21,11 +21,16 @@ pub fn load_init( kernel_pt: &mmu::PageTable, ) -> (LoadedProcess, ThreadId) { let (pid, tid) = kern() - .boot(types::bounded::Priority::DEFAULT, types::time::TimeSlice::DEFAULT) + .boot( + types::bounded::Priority::DEFAULT, + types::time::TimeSlice::DEFAULT, + ) .unwrap_or_else(|_| crate::halt(uart, "boot failed")); let entry = load_elf(blk, kernel_pt, pid, b"init.elf"); - if entry == 0 { crate::halt(uart, "init.elf not found"); } + if entry == 0 { + crate::halt(uart, "init.elf not found"); + } setup_thread(tid, entry); uart.write_str("k-os: init loaded\n"); @@ -39,11 +44,15 @@ pub fn load_server( filename: &[u8], label: &str, ) -> LoadedProcess { - let pid = kern().create_process_internal() + let pid = kern() + .create_process_internal() .unwrap_or_else(|| crate::halt(uart, "process create failed")); let entry = load_elf(blk, kernel_pt, pid, filename); - if entry == 0 { crate::halt(uart, "elf not found"); } - let tid = kern().spawn_thread_internal(pid) + if entry == 0 { + crate::halt(uart, "elf not found"); + } + let tid = kern() + .spawn_thread_internal(pid) .unwrap_or_else(|| crate::halt(uart, "thread spawn failed")); setup_thread(tid, entry); uart.write_str("k-os: "); @@ -103,7 +112,9 @@ fn load_elf( let buf = unsafe { core::slice::from_raw_parts_mut(buf_base as *mut u8, MAX_FILE_SIZE) }; let file_size = boot_fs::read_file_from_disk(blk, filename, buf).unwrap_or(0); - if file_size == 0 { return 0; } + if file_size == 0 { + return 0; + } let elf_info = match elf::parse(&buf[..file_size]) { Ok(info) => info, @@ -130,7 +141,9 @@ fn load_elf( let dest_off = if p == 0 { offset_in_page } else { 0 }; let copy_len = if seg_file_start < segment.file_size { (segment.file_size - seg_file_start).min(4096 - dest_off) - } else { 0 }; + } else { + 0 + }; if copy_len > 0 { let src = segment.file_offset + seg_file_start; @@ -152,25 +165,33 @@ fn load_elf( } else { mmu::Sv39Flags::user_rx() }; - mmu::map(user_pt, mmu::Mapping { - va: types::address::VirtualAddress::from_raw(page_va), - pa: types::address::PhysicalAddress::from_raw(page), - pages: 1, - flags, - }); + mmu::map( + user_pt, + mmu::Mapping { + va: types::address::VirtualAddress::from_raw(page_va), + pa: types::address::PhysicalAddress::from_raw(page), + pages: 1, + flags, + }, + ); } } for i in 0..16usize { let sp = mmu::allocator::alloc_zeroed_page(); - mmu::map(user_pt, mmu::Mapping { - va: types::address::VirtualAddress::from_raw(USER_VA_BASE - (16 - i) * 4096), - pa: types::address::PhysicalAddress::from_raw(sp), - pages: 1, - flags: mmu::Sv39Flags::user_rw(), - }); + mmu::map( + user_pt, + mmu::Mapping { + va: types::address::VirtualAddress::from_raw(USER_VA_BASE - (16 - i) * 4096), + pa: types::address::PhysicalAddress::from_raw(sp), + pages: 1, + flags: mmu::Sv39Flags::user_rw(), + }, + ); } - kern().platform_mut().set_page_table(pid, user_pt as *const mmu::PageTable as usize); + kern() + .platform_mut() + .set_page_table(pid, user_pt as *const mmu::PageTable as usize); elf_info.entry_point } diff --git a/crates/adapter-riscv/src/boot_fs.rs b/crates/adapter-riscv/src/boot_fs.rs index 00cd694..52f3e68 100644 --- a/crates/adapter-riscv/src/boot_fs.rs +++ b/crates/adapter-riscv/src/boot_fs.rs @@ -19,7 +19,9 @@ impl BootFat16 { } let bytes_per_sector = u16::from_le_bytes([boot_sector[11], boot_sector[12]]); - if bytes_per_sector != SECTOR_SIZE as u16 { return None; } + if bytes_per_sector != SECTOR_SIZE as u16 { + return None; + } let sectors_per_cluster = boot_sector[13]; let reserved_sectors = u16::from_le_bytes([boot_sector[14], boot_sector[15]]); @@ -50,7 +52,9 @@ impl BootFat16 { fn to_fat_name(name: &[u8]) -> [u8; 11] { let mut fat = [b' '; 11]; let dot_pos = name.iter().position(|&b| b == b'.').unwrap_or(name.len()); - for i in 0..dot_pos.min(8) { fat[i] = name[i].to_ascii_uppercase(); } + for i in 0..dot_pos.min(8) { + fat[i] = name[i].to_ascii_uppercase(); + } if dot_pos < name.len() { for i in 0..(name.len() - dot_pos - 1).min(3) { fat[8 + i] = name[dot_pos + 1 + i].to_ascii_uppercase(); @@ -67,7 +71,9 @@ pub fn read_file_from_disk( let mut sector_buf = [0u8; SECTOR_SIZE]; // Read boot sector - if !blk.read_sector(0, &mut sector_buf) { return None; } + if !blk.read_sector(0, &mut sector_buf) { + return None; + } let fs = BootFat16::parse(§or_buf)?; let fat_name = to_fat_name(filename); @@ -78,25 +84,37 @@ pub fn read_file_from_disk( let mut found = false; for s in 0..fs.root_dir_sectors { - if !blk.read_sector((fs.root_dir_start + s) as u32, &mut sector_buf) { continue; } + if !blk.read_sector((fs.root_dir_start + s) as u32, &mut sector_buf) { + continue; + } for i in 0..(SECTOR_SIZE / 32) { let off = i * 32; - if sector_buf[off] == 0x00 { break; } - if sector_buf[off] == 0xE5 { continue; } + if sector_buf[off] == 0x00 { + break; + } + if sector_buf[off] == 0xE5 { + continue; + } if sector_buf[off..off + 11] == fat_name { first_cluster = u16::from_le_bytes([sector_buf[off + 26], sector_buf[off + 27]]); file_size = u32::from_le_bytes([ - sector_buf[off + 28], sector_buf[off + 29], - sector_buf[off + 30], sector_buf[off + 31], + sector_buf[off + 28], + sector_buf[off + 29], + sector_buf[off + 30], + sector_buf[off + 31], ]); found = true; break; } } - if found { break; } + if found { + break; + } } - if !found { return None; } + if !found { + return None; + } let size = (file_size as usize).min(out_buf.len()); let mut read = 0; @@ -105,9 +123,13 @@ pub fn read_file_from_disk( while read < size && cluster >= 2 && cluster < 0xFFF8 { for s in 0..sectors_per_cluster { - if read >= size { break; } + if read >= size { + break; + } let sector = fs.cluster_to_sector(cluster) + s; - if !blk.read_sector(sector, &mut sector_buf) { return Some(read); } + if !blk.read_sector(sector, &mut sector_buf) { + return Some(read); + } let chunk = (size - read).min(SECTOR_SIZE); out_buf[read..read + chunk].copy_from_slice(§or_buf[..chunk]); read += chunk; @@ -117,7 +139,9 @@ pub fn read_file_from_disk( let fat_offset = (cluster as u32) * 2; let fat_sector = fs.reserved_sectors as u32 + fat_offset / SECTOR_SIZE as u32; let fat_byte = (fat_offset % SECTOR_SIZE as u32) as usize; - if !blk.read_sector(fat_sector, &mut sector_buf) { break; } + if !blk.read_sector(fat_sector, &mut sector_buf) { + break; + } cluster = u16::from_le_bytes([sector_buf[fat_byte], sector_buf[fat_byte + 1]]); } diff --git a/crates/adapter-riscv/src/devices/gpu_setup.rs b/crates/adapter-riscv/src/devices/gpu_setup.rs index 2deb015..f33d8f3 100644 --- a/crates/adapter-riscv/src/devices/gpu_setup.rs +++ b/crates/adapter-riscv/src/devices/gpu_setup.rs @@ -38,9 +38,8 @@ pub fn configure(uart: &Uart, display_pid: ProcessId) { gpu.init_device(vq_phys); - let queue = hw_virtio::queue::VirtioQueue::new( - hw_virtio::queue::QueueAddrs::from_base(vq_phys), - ); + let queue = + hw_virtio::queue::VirtioQueue::new(hw_virtio::queue::QueueAddrs::from_base(vq_phys)); let dma = hw_virtio::gpu::GpuDmaAddrs { cmd_pa: types::address::PhysicalAddress::from_raw(cmd_phys), cmd_va: types::address::VirtualAddress::from_raw(cmd_phys), @@ -86,12 +85,15 @@ pub fn configure(uart: &Uart, display_pid: ProcessId) { } fn map_page(pt: &mut mmu::PageTable, va: usize, pa: usize) { - mmu::map(pt, mmu::Mapping { - va: types::address::VirtualAddress::from_raw(va), - pa: types::address::PhysicalAddress::from_raw(pa), - pages: 1, - flags: mmu::Sv39Flags::user_rw(), - }); + mmu::map( + pt, + mmu::Mapping { + va: types::address::VirtualAddress::from_raw(va), + pa: types::address::PhysicalAddress::from_raw(pa), + pages: 1, + flags: mmu::Sv39Flags::user_rw(), + }, + ); } fn map_range(pt: &mut mmu::PageTable, va_base: usize, pa_base: usize, count: usize) { diff --git a/crates/adapter-riscv/src/devices/input_setup.rs b/crates/adapter-riscv/src/devices/input_setup.rs index ef875a2..9b6c0ff 100644 --- a/crates/adapter-riscv/src/devices/input_setup.rs +++ b/crates/adapter-riscv/src/devices/input_setup.rs @@ -45,12 +45,15 @@ pub fn configure(uart: &Uart, input_pid: ProcessId) { } fn map_page(pt: &mut mmu::PageTable, va: usize, pa: usize) { - mmu::map(pt, mmu::Mapping { - va: types::address::VirtualAddress::from_raw(va), - pa: types::address::PhysicalAddress::from_raw(pa), - pages: 1, - flags: mmu::Sv39Flags::user_rw(), - }); + mmu::map( + pt, + mmu::Mapping { + va: types::address::VirtualAddress::from_raw(va), + pa: types::address::PhysicalAddress::from_raw(pa), + pages: 1, + flags: mmu::Sv39Flags::user_rw(), + }, + ); } fn map_range(pt: &mut mmu::PageTable, va_base: usize, pa_base: usize, count: usize) { diff --git a/crates/adapter-riscv/src/devices/storage_setup.rs b/crates/adapter-riscv/src/devices/storage_setup.rs index 36486c9..325afed 100644 --- a/crates/adapter-riscv/src/devices/storage_setup.rs +++ b/crates/adapter-riscv/src/devices/storage_setup.rs @@ -13,12 +13,7 @@ const PHYSINFO_VA: usize = 0x24000; const SHARED_BUF_VA: usize = 0x30000; const SHARED_BUF_PAGES: usize = 16; -pub fn configure( - uart: &Uart, - init_pid: ProcessId, - storage_pid: ProcessId, - virtio_base: usize, -) { +pub fn configure(uart: &Uart, init_pid: ProcessId, storage_pid: ProcessId, virtio_base: usize) { let storage_pt = get_pt(storage_pid); let init_pt = get_pt(init_pid); @@ -39,47 +34,59 @@ fn get_pt(pid: ProcessId) -> &'static mut mmu::PageTable { } fn map_virtio_mmio(pt: &mut mmu::PageTable, virtio_base: usize) { - mmu::map(pt, mmu::Mapping { - va: types::address::VirtualAddress::from_raw(VIRTIO_VA), - pa: types::address::PhysicalAddress::from_raw(virtio_base), - pages: 1, - flags: mmu::Sv39Flags::user_rw(), - }); + mmu::map( + pt, + mmu::Mapping { + va: types::address::VirtualAddress::from_raw(VIRTIO_VA), + pa: types::address::PhysicalAddress::from_raw(virtio_base), + pages: 1, + flags: mmu::Sv39Flags::user_rw(), + }, + ); } fn alloc_and_map_virtqueue(pt: &mut mmu::PageTable) -> usize { let phys = mmu::allocator::alloc_zeroed_page(); mmu::allocator::alloc_zeroed_page(); for i in 0..2usize { - mmu::map(pt, mmu::Mapping { - va: types::address::VirtualAddress::from_raw(VQUEUE_VA + i * 4096), - pa: types::address::PhysicalAddress::from_raw(phys + i * 4096), - pages: 1, - flags: mmu::Sv39Flags::user_rw(), - }); + mmu::map( + pt, + mmu::Mapping { + va: types::address::VirtualAddress::from_raw(VQUEUE_VA + i * 4096), + pa: types::address::PhysicalAddress::from_raw(phys + i * 4096), + pages: 1, + flags: mmu::Sv39Flags::user_rw(), + }, + ); } phys } fn alloc_and_map_reqhdr(pt: &mut mmu::PageTable) -> usize { let phys = mmu::allocator::alloc_zeroed_page(); - mmu::map(pt, mmu::Mapping { - va: types::address::VirtualAddress::from_raw(REQHDR_VA), - pa: types::address::PhysicalAddress::from_raw(phys), - pages: 1, - flags: mmu::Sv39Flags::user_rw(), - }); + mmu::map( + pt, + mmu::Mapping { + va: types::address::VirtualAddress::from_raw(REQHDR_VA), + pa: types::address::PhysicalAddress::from_raw(phys), + pages: 1, + flags: mmu::Sv39Flags::user_rw(), + }, + ); phys } fn write_phys_info(pt: &mut mmu::PageTable, reqhdr_phys: usize) { let phys = mmu::allocator::alloc_zeroed_page(); - mmu::map(pt, mmu::Mapping { - va: types::address::VirtualAddress::from_raw(PHYSINFO_VA), - pa: types::address::PhysicalAddress::from_raw(phys), - pages: 1, - flags: mmu::Sv39Flags::user_rw(), - }); + mmu::map( + pt, + mmu::Mapping { + va: types::address::VirtualAddress::from_raw(PHYSINFO_VA), + pa: types::address::PhysicalAddress::from_raw(phys), + pages: 1, + flags: mmu::Sv39Flags::user_rw(), + }, + ); unsafe { let info = phys as *mut u64; core::ptr::write_volatile(info, reqhdr_phys as u64); @@ -104,11 +111,14 @@ fn map_shared_buffer(init_pt: &mut mmu::PageTable, storage_pt: &mut mmu::PageTab flags: mmu::Sv39Flags::user_rw(), }; mmu::map(init_pt, mapping); - mmu::map(storage_pt, mmu::Mapping { - va: types::address::VirtualAddress::from_raw(va), - pa: types::address::PhysicalAddress::from_raw(page), - pages: 1, - flags: mmu::Sv39Flags::user_rw(), - }); + mmu::map( + storage_pt, + mmu::Mapping { + va: types::address::VirtualAddress::from_raw(va), + pa: types::address::PhysicalAddress::from_raw(page), + pages: 1, + flags: mmu::Sv39Flags::user_rw(), + }, + ); } } diff --git a/crates/adapter-riscv/src/hw/uart.rs b/crates/adapter-riscv/src/hw/uart.rs index 9735968..ee222f8 100644 --- a/crates/adapter-riscv/src/hw/uart.rs +++ b/crates/adapter-riscv/src/hw/uart.rs @@ -6,7 +6,9 @@ pub struct Uart { impl Uart { pub fn new() -> Self { - Self { base: board::UART_BASE } + Self { + base: board::UART_BASE, + } } pub fn put_char(&self, byte: u8) { @@ -30,7 +32,11 @@ impl Uart { let mut i = 0; while value > 0 { let digit = (value & 0xF) as u8; - buf[i] = if digit < 10 { b'0' + digit } else { b'a' + digit - 10 }; + buf[i] = if digit < 10 { + b'0' + digit + } else { + b'a' + digit - 10 + }; value >>= 4; i += 1; } diff --git a/crates/adapter-riscv/src/hw/virtio_blk.rs b/crates/adapter-riscv/src/hw/virtio_blk.rs index 14c40aa..25e533e 100644 --- a/crates/adapter-riscv/src/hw/virtio_blk.rs +++ b/crates/adapter-riscv/src/hw/virtio_blk.rs @@ -1,6 +1,6 @@ -use hw_virtio::mmio::{self, DirectMmio}; -use hw_virtio::queue::{QueueAddrs, VirtioQueue, QUEUE_SIZE}; use hw_virtio::block::{self, DmaAddrs}; +use hw_virtio::mmio::{self, DirectMmio}; +use hw_virtio::queue::{QUEUE_SIZE, QueueAddrs, VirtioQueue}; use types::address::{PhysicalAddress, VirtualAddress}; const SECTOR_SIZE: usize = 512; @@ -11,7 +11,11 @@ struct VirtqMem { } static mut VQUEUE: VirtqMem = VirtqMem { _data: [0; 8192] }; -static mut REQ_HEADER: block::BlockReqHeader = block::BlockReqHeader { req_type: 0, reserved: 0, sector: 0 }; +static mut REQ_HEADER: block::BlockReqHeader = block::BlockReqHeader { + req_type: 0, + reserved: 0, + sector: 0, +}; static mut REQ_STATUS: u8 = 0xFF; static mut SECTOR_BUF: [u8; SECTOR_SIZE] = [0; SECTOR_SIZE]; diff --git a/crates/adapter-riscv/src/hw/virtio_gpu.rs b/crates/adapter-riscv/src/hw/virtio_gpu.rs index 64aeacb..c59d242 100644 --- a/crates/adapter-riscv/src/hw/virtio_gpu.rs +++ b/crates/adapter-riscv/src/hw/virtio_gpu.rs @@ -1,6 +1,6 @@ -use hw_virtio::mmio::{self, DirectMmio}; -use hw_virtio::queue::{QueueAddrs, VirtioQueue, QUEUE_SIZE}; use hw_virtio::gpu::{self, GpuDmaAddrs}; +use hw_virtio::mmio::{self, DirectMmio}; +use hw_virtio::queue::{QUEUE_SIZE, QueueAddrs, VirtioQueue}; use types::address::{PhysicalAddress, VirtualAddress}; use types::display::Dimension; @@ -26,7 +26,14 @@ impl VirtioGpu { mmio::init_legacy_device(&self.mmio, vqueue_phys, QUEUE_SIZE as u32); } - pub fn setup_framebuffer(&self, cmd_phys: usize, vq_phys: usize, fb_phys: usize, width: Dimension, height: Dimension) -> bool { + pub fn setup_framebuffer( + &self, + cmd_phys: usize, + vq_phys: usize, + fb_phys: usize, + width: Dimension, + height: Dimension, + ) -> bool { let queue = VirtioQueue::new(QueueAddrs::from_base(vq_phys)); let dma = GpuDmaAddrs { cmd_pa: PhysicalAddress::from_raw(cmd_phys), @@ -34,7 +41,14 @@ impl VirtioGpu { resp_pa: PhysicalAddress::from_raw(cmd_phys + 512), }; let ok1 = gpu::create_2d(&self.mmio, &queue, &dma, 1, width, height); - let ok2 = gpu::attach_backing(&self.mmio, &queue, &dma, 1, PhysicalAddress::from_raw(fb_phys), width.raw() as u32 * height.raw() as u32 * 4); + let ok2 = gpu::attach_backing( + &self.mmio, + &queue, + &dma, + 1, + PhysicalAddress::from_raw(fb_phys), + width.raw() as u32 * height.raw() as u32 * 4, + ); let ok3 = gpu::set_scanout(&self.mmio, &queue, &dma, 0, 1, width, height); ok1 && ok2 && ok3 } diff --git a/crates/adapter-riscv/src/main.rs b/crates/adapter-riscv/src/main.rs index 000698a..9b2cfd9 100644 --- a/crates/adapter-riscv/src/main.rs +++ b/crates/adapter-riscv/src/main.rs @@ -42,8 +42,8 @@ extern "C" fn kmain() -> ! { uart.write_str("k-os: booted on RISC-V\n"); let kernel_pt = boot::hardware::init(&uart); - let mut blk = boot::hardware::probe_block_device(&uart) - .unwrap_or_else(|| halt(&uart, "no block device")); + let mut blk = + boot::hardware::probe_block_device(&uart).unwrap_or_else(|| halt(&uart, "no block device")); let (init, _) = boot::loader::load_init(&uart, &mut blk, kernel_pt); let storage = boot::loader::load_server(&uart, &mut blk, kernel_pt, b"storage.elf", "storage"); @@ -65,7 +65,9 @@ pub fn halt(uart: &Uart, msg: &str) -> ! { uart.write_str("k-os: FATAL — "); uart.write_str(msg); uart.put_char(b'\n'); - loop { unsafe { core::arch::asm!("wfi") }; } + loop { + unsafe { core::arch::asm!("wfi") }; + } } #[panic_handler] @@ -78,5 +80,7 @@ fn panic(info: &core::panic::PanicInfo) -> ! { uart.write_dec(location.line() as usize); } uart.put_char(b'\n'); - loop { unsafe { core::arch::asm!("wfi") }; } + loop { + unsafe { core::arch::asm!("wfi") }; + } } diff --git a/crates/adapter-riscv/src/mmu/allocator.rs b/crates/adapter-riscv/src/mmu/allocator.rs index c71b7e1..978042f 100644 --- a/crates/adapter-riscv/src/mmu/allocator.rs +++ b/crates/adapter-riscv/src/mmu/allocator.rs @@ -1,11 +1,13 @@ -use super::page_table::{PageTable, PAGE_SIZE}; +use super::page_table::{PAGE_SIZE, PageTable}; // Boot-time bump allocator for page tables. // Only used during init before the scheduler starts. static mut NEXT_FREE: usize = 0; pub fn init_allocator(start: usize) { - unsafe { NEXT_FREE = start; } + unsafe { + NEXT_FREE = start; + } } pub fn alloc_zeroed_page() -> usize { diff --git a/crates/adapter-riscv/src/mmu/mod.rs b/crates/adapter-riscv/src/mmu/mod.rs index 4d36cac..f3b233b 100644 --- a/crates/adapter-riscv/src/mmu/mod.rs +++ b/crates/adapter-riscv/src/mmu/mod.rs @@ -2,4 +2,7 @@ pub mod allocator; pub mod page_table; pub use allocator::init_allocator; -pub use page_table::{activate, init_kernel_page_table, create_user_page_table, map, translate, Sv39Flags, Mapping, PageTable, PAGE_SIZE}; +pub use page_table::{ + Mapping, PAGE_SIZE, PageTable, Sv39Flags, activate, create_user_page_table, + init_kernel_page_table, map, translate, +}; diff --git a/crates/adapter-riscv/src/mmu/page_table.rs b/crates/adapter-riscv/src/mmu/page_table.rs index 085f896..dbdd21b 100644 --- a/crates/adapter-riscv/src/mmu/page_table.rs +++ b/crates/adapter-riscv/src/mmu/page_table.rs @@ -1,5 +1,5 @@ -use crate::board; use super::allocator::alloc_page_table; +use crate::board; use types::address::{PhysicalAddress, VirtualAddress}; pub use types::mapping::Mapping; @@ -21,26 +21,40 @@ pub struct Sv39Flags { impl Sv39Flags { pub fn kernel_rwx() -> Self { - Self { bits: PTE_R | PTE_W | PTE_X | PTE_G } + Self { + bits: PTE_R | PTE_W | PTE_X | PTE_G, + } } pub fn kernel_rw() -> Self { - Self { bits: PTE_R | PTE_W | PTE_G } + Self { + bits: PTE_R | PTE_W | PTE_G, + } } pub fn user_rx() -> Self { - Self { bits: PTE_R | PTE_X | PTE_U } + Self { + bits: PTE_R | PTE_X | PTE_U, + } } pub fn user_rw() -> Self { - Self { bits: PTE_R | PTE_W | PTE_U } + Self { + bits: PTE_R | PTE_W | PTE_U, + } } pub fn user(read: bool, write: bool, exec: bool) -> Self { let mut bits = PTE_U; - if read { bits |= PTE_R; } - if write { bits |= PTE_W; } - if exec { bits |= PTE_X; } + if read { + bits |= PTE_R; + } + if write { + bits |= PTE_W; + } + if exec { + bits |= PTE_X; + } Self { bits } } @@ -94,15 +108,21 @@ fn vpn(va: usize, level: usize) -> usize { pub fn translate(root: &PageTable, va: usize) -> Option { let vpn2 = vpn(va, 2); - if !root.entries[vpn2].is_valid() { return None; } + if !root.entries[vpn2].is_valid() { + return None; + } let l1 = unsafe { &*((root.entries[vpn2].ppn() << 12) as *const PageTable) }; let vpn1 = vpn(va, 1); - if !l1.entries[vpn1].is_valid() { return None; } + if !l1.entries[vpn1].is_valid() { + return None; + } let l0 = unsafe { &*((l1.entries[vpn1].ppn() << 12) as *const PageTable) }; let vpn0 = vpn(va, 0); - if !l0.entries[vpn0].is_valid() { return None; } + if !l0.entries[vpn0].is_valid() { + return None; + } let pa = (l0.entries[vpn0].ppn() << 12) as usize | (va & 0xFFF); Some(pa) } @@ -137,29 +157,79 @@ fn map_page(root: &mut PageTable, va: usize, pa: usize, flags: Sv39Flags) { pub fn map(root: &mut PageTable, mapping: Mapping) { for i in 0..mapping.pages { let offset = i * PAGE_SIZE; - map_page(root, mapping.va.raw() + offset, mapping.pa.raw() + offset, mapping.flags); + map_page( + root, + mapping.va.raw() + offset, + mapping.pa.raw() + offset, + mapping.flags, + ); } } pub fn init_kernel_page_table() -> &'static mut PageTable { let root = alloc_page_table(); - let identity = |addr: usize| (VirtualAddress::from_raw(addr), PhysicalAddress::from_raw(addr)); + let identity = |addr: usize| { + ( + VirtualAddress::from_raw(addr), + PhysicalAddress::from_raw(addr), + ) + }; let (va, pa) = identity(board::RAM_BASE); - map(root, Mapping { va, pa, pages: board::RAM_SIZE / PAGE_SIZE, flags: Sv39Flags::kernel_rwx() }); + map( + root, + Mapping { + va, + pa, + pages: board::RAM_SIZE / PAGE_SIZE, + flags: Sv39Flags::kernel_rwx(), + }, + ); let (va, pa) = identity(board::UART_BASE); - map(root, Mapping { va, pa, pages: 1, flags: Sv39Flags::kernel_rw() }); + map( + root, + Mapping { + va, + pa, + pages: 1, + flags: Sv39Flags::kernel_rw(), + }, + ); let (va, pa) = identity(board::PLIC_BASE); - map(root, Mapping { va, pa, pages: 0x400000 / PAGE_SIZE, flags: Sv39Flags::kernel_rw() }); + map( + root, + Mapping { + va, + pa, + pages: 0x400000 / PAGE_SIZE, + flags: Sv39Flags::kernel_rw(), + }, + ); let (va, pa) = identity(board::CLINT_BASE); - map(root, Mapping { va, pa, pages: 0x10000 / PAGE_SIZE, flags: Sv39Flags::kernel_rw() }); + map( + root, + Mapping { + va, + pa, + pages: 0x10000 / PAGE_SIZE, + flags: Sv39Flags::kernel_rw(), + }, + ); let (va, pa) = identity(board::VIRTIO_BASE); - map(root, Mapping { va, pa, pages: board::VIRTIO_SIZE / PAGE_SIZE, flags: Sv39Flags::kernel_rw() }); + map( + root, + Mapping { + va, + pa, + pages: board::VIRTIO_SIZE / PAGE_SIZE, + flags: Sv39Flags::kernel_rw(), + }, + ); root } diff --git a/crates/adapter-riscv/src/platform.rs b/crates/adapter-riscv/src/platform.rs index 058f790..175292d 100644 --- a/crates/adapter-riscv/src/platform.rs +++ b/crates/adapter-riscv/src/platform.rs @@ -57,12 +57,15 @@ impl Platform for RiscVPlatform { fn configure_protection(&mut self, process: ProcessId, regions: &[MemoryRegion]) { let pt = self.ensure_page_table(process); for region in regions { - mmu::map(pt, mmu::Mapping { - va: VirtualAddress::from_raw(region.base().raw()), - pa: region.base(), - pages: region.size().value() as usize, - flags: mmu::Sv39Flags::user(true, true, true), - }); + mmu::map( + pt, + mmu::Mapping { + va: VirtualAddress::from_raw(region.base().raw()), + pa: region.base(), + pages: region.size().value() as usize, + flags: mmu::Sv39Flags::user(true, true, true), + }, + ); } } @@ -122,16 +125,19 @@ impl Platform for RiscVPlatform { permissions: PermissionSet, ) { let pt = self.ensure_page_table(process); - mmu::map(pt, mmu::Mapping { - va: VirtualAddress::from_raw(base.raw()), - pa: base, - pages: size.value() as usize, - flags: mmu::Sv39Flags::user( - permissions.allows(Permission::Read), - permissions.allows(Permission::Write), - permissions.allows(Permission::Execute), - ), - }); + mmu::map( + pt, + mmu::Mapping { + va: VirtualAddress::from_raw(base.raw()), + pa: base, + pages: size.value() as usize, + flags: mmu::Sv39Flags::user( + permissions.allows(Permission::Read), + permissions.allows(Permission::Write), + permissions.allows(Permission::Execute), + ), + }, + ); } fn debug_putchar(&self, byte: u8) { @@ -140,20 +146,32 @@ impl Platform for RiscVPlatform { fn translate_va(&self, process: ProcessId, va: VirtualAddress) -> Option { let pt_addr = self.page_tables[process.raw() as usize]; - if pt_addr == 0 { return None; } + if pt_addr == 0 { + return None; + } let pt = unsafe { &*(pt_addr as *const mmu::PageTable) }; mmu::translate(pt, va.raw()).map(PhysicalAddress::from_raw) } - fn map_user_page(&mut self, process: ProcessId, va: VirtualAddress, pa: PhysicalAddress, writable: bool, executable: bool) { + fn map_user_page( + &mut self, + process: ProcessId, + va: VirtualAddress, + pa: PhysicalAddress, + writable: bool, + executable: bool, + ) { let pt = self.ensure_page_table(process); let flags = mmu::Sv39Flags::user(true, writable, executable); - mmu::map(pt, mmu::Mapping { - va, - pa, - pages: 1, - flags, - }); + mmu::map( + pt, + mmu::Mapping { + va, + pa, + pages: 1, + flags, + }, + ); } fn halt(&self) -> ! { @@ -166,6 +184,8 @@ impl Platform for RiscVPlatform { in("a6") 0usize, ); } - loop { unsafe { core::arch::asm!("wfi") }; } + loop { + unsafe { core::arch::asm!("wfi") }; + } } } diff --git a/crates/adapter-riscv/src/trap/mod.rs b/crates/adapter-riscv/src/trap/mod.rs index a5e9ee5..0ac8bb3 100644 --- a/crates/adapter-riscv/src/trap/mod.rs +++ b/crates/adapter-riscv/src/trap/mod.rs @@ -17,7 +17,8 @@ impl TrapFrame { } } -global_asm!(r#" +global_asm!( + r#" .align 4 .globl trap_vector trap_vector: @@ -120,7 +121,8 @@ _restore_smode: csrrw sp, sscratch, sp _sret_smode: sret -"#); +"# +); const CAUSE_INTERRUPT_BIT: usize = 1 << 63; const CAUSE_S_TIMER: usize = 5; @@ -169,7 +171,10 @@ fn decode_syscall(frame: &TrapFrame) -> Option { SYS_SEND => { let slot = types::bounded::CapSlot::new(a0 as u8)?; let msg = Message::from_words([a1, a2, a3, a4]); - Some(Syscall::Send { endpoint: slot, message: msg }) + Some(Syscall::Send { + endpoint: slot, + message: msg, + }) } SYS_RECEIVE => { let slot = types::bounded::CapSlot::new(a0 as u8)?; @@ -179,7 +184,11 @@ fn decode_syscall(frame: &TrapFrame) -> Option { let slot = types::bounded::CapSlot::new(a0 as u8)?; let to = types::bounded::CapSlot::new(a1 as u8)?; let perms = types::permission::PermissionSet::from_bits(a2 as u8); - Some(Syscall::Delegate { slot, to_endpoint: to, permissions: perms }) + Some(Syscall::Delegate { + slot, + to_endpoint: to, + permissions: perms, + }) } SYS_WAIT_FOR_INTERRUPT => { let slot = types::bounded::CapSlot::new(a0 as u8)?; @@ -190,14 +199,27 @@ fn decode_syscall(frame: &TrapFrame) -> Option { Some(Syscall::AcknowledgeInterrupt { irq: slot }) } SYS_WAIT_ANY => { - let ep0 = if a0 != usize::MAX { types::bounded::CapSlot::new(a0 as u8) } else { None }; - let ep1 = if a1 != usize::MAX { types::bounded::CapSlot::new(a1 as u8) } else { None }; - let ep2 = if a2 != usize::MAX { types::bounded::CapSlot::new(a2 as u8) } else { None }; - let ep3 = if a3 != usize::MAX { types::bounded::CapSlot::new(a3 as u8) } else { None }; - let sources = WaitSet::new( - [ep0, ep1, ep2, ep3], - [None, None, None, None], - ); + let ep0 = if a0 != usize::MAX { + types::bounded::CapSlot::new(a0 as u8) + } else { + None + }; + let ep1 = if a1 != usize::MAX { + types::bounded::CapSlot::new(a1 as u8) + } else { + None + }; + let ep2 = if a2 != usize::MAX { + types::bounded::CapSlot::new(a2 as u8) + } else { + None + }; + let ep3 = if a3 != usize::MAX { + types::bounded::CapSlot::new(a3 as u8) + } else { + None + }; + let sources = WaitSet::new([ep0, ep1, ep2, ep3], [None, None, None, None]); Some(Syscall::WaitAny { sources }) } SYS_CREATE_PROCESS => { @@ -288,7 +310,7 @@ fn load_context_to_frame(ctx: &domain::thread::SavedContext, frame: &mut TrapFra frame.sstatus = ctx.status(); // ensure returning to U-mode frame.sstatus &= !(1 << 8); // clear SPP - frame.sstatus |= 1 << 5; // set SPIE + frame.sstatus |= 1 << 5; // set SPIE } fn apply_pending_result(frame: &mut TrapFrame, tid: types::id::ThreadId) { @@ -315,7 +337,11 @@ fn write_result_direct(frame: &mut TrapFrame, result: &kernel::SyscallResult) { } } -fn switch_to_thread(frame: &mut TrapFrame, current_tid: types::id::ThreadId, next_tid: types::id::ThreadId) { +fn switch_to_thread( + frame: &mut TrapFrame, + current_tid: types::id::ThreadId, + next_tid: types::id::ThreadId, +) { let kern = unsafe { &mut *crate::kernel_ptr() }; if let Some(ctx) = kern.thread_context_mut(current_tid) { @@ -372,7 +398,9 @@ fn switch_to_next(frame: &mut TrapFrame, current_tid: types::id::ThreadId) { } } } else { - loop { unsafe { core::arch::asm!("wfi") }; } + loop { + unsafe { core::arch::asm!("wfi") }; + } } } @@ -471,7 +499,9 @@ fn handle_exception(frame: &mut TrapFrame, scause: usize) { kern.handle_fault(current_tid, fault, frame.sepc); switch_to_next(frame, current_tid); } else { - loop { unsafe { core::arch::asm!("wfi") }; } + loop { + unsafe { core::arch::asm!("wfi") }; + } } } } diff --git a/crates/domain/src/capability/mod.rs b/crates/domain/src/capability/mod.rs index ec02e00..88ee80c 100644 --- a/crates/domain/src/capability/mod.rs +++ b/crates/domain/src/capability/mod.rs @@ -17,11 +17,7 @@ pub struct Capability { } impl Capability { - pub fn new( - resource: Resource, - permissions: PermissionSet, - generation: Generation, - ) -> Self { + pub fn new(resource: Resource, permissions: PermissionSet, generation: Generation) -> Self { Self { resource, permissions, diff --git a/crates/domain/src/endpoint/mod.rs b/crates/domain/src/endpoint/mod.rs index 7fd7890..948ff41 100644 --- a/crates/domain/src/endpoint/mod.rs +++ b/crates/domain/src/endpoint/mod.rs @@ -95,15 +95,21 @@ impl EndpointTable { } pub fn get(&self, id: EndpointId) -> Option<&Endpoint> { - self.endpoints.get(id.raw() as usize).and_then(|s| s.as_ref()) + self.endpoints + .get(id.raw() as usize) + .and_then(|s| s.as_ref()) } pub fn get_mut(&mut self, id: EndpointId) -> Option<&mut Endpoint> { - self.endpoints.get_mut(id.raw() as usize).and_then(|s| s.as_mut()) + self.endpoints + .get_mut(id.raw() as usize) + .and_then(|s| s.as_mut()) } pub fn destroy(&mut self, id: EndpointId) -> Option { - self.endpoints.get_mut(id.raw() as usize).and_then(|s| s.take()) + self.endpoints + .get_mut(id.raw() as usize) + .and_then(|s| s.take()) } pub fn remove_thread_from_all(&mut self, thread: ThreadId) { diff --git a/crates/domain/src/endpoint/tests.rs b/crates/domain/src/endpoint/tests.rs index 94a42d3..58a7f0c 100644 --- a/crates/domain/src/endpoint/tests.rs +++ b/crates/domain/src/endpoint/tests.rs @@ -166,7 +166,11 @@ fn table_destroy_then_get_fails() { fn table_get_mut_allows_enqueue() { let mut table = EndpointTable::new(); let id = table.create().unwrap(); - table.get_mut(id).unwrap().enqueue_sender(thread(1)).unwrap(); + table + .get_mut(id) + .unwrap() + .enqueue_sender(thread(1)) + .unwrap(); assert!(table.get(id).unwrap().has_waiting_sender()); } diff --git a/crates/domain/src/memory/mod.rs b/crates/domain/src/memory/mod.rs index 00f7ff1..a5164a7 100644 --- a/crates/domain/src/memory/mod.rs +++ b/crates/domain/src/memory/mod.rs @@ -87,11 +87,15 @@ impl RegionTable { } pub fn get_mut(&mut self, id: RegionId) -> Option<&mut MemoryRegion> { - self.regions.get_mut(id.raw() as usize).and_then(|s| s.as_mut()) + self.regions + .get_mut(id.raw() as usize) + .and_then(|s| s.as_mut()) } pub fn remove(&mut self, id: RegionId) -> Option { - self.regions.get_mut(id.raw() as usize).and_then(|s| s.take()) + self.regions + .get_mut(id.raw() as usize) + .and_then(|s| s.take()) } pub fn find_by_base( diff --git a/crates/domain/src/memory/tests.rs b/crates/domain/src/memory/tests.rs index 106c452..b4bd2ee 100644 --- a/crates/domain/src/memory/tests.rs +++ b/crates/domain/src/memory/tests.rs @@ -178,13 +178,15 @@ fn region_table_insert_and_get() { #[test] fn region_table_remove() { let mut table = RegionTable::new(); - let id = table.insert(MemoryRegion::new( - RegionId::from_raw(0), - process(0), - base(), - pages(4), - Generation::initial(), - )).unwrap(); + let id = table + .insert(MemoryRegion::new( + RegionId::from_raw(0), + process(0), + base(), + pages(4), + Generation::initial(), + )) + .unwrap(); let removed = table.remove(id); assert!(removed.is_some()); assert!(table.get(id).is_none()); @@ -194,13 +196,25 @@ fn region_table_remove() { fn region_table_regions_for_process() { let mut table = RegionTable::new(); table.insert(MemoryRegion::new( - RegionId::from_raw(0), process(0), base(), pages(4), Generation::initial(), + RegionId::from_raw(0), + process(0), + base(), + pages(4), + Generation::initial(), )); table.insert(MemoryRegion::new( - RegionId::from_raw(1), process(1), base(), pages(4), Generation::initial(), + RegionId::from_raw(1), + process(1), + base(), + pages(4), + Generation::initial(), )); table.insert(MemoryRegion::new( - RegionId::from_raw(2), process(0), base(), pages(2), Generation::initial(), + RegionId::from_raw(2), + process(0), + base(), + pages(2), + Generation::initial(), )); assert_eq!(table.regions_for_process(process(0)).count(), 2); assert_eq!(table.regions_for_process(process(1)).count(), 1); diff --git a/crates/domain/src/message/tests.rs b/crates/domain/src/message/tests.rs index 1627a18..188106d 100644 --- a/crates/domain/src/message/tests.rs +++ b/crates/domain/src/message/tests.rs @@ -44,10 +44,7 @@ fn caps_returns_full_array() { #[test] fn builder_sets_individual_words() { - let msg = Message::builder() - .word(0, 42) - .word(2, 99) - .build(); + let msg = Message::builder().word(0, 42).word(2, 99).build(); assert_eq!(msg.word(0), 42); assert_eq!(msg.word(1), 0); assert_eq!(msg.word(2), 99); @@ -56,10 +53,7 @@ fn builder_sets_individual_words() { #[test] fn builder_sets_caps() { - let msg = Message::builder() - .cap(0, slot(5)) - .cap(1, slot(10)) - .build(); + let msg = Message::builder().cap(0, slot(5)).cap(1, slot(10)).build(); assert_eq!(msg.cap(0), Some(slot(5))); assert_eq!(msg.cap(1), Some(slot(10))); assert!(msg.cap(2).is_none()); @@ -79,8 +73,6 @@ fn builder_sets_words_and_caps_together() { #[test] fn builder_with_all_words() { - let msg = Message::builder() - .words([11, 22, 33, 44]) - .build(); + let msg = Message::builder().words([11, 22, 33, 44]).build(); assert_eq!(msg.words(), &[11, 22, 33, 44]); } diff --git a/crates/domain/src/proofs/capability.rs b/crates/domain/src/proofs/capability.rs index cfed119..d52ba88 100644 --- a/crates/domain/src/proofs/capability.rs +++ b/crates/domain/src/proofs/capability.rs @@ -1,6 +1,6 @@ +use super::{arbitrary_endpoint_cap, insert_cap}; use crate::capability::CapabilityTable; use crate::resource::Resource; -use super::{arbitrary_endpoint_cap, insert_cap}; use types::permission::PermissionSet; #[kani::proof] diff --git a/crates/domain/src/proofs/delegation.rs b/crates/domain/src/proofs/delegation.rs index dcc16eb..a3cc131 100644 --- a/crates/domain/src/proofs/delegation.rs +++ b/crates/domain/src/proofs/delegation.rs @@ -1,6 +1,6 @@ +use super::{arbitrary_endpoint_cap, insert_cap}; use crate::capability::{Capability, CapabilityTable}; use crate::resource::Resource; -use super::{arbitrary_endpoint_cap, insert_cap}; use types::generation::Generation; use types::id::EndpointId; use types::permission::{Permission, PermissionSet}; @@ -16,7 +16,10 @@ fn delegation_via_cap_table_never_escalates() { kani::assume(source_perms.allows(Permission::Delegate)); let mut source_table = CapabilityTable::new(); - let slot = insert_cap(&mut source_table, arbitrary_endpoint_cap(source_bits, ep_id)); + let slot = insert_cap( + &mut source_table, + arbitrary_endpoint_cap(source_bits, ep_id), + ); let cap = source_table.get(slot).unwrap(); let original_perms = *cap.permissions(); @@ -43,11 +46,21 @@ fn delegation_cannot_add_permissions_not_in_source() { let source = PermissionSet::from_bits(source_bits); let result = source.restrict_to(&PermissionSet::from_bits(restrict_bits)); - if !source.allows(Permission::Read) { assert!(!result.allows(Permission::Read)); } - if !source.allows(Permission::Write) { assert!(!result.allows(Permission::Write)); } - if !source.allows(Permission::Execute) { assert!(!result.allows(Permission::Execute)); } - if !source.allows(Permission::Delegate) { assert!(!result.allows(Permission::Delegate)); } - if !source.allows(Permission::Revoke) { assert!(!result.allows(Permission::Revoke)); } + if !source.allows(Permission::Read) { + assert!(!result.allows(Permission::Read)); + } + if !source.allows(Permission::Write) { + assert!(!result.allows(Permission::Write)); + } + if !source.allows(Permission::Execute) { + assert!(!result.allows(Permission::Execute)); + } + if !source.allows(Permission::Delegate) { + assert!(!result.allows(Permission::Delegate)); + } + if !source.allows(Permission::Revoke) { + assert!(!result.allows(Permission::Revoke)); + } } #[kani::proof] diff --git a/crates/domain/src/scheduler/multi_core.rs b/crates/domain/src/scheduler/multi_core.rs index 80927aa..50b99ea 100644 --- a/crates/domain/src/scheduler/multi_core.rs +++ b/crates/domain/src/scheduler/multi_core.rs @@ -3,7 +3,7 @@ use types::{ id::{CoreId, ThreadId}, }; -use super::{per_core::PerCoreScheduler, Scheduler, SchedulerDecision}; +use super::{Scheduler, SchedulerDecision, per_core::PerCoreScheduler}; const MAX_CORES: usize = 8; const MAX_SCHEDULED_THREADS: usize = 256; diff --git a/crates/domain/src/syscall.rs b/crates/domain/src/syscall.rs index 251e108..70ff620 100644 --- a/crates/domain/src/syscall.rs +++ b/crates/domain/src/syscall.rs @@ -12,11 +12,11 @@ pub struct WaitSet { } impl WaitSet { - pub fn new( - endpoints: [Option; 4], - interrupts: [Option; 4], - ) -> Self { - Self { endpoints, interrupts } + pub fn new(endpoints: [Option; 4], interrupts: [Option; 4]) -> Self { + Self { + endpoints, + interrupts, + } } pub fn endpoints(&self) -> &[Option; 4] { @@ -28,8 +28,7 @@ impl WaitSet { } pub fn is_empty(&self) -> bool { - self.endpoints.iter().all(|s| s.is_none()) - && self.interrupts.iter().all(|s| s.is_none()) + self.endpoints.iter().all(|s| s.is_none()) && self.interrupts.iter().all(|s| s.is_none()) } } @@ -88,7 +87,9 @@ pub enum Syscall { Exit, Halt, CreateEndpoint, - DebugPutchar { byte: u8 }, + DebugPutchar { + byte: u8, + }, MapPage { process: CapSlot, src_va: VirtualAddress, diff --git a/crates/domain/src/thread/mod.rs b/crates/domain/src/thread/mod.rs index 1c94903..28acf33 100644 --- a/crates/domain/src/thread/mod.rs +++ b/crates/domain/src/thread/mod.rs @@ -236,7 +236,13 @@ impl ThreadTable { .ok_or(KernelError::TooManyThreads)?; let id = ThreadId::from_raw(idx as u16); - self.threads[idx] = Some(Thread::new(id, process, priority, time_slice, core_affinity)); + self.threads[idx] = Some(Thread::new( + id, + process, + priority, + time_slice, + core_affinity, + )); Ok(id) } @@ -255,7 +261,14 @@ impl ThreadTable { .ok_or(KernelError::TooManyThreads)?; let id = ThreadId::from_raw(idx as u16); - self.threads[idx] = Some(Thread::with_context(id, process, priority, time_slice, core_affinity, context)); + self.threads[idx] = Some(Thread::with_context( + id, + process, + priority, + time_slice, + core_affinity, + context, + )); Ok(id) } diff --git a/crates/domain/src/thread/tests.rs b/crates/domain/src/thread/tests.rs index 9d23e6f..cae2363 100644 --- a/crates/domain/src/thread/tests.rs +++ b/crates/domain/src/thread/tests.rs @@ -66,7 +66,10 @@ fn running_to_blocked() { let mut t = test_thread(0, 0); t.set_running(core(0)).unwrap(); t.block(BlockReason::WaitingAny).unwrap(); - assert!(matches!(t.state(), ThreadState::Blocked(BlockReason::WaitingAny))); + assert!(matches!( + t.state(), + ThreadState::Blocked(BlockReason::WaitingAny) + )); } #[test] @@ -162,7 +165,9 @@ fn time_slice_mut_ticks() { #[test] fn table_spawn_and_lookup() { let mut table = ThreadTable::new(); - let id = table.spawn(process(0), prio(10), time_slice(), None).unwrap(); + let id = table + .spawn(process(0), prio(10), time_slice(), None) + .unwrap(); let t = table.get(id).unwrap(); assert_eq!(t.id(), id); assert_eq!(t.process(), process(0)); @@ -171,15 +176,21 @@ fn table_spawn_and_lookup() { #[test] fn table_spawn_returns_unique_ids() { let mut table = ThreadTable::new(); - let a = table.spawn(process(0), prio(10), time_slice(), None).unwrap(); - let b = table.spawn(process(0), prio(10), time_slice(), None).unwrap(); + let a = table + .spawn(process(0), prio(10), time_slice(), None) + .unwrap(); + let b = table + .spawn(process(0), prio(10), time_slice(), None) + .unwrap(); assert_ne!(a, b); } #[test] fn table_destroy_then_get_fails() { let mut table = ThreadTable::new(); - let id = table.spawn(process(0), prio(10), time_slice(), None).unwrap(); + let id = table + .spawn(process(0), prio(10), time_slice(), None) + .unwrap(); table.destroy(id).unwrap(); assert!(table.get(id).is_err()); } @@ -187,9 +198,15 @@ fn table_destroy_then_get_fails() { #[test] fn table_threads_for_process_filters() { let mut table = ThreadTable::new(); - table.spawn(process(0), prio(10), time_slice(), None).unwrap(); - table.spawn(process(1), prio(10), time_slice(), None).unwrap(); - table.spawn(process(0), prio(5), time_slice(), None).unwrap(); + table + .spawn(process(0), prio(10), time_slice(), None) + .unwrap(); + table + .spawn(process(1), prio(10), time_slice(), None) + .unwrap(); + table + .spawn(process(0), prio(5), time_slice(), None) + .unwrap(); let count = table.threads_for_process(process(0)).count(); assert_eq!(count, 2); @@ -198,16 +215,25 @@ fn table_threads_for_process_filters() { #[test] fn table_get_mut_allows_state_transition() { let mut table = ThreadTable::new(); - let id = table.spawn(process(0), prio(10), time_slice(), None).unwrap(); + let id = table + .spawn(process(0), prio(10), time_slice(), None) + .unwrap(); table.get_mut(id).unwrap().set_running(core(0)).unwrap(); - assert!(matches!(table.get(id).unwrap().state(), ThreadState::Running(_))); + assert!(matches!( + table.get(id).unwrap().state(), + ThreadState::Running(_) + )); } #[test] fn table_destroy_reuses_slot() { let mut table = ThreadTable::new(); - let id = table.spawn(process(0), prio(10), time_slice(), None).unwrap(); + let id = table + .spawn(process(0), prio(10), time_slice(), None) + .unwrap(); table.destroy(id).unwrap(); - let new_id = table.spawn(process(0), prio(10), time_slice(), None).unwrap(); + let new_id = table + .spawn(process(0), prio(10), time_slice(), None) + .unwrap(); assert_eq!(id, new_id); } diff --git a/crates/kernel/src/interrupt.rs b/crates/kernel/src/interrupt.rs index 49ea814..03ecebf 100644 --- a/crates/kernel/src/interrupt.rs +++ b/crates/kernel/src/interrupt.rs @@ -26,15 +26,26 @@ impl Kernel

{ self.scheduler.add(current_tid, priority, core); match self.scheduler.next(core) { Some(next) => { - if self.threads.get_mut(next).and_then(|t| t.set_running(core)).is_ok() { + if self + .threads + .get_mut(next) + .and_then(|t| t.set_running(core)) + .is_ok() + { SchedulerDecision::Preempt(next) } else { - let _ = self.threads.get_mut(current_tid).map(|t| t.set_running(core)); + let _ = self + .threads + .get_mut(current_tid) + .map(|t| t.set_running(core)); SchedulerDecision::Continue } } None => { - let _ = self.threads.get_mut(current_tid).map(|t| t.set_running(core)); + let _ = self + .threads + .get_mut(current_tid) + .map(|t| t.set_running(core)); SchedulerDecision::Continue } } diff --git a/crates/kernel/src/lib.rs b/crates/kernel/src/lib.rs index d1c5b9a..adb7953 100644 --- a/crates/kernel/src/lib.rs +++ b/crates/kernel/src/lib.rs @@ -16,17 +16,13 @@ use domain::{ endpoint::EndpointTable, error::KernelError, irq::IrqRoutingTable, - memory::{ - page_pool::PagePool, - process_memory::ProcessMemory, - RegionTable, - }, + memory::{RegionTable, page_pool::PagePool, process_memory::ProcessMemory}, message::Message, - process::{ProcessTable, MAX_PROCESSES}, + process::{MAX_PROCESSES, ProcessTable}, resource::Resource, - scheduler::{multi_core::MultiCoreScheduler, Scheduler}, + scheduler::{Scheduler, multi_core::MultiCoreScheduler}, syscall::WaitSet, - thread::{ThreadTable, ThreadState, MAX_THREADS}, + thread::{MAX_THREADS, ThreadState, ThreadTable}, }; use platform::Platform; use types::{ @@ -88,7 +84,10 @@ impl Kernel

{ PermissionSet::empty().with(Permission::Execute), Generation::initial(), ); - self.processes.get_mut(pid)?.capabilities_mut().insert(cap)?; + self.processes + .get_mut(pid)? + .capabilities_mut() + .insert(cap)?; let core = self.platform.core_id(); self.scheduler.add(tid, priority, core); @@ -109,7 +108,11 @@ impl Kernel

{ self.pending_results[thread.raw() as usize].take() } - pub fn set_thread_running(&mut self, tid: ThreadId, core: types::id::CoreId) -> Result<(), domain::error::KernelError> { + pub fn set_thread_running( + &mut self, + tid: ThreadId, + core: types::id::CoreId, + ) -> Result<(), domain::error::KernelError> { self.threads.get_mut(tid)?.set_running(core) } @@ -125,8 +128,14 @@ impl Kernel

{ self.threads.get(tid).ok().map(|t| t.saved_context()) } - pub fn thread_context_mut(&mut self, tid: ThreadId) -> Option<&mut domain::thread::SavedContext> { - self.threads.get_mut(tid).ok().map(|t| t.saved_context_mut()) + pub fn thread_context_mut( + &mut self, + tid: ThreadId, + ) -> Option<&mut domain::thread::SavedContext> { + self.threads + .get_mut(tid) + .ok() + .map(|t| t.saved_context_mut()) } pub fn thread_process(&self, tid: ThreadId) -> Option { @@ -147,21 +156,19 @@ impl Kernel

{ pub fn create_process_internal(&mut self) -> Option { let pid = self.processes.create(CapabilityTable::new(), None).ok()?; self.process_memory[pid.raw() as usize] = - Some(domain::memory::process_memory::ProcessMemory::new(pid, ProcessMemory::DEFAULT_PAGE_LIMIT)); + Some(domain::memory::process_memory::ProcessMemory::new( + pid, + ProcessMemory::DEFAULT_PAGE_LIMIT, + )); Some(pid) } - pub fn spawn_thread_internal( - &mut self, - pid: ProcessId, - ) -> Option { + pub fn spawn_thread_internal(&mut self, pid: ProcessId) -> Option { use domain::scheduler::Scheduler; - let tid = self.threads.spawn( - pid, - Priority::DEFAULT, - TimeSlice::DEFAULT, - None, - ).ok()?; + let tid = self + .threads + .spawn(pid, Priority::DEFAULT, TimeSlice::DEFAULT, None) + .ok()?; let _ = self.processes.get_mut(pid).map(|p| p.add_thread(tid)); let core = self.platform.core_id(); self.scheduler.add(tid, Priority::DEFAULT, core); @@ -208,7 +215,9 @@ impl Kernel

{ fn caller(&self) -> Result<(ThreadId, ProcessId), KernelError> { let core = self.platform.core_id(); - let tid = self.scheduler.current(core) + let tid = self + .scheduler + .current(core) .ok_or(KernelError::WouldBlock)?; let thread = self.threads.get(tid)?; match thread.state() { @@ -220,11 +229,14 @@ impl Kernel

{ pub(crate) fn destroy_process(&mut self, pid: ProcessId) { use domain::process::MAX_THREADS_PER_PROCESS; - let thread_ids: [Option; MAX_THREADS_PER_PROCESS] = match self.processes.get(pid) { + let thread_ids: [Option; MAX_THREADS_PER_PROCESS] = match self.processes.get(pid) + { Ok(p) => { let mut ids = [None; MAX_THREADS_PER_PROCESS]; for (i, tid) in p.thread_ids().enumerate() { - if i < MAX_THREADS_PER_PROCESS { ids[i] = Some(tid); } + if i < MAX_THREADS_PER_PROCESS { + ids[i] = Some(tid); + } } ids } diff --git a/crates/kernel/src/proofs/delegation.rs b/crates/kernel/src/proofs/delegation.rs index 596e9f2..250a772 100644 --- a/crates/kernel/src/proofs/delegation.rs +++ b/crates/kernel/src/proofs/delegation.rs @@ -1,6 +1,6 @@ +use super::{arbitrary_endpoint_cap, insert_cap}; use domain::capability::{Capability, CapabilityTable}; use domain::resource::Resource; -use super::{arbitrary_endpoint_cap, insert_cap}; use types::generation::Generation; use types::id::EndpointId; use types::permission::{Permission, PermissionSet}; @@ -16,17 +16,16 @@ fn kernel_delegate_path_never_escalates() { kani::assume(source_perms.allows(Permission::Delegate)); let mut source_table = CapabilityTable::new(); - let slot = insert_cap(&mut source_table, arbitrary_endpoint_cap(source_bits, ep_id)); + let slot = insert_cap( + &mut source_table, + arbitrary_endpoint_cap(source_bits, ep_id), + ); let cap = source_table.get(slot).unwrap(); let original_perms = *cap.permissions(); let restricted = original_perms.restrict_to(&PermissionSet::from_bits(restrict_bits)); - let delegated = Capability::new( - cap.resource().clone(), - restricted, - Generation::initial(), - ); + let delegated = Capability::new(cap.resource().clone(), restricted, Generation::initial()); let mut target_table = CapabilityTable::new(); let target_slot = insert_cap(&mut target_table, delegated); @@ -34,11 +33,21 @@ fn kernel_delegate_path_never_escalates() { let result = target_table.get(target_slot).unwrap(); assert!(result.permissions().is_subset_of(&original_perms)); - if !original_perms.allows(Permission::Read) { assert!(!result.permissions().allows(Permission::Read)); } - if !original_perms.allows(Permission::Write) { assert!(!result.permissions().allows(Permission::Write)); } - if !original_perms.allows(Permission::Execute) { assert!(!result.permissions().allows(Permission::Execute)); } - if !original_perms.allows(Permission::Delegate) { assert!(!result.permissions().allows(Permission::Delegate)); } - if !original_perms.allows(Permission::Revoke) { assert!(!result.permissions().allows(Permission::Revoke)); } + if !original_perms.allows(Permission::Read) { + assert!(!result.permissions().allows(Permission::Read)); + } + if !original_perms.allows(Permission::Write) { + assert!(!result.permissions().allows(Permission::Write)); + } + if !original_perms.allows(Permission::Execute) { + assert!(!result.permissions().allows(Permission::Execute)); + } + if !original_perms.allows(Permission::Delegate) { + assert!(!result.permissions().allows(Permission::Delegate)); + } + if !original_perms.allows(Permission::Revoke) { + assert!(!result.permissions().allows(Permission::Revoke)); + } } #[kani::proof] @@ -58,7 +67,9 @@ fn kernel_chained_delegate_never_escalates() { let slot_a = insert_cap(&mut table_a, arbitrary_endpoint_cap(original_bits, ep_id)); let cap = table_a.get(slot_a).unwrap(); - let perms_for_b = cap.permissions().restrict_to(&PermissionSet::from_bits(restrict1_bits)); + let perms_for_b = cap + .permissions() + .restrict_to(&PermissionSet::from_bits(restrict1_bits)); let mut table_b = CapabilityTable::new(); let cap_b = Capability::new(resource.clone(), perms_for_b, Generation::initial()); @@ -66,7 +77,9 @@ fn kernel_chained_delegate_never_escalates() { let cap_in_b = table_b.get(slot_b).unwrap(); if cap_in_b.permissions().allows(Permission::Delegate) { - let perms_for_c = cap_in_b.permissions().restrict_to(&PermissionSet::from_bits(restrict2_bits)); + let perms_for_c = cap_in_b + .permissions() + .restrict_to(&PermissionSet::from_bits(restrict2_bits)); let mut table_c = CapabilityTable::new(); let cap_c = Capability::new(resource, perms_for_c, Generation::initial()); diff --git a/crates/kernel/src/proofs/mediation.rs b/crates/kernel/src/proofs/mediation.rs index 04be40c..4c72ccf 100644 --- a/crates/kernel/src/proofs/mediation.rs +++ b/crates/kernel/src/proofs/mediation.rs @@ -1,5 +1,5 @@ -use domain::capability::CapabilityTable; use super::{arbitrary_endpoint_cap, insert_cap}; +use domain::capability::CapabilityTable; use types::bounded::CapSlot; use types::permission::{Permission, PermissionSet}; @@ -60,7 +60,11 @@ fn check_cap_faithfully_reflects_stored_permissions() { assert!(retrieved.permissions().allows(Permission::Read) == perms.allows(Permission::Read)); assert!(retrieved.permissions().allows(Permission::Write) == perms.allows(Permission::Write)); - assert!(retrieved.permissions().allows(Permission::Execute) == perms.allows(Permission::Execute)); - assert!(retrieved.permissions().allows(Permission::Delegate) == perms.allows(Permission::Delegate)); + assert!( + retrieved.permissions().allows(Permission::Execute) == perms.allows(Permission::Execute) + ); + assert!( + retrieved.permissions().allows(Permission::Delegate) == perms.allows(Permission::Delegate) + ); assert!(retrieved.permissions().allows(Permission::Revoke) == perms.allows(Permission::Revoke)); } diff --git a/crates/kernel/src/proofs/revocation.rs b/crates/kernel/src/proofs/revocation.rs index f928f0b..fe11da0 100644 --- a/crates/kernel/src/proofs/revocation.rs +++ b/crates/kernel/src/proofs/revocation.rs @@ -1,7 +1,7 @@ +use super::{arbitrary_endpoint_cap, insert_cap}; use domain::capability::{Capability, CapabilityTable}; use domain::endpoint::Endpoint; use domain::resource::Resource; -use super::{arbitrary_endpoint_cap, insert_cap}; use types::generation::Generation; use types::id::EndpointId; use types::permission::{Permission, PermissionSet}; @@ -81,12 +81,24 @@ fn generation_revocation_invalidates_all_caps() { let mut table = CapabilityTable::new(); let slot = insert_cap(&mut table, cap); - assert!(table.get(slot).unwrap().generation().is_valid_against(&original_gen)); + assert!( + table + .get(slot) + .unwrap() + .generation() + .is_valid_against(&original_gen) + ); endpoint.revoke(); let new_gen = *endpoint.generation(); - assert!(!table.get(slot).unwrap().generation().is_valid_against(&new_gen)); + assert!( + !table + .get(slot) + .unwrap() + .generation() + .is_valid_against(&new_gen) + ); } #[kani::proof] diff --git a/crates/kernel/src/syscall/capability.rs b/crates/kernel/src/syscall/capability.rs index 0db8596..06faa28 100644 --- a/crates/kernel/src/syscall/capability.rs +++ b/crates/kernel/src/syscall/capability.rs @@ -11,14 +11,11 @@ impl Kernel

{ to_endpoint: types::bounded::CapSlot, restrict: types::permission::PermissionSet, ) -> SyscallOutcome { - let (resource, permissions) = match self.check_cap( - caller_pid, - slot, - types::permission::Permission::Delegate, - ) { - Ok(cap) => (cap.resource().clone(), *cap.permissions()), - Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), - }; + let (resource, permissions) = + match self.check_cap(caller_pid, slot, types::permission::Permission::Delegate) { + Ok(cap) => (cap.resource().clone(), *cap.permissions()), + Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), + }; let restricted = permissions.restrict_to(&restrict); @@ -29,12 +26,14 @@ impl Kernel

{ ) { Ok(cap) => match cap.resource() { domain::resource::Resource::Process(pid) => *pid, - _ => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::PermissionDenied { - slot: to_endpoint, - needed: types::permission::Permission::Execute, - }, - )), + _ => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::PermissionDenied { + slot: to_endpoint, + needed: types::permission::Permission::Execute, + }, + )); + } }, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; @@ -45,12 +44,8 @@ impl Kernel

{ if let domain::resource::Resource::Memory(region_id) = &resource { if let Some(region) = self.regions.get(*region_id) { - self.platform.map_shared( - target_pid, - region.base(), - region.size(), - restricted, - ); + self.platform + .map_shared(target_pid, region.base(), region.size(), restricted); } } @@ -62,11 +57,8 @@ impl Kernel

{ caller_pid: types::id::ProcessId, slot: types::bounded::CapSlot, ) -> SyscallOutcome { - let resource = match self.check_cap( - caller_pid, - slot, - types::permission::Permission::Revoke, - ) { + let resource = match self.check_cap(caller_pid, slot, types::permission::Permission::Revoke) + { Ok(cap) => cap.resource().clone(), Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; diff --git a/crates/kernel/src/syscall/ipc.rs b/crates/kernel/src/syscall/ipc.rs index 105a9b3..51b4e9c 100644 --- a/crates/kernel/src/syscall/ipc.rs +++ b/crates/kernel/src/syscall/ipc.rs @@ -48,26 +48,34 @@ impl Kernel

{ ) { Ok(cap) => match cap.resource() { domain::resource::Resource::Endpoint(id) => *id, - _ => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::InvalidEndpoint(types::id::EndpointId::from_raw(0)), - )), + _ => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::InvalidEndpoint( + types::id::EndpointId::from_raw(0), + ), + )); + } }, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; let endpoint = match self.endpoints.get_mut(ep_id) { Some(ep) => ep, - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::InvalidEndpoint(ep_id), - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::InvalidEndpoint(ep_id), + )); + } }; if endpoint.has_waiting_receiver() { let receiver_tid = match endpoint.dequeue_receiver() { Some(t) => t, - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::WouldBlock, - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::WouldBlock, + )); + } }; self.pending_results[receiver_tid.raw() as usize] = @@ -98,9 +106,11 @@ impl Kernel

{ let endpoint = match self.endpoints.get_mut(ep_id) { Some(ep) => ep, - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::InvalidEndpoint(ep_id), - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::InvalidEndpoint(ep_id), + )); + } }; if endpoint.enqueue_sender(caller_tid).is_none() { self.pending_messages[caller_tid.raw() as usize] = None; @@ -135,30 +145,41 @@ impl Kernel

{ ) { Ok(cap) => match cap.resource() { domain::resource::Resource::Endpoint(id) => *id, - _ => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::InvalidEndpoint(types::id::EndpointId::from_raw(0)), - )), + _ => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::InvalidEndpoint( + types::id::EndpointId::from_raw(0), + ), + )); + } }, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; let endpoint = match self.endpoints.get_mut(ep_id) { Some(ep) => ep, - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::InvalidEndpoint(ep_id), - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::InvalidEndpoint(ep_id), + )); + } }; if endpoint.has_waiting_sender() { let sender_tid = match endpoint.dequeue_sender() { Some(t) => t, - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::WouldBlock, - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::WouldBlock, + )); + } }; let message = self.pending_messages[sender_tid.raw() as usize].take(); - debug_assert!(message.is_some(), "sender in wait queue had no pending message"); + debug_assert!( + message.is_some(), + "sender in wait queue had no pending message" + ); let message = message.unwrap_or_else(|| domain::message::Message::empty()); self.pending_results[sender_tid.raw() as usize] = Some(SyscallResult::Ok); @@ -176,9 +197,11 @@ impl Kernel

{ } else { let endpoint = match self.endpoints.get_mut(ep_id) { Some(ep) => ep, - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::InvalidEndpoint(ep_id), - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::InvalidEndpoint(ep_id), + )); + } }; if endpoint.enqueue_receiver(caller_tid).is_none() { return SyscallOutcome::Complete(SyscallResult::Error( @@ -205,16 +228,15 @@ impl Kernel

{ ) -> SyscallOutcome { use domain::scheduler::Scheduler; - let irq_id = match self.check_cap( - caller_pid, - irq_slot, - types::permission::Permission::Read, - ) { + let irq_id = match self.check_cap(caller_pid, irq_slot, types::permission::Permission::Read) + { Ok(cap) => match cap.resource() { domain::resource::Resource::Interrupt(id) => *id, - _ => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::InvalidIrq(types::id::IrqId::from_raw(0)), - )), + _ => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::InvalidIrq(types::id::IrqId::from_raw(0)), + )); + } }, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; @@ -236,19 +258,18 @@ impl Kernel

{ caller_pid: types::id::ProcessId, irq_slot: types::bounded::CapSlot, ) -> SyscallOutcome { - let irq_id = match self.check_cap( - caller_pid, - irq_slot, - types::permission::Permission::Write, - ) { - Ok(cap) => match cap.resource() { - domain::resource::Resource::Interrupt(id) => *id, - _ => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::InvalidIrq(types::id::IrqId::from_raw(0)), - )), - }, - Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), - }; + let irq_id = + match self.check_cap(caller_pid, irq_slot, types::permission::Permission::Write) { + Ok(cap) => match cap.resource() { + domain::resource::Resource::Interrupt(id) => *id, + _ => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::InvalidIrq(types::id::IrqId::from_raw(0)), + )); + } + }, + Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), + }; self.platform.unmask_irq(irq_id); SyscallOutcome::Complete(SyscallResult::Ok) @@ -270,17 +291,14 @@ impl Kernel

{ for ep_slot in sources.endpoints() { if let Some(slot) = ep_slot { - let ep_id = match self.check_cap( - caller_pid, - *slot, - types::permission::Permission::Read, - ) { - Ok(cap) => match cap.resource() { - domain::resource::Resource::Endpoint(id) => *id, - _ => continue, - }, - Err(_) => continue, - }; + let ep_id = + match self.check_cap(caller_pid, *slot, types::permission::Permission::Read) { + Ok(cap) => match cap.resource() { + domain::resource::Resource::Endpoint(id) => *id, + _ => continue, + }, + Err(_) => continue, + }; if let Some(ep) = self.endpoints.get_mut(ep_id) { if ep.has_waiting_sender() { @@ -294,11 +312,9 @@ impl Kernel

{ for irq_slot in sources.interrupts() { if let Some(slot) = irq_slot { - if let Ok(cap) = self.check_cap( - caller_pid, - *slot, - types::permission::Permission::Read, - ) { + if let Ok(cap) = + self.check_cap(caller_pid, *slot, types::permission::Permission::Read) + { if let domain::resource::Resource::Interrupt(irq_id) = cap.resource() { if self.irqs.owner(*irq_id).is_some() { return SyscallOutcome::Complete(SyscallResult::WakeReason( @@ -312,7 +328,9 @@ impl Kernel

{ for ep_slot in sources.endpoints() { if let Some(slot) = ep_slot { - if let Ok(cap) = self.check_cap(caller_pid, *slot, types::permission::Permission::Read) { + if let Ok(cap) = + self.check_cap(caller_pid, *slot, types::permission::Permission::Read) + { if let domain::resource::Resource::Endpoint(id) = cap.resource() { if let Some(ep) = self.endpoints.get_mut(*id) { let _ = ep.enqueue_receiver(caller_tid); diff --git a/crates/kernel/src/syscall/lifecycle.rs b/crates/kernel/src/syscall/lifecycle.rs index b658a03..a2f4264 100644 --- a/crates/kernel/src/syscall/lifecycle.rs +++ b/crates/kernel/src/syscall/lifecycle.rs @@ -18,7 +18,10 @@ impl Kernel

{ let time_slice = types::time::TimeSlice::DEFAULT; let context = SavedContext::with_entry_and_stack(entry, stack); - let tid = match self.threads.spawn_with_context(pid, priority, time_slice, None, context) { + let tid = match self + .threads + .spawn_with_context(pid, priority, time_slice, None, context) + { Ok(t) => t, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; @@ -39,20 +42,27 @@ impl Kernel

{ create_cap: types::bounded::CapSlot, _image: types::address::DataRef, ) -> SyscallOutcome { - if let Err(e) = self.check_cap(caller_pid, create_cap, types::permission::Permission::Execute) { + if let Err(e) = self.check_cap( + caller_pid, + create_cap, + types::permission::Permission::Execute, + ) { return SyscallOutcome::Complete(SyscallResult::Error(e)); } - let new_pid = match self.processes.create( - domain::capability::CapabilityTable::new(), - None, - ) { + let new_pid = match self + .processes + .create(domain::capability::CapabilityTable::new(), None) + { Ok(p) => p, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; self.process_memory[new_pid.raw() as usize] = - Some(domain::memory::process_memory::ProcessMemory::new(new_pid, domain::memory::process_memory::ProcessMemory::DEFAULT_PAGE_LIMIT)); + Some(domain::memory::process_memory::ProcessMemory::new( + new_pid, + domain::memory::process_memory::ProcessMemory::DEFAULT_PAGE_LIMIT, + )); match self.grant_cap( caller_pid, @@ -88,12 +98,14 @@ impl Kernel

{ ) { Ok(cap) => match cap.resource() { domain::resource::Resource::Process(pid) => *pid, - _ => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::PermissionDenied { - slot: process_cap, - needed: types::permission::Permission::Execute, - }, - )), + _ => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::PermissionDenied { + slot: process_cap, + needed: types::permission::Permission::Execute, + }, + )); + } }, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; @@ -102,12 +114,19 @@ impl Kernel

{ let time_slice = types::time::TimeSlice::DEFAULT; let context = SavedContext::with_entry_and_stack(entry, stack); - let tid = match self.threads.spawn_with_context(target_pid, priority, time_slice, None, context) { + let tid = match self + .threads + .spawn_with_context(target_pid, priority, time_slice, None, context) + { Ok(t) => t, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; - if let Err(e) = self.processes.get_mut(target_pid).and_then(|p| p.add_thread(tid)) { + if let Err(e) = self + .processes + .get_mut(target_pid) + .and_then(|p| p.add_thread(tid)) + { let _ = self.threads.destroy(tid); return SyscallOutcome::Complete(SyscallResult::Error(e)); } @@ -122,15 +141,21 @@ impl Kernel

{ caller_pid: types::id::ProcessId, process_cap: types::bounded::CapSlot, ) -> SyscallOutcome { - let target_pid = match self.check_cap(caller_pid, process_cap, types::permission::Permission::Execute) { + let target_pid = match self.check_cap( + caller_pid, + process_cap, + types::permission::Permission::Execute, + ) { Ok(cap) => match cap.resource() { domain::resource::Resource::Process(pid) => *pid, - _ => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::PermissionDenied { - slot: process_cap, - needed: types::permission::Permission::Execute, - }, - )), + _ => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::PermissionDenied { + slot: process_cap, + needed: types::permission::Permission::Execute, + }, + )); + } }, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; diff --git a/crates/kernel/src/syscall/memory.rs b/crates/kernel/src/syscall/memory.rs index 02297a5..5b6f7bf 100644 --- a/crates/kernel/src/syscall/memory.rs +++ b/crates/kernel/src/syscall/memory.rs @@ -22,9 +22,11 @@ impl Kernel

{ )); } } - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::InvalidProcess(pid), - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::InvalidProcess(pid), + )); + } } let phys_addr = match self.page_pool.allocate(pages) { @@ -56,7 +58,8 @@ impl Kernel

{ for i in 0..pages { let page_va = VirtualAddress::from_raw(user_va.raw() + i * 4096); let page_pa = PhysicalAddress::from_raw(phys_addr.raw() + i * 4096); - self.platform.map_user_page(pid, page_va, page_pa, true, false); + self.platform + .map_user_page(pid, page_va, page_pa, true, false); } let region = domain::memory::MemoryRegion::new( @@ -96,24 +99,29 @@ impl Kernel

{ ) { Ok(cap) => match cap.resource() { domain::resource::Resource::Process(pid) => *pid, - _ => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::PermissionDenied { - slot: process_cap, - needed: types::permission::Permission::Execute, - }, - )), + _ => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::PermissionDenied { + slot: process_cap, + needed: types::permission::Permission::Execute, + }, + )); + } }, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; let pa = match self.platform.translate_va(caller_pid, src_va) { Some(pa) => pa, - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::OutOfMemory, - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::OutOfMemory, + )); + } }; - self.platform.map_user_page(target_pid, dst_va, pa, !executable, executable); + self.platform + .map_user_page(target_pid, dst_va, pa, !executable, executable); SyscallOutcome::Complete(SyscallResult::Ok) } @@ -127,16 +135,20 @@ impl Kernel

{ let pages = count.value() as usize; let phys = match self.platform.translate_va(pid, addr) { Some(pa) => pa, - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::OutOfMemory, - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::OutOfMemory, + )); + } }; let region_id = match self.regions.find_by_base(pid, phys) { Some((rid, _)) => rid, - None => return SyscallOutcome::Complete(SyscallResult::Error( - domain::error::KernelError::OutOfMemory, - )), + None => { + return SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::OutOfMemory, + )); + } }; if !self.page_pool.free(phys, pages) { diff --git a/crates/kernel/src/syscall/mod.rs b/crates/kernel/src/syscall/mod.rs index 88bf343..4223120 100644 --- a/crates/kernel/src/syscall/mod.rs +++ b/crates/kernel/src/syscall/mod.rs @@ -43,12 +43,16 @@ impl Kernel

{ Syscall::RequestPages { count } => self.handle_request_pages(pid, count), Syscall::ReleasePages { addr, count } => self.handle_release_pages(pid, addr, count), Syscall::SpawnThread { entry, stack } => self.handle_spawn_thread(pid, entry, stack), - Syscall::CreateProcess { create_cap, image } => self.handle_create_process(pid, create_cap, image), + Syscall::CreateProcess { create_cap, image } => { + self.handle_create_process(pid, create_cap, image) + } Syscall::Kill { process } => self.handle_kill(pid, process), Syscall::Revoke { slot } => self.handle_revoke(pid, slot), - Syscall::Delegate { slot, to_endpoint, permissions } => { - self.handle_delegate(pid, slot, to_endpoint, permissions) - } + Syscall::Delegate { + slot, + to_endpoint, + permissions, + } => self.handle_delegate(pid, slot, to_endpoint, permissions), Syscall::Send { endpoint, message } => self.handle_send(tid, pid, endpoint, message), Syscall::Receive { endpoint } => self.handle_receive(tid, pid, endpoint), Syscall::WaitForInterrupt { irq } => self.handle_wait_for_interrupt(tid, pid, irq), @@ -57,12 +61,17 @@ impl Kernel

{ Syscall::Halt => self.handle_halt(pid), Syscall::CreateEndpoint => self.handle_create_endpoint(pid), Syscall::DebugPutchar { byte } => self.handle_debug_putchar(byte), - Syscall::MapPage { process, src_va, dst_va, executable } => { - self.handle_map_page(pid, process, src_va, dst_va, executable) - } - Syscall::SpawnThreadIn { process, entry, stack } => { - self.handle_spawn_thread_in(pid, process, entry, stack) - } + Syscall::MapPage { + process, + src_va, + dst_va, + executable, + } => self.handle_map_page(pid, process, src_va, dst_va, executable), + Syscall::SpawnThreadIn { + process, + entry, + stack, + } => self.handle_spawn_thread_in(pid, process, entry, stack), } } } diff --git a/crates/kernel/src/syscall/simple.rs b/crates/kernel/src/syscall/simple.rs index 1ea7ec6..110bf1c 100644 --- a/crates/kernel/src/syscall/simple.rs +++ b/crates/kernel/src/syscall/simple.rs @@ -31,15 +31,26 @@ impl Kernel

{ match self.scheduler.next(core) { Some(next) if next != caller_tid => { - if self.threads.get_mut(next).and_then(|t| t.set_running(core)).is_ok() { + if self + .threads + .get_mut(next) + .and_then(|t| t.set_running(core)) + .is_ok() + { SyscallOutcome::SwitchTo(next) } else { - let _ = self.threads.get_mut(caller_tid).map(|t| t.set_running(core)); + let _ = self + .threads + .get_mut(caller_tid) + .map(|t| t.set_running(core)); SyscallOutcome::Complete(SyscallResult::Ok) } } _ => { - let _ = self.threads.get_mut(caller_tid).map(|t| t.set_running(core)); + let _ = self + .threads + .get_mut(caller_tid) + .map(|t| t.set_running(core)); SyscallOutcome::Complete(SyscallResult::Ok) } } @@ -79,10 +90,7 @@ impl Kernel

{ SyscallOutcome::Complete(SyscallResult::Ok) } - pub(crate) fn handle_halt( - &mut self, - pid: types::id::ProcessId, - ) -> SyscallOutcome { + pub(crate) fn handle_halt(&mut self, pid: types::id::ProcessId) -> SyscallOutcome { if pid.raw() != 0 { return SyscallOutcome::Complete(SyscallResult::Error( domain::error::KernelError::ProcessCreateDenied, diff --git a/crates/kernel/src/tests/capability.rs b/crates/kernel/src/tests/capability.rs index e62dc1b..0a61f78 100644 --- a/crates/kernel/src/tests/capability.rs +++ b/crates/kernel/src/tests/capability.rs @@ -2,9 +2,9 @@ use super::*; use crate::{SyscallOutcome, SyscallResult}; use domain::resource::Resource; use domain::syscall::Syscall; +use types::address::DataRef; use types::bounded::CapSlot; use types::permission::{Permission, PermissionSet}; -use types::address::DataRef; #[test] fn delegate_without_delegate_permission_fails() { @@ -75,7 +75,9 @@ fn revoke_resource_invalidates_all_caps() { let outcome = k.handle_syscall(Syscall::Receive { endpoint: cap_slot }); assert!(matches!( outcome, - SyscallOutcome::Complete(SyscallResult::Error(domain::error::KernelError::RevokedCapability(_))) + SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::RevokedCapability(_) + )) )); } @@ -97,7 +99,9 @@ fn new_cap_after_revoke_uses_current_generation() { let outcome = k.handle_syscall(Syscall::Receive { endpoint: old_slot }); assert!(matches!( outcome, - SyscallOutcome::Complete(SyscallResult::Error(domain::error::KernelError::RevokedCapability(_))) + SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::RevokedCapability(_) + )) )); // New cap with current generation works @@ -136,7 +140,9 @@ fn revoke_does_not_affect_other_resources() { let outcome = k.handle_syscall(Syscall::Receive { endpoint: slot1 }); assert!(matches!( outcome, - SyscallOutcome::Complete(SyscallResult::Error(domain::error::KernelError::RevokedCapability(_))) + SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::RevokedCapability(_) + )) )); // ep2 cap still works @@ -159,13 +165,18 @@ fn revoke_syscall_invalidates_via_generation() { // Revoke via syscall let outcome = k.handle_syscall(Syscall::Revoke { slot: cap_slot }); - assert!(matches!(outcome, SyscallOutcome::Complete(SyscallResult::Ok))); + assert!(matches!( + outcome, + SyscallOutcome::Complete(SyscallResult::Ok) + )); // The cap itself is now revoked (generation mismatch) let outcome = k.handle_syscall(Syscall::Receive { endpoint: cap_slot }); assert!(matches!( outcome, - SyscallOutcome::Complete(SyscallResult::Error(domain::error::KernelError::RevokedCapability(_))) + SyscallOutcome::Complete(SyscallResult::Error( + domain::error::KernelError::RevokedCapability(_) + )) )); } diff --git a/crates/kernel/src/tests/helpers.rs b/crates/kernel/src/tests/helpers.rs index b46291f..7e3153e 100644 --- a/crates/kernel/src/tests/helpers.rs +++ b/crates/kernel/src/tests/helpers.rs @@ -11,8 +11,8 @@ use types::{ time::TimeSlice, }; -use crate::Kernel; use super::mock_platform::MockPlatform; +use crate::Kernel; pub fn test_kernel() -> Kernel { let mock = MockPlatform::new(1); @@ -22,9 +22,7 @@ pub fn test_kernel() -> Kernel { pub fn kernel_with_process() -> (Kernel, ProcessId) { let mut kernel = test_kernel(); - let (pid, _tid) = kernel - .boot(Priority::DEFAULT, TimeSlice::DEFAULT) - .unwrap(); + let (pid, _tid) = kernel.boot(Priority::DEFAULT, TimeSlice::DEFAULT).unwrap(); (kernel, pid) } @@ -35,7 +33,10 @@ impl Kernel { priority: Priority, time_slice: TimeSlice, ) -> ThreadId { - let tid = self.threads.spawn(pid, priority, time_slice, None).expect("spawn"); + let tid = self + .threads + .spawn(pid, priority, time_slice, None) + .expect("spawn"); let _ = self.processes.get_mut(pid).map(|p| p.add_thread(tid)); let core = self.platform.core_id(); self.scheduler.add(tid, priority, core); @@ -46,11 +47,7 @@ impl Kernel { let _ = self.irqs.register(irq, thread); } - pub fn block_thread_for_test( - &mut self, - tid: ThreadId, - reason: domain::thread::BlockReason, - ) { + pub fn block_thread_for_test(&mut self, tid: ThreadId, reason: domain::thread::BlockReason) { let core = self.platform.core_id(); if let Ok(t) = self.threads.get_mut(tid) { if matches!(t.state(), ThreadState::Ready) { @@ -95,6 +92,7 @@ impl Kernel { resource: Resource, permissions: PermissionSet, ) -> CapSlot { - self.grant_cap(pid, resource, permissions).expect("grant cap") + self.grant_cap(pid, resource, permissions) + .expect("grant cap") } } diff --git a/crates/kernel/src/tests/ipc.rs b/crates/kernel/src/tests/ipc.rs index 29c6baa..882298a 100644 --- a/crates/kernel/src/tests/ipc.rs +++ b/crates/kernel/src/tests/ipc.rs @@ -9,11 +9,11 @@ use types::permission::{Permission, PermissionSet}; fn setup_ipc_kernel() -> ( crate::Kernel, - ProcessId, // process A - ProcessId, // process B - CapSlot, // endpoint cap for A (Execute perm) - CapSlot, // endpoint cap for B (Read perm) - ThreadId, // thread B id + ProcessId, // process A + ProcessId, // process B + CapSlot, // endpoint cap for A (Execute perm) + CapSlot, // endpoint cap for B (Read perm) + ThreadId, // thread B id ) { let (mut k, pid_a) = kernel_with_process(); @@ -27,11 +27,7 @@ fn setup_ipc_kernel() -> ( }; let pid_b = ProcessId::from_raw(1); - let tid_b = k.spawn_thread_for_test( - pid_b, - Priority::DEFAULT, - TimeSlice::DEFAULT, - ); + let tid_b = k.spawn_thread_for_test(pid_b, Priority::DEFAULT, TimeSlice::DEFAULT); // Create an endpoint let ep_id = k.create_endpoint_for_test(); @@ -65,7 +61,10 @@ fn send_without_receiver_blocks_caller() { endpoint: cap_a, message: msg, }); - assert!(matches!(outcome, SyscallOutcome::BlockCaller(BlockReason::Sending(_)))); + assert!(matches!( + outcome, + SyscallOutcome::BlockCaller(BlockReason::Sending(_)) + )); } #[test] @@ -75,10 +74,11 @@ fn receive_without_sender_blocks_caller() { // Switch to thread B to call Receive k.switch_to_thread_for_test(tid_b); - let outcome = k.handle_syscall(Syscall::Receive { - endpoint: cap_b, - }); - assert!(matches!(outcome, SyscallOutcome::BlockCaller(BlockReason::Receiving(_)))); + let outcome = k.handle_syscall(Syscall::Receive { endpoint: cap_b }); + assert!(matches!( + outcome, + SyscallOutcome::BlockCaller(BlockReason::Receiving(_)) + )); } #[test] @@ -196,10 +196,7 @@ fn wait_any_with_ready_source_returns_immediately() { // Thread A does WaitAny on the endpoint k.switch_to_thread_for_test(tid_a); - let wait_set = WaitSet::new( - [Some(cap_a), None, None, None], - [None, None, None, None], - ); + let wait_set = WaitSet::new([Some(cap_a), None, None, None], [None, None, None, None]); let outcome = k.handle_syscall(Syscall::WaitAny { sources: wait_set }); assert!(matches!( outcome, @@ -210,10 +207,7 @@ fn wait_any_with_ready_source_returns_immediately() { #[test] fn wait_any_with_no_ready_source_blocks() { let (mut k, pid_a, _, cap_a, _, _) = setup_ipc_kernel(); - let wait_set = WaitSet::new( - [Some(cap_a), None, None, None], - [None, None, None, None], - ); + let wait_set = WaitSet::new([Some(cap_a), None, None, None], [None, None, None, None]); let outcome = k.handle_syscall(Syscall::WaitAny { sources: wait_set }); assert!(matches!( outcome, @@ -224,10 +218,7 @@ fn wait_any_with_no_ready_source_blocks() { #[test] fn wait_any_empty_sources_returns_error() { let (mut k, _, _, _, _, _) = setup_ipc_kernel(); - let wait_set = WaitSet::new( - [None, None, None, None], - [None, None, None, None], - ); + let wait_set = WaitSet::new([None, None, None, None], [None, None, None, None]); let outcome = k.handle_syscall(Syscall::WaitAny { sources: wait_set }); assert!(matches!( outcome, diff --git a/crates/kernel/src/tests/memory.rs b/crates/kernel/src/tests/memory.rs index e96b041..5e74f6b 100644 --- a/crates/kernel/src/tests/memory.rs +++ b/crates/kernel/src/tests/memory.rs @@ -1,8 +1,8 @@ use super::*; use crate::{SyscallOutcome, SyscallResult}; use domain::syscall::Syscall; -use types::bounded::PageCount; use types::address::VirtualAddress; +use types::bounded::PageCount; #[test] fn request_pages_returns_user_va() { diff --git a/crates/kernel/src/tests/mock_platform.rs b/crates/kernel/src/tests/mock_platform.rs index 06575c3..e3e3cd6 100644 --- a/crates/kernel/src/tests/mock_platform.rs +++ b/crates/kernel/src/tests/mock_platform.rs @@ -44,14 +44,29 @@ impl Platform for MockPlatform { loop {} } fn set_timer(&mut self, _duration: TimerDuration) {} - fn current_ticks(&self) -> Ticks { self.ticks } + fn current_ticks(&self) -> Ticks { + self.ticks + } fn mask_irq(&mut self, _irq: IrqId) {} fn unmask_irq(&mut self, _irq: IrqId) {} fn send_ipi(&mut self, _target: CoreId) {} - fn core_id(&self) -> CoreId { self.core } - fn num_cores(&self) -> u8 { self.cores } - fn map_shared(&mut self, _process: ProcessId, _base: PhysicalAddress, _size: PageCount, _permissions: PermissionSet) {} - fn halt(&self) -> ! { loop {} } + fn core_id(&self) -> CoreId { + self.core + } + fn num_cores(&self) -> u8 { + self.cores + } + fn map_shared( + &mut self, + _process: ProcessId, + _base: PhysicalAddress, + _size: PageCount, + _permissions: PermissionSet, + ) { + } + fn halt(&self) -> ! { + loop {} + } fn debug_putchar(&self, _byte: u8) {} fn translate_va(&self, process: ProcessId, va: VirtualAddress) -> Option { @@ -65,10 +80,21 @@ impl Platform for MockPlatform { None } - fn map_user_page(&mut self, process: ProcessId, va: VirtualAddress, pa: PhysicalAddress, _writable: bool, _executable: bool) { + fn map_user_page( + &mut self, + process: ProcessId, + va: VirtualAddress, + pa: PhysicalAddress, + _writable: bool, + _executable: bool, + ) { for slot in &mut self.mappings { if slot.is_none() { - *slot = Some(PageMapping { process, va: va.raw(), pa: pa.raw() }); + *slot = Some(PageMapping { + process, + va: va.raw(), + pa: pa.raw(), + }); return; } } diff --git a/crates/kernel/src/tests/mod.rs b/crates/kernel/src/tests/mod.rs index eec506d..c477364 100644 --- a/crates/kernel/src/tests/mod.rs +++ b/crates/kernel/src/tests/mod.rs @@ -1,5 +1,5 @@ -mod mock_platform; mod helpers; +mod mock_platform; mod capability; mod exit; @@ -9,12 +9,12 @@ mod memory; mod simple; mod tick; +pub use helpers::{kernel_with_process, test_kernel}; pub use mock_platform::MockPlatform; -pub use helpers::{test_kernel, kernel_with_process}; pub use crate::Kernel; +pub use domain::memory::page_pool::PagePool; pub use types::address::PhysicalAddress; pub use types::bounded::Priority; pub use types::id::ProcessId; pub use types::time::TimeSlice; -pub use domain::memory::page_pool::PagePool; diff --git a/crates/kernel/src/tests/tick.rs b/crates/kernel/src/tests/tick.rs index dffe3a9..ad5d92f 100644 --- a/crates/kernel/src/tests/tick.rs +++ b/crates/kernel/src/tests/tick.rs @@ -46,9 +46,10 @@ fn interrupt_unblocks_registered_thread() { // Register and block the thread on this IRQ k.register_irq_for_test(irq, tid); - k.block_thread_for_test(tid, domain::thread::BlockReason::WaitingForInterrupt( - types::bounded::CapSlot::new(0).unwrap() - )); + k.block_thread_for_test( + tid, + domain::thread::BlockReason::WaitingForInterrupt(types::bounded::CapSlot::new(0).unwrap()), + ); let result = k.handle_interrupt(irq); assert_eq!(result, Some(tid)); diff --git a/crates/platform/src/lib.rs b/crates/platform/src/lib.rs index 050f98f..7111d41 100644 --- a/crates/platform/src/lib.rs +++ b/crates/platform/src/lib.rs @@ -29,5 +29,12 @@ pub trait Platform { fn halt(&self) -> !; fn debug_putchar(&self, byte: u8); fn translate_va(&self, process: ProcessId, va: VirtualAddress) -> Option; - fn map_user_page(&mut self, process: ProcessId, va: VirtualAddress, pa: PhysicalAddress, writable: bool, executable: bool); + fn map_user_page( + &mut self, + process: ProcessId, + va: VirtualAddress, + pa: PhysicalAddress, + writable: bool, + executable: bool, + ); } diff --git a/crates/types/src/bounded.rs b/crates/types/src/bounded.rs index 0c9635f..0fffd39 100644 --- a/crates/types/src/bounded.rs +++ b/crates/types/src/bounded.rs @@ -7,4 +7,3 @@ bounded!(PageCount, u16, 1, 1024); impl Priority { pub const DEFAULT: Self = Self(16); } - diff --git a/crates/types/src/display.rs b/crates/types/src/display.rs index 387567b..f135d25 100644 --- a/crates/types/src/display.rs +++ b/crates/types/src/display.rs @@ -2,8 +2,12 @@ pub struct Color(u32); impl Color { - pub const fn from_raw(v: u32) -> Self { Self(v) } - pub const fn raw(&self) -> u32 { self.0 } + pub const fn from_raw(v: u32) -> Self { + Self(v) + } + pub const fn raw(&self) -> u32 { + self.0 + } pub const fn rgb(r: u8, g: u8, b: u8) -> Self { Self(((r as u32) << 16) | ((g as u32) << 8) | (b as u32) | 0xFF000000) @@ -18,19 +22,29 @@ impl Color { pub struct ScreenCoord(u16); impl ScreenCoord { - pub const fn new(v: u16) -> Self { Self(v) } - pub const fn raw(&self) -> u16 { self.0 } + pub const fn new(v: u16) -> Self { + Self(v) + } + pub const fn raw(&self) -> u16 { + self.0 + } } impl core::ops::Add for ScreenCoord { type Output = Self; - fn add(self, rhs: Dimension) -> Self { Self(self.0 + rhs.0) } + fn add(self, rhs: Dimension) -> Self { + Self(self.0 + rhs.0) + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Dimension(u16); impl Dimension { - pub const fn new(v: u16) -> Self { Self(v) } - pub const fn raw(&self) -> u16 { self.0 } + pub const fn new(v: u16) -> Self { + Self(v) + } + pub const fn raw(&self) -> u16 { + self.0 + } } diff --git a/crates/types/src/macros.rs b/crates/types/src/macros.rs index e893f13..c3bd861 100644 --- a/crates/types/src/macros.rs +++ b/crates/types/src/macros.rs @@ -33,7 +33,10 @@ macro_rules! bounded { } pub const fn const_new(value: $inner) -> Self { - assert!(value >= Self::MIN && value <= Self::MAX, "bounded value out of range"); + assert!( + value >= Self::MIN && value <= Self::MAX, + "bounded value out of range" + ); Self(value) }