This commit is contained in:
parent
68684e3817
commit
55e78f3b98
12 changed files with 118 additions and 50 deletions
|
@ -1,5 +1,6 @@
|
||||||
use core::{
|
use core::{
|
||||||
arch::asm,
|
arch::asm,
|
||||||
|
cell::OnceCell,
|
||||||
panic,
|
panic,
|
||||||
sync::atomic::{AtomicBool, AtomicU64, Ordering},
|
sync::atomic::{AtomicBool, AtomicU64, Ordering},
|
||||||
};
|
};
|
||||||
|
@ -12,7 +13,7 @@ use kernel_common::{
|
||||||
};
|
};
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use crate::sys::{locks::Spinlock, smp::smp_invalidate_tlb};
|
use crate::sys::{locks::Spinlock, process::get_kernel_process, smp::smp_invalidate_tlb};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static _text_start: u8;
|
static _text_start: u8;
|
||||||
|
@ -26,13 +27,12 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AddressSpace {
|
pub struct AddressSpace {
|
||||||
pub pml4: Option<Box<PageTable>>,
|
pub pml4: OnceCell<Box<PageTable>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static PAGING_ACTIVE: AtomicBool = AtomicBool::new(false);
|
static PAGING_ACTIVE: AtomicBool = AtomicBool::new(false);
|
||||||
pub static CURRENT_ADDRESS_SPACE: Spinlock<AddressSpace> = Spinlock::new(AddressSpace { pml4: None });
|
|
||||||
static HEAP_PHYS_START: AtomicU64 = AtomicU64::new(0);
|
static HEAP_PHYS_START: AtomicU64 = AtomicU64::new(0);
|
||||||
static PHYSICAL_FRAMES: Spinlock<Option<BitVec<u64>>> = Spinlock::new(None);
|
static PHYSICAL_FRAMES: Spinlock<OnceCell<BitVec<u64>>> = Spinlock::new(OnceCell::new());
|
||||||
static HEAP_PHYS_MAPPING: Spinlock<Vec<u64>> = Spinlock::new(Vec::new());
|
static HEAP_PHYS_MAPPING: Spinlock<Vec<u64>> = Spinlock::new(Vec::new());
|
||||||
const KERNEL_MAPPINGS_START: u64 = 0xfffffffd00000000;
|
const KERNEL_MAPPINGS_START: u64 = 0xfffffffd00000000;
|
||||||
const KERNEL_MAPPINGS_END: u64 = 0xfffffffe00000000;
|
const KERNEL_MAPPINGS_END: u64 = 0xfffffffe00000000;
|
||||||
|
@ -44,7 +44,7 @@ impl AddressSpace {
|
||||||
let directory_i = virt_page / 512 % 512;
|
let directory_i = virt_page / 512 % 512;
|
||||||
let pdpt_i = virt_page / 512 / 512 % 512;
|
let pdpt_i = virt_page / 512 / 512 % 512;
|
||||||
let pml4_i = virt_page / 512 / 512 / 512 % 512;
|
let pml4_i = virt_page / 512 / 512 / 512 % 512;
|
||||||
let pdpt = &mut self.pml4.as_mut().unwrap().entries_virt[pml4_i];
|
let pdpt = &mut self.pml4.get_mut().unwrap().entries_virt[pml4_i];
|
||||||
if let Some(pdpt) = pdpt {
|
if let Some(pdpt) = pdpt {
|
||||||
let directory = &mut pdpt.entries_virt[pdpt_i];
|
let directory = &mut pdpt.entries_virt[pdpt_i];
|
||||||
if let Some(directory) = directory {
|
if let Some(directory) = directory {
|
||||||
|
@ -84,8 +84,8 @@ impl AddressSpace {
|
||||||
{
|
{
|
||||||
let mut frames_vec = PHYSICAL_FRAMES.lock();
|
let mut frames_vec = PHYSICAL_FRAMES.lock();
|
||||||
let frame = phys as usize / 0x1000;
|
let frame = phys as usize / 0x1000;
|
||||||
if frame < frames_vec.as_ref().unwrap().len() {
|
if frame < frames_vec.get().unwrap().len() {
|
||||||
frames_vec.as_mut().unwrap().set(frame, true);
|
frames_vec.get_mut().unwrap().set(frame, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let virt_page = virt as usize / 0x1000;
|
let virt_page = virt as usize / 0x1000;
|
||||||
|
@ -93,7 +93,7 @@ impl AddressSpace {
|
||||||
let directory_i = virt_page / 512 % 512;
|
let directory_i = virt_page / 512 % 512;
|
||||||
let pdpt_i = virt_page / 512 / 512 % 512;
|
let pdpt_i = virt_page / 512 / 512 % 512;
|
||||||
let pml4_i = virt_page / 512 / 512 / 512 % 512;
|
let pml4_i = virt_page / 512 / 512 / 512 % 512;
|
||||||
let pdpt = get_table_entry(self.pml4.as_mut().unwrap(), pml4_i);
|
let pdpt = get_table_entry(self.pml4.get_mut().unwrap(), pml4_i);
|
||||||
let directory = get_table_entry(pdpt, pdpt_i);
|
let directory = get_table_entry(pdpt, pdpt_i);
|
||||||
let table = get_table_entry(directory, directory_i);
|
let table = get_table_entry(directory, directory_i);
|
||||||
let should_invalidate = table.entries_phys[table_i].present() == 1;
|
let should_invalidate = table.entries_phys[table_i].present() == 1;
|
||||||
|
@ -151,8 +151,9 @@ impl AddressSpace {
|
||||||
|
|
||||||
fn _get_free_frame() -> u64 {
|
fn _get_free_frame() -> u64 {
|
||||||
let frames_vec = PHYSICAL_FRAMES.lock();
|
let frames_vec = PHYSICAL_FRAMES.lock();
|
||||||
for i in 0..frames_vec.as_ref().unwrap().len() {
|
let frames_vec = frames_vec.get().unwrap();
|
||||||
if !frames_vec.as_ref().unwrap()[i] {
|
for i in 0..frames_vec.len() {
|
||||||
|
if !frames_vec[i] {
|
||||||
return i as u64;
|
return i as u64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,8 +199,8 @@ pub fn setup_paging(loader_struct: &LoaderStruct, phys_start: u64, heap_start: u
|
||||||
info!("Memory size: {} MB", memory_size * 0x1000 / 1024 / 1024);
|
info!("Memory size: {} MB", memory_size * 0x1000 / 1024 / 1024);
|
||||||
{
|
{
|
||||||
let mut frames_vec = PHYSICAL_FRAMES.lock();
|
let mut frames_vec = PHYSICAL_FRAMES.lock();
|
||||||
*frames_vec = Some(BitVec::<u64, Lsb0>::repeat(true, memory_size as usize));
|
frames_vec.set(BitVec::<u64, Lsb0>::repeat(true, memory_size as usize)).unwrap_or_else(|_| panic!());
|
||||||
let frames_vec = frames_vec.as_mut().unwrap();
|
let frames_vec = frames_vec.get_mut().unwrap();
|
||||||
for i in &loader_struct.available_memory {
|
for i in &loader_struct.available_memory {
|
||||||
for j in 0..i.page_count {
|
for j in 0..i.page_count {
|
||||||
let page = i.initial_page + j;
|
let page = i.initial_page + j;
|
||||||
|
@ -227,12 +228,17 @@ pub fn setup_paging(loader_struct: &LoaderStruct, phys_start: u64, heap_start: u
|
||||||
bss_start = &_bss_start as *const u8 as u64 / 0x1000;
|
bss_start = &_bss_start as *const u8 as u64 / 0x1000;
|
||||||
bss_end = (&_bss_end as *const u8 as u64 + 0xfff) / 0x1000;
|
bss_end = (&_bss_end as *const u8 as u64 + 0xfff) / 0x1000;
|
||||||
}
|
}
|
||||||
let mut address_space = CURRENT_ADDRESS_SPACE.lock();
|
let kernel_proc = get_kernel_process();
|
||||||
address_space.pml4 = Some(Box::new(PageTable {
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
entries_phys: [PageEntry(0); 512],
|
let address_space = &mut kernel_proc.address_space;
|
||||||
entries_virt: [const { None }; 512],
|
address_space
|
||||||
}));
|
.pml4
|
||||||
let pml4 = address_space.pml4.as_mut().unwrap();
|
.set(Box::new(PageTable {
|
||||||
|
entries_phys: [PageEntry(0); 512],
|
||||||
|
entries_virt: [const { None }; 512],
|
||||||
|
}))
|
||||||
|
.unwrap_or_else(|_| panic!());
|
||||||
|
let pml4 = address_space.pml4.get_mut().unwrap();
|
||||||
let pml4_address = pml4.as_ref() as *const PageTable as u64;
|
let pml4_address = pml4.as_ref() as *const PageTable as u64;
|
||||||
for i in 256..512 {
|
for i in 256..512 {
|
||||||
get_table_entry(pml4, i);
|
get_table_entry(pml4, i);
|
||||||
|
|
|
@ -116,7 +116,7 @@ fn panic(info: &PanicInfo) -> ! {
|
||||||
error!("{}", info);
|
error!("{}", info);
|
||||||
let str = format!("{}", info);
|
let str = format!("{}", info);
|
||||||
let mut display = PANIC_DISPLAY.lock();
|
let mut display = PANIC_DISPLAY.lock();
|
||||||
if let Some(display) = display.as_mut() {
|
if let Some(display) = display.get_mut() {
|
||||||
display.clear();
|
display.clear();
|
||||||
display.print(&str);
|
display.print(&str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use core::cell::OnceCell;
|
||||||
|
|
||||||
use alloc::{string::ToString, vec};
|
use alloc::{string::ToString, vec};
|
||||||
use embedded_graphics::{
|
use embedded_graphics::{
|
||||||
mono_font::{iso_8859_13::FONT_10X20, MonoTextStyle},
|
mono_font::{iso_8859_13::FONT_10X20, MonoTextStyle},
|
||||||
|
@ -7,7 +9,10 @@ use embedded_graphics::{
|
||||||
};
|
};
|
||||||
use kernel_common::loader_struct::FramebufferInfo;
|
use kernel_common::loader_struct::FramebufferInfo;
|
||||||
|
|
||||||
use crate::{cpu::paging::CURRENT_ADDRESS_SPACE, misc::draw_target::FramebufferTarget, sys::locks::Spinlock};
|
use crate::{
|
||||||
|
misc::draw_target::FramebufferTarget,
|
||||||
|
sys::{locks::Spinlock, process::get_kernel_process},
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Display {
|
pub struct Display {
|
||||||
framebuffer: FramebufferTarget,
|
framebuffer: FramebufferTarget,
|
||||||
|
@ -19,8 +24,8 @@ pub struct Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Change to mutex
|
//TODO: Change to mutex
|
||||||
pub static DISPLAY: Spinlock<Option<Display>> = Spinlock::new(None);
|
pub static DISPLAY: Spinlock<OnceCell<Display>> = Spinlock::new(OnceCell::new());
|
||||||
pub static PANIC_DISPLAY: Spinlock<Option<Display>> = Spinlock::new(None);
|
pub static PANIC_DISPLAY: Spinlock<OnceCell<Display>> = Spinlock::new(OnceCell::new());
|
||||||
|
|
||||||
impl Display {
|
impl Display {
|
||||||
fn write_char(&mut self, x: usize, y: usize, c: char) {
|
fn write_char(&mut self, x: usize, y: usize, c: char) {
|
||||||
|
@ -71,7 +76,12 @@ impl Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn setup_display(info: FramebufferInfo) {
|
pub fn setup_display(info: FramebufferInfo) {
|
||||||
let addr = unsafe { CURRENT_ADDRESS_SPACE.lock().map_physical(info.address, info.height * info.stride * 4, true) };
|
let addr;
|
||||||
|
{
|
||||||
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
|
addr = unsafe { kernel_proc.address_space.map_physical(info.address, info.height * info.stride * 4, true) };
|
||||||
|
}
|
||||||
let fb = vec![0; info.height as usize * info.stride as usize * 4];
|
let fb = vec![0; info.height as usize * info.stride as usize * 4];
|
||||||
let display = Display {
|
let display = Display {
|
||||||
framebuffer: FramebufferTarget {
|
framebuffer: FramebufferTarget {
|
||||||
|
@ -86,7 +96,7 @@ pub fn setup_display(info: FramebufferInfo) {
|
||||||
current_x: 0,
|
current_x: 0,
|
||||||
current_y: 0,
|
current_y: 0,
|
||||||
};
|
};
|
||||||
*PANIC_DISPLAY.lock() = Some(display);
|
PANIC_DISPLAY.lock().set(display).unwrap_or_else(|_| panic!());
|
||||||
let fb = vec![0; info.height as usize * info.stride as usize * 4];
|
let fb = vec![0; info.height as usize * info.stride as usize * 4];
|
||||||
let display = Display {
|
let display = Display {
|
||||||
framebuffer: FramebufferTarget {
|
framebuffer: FramebufferTarget {
|
||||||
|
@ -101,5 +111,5 @@ pub fn setup_display(info: FramebufferInfo) {
|
||||||
current_x: 0,
|
current_x: 0,
|
||||||
current_y: 0,
|
current_y: 0,
|
||||||
};
|
};
|
||||||
*DISPLAY.lock() = Some(display);
|
DISPLAY.lock().set(display).unwrap_or_else(|_| panic!());
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ use kernel_common::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cpu::paging::CURRENT_ADDRESS_SPACE,
|
|
||||||
misc::wrapped_alloc::{wrapped_alloc, wrapped_dealloc},
|
misc::wrapped_alloc::{wrapped_alloc, wrapped_dealloc},
|
||||||
sys::ioapic::{register_irq_handler, set_irq_override},
|
sys::ioapic::{register_irq_handler, set_irq_override},
|
||||||
RSDP_ADDRESS,
|
RSDP_ADDRESS,
|
||||||
|
@ -26,6 +25,7 @@ use super::{
|
||||||
hpet::get_current_time,
|
hpet::get_current_time,
|
||||||
lapic::get_current_lapic_id,
|
lapic::get_current_lapic_id,
|
||||||
locks::Spinlock,
|
locks::Spinlock,
|
||||||
|
process::get_kernel_process,
|
||||||
sync::{create_semaphore, lock_semaphore, unlock_semaphore, RawSemaphore, RawSpinlock},
|
sync::{create_semaphore, lock_semaphore, unlock_semaphore, RawSemaphore, RawSpinlock},
|
||||||
task::{CURRENT_TASKS, MULTITASKING_ENABLED},
|
task::{CURRENT_TASKS, MULTITASKING_ENABLED},
|
||||||
};
|
};
|
||||||
|
@ -117,7 +117,9 @@ extern "C" fn AcpiOsInstallInterruptHandler(gsi: UINT32, handler: ACPI_OSD_HANDL
|
||||||
}
|
}
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn AcpiOsMapMemory(phys: ACPI_PHYSICAL_ADDRESS, size: ACPI_SIZE) -> *mut c_void {
|
extern "C" fn AcpiOsMapMemory(phys: ACPI_PHYSICAL_ADDRESS, size: ACPI_SIZE) -> *mut c_void {
|
||||||
unsafe { CURRENT_ADDRESS_SPACE.lock().map_physical(phys, size, false) as *mut c_void }
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
|
unsafe { kernel_proc.address_space.map_physical(phys, size, false) as *mut c_void }
|
||||||
}
|
}
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn AcpiOsPhysicalTableOverride(_existing: *mut ACPI_TABLE_HEADER, new_address: *mut ACPI_PHYSICAL_ADDRESS, new_length: *mut UINT32) -> ACPI_STATUS {
|
extern "C" fn AcpiOsPhysicalTableOverride(_existing: *mut ACPI_TABLE_HEADER, new_address: *mut ACPI_PHYSICAL_ADDRESS, new_length: *mut UINT32) -> ACPI_STATUS {
|
||||||
|
@ -199,8 +201,10 @@ extern "C" fn AcpiOsTerminate() -> ACPI_STATUS {
|
||||||
}
|
}
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn AcpiOsUnmapMemory(address: *mut c_void, size: ACPI_SIZE) {
|
extern "C" fn AcpiOsUnmapMemory(address: *mut c_void, size: ACPI_SIZE) {
|
||||||
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
unsafe {
|
unsafe {
|
||||||
CURRENT_ADDRESS_SPACE.lock().unmap_physical(address as u64, size);
|
kernel_proc.address_space.unmap_physical(address as u64, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
@ -2,21 +2,25 @@ use core::ptr::NonNull;
|
||||||
|
|
||||||
use acpi::{AcpiHandler, PhysicalMapping};
|
use acpi::{AcpiHandler, PhysicalMapping};
|
||||||
|
|
||||||
use crate::cpu::paging::CURRENT_ADDRESS_SPACE;
|
use super::process::get_kernel_process;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct EarlyACPIHandler {}
|
pub struct EarlyACPIHandler {}
|
||||||
|
|
||||||
impl AcpiHandler for EarlyACPIHandler {
|
impl AcpiHandler for EarlyACPIHandler {
|
||||||
unsafe fn map_physical_region<T>(&self, phys: usize, size: usize) -> PhysicalMapping<Self, T> {
|
unsafe fn map_physical_region<T>(&self, phys: usize, size: usize) -> PhysicalMapping<Self, T> {
|
||||||
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
unsafe {
|
unsafe {
|
||||||
let virt = CURRENT_ADDRESS_SPACE.lock().map_physical(phys as u64, size as u64, false);
|
let virt = kernel_proc.address_space.map_physical(phys as u64, size as u64, false);
|
||||||
PhysicalMapping::new(phys, NonNull::new(virt as *mut T).unwrap(), size, size, *self)
|
PhysicalMapping::new(phys, NonNull::new(virt as *mut T).unwrap(), size, size, *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn unmap_physical_region<T>(region: &PhysicalMapping<Self, T>) {
|
fn unmap_physical_region<T>(region: &PhysicalMapping<Self, T>) {
|
||||||
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
unsafe {
|
unsafe {
|
||||||
CURRENT_ADDRESS_SPACE.lock().unmap_physical(region.virtual_start().as_ptr() as u64, region.mapped_length() as u64);
|
kernel_proc.address_space.unmap_physical(region.virtual_start().as_ptr() as u64, region.mapped_length() as u64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,12 @@ use acpi::{AcpiTables, HpetInfo};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use kernel_common::instructions::pause;
|
use kernel_common::instructions::pause;
|
||||||
|
|
||||||
use crate::cpu::paging::CURRENT_ADDRESS_SPACE;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
early_acpi::EarlyACPIHandler,
|
early_acpi::EarlyACPIHandler,
|
||||||
ioapic::register_irq_handler,
|
ioapic::register_irq_handler,
|
||||||
lapic::get_current_lapic_id,
|
lapic::get_current_lapic_id,
|
||||||
locks::Spinlock,
|
locks::Spinlock,
|
||||||
|
process::get_kernel_process,
|
||||||
scheduler::{yield_task, SCHEDULER},
|
scheduler::{yield_task, SCHEDULER},
|
||||||
task::{Task, TaskState, CURRENT_TASKS, MULTITASKING_ENABLED},
|
task::{Task, TaskState, CURRENT_TASKS, MULTITASKING_ENABLED},
|
||||||
};
|
};
|
||||||
|
@ -118,7 +117,12 @@ pub fn sleep_internal(task: Task) {
|
||||||
}
|
}
|
||||||
pub fn setup_hpet(tables: &AcpiTables<EarlyACPIHandler>) {
|
pub fn setup_hpet(tables: &AcpiTables<EarlyACPIHandler>) {
|
||||||
let hpet_info = HpetInfo::new(tables).unwrap();
|
let hpet_info = HpetInfo::new(tables).unwrap();
|
||||||
let address = unsafe { CURRENT_ADDRESS_SPACE.lock().map_physical(hpet_info.base_address as u64, 0x200, false) } as *mut u64;
|
let address;
|
||||||
|
{
|
||||||
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
|
address = unsafe { kernel_proc.address_space.map_physical(hpet_info.base_address as u64, 0x200, false) } as *mut u64;
|
||||||
|
}
|
||||||
ADDRESS.store(address, Ordering::SeqCst);
|
ADDRESS.store(address, Ordering::SeqCst);
|
||||||
let period = unsafe { address.add(REGISTER_CAPABILITIES).read_volatile() >> 32 } as usize;
|
let period = unsafe { address.add(REGISTER_CAPABILITIES).read_volatile() >> 32 } as usize;
|
||||||
PERIOD.store(period, Ordering::SeqCst);
|
PERIOD.store(period, Ordering::SeqCst);
|
||||||
|
|
|
@ -6,8 +6,8 @@ use core::{
|
||||||
use bitfield::bitfield;
|
use bitfield::bitfield;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cpu::{isr::ISR_HANDLERS, paging::CURRENT_ADDRESS_SPACE},
|
cpu::isr::ISR_HANDLERS,
|
||||||
sys::lapic::BSP_LAPIC_ID,
|
sys::{lapic::BSP_LAPIC_ID, process::get_kernel_process},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IOAPIC {
|
struct IOAPIC {
|
||||||
|
@ -98,7 +98,12 @@ pub fn register_irq_handler(vector: usize, handler: fn()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn setup_ioapic(phys: u64, gsi_base: usize) {
|
pub fn setup_ioapic(phys: u64, gsi_base: usize) {
|
||||||
let address = unsafe { CURRENT_ADDRESS_SPACE.lock().map_physical(phys, 0x14, false) as *mut u32 };
|
let address;
|
||||||
|
{
|
||||||
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
|
address = unsafe { kernel_proc.address_space.map_physical(phys, 0x14, false) as *mut u32 };
|
||||||
|
}
|
||||||
let next_id = NEXT_IOAPIC_ID.fetch_add(1, Ordering::SeqCst);
|
let next_id = NEXT_IOAPIC_ID.fetch_add(1, Ordering::SeqCst);
|
||||||
IOAPICS[next_id].address.store(address, Ordering::SeqCst);
|
IOAPICS[next_id].address.store(address, Ordering::SeqCst);
|
||||||
IOAPICS[next_id].start_gsi.store(gsi_base, Ordering::SeqCst);
|
IOAPICS[next_id].start_gsi.store(gsi_base, Ordering::SeqCst);
|
||||||
|
|
|
@ -5,9 +5,9 @@ use core::{
|
||||||
|
|
||||||
use kernel_common::instructions::get_rflags;
|
use kernel_common::instructions::get_rflags;
|
||||||
|
|
||||||
use crate::cpu::{isr::ISR_SCHEDULER, paging::CURRENT_ADDRESS_SPACE};
|
use crate::cpu::isr::ISR_SCHEDULER;
|
||||||
|
|
||||||
use super::hpet::sleep;
|
use super::{hpet::sleep, process::get_kernel_process};
|
||||||
|
|
||||||
pub struct LAPIC {
|
pub struct LAPIC {
|
||||||
pub lapic_id: AtomicUsize,
|
pub lapic_id: AtomicUsize,
|
||||||
|
@ -49,7 +49,9 @@ pub fn get_current_lapic_id() -> usize {
|
||||||
}
|
}
|
||||||
pub fn setup_lapic(phys: u64) {
|
pub fn setup_lapic(phys: u64) {
|
||||||
if phys != 0 {
|
if phys != 0 {
|
||||||
let address = unsafe { CURRENT_ADDRESS_SPACE.lock().map_physical(phys, 0x400, false) as *mut u32 };
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
|
let address = unsafe { kernel_proc.address_space.map_physical(phys, 0x400, false) as *mut u32 };
|
||||||
ADDRESS.store(address, Ordering::SeqCst);
|
ADDRESS.store(address, Ordering::SeqCst);
|
||||||
BSP_LAPIC_ID.store(get_current_lapic_id(), Ordering::SeqCst);
|
BSP_LAPIC_ID.store(get_current_lapic_id(), Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ pub mod lapic;
|
||||||
pub mod locks;
|
pub mod locks;
|
||||||
pub mod madt;
|
pub mod madt;
|
||||||
pub mod pic;
|
pub mod pic;
|
||||||
|
pub mod process;
|
||||||
pub mod scheduler;
|
pub mod scheduler;
|
||||||
pub mod smp;
|
pub mod smp;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
|
|
22
kernel/src/sys/process.rs
Normal file
22
kernel/src/sys/process.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
use core::cell::{LazyCell, OnceCell};
|
||||||
|
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
|
use crate::cpu::paging::AddressSpace;
|
||||||
|
|
||||||
|
use super::locks::Spinlock;
|
||||||
|
|
||||||
|
pub struct Process {
|
||||||
|
pub address_space: AddressSpace,
|
||||||
|
}
|
||||||
|
|
||||||
|
static KERNEL_PROCESS: Spinlock<LazyCell<Arc<Spinlock<Process>>>> = Spinlock::new(LazyCell::new(|| {
|
||||||
|
let process = Process {
|
||||||
|
address_space: AddressSpace { pml4: OnceCell::new() },
|
||||||
|
};
|
||||||
|
Arc::new(Spinlock::new(process))
|
||||||
|
}));
|
||||||
|
|
||||||
|
pub fn get_kernel_process() -> Arc<Spinlock<Process>> {
|
||||||
|
KERNEL_PROCESS.lock().clone()
|
||||||
|
}
|
|
@ -4,16 +4,14 @@ use alloc::{vec, vec::Vec};
|
||||||
use kernel_common::{instructions::pause, paging::PageTable};
|
use kernel_common::{instructions::pause, paging::PageTable};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cpu::{
|
cpu::{isr::ISR_INVALIDATE_TLB, paging::virt_to_phys},
|
||||||
isr::ISR_INVALIDATE_TLB,
|
|
||||||
paging::{virt_to_phys, CURRENT_ADDRESS_SPACE},
|
|
||||||
},
|
|
||||||
BROADCASTED_PANIC,
|
BROADCASTED_PANIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
hpet::sleep,
|
hpet::sleep,
|
||||||
lapic::{get_current_lapic_id, send_ipi, BSP_LAPIC_ID, LAPICS, NEXT_LAPIC_ID},
|
lapic::{get_current_lapic_id, send_ipi, BSP_LAPIC_ID, LAPICS, NEXT_LAPIC_ID},
|
||||||
|
process::get_kernel_process,
|
||||||
sync::RawSpinlock,
|
sync::RawSpinlock,
|
||||||
task::{ALL_APS_STARTED, STACK_SIZE, STARTING_AP_ID},
|
task::{ALL_APS_STARTED, STACK_SIZE, STARTING_AP_ID},
|
||||||
};
|
};
|
||||||
|
@ -34,9 +32,11 @@ pub fn start_aps() {
|
||||||
let stack: Vec<u8> = vec![0; STACK_SIZE];
|
let stack: Vec<u8> = vec![0; STACK_SIZE];
|
||||||
let pml4_phys_addr;
|
let pml4_phys_addr;
|
||||||
{
|
{
|
||||||
let mut address_space = CURRENT_ADDRESS_SPACE.lock();
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
|
let address_space = &mut kernel_proc.address_space;
|
||||||
let pml4 = &address_space.pml4;
|
let pml4 = &address_space.pml4;
|
||||||
let pml4_phys_addr_u64 = virt_to_phys(pml4.as_ref().unwrap().as_ref() as *const PageTable as u64);
|
let pml4_phys_addr_u64 = virt_to_phys(pml4.get().unwrap().as_ref() as *const PageTable as u64);
|
||||||
pml4_phys_addr = u32::try_from(pml4_phys_addr_u64).unwrap();
|
pml4_phys_addr = u32::try_from(pml4_phys_addr_u64).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
address_space.map_range(0x1000, 0x1000, 0x1000, false, true, false, false);
|
address_space.map_range(0x1000, 0x1000, 0x1000, false, true, false, false);
|
||||||
|
@ -67,7 +67,9 @@ pub fn start_aps() {
|
||||||
}
|
}
|
||||||
ALL_APS_STARTED.store(true, Ordering::SeqCst);
|
ALL_APS_STARTED.store(true, Ordering::SeqCst);
|
||||||
unsafe {
|
unsafe {
|
||||||
CURRENT_ADDRESS_SPACE.lock().unmap(0x1000);
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut kernel_proc = kernel_proc.lock();
|
||||||
|
kernel_proc.address_space.unmap(0x1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn smp_invalidate_tlb() {
|
pub fn smp_invalidate_tlb() {
|
||||||
|
|
|
@ -16,6 +16,7 @@ use super::{
|
||||||
hpet::sleep_internal,
|
hpet::sleep_internal,
|
||||||
lapic::{get_current_lapic_id, schedule_timer_interrupt},
|
lapic::{get_current_lapic_id, schedule_timer_interrupt},
|
||||||
locks::Spinlock,
|
locks::Spinlock,
|
||||||
|
process::{get_kernel_process, Process},
|
||||||
scheduler::yield_task,
|
scheduler::yield_task,
|
||||||
sync::{lock_semaphore_internal, RawSemaphore},
|
sync::{lock_semaphore_internal, RawSemaphore},
|
||||||
};
|
};
|
||||||
|
@ -31,6 +32,7 @@ pub enum TaskState {
|
||||||
|
|
||||||
pub struct Task {
|
pub struct Task {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
|
_process: Arc<Spinlock<Process>>,
|
||||||
state: ISRState,
|
state: ISRState,
|
||||||
_kernel_stack: Vec<u8>,
|
_kernel_stack: Vec<u8>,
|
||||||
initial_func: fn(),
|
initial_func: fn(),
|
||||||
|
@ -70,10 +72,11 @@ pub fn switch_task(current_state: &mut ISRState, new_task: Task) {
|
||||||
_current_task[get_current_lapic_id()] = Some(new_task);
|
_current_task[get_current_lapic_id()] = Some(new_task);
|
||||||
schedule_timer_interrupt();
|
schedule_timer_interrupt();
|
||||||
}
|
}
|
||||||
pub fn create_task(func: fn()) -> Task {
|
pub fn create_task(process: Arc<Spinlock<Process>>, func: fn()) -> Task {
|
||||||
let stack = vec![0; STACK_SIZE];
|
let stack = vec![0; STACK_SIZE];
|
||||||
Task {
|
Task {
|
||||||
id: NEXT_TASK_ID.fetch_add(1, Ordering::SeqCst),
|
id: NEXT_TASK_ID.fetch_add(1, Ordering::SeqCst),
|
||||||
|
_process: process,
|
||||||
state: ISRState {
|
state: ISRState {
|
||||||
rax: 0,
|
rax: 0,
|
||||||
rbx: 0,
|
rbx: 0,
|
||||||
|
@ -107,7 +110,8 @@ pub fn create_task(func: fn()) -> Task {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn create_idle_task() {
|
fn create_idle_task() {
|
||||||
let mut idle_task = create_task(idle_main);
|
let kernel_proc = get_kernel_process();
|
||||||
|
let mut idle_task = create_task(kernel_proc, idle_main);
|
||||||
idle_task.task_state = TaskState::Idle;
|
idle_task.task_state = TaskState::Idle;
|
||||||
{
|
{
|
||||||
IDLE_TASKS.lock().push(idle_task);
|
IDLE_TASKS.lock().push(idle_task);
|
||||||
|
@ -147,7 +151,11 @@ pub fn setup_multitasking() -> ! {
|
||||||
for _ in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
|
for _ in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
|
||||||
create_idle_task();
|
create_idle_task();
|
||||||
}
|
}
|
||||||
let task = create_task(main);
|
let task;
|
||||||
|
{
|
||||||
|
let kernel_proc = get_kernel_process();
|
||||||
|
task = create_task(kernel_proc, main);
|
||||||
|
}
|
||||||
SCHEDULER.lock().add_task(task);
|
SCHEDULER.lock().add_task(task);
|
||||||
MULTITASKING_ENABLED.store(true, Ordering::SeqCst);
|
MULTITASKING_ENABLED.store(true, Ordering::SeqCst);
|
||||||
yield_task();
|
yield_task();
|
||||||
|
|
Loading…
Add table
Reference in a new issue