Merge branch 'fix-warnings' into 'master'
Fix warnings See merge request redox-os/kernel!114
This commit is contained in:
43
build.rs
43
build.rs
@@ -1,9 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::{Error, Write};
|
||||
use std::path::Path;
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
||||
// View loc folder with subfolders, get listings
|
||||
// Returns touple (folder_map, file_list)
|
||||
@@ -36,7 +35,9 @@ fn scan_folder(loc: &Path) -> (HashMap<String, Vec<String>>, Vec<String>) {
|
||||
}
|
||||
|
||||
current.sort();
|
||||
folders.entry(String::from(loc.to_str().unwrap()).replace("\\", "/")).or_insert(current);
|
||||
folders
|
||||
.entry(String::from(loc.to_str().unwrap()).replace("\\", "/"))
|
||||
.or_insert(current);
|
||||
} else {
|
||||
panic!("{:?} is not a folder!", loc);
|
||||
}
|
||||
@@ -45,9 +46,9 @@ fn scan_folder(loc: &Path) -> (HashMap<String, Vec<String>>, Vec<String>) {
|
||||
}
|
||||
|
||||
// Write folder/file information to output file
|
||||
fn fill_from_location(f: &mut fs::File, loc: &Path ) -> Result<(), (Error)> {
|
||||
fn fill_from_location(f: &mut fs::File, loc: &Path) -> Result<(), Error> {
|
||||
let (folders, mut files) = scan_folder(loc);
|
||||
let mut folder_it:Vec<_> = folders.keys().collect();
|
||||
let mut folder_it: Vec<_> = folders.keys().collect();
|
||||
|
||||
let loc_str = loc.to_str().unwrap();
|
||||
let mut idx = loc_str.len();
|
||||
@@ -80,7 +81,11 @@ fn fill_from_location(f: &mut fs::File, loc: &Path ) -> Result<(), (Error)> {
|
||||
|
||||
for name in files.iter() {
|
||||
let (_, strip) = name.split_at(idx);
|
||||
write!(f, " files.insert(b\"{}\", (include_bytes!(\"{}\"), false));\n", strip, name)?;
|
||||
write!(
|
||||
f,
|
||||
" files.insert(b\"{}\", (include_bytes!(\"{}\"), false));\n",
|
||||
strip, name
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -96,29 +101,39 @@ fn main() {
|
||||
let src = env::var("INITFS_FOLDER");
|
||||
|
||||
// Write header
|
||||
f.write_all(b"
|
||||
f.write_all(
|
||||
b"
|
||||
mod gen {
|
||||
use alloc::collections::BTreeMap;
|
||||
pub fn gen() -> BTreeMap<&'static [u8], (&'static [u8], bool)> {
|
||||
let mut files: BTreeMap<&'static [u8], (&'static [u8], bool)> = BTreeMap::new();
|
||||
").unwrap();
|
||||
",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
match src {
|
||||
Ok(v) => {
|
||||
println!("cargo:rerun-if-changed={}", v);
|
||||
fill_from_location(&mut f, Path::new(&v)).unwrap()
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
f.write_all(
|
||||
b" files.clear();" // Silence mutability warning
|
||||
).unwrap();
|
||||
println!("cargo:warning=location not found: {}, please set proper INITFS_FOLDER.", e);
|
||||
b" files.clear();", // Silence mutability warning
|
||||
)
|
||||
.unwrap();
|
||||
println!(
|
||||
"cargo:warning=location not found: {}, please set proper INITFS_FOLDER.",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
f.write_all(b"
|
||||
f.write_all(
|
||||
b"
|
||||
files
|
||||
}
|
||||
}
|
||||
").unwrap();
|
||||
",
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//! # Paging
|
||||
//! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html)
|
||||
|
||||
use core::{mem, ptr};
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use core::{mem, ptr};
|
||||
use spin::Mutex;
|
||||
use x86::shared::{control_regs, msr, tlb};
|
||||
|
||||
@@ -45,9 +45,7 @@ fn page_table_lock() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
crate::arch::interrupt::pause();
|
||||
}
|
||||
crate::arch::interrupt::pause();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,13 +73,22 @@ unsafe fn init_pat() {
|
||||
let pat6 = pat2;
|
||||
let pat7 = pat3;
|
||||
|
||||
msr::wrmsr(msr::IA32_PAT, pat7 << 56 | pat6 << 48 | pat5 << 40 | pat4 << 32
|
||||
| pat3 << 24 | pat2 << 16 | pat1 << 8 | pat0);
|
||||
msr::wrmsr(
|
||||
msr::IA32_PAT,
|
||||
pat7 << 56
|
||||
| pat6 << 48
|
||||
| pat5 << 40
|
||||
| pat4 << 32
|
||||
| pat3 << 24
|
||||
| pat2 << 16
|
||||
| pat1 << 8
|
||||
| pat0,
|
||||
);
|
||||
}
|
||||
|
||||
/// Copy tdata, clear tbss, set TCB self pointer
|
||||
unsafe fn init_tcb(cpu_id: usize) -> usize {
|
||||
extern {
|
||||
extern "C" {
|
||||
/// The starting byte of the thread data segment
|
||||
static mut __tdata_start: u8;
|
||||
/// The ending byte of the thread data segment
|
||||
@@ -94,14 +101,14 @@ unsafe fn init_tcb(cpu_id: usize) -> usize {
|
||||
|
||||
let tcb_offset;
|
||||
{
|
||||
let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize;
|
||||
let tbss_offset = & __tbss_start as *const _ as usize - & __tdata_start as *const _ as usize;
|
||||
let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize;
|
||||
let tbss_offset = &__tbss_start as *const _ as usize - &__tdata_start as *const _ as usize;
|
||||
|
||||
let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id;
|
||||
let end = start + size;
|
||||
tcb_offset = end - mem::size_of::<usize>();
|
||||
|
||||
ptr::copy(& __tdata_start as *const u8, start as *mut u8, tbss_offset);
|
||||
ptr::copy(&__tdata_start as *const u8, start as *mut u8, tbss_offset);
|
||||
ptr::write_bytes((start + tbss_offset) as *mut u8, 0, size - tbss_offset);
|
||||
|
||||
*(tcb_offset as *mut usize) = end;
|
||||
@@ -112,8 +119,14 @@ unsafe fn init_tcb(cpu_id: usize) -> usize {
|
||||
/// Initialize paging
|
||||
///
|
||||
/// Returns page table and thread control block offset
|
||||
pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_start: usize, stack_end: usize) -> (ActivePageTable, usize) {
|
||||
extern {
|
||||
pub unsafe fn init(
|
||||
cpu_id: usize,
|
||||
kernel_start: usize,
|
||||
kernel_end: usize,
|
||||
stack_start: usize,
|
||||
stack_end: usize,
|
||||
) -> (ActivePageTable, usize) {
|
||||
extern "C" {
|
||||
/// The starting byte of the text (code) data segment.
|
||||
static mut __text_start: u8;
|
||||
/// The ending byte of the text (code) data segment.
|
||||
@@ -144,7 +157,9 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
|
||||
|
||||
let mut active_table = ActivePageTable::new_unlocked();
|
||||
|
||||
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(crate::USER_TMP_MISC_OFFSET)));
|
||||
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(
|
||||
crate::USER_TMP_MISC_OFFSET,
|
||||
)));
|
||||
|
||||
let mut new_table = {
|
||||
let frame = allocate_frames(1).expect("no more frames in paging::init new_table");
|
||||
@@ -154,13 +169,28 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
|
||||
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
|
||||
// Remap stack writable, no execute
|
||||
{
|
||||
let start_frame = Frame::containing_address(PhysicalAddress::new(stack_start - crate::KERNEL_OFFSET));
|
||||
let end_frame = Frame::containing_address(PhysicalAddress::new(stack_end - crate::KERNEL_OFFSET - 1));
|
||||
let start_frame =
|
||||
Frame::containing_address(PhysicalAddress::new(stack_start - crate::KERNEL_OFFSET));
|
||||
let end_frame = Frame::containing_address(PhysicalAddress::new(
|
||||
stack_end - crate::KERNEL_OFFSET - 1,
|
||||
));
|
||||
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
||||
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + crate::KERNEL_OFFSET));
|
||||
let result = mapper.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
|
||||
let page = Page::containing_address(VirtualAddress::new(
|
||||
frame.start_address().get() + crate::KERNEL_OFFSET,
|
||||
));
|
||||
let result = mapper.map_to(
|
||||
page,
|
||||
frame,
|
||||
EntryFlags::PRESENT
|
||||
| EntryFlags::GLOBAL
|
||||
| EntryFlags::NO_EXECUTE
|
||||
| EntryFlags::WRITABLE,
|
||||
);
|
||||
// The flush can be ignored as this is not the active table. See later active_table.switch
|
||||
/* unsafe */ { result.ignore(); }
|
||||
/* unsafe */
|
||||
{
|
||||
result.ignore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,10 +203,10 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
|
||||
let virt_addr = phys_addr + crate::KERNEL_OFFSET;
|
||||
|
||||
macro_rules! in_section {
|
||||
($n: ident) => (
|
||||
virt_addr >= & concat_idents!(__, $n, _start) as *const u8 as usize &&
|
||||
virt_addr < & concat_idents!(__, $n, _end) as *const u8 as usize
|
||||
);
|
||||
($n: ident) => {
|
||||
virt_addr >= &concat_idents!(__, $n, _start) as *const u8 as usize
|
||||
&& virt_addr < &concat_idents!(__, $n, _end) as *const u8 as usize
|
||||
};
|
||||
}
|
||||
|
||||
let flags = if in_section!(text) {
|
||||
@@ -187,13 +217,19 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
|
||||
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE
|
||||
} else if in_section!(data) {
|
||||
// Remap data writable, no execute
|
||||
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE
|
||||
EntryFlags::PRESENT
|
||||
| EntryFlags::GLOBAL
|
||||
| EntryFlags::NO_EXECUTE
|
||||
| EntryFlags::WRITABLE
|
||||
} else if in_section!(tdata) {
|
||||
// Remap tdata master read-only, no execute
|
||||
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE
|
||||
} else if in_section!(bss) {
|
||||
// Remap bss writable, no execute
|
||||
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE
|
||||
EntryFlags::PRESENT
|
||||
| EntryFlags::GLOBAL
|
||||
| EntryFlags::NO_EXECUTE
|
||||
| EntryFlags::WRITABLE
|
||||
} else {
|
||||
// Remap anything else read-only, no execute
|
||||
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE
|
||||
@@ -202,13 +238,16 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
|
||||
let page = Page::containing_address(VirtualAddress::new(virt_addr));
|
||||
let result = mapper.map_to(page, frame, flags);
|
||||
// The flush can be ignored as this is not the active table. See later active_table.switch
|
||||
/* unsafe */ { result.ignore(); }
|
||||
/* unsafe */
|
||||
{
|
||||
result.ignore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map tdata and tbss
|
||||
{
|
||||
let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize;
|
||||
let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize;
|
||||
|
||||
let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id;
|
||||
let end = start + size;
|
||||
@@ -216,7 +255,13 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
|
||||
let start_page = Page::containing_address(VirtualAddress::new(start));
|
||||
let end_page = Page::containing_address(VirtualAddress::new(end - 1));
|
||||
for page in Page::range_inclusive(start_page, end_page) {
|
||||
let result = mapper.map(page, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
|
||||
let result = mapper.map(
|
||||
page,
|
||||
EntryFlags::PRESENT
|
||||
| EntryFlags::GLOBAL
|
||||
| EntryFlags::NO_EXECUTE
|
||||
| EntryFlags::WRITABLE,
|
||||
);
|
||||
// The flush can be ignored as this is not the active table. See later active_table.switch
|
||||
result.ignore();
|
||||
}
|
||||
@@ -230,8 +275,13 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
|
||||
(active_table, init_tcb(cpu_id))
|
||||
}
|
||||
|
||||
pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack_end: usize) -> usize {
|
||||
extern {
|
||||
pub unsafe fn init_ap(
|
||||
cpu_id: usize,
|
||||
bsp_table: usize,
|
||||
stack_start: usize,
|
||||
stack_end: usize,
|
||||
) -> usize {
|
||||
extern "C" {
|
||||
/// The starting byte of the thread data segment
|
||||
static mut __tdata_start: u8;
|
||||
/// The ending byte of the thread data segment
|
||||
@@ -248,12 +298,14 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
|
||||
|
||||
let mut new_table = InactivePageTable::from_address(bsp_table);
|
||||
|
||||
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(crate::USER_TMP_MISC_OFFSET)));
|
||||
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(
|
||||
crate::USER_TMP_MISC_OFFSET,
|
||||
)));
|
||||
|
||||
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
|
||||
// Map tdata and tbss
|
||||
{
|
||||
let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize;
|
||||
let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize;
|
||||
|
||||
let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id;
|
||||
let end = start + size;
|
||||
@@ -261,7 +313,13 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
|
||||
let start_page = Page::containing_address(VirtualAddress::new(start));
|
||||
let end_page = Page::containing_address(VirtualAddress::new(end - 1));
|
||||
for page in Page::range_inclusive(start_page, end_page) {
|
||||
let result = mapper.map(page, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
|
||||
let result = mapper.map(
|
||||
page,
|
||||
EntryFlags::PRESENT
|
||||
| EntryFlags::GLOBAL
|
||||
| EntryFlags::NO_EXECUTE
|
||||
| EntryFlags::WRITABLE,
|
||||
);
|
||||
// The flush can be ignored as this is not the active table. See later active_table.switch
|
||||
result.ignore();
|
||||
}
|
||||
@@ -272,7 +330,9 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
|
||||
let start_frame = Frame::containing_address(PhysicalAddress::new(start));
|
||||
let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1));
|
||||
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
||||
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + crate::KERNEL_OFFSET));
|
||||
let page = Page::containing_address(VirtualAddress::new(
|
||||
frame.start_address().get() + crate::KERNEL_OFFSET,
|
||||
));
|
||||
let result = mapper.map_to(page, frame, flags);
|
||||
// The flush can be ignored as this is not the active table. See later active_table.switch
|
||||
result.ignore();
|
||||
@@ -281,7 +341,14 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
|
||||
};
|
||||
|
||||
// Remap stack writable, no execute
|
||||
remap(stack_start - crate::KERNEL_OFFSET, stack_end - crate::KERNEL_OFFSET, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
|
||||
remap(
|
||||
stack_start - crate::KERNEL_OFFSET,
|
||||
stack_end - crate::KERNEL_OFFSET,
|
||||
EntryFlags::PRESENT
|
||||
| EntryFlags::GLOBAL
|
||||
| EntryFlags::NO_EXECUTE
|
||||
| EntryFlags::WRITABLE,
|
||||
);
|
||||
});
|
||||
|
||||
// This switches the active table, which is setup by the bootloader, to a correct table
|
||||
@@ -328,9 +395,9 @@ impl ActivePageTable {
|
||||
|
||||
pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
|
||||
let old_table = InactivePageTable {
|
||||
p4_frame: Frame::containing_address(
|
||||
PhysicalAddress::new(unsafe { control_regs::cr3() } as usize)
|
||||
),
|
||||
p4_frame: Frame::containing_address(PhysicalAddress::new(
|
||||
unsafe { control_regs::cr3() } as usize,
|
||||
)),
|
||||
};
|
||||
unsafe {
|
||||
control_regs::cr3_write(new_table.p4_frame.start_address().get() as u64);
|
||||
@@ -339,31 +406,52 @@ impl ActivePageTable {
|
||||
}
|
||||
|
||||
pub fn flush(&mut self, page: Page) {
|
||||
unsafe { tlb::flush(page.start_address().get()); }
|
||||
unsafe {
|
||||
tlb::flush(page.start_address().get());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flush_all(&mut self) {
|
||||
unsafe { tlb::flush_all(); }
|
||||
unsafe {
|
||||
tlb::flush_all();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with<F>(&mut self, table: &mut InactivePageTable, temporary_page: &mut TemporaryPage, f: F)
|
||||
where F: FnOnce(&mut Mapper)
|
||||
pub fn with<F>(
|
||||
&mut self,
|
||||
table: &mut InactivePageTable,
|
||||
temporary_page: &mut TemporaryPage,
|
||||
f: F,
|
||||
) where
|
||||
F: FnOnce(&mut Mapper),
|
||||
{
|
||||
{
|
||||
let backup = Frame::containing_address(PhysicalAddress::new(unsafe { control_regs::cr3() as usize }));
|
||||
let backup = Frame::containing_address(PhysicalAddress::new(unsafe {
|
||||
control_regs::cr3() as usize
|
||||
}));
|
||||
|
||||
// map temporary_page to current p4 table
|
||||
let p4_table = temporary_page.map_table_frame(backup.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, self);
|
||||
let p4_table = temporary_page.map_table_frame(
|
||||
backup.clone(),
|
||||
EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE,
|
||||
self,
|
||||
);
|
||||
|
||||
// overwrite recursive mapping
|
||||
self.p4_mut()[crate::RECURSIVE_PAGE_PML4].set(table.p4_frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
|
||||
self.p4_mut()[crate::RECURSIVE_PAGE_PML4].set(
|
||||
table.p4_frame.clone(),
|
||||
EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE,
|
||||
);
|
||||
self.flush_all();
|
||||
|
||||
// execute f in the new context
|
||||
f(self);
|
||||
|
||||
// restore recursive mapping to original p4 table
|
||||
p4_table[crate::RECURSIVE_PAGE_PML4].set(backup, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
|
||||
p4_table[crate::RECURSIVE_PAGE_PML4].set(
|
||||
backup,
|
||||
EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE,
|
||||
);
|
||||
self.flush_all();
|
||||
}
|
||||
|
||||
@@ -389,13 +477,24 @@ pub struct InactivePageTable {
|
||||
}
|
||||
|
||||
impl InactivePageTable {
|
||||
pub fn new(frame: Frame, active_table: &mut ActivePageTable, temporary_page: &mut TemporaryPage) -> InactivePageTable {
|
||||
pub fn new(
|
||||
frame: Frame,
|
||||
active_table: &mut ActivePageTable,
|
||||
temporary_page: &mut TemporaryPage,
|
||||
) -> InactivePageTable {
|
||||
{
|
||||
let table = temporary_page.map_table_frame(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, active_table);
|
||||
let table = temporary_page.map_table_frame(
|
||||
frame.clone(),
|
||||
EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE,
|
||||
active_table,
|
||||
);
|
||||
// now we are able to zero the table
|
||||
table.zero();
|
||||
// set up recursive mapping for the table
|
||||
table[crate::RECURSIVE_PAGE_PML4].set(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
|
||||
table[crate::RECURSIVE_PAGE_PML4].set(
|
||||
frame.clone(),
|
||||
EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE,
|
||||
);
|
||||
}
|
||||
temporary_page.unmap(active_table);
|
||||
|
||||
@@ -403,7 +502,9 @@ impl InactivePageTable {
|
||||
}
|
||||
|
||||
pub unsafe fn from_address(cr3: usize) -> InactivePageTable {
|
||||
InactivePageTable { p4_frame: Frame::containing_address(PhysicalAddress::new(cr3)) }
|
||||
InactivePageTable {
|
||||
p4_frame: Frame::containing_address(PhysicalAddress::new(cr3)),
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn address(&self) -> usize {
|
||||
@@ -442,7 +543,7 @@ impl VirtualAddress {
|
||||
/// Page
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Page {
|
||||
number: usize
|
||||
number: usize,
|
||||
}
|
||||
|
||||
impl Page {
|
||||
@@ -469,7 +570,9 @@ impl Page {
|
||||
pub fn containing_address(address: VirtualAddress) -> Page {
|
||||
//TODO assert!(address.get() < 0x0000_8000_0000_0000 || address.get() >= 0xffff_8000_0000_0000,
|
||||
// "invalid address: 0x{:x}", address.get());
|
||||
Page { number: address.get() / PAGE_SIZE }
|
||||
Page {
|
||||
number: address.get() / PAGE_SIZE,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn range_inclusive(start: Page, end: Page) -> PageIter {
|
||||
@@ -477,7 +580,9 @@ impl Page {
|
||||
}
|
||||
|
||||
pub fn next(self) -> Page {
|
||||
Self { number: self.number + 1 }
|
||||
Self {
|
||||
number: self.number + 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use core::convert::TryInto;
|
||||
|
||||
use crate::syscall::io::{Io, Pio, Mmio, ReadOnly};
|
||||
use crate::syscall::io::{Io, Mmio, Pio, ReadOnly};
|
||||
|
||||
bitflags! {
|
||||
/// Interrupt enable flags
|
||||
@@ -51,7 +51,7 @@ impl SerialPort<Pio<u8>> {
|
||||
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))
|
||||
modem_sts: ReadOnly::new(Pio::new(base + 6)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,30 +63,37 @@ impl SerialPort<Mmio<u32>> {
|
||||
}
|
||||
|
||||
impl<T: Io> SerialPort<T>
|
||||
where T::Value: From<u8> + TryInto<u8>
|
||||
where
|
||||
T::Value: From<u8> + TryInto<u8>,
|
||||
{
|
||||
pub fn init(&mut self) {
|
||||
//TODO: Cleanup
|
||||
self.int_en.write(0x00.into());
|
||||
self.line_ctrl.write(0x80.into());
|
||||
self.data.write(0x01.into());
|
||||
self.int_en.write(0x00.into());
|
||||
self.line_ctrl.write(0x03.into());
|
||||
self.fifo_ctrl.write(0xC7.into());
|
||||
self.modem_ctrl.write(0x0B.into());
|
||||
self.int_en.write(0x01.into());
|
||||
unsafe {
|
||||
self.int_en.write(0x00.into());
|
||||
self.line_ctrl.write(0x80.into());
|
||||
self.data.write(0x01.into());
|
||||
self.int_en.write(0x00.into());
|
||||
self.line_ctrl.write(0x03.into());
|
||||
self.fifo_ctrl.write(0xC7.into());
|
||||
self.modem_ctrl.write(0x0B.into());
|
||||
self.int_en.write(0x01.into());
|
||||
}
|
||||
}
|
||||
|
||||
fn line_sts(&self) -> LineStsFlags {
|
||||
LineStsFlags::from_bits_truncate(
|
||||
(self.line_sts.read() & 0xFF.into()).try_into().unwrap_or(0)
|
||||
(unsafe { self.line_sts.read() } & 0xFF.into())
|
||||
.try_into()
|
||||
.unwrap_or(0),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn receive(&mut self) -> Option<u8> {
|
||||
if self.line_sts().contains(LineStsFlags::INPUT_FULL) {
|
||||
Some(
|
||||
(self.data.read() & 0xFF.into()).try_into().unwrap_or(0)
|
||||
(unsafe { self.data.read() } & 0xFF.into())
|
||||
.try_into()
|
||||
.unwrap_or(0),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@@ -94,8 +101,8 @@ impl<T: Io> SerialPort<T>
|
||||
}
|
||||
|
||||
pub fn send(&mut self, data: u8) {
|
||||
while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {}
|
||||
self.data.write(data.into());
|
||||
while !self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {}
|
||||
unsafe { self.data.write(data.into()) }
|
||||
}
|
||||
|
||||
pub fn write(&mut self, buf: &[u8]) {
|
||||
@@ -105,11 +112,11 @@ impl<T: Io> SerialPort<T>
|
||||
self.send(8);
|
||||
self.send(b' ');
|
||||
self.send(8);
|
||||
},
|
||||
}
|
||||
b'\n' => {
|
||||
self.send(b'\r');
|
||||
self.send(b'\n');
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
self.send(b);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user