Make inits 'safe'

master
WangRunji 7 years ago
parent 2028eadbfe
commit cf099ffa99

@ -10,7 +10,7 @@ grub_cfg := $(boot_src)/grub.cfg
assembly_source_files := $(wildcard $(boot_src)/*.asm) assembly_source_files := $(wildcard $(boot_src)/*.asm)
assembly_object_files := $(patsubst $(boot_src)/%.asm, \ assembly_object_files := $(patsubst $(boot_src)/%.asm, \
build/arch/$(arch)/boot/%.o, $(assembly_source_files)) build/arch/$(arch)/boot/%.o, $(assembly_source_files))
qemu_opts := -cdrom $(iso) -smp 2 -serial stdio qemu_opts := -cdrom $(iso) -smp 2 -serial mon:stdio
ifdef travis ifdef travis
test := 1 test := 1

@ -12,13 +12,14 @@ use spin::Mutex;
pub fn init(ioapic_id: u8) pub fn init(ioapic_id: u8)
{ {
let mut ioapic = IOAPIC.lock(); let mut ioapic = IOAPIC.lock();
assert!(ioapic.id() == ioapic_id, "ioapicinit: id isn't equal to ioapicid; not a MP"); assert!(ioapic.id() == ioapic_id, "ioapic.init: id isn't equal to ioapicid; not a MP");
// Mark all interrupts edge-triggered, active high, disabled, // Mark all interrupts edge-triggered, active high, disabled,
// and not routed to any CPUs. // and not routed to any CPUs.
for i in 0.. ioapic.maxintr() + 1 { for i in 0.. ioapic.maxintr() + 1 {
ioapic.write_irq(i, DISABLED, 0); ioapic.write_irq(i, DISABLED, 0);
} }
debug!("ioapic: init end");
} }
const IOAPIC_ADDRESS : u32 = 0xFEC00000; // Default physical address of IO APIC const IOAPIC_ADDRESS : u32 = 0xFEC00000; // Default physical address of IO APIC
@ -80,6 +81,7 @@ impl IoApic {
} }
pub fn enable(&mut self, irq: u8, cpunum: u8) pub fn enable(&mut self, irq: u8, cpunum: u8)
{ {
debug!("ioapic: enable irq {} @ cpu{}", irq, cpunum);
// Mark interrupt edge-triggered, active high, // Mark interrupt edge-triggered, active high,
// enabled, and routed to the given cpunum, // enabled, and routed to the given cpunum,
// which happens to be that cpu's APIC ID. // which happens to be that cpu's APIC ID.

@ -3,8 +3,11 @@ extern {
fn lapicinit(); // must set `lapic` first fn lapicinit(); // must set `lapic` first
} }
pub unsafe fn init(lapic_addr: *const ()) { pub fn init(lapic_addr: *const ()) {
debug!("WARNING: lapic::init use C lib"); debug!("WARNING: lapic::init use C lib");
lapic = lapic_addr; unsafe {
lapicinit(); lapic = lapic_addr;
lapicinit();
}
debug!("lapic: init end");
} }

@ -3,7 +3,8 @@ pub use self::ioapic::IOAPIC;
mod lapic; mod lapic;
mod ioapic; mod ioapic;
pub unsafe fn init(lapic_addr: *const (), ioapic_id: u8) { pub fn init(lapic_addr: *const (), ioapic_id: u8) {
assert_has_not_been_called!("apic::init must be called only once");
self::lapic::init(lapic_addr); self::lapic::init(lapic_addr);
self::ioapic::init(ioapic_id); self::ioapic::init(ioapic_id);
} }

@ -5,6 +5,8 @@ static MASTER: Mutex<Pic> = Mutex::new(Pic::new(0x20));
static SLAVE: Mutex<Pic> = Mutex::new(Pic::new(0xA0)); static SLAVE: Mutex<Pic> = Mutex::new(Pic::new(0xA0));
pub fn init() { pub fn init() {
assert_has_not_been_called!("pic::init must be called only once");
let mut master = MASTER.lock(); let mut master = MASTER.lock();
let mut slave = SLAVE.lock(); let mut slave = SLAVE.lock();

@ -78,9 +78,9 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) {
memory_controller.map_page_identity(acpi.lapic_addr as usize); // LAPIC memory_controller.map_page_identity(acpi.lapic_addr as usize); // LAPIC
memory_controller.map_page_identity(0xFEC00000); // IOAPIC memory_controller.map_page_identity(0xFEC00000); // IOAPIC
unsafe{ arch::driver::apic::init(acpi.lapic_addr, acpi.ioapic_id); } arch::driver::apic::init(acpi.lapic_addr, acpi.ioapic_id);
unsafe{ arch::driver::pic::init(); } arch::driver::pic::init();
test_end!(); test_end!();
} }

Loading…
Cancel
Save