mirror of
https://github.com/realmicrosoft/windows.git
synced 2024-08-14 22:46:44 +00:00
ITS FUCKING WORKING OH MY GOD
This commit is contained in:
parent
d11d5ddd97
commit
314189882b
8 changed files with 216 additions and 94 deletions
|
@ -11,12 +11,13 @@ rlibc = "1.0"
|
||||||
limine = { version = "0.1.9", optional = true }
|
limine = { version = "0.1.9", optional = true }
|
||||||
acpi = { version = "4.1.1", optional = true }
|
acpi = { version = "4.1.1", optional = true }
|
||||||
linked_list_allocator = { version = "0.9.0", optional = true }
|
linked_list_allocator = { version = "0.9.0", optional = true }
|
||||||
|
pc-keyboard = "0.6.1"
|
||||||
[dependencies.lazy_static]
|
[dependencies.lazy_static]
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
features = ["spin_no_std"]
|
features = ["spin_no_std"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["f_limine", "f_ll_alloc", "f_debug_verbose"]
|
default = ["f_limine", "f_ll_alloc"]#, "f_debug_verbose"]
|
||||||
f_debug_verbose = []
|
f_debug_verbose = []
|
||||||
f_limine = ["dep:limine", "dep:acpi"]
|
f_limine = ["dep:limine", "dep:acpi"]
|
||||||
f_ll_alloc = ["dep:linked_list_allocator"]
|
f_ll_alloc = ["dep:linked_list_allocator"]
|
50
serial.log
50
serial.log
|
@ -12,50 +12,14 @@ debug: IDT loaded
|
||||||
|
|
||||||
welcome to wukkOS!
|
welcome to wukkOS!
|
||||||
(c) 2022 Real Microsoft, LLC
|
(c) 2022 Real Microsoft, LLC
|
||||||
initialising mapper...[debug] kernel physical address: 0x19b3d000
|
initialising mapper...[OK]
|
||||||
[debug] kernel virtual address: 0xffffffff80000000
|
|
||||||
[OK]
|
|
||||||
initialising frame allocator...[OK]
|
initialising frame allocator...[OK]
|
||||||
initialising heap...[OK]
|
initialising heap...[OK]
|
||||||
testing heap...[OK]
|
testing heap...[OK]
|
||||||
checking for apic compatibility...[OK]
|
checking for apic compatibility...[OK]
|
||||||
initialising apic...[debug] Mapping physical region: 1fb7e014 - 1fb7e038
|
initialising apic...[OK]
|
||||||
[debug] Mapping physical region: 1fb7d0e8 - 1fb7d10c
|
setting up apic interrupts...[OK]
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[debug] Mapping physical region: 1fb7d0e8 - 1fb7d134
|
hello world i am typing this using the legacy keyboard driver thingy in the apic from ioapic irq 1!
|
||||||
[debug] Mapping physical region: 1fb7a000 - 1fb7a024
|
wukkOS moment, probably gonna swap this out for a real keyboard driver eventually but this is funny so (:
|
||||||
[WARN] failed to unmap page (this is normal)
|
top ten wukkooOS moments
|
||||||
[debug] Mapping physical region: 1fb7a000 - 1fb7a114
|
|
||||||
[debug] Mapping physical region: 1fb7b000 - 1fb7b024
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[debug] Mapping physical region: 1fb79000 - 1fb79024
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[debug] Mapping physical region: 1fb78000 - 1fb78024
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[debug] Mapping physical region: 1fb77000 - 1fb77024
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[debug] Mapping physical region: 1fb76000 - 1fb76024
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[debug] Mapping physical region: 1fb7a000 - 1fb7a074
|
|
||||||
[debug] Mapping physical region: 1fb79000 - 1fb79078
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[WARN] failed to unmap page (this is normal)
|
|
||||||
[OK]
|
|
||||||
setting up apic interrupts...[debug] ioapicaddr: 0xfec00000
|
|
||||||
[OK]
|
|
||||||
---KERNEL FUCKY WUKKY UWU---
|
|
||||||
double fault!
|
|
||||||
stack frame: InterruptStackFrame {
|
|
||||||
instruction_pointer: VirtAddr(
|
|
||||||
0xffffffff80004729,
|
|
||||||
),
|
|
||||||
code_segment: 8,
|
|
||||||
cpu_flags: 0x282,
|
|
||||||
stack_pointer: VirtAddr(
|
|
||||||
0xffff800019b3bd00,
|
|
||||||
),
|
|
||||||
stack_segment: 16,
|
|
||||||
}
|
|
|
@ -1,8 +1,10 @@
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
|
use alloc::vec::Vec;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
use acpi::{AcpiHandler, AcpiTables, InterruptModel, PhysicalMapping};
|
use acpi::{AcpiHandler, AcpiTables, InterruptModel, PhysicalMapping};
|
||||||
use limine::{LimineBootInfoRequest, LimineKernelAddressRequest, LimineMemmapRequest, LimineTerminalRequest, LimineTerminalResponse, LimineRsdpRequest};
|
use acpi::platform::interrupt::InterruptSourceOverride;
|
||||||
|
use limine::{LimineBootInfoRequest, LimineKernelAddressRequest, LimineMemmapRequest, LimineTerminalRequest, LimineTerminalResponse, LimineRsdpRequest, LimineSmpRequest};
|
||||||
use crate::{debug, println};
|
use crate::{debug, println};
|
||||||
|
|
||||||
#[cfg(feature = "f_multiboot2")]
|
#[cfg(feature = "f_multiboot2")]
|
||||||
|
@ -17,6 +19,7 @@ pub static TERMINAL_REQUEST: LimineTerminalRequest = LimineTerminalRequest::new(
|
||||||
pub static MEM_MAP: LimineMemmapRequest = LimineMemmapRequest::new(0);
|
pub static MEM_MAP: LimineMemmapRequest = LimineMemmapRequest::new(0);
|
||||||
pub static RSDP_REQUEST: LimineRsdpRequest = LimineRsdpRequest::new(0);
|
pub static RSDP_REQUEST: LimineRsdpRequest = LimineRsdpRequest::new(0);
|
||||||
pub static KERNEL_ADDRESS: LimineKernelAddressRequest = LimineKernelAddressRequest::new(0);
|
pub static KERNEL_ADDRESS: LimineKernelAddressRequest = LimineKernelAddressRequest::new(0);
|
||||||
|
pub static SMP_REQUEST: LimineSmpRequest = LimineSmpRequest::new(0);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Handler;
|
struct Handler;
|
||||||
|
@ -24,7 +27,7 @@ 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
|
unsafe fn map_physical_region<T>(&self, physical_address: usize, size: usize) -> PhysicalMapping<Self, T> { // todo! check if size is too big
|
||||||
// only get lower 32 bits of physical address
|
// only get lower 32 bits of physical address
|
||||||
let physical_address = physical_address as u32;
|
let physical_address = physical_address as u32;
|
||||||
debug!("Mapping physical region: {:x} - {:x}", physical_address, physical_address + size as u32);
|
debug!("mapping physical region: {:x} - {:x}", physical_address, physical_address + size as u32);
|
||||||
let _ = read_phys_memory32(physical_address as u32) as usize;
|
let _ = read_phys_memory32(physical_address as u32) as usize;
|
||||||
PhysicalMapping::new(
|
PhysicalMapping::new(
|
||||||
physical_address as usize,
|
physical_address as usize,
|
||||||
|
@ -40,8 +43,8 @@ impl AcpiHandler for Handler {
|
||||||
let res = unsafe { MEM_MAPPER.lock().as_mut().unwrap().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
|
// 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() {
|
if let Err(e) = res {
|
||||||
println!("[WARN] failed to unmap page (this is normal)");
|
debug!("(THIS IS NORMAL) failed to unmap physical region: {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,15 +71,18 @@ impl core::fmt::Write for LimineWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ioapic_addr() -> u32 {
|
pub fn get_ioapic_info() -> (u32, Vec<InterruptSourceOverride>) {
|
||||||
let rsdp = RSDP_REQUEST.get_response().get().unwrap();
|
let rsdp = RSDP_REQUEST.get_response().get().unwrap();
|
||||||
let rsdp_ptr = rsdp.address.get().unwrap() as *const u8;
|
let rsdp_ptr = rsdp.address.get().unwrap() as *const u8;
|
||||||
let tables = unsafe { AcpiTables::from_rsdp(Handler, rsdp_ptr as usize).unwrap() };
|
let tables = unsafe { AcpiTables::from_rsdp(Handler, rsdp_ptr as usize).unwrap() };
|
||||||
let platform_info = tables.platform_info().expect("no platform info");
|
let platform_info = tables.platform_info().expect("no platform info");
|
||||||
let interrupt_model = platform_info.interrupt_model;
|
let interrupt_model = platform_info.interrupt_model;
|
||||||
let ioapic_addr = match interrupt_model {
|
let apic = match interrupt_model {
|
||||||
InterruptModel::Apic(apic) => apic.io_apics[0].address,
|
InterruptModel::Apic(apic) => apic,
|
||||||
_ => panic!("unsupported interrupt model"),
|
_ => panic!("unsupported interrupt model"),
|
||||||
};
|
};
|
||||||
ioapic_addr
|
let ioapic = apic.io_apics.first().expect("no ioapic");
|
||||||
|
let address = ioapic.address;
|
||||||
|
let overrides = apic.interrupt_source_overrides;
|
||||||
|
(address, overrides)
|
||||||
}
|
}
|
|
@ -1,15 +1,46 @@
|
||||||
|
use alloc::vec::Vec;
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
use acpi::platform::interrupt::InterruptSourceOverride;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use spin::Mutex;
|
||||||
use x2apic::ioapic::{IoApic, IrqFlags, IrqMode, RedirectionTableEntry};
|
use x2apic::ioapic::{IoApic, IrqFlags, IrqMode, RedirectionTableEntry};
|
||||||
use x2apic::lapic::{LocalApicBuilder, xapic_base};
|
use x2apic::lapic::{LocalApic, LocalApicBuilder, xapic_base};
|
||||||
use x86_64::PhysAddr;
|
use x86_64::PhysAddr;
|
||||||
use x86_64::structures::idt::InterruptStackFrame;
|
use x86_64::structures::idt::InterruptStackFrame;
|
||||||
use x86_64::structures::paging::PhysFrame;
|
use x86_64::structures::paging::PhysFrame;
|
||||||
use crate::{debug, print, println};
|
use crate::{debug, print, println};
|
||||||
use crate::memory::{BootInfoFrameAllocator, read_phys_memory32, write_phys_memory32};
|
use crate::memory::{BootInfoFrameAllocator, read_phys_memory32, write_phys_memory32};
|
||||||
use crate::serial::{command, read};
|
use crate::serial::{command, read};
|
||||||
|
use crate::serial::simplifiers::handle_scancode;
|
||||||
|
|
||||||
// todo! maybe abstract this into different sections for different parts of cpu func?
|
// todo! maybe abstract this into different sections for different parts of cpu func?
|
||||||
|
|
||||||
|
pub const APIC_INTERRUPT_OFFSET: usize = 32;
|
||||||
|
|
||||||
|
pub const TIMER_IRQ: usize = 0 + APIC_INTERRUPT_OFFSET;
|
||||||
|
pub const ERROR_IRQ: usize = 1 + APIC_INTERRUPT_OFFSET;
|
||||||
|
pub const SPURIOUS_IRQ: usize = 2 + APIC_INTERRUPT_OFFSET;
|
||||||
|
|
||||||
|
pub const IOAPIC_IRQ_OFFSET: usize = 42;
|
||||||
|
pub const FALLBACK_KEYBOARD_IRQ: usize = 1 + IOAPIC_IRQ_OFFSET;
|
||||||
|
|
||||||
|
|
||||||
|
lazy_static!{
|
||||||
|
static ref LAPIC: Mutex<LocalApic> = {
|
||||||
|
// we need to get the xapic region
|
||||||
|
let phys_addr = unsafe { xapic_base() };
|
||||||
|
|
||||||
|
let mut lapic = LocalApicBuilder::new()
|
||||||
|
.timer_vector(TIMER_IRQ as usize)
|
||||||
|
.spurious_vector(SPURIOUS_IRQ as usize)
|
||||||
|
.error_vector(ERROR_IRQ as usize)
|
||||||
|
.set_xapic_base(phys_addr)
|
||||||
|
.build()
|
||||||
|
.unwrap_or_else(|e| panic!("failed to build local apic: {}", e));
|
||||||
|
Mutex::new(lapic)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_apic_compat() -> bool {
|
pub fn check_apic_compat() -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut eax: u32;
|
let mut eax: u32;
|
||||||
|
@ -23,42 +54,54 @@ pub fn check_apic_compat() -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_apic() {
|
pub fn tell_pic8259a_to_f_off() {
|
||||||
// we need to get the xapic region
|
|
||||||
let phys_addr = unsafe { xapic_base() };
|
|
||||||
|
|
||||||
let mut lapic = LocalApicBuilder::new()
|
|
||||||
.timer_vector(0x40)
|
|
||||||
.error_vector(0x41)
|
|
||||||
.spurious_vector(0x42)
|
|
||||||
.set_xapic_base(phys_addr)
|
|
||||||
.build()
|
|
||||||
.unwrap_or_else(|e| panic!("failed to build local apic: {}", e));
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
lapic.enable();
|
asm!("cli");
|
||||||
|
asm!("out dx, al", in("dx") 0x20, in("al") 0x11i8);
|
||||||
|
asm!("out dx, al", in("dx") 0xA0, in("al") 0x11i8);
|
||||||
|
asm!("out dx, al", in("dx") 0x21, in("al") 0x20i8);
|
||||||
|
asm!("out dx, al", in("dx") 0xA1, in("al") 0x28i8);
|
||||||
|
asm!("out dx, al", in("dx") 0x21, in("al") 0x04i8);
|
||||||
|
asm!("out dx, al", in("dx") 0xA1, in("al") 0x02i8);
|
||||||
|
asm!("out dx, al", in("dx") 0x21, in("al") 0x01i8);
|
||||||
|
asm!("out dx, al", in("dx") 0xA1, in("al") 0x01i8);
|
||||||
|
asm!("out dx, al", in("dx") 0x21, in("al") 0x0i8);
|
||||||
|
asm!("out dx, al", in("dx") 0xA1, in("al") 0x0i8);
|
||||||
|
asm!("sti");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable_apic() {
|
||||||
|
unsafe {
|
||||||
|
LAPIC.lock().enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "x86-interrupt" fn timer(stack_frame: InterruptStackFrame) {
|
pub extern "x86-interrupt" fn timer(stack_frame: InterruptStackFrame) {
|
||||||
println!("timer interrupt");
|
end_of_interupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "x86-interrupt" fn error(stack_frame: InterruptStackFrame) {
|
pub extern "x86-interrupt" fn error(stack_frame: InterruptStackFrame) {
|
||||||
println!("error interrupt");
|
println!("error interrupt");
|
||||||
|
end_of_interupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "x86-interrupt" fn spurious(stack_frame: InterruptStackFrame) {
|
pub extern "x86-interrupt" fn spurious(stack_frame: InterruptStackFrame) {
|
||||||
println!("spurious interrupt");
|
println!("spurious interrupt");
|
||||||
|
end_of_interupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_of_interupt() {
|
||||||
|
unsafe {
|
||||||
|
LAPIC.lock().end_of_interrupt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo! in the future this will be removed, it is only for testing basic apic functionality
|
// todo! in the future this will be removed, it is only for testing basic apic functionality
|
||||||
pub extern "x86-interrupt" fn keyboard_irq(stack_frame: InterruptStackFrame) {
|
pub extern "x86-interrupt" fn keyboard_irq(stack_frame: InterruptStackFrame) {
|
||||||
debug!("keyboard interrupt");
|
|
||||||
unsafe { asm!("iretq"); }
|
|
||||||
let scancode = read(0x60);
|
let scancode = read(0x60);
|
||||||
|
|
||||||
print!("ksc: {},", scancode);
|
handle_scancode(scancode);
|
||||||
|
|
||||||
// reset keyboard controller
|
// reset keyboard controller
|
||||||
let mut a = read(0x61);
|
let mut a = read(0x61);
|
||||||
|
@ -66,21 +109,27 @@ pub extern "x86-interrupt" fn keyboard_irq(stack_frame: InterruptStackFrame) {
|
||||||
command(0x61, a);
|
command(0x61, a);
|
||||||
a &= 0x7f;
|
a &= 0x7f;
|
||||||
command(0x61, a);
|
command(0x61, a);
|
||||||
|
|
||||||
|
end_of_interupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo! we should abstract this away
|
// todo! we should abstract this away
|
||||||
pub fn setup_ioapic(ioapicaddr: u32) {
|
pub fn setup_ioapic(ioapicaddr: u32, isos: Vec<InterruptSourceOverride>) {
|
||||||
let mut ioapic = unsafe {
|
let mut ioapic = unsafe {
|
||||||
IoApic::new(ioapicaddr as u64)
|
IoApic::new(ioapicaddr as u64)
|
||||||
};
|
};
|
||||||
// setup keyboard interrupt
|
// setup keyboard interrupt
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// FIXME! only for testing that this works, abstract ASAP!
|
||||||
|
let gsi_keyboard = isos.iter().find(|iso| iso.isa_source == 1)
|
||||||
|
.map(|iso| iso.global_system_interrupt).unwrap_or(1);
|
||||||
// init with irq offset
|
// init with irq offset
|
||||||
ioapic.init(0x50);
|
ioapic.init(IOAPIC_IRQ_OFFSET as u8);
|
||||||
let mut entry = RedirectionTableEntry::default();
|
let mut entry = RedirectionTableEntry::default();
|
||||||
entry.set_mode(IrqMode::Fixed);
|
entry.set_mode(IrqMode::Fixed);
|
||||||
entry.set_flags(IrqFlags::LEVEL_TRIGGERED | IrqFlags::LOW_ACTIVE | IrqFlags::MASKED);
|
entry.set_flags(IrqFlags::LEVEL_TRIGGERED | IrqFlags::LOW_ACTIVE | IrqFlags::MASKED);
|
||||||
entry.set_dest(0);
|
entry.set_dest(0);
|
||||||
|
entry.set_vector(gsi_keyboard as u8 + IOAPIC_IRQ_OFFSET as u8);
|
||||||
ioapic.set_table_entry(1, entry);
|
ioapic.set_table_entry(1, entry);
|
||||||
|
|
||||||
ioapic.enable_irq(1);
|
ioapic.enable_irq(1);
|
||||||
|
|
|
@ -14,10 +14,11 @@ pub extern "x86-interrupt" fn breakpoint_exception(stack_frame: InterruptStackFr
|
||||||
println!("stack frame: {:#?}", stack_frame);
|
println!("stack frame: {:#?}", stack_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "x86-interrupt" fn double_fault(stack_frame: InterruptStackFrame, _error_code: u64) -> ! {
|
pub extern "x86-interrupt" fn double_fault(stack_frame: InterruptStackFrame, error_code: u64) -> ! {
|
||||||
println!("---KERNEL FUCKY WUKKY UWU---");
|
println!("---KERNEL FUCKY WUKKY UWU---");
|
||||||
println!("double fault!");
|
println!("double fault!");
|
||||||
println!("stack frame: {:#?}", stack_frame);
|
println!("stack frame: {:#?}", stack_frame);
|
||||||
|
println!("error code: {}", error_code);
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,4 +29,12 @@ pub extern "x86-interrupt" fn page_fault(stack_frame: InterruptStackFrame, error
|
||||||
println!("error code: {:?}", error_code);
|
println!("error code: {:?}", error_code);
|
||||||
println!("stack frame: {:#?}", stack_frame);
|
println!("stack frame: {:#?}", stack_frame);
|
||||||
loop {}
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unhandled(stack_frame: InterruptStackFrame, index: u8, error_code: Option<u64>) {
|
||||||
|
println!("---KERNEL FUCKY WUKKY UWU---");
|
||||||
|
println!("unhandled interrupt: {}", index);
|
||||||
|
println!("error code: {:?}", error_code);
|
||||||
|
println!("stack frame: {:#?}", stack_frame);
|
||||||
|
loop {}
|
||||||
}
|
}
|
114
src/main.rs
114
src/main.rs
|
@ -21,10 +21,10 @@ use spin::Mutex;
|
||||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||||
use x86_64::structures::gdt::{GlobalDescriptorTable, Descriptor};
|
use x86_64::structures::gdt::{GlobalDescriptorTable, Descriptor};
|
||||||
use x86_64::structures::tss::TaskStateSegment;
|
use x86_64::structures::tss::TaskStateSegment;
|
||||||
use x86_64::{PhysAddr, VirtAddr};
|
use x86_64::{PhysAddr, set_general_handler, VirtAddr};
|
||||||
use x86_64::registers::segmentation::{CS, Segment, SS};
|
use x86_64::registers::segmentation::{CS, Segment, SS};
|
||||||
use x86_64::structures::paging::Translate;
|
use x86_64::structures::paging::Translate;
|
||||||
use crate::boot::{get_ioapic_addr, KERNEL_ADDRESS};
|
use crate::boot::{get_ioapic_info, KERNEL_ADDRESS};
|
||||||
use crate::internals::WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood::*;
|
use crate::internals::WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood::*;
|
||||||
use crate::memory::{FRAME_ALLOC, MEM_MAPPER};
|
use crate::memory::{FRAME_ALLOC, MEM_MAPPER};
|
||||||
use crate::serial::terminal::ST;
|
use crate::serial::terminal::ST;
|
||||||
|
@ -45,14 +45,17 @@ lazy_static! {
|
||||||
};
|
};
|
||||||
static ref IDT: InterruptDescriptorTable = {
|
static ref IDT: InterruptDescriptorTable = {
|
||||||
let mut idt = InterruptDescriptorTable::new();
|
let mut idt = InterruptDescriptorTable::new();
|
||||||
idt.breakpoint.set_handler_fn(internals::errors::breakpoint_exception);
|
unsafe {
|
||||||
idt.double_fault.set_handler_fn(internals::errors::double_fault);
|
use internals::errors::unhandled;
|
||||||
idt.page_fault.set_handler_fn(internals::errors::page_fault);
|
set_general_handler!(&mut idt, unhandled);
|
||||||
idt[40].set_handler_fn(internals::cpu::timer);
|
idt.breakpoint.set_handler_fn(internals::errors::breakpoint_exception).set_stack_index(0);
|
||||||
idt[41].set_handler_fn(internals::cpu::error);
|
idt.double_fault.set_handler_fn(internals::errors::double_fault).set_stack_index(0);
|
||||||
idt[42].set_handler_fn(internals::cpu::spurious);
|
idt.page_fault.set_handler_fn(internals::errors::page_fault).set_stack_index(0);
|
||||||
idt[50].set_handler_fn(internals::cpu::timer);
|
idt[internals::cpu::TIMER_IRQ].set_handler_fn(internals::cpu::timer).set_stack_index(1);
|
||||||
idt[51].set_handler_fn(internals::cpu::keyboard_irq);
|
idt[internals::cpu::ERROR_IRQ].set_handler_fn(internals::cpu::error).set_stack_index(1);
|
||||||
|
idt[internals::cpu::SPURIOUS_IRQ].set_handler_fn(internals::cpu::spurious).set_stack_index(1);
|
||||||
|
idt[internals::cpu::FALLBACK_KEYBOARD_IRQ].set_handler_fn(internals::cpu::keyboard_irq).set_stack_index(1);
|
||||||
|
}
|
||||||
idt
|
idt
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -74,7 +77,7 @@ fn panic(info: &PanicInfo) -> ! {
|
||||||
println!("no panic payload")
|
println!("no panic payload")
|
||||||
};
|
};
|
||||||
if let Some(msg) = info.message() {
|
if let Some(msg) = info.message() {
|
||||||
println!("panic msg: {}", msg.as_str().unwrap_or("no message"))
|
println!("panic msg: {}", msg)
|
||||||
} else {
|
} else {
|
||||||
println!("no message");
|
println!("no message");
|
||||||
}
|
}
|
||||||
|
@ -112,13 +115,80 @@ pub extern "C" fn kernel_main() -> ! {
|
||||||
static mut tss: TaskStateSegment = TaskStateSegment::new();
|
static mut tss: TaskStateSegment = TaskStateSegment::new();
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
tss.interrupt_stack_table[0] = {
|
{
|
||||||
const STACK_SIZE: usize = 4096 * 5;
|
tss.interrupt_stack_table[0] = {
|
||||||
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
let stack_end = stack_start + STACK_SIZE;
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
stack_end
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
};
|
stack_end
|
||||||
|
};
|
||||||
|
tss.interrupt_stack_table[1] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
tss.interrupt_stack_table[2] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
tss.interrupt_stack_table[3] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
tss.interrupt_stack_table[4] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
tss.interrupt_stack_table[5] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
tss.interrupt_stack_table[6] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
tss.privilege_stack_table[0] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
tss.privilege_stack_table[1] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
tss.privilege_stack_table[2] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
|
let stack_end = stack_start + STACK_SIZE;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
}
|
||||||
// set word at offset 102 to 0x68 and last two bytes of the tss to 0xffff
|
// set word at offset 102 to 0x68 and last two bytes of the tss to 0xffff
|
||||||
// this is a hack to make the tss valid
|
// this is a hack to make the tss valid
|
||||||
let tss_ptr = &tss as *const TaskStateSegment as *mut u8;
|
let tss_ptr = &tss as *const TaskStateSegment as *mut u8;
|
||||||
|
@ -208,17 +278,19 @@ pub extern "C" fn kernel_main() -> ! {
|
||||||
panic!("apic required at the moment");
|
panic!("apic required at the moment");
|
||||||
}
|
}
|
||||||
print!("initialising apic...");
|
print!("initialising apic...");
|
||||||
let ioapicaddr = get_ioapic_addr();
|
//internals::cpu::tell_pic8259a_to_f_off();
|
||||||
|
let (addr, isos) = get_ioapic_info();
|
||||||
unsafe { internals::cpu::enable_apic() };
|
unsafe { internals::cpu::enable_apic() };
|
||||||
println!("[OK]");
|
println!("[OK]");
|
||||||
print!("setting up apic interrupts...");
|
print!("setting up apic interrupts...");
|
||||||
debug!("ioapicaddr: {:#x}", ioapicaddr);
|
debug!("ioapicaddr: {:#x}", addr);
|
||||||
unsafe { internals::cpu::setup_ioapic(ioapicaddr) };
|
unsafe { internals::cpu::setup_ioapic(addr, isos) };
|
||||||
println!("[OK]");
|
println!("[OK]");
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
//x86_64::instructions::interrupts::enable();
|
//x86_64::instructions::interrupts::enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
x86_64::instructions::hlt();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,7 @@ use core::ops::Deref;
|
||||||
|
|
||||||
pub mod terminal_helpers;
|
pub mod terminal_helpers;
|
||||||
pub mod terminal;
|
pub mod terminal;
|
||||||
|
pub mod simplifiers;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum potential_serial_ports {
|
pub enum potential_serial_ports {
|
||||||
|
|
20
src/serial/simplifiers.rs
Normal file
20
src/serial/simplifiers.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use pc_keyboard::{Keyboard, layouts, ScancodeSet1, HandleControl};
|
||||||
|
use pc_keyboard::DecodedKey::Unicode;
|
||||||
|
use spin::Mutex;
|
||||||
|
use crate::print;
|
||||||
|
|
||||||
|
lazy_static!{
|
||||||
|
static ref KBD: Mutex<Keyboard<layouts::Us104Key, ScancodeSet1>> = Mutex::new(Keyboard::new(HandleControl::MapLettersToUnicode));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_scancode(scancode: u8) {
|
||||||
|
let mut kbd = KBD.lock();
|
||||||
|
if let Ok(Some(key_event)) = kbd.add_byte(scancode) {
|
||||||
|
if let Some(key) = kbd.process_keyevent(key_event) {
|
||||||
|
if let Unicode(c) = key {
|
||||||
|
print!("{}", c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue