Verified Commit 4942947f authored by Jeremy Soller's avatar Jeremy Soller
Browse files

paging_framebuffer function to ensure framebuffer is mapped

parent adfeb79e
......@@ -3,6 +3,8 @@ use redoxfs::Disk;
use crate::os::{Os, OsVideoMode};
pub(crate) const PHYS_OFFSET: u64 = 0xfffffe0000000000;
unsafe fn paging_allocate<
D: Disk,
V: Iterator<Item=OsVideoMode>
......@@ -21,7 +23,15 @@ unsafe fn paging_allocate<
pub unsafe fn paging_create<
D: Disk,
V: Iterator<Item=OsVideoMode>
>(os: &mut dyn Os<D, V>, kernel_phys: usize, kernel_base: usize) -> Option<usize> {
>(os: &mut dyn Os<D, V>, kernel_phys: u64, kernel_base: u64) -> Option<usize> {
log::error!("paging_create not implemented for aarch64");
None
}
pub unsafe fn paging_framebuffer<
D: Disk,
V: Iterator<Item=OsVideoMode>
>(os: &mut dyn Os<D, V>, page_phys: usize, framebuffer_phys: u64, framebuffer_size: u64) -> Option<()> {
log::error!("paging_framebuffer not implemented for aarch64");
None
}
......@@ -3,6 +3,8 @@ use redoxfs::Disk;
use crate::os::{Os, OsVideoMode};
pub(crate) const PHYS_OFFSET: u64 = 0xFFFF800000000000;
unsafe fn paging_allocate<
D: Disk,
V: Iterator<Item=OsVideoMode>
......@@ -21,7 +23,7 @@ unsafe fn paging_allocate<
pub unsafe fn paging_create<
D: Disk,
V: Iterator<Item=OsVideoMode>
>(os: &mut dyn Os<D, V>, kernel_phys: usize, kernel_size: usize) -> Option<usize> {
>(os: &mut dyn Os<D, V>, kernel_phys: u64, kernel_size: u64) -> Option<usize> {
// Create PML4
let pml4 = paging_allocate(os)?;
......@@ -69,7 +71,7 @@ pub unsafe fn paging_create<
let mut pt_i = 0;
while kernel_mapped < kernel_size && pt_i < pt.len() {
let addr = (kernel_phys + kernel_mapped) as u64;
let addr = kernel_phys + kernel_mapped;
pt[pt_i] = addr | 1 << 1 | 1;
pt_i += 1;
kernel_mapped += 4096;
......@@ -81,3 +83,51 @@ pub unsafe fn paging_create<
Some(pml4.as_ptr() as usize)
}
pub unsafe fn paging_framebuffer<
D: Disk,
V: Iterator<Item=OsVideoMode>
>(os: &mut dyn Os<D, V>, 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(());
}
let framebuffer_virt = framebuffer_phys + PHYS_OFFSET;
let pml4_i = (framebuffer_virt / 0x80_0000_0000) as usize;
let mut pdp_i = ((framebuffer_virt % 0x80_0000_0000) / 0x4000_0000) as usize;
let mut pd_i = ((framebuffer_virt % 0x4000_0000) / 0x20_0000) as usize;
assert_eq!(framebuffer_virt % 0x20_0000, 0);
let pml4 = slice::from_raw_parts_mut(
page_phys as *mut u64,
512
);
// Create PDP for framebuffer mapping
let pdp = paging_allocate(os)?;
assert_eq!(pml4[pml4_i], 0);
pml4[pml4_i] = pdp.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;
}
pdp_i += 1;
pd_i = 0;
}
assert!(framebuffer_mapped >= framebuffer_size);
Some(())
}
......@@ -28,7 +28,7 @@ use core::{
};
use redoxfs::Disk;
use self::arch::paging_create;
use self::arch::{paging_create, paging_framebuffer};
use self::os::{Os, OsKey, OsMemoryEntry, OsMemoryKind, OsVideoMode};
#[macro_use]
......@@ -338,8 +338,9 @@ fn main<
Ok(kernel)
}).expect("RedoxFS transaction failed");
let page_phys = unsafe { paging_create(os, kernel.as_ptr() as usize, kernel.len()) }
.expect("Failed to set up paging");
let page_phys = unsafe {
paging_create(os, kernel.as_ptr() as u64, kernel.len() as u64)
}.expect("Failed to set up paging");
//TODO: properly reserve page table allocations so kernel does not re-use them
let live_opt = if cfg!(feature = "live") {
......@@ -413,6 +414,15 @@ fn main<
// Set mode to get updated values
os.set_video_mode(&mut mode);
unsafe {
paging_framebuffer(
os,
page_phys,
mode.base,
(mode.width * mode.height * 4) as u64
)
}.expect("Failed to map framebuffer");
writeln!(w, "FRAMEBUFFER_ADDR={:016x}", mode.base).unwrap();
writeln!(w, "FRAMEBUFFER_WIDTH={:016x}", mode.width).unwrap();
writeln!(w, "FRAMEBUFFER_HEIGHT={:016x}", mode.height).unwrap();
......
......@@ -3,6 +3,7 @@ use uefi::status::Result;
use crate::{
KernelArgs,
arch::PHYS_OFFSET,
logger::LOGGER,
};
......@@ -16,8 +17,6 @@ use super::super::{
memory_map::memory_map,
};
static PHYS_OFFSET: u64 = 0xFFFF800000000000;
#[no_mangle]
pub extern "C" fn __chkstk() {
//TODO
......
......@@ -7,6 +7,8 @@ use x86::{
use crate::{
KernelArgs,
Os,
arch::PHYS_OFFSET,
logger::LOGGER,
};
......@@ -20,8 +22,6 @@ use super::super::{
memory_map::memory_map,
};
static PHYS_OFFSET: u64 = 0xFFFF800000000000;
unsafe extern "C" fn kernel_entry(
page_phys: usize,
stack: u64,
......@@ -58,7 +58,9 @@ unsafe extern "C" fn kernel_entry(
// Enable paging, write protect kernel, protected mode
let mut cr0 = controlregs::cr0();
cr0 |= Cr0::CR0_ENABLE_PAGING | Cr0::CR0_WRITE_PROTECT | Cr0::CR0_PROTECTED_MODE;
cr0 |= Cr0::CR0_ENABLE_PAGING
| Cr0::CR0_WRITE_PROTECT
| Cr0::CR0_PROTECTED_MODE;
controlregs::cr0_write(cr0);
// Set stack
......
......@@ -82,7 +82,7 @@ impl Os<
}
fn filesystem(&self, password_opt: Option<&[u8]>) -> syscall::Result<redoxfs::FileSystem<DiskEfi>> {
for (i, block_io) in DiskEfi::all().into_iter().enumerate() {
for block_io in DiskEfi::all().into_iter() {
if !block_io.0.Media.LogicalPartition {
continue;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment