ITS FUCKING WORKING OH MY GOD

This commit is contained in:
fekhesk 2022-10-27 21:58:36 -07:00
parent d11d5ddd97
commit 314189882b
No known key found for this signature in database
GPG key ID: 6B3D8CB511646891
8 changed files with 216 additions and 94 deletions

View file

@ -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"]

View file

@ -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,
}

View file

@ -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)
} }

View file

@ -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);

View file

@ -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 {}
} }
@ -29,3 +30,11 @@ pub extern "x86-interrupt" fn page_fault(stack_frame: InterruptStackFrame, error
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 {}
}

View file

@ -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,6 +115,7 @@ 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] = { tss.interrupt_stack_table[0] = {
const STACK_SIZE: usize = 4096 * 5; const STACK_SIZE: usize = 4096 * 5;
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE]; static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
@ -119,6 +123,72 @@ pub extern "C" fn kernel_main() -> ! {
let stack_end = stack_start + STACK_SIZE; let stack_end = stack_start + STACK_SIZE;
stack_end 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();
} }
} }

View file

@ -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
View 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);
}
}
}
}