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:
Connor Wood
2017-03-18 16:08:45 +00:00
parent 661ebb6390
commit f79424aeac
4 changed files with 35 additions and 8 deletions

View File

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

View File

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

View File

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

View File

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