Skip to content
Browse files

Match x86 paging with x86_64

  • Loading branch information...
1 parent c026a58 commit 377adb53d86b46d829b3d534a012434be77b5372 @jackpot51 jackpot51 committed
Showing with 90 additions and 96 deletions.
  1. +49 −30 kernel/arch/x86_64/paging.rs
  2. +40 −65 kernel/disk/ide.rs
  3. +1 −1 x86_64-unknown-redox.json
View
79 kernel/arch/x86_64/paging.rs
@@ -1,5 +1,23 @@
use core::ptr;
+//Page flags
+pub const PF_PRESENT: usize = 1;
+pub const PF_WRITE: usize = 1 << 1;
+pub const PF_USER: usize = 1 << 2;
+pub const PF_WRITE_THROUGH: usize = 1 << 3;
+pub const PF_CACHE_DISABLE: usize = 1 << 4;
+pub const PF_ACCESSED: usize = 1 << 5;
+pub const PF_DIRTY: usize = 1 << 6;
+pub const PF_SIZE: usize = 1 << 7;
+pub const PF_GLOBAL: usize = 1 << 8;
+//Extra flags (Redox specific)
+pub const PF_ALLOC: usize = 1 << 9;
+pub const PF_EXEC: usize = 1 << 10;
+pub const PF_STACK: usize = 1 << 11;
+
+pub const PF_ALL: usize = 0xFFF;
+pub const PF_NONE: usize = 0xFFFFFFFFFFFFF000;
+
// PAGE_LEVEL_4:
// 512 qwords pointing to page directory pointers
// PAGE_DIR_PTRS:
@@ -32,32 +50,32 @@ impl Page {
pub unsafe fn init() {
for l4_i in 0..PAGE_TABLE_SIZE {
if l4_i == 0 {
- ptr::write((PAGE_LEVEL_4 + l4_i * PAGE_ENTRY_SIZE) as *mut u64,
- (PAGE_DIR_PTRS + l4_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) as u64 |
- 1 << 2 | 0b11 << 1 | 1); //Allow userspace, read/write, present
+ ptr::write((PAGE_LEVEL_4 + l4_i * PAGE_ENTRY_SIZE) as *mut usize,
+ (PAGE_DIR_PTRS + l4_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) |
+ PF_USER | PF_WRITE | PF_PRESENT); //Allow userspace, read/write, present
} else {
- ptr::write((PAGE_LEVEL_4 + l4_i * PAGE_ENTRY_SIZE) as *mut u64, 0);
+ ptr::write((PAGE_LEVEL_4 + l4_i * PAGE_ENTRY_SIZE) as *mut usize, 0);
}
}
for dp_i in 0..PAGE_TABLE_SIZE {
if dp_i < 4 {
- ptr::write((PAGE_DIR_PTRS + dp_i * PAGE_ENTRY_SIZE) as *mut u64,
- (PAGE_DIRECTORIES + dp_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) as u64 |
- 1 << 2 |
- 0b11 << 1 | 1); //Allow userspace, read/write, present
+ ptr::write((PAGE_DIR_PTRS + dp_i * PAGE_ENTRY_SIZE) as *mut usize,
+ (PAGE_DIRECTORIES + dp_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) |
+ PF_USER | PF_WRITE | PF_PRESENT); //Allow userspace, read/write, present
} else {
- ptr::write((PAGE_DIR_PTRS + dp_i * PAGE_ENTRY_SIZE) as *mut u64, 0);
+ ptr::write((PAGE_DIR_PTRS + dp_i * PAGE_ENTRY_SIZE) as *mut usize, 0);
}
}
for table_i in 0..4 * PAGE_TABLE_SIZE {
- ptr::write((PAGE_DIRECTORIES + table_i * PAGE_ENTRY_SIZE) as *mut u64,
- (PAGE_TABLES + table_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) as u64 |
- 1 << 2 | 0b11 << 1 | 1); //Allow userspace, read/write, present
+ ptr::write((PAGE_DIRECTORIES + table_i * PAGE_ENTRY_SIZE) as *mut usize,
+ (PAGE_TABLES + table_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) |
+ PF_USER | PF_WRITE | PF_PRESENT); //Allow userspace, read/write, present
for entry_i in 0..PAGE_TABLE_SIZE {
- Page::new((table_i * PAGE_TABLE_SIZE + entry_i) * PAGE_SIZE).map_identity();
+ let addr = (table_i * PAGE_TABLE_SIZE + entry_i) * PAGE_SIZE;
+ Page::new(addr).map_kernel_write(addr);
}
}
@@ -66,7 +84,7 @@ impl Page {
or $0, $1
mov cr0, $0"
:
- : "r"(PAGE_LEVEL_4), "r"(0x80000000 as usize)
+ : "r"(PAGE_LEVEL_4), "r"((1 << 31 | 1 << 16) as usize)
: "memory"
: "intel", "volatile");
}
@@ -96,44 +114,45 @@ impl Page {
/// Get the current physical address
pub fn phys_addr(&self) -> usize {
- unsafe { (ptr::read(self.entry_address() as *mut u64) & 0xFFFFFFFFFFFFF000) as usize }
+ unsafe { (ptr::read(self.entry_address() as *mut usize) & PF_NONE) as usize }
}
/// Get the current virtual address
pub fn virt_addr(&self) -> usize {
- self.virtual_address & 0xFFFFFFFFFFFFF000
+ self.virtual_address & PF_NONE
}
/// Map the memory page to a given physical memory address
- pub unsafe fn map(&mut self, physical_address: usize) {
- ptr::write(self.entry_address() as *mut u64,
- (physical_address as u64 & 0xFFFFFFFFFFFFF000) | 1); //present
+ pub unsafe fn map_kernel_read(&mut self, physical_address: usize) {
+ ptr::write(self.entry_address() as *mut usize,
+ (physical_address & PF_NONE) | PF_PRESENT); //present
+ self.flush();
+ }
+
+ /// Map the memory page to a given physical memory address and allow userspace read access
+ pub unsafe fn map_kernel_write(&mut self, physical_address: usize) {
+ ptr::write(self.entry_address() as *mut usize,
+ (physical_address & PF_NONE) | PF_WRITE | PF_PRESENT); //Allow write, present
self.flush();
}
/// Map the memory page to a given physical memory address and allow userspace read access
pub unsafe fn map_user_read(&mut self, physical_address: usize) {
- ptr::write(self.entry_address() as *mut u64,
- (physical_address as u64 & 0xFFFFFFFFFFFFF000) | 1 << 2 | 1); //Allow userspace, present
+ ptr::write(self.entry_address() as *mut usize,
+ (physical_address & PF_NONE) | PF_USER | PF_PRESENT); //Allow userspace, present
self.flush();
}
/// Map the memory page to a given physical memory address and allow userspace read/write access
pub unsafe fn map_user_write(&mut self, physical_address: usize) {
- ptr::write(self.entry_address() as *mut u64,
- (physical_address as u64 & 0xFFFFFFFFFFFFF000) | 1 << 2 | 1 << 1 | 1); //Allow userspace, read/write, present
+ ptr::write(self.entry_address() as *mut usize,
+ (physical_address & PF_NONE) | PF_USER | PF_WRITE | PF_PRESENT); //Allow userspace, read/write, present
self.flush();
}
- /// Map to the virtual address
- pub unsafe fn map_identity(&mut self) {
- let physical_address = self.virtual_address;
- self.map(physical_address);
- }
-
/// Unmap the memory page
pub unsafe fn unmap(&mut self) {
- ptr::write(self.entry_address() as *mut u64, 0);
+ ptr::write(self.entry_address() as *mut usize, 0);
self.flush();
}
}
View
105 kernel/disk/ide.rs
@@ -231,6 +231,35 @@ impl IdeDisk {
0
}
+ pub fn ata(&mut self, cmd: u8, block: u64, len: u16) {
+ while self.cmdsts.readf(ATA_SR_BSY) {}
+
+ self.devsel.write(if self.master {
+ 0x40
+ } else {
+ 0x40 | 0x10
+ });
+
+ self.ctrl.read();
+ self.ctrl.read();
+ self.ctrl.read();
+ self.ctrl.read();
+
+ while self.cmdsts.readf(ATA_SR_BSY) {}
+
+ self.seccount.write((len >> 8) as u8);
+ self.sector0.write((block >> 24) as u8);
+ self.sector1.write((block >> 32) as u8);
+ self.sector2.write((block >> 40) as u8);
+
+ self.seccount.write(len as u8);
+ self.sector0.write(block as u8);
+ self.sector1.write((block >> 8) as u8);
+ self.sector2.write((block >> 16) as u8);
+
+ self.cmdsts.write(cmd);
+ }
+
/// Identify
pub unsafe fn identify(&mut self) -> bool {
if self.cmdsts.read() == 0xFF {
@@ -239,20 +268,7 @@ impl IdeDisk {
return false;
}
- while self.cmdsts.readf(ATA_SR_BSY) {}
-
- if self.master {
- self.devsel.write(0xA0);
- } else {
- self.devsel.write(0xB0);
- }
-
- self.seccount.write(0);
- self.sector0.write(0);
- self.sector1.write(0);
- self.sector2.write(0);
-
- self.cmdsts.write(ATA_CMD_IDENTIFY);
+ self.ata(ATA_CMD_IDENTIFY, 0, 0);
let status = self.cmdsts.read();
debug!(" Status: {:X}", status);
@@ -332,29 +348,11 @@ impl IdeDisk {
write: bool)
-> Result<usize> {
if buf > 0 {
- while self.cmdsts.readf(ATA_SR_BSY) {}
-
- if self.master {
- self.devsel.write(0x40);
- } else {
- self.devsel.write(0x50);
- }
-
- self.seccount.write(((sectors >> 8) & 0xFF) as u8);
- self.sector0.write(((block >> 24) & 0xFF) as u8);
- self.sector1.write(((block >> 32) & 0xFF) as u8);
- self.sector2.write(((block >> 40) & 0xFF) as u8);
-
- self.seccount.write(((sectors >> 0) & 0xFF) as u8);
- self.sector0.write(((block >> 0) & 0xFF) as u8);
- self.sector1.write(((block >> 8) & 0xFF) as u8);
- self.sector2.write(((block >> 16) & 0xFF) as u8);
-
- if write {
- self.cmdsts.write(ATA_CMD_WRITE_PIO_EXT);
+ self.ata(if write {
+ ATA_CMD_WRITE_PIO_EXT
} else {
- self.cmdsts.write(ATA_CMD_READ_PIO_EXT);
- }
+ ATA_CMD_READ_PIO_EXT
+ }, block, sectors);
for sector in 0..sectors as usize {
let err = self.ide_poll(true);
@@ -385,7 +383,7 @@ impl IdeDisk {
}
fn ata_pio(&mut self, block: u64, sectors: usize, buf: usize, write: bool) -> Result<usize> {
- // debugln!("IDE PIO BLOCK: {:X} SECTORS: {} BUF: {:X} WRITE: {}", block, sectors, buf, write);
+ // debugln!("IDE PIO BLOCK: {} SECTORS: {} BUF: {:X} WRITE: {}", block, sectors, buf, write);
if buf > 0 && sectors > 0 {
let mut sector: usize = 0;
@@ -468,29 +466,12 @@ impl IdeDisk {
self.buscmd.writef(CMD_DIR, !write);
- while self.cmdsts.readf(ATA_SR_BSY) {}
- if self.master {
- self.devsel.write(0x40);
+ self.ata(if write {
+ ATA_CMD_WRITE_DMA_EXT
} else {
- self.devsel.write(0x50);
- }
-
- self.seccount.write(((sectors >> 8) & 0xFF) as u8);
- self.sector0.write(((block >> 24) & 0xFF) as u8);
- self.sector1.write(((block >> 32) & 0xFF) as u8);
- self.sector2.write(((block >> 40) & 0xFF) as u8);
-
- self.seccount.write(((sectors >> 0) & 0xFF) as u8);
- self.sector0.write(((block >> 0) & 0xFF) as u8);
- self.sector1.write(((block >> 8) & 0xFF) as u8);
- self.sector2.write(((block >> 16) & 0xFF) as u8);
-
- if write {
- self.cmdsts.write(ATA_CMD_WRITE_DMA_EXT);
- } else {
- self.cmdsts.write(ATA_CMD_READ_DMA_EXT);
- }
+ ATA_CMD_READ_DMA_EXT
+ }, block, sectors);
self.buscmd.writef(CMD_ACT, true);
@@ -516,7 +497,7 @@ impl IdeDisk {
}
fn ata_dma(&mut self, block: u64, sectors: usize, buf: usize, write: bool) -> Result<usize> {
- // debugln!("IDE DMA BLOCK: {:X} SECTORS: {} BUF: {:X} WRITE: {}", block, sectors, buf, write);
+ // debugln!("IDE DMA BLOCK: {} SECTORS: {} BUF: {:X} WRITE: {}", block, sectors, buf, write);
if buf > 0 && sectors > 0 {
let mut sector: usize = 0;
@@ -562,16 +543,10 @@ impl Disk for IdeDisk {
}
fn read(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
- if buffer.as_ptr() as usize % 512 > 0 {
- panic!("IdeDisk::read not aligned");
- }
self.ata_dma(block, buffer.len() / 512, buffer.as_ptr() as usize, false)
}
fn write(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
- if buffer.as_ptr() as usize % 512 > 0 {
- panic!("IdeDisk::write not aligned");
- }
self.ata_dma(block, buffer.len() / 512, buffer.as_ptr() as usize, true)
}
}
View
2 x86_64-unknown-redox.json
@@ -7,7 +7,7 @@
"env": "",
"vendor": "unknown",
"pre-link-args": ["-m64", "-nostdlib", "-static", "build/x86_64-unknown-redox/debug/crt0.o"],
- "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2",
+ "features": "-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2",
"dynamic-linking": false,
"executables": true,
"relocation-model": "static",

0 comments on commit 377adb5

Please sign in to comment.
Something went wrong with that request. Please try again.