From 014babe444dd2aa26e65402c82d8c0c805ce732b Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 17 Feb 2025 11:02:36 -0800 Subject: [PATCH] fmt --- bootloader/bootloader/src/arch/x86/mod.rs | 34 +-- bootloader/bootloader/src/arch/x86/x32.rs | 124 ++++----- bootloader/bootloader/src/arch/x86/x64.rs | 206 +++++++-------- bootloader/bootloader/src/os/bios/disk.rs | 246 +++++++++--------- .../bootloader/src/os/bios/memory_map.rs | 114 ++++---- bootloader/bootloader/src/os/bios/thunk.rs | 62 ++--- bootloader/bootloader/src/os/bios/vbe.rs | 226 ++++++++-------- bootloader/bootloader/src/os/bios/vga.rs | 190 +++++++------- bootloader/bootloader/src/serial_16550.rs | 206 +++++++-------- 9 files changed, 704 insertions(+), 704 deletions(-) diff --git a/bootloader/bootloader/src/arch/x86/mod.rs b/bootloader/bootloader/src/arch/x86/mod.rs index 5a705e6..3b2c49e 100644 --- a/bootloader/bootloader/src/arch/x86/mod.rs +++ b/bootloader/bootloader/src/arch/x86/mod.rs @@ -6,26 +6,26 @@ pub(crate) mod x32; pub(crate) mod x64; pub unsafe fn paging_create>( - os: &dyn Os, - kernel_phys: u64, - kernel_size: u64, + os: &dyn Os, + kernel_phys: u64, + kernel_size: u64, ) -> Option { - if crate::KERNEL_64BIT { - x64::paging_create(os, kernel_phys, kernel_size) - } else { - x32::paging_create(os, kernel_phys, kernel_size) - } + if crate::KERNEL_64BIT { + x64::paging_create(os, kernel_phys, kernel_size) + } else { + x32::paging_create(os, kernel_phys, kernel_size) + } } pub unsafe fn paging_framebuffer>( - os: &dyn Os, - page_phys: usize, - framebuffer_phys: u64, - framebuffer_size: u64, + os: &dyn Os, + page_phys: usize, + framebuffer_phys: u64, + framebuffer_size: u64, ) -> Option { - if crate::KERNEL_64BIT { - x64::paging_framebuffer(os, page_phys, framebuffer_phys, framebuffer_size) - } else { - x32::paging_framebuffer(os, page_phys, framebuffer_phys, framebuffer_size) - } + if crate::KERNEL_64BIT { + x64::paging_framebuffer(os, page_phys, framebuffer_phys, framebuffer_size) + } else { + x32::paging_framebuffer(os, page_phys, framebuffer_phys, framebuffer_size) + } } diff --git a/bootloader/bootloader/src/arch/x86/x32.rs b/bootloader/bootloader/src/arch/x86/x32.rs index 6be56a2..536bad2 100644 --- a/bootloader/bootloader/src/arch/x86/x32.rs +++ b/bootloader/bootloader/src/arch/x86/x32.rs @@ -8,82 +8,82 @@ const PAGE_SIZE: usize = 4096; pub(crate) const PHYS_OFFSET: u32 = 0x8000_0000; unsafe fn paging_allocate>( - os: &dyn Os, + os: &dyn Os, ) -> Option<&'static mut [u32]> { - let ptr = os.alloc_zeroed_page_aligned(PAGE_SIZE); - if !ptr.is_null() { - area_add(OsMemoryEntry { - base: ptr as u64, - size: PAGE_SIZE as u64, - kind: OsMemoryKind::Reclaim, - }); - Some(slice::from_raw_parts_mut(ptr as *mut u32, PAGE_ENTRIES)) - } else { - None - } + let ptr = os.alloc_zeroed_page_aligned(PAGE_SIZE); + if !ptr.is_null() { + area_add(OsMemoryEntry { + base: ptr as u64, + size: PAGE_SIZE as u64, + kind: OsMemoryKind::Reclaim, + }); + Some(slice::from_raw_parts_mut(ptr as *mut u32, PAGE_ENTRIES)) + } else { + None + } } pub unsafe fn paging_create>( - os: &dyn Os, - kernel_phys: u64, - kernel_size: u64, + os: &dyn Os, + kernel_phys: u64, + kernel_size: u64, ) -> Option { - let pd = paging_allocate(os)?; - //Identity map 1 GiB using 4 MiB pages, also map at PHYS_OFFSET - for pd_i in 0..256 { - let addr = pd_i as u32 * 0x40_0000; - pd[pd_i] = addr | 1 << 7 | 1 << 1 | 1; - pd[pd_i + 512] = addr | 1 << 7 | 1 << 1 | 1; - } + let pd = paging_allocate(os)?; + //Identity map 1 GiB using 4 MiB pages, also map at PHYS_OFFSET + for pd_i in 0..256 { + let addr = pd_i as u32 * 0x40_0000; + pd[pd_i] = addr | 1 << 7 | 1 << 1 | 1; + pd[pd_i + 512] = addr | 1 << 7 | 1 << 1 | 1; + } - // Map kernel_size at kernel offset - let mut kernel_mapped = 0; - let mut pd_i = 0xC000_0000 / 0x40_0000; - while kernel_mapped < kernel_size && pd_i < pd.len() { - let pt = paging_allocate(os)?; - pd[pd_i] = pt.as_ptr() as u32 | 1 << 1 | 1; - pd_i += 1; + // Map kernel_size at kernel offset + let mut kernel_mapped = 0; + let mut pd_i = 0xC000_0000 / 0x40_0000; + while kernel_mapped < kernel_size && pd_i < pd.len() { + let pt = paging_allocate(os)?; + pd[pd_i] = pt.as_ptr() as u32 | 1 << 1 | 1; + pd_i += 1; - let mut pt_i = 0; - while kernel_mapped < kernel_size && pt_i < pt.len() { - let addr = kernel_phys + kernel_mapped; - pt[pt_i] = addr as u32 | 1 << 1 | 1; - pt_i += 1; - kernel_mapped += PAGE_SIZE as u64; - } - } - assert!(kernel_mapped >= kernel_size); + let mut pt_i = 0; + while kernel_mapped < kernel_size && pt_i < pt.len() { + let addr = kernel_phys + kernel_mapped; + pt[pt_i] = addr as u32 | 1 << 1 | 1; + pt_i += 1; + kernel_mapped += PAGE_SIZE as u64; + } + } + assert!(kernel_mapped >= kernel_size); - Some(pd.as_ptr() as usize) + Some(pd.as_ptr() as usize) } pub unsafe fn paging_framebuffer>( - os: &dyn Os, - page_phys: usize, - framebuffer_phys: u64, - framebuffer_size: u64, + os: &dyn Os, + page_phys: usize, + framebuffer_phys: u64, + framebuffer_size: u64, ) -> Option { - let framebuffer_virt = 0xD000_0000; // 256 MiB after kernel mapping, but before heap mapping + let framebuffer_virt = 0xD000_0000; // 256 MiB after kernel mapping, but before heap mapping - let pd = slice::from_raw_parts_mut(page_phys as *mut u32, PAGE_ENTRIES); + let pd = slice::from_raw_parts_mut(page_phys as *mut u32, PAGE_ENTRIES); - // Map framebuffer_size at framebuffer offset - let mut framebuffer_mapped = 0; - let mut pd_i = framebuffer_virt / 0x40_0000; - while framebuffer_mapped < framebuffer_size && pd_i < pd.len() { - let pt = paging_allocate(os)?; - pd[pd_i] = pt.as_ptr() as u32 | 1 << 1 | 1; - pd_i += 1; + // Map framebuffer_size at framebuffer offset + let mut framebuffer_mapped = 0; + let mut pd_i = framebuffer_virt / 0x40_0000; + while framebuffer_mapped < framebuffer_size && pd_i < pd.len() { + let pt = paging_allocate(os)?; + pd[pd_i] = pt.as_ptr() as u32 | 1 << 1 | 1; + pd_i += 1; - let mut pt_i = 0; - while framebuffer_mapped < framebuffer_size && pt_i < pt.len() { - let addr = framebuffer_phys + framebuffer_mapped; - pt[pt_i] = addr as u32 | 1 << 1 | 1; - pt_i += 1; - framebuffer_mapped += PAGE_SIZE as u64; - } - } - assert!(framebuffer_mapped >= framebuffer_size); + let mut pt_i = 0; + while framebuffer_mapped < framebuffer_size && pt_i < pt.len() { + let addr = framebuffer_phys + framebuffer_mapped; + pt[pt_i] = addr as u32 | 1 << 1 | 1; + pt_i += 1; + framebuffer_mapped += PAGE_SIZE as u64; + } + } + assert!(framebuffer_mapped >= framebuffer_size); - Some(framebuffer_virt as u64) + Some(framebuffer_virt as u64) } diff --git a/bootloader/bootloader/src/arch/x86/x64.rs b/bootloader/bootloader/src/arch/x86/x64.rs index d37cccc..51d3a80 100644 --- a/bootloader/bootloader/src/arch/x86/x64.rs +++ b/bootloader/bootloader/src/arch/x86/x64.rs @@ -10,20 +10,20 @@ const PAGE_SIZE: usize = 4096; pub(crate) const PHYS_OFFSET: u64 = 0xFFFF_8000_0000_0000; unsafe fn paging_allocate>( - os: &dyn Os, + os: &dyn Os, ) -> Option<&'static mut [u64]> { - let ptr = os.alloc_zeroed_page_aligned(PAGE_SIZE); - if !ptr.is_null() { - area_add(OsMemoryEntry { - base: ptr as u64, - size: PAGE_SIZE as u64, - kind: OsMemoryKind::Reclaim, - }); + let ptr = os.alloc_zeroed_page_aligned(PAGE_SIZE); + if !ptr.is_null() { + area_add(OsMemoryEntry { + base: ptr as u64, + size: PAGE_SIZE as u64, + kind: OsMemoryKind::Reclaim, + }); - Some(slice::from_raw_parts_mut(ptr as *mut u64, PAGE_ENTRIES)) - } else { - None - } + Some(slice::from_raw_parts_mut(ptr as *mut u64, PAGE_ENTRIES)) + } else { + None + } } const PRESENT: u64 = 1; @@ -31,119 +31,119 @@ const WRITABLE: u64 = 1 << 1; const LARGE: u64 = 1 << 7; pub unsafe fn paging_create>( - os: &dyn Os, - kernel_phys: u64, - kernel_size: u64, + os: &dyn Os, + kernel_phys: u64, + kernel_size: u64, ) -> Option { - // Create PML4 - let pml4 = paging_allocate(os)?; + // Create PML4 + let pml4 = paging_allocate(os)?; - { - // Create PDP for identity mapping - let pdp = paging_allocate(os)?; + { + // Create PDP for identity mapping + let pdp = paging_allocate(os)?; - // Link first user and first kernel PML4 entry to PDP - pml4[0] = pdp.as_ptr() as u64 | WRITABLE | PRESENT; - pml4[256] = pdp.as_ptr() as u64 | WRITABLE | PRESENT; + // Link first user and first kernel PML4 entry to PDP + pml4[0] = pdp.as_ptr() as u64 | WRITABLE | PRESENT; + pml4[256] = pdp.as_ptr() as u64 | WRITABLE | PRESENT; - // Identity map 8 GiB using 2 MiB pages - for pdp_i in 0..8 { - let pd = paging_allocate(os)?; - pdp[pdp_i] = pd.as_ptr() as u64 | WRITABLE | PRESENT; - for pd_i in 0..pd.len() { - let addr = pdp_i as u64 * 0x4000_0000 + pd_i as u64 * 0x20_0000; - pd[pd_i] = addr | LARGE | WRITABLE | PRESENT; - } - } - } + // Identity map 8 GiB using 2 MiB pages + for pdp_i in 0..8 { + let pd = paging_allocate(os)?; + pdp[pdp_i] = pd.as_ptr() as u64 | WRITABLE | PRESENT; + for pd_i in 0..pd.len() { + let addr = pdp_i as u64 * 0x4000_0000 + pd_i as u64 * 0x20_0000; + pd[pd_i] = addr | LARGE | WRITABLE | PRESENT; + } + } + } - { - // Create PDP (spanning 512 GiB) for kernel mapping - let pdp = paging_allocate(os)?; + { + // Create PDP (spanning 512 GiB) for kernel mapping + let pdp = paging_allocate(os)?; - // Link last PML4 entry to PDP - pml4[511] = pdp.as_ptr() as u64 | WRITABLE | PRESENT; + // Link last PML4 entry to PDP + pml4[511] = pdp.as_ptr() as u64 | WRITABLE | PRESENT; - // Create PD (spanning 1 GiB) for kernel mapping. - let pd = paging_allocate(os)?; + // Create PD (spanning 1 GiB) for kernel mapping. + let pd = paging_allocate(os)?; - // The kernel is mapped at -2^31, i.e. 0xFFFF_FFFF_8000_0000. Since a PD is 1 GiB, link - // the second last PDP entry to PD. - pdp[510] = pd.as_ptr() as u64 | WRITABLE | PRESENT; + // The kernel is mapped at -2^31, i.e. 0xFFFF_FFFF_8000_0000. Since a PD is 1 GiB, link + // the second last PDP entry to PD. + pdp[510] = pd.as_ptr() as u64 | WRITABLE | PRESENT; - // Map kernel_size bytes to kernel offset, i.e. to the start of the PD. + // Map kernel_size bytes to kernel offset, i.e. to the start of the PD. - let mut kernel_mapped = 0; + let mut kernel_mapped = 0; - let mut pd_idx = 0; - while kernel_mapped < kernel_size && pd_idx < pd.len() { - let pt = paging_allocate(os)?; - pd[pd_idx] = pt.as_ptr() as u64 | WRITABLE | PRESENT; - pd_idx += 1; + let mut pd_idx = 0; + while kernel_mapped < kernel_size && pd_idx < pd.len() { + let pt = paging_allocate(os)?; + pd[pd_idx] = pt.as_ptr() as u64 | WRITABLE | PRESENT; + pd_idx += 1; - let mut pt_idx = 0; - while kernel_mapped < kernel_size && pt_idx < pt.len() { - let addr = kernel_phys + kernel_mapped; - pt[pt_idx] = addr | WRITABLE | PRESENT; - pt_idx += 1; - kernel_mapped += PAGE_SIZE as u64; - } - } - assert!(kernel_mapped >= kernel_size); - } + let mut pt_idx = 0; + while kernel_mapped < kernel_size && pt_idx < pt.len() { + let addr = kernel_phys + kernel_mapped; + pt[pt_idx] = addr | WRITABLE | PRESENT; + pt_idx += 1; + kernel_mapped += PAGE_SIZE as u64; + } + } + assert!(kernel_mapped >= kernel_size); + } - Some(pml4.as_ptr() as usize) + Some(pml4.as_ptr() as usize) } pub unsafe fn paging_framebuffer>( - os: &dyn Os, - page_phys: usize, - framebuffer_phys: u64, - framebuffer_size: u64, + os: &dyn Os, + page_phys: usize, + framebuffer_phys: u64, + framebuffer_size: u64, ) -> Option { - //TODO: smarter test for framebuffer already mapped - if framebuffer_phys + framebuffer_size <= 0x2_0000_0000 { - return Some(framebuffer_phys + PHYS_OFFSET); - } + //TODO: smarter test for framebuffer already mapped + if framebuffer_phys + framebuffer_size <= 0x2_0000_0000 { + return Some(framebuffer_phys + PHYS_OFFSET); + } - let pml4_i = ((framebuffer_phys / 0x80_0000_0000) + 256) as usize; - let mut pdp_i = ((framebuffer_phys % 0x80_0000_0000) / 0x4000_0000) as usize; - let mut pd_i = ((framebuffer_phys % 0x4000_0000) / 0x20_0000) as usize; - assert_eq!(framebuffer_phys % 0x20_0000, 0); + let pml4_i = ((framebuffer_phys / 0x80_0000_0000) + 256) as usize; + let mut pdp_i = ((framebuffer_phys % 0x80_0000_0000) / 0x4000_0000) as usize; + let mut pd_i = ((framebuffer_phys % 0x4000_0000) / 0x20_0000) as usize; + assert_eq!(framebuffer_phys % 0x20_0000, 0); - let pml4 = slice::from_raw_parts_mut(page_phys as *mut u64, PAGE_ENTRIES); + let pml4 = slice::from_raw_parts_mut(page_phys as *mut u64, PAGE_ENTRIES); - // Create PDP for framebuffer mapping - let pdp = if pml4[pml4_i] == 0 { - let pdp = paging_allocate(os)?; - pml4[pml4_i] = pdp.as_ptr() as u64 | 1 << 1 | 1; - pdp - } else { - slice::from_raw_parts_mut( - (pml4[pml4_i] & ENTRY_ADDRESS_MASK) as *mut u64, - PAGE_ENTRIES, - ) - }; + // Create PDP for framebuffer mapping + let pdp = if pml4[pml4_i] == 0 { + let pdp = paging_allocate(os)?; + pml4[pml4_i] = pdp.as_ptr() as u64 | 1 << 1 | 1; + pdp + } else { + slice::from_raw_parts_mut( + (pml4[pml4_i] & ENTRY_ADDRESS_MASK) as *mut u64, + PAGE_ENTRIES, + ) + }; - // Map framebuffer_size at framebuffer offset - let mut framebuffer_mapped = 0; - while framebuffer_mapped < framebuffer_size && pdp_i < pdp.len() { - let pd = paging_allocate(os)?; - assert_eq!(pdp[pdp_i], 0); - pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1; + // Map framebuffer_size at framebuffer offset + let mut framebuffer_mapped = 0; + while framebuffer_mapped < framebuffer_size && pdp_i < pdp.len() { + let pd = paging_allocate(os)?; + assert_eq!(pdp[pdp_i], 0); + pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1; - while framebuffer_mapped < framebuffer_size && pd_i < pd.len() { - let addr = framebuffer_phys + framebuffer_mapped; - assert_eq!(pd[pd_i], 0); - pd[pd_i] = addr | 1 << 7 | 1 << 1 | 1; - framebuffer_mapped += 0x20_0000; - pd_i += 1; - } + while framebuffer_mapped < framebuffer_size && pd_i < pd.len() { + let addr = framebuffer_phys + framebuffer_mapped; + assert_eq!(pd[pd_i], 0); + pd[pd_i] = addr | 1 << 7 | 1 << 1 | 1; + framebuffer_mapped += 0x20_0000; + pd_i += 1; + } - pdp_i += 1; - pd_i = 0; - } - assert!(framebuffer_mapped >= framebuffer_size); + pdp_i += 1; + pd_i = 0; + } + assert!(framebuffer_mapped >= framebuffer_size); - Some(framebuffer_phys + PHYS_OFFSET) + Some(framebuffer_phys + PHYS_OFFSET) } diff --git a/bootloader/bootloader/src/os/bios/disk.rs b/bootloader/bootloader/src/os/bios/disk.rs index a666d00..9426629 100644 --- a/bootloader/bootloader/src/os/bios/disk.rs +++ b/bootloader/bootloader/src/os/bios/disk.rs @@ -15,161 +15,161 @@ const MAX_BLOCKS: u64 = MAX_SECTORS * SECTOR_SIZE / BLOCK_SIZE; #[derive(Clone, Copy)] #[repr(C, packed)] pub struct DiskAddressPacket { - size: u8, - reserved: u8, - sectors: u16, - buffer: u16, - segment: u16, - address: u64, + size: u8, + reserved: u8, + sectors: u16, + buffer: u16, + segment: u16, + address: u64, } impl DiskAddressPacket { - pub fn from_block(block: u64, count: u64) -> DiskAddressPacket { - let address = block * BLOCKS_PER_SECTOR; - let sectors = count * BLOCKS_PER_SECTOR; - assert!(sectors <= MAX_SECTORS); - DiskAddressPacket { - size: mem::size_of::() as u8, - reserved: 0, - sectors: sectors as u16, - buffer: (DISK_BIOS_ADDR & 0xF) as u16, - segment: (DISK_BIOS_ADDR >> 4) as u16, - address, - } - } + pub fn from_block(block: u64, count: u64) -> DiskAddressPacket { + let address = block * BLOCKS_PER_SECTOR; + let sectors = count * BLOCKS_PER_SECTOR; + assert!(sectors <= MAX_SECTORS); + DiskAddressPacket { + size: mem::size_of::() as u8, + reserved: 0, + sectors: sectors as u16, + buffer: (DISK_BIOS_ADDR & 0xF) as u16, + segment: (DISK_BIOS_ADDR >> 4) as u16, + address, + } + } } pub struct DiskBios { - boot_disk: u8, - thunk13: extern "C" fn(), - chs_opt: Option<(u32, u32, u32)>, + boot_disk: u8, + thunk13: extern "C" fn(), + chs_opt: Option<(u32, u32, u32)>, } impl DiskBios { - pub fn new(boot_disk: u8, thunk13: extern "C" fn()) -> Self { - let chs_opt = unsafe { - let mut data = ThunkData::new(); - data.eax = 0x4100; - data.ebx = 0x55AA; - data.edx = boot_disk as u32; + pub fn new(boot_disk: u8, thunk13: extern "C" fn()) -> Self { + let chs_opt = unsafe { + let mut data = ThunkData::new(); + data.eax = 0x4100; + data.ebx = 0x55AA; + data.edx = boot_disk as u32; - data.with(thunk13); + data.with(thunk13); - if (data.ebx & 0xFFFF) == 0xAA55 { - // Extensions are installed, do not use CHS - None - } else { - // Extensions are not installed, get CHS geometry - data = ThunkData::new(); - data.eax = 0x0800; - data.edx = boot_disk as u32; - data.edi = 0; + if (data.ebx & 0xFFFF) == 0xAA55 { + // Extensions are installed, do not use CHS + None + } else { + // Extensions are not installed, get CHS geometry + data = ThunkData::new(); + data.eax = 0x0800; + data.edx = boot_disk as u32; + data.edi = 0; - data.with(thunk13); + data.with(thunk13); - //TODO: return result on error - let ah = ({ data.eax } >> 8) & 0xFF; - assert_eq!(ah, 0); + //TODO: return result on error + let ah = ({ data.eax } >> 8) & 0xFF; + assert_eq!(ah, 0); - let c = (data.ecx >> 8) & 0xFF | ((data.ecx >> 6) & 0x3) << 8; - let h = ((data.edx >> 8) & 0xFF) + 1; - let s = data.ecx & 0x3F; + let c = (data.ecx >> 8) & 0xFF | ((data.ecx >> 6) & 0x3) << 8; + let h = ((data.edx >> 8) & 0xFF) + 1; + let s = data.ecx & 0x3F; - Some((c, h, s)) - } - }; + Some((c, h, s)) + } + }; - Self { - boot_disk, - thunk13, - chs_opt, - } - } + Self { + boot_disk, + thunk13, + chs_opt, + } + } } impl Disk for DiskBios { - unsafe fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result { - // Optimization for live disks - if let Some(live) = crate::LIVE_OPT { - if block >= live.0 { - let start = ((block - live.0) * BLOCK_SIZE) as usize; - let end = start + buffer.len(); - if end <= live.1.len() { - buffer.copy_from_slice(&live.1[start..end]); - return Ok(buffer.len()); - } - } - } + unsafe fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result { + // Optimization for live disks + if let Some(live) = crate::LIVE_OPT { + if block >= live.0 { + let start = ((block - live.0) * BLOCK_SIZE) as usize; + let end = start + buffer.len(); + if end <= live.1.len() { + buffer.copy_from_slice(&live.1[start..end]); + return Ok(buffer.len()); + } + } + } - for (i, chunk) in buffer - .chunks_mut((MAX_BLOCKS * BLOCK_SIZE) as usize) - .enumerate() - { - let dap = DiskAddressPacket::from_block( - block + i as u64 * MAX_BLOCKS, - chunk.len() as u64 / BLOCK_SIZE, - ); + for (i, chunk) in buffer + .chunks_mut((MAX_BLOCKS * BLOCK_SIZE) as usize) + .enumerate() + { + let dap = DiskAddressPacket::from_block( + block + i as u64 * MAX_BLOCKS, + chunk.len() as u64 / BLOCK_SIZE, + ); - if let Some((_, h_max, s_max)) = self.chs_opt { - let s = (dap.address % s_max as u64) + 1; - assert!(s <= 63, "invalid sector {}", s); + if let Some((_, h_max, s_max)) = self.chs_opt { + let s = (dap.address % s_max as u64) + 1; + assert!(s <= 63, "invalid sector {}", s); - let tmp = dap.address / s_max as u64; - let h = tmp % h_max as u64; - assert!(h <= 255, "invalid head {}", h); + let tmp = dap.address / s_max as u64; + let h = tmp % h_max as u64; + assert!(h <= 255, "invalid head {}", h); - let c = tmp / h_max as u64; - assert!(c <= 1023, "invalid cylinder {}", c); + let c = tmp / h_max as u64; + assert!(c <= 1023, "invalid cylinder {}", c); - let mut data = ThunkData::new(); - data.eax = 0x0200 | (dap.sectors as u32); - data.ebx = dap.buffer as u32; - data.ecx = - (s as u32) | (((c as u32) & 0xFF) << 8) | ((((c as u32) >> 8) & 0x3) << 6); - data.edx = (self.boot_disk as u32) | ((h as u32) << 8); - data.es = dap.segment; + let mut data = ThunkData::new(); + data.eax = 0x0200 | (dap.sectors as u32); + data.ebx = dap.buffer as u32; + data.ecx = + (s as u32) | (((c as u32) & 0xFF) << 8) | ((((c as u32) >> 8) & 0x3) << 6); + data.edx = (self.boot_disk as u32) | ((h as u32) << 8); + data.es = dap.segment; - data.with(self.thunk13); + data.with(self.thunk13); - //TODO: return result on error - let ah = ({ data.eax } >> 8) & 0xFF; - assert_eq!(ah, 0); - } else { - ptr::write(DISK_ADDRESS_PACKET_ADDR as *mut DiskAddressPacket, dap); + //TODO: return result on error + let ah = ({ data.eax } >> 8) & 0xFF; + assert_eq!(ah, 0); + } else { + ptr::write(DISK_ADDRESS_PACKET_ADDR as *mut DiskAddressPacket, dap); - let mut data = ThunkData::new(); - data.eax = 0x4200; - data.edx = self.boot_disk as u32; - data.esi = DISK_ADDRESS_PACKET_ADDR as u32; + let mut data = ThunkData::new(); + data.eax = 0x4200; + data.edx = self.boot_disk as u32; + data.esi = DISK_ADDRESS_PACKET_ADDR as u32; - data.with(self.thunk13); + data.with(self.thunk13); - //TODO: return result on error - let ah = ({ data.eax } >> 8) & 0xFF; - assert_eq!(ah, 0); + //TODO: return result on error + let ah = ({ data.eax } >> 8) & 0xFF; + assert_eq!(ah, 0); - //TODO: check blocks transferred - // dap = ptr::read(DISK_ADDRESS_PACKET_ADDR as *mut DiskAddressPacket); - } + //TODO: check blocks transferred + // dap = ptr::read(DISK_ADDRESS_PACKET_ADDR as *mut DiskAddressPacket); + } - ptr::copy(DISK_BIOS_ADDR as *const u8, chunk.as_mut_ptr(), chunk.len()); - } + ptr::copy(DISK_BIOS_ADDR as *const u8, chunk.as_mut_ptr(), chunk.len()); + } - Ok(buffer.len()) - } + Ok(buffer.len()) + } - unsafe fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result { - log::error!( - "DiskBios::write_at(0x{:X}, 0x{:X}:0x{:X}) not allowed", - block, - buffer.as_ptr() as usize, - buffer.len() - ); - Err(Error::new(EIO)) - } + unsafe fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result { + log::error!( + "DiskBios::write_at(0x{:X}, 0x{:X}:0x{:X}) not allowed", + block, + buffer.as_ptr() as usize, + buffer.len() + ); + Err(Error::new(EIO)) + } - fn size(&mut self) -> Result { - log::error!("DiskBios::size not implemented"); - Err(Error::new(EIO)) - } + fn size(&mut self) -> Result { + log::error!("DiskBios::size not implemented"); + Err(Error::new(EIO)) + } } diff --git a/bootloader/bootloader/src/os/bios/memory_map.rs b/bootloader/bootloader/src/os/bios/memory_map.rs index a92cbae..bdb42c6 100644 --- a/bootloader/bootloader/src/os/bios/memory_map.rs +++ b/bootloader/bootloader/src/os/bios/memory_map.rs @@ -7,78 +7,78 @@ use super::{thunk::ThunkData, MEMORY_MAP_ADDR}; #[repr(C, packed)] struct MemoryMapEntry { - pub base: u64, - pub size: u64, - pub kind: u32, + pub base: u64, + pub size: u64, + pub kind: u32, } pub struct MemoryMapIter { - thunk15: extern "C" fn(), - data: ThunkData, - first: bool, + thunk15: extern "C" fn(), + data: ThunkData, + first: bool, } impl MemoryMapIter { - pub fn new(thunk15: extern "C" fn()) -> Self { - Self { - thunk15, - data: ThunkData::new(), - first: true, - } - } + pub fn new(thunk15: extern "C" fn()) -> Self { + Self { + thunk15, + data: ThunkData::new(), + first: true, + } + } } impl Iterator for MemoryMapIter { - type Item = OsMemoryEntry; - fn next(&mut self) -> Option { - if self.first { - self.first = false; - } else if self.data.ebx == 0 { - return None; - } + type Item = OsMemoryEntry; + fn next(&mut self) -> Option { + if self.first { + self.first = false; + } else if self.data.ebx == 0 { + return None; + } - self.data.eax = 0xE820; - self.data.ecx = mem::size_of::() as u32; - self.data.edx = 0x534D4150; - self.data.edi = MEMORY_MAP_ADDR as u32; + self.data.eax = 0xE820; + self.data.ecx = mem::size_of::() as u32; + self.data.edx = 0x534D4150; + self.data.edi = MEMORY_MAP_ADDR as u32; - unsafe { - self.data.with(self.thunk15); - } + unsafe { + self.data.with(self.thunk15); + } - //TODO: return error? - assert_eq!({ self.data.eax }, 0x534D4150); - assert_eq!({ self.data.ecx }, mem::size_of::() as u32); + //TODO: return error? + assert_eq!({ self.data.eax }, 0x534D4150); + assert_eq!({ self.data.ecx }, mem::size_of::() as u32); - let entry = unsafe { ptr::read(MEMORY_MAP_ADDR as *const MemoryMapEntry) }; - Some(Self::Item { - base: entry.base, - size: entry.size, - kind: match entry.kind { - 0 => OsMemoryKind::Null, - 1 => OsMemoryKind::Free, - 3 => OsMemoryKind::Reclaim, - _ => OsMemoryKind::Reserved, - }, - }) - } + let entry = unsafe { ptr::read(MEMORY_MAP_ADDR as *const MemoryMapEntry) }; + Some(Self::Item { + base: entry.base, + size: entry.size, + kind: match entry.kind { + 0 => OsMemoryKind::Null, + 1 => OsMemoryKind::Free, + 3 => OsMemoryKind::Reclaim, + _ => OsMemoryKind::Reserved, + }, + }) + } } pub unsafe fn memory_map(thunk15: extern "C" fn()) -> Option<(usize, usize)> { - let mut heap_limits = None; - for entry in MemoryMapIter::new(thunk15) { - let heap_start = 1 * 1024 * 1024; - if { entry.kind } == OsMemoryKind::Free - && entry.base <= heap_start as u64 - && (entry.base + entry.size) >= heap_start as u64 - { - let heap_end = cmp::min(entry.base + entry.size, usize::MAX as u64) as usize; - if heap_end >= heap_start { - heap_limits = Some((heap_start, heap_end - heap_start)); - } - } + let mut heap_limits = None; + for entry in MemoryMapIter::new(thunk15) { + let heap_start = 1 * 1024 * 1024; + if { entry.kind } == OsMemoryKind::Free + && entry.base <= heap_start as u64 + && (entry.base + entry.size) >= heap_start as u64 + { + let heap_end = cmp::min(entry.base + entry.size, usize::MAX as u64) as usize; + if heap_end >= heap_start { + heap_limits = Some((heap_start, heap_end - heap_start)); + } + } - area_add(entry); - } - heap_limits + area_add(entry); + } + heap_limits } diff --git a/bootloader/bootloader/src/os/bios/thunk.rs b/bootloader/bootloader/src/os/bios/thunk.rs index 036157b..9e26ab7 100644 --- a/bootloader/bootloader/src/os/bios/thunk.rs +++ b/bootloader/bootloader/src/os/bios/thunk.rs @@ -6,41 +6,41 @@ use super::THUNK_STACK_ADDR; #[derive(Clone, Copy, Debug)] #[repr(C, packed)] pub struct ThunkData { - pub es: u16, - pub edi: u32, - pub esi: u32, - pub ebp: u32, - pub ebx: u32, - pub edx: u32, - pub ecx: u32, - pub eax: u32, + pub es: u16, + pub edi: u32, + pub esi: u32, + pub ebp: u32, + pub ebx: u32, + pub edx: u32, + pub ecx: u32, + pub eax: u32, } impl ThunkData { - pub fn new() -> Self { - Self { - es: 0, - edi: 0, - esi: 0, - ebp: 0, - ebx: 0, - edx: 0, - ecx: 0, - eax: 0, - } - } + pub fn new() -> Self { + Self { + es: 0, + edi: 0, + esi: 0, + ebp: 0, + ebx: 0, + edx: 0, + ecx: 0, + eax: 0, + } + } - pub unsafe fn save(&self) { - ptr::write((THUNK_STACK_ADDR - 64) as *mut ThunkData, *self); - } + pub unsafe fn save(&self) { + ptr::write((THUNK_STACK_ADDR - 64) as *mut ThunkData, *self); + } - pub unsafe fn load(&mut self) { - *self = ptr::read((THUNK_STACK_ADDR - 64) as *const ThunkData); - } + pub unsafe fn load(&mut self) { + *self = ptr::read((THUNK_STACK_ADDR - 64) as *const ThunkData); + } - pub unsafe fn with(&mut self, f: extern "C" fn()) { - self.save(); - f(); - self.load(); - } + pub unsafe fn with(&mut self, f: extern "C" fn()) { + self.save(); + f(); + self.load(); + } } diff --git a/bootloader/bootloader/src/os/bios/vbe.rs b/bootloader/bootloader/src/os/bios/vbe.rs index 9498b8d..84a36b4 100644 --- a/bootloader/bootloader/src/os/bios/vbe.rs +++ b/bootloader/bootloader/src/os/bios/vbe.rs @@ -8,144 +8,144 @@ use super::{ThunkData, VBE_CARD_INFO_ADDR, VBE_MODE_INFO_ADDR}; #[derive(Clone, Copy, Debug)] #[repr(C, packed)] pub struct VbeFarPtr { - pub offset: u16, - pub segment: u16, + pub offset: u16, + pub segment: u16, } impl VbeFarPtr { - pub unsafe fn as_ptr(&self) -> *const T { - (((self.segment as usize) << 4) + (self.offset as usize)) as *const T - } + pub unsafe fn as_ptr(&self) -> *const T { + (((self.segment as usize) << 4) + (self.offset as usize)) as *const T + } } #[derive(Clone, Copy, Debug)] #[repr(C, packed)] pub struct VbeCardInfo { - pub signature: [u8; 4], - pub version: u16, - pub oemstring: VbeFarPtr, - pub capabilities: [u8; 4], - pub videomodeptr: VbeFarPtr, - pub totalmemory: u16, - pub oemsoftwarerev: u16, - pub oemvendornameptr: VbeFarPtr, - pub oemproductnameptr: VbeFarPtr, - pub oemproductrevptr: VbeFarPtr, - pub reserved: [u8; 222], - pub oemdata: [u8; 256], + pub signature: [u8; 4], + pub version: u16, + pub oemstring: VbeFarPtr, + pub capabilities: [u8; 4], + pub videomodeptr: VbeFarPtr, + pub totalmemory: u16, + pub oemsoftwarerev: u16, + pub oemvendornameptr: VbeFarPtr, + pub oemproductnameptr: VbeFarPtr, + pub oemproductrevptr: VbeFarPtr, + pub reserved: [u8; 222], + pub oemdata: [u8; 256], } #[derive(Clone, Copy, Debug)] #[repr(C, packed)] pub struct VbeModeInfo { - pub attributes: u16, - pub win_a: u8, - pub win_b: u8, - pub granularity: u16, - pub winsize: u16, - pub segment_a: u16, - pub segment_b: u16, - pub winfuncptr: u32, - pub bytesperscanline: u16, - pub xresolution: u16, - pub yresolution: u16, - pub xcharsize: u8, - pub ycharsize: u8, - pub numberofplanes: u8, - pub bitsperpixel: u8, - pub numberofbanks: u8, - pub memorymodel: u8, - pub banksize: u8, - pub numberofimagepages: u8, - pub unused: u8, - pub redmasksize: u8, - pub redfieldposition: u8, - pub greenmasksize: u8, - pub greenfieldposition: u8, - pub bluemasksize: u8, - pub bluefieldposition: u8, - pub rsvdmasksize: u8, - pub rsvdfieldposition: u8, - pub directcolormodeinfo: u8, - pub physbaseptr: u32, - pub offscreenmemoryoffset: u32, - pub offscreenmemsize: u16, - pub reserved: [u8; 206], + pub attributes: u16, + pub win_a: u8, + pub win_b: u8, + pub granularity: u16, + pub winsize: u16, + pub segment_a: u16, + pub segment_b: u16, + pub winfuncptr: u32, + pub bytesperscanline: u16, + pub xresolution: u16, + pub yresolution: u16, + pub xcharsize: u8, + pub ycharsize: u8, + pub numberofplanes: u8, + pub bitsperpixel: u8, + pub numberofbanks: u8, + pub memorymodel: u8, + pub banksize: u8, + pub numberofimagepages: u8, + pub unused: u8, + pub redmasksize: u8, + pub redfieldposition: u8, + pub greenmasksize: u8, + pub greenfieldposition: u8, + pub bluemasksize: u8, + pub bluefieldposition: u8, + pub rsvdmasksize: u8, + pub rsvdfieldposition: u8, + pub directcolormodeinfo: u8, + pub physbaseptr: u32, + pub offscreenmemoryoffset: u32, + pub offscreenmemsize: u16, + pub reserved: [u8; 206], } pub struct VideoModeIter { - thunk10: extern "C" fn(), - mode_ptr: *const u16, + thunk10: extern "C" fn(), + mode_ptr: *const u16, } impl VideoModeIter { - pub fn new(thunk10: extern "C" fn()) -> Self { - // Get card info - let mut data = ThunkData::new(); - data.eax = 0x4F00; - data.edi = VBE_CARD_INFO_ADDR as u32; - unsafe { - data.with(thunk10); - } - let mode_ptr = if data.eax == 0x004F { - let card_info = unsafe { ptr::read(VBE_CARD_INFO_ADDR as *const VbeCardInfo) }; - unsafe { card_info.videomodeptr.as_ptr::() } - } else { - error!("Failed to read VBE card info: 0x{:04X}", { data.eax }); - ptr::null() - }; - Self { thunk10, mode_ptr } - } + pub fn new(thunk10: extern "C" fn()) -> Self { + // Get card info + let mut data = ThunkData::new(); + data.eax = 0x4F00; + data.edi = VBE_CARD_INFO_ADDR as u32; + unsafe { + data.with(thunk10); + } + let mode_ptr = if data.eax == 0x004F { + let card_info = unsafe { ptr::read(VBE_CARD_INFO_ADDR as *const VbeCardInfo) }; + unsafe { card_info.videomodeptr.as_ptr::() } + } else { + error!("Failed to read VBE card info: 0x{:04X}", { data.eax }); + ptr::null() + }; + Self { thunk10, mode_ptr } + } } impl Iterator for VideoModeIter { - type Item = OsVideoMode; - fn next(&mut self) -> Option { - if self.mode_ptr.is_null() { - return None; - } + type Item = OsVideoMode; + fn next(&mut self) -> Option { + if self.mode_ptr.is_null() { + return None; + } - loop { - // Set bit 14 to get linear frame buffer - let mode = unsafe { *self.mode_ptr } | (1 << 14); - if mode == 0xFFFF { - return None; - } - self.mode_ptr = unsafe { self.mode_ptr.add(1) }; + loop { + // Set bit 14 to get linear frame buffer + let mode = unsafe { *self.mode_ptr } | (1 << 14); + if mode == 0xFFFF { + return None; + } + self.mode_ptr = unsafe { self.mode_ptr.add(1) }; - // Get mode info - let mut data = ThunkData::new(); - data.eax = 0x4F01; - data.ecx = mode as u32; - data.edi = VBE_MODE_INFO_ADDR as u32; - unsafe { - data.with(self.thunk10); - } - if data.eax == 0x004F { - let mode_info = unsafe { ptr::read(VBE_MODE_INFO_ADDR as *const VbeModeInfo) }; + // Get mode info + let mut data = ThunkData::new(); + data.eax = 0x4F01; + data.ecx = mode as u32; + data.edi = VBE_MODE_INFO_ADDR as u32; + unsafe { + data.with(self.thunk10); + } + if data.eax == 0x004F { + let mode_info = unsafe { ptr::read(VBE_MODE_INFO_ADDR as *const VbeModeInfo) }; - // We only support 32-bits per pixel modes - if mode_info.bitsperpixel != 32 { - continue; - } + // We only support 32-bits per pixel modes + if mode_info.bitsperpixel != 32 { + continue; + } - let width = mode_info.xresolution as u32; - let height = mode_info.yresolution as u32; - //TODO: support stride that is not a multiple of 4 - let stride = mode_info.bytesperscanline as u32 / 4; + let width = mode_info.xresolution as u32; + let height = mode_info.yresolution as u32; + //TODO: support stride that is not a multiple of 4 + let stride = mode_info.bytesperscanline as u32 / 4; - return Some(OsVideoMode { - id: mode as u32, - width, - height, - stride, - base: mode_info.physbaseptr as u64, - }); - } else { - error!("Failed to read VBE mode 0x{:04X} info: 0x{:04X}", mode, { - data.eax - }); - } - } - } + return Some(OsVideoMode { + id: mode as u32, + width, + height, + stride, + base: mode_info.physbaseptr as u64, + }); + } else { + error!("Failed to read VBE mode 0x{:04X} info: 0x{:04X}", mode, { + data.eax + }); + } + } + } } diff --git a/bootloader/bootloader/src/os/bios/vga.rs b/bootloader/bootloader/src/os/bios/vga.rs index 9bba2d8..bb19823 100644 --- a/bootloader/bootloader/src/os/bios/vga.rs +++ b/bootloader/bootloader/src/os/bios/vga.rs @@ -3,117 +3,117 @@ use core::{fmt, slice}; #[derive(Clone, Copy)] #[repr(C, packed)] pub struct VgaTextBlock { - pub char: u8, - pub color: u8, + pub char: u8, + pub color: u8, } #[allow(dead_code)] #[derive(Clone, Copy)] #[repr(u8)] pub enum VgaTextColor { - Black = 0, - Blue = 1, - Green = 2, - Cyan = 3, - Red = 4, - Purple = 5, - Brown = 6, - Gray = 7, - DarkGray = 8, - LightBlue = 9, - LightGreen = 10, - LightCyan = 11, - LightRed = 12, - LightPurple = 13, - Yellow = 14, - White = 15, + Black = 0, + Blue = 1, + Green = 2, + Cyan = 3, + Red = 4, + Purple = 5, + Brown = 6, + Gray = 7, + DarkGray = 8, + LightBlue = 9, + LightGreen = 10, + LightCyan = 11, + LightRed = 12, + LightPurple = 13, + Yellow = 14, + White = 15, } pub struct Vga { - pub base: usize, - pub width: usize, - pub height: usize, - pub x: usize, - pub y: usize, - pub bg: VgaTextColor, - pub fg: VgaTextColor, + pub base: usize, + pub width: usize, + pub height: usize, + pub x: usize, + pub y: usize, + pub bg: VgaTextColor, + pub fg: VgaTextColor, } impl Vga { - pub const unsafe fn new(base: usize, width: usize, height: usize) -> Self { - Self { - base, - width, - height, - x: 0, - y: 0, - bg: VgaTextColor::Black, - fg: VgaTextColor::Gray, - } - } + pub const unsafe fn new(base: usize, width: usize, height: usize) -> Self { + Self { + base, + width, + height, + x: 0, + y: 0, + bg: VgaTextColor::Black, + fg: VgaTextColor::Gray, + } + } - pub unsafe fn blocks(&mut self) -> &'static mut [VgaTextBlock] { - slice::from_raw_parts_mut(self.base as *mut VgaTextBlock, self.width * self.height) - } + pub unsafe fn blocks(&mut self) -> &'static mut [VgaTextBlock] { + slice::from_raw_parts_mut(self.base as *mut VgaTextBlock, self.width * self.height) + } - pub fn clear(&mut self) { - self.x = 0; - self.y = 0; - let blocks = unsafe { self.blocks() }; - for i in 0..blocks.len() { - blocks[i] = VgaTextBlock { - char: 0, - color: ((self.bg as u8) << 4) | (self.fg as u8), - }; - } - } + pub fn clear(&mut self) { + self.x = 0; + self.y = 0; + let blocks = unsafe { self.blocks() }; + for i in 0..blocks.len() { + blocks[i] = VgaTextBlock { + char: 0, + color: ((self.bg as u8) << 4) | (self.fg as u8), + }; + } + } } impl fmt::Write for Vga { - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - let blocks = unsafe { self.blocks() }; - for c in s.chars() { - if self.x >= self.width { - self.x = 0; - self.y += 1; - } - while self.y >= self.height { - for y in 1..self.height { - for x in 0..self.width { - let i = y * self.width + x; - let j = i - self.width; - blocks[j] = blocks[i]; - if y + 1 == self.height { - blocks[i].char = 0; - } - } - } - self.y -= 1; - } - match c { - '\x08' => { - if self.x > 0 { - self.x -= 1; - } - } - '\r' => { - self.x = 0; - } - '\n' => { - self.x = 0; - self.y += 1; - } - _ => { - let i = self.y * self.width + self.x; - if let Some(block) = blocks.get_mut(i) { - block.char = c as u8; - block.color = ((self.bg as u8) << 4) | (self.fg as u8); - } - self.x += 1; - } - } - } + fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { + let blocks = unsafe { self.blocks() }; + for c in s.chars() { + if self.x >= self.width { + self.x = 0; + self.y += 1; + } + while self.y >= self.height { + for y in 1..self.height { + for x in 0..self.width { + let i = y * self.width + x; + let j = i - self.width; + blocks[j] = blocks[i]; + if y + 1 == self.height { + blocks[i].char = 0; + } + } + } + self.y -= 1; + } + match c { + '\x08' => { + if self.x > 0 { + self.x -= 1; + } + } + '\r' => { + self.x = 0; + } + '\n' => { + self.x = 0; + self.y += 1; + } + _ => { + let i = self.y * self.width + self.x; + if let Some(block) = blocks.get_mut(i) { + block.char = c as u8; + block.color = ((self.bg as u8) << 4) | (self.fg as u8); + } + self.x += 1; + } + } + } - Ok(()) - } + Ok(()) + } } diff --git a/bootloader/bootloader/src/serial_16550.rs b/bootloader/bootloader/src/serial_16550.rs index 5ea26c0..ea8bdc8 100644 --- a/bootloader/bootloader/src/serial_16550.rs +++ b/bootloader/bootloader/src/serial_16550.rs @@ -7,136 +7,136 @@ use syscall::io::Pio; use syscall::io::{Io, Mmio, ReadOnly}; bitflags! { - /// Interrupt enable flags - struct IntEnFlags: u8 { - const RECEIVED = 1; - const SENT = 1 << 1; - const ERRORED = 1 << 2; - const STATUS_CHANGE = 1 << 3; - // 4 to 7 are unused - } + /// Interrupt enable flags + struct IntEnFlags: u8 { + const RECEIVED = 1; + const SENT = 1 << 1; + const ERRORED = 1 << 2; + const STATUS_CHANGE = 1 << 3; + // 4 to 7 are unused + } } bitflags! { - /// Line status flags - struct LineStsFlags: u8 { - const INPUT_FULL = 1; - // 1 to 4 unknown - const OUTPUT_EMPTY = 1 << 5; - // 6 and 7 unknown - } + /// Line status flags + struct LineStsFlags: u8 { + const INPUT_FULL = 1; + // 1 to 4 unknown + const OUTPUT_EMPTY = 1 << 5; + // 6 and 7 unknown + } } #[allow(dead_code)] #[repr(C, packed)] pub struct SerialPort { - /// Data register, read to receive, write to send - data: T, - /// Interrupt enable - int_en: T, - /// FIFO control - fifo_ctrl: T, - /// Line control - line_ctrl: T, - /// Modem control - modem_ctrl: T, - /// Line status - line_sts: ReadOnly, - /// Modem status - modem_sts: ReadOnly, + /// Data register, read to receive, write to send + data: T, + /// Interrupt enable + int_en: T, + /// FIFO control + fifo_ctrl: T, + /// Line control + line_ctrl: T, + /// Modem control + modem_ctrl: T, + /// Line status + line_sts: ReadOnly, + /// Modem status + modem_sts: ReadOnly, } #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] impl SerialPort> { - pub const fn new(base: u16) -> SerialPort> { - SerialPort { - data: Pio::new(base), - int_en: Pio::new(base + 1), - fifo_ctrl: Pio::new(base + 2), - line_ctrl: Pio::new(base + 3), - modem_ctrl: Pio::new(base + 4), - line_sts: ReadOnly::new(Pio::new(base + 5)), - modem_sts: ReadOnly::new(Pio::new(base + 6)), - } - } + pub const fn new(base: u16) -> SerialPort> { + SerialPort { + data: Pio::new(base), + int_en: Pio::new(base + 1), + fifo_ctrl: Pio::new(base + 2), + line_ctrl: Pio::new(base + 3), + modem_ctrl: Pio::new(base + 4), + line_sts: ReadOnly::new(Pio::new(base + 5)), + modem_sts: ReadOnly::new(Pio::new(base + 6)), + } + } } impl SerialPort> { - pub unsafe fn new(base: usize) -> &'static mut SerialPort> { - &mut *(base as *mut Self) - } + pub unsafe fn new(base: usize) -> &'static mut SerialPort> { + &mut *(base as *mut Self) + } } impl SerialPort where - T::Value: From + TryInto, + T::Value: From + TryInto, { - pub fn init(&mut self) { - unsafe { - //TODO: Cleanup - // FIXME: Fix UB if unaligned - (&mut *addr_of_mut!(self.int_en)).write(0x00.into()); - (&mut *addr_of_mut!(self.line_ctrl)).write(0x80.into()); - (&mut *addr_of_mut!(self.data)).write(0x01.into()); - (&mut *addr_of_mut!(self.int_en)).write(0x00.into()); - (&mut *addr_of_mut!(self.line_ctrl)).write(0x03.into()); - (&mut *addr_of_mut!(self.fifo_ctrl)).write(0xC7.into()); - (&mut *addr_of_mut!(self.modem_ctrl)).write(0x0B.into()); - (&mut *addr_of_mut!(self.int_en)).write(0x01.into()); - } - } + pub fn init(&mut self) { + unsafe { + //TODO: Cleanup + // FIXME: Fix UB if unaligned + (&mut *addr_of_mut!(self.int_en)).write(0x00.into()); + (&mut *addr_of_mut!(self.line_ctrl)).write(0x80.into()); + (&mut *addr_of_mut!(self.data)).write(0x01.into()); + (&mut *addr_of_mut!(self.int_en)).write(0x00.into()); + (&mut *addr_of_mut!(self.line_ctrl)).write(0x03.into()); + (&mut *addr_of_mut!(self.fifo_ctrl)).write(0xC7.into()); + (&mut *addr_of_mut!(self.modem_ctrl)).write(0x0B.into()); + (&mut *addr_of_mut!(self.int_en)).write(0x01.into()); + } + } - fn line_sts(&self) -> LineStsFlags { - LineStsFlags::from_bits_truncate( - (unsafe { &*addr_of!(self.line_sts) }.read() & 0xFF.into()) - .try_into() - .unwrap_or(0), - ) - } + fn line_sts(&self) -> LineStsFlags { + LineStsFlags::from_bits_truncate( + (unsafe { &*addr_of!(self.line_sts) }.read() & 0xFF.into()) + .try_into() + .unwrap_or(0), + ) + } - pub fn receive(&mut self) -> Option { - if self.line_sts().contains(LineStsFlags::INPUT_FULL) { - Some( - (unsafe { &*addr_of!(self.data) }.read() & 0xFF.into()) - .try_into() - .unwrap_or(0), - ) - } else { - None - } - } + pub fn receive(&mut self) -> Option { + if self.line_sts().contains(LineStsFlags::INPUT_FULL) { + Some( + (unsafe { &*addr_of!(self.data) }.read() & 0xFF.into()) + .try_into() + .unwrap_or(0), + ) + } else { + None + } + } - pub fn send(&mut self, data: u8) { - while !self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} - unsafe { &mut *addr_of_mut!(self.data) }.write(data.into()) - } + pub fn send(&mut self, data: u8) { + while !self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} + unsafe { &mut *addr_of_mut!(self.data) }.write(data.into()) + } - pub fn write(&mut self, buf: &[u8]) { - for &b in buf { - match b { - 8 | 0x7F => { - self.send(8); - self.send(b' '); - self.send(8); - } - b'\n' => { - self.send(b'\r'); - self.send(b'\n'); - } - _ => { - self.send(b); - } - } - } - } + pub fn write(&mut self, buf: &[u8]) { + for &b in buf { + match b { + 8 | 0x7F => { + self.send(8); + self.send(b' '); + self.send(8); + } + b'\n' => { + self.send(b'\r'); + self.send(b'\n'); + } + _ => { + self.send(b); + } + } + } + } } impl fmt::Write for SerialPort where - T::Value: From + TryInto, + T::Value: From + TryInto, { - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - self.write(s.as_bytes()); - Ok(()) - } + fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { + self.write(s.as_bytes()); + Ok(()) + } }