Fully implemented reading the RTC century counter, and laid out initial infrastructure for ACPI information to be used across the kernel, in the x86_64 architecture.
- Implemented a global variable, ACPI_TABLE, behind a mutex, which contains the ACPI information pertinent to the rest of the kernel, currently solely containing a pointer to the FADT. - Split device initialization into two categories - "core" devices, such as the PIC and local APIC, necessary for initializing the rest of the kernel, and "non-core" devices such as serial and RTC, which are to be initialized last. - Checked for the presence of the century register, and consequentially read from, in the RTC code, now factored into the date calculation. The location of the register is pulled from the "century" field in the FADT. - Modified page unmapping in the ACPI code, such that any tables to be stored globally (currently only the FADT) are not unmapped after reading, such that they can be stored in globally accessible pointers without causing page faults.
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
use core::intrinsics::{atomic_load, atomic_store};
|
||||
use core::sync::atomic::Ordering;
|
||||
|
||||
use spin::Mutex;
|
||||
|
||||
use device::local_apic::LOCAL_APIC;
|
||||
use interrupt;
|
||||
use memory::{allocate_frames, Frame};
|
||||
@@ -173,7 +175,7 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) -> Option
|
||||
}
|
||||
|
||||
/// Parse the ACPI tables to gather CPU, interrupt, and timer information
|
||||
pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> {
|
||||
pub unsafe fn init(active_table: &mut ActivePageTable) {
|
||||
let start_addr = 0xE0000;
|
||||
let end_addr = 0xFFFFF;
|
||||
|
||||
@@ -266,16 +268,16 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> {
|
||||
}
|
||||
|
||||
if let Some(fadt) = theFADT {
|
||||
Some(Acpi { fadt: fadt })
|
||||
} else {
|
||||
None
|
||||
ACPI_TABLE.lock().fadt = Some(fadt);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Acpi {
|
||||
pub fadt: Fadt
|
||||
pub fadt: Option<Fadt>
|
||||
}
|
||||
|
||||
pub static ACPI_TABLE: Mutex<Acpi> = Mutex::new(Acpi { fadt: None });
|
||||
|
||||
/// RSDP
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(packed)]
|
||||
|
||||
@@ -9,6 +9,9 @@ pub mod serial;
|
||||
pub unsafe fn init(active_table: &mut ActivePageTable){
|
||||
pic::init();
|
||||
local_apic::init(active_table);
|
||||
}
|
||||
|
||||
pub unsafe fn init_noncore() {
|
||||
rtc::init();
|
||||
serial::init();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use syscall::io::{Io, Pio};
|
||||
use time;
|
||||
|
||||
use acpi;
|
||||
|
||||
pub fn init() {
|
||||
let mut rtc = Rtc::new();
|
||||
time::START.lock().0 = rtc.time();
|
||||
@@ -45,7 +47,15 @@ impl Rtc {
|
||||
let mut day;
|
||||
let mut month;
|
||||
let mut year;
|
||||
let mut century;
|
||||
let register_b;
|
||||
|
||||
let century_register = if let Some(ref fadt) = acpi::ACPI_TABLE.lock().fadt {
|
||||
Some(fadt.century)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
unsafe {
|
||||
self.wait();
|
||||
second = self.read(0) as usize;
|
||||
@@ -54,6 +64,11 @@ impl Rtc {
|
||||
day = self.read(7) as usize;
|
||||
month = self.read(8) as usize;
|
||||
year = self.read(9) as usize;
|
||||
century = if let Some(century_reg) = century_register {
|
||||
self.read(century_reg) as usize
|
||||
} else {
|
||||
20 as usize
|
||||
};
|
||||
register_b = self.read(0xB);
|
||||
}
|
||||
|
||||
@@ -64,14 +79,18 @@ impl Rtc {
|
||||
day = cvt_bcd(day);
|
||||
month = cvt_bcd(month);
|
||||
year = cvt_bcd(year);
|
||||
century = if let Some(century_reg) = century_register {
|
||||
cvt_bcd(century)
|
||||
} else {
|
||||
century
|
||||
};
|
||||
}
|
||||
|
||||
if register_b & 2 != 2 || hour & 0x80 == 0x80 {
|
||||
hour = ((hour & 0x7F) + 12) % 24;
|
||||
}
|
||||
|
||||
// TODO: Century Register
|
||||
year += 2000;
|
||||
year += century * 100;
|
||||
|
||||
// Unix time from clock
|
||||
let mut secs: u64 = (year as u64 - 1970) * 31536000;
|
||||
|
||||
@@ -113,13 +113,16 @@ pub unsafe extern fn kstart() -> ! {
|
||||
// Init the allocator
|
||||
allocator::init(::KERNEL_HEAP_OFFSET, ::KERNEL_HEAP_SIZE);
|
||||
}
|
||||
|
||||
|
||||
// Initialize devices
|
||||
device::init(&mut active_table);
|
||||
|
||||
// Read ACPI tables, starts APs
|
||||
acpi::init(&mut active_table);
|
||||
|
||||
// Initialize all of the non-core devices not otherwise needed to complete initialization
|
||||
device::init_noncore();
|
||||
|
||||
BSP_READY.store(true, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user