diff --git a/Cargo.toml b/Cargo.toml index 2b4742c..ace384d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ rlibc = "1.0" volatile = "0.1.0" spin = "0.4.5" multiboot2 = "0.1.0" -bitflags = "0.7.0" +bitflags = "1.0" x86_64 = "0.1.2" once = "0.3.3" linked_list_allocator = "0.5.0" diff --git a/src/arch/x86_64/driver/apic/ioapic.rs b/src/arch/x86_64/driver/apic/ioapic.rs index e9ddc2d..c123dba 100644 --- a/src/arch/x86_64/driver/apic/ioapic.rs +++ b/src/arch/x86_64/driver/apic/ioapic.rs @@ -12,12 +12,12 @@ use spin::Mutex; pub fn init(ioapic_id: u8) { let mut ioapic = IOAPIC.lock(); - assert!(ioapic.id() == ioapic_id, "ioapic.init: id isn't equal to ioapicid; not a MP"); + assert_eq!(ioapic.id(), ioapic_id, "ioapic.init: id isn't equal to ioapicid; not a MP"); // Mark all interrupts edge-triggered, active high, disabled, // and not routed to any CPUs. for i in 0.. ioapic.maxintr() + 1 { - ioapic.write_irq(i, DISABLED, 0); + ioapic.write_irq(i, RedirectionEntry::DISABLED, 0); } debug!("ioapic: init end"); } @@ -35,12 +35,12 @@ const REG_TABLE : u8 = 0x10; // Redirection table base // CPUs can serve that interrupt. bitflags! { - flags RedirectionEntry: u32 { - const DISABLED = 0x00010000, // Interrupt disabled - const LEVEL = 0x00008000, // Level-triggered (vs edge-) - const ACTIVELOW = 0x00002000, // Active low (vs high) - const LOGICAL = 0x00000800, // Destination is CPU id (vs APIC ID) - const NONE = 0x00000000, + struct RedirectionEntry: u32 { + const DISABLED = 0x00010000; // Interrupt disabled + const LEVEL = 0x00008000; // Level-triggered (vs edge-) + const ACTIVELOW = 0x00002000; // Active low (vs high) + const LOGICAL = 0x00000800; // Destination is CPU id (vs APIC ID) + const NONE = 0x00000000; } } @@ -85,7 +85,7 @@ impl IoApic { // Mark interrupt edge-triggered, active high, // enabled, and routed to the given cpunum, // which happens to be that cpu's APIC ID. - self.write_irq(irq, NONE, cpunum); + self.write_irq(irq, RedirectionEntry::NONE, cpunum); } fn id(&mut self) -> u8 { self.read(REG_ID).get_bits(24..28) as u8 diff --git a/src/arch/x86_64/driver/serial.rs b/src/arch/x86_64/driver/serial.rs index b5dd0c7..9895099 100644 --- a/src/arch/x86_64/driver/serial.rs +++ b/src/arch/x86_64/driver/serial.rs @@ -84,7 +84,7 @@ impl> SerialPort { } pub fn receive(&mut self) { - while self.line_sts().contains(INPUT_FULL) { + while self.line_sts().contains(LineStsFlags::INPUT_FULL) { let data = self.data.read(); write!(self, "serial receive {}", data); // TODO handle received data @@ -92,7 +92,7 @@ impl> SerialPort { } fn wait(&self) { - while ! self.line_sts().contains(OUTPUT_EMPTY) {} + while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} } pub fn send(&mut self, data: u8) { @@ -124,21 +124,21 @@ impl> Write for SerialPort { bitflags! { /// Interrupt enable flags - flags IntEnFlags: u8 { - const RECEIVED = 1, - const SENT = 1 << 1, - const ERRORED = 1 << 2, - const STATUS_CHANGE = 1 << 3, + struct IntEnFlags: u8 { + const RECEIVED = 1 << 0; + const SENT = 1 << 1; + const ERRORED = 1 << 2; + const STATUS_CHANGE = 1 << 3; // 4 to 7 are unused } } bitflags! { /// Line status flags - flags LineStsFlags: u8 { - const INPUT_FULL = 1, + struct LineStsFlags: u8 { + const INPUT_FULL = 1 << 0; // 1 to 4 unknown - const OUTPUT_EMPTY = 1 << 5, + const OUTPUT_EMPTY = 1 << 5; // 6 and 7 unknown } } \ No newline at end of file diff --git a/src/arch/x86_64/gdt.rs b/src/arch/x86_64/gdt.rs index 8e87c56..0f1f36b 100644 --- a/src/arch/x86_64/gdt.rs +++ b/src/arch/x86_64/gdt.rs @@ -107,18 +107,13 @@ pub enum Descriptor { } impl Descriptor { - pub fn kernel_code_segment() -> Descriptor { - let flags = USER_SEGMENT | PRESENT | EXECUTABLE | LONG_MODE; - Descriptor::UserSegment(flags.bits()) - } - pub fn tss_segment(tss: &'static TaskStateSegment) -> Descriptor { use core::mem::size_of; use bit_field::BitField; let ptr = tss as *const _ as u64; - let mut low = PRESENT.bits(); + let mut low = DescriptorFlags::PRESENT.bits(); // base low.set_bits(16..40, ptr.get_bits(0..24)); low.set_bits(56..64, ptr.get_bits(24..32)); @@ -136,16 +131,16 @@ impl Descriptor { bitflags! { /// Reference: https://wiki.osdev.org/GDT - flags DescriptorFlags: u64 { - const ACCESSED = 1 << 40, - const DATA_WRITABLE = 1 << 41, - const CODE_READABLE = 1 << 41, - const CONFORMING = 1 << 42, - const EXECUTABLE = 1 << 43, - const USER_SEGMENT = 1 << 44, - const USER_MODE = 1 << 45 | 1 << 46, - const PRESENT = 1 << 47, - const LONG_MODE = 1 << 53, + struct DescriptorFlags: u64 { + const ACCESSED = 1 << 40; + const DATA_WRITABLE = 1 << 41; + const CODE_READABLE = 1 << 41; + const CONFORMING = 1 << 42; + const EXECUTABLE = 1 << 43; + const USER_SEGMENT = 1 << 44; + const USER_MODE = 1 << 45 | 1 << 46; + const PRESENT = 1 << 47; + const LONG_MODE = 1 << 53; } } diff --git a/src/arch/x86_64/paging/entry.rs b/src/arch/x86_64/paging/entry.rs index ce735d4..8f1edf1 100644 --- a/src/arch/x86_64/paging/entry.rs +++ b/src/arch/x86_64/paging/entry.rs @@ -17,7 +17,7 @@ impl Entry { } pub fn pointed_frame(&self) -> Option { - if self.flags().contains(PRESENT) { + if self.flags().contains(EntryFlags::PRESENT) { Some(Frame::containing_address( self.0 as usize & 0x000fffff_fffff000 )) @@ -33,17 +33,17 @@ impl Entry { } bitflags! { - pub flags EntryFlags: u64 { - const PRESENT = 1 << 0, - const WRITABLE = 1 << 1, - const USER_ACCESSIBLE = 1 << 2, - const WRITE_THROUGH = 1 << 3, - const NO_CACHE = 1 << 4, - const ACCESSED = 1 << 5, - const DIRTY = 1 << 6, - const HUGE_PAGE = 1 << 7, - const GLOBAL = 1 << 8, - const NO_EXECUTE = 1 << 63, + pub struct EntryFlags: u64 { + const PRESENT = 1 << 0; + const WRITABLE = 1 << 1; + const USER_ACCESSIBLE = 1 << 2; + const WRITE_THROUGH = 1 << 3; + const NO_CACHE = 1 << 4; + const ACCESSED = 1 << 5; + const DIRTY = 1 << 6; + const HUGE_PAGE = 1 << 7; + const GLOBAL = 1 << 8; + const NO_EXECUTE = 1 << 63; } } @@ -57,13 +57,13 @@ impl EntryFlags { if section.flags().contains(ELF_SECTION_ALLOCATED) { // section is loaded to memory - flags = flags | PRESENT; + flags = flags | EntryFlags::PRESENT; } if section.flags().contains(ELF_SECTION_WRITABLE) { - flags = flags | WRITABLE; + flags = flags | EntryFlags::WRITABLE; } if !section.flags().contains(ELF_SECTION_EXECUTABLE) { - flags = flags | NO_EXECUTE; + flags = flags | EntryFlags::NO_EXECUTE; } flags diff --git a/src/arch/x86_64/paging/mapper.rs b/src/arch/x86_64/paging/mapper.rs index f8f0df6..d9a394c 100644 --- a/src/arch/x86_64/paging/mapper.rs +++ b/src/arch/x86_64/paging/mapper.rs @@ -1,4 +1,4 @@ -use super::{Page, ENTRY_COUNT}; +use super::{Page, ENTRY_COUNT, EntryFlags}; use super::table::{self, Table, Level4, Level1}; use memory::*; use core::ptr::Unique; @@ -36,7 +36,7 @@ impl Mapper { let p3_entry = &p3[page.p3_index()]; // 1GiB page? if let Some(start_frame) = p3_entry.pointed_frame() { - if p3_entry.flags().contains(HUGE_PAGE) { + if p3_entry.flags().contains(EntryFlags::HUGE_PAGE) { // address must be 1GiB aligned assert!(start_frame.start_address().get() % (ENTRY_COUNT * ENTRY_COUNT * PAGE_SIZE) == 0); return Some(Frame::containing_address( @@ -49,7 +49,7 @@ impl Mapper { let p2_entry = &p2[page.p2_index()]; // 2MiB page? if let Some(start_frame) = p2_entry.pointed_frame() { - if p2_entry.flags().contains(HUGE_PAGE) { + if p2_entry.flags().contains(EntryFlags::HUGE_PAGE) { // address must be 2MiB aligned assert!(start_frame.start_address().get() % ENTRY_COUNT == 0); return Some(Frame::containing_address( @@ -78,7 +78,7 @@ impl Mapper { let mut p1 = p2.next_table_create(page.p2_index(), allocator); assert!(p1[page.p1_index()].is_unused()); - p1[page.p1_index()].set(frame, flags | PRESENT); + p1[page.p1_index()].set(frame, flags | EntryFlags::PRESENT); } pub fn map(&mut self, page: Page, flags: EntryFlags, allocator: &mut A) diff --git a/src/arch/x86_64/paging/mod.rs b/src/arch/x86_64/paging/mod.rs index 6d75cdb..535815b 100644 --- a/src/arch/x86_64/paging/mod.rs +++ b/src/arch/x86_64/paging/mod.rs @@ -120,14 +120,14 @@ impl ActivePageTable { let p4_table = temporary_page.map_table_frame(backup.clone(), self); // overwrite recursive mapping - self.p4_mut()[511].set(table.p4_frame.clone(), PRESENT | WRITABLE); + self.p4_mut()[511].set(table.p4_frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE); tlb::flush_all(); // execute f in the new context f(self); // restore recursive mapping to original p4 table - p4_table[511].set(backup, PRESENT | WRITABLE); + p4_table[511].set(backup, EntryFlags::PRESENT | EntryFlags::WRITABLE); tlb::flush_all(); } @@ -167,7 +167,7 @@ impl InactivePageTable { // now we are able to zero the table table.zero(); // set up recursive mapping for the table - table[511].set(frame.clone(), PRESENT | WRITABLE); + table[511].set(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE); } temporary_page.unmap(active_table); diff --git a/src/arch/x86_64/paging/table.rs b/src/arch/x86_64/paging/table.rs index bd50282..17736b0 100644 --- a/src/arch/x86_64/paging/table.rs +++ b/src/arch/x86_64/paging/table.rs @@ -22,7 +22,7 @@ impl Table where L: TableLevel { impl Table where L: HierarchicalLevel { fn next_table_address(&self, index: usize) -> Option { let entry_flags = self[index].flags(); - if entry_flags.contains(PRESENT) && !entry_flags.contains(HUGE_PAGE) { + if entry_flags.contains(EntryFlags::PRESENT) && !entry_flags.contains(EntryFlags::HUGE_PAGE) { let table_address = self as *const _ as usize; Some((table_address << 9) | (index << 12)) } else { @@ -47,10 +47,10 @@ impl Table where L: HierarchicalLevel { where A: FrameAllocator { if self.next_table(index).is_none() { - assert!(!self.entries[index].flags().contains(HUGE_PAGE), + assert!(!self.entries[index].flags().contains(EntryFlags::HUGE_PAGE), "mapping code does not support huge pages"); let frame = allocator.allocate_frame().expect("no frames available"); - self.entries[index].set(frame, PRESENT | WRITABLE); + self.entries[index].set(frame, EntryFlags::PRESENT | EntryFlags::WRITABLE); self.next_table_mut(index).unwrap().zero(); } self.next_table_mut(index).unwrap() diff --git a/src/arch/x86_64/paging/temporary_page.rs b/src/arch/x86_64/paging/temporary_page.rs index 0c9d8c4..4ba6a9a 100644 --- a/src/arch/x86_64/paging/temporary_page.rs +++ b/src/arch/x86_64/paging/temporary_page.rs @@ -22,11 +22,11 @@ impl TemporaryPage { pub fn map(&mut self, frame: Frame, active_table: &mut ActivePageTable) -> VirtualAddress { - use super::entry::WRITABLE; + use super::entry::EntryFlags; assert!(active_table.translate_page(self.page).is_none(), "temporary page is already mapped"); - active_table.map_to(self.page, frame, WRITABLE, &mut self.allocator); + active_table.map_to(self.page, frame, EntryFlags::WRITABLE, &mut self.allocator); self.page.start_address() } diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 54073f1..03d16af 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -7,7 +7,7 @@ pub use self::frame::*; use multiboot2::BootInformation; use consts::KERNEL_OFFSET; use arch::paging; - +use arch::paging::EntryFlags; mod area_frame_allocator; pub mod heap_allocator; mod stack_allocator; @@ -55,7 +55,7 @@ pub fn init(boot_info: &BootInformation) -> MemoryController { let heap_end_page = Page::containing_address(KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE-1); for page in Page::range_inclusive(heap_start_page, heap_end_page) { - active_table.map(page, paging::WRITABLE, &mut frame_allocator); + active_table.map(page, EntryFlags::WRITABLE, &mut frame_allocator); } let stack_allocator = { @@ -119,13 +119,13 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) // identity map the VGA text buffer let vga_buffer_frame = Frame::containing_address(0xb8000); - mapper.identity_map(vga_buffer_frame, WRITABLE, allocator); + mapper.identity_map(vga_buffer_frame, EntryFlags::WRITABLE, allocator); // identity map the multiboot info structure let multiboot_start = Frame::containing_address(boot_info.start_address()); let multiboot_end = Frame::containing_address(boot_info.end_address() - 1); for frame in Frame::range_inclusive(multiboot_start, multiboot_end) { - mapper.identity_map(frame, PRESENT, allocator); + mapper.identity_map(frame, EntryFlags::PRESENT, allocator); } }); @@ -160,9 +160,8 @@ impl MemoryController { size_in_pages) } pub fn map_page_identity(&mut self, addr: usize) { - use self::paging::{WRITABLE}; let frame = Frame::containing_address(addr); - let flags = WRITABLE; + let flags = EntryFlags::WRITABLE; self.active_table.identity_map(frame, flags, &mut self.frame_allocator); } pub fn print_page_table(&self) { diff --git a/src/memory/stack_allocator.rs b/src/memory/stack_allocator.rs index efb6696..7249874 100644 --- a/src/memory/stack_allocator.rs +++ b/src/memory/stack_allocator.rs @@ -1,4 +1,4 @@ -use memory::paging::{self, Page, PageIter, ActivePageTable}; +use memory::paging::{Page, PageIter, ActivePageTable, EntryFlags}; use memory::{PAGE_SIZE, FrameAllocator}; pub struct StackAllocator { @@ -42,7 +42,7 @@ impl StackAllocator { // map stack pages to physical frames for page in Page::range_inclusive(start, end) { - active_table.map(page, paging::WRITABLE, frame_allocator); + active_table.map(page, EntryFlags::WRITABLE, frame_allocator); } // create a new stack