mirror of
https://github.com/realmicrosoft/windows.git
synced 2024-08-14 22:46:44 +00:00
Compare commits
2 commits
50970fa2cc
...
eb1e469fdc
Author | SHA1 | Date | |
---|---|---|---|
|
eb1e469fdc | ||
|
5f130d43e1 |
5 changed files with 112 additions and 88 deletions
118
src/boot/mod.rs
118
src/boot/mod.rs
|
@ -1,12 +1,13 @@
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use acpi::{AcpiHandler, PhysicalMapping};
|
use core::ptr::NonNull;
|
||||||
use crate::{debug, KernelArgs};
|
use acpi::{AcpiHandler, InterruptModel, PhysicalMapping};
|
||||||
|
use crate::{debug, KernelArgs, println};
|
||||||
|
|
||||||
#[cfg(feature = "f_multiboot2")]
|
#[cfg(feature = "f_multiboot2")]
|
||||||
use multiboot2::{load, MemoryMapTag, BootInformation};
|
use multiboot2::{load, MemoryMapTag, BootInformation};
|
||||||
use x86_64::structures::paging::{FrameAllocator, OffsetPageTable};
|
use x86_64::structures::paging::{FrameAllocator, Mapper, OffsetPageTable, Translate};
|
||||||
use crate::memory::BootInfoFrameAllocator;
|
use crate::memory::{BootInfoFrameAllocator, FRAME_ALLOC, MEM_MAPPER};
|
||||||
|
|
||||||
pub struct KernelInfo {
|
pub struct KernelInfo {
|
||||||
kernel_start: u64,
|
kernel_start: u64,
|
||||||
|
@ -16,6 +17,48 @@ pub struct KernelInfo {
|
||||||
boot_info: BootInformation,
|
boot_info: BootInformation,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Handler;
|
||||||
|
impl AcpiHandler for Handler {
|
||||||
|
unsafe fn map_physical_region<T>(&self, physical_address: usize, size: usize) -> PhysicalMapping<Self, T> {
|
||||||
|
// todo! check if size is too big
|
||||||
|
debug!("read_phys_memory32: addr {:x} not mapped", physical_address);
|
||||||
|
// map the page
|
||||||
|
let frame = FRAME_ALLOC.lock().as_mut().unwrap().allocate_frame().unwrap();
|
||||||
|
debug!("allocated frame: {:?}", frame);
|
||||||
|
let flags = x86_64::structures::paging::PageTableFlags::PRESENT | x86_64::structures::paging::PageTableFlags::WRITABLE;
|
||||||
|
let page = x86_64::structures::paging::Page::containing_address(initaladdr);
|
||||||
|
debug!("mapped page: {:?}", page);
|
||||||
|
let map_to_result = unsafe { MEM_MAPPER.lock().as_mut().unwrap().map_to(page, frame, flags, FRAME_ALLOC.lock().as_mut().unwrap()) };
|
||||||
|
debug!("map_to_result: {:?}", map_to_result);
|
||||||
|
if map_to_result.is_err() {
|
||||||
|
panic!("Failed to map page");
|
||||||
|
}
|
||||||
|
let addr = unsafe { MEM_MAPPER.lock().as_mut().unwrap().translate_addr(initaladdr) };
|
||||||
|
if let Some(addr) = addr {
|
||||||
|
// physical start, virtual start, region length, mapped length, Self
|
||||||
|
PhysicalMapping::new(
|
||||||
|
physical_address,
|
||||||
|
NonNull::new_unchecked(addr.as_u64() as *mut T),
|
||||||
|
size, size,
|
||||||
|
Self)
|
||||||
|
} else {
|
||||||
|
panic!("Failed to map page");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unmap_physical_region<T>(region: &PhysicalMapping<Self, T>) {
|
||||||
|
// get page
|
||||||
|
let page = x86_64::structures::paging::Page::containing_address(region.start_address());
|
||||||
|
// unmap page
|
||||||
|
let res = unsafe { MEM_MAPPER.lock().as_mut().unwrap().unmap(page) };
|
||||||
|
// it isn't *that* important if we don't unmap successfully at the moment, so just write a warning if we fail
|
||||||
|
if res.is_err() {
|
||||||
|
println!("[WARN] failed to unmap page");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl KernelInfo {
|
impl KernelInfo {
|
||||||
pub fn init_from_kernel_args(args: KernelArgs) -> Self {
|
pub fn init_from_kernel_args(args: KernelArgs) -> Self {
|
||||||
#[cfg(feature = "f_multiboot2")]
|
#[cfg(feature = "f_multiboot2")]
|
||||||
|
@ -56,64 +99,29 @@ impl KernelInfo {
|
||||||
self.safe_mem_start
|
self.safe_mem_start
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn acpi_get_ioapic_addr(&self, mem_mapper: &mut OffsetPageTable, frame_allocator: &mut BootInfoFrameAllocator) -> u64 {
|
pub fn acpi_get_ioapic_addr(&self) -> u32 {
|
||||||
#[cfg(feature = "f_multiboot2")]
|
#[cfg(feature = "f_multiboot2")]
|
||||||
{
|
{
|
||||||
let acpi_tag = self.boot_info.rsdp_v1_tag().expect("no acpi tag");
|
let acpi_tag = self.boot_info.rsdp_v1_tag().expect("no acpi tag");
|
||||||
let rsdp = acpi_tag;
|
let rsdp = acpi_tag;
|
||||||
let rsdp = unsafe { &*rsdp };
|
let rsdp = unsafe { &*rsdp };
|
||||||
let rsdt = rsdp.rsdt_address();
|
let rsdt = rsdp.rsdt_address();
|
||||||
#[derive(Clone)]
|
let rsdt = unsafe {
|
||||||
struct Handler<'a> {
|
acpi::AcpiTables::from_rsdt(
|
||||||
mem_mapper: Arc<&'a mut OffsetPageTable<'a>>,
|
AcpiHandler, 0,
|
||||||
frame_allocator: Arc<&'a mut BootInfoFrameAllocator>,
|
rsdt)
|
||||||
|
.expect("failed to get acpi tables")
|
||||||
|
};
|
||||||
|
let platform_info = rsdt.platform_info().expect("failed to get platform info");
|
||||||
|
let interrupt_model = platform_info.interrupt_model;
|
||||||
|
if let InterruptModel::Apic(apic) = interrupt_model {
|
||||||
|
let ioapics = apic.io_apics;
|
||||||
|
let ioapic = ioapics.first().expect("no ioapics");
|
||||||
|
let ioapic_addr = ioapic.address;
|
||||||
|
ioapic_addr
|
||||||
|
} else {
|
||||||
|
panic!("no ioapic");
|
||||||
}
|
}
|
||||||
impl<'a> AcpiHandler for Handler<'a> {
|
|
||||||
unsafe fn map_physical_region<T>(&self, physical_address: usize, size: usize) -> PhysicalMapping<Self, T> {
|
|
||||||
let frame_allocator = self.frame_allocator.clone();
|
|
||||||
debug!("read_phys_memory32: addr {:x} not mapped", physical_address);
|
|
||||||
// map the page
|
|
||||||
let frame = frame_allocator.allocate_frame().unwrap();
|
|
||||||
debug!("allocated frame: {:?}", frame);
|
|
||||||
let flags = x86_64::structures::paging::PageTableFlags::PRESENT | x86_64::structures::paging::PageTableFlags::WRITABLE;
|
|
||||||
let page = x86_64::structures::paging::Page::containing_address(initaladdr);
|
|
||||||
debug!("mapped page: {:?}", page);
|
|
||||||
let map_to_result = unsafe { mem_mapper.map_to(page, frame, flags, frame_allocator) };
|
|
||||||
debug!("map_to_result: {:?}", map_to_result);
|
|
||||||
if map_to_result.is_err() {
|
|
||||||
panic!("Failed to map page");
|
|
||||||
}
|
|
||||||
let addr = unsafe { mem_mapper.translate_addr(initaladdr) };
|
|
||||||
if let Some(addr) = addr {
|
|
||||||
let addr = addr.as_u64() as *const u32;
|
|
||||||
unsafe { *addr }
|
|
||||||
} else {
|
|
||||||
panic!("Failed to map page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unmap_physical_region<T>(region: &PhysicalMapping<Self, T>) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let rsdt = acpi::AcpiTables::from_rsdt(rsdt).expect("failed to get acpi tables");
|
|
||||||
let mut ioapic_addr = 0;
|
|
||||||
for entry in rsdt.entries() {
|
|
||||||
let entry = unsafe { &*entry };
|
|
||||||
if entry.signature() == *b"APIC" {
|
|
||||||
let apic = entry.as_apic();
|
|
||||||
let apic = unsafe { &*apic };
|
|
||||||
for entry in apic.entries() {
|
|
||||||
let entry = unsafe { &*entry };
|
|
||||||
if entry.signature() == *b"IOAP" {
|
|
||||||
let ioapic = entry.as_ioapic();
|
|
||||||
let ioapic = unsafe { &*ioapic };
|
|
||||||
ioapic_addr = ioapic.address();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ioapic_addr
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -47,23 +47,23 @@ pub fn get_apic_base() -> usize {
|
||||||
((edx as usize) << 32) | (eax as usize)
|
((edx as usize) << 32) | (eax as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_apic(mem_mapper: &mut OffsetPageTable, frame_alloc: &mut BootInfoFrameAllocator) {
|
pub fn enable_apic() {
|
||||||
// PIC should be disabled by now
|
// PIC should be disabled by now
|
||||||
// now enable local apic
|
// now enable local apic
|
||||||
// 1. set bit 8 of spurious interrupt vector register
|
// 1. set bit 8 of spurious interrupt vector register
|
||||||
let sivr_addr = 0xfee000f0;
|
let sivr_addr = 0xfee000f0;
|
||||||
let sivr = read_phys_memory32(mem_mapper, frame_alloc, sivr_addr);
|
let sivr = read_phys_memory32(sivr_addr);
|
||||||
write_phys_memory32(mem_mapper, frame_alloc, sivr_addr, sivr | (1 << 8));
|
write_phys_memory32(sivr_addr, sivr | (1 << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apic_read_io(mem_mapper: &mut OffsetPageTable, frame_alloc: &mut BootInfoFrameAllocator, ioapicaddr: usize, reg: u32) -> u32 {
|
pub fn apic_read_io(ioapicaddr: u32, reg: u32) -> u32 {
|
||||||
write_phys_memory32(mem_mapper, frame_alloc, ioapicaddr as u32, reg);
|
write_phys_memory32(ioapicaddr as u32, reg);
|
||||||
read_phys_memory32(mem_mapper, frame_alloc, ioapicaddr as u32 + 0x10)
|
read_phys_memory32(ioapicaddr as u32 + 0x10)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apic_write_io(mem_mapper: &mut OffsetPageTable, frame_alloc: &mut BootInfoFrameAllocator, ioapicaddr: usize, reg: u32, val: u32) {
|
pub fn apic_write_io(ioapicaddr: u32, reg: u32, val: u32) {
|
||||||
write_phys_memory32(mem_mapper, frame_alloc, ioapicaddr as u32, reg);
|
write_phys_memory32(ioapicaddr as u32, reg);
|
||||||
write_phys_memory32(mem_mapper, frame_alloc, ioapicaddr as u32 + 0x10, val);
|
write_phys_memory32(ioapicaddr as u32 + 0x10, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_pic() {
|
pub fn disable_pic() {
|
||||||
|
@ -83,17 +83,17 @@ pub fn disable_pic() {
|
||||||
command(0xa1, 0xff);
|
command(0xa1, 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ioapic_set_irq(mem_mapper: &mut OffsetPageTable, frame_alloc: &mut BootInfoFrameAllocator, ioapicaddr: usize, irq: u8, apic_id: u64, vector:u8) {
|
pub fn ioapic_set_irq(ioapicaddr: u32, irq: u8, apic_id: u64, vector:u8) {
|
||||||
let lo_index: u32 = (0x10 + irq*2 ) as u32;
|
let lo_index: u32 = (0x10 + irq*2 ) as u32;
|
||||||
let hi_index: u32 = (0x10 + irq*2 + 1) as u32;
|
let hi_index: u32 = (0x10 + irq*2 + 1) as u32;
|
||||||
|
|
||||||
let mut high = apic_read_io(mem_mapper, frame_alloc, ioapicaddr, hi_index);
|
let mut high = apic_read_io(ioapicaddr, hi_index);
|
||||||
// set apic id
|
// set apic id
|
||||||
high &= !(0xff000000);
|
high &= !(0xff000000);
|
||||||
high |= (apic_id as u32) << 24;
|
high |= (apic_id as u32) << 24;
|
||||||
apic_write_io(mem_mapper, frame_alloc, ioapicaddr, hi_index, high);
|
apic_write_io(ioapicaddr, hi_index, high);
|
||||||
|
|
||||||
let mut low = apic_read_io(mem_mapper, frame_alloc, ioapicaddr, lo_index);
|
let mut low = apic_read_io( ioapicaddr, lo_index);
|
||||||
|
|
||||||
// unmask
|
// unmask
|
||||||
low &= !(1 << 16);
|
low &= !(1 << 16);
|
||||||
|
@ -105,7 +105,7 @@ pub fn ioapic_set_irq(mem_mapper: &mut OffsetPageTable, frame_alloc: &mut BootIn
|
||||||
low &= !(0xff);
|
low &= !(0xff);
|
||||||
low |= vector as u32;
|
low |= vector as u32;
|
||||||
|
|
||||||
apic_write_io(mem_mapper, frame_alloc, ioapicaddr, lo_index, low);
|
apic_write_io(ioapicaddr, lo_index, low);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apic_eoi() {
|
pub fn apic_eoi() {
|
||||||
|
@ -136,7 +136,7 @@ pub extern "x86-interrupt" fn keyboard_irq(stack_frame: InterruptStackFrame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo! we should abstract this away
|
// todo! we should abstract this away
|
||||||
pub fn setup_apic_interrupts(mem_mapper: &mut OffsetPageTable, frame_alloc: &mut BootInfoFrameAllocator, ioapicaddr: usize) {
|
pub fn setup_apic_interrupts(ioapicaddr: u32) {
|
||||||
// set keyboard irq to interrupt 40
|
// set keyboard irq to interrupt 40
|
||||||
ioapic_set_irq(mem_mapper, frame_alloc, ioapicaddr, 1, 0, 40);
|
ioapic_set_irq(ioapicaddr, 1, 0, 40);
|
||||||
}
|
}
|
13
src/lib.rs
13
src/lib.rs
|
@ -25,6 +25,7 @@ use x86_64::registers::segmentation::{CS, Segment, SS};
|
||||||
use x86_64::structures::paging::Translate;
|
use x86_64::structures::paging::Translate;
|
||||||
use crate::boot::KernelInfo;
|
use crate::boot::KernelInfo;
|
||||||
use crate::internals::WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood::*;
|
use crate::internals::WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood::*;
|
||||||
|
use crate::memory::{FRAME_ALLOC, MEM_MAPPER};
|
||||||
use crate::serial::terminal::ST;
|
use crate::serial::terminal::ST;
|
||||||
|
|
||||||
mod font;
|
mod font;
|
||||||
|
@ -165,17 +166,15 @@ pub extern fn kernel_main(args: KernelArgs) -> ! {
|
||||||
let kern_info = Mutex::new(KernelInfo::init_from_kernel_args(args));
|
let kern_info = Mutex::new(KernelInfo::init_from_kernel_args(args));
|
||||||
|
|
||||||
// memory stuff
|
// memory stuff
|
||||||
let mut mapper = None;
|
|
||||||
let mut frame_allocator = None;
|
|
||||||
{
|
{
|
||||||
print!("initialising mapper...");
|
print!("initialising mapper...");
|
||||||
mapper = Some(unsafe { memory::init(VirtAddr::new(0)) });
|
MEM_MAPPER.lock().replace(unsafe { memory::init(VirtAddr::new(0)) });
|
||||||
println!("[OK]");
|
println!("[OK]");
|
||||||
print!("initialising frame allocator...");
|
print!("initialising frame allocator...");
|
||||||
frame_allocator = Some(unsafe { memory::BootInfoFrameAllocator::init(kern_info) });
|
FRAME_ALLOC.lock().replace(unsafe { memory::BootInfoFrameAllocator::init(kern_info) });
|
||||||
println!("[OK]");
|
println!("[OK]");
|
||||||
print!("initialising heap...");
|
print!("initialising heap...");
|
||||||
memory::allocator::init_heap(mapper.as_mut().unwrap(), frame_allocator.as_mut().unwrap()).expect("heap init failed");
|
memory::allocator::init_heap(MEM_MAPPER.lock().as_mut().unwrap(), FRAME_ALLOC.lock().as_mut().unwrap()).expect("heap init failed");
|
||||||
println!("[OK]");
|
println!("[OK]");
|
||||||
|
|
||||||
print!("testing heap...");
|
print!("testing heap...");
|
||||||
|
@ -206,10 +205,10 @@ pub extern fn kernel_main(args: KernelArgs) -> ! {
|
||||||
unsafe { internals::cpu::disable_pic() };
|
unsafe { internals::cpu::disable_pic() };
|
||||||
println!("[OK]");
|
println!("[OK]");
|
||||||
print!("initialising apic...");
|
print!("initialising apic...");
|
||||||
unsafe { internals::cpu::enable_apic(mapper.as_mut().unwrap(), frame_allocator.as_mut().unwrap()) };
|
unsafe { internals::cpu::enable_apic() };
|
||||||
println!("[OK]");
|
println!("[OK]");
|
||||||
print!("setting up apic interrupts...");
|
print!("setting up apic interrupts...");
|
||||||
unsafe { internals::cpu::setup_apic_interrupts(mapper.as_mut().unwrap(), frame_allocator.as_mut().unwrap()) };
|
unsafe { internals::cpu::setup_apic_interrupts(kern_info.lock().acpi_get_ioapic_addr()) };
|
||||||
println!("[OK]");
|
println!("[OK]");
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
x86_64::instructions::interrupts::enable();
|
x86_64::instructions::interrupts::enable();
|
||||||
|
|
|
@ -2,9 +2,15 @@ pub mod allocator;
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use x86_64::structures::paging::{FrameAllocator, Mapper, OffsetPageTable, PageTable, PhysFrame, Size4KiB, Translate};
|
use x86_64::structures::paging::{FrameAllocator, Mapper, OffsetPageTable, PageTable, PhysFrame, Size4KiB, Translate};
|
||||||
use x86_64::{PhysAddr, VirtAddr};
|
use x86_64::{PhysAddr, VirtAddr};
|
||||||
|
|
||||||
|
lazy_static!{
|
||||||
|
pub static ref MEM_MAPPER: Mutex<Option<OffsetPageTable>> = Mutex::new(None);
|
||||||
|
pub static ref FRAME_ALLOC: Mutex<Option<BootInfoFrameAllocator>> = Mutex::new(None);
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Locked<A> {
|
pub struct Locked<A> {
|
||||||
inner: spin::Mutex<A>,
|
inner: spin::Mutex<A>,
|
||||||
}
|
}
|
||||||
|
@ -86,26 +92,26 @@ unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_phys_memory32(mem_mapper: &mut OffsetPageTable, frame_allocator: &mut BootInfoFrameAllocator, addr: u32) -> u32 {
|
pub fn read_phys_memory32(addr: u32) -> u32 {
|
||||||
let initaladdr = VirtAddr::new(addr as u64);
|
let initaladdr = VirtAddr::new(addr as u64);
|
||||||
let addr = unsafe { mem_mapper.translate_addr(initaladdr) };
|
let addr = unsafe { MEM_MAPPER.lock().as_mut().unwrap().translate_addr(initaladdr) };
|
||||||
if let Some(addr) = addr {
|
if let Some(addr) = addr {
|
||||||
let addr = addr.as_u64() as *const u32;
|
let addr = addr.as_u64() as *const u32;
|
||||||
unsafe { *addr }
|
unsafe { *addr }
|
||||||
} else {
|
} else {
|
||||||
debug!("read_phys_memory32: addr {:x} not mapped", initaladdr.as_u64());
|
debug!("read_phys_memory32: addr {:x} not mapped", initaladdr.as_u64());
|
||||||
// map the page
|
// map the page
|
||||||
let frame = frame_allocator.allocate_frame().unwrap();
|
let frame = FRAME_ALLOC.lock().as_mut().unwrap().allocate_frame().unwrap();
|
||||||
debug!("allocated frame: {:?}", frame);
|
debug!("allocated frame: {:?}", frame);
|
||||||
let flags = x86_64::structures::paging::PageTableFlags::PRESENT | x86_64::structures::paging::PageTableFlags::WRITABLE;
|
let flags = x86_64::structures::paging::PageTableFlags::PRESENT | x86_64::structures::paging::PageTableFlags::WRITABLE;
|
||||||
let page = x86_64::structures::paging::Page::containing_address(initaladdr);
|
let page = x86_64::structures::paging::Page::containing_address(initaladdr);
|
||||||
debug!("mapped page: {:?}", page);
|
debug!("mapped page: {:?}", page);
|
||||||
let map_to_result = unsafe { mem_mapper.map_to(page, frame, flags, frame_allocator) };
|
let map_to_result = unsafe { MEM_MAPPER.lock().as_mut().unwrap().map_to(page, frame, flags, FRAME_ALLOC.lock().as_mut().unwrap()) };
|
||||||
debug!("map_to_result: {:?}", map_to_result);
|
debug!("map_to_result: {:?}", map_to_result);
|
||||||
if map_to_result.is_err() {
|
if map_to_result.is_err() {
|
||||||
panic!("Failed to map page");
|
panic!("Failed to map page");
|
||||||
}
|
}
|
||||||
let addr = unsafe { mem_mapper.translate_addr(initaladdr) };
|
let addr = unsafe { MEM_MAPPER.lock().as_mut().unwrap().translate_addr(initaladdr) };
|
||||||
if let Some(addr) = addr {
|
if let Some(addr) = addr {
|
||||||
let addr = addr.as_u64() as *const u32;
|
let addr = addr.as_u64() as *const u32;
|
||||||
unsafe { *addr }
|
unsafe { *addr }
|
||||||
|
@ -115,26 +121,26 @@ pub fn read_phys_memory32(mem_mapper: &mut OffsetPageTable, frame_allocator: &mu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_phys_memory32(mem_mapper: &mut OffsetPageTable, frame_allocator: &mut BootInfoFrameAllocator, addr: u32, value: u32) {
|
pub fn write_phys_memory32(addr: u32, value: u32) {
|
||||||
let initaladdr = VirtAddr::new(addr as u64);
|
let initaladdr = VirtAddr::new(addr as u64);
|
||||||
let addr = unsafe { mem_mapper.translate_addr(initaladdr) };
|
let addr = unsafe { MEM_MAPPER.lock().as_mut().unwrap().translate_addr(initaladdr) };
|
||||||
if let Some(addr) = addr {
|
if let Some(addr) = addr {
|
||||||
let addr = addr.as_u64() as *mut u32;
|
let addr = addr.as_u64() as *mut u32;
|
||||||
unsafe { *addr = value };
|
unsafe { *addr = value };
|
||||||
} else {
|
} else {
|
||||||
debug!("write_phys_memory32: addr {:x} not mapped", initaladdr.as_u64());
|
debug!("write_phys_memory32: addr {:x} not mapped", initaladdr.as_u64());
|
||||||
// map the page
|
// map the page
|
||||||
let frame = frame_allocator.allocate_frame().unwrap();
|
let frame = FRAME_ALLOC.lock().as_mut().unwrap().allocate_frame().unwrap();
|
||||||
debug!("allocated frame: {:?}", frame);
|
debug!("allocated frame: {:?}", frame);
|
||||||
let flags = x86_64::structures::paging::PageTableFlags::PRESENT | x86_64::structures::paging::PageTableFlags::WRITABLE;
|
let flags = x86_64::structures::paging::PageTableFlags::PRESENT | x86_64::structures::paging::PageTableFlags::WRITABLE;
|
||||||
let page = x86_64::structures::paging::Page::containing_address(initaladdr);
|
let page = x86_64::structures::paging::Page::containing_address(initaladdr);
|
||||||
debug!("mapped page: {:?}", page);
|
debug!("mapped page: {:?}", page);
|
||||||
let map_to_result = unsafe { mem_mapper.map_to(page, frame, flags, frame_allocator) };
|
let map_to_result = unsafe { MEM_MAPPER.lock().as_mut().unwrap().map_to(page, frame, flags, FRAME_ALLOC.lock().as_mut().unwrap()) };
|
||||||
debug!("map_to_result: {:?}", map_to_result);
|
debug!("map_to_result: {:?}", map_to_result);
|
||||||
if map_to_result.is_err() {
|
if map_to_result.is_err() {
|
||||||
panic!("Failed to map page");
|
panic!("Failed to map page");
|
||||||
}
|
}
|
||||||
let addr = unsafe { mem_mapper.translate_addr(initaladdr) };
|
let addr = unsafe { MEM_MAPPER.lock().as_mut().unwrap().translate_addr(initaladdr) };
|
||||||
if let Some(addr) = addr {
|
if let Some(addr) = addr {
|
||||||
let addr = addr.as_u64() as *mut u32;
|
let addr = addr.as_u64() as *mut u32;
|
||||||
unsafe { *addr = value };
|
unsafe { *addr = value };
|
||||||
|
|
|
@ -74,6 +74,17 @@ pub fn read(port: u16) -> u8 {
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dummy functions for non-x86
|
||||||
|
#[cfg(not(any(target_arch="x86", target_arch="x86_64")))]
|
||||||
|
pub fn command(port: u16, data: u8) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(target_arch="x86", target_arch="x86_64")))]
|
||||||
|
pub fn read(port: u16) -> u8 {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
impl Port {
|
impl Port {
|
||||||
fn is_transmit_empty(&self) -> bool {
|
fn is_transmit_empty(&self) -> bool {
|
||||||
let status = read(self.base as u16 + serial_offsets::LINE_STATUS as u16);
|
let status = read(self.base as u16 + serial_offsets::LINE_STATUS as u16);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue