This commit is contained in:
parent
fe1c702a8f
commit
0bd69ce363
11 changed files with 110 additions and 39 deletions
|
@ -1,6 +1,6 @@
|
||||||
[licenses]
|
[licenses]
|
||||||
allow = ["Apache-2.0", "BSD-3-Clause", "ISC", "MIT", "MPL-2.0", "Unlicense"]
|
allow = ["Apache-2.0", "BSD-3-Clause", "ISC", "MIT", "MPL-2.0", "Unlicense", "Zlib"]
|
||||||
exceptions = [
|
exceptions = [
|
||||||
{allow = ["BSD-3-Clause-acpica"], crate = "acpica-rs"},
|
{allow = ["BSD-3-Clause-acpica"], crate = "acpica-rs"},
|
||||||
{allow = ["Unicode-DFS-2016"], crate = "unicode-ident"}
|
{allow = ["Unicode-3.0"], crate = "unicode-ident"}
|
||||||
]
|
]
|
||||||
|
|
|
@ -561,7 +561,7 @@ pub fn setup_idt() {
|
||||||
set_address(&mut idt.entries[249], isr249);
|
set_address(&mut idt.entries[249], isr249);
|
||||||
set_address(&mut idt.entries[250], isr250);
|
set_address(&mut idt.entries[250], isr250);
|
||||||
set_address(&mut idt.entries[251], isr251);
|
set_address(&mut idt.entries[251], isr251);
|
||||||
set_address(&mut idt.entries[252], isr252);
|
set_address(&mut idt.entries[252], isr252); // Invalidate TLB
|
||||||
set_address(&mut idt.entries[253], isr253); // SCI
|
set_address(&mut idt.entries[253], isr253); // SCI
|
||||||
set_address(&mut idt.entries[254], isr254); // Scheduler
|
set_address(&mut idt.entries[254], isr254); // Scheduler
|
||||||
set_address(&mut idt.entries[255], isr255); // Spurious interrupt
|
set_address(&mut idt.entries[255], isr255); // Spurious interrupt
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
use core::{arch::global_asm, sync::atomic::Ordering};
|
use core::{
|
||||||
|
arch::{asm, global_asm},
|
||||||
|
sync::atomic::Ordering,
|
||||||
|
};
|
||||||
|
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
use crate::sys::{lapic::send_eoi, scheduler::scheduler, sync::IN_ISR_HANDLER};
|
use crate::sys::{
|
||||||
|
lapic::{get_current_lapic_id, send_eoi},
|
||||||
|
scheduler::scheduler,
|
||||||
|
sync::{IN_ISR_HANDLER, LOCKS_HELD},
|
||||||
|
};
|
||||||
|
|
||||||
global_asm!(include_str!("isr.s"), options(att_syntax));
|
global_asm!(include_str!("isr.s"), options(att_syntax));
|
||||||
|
|
||||||
|
@ -69,6 +76,8 @@ const EXCEPTIONS: [&str; 32] = [
|
||||||
"Reserved",
|
"Reserved",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
pub const ISR_INVALIDATE_TLB: u64 = 252;
|
||||||
|
pub const ISR_SCHEDULER: u64 = 254;
|
||||||
pub static ISR_HANDLERS: Mutex<[Option<fn()>; 256]> = Mutex::new([None; 256]);
|
pub static ISR_HANDLERS: Mutex<[Option<fn()>; 256]> = Mutex::new([None; 256]);
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -85,10 +94,19 @@ extern "C" fn isr_handler(state: &mut ISRState) {
|
||||||
if 48 <= state.isr && state.isr <= 254 {
|
if 48 <= state.isr && state.isr <= 254 {
|
||||||
send_eoi(); // APIC interrupt
|
send_eoi(); // APIC interrupt
|
||||||
}
|
}
|
||||||
IN_ISR_HANDLER.store(true, Ordering::SeqCst);
|
if state.isr == ISR_INVALIDATE_TLB {
|
||||||
if state.isr == 254 {
|
// TODO: Only invalidate the entries that changed
|
||||||
|
unsafe {
|
||||||
|
asm!("mov rax, cr3; mov cr3, rax", out("rax") _);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let lapic_id = get_current_lapic_id();
|
||||||
|
IN_ISR_HANDLER[lapic_id].store(true, Ordering::SeqCst);
|
||||||
|
if state.isr == ISR_SCHEDULER {
|
||||||
scheduler(state);
|
scheduler(state);
|
||||||
IN_ISR_HANDLER.store(false, Ordering::SeqCst);
|
assert_eq!(LOCKS_HELD[lapic_id].load(Ordering::SeqCst), 0);
|
||||||
|
IN_ISR_HANDLER[lapic_id].store(false, Ordering::SeqCst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let handler;
|
let handler;
|
||||||
|
@ -100,5 +118,6 @@ extern "C" fn isr_handler(state: &mut ISRState) {
|
||||||
} else {
|
} else {
|
||||||
warn!("Unhandled interrupt: {}", state.isr);
|
warn!("Unhandled interrupt: {}", state.isr);
|
||||||
}
|
}
|
||||||
IN_ISR_HANDLER.store(false, Ordering::SeqCst);
|
assert_eq!(LOCKS_HELD[lapic_id].load(Ordering::SeqCst), 0);
|
||||||
|
IN_ISR_HANDLER[lapic_id].store(false, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ use kernel_common::{
|
||||||
use log::info;
|
use log::info;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
|
use crate::sys::lapic::smp_invalidate_tlb;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static _text_start: u8;
|
static _text_start: u8;
|
||||||
static _text_end: u8;
|
static _text_end: u8;
|
||||||
|
@ -42,10 +44,10 @@ fn _get_free_frame() -> u64 {
|
||||||
panic!("No free memory left");
|
panic!("No free memory left");
|
||||||
}
|
}
|
||||||
fn invlpg(addr: u64) {
|
fn invlpg(addr: u64) {
|
||||||
// TODO: Broadcast to all cores
|
|
||||||
unsafe {
|
unsafe {
|
||||||
asm!("invlpg [{}]", in(reg) addr);
|
asm!("invlpg [{}]", in(reg) addr);
|
||||||
}
|
}
|
||||||
|
smp_invalidate_tlb();
|
||||||
}
|
}
|
||||||
pub fn virt_to_phys(virt: u64) -> u64 {
|
pub fn virt_to_phys(virt: u64) -> u64 {
|
||||||
if !PAGING_ACTIVE.load(Ordering::SeqCst) {
|
if !PAGING_ACTIVE.load(Ordering::SeqCst) {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use core::arch::asm;
|
||||||
|
|
||||||
use kernel_common::instructions::sti;
|
use kernel_common::instructions::sti;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -15,9 +17,17 @@ extern "C" fn ap_main() -> ! {
|
||||||
setup_lapic(0);
|
setup_lapic(0);
|
||||||
// TODO: Also calibrate other cores
|
// TODO: Also calibrate other cores
|
||||||
setup_lapic_timer(false);
|
setup_lapic_timer(false);
|
||||||
|
set_cpu_flags();
|
||||||
unsafe {
|
unsafe {
|
||||||
sti();
|
sti();
|
||||||
}
|
}
|
||||||
yield_task();
|
yield_task();
|
||||||
panic!("Yielding to idle task failed");
|
panic!("Yielding to idle task failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_cpu_flags() {
|
||||||
|
unsafe {
|
||||||
|
// SMAP and SMEP
|
||||||
|
asm!("mov rax, cr4; bts rax, 20; bts rax, 21; mov cr4, rax", out("rax") _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use acpi::AcpiTables;
|
||||||
use acpica_rs::{AcpiEnableSubsystem, AcpiInitializeObjects, AcpiInitializeSubsystem, AcpiInitializeTables, AcpiLoadTables, ACPI_FULL_INITIALIZATION};
|
use acpica_rs::{AcpiEnableSubsystem, AcpiInitializeObjects, AcpiInitializeSubsystem, AcpiInitializeTables, AcpiLoadTables, ACPI_FULL_INITIALIZATION};
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
use buddy_system_allocator::LockedHeap;
|
use buddy_system_allocator::LockedHeap;
|
||||||
use cpu::{gdt::setup_gdt, idt::setup_idt, paging::setup_paging};
|
use cpu::{gdt::setup_gdt, idt::setup_idt, paging::setup_paging, smp::set_cpu_flags};
|
||||||
use kernel_common::{
|
use kernel_common::{
|
||||||
instructions::{cli, hlt},
|
instructions::{cli, hlt},
|
||||||
loader_struct::{FramebufferInfo, LoaderStruct, LoaderStructMemoryRegion, LOADER_STRUCT_MAGIC},
|
loader_struct::{FramebufferInfo, LoaderStruct, LoaderStructMemoryRegion, LOADER_STRUCT_MAGIC},
|
||||||
|
@ -29,7 +29,7 @@ use sys::{
|
||||||
acpica_osl::AE_OK,
|
acpica_osl::AE_OK,
|
||||||
early_acpi::EarlyACPIHandler,
|
early_acpi::EarlyACPIHandler,
|
||||||
hpet::setup_hpet,
|
hpet::setup_hpet,
|
||||||
lapic::{setup_lapic_timer, start_aps},
|
lapic::{get_current_lapic_id, setup_lapic_timer, start_aps},
|
||||||
madt::parse_madt,
|
madt::parse_madt,
|
||||||
pic::disable_pic,
|
pic::disable_pic,
|
||||||
sync::LOCKS_HELD,
|
sync::LOCKS_HELD,
|
||||||
|
@ -90,6 +90,7 @@ extern "C" fn early_main(temp_loader_struct: *const LoaderStruct) -> ! {
|
||||||
}
|
}
|
||||||
fn main() {
|
fn main() {
|
||||||
info!("Starting main kernel task...");
|
info!("Starting main kernel task...");
|
||||||
|
set_cpu_flags();
|
||||||
let mut status = unsafe { AcpiInitializeSubsystem() };
|
let mut status = unsafe { AcpiInitializeSubsystem() };
|
||||||
assert_eq!(status, AE_OK);
|
assert_eq!(status, AE_OK);
|
||||||
status = unsafe { AcpiInitializeTables(null_mut(), 0, 0) };
|
status = unsafe { AcpiInitializeTables(null_mut(), 0, 0) };
|
||||||
|
@ -105,7 +106,7 @@ fn main() {
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(info: &PanicInfo) -> ! {
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
cli();
|
cli();
|
||||||
LOCKS_HELD.fetch_add(1, Ordering::SeqCst);
|
LOCKS_HELD[get_current_lapic_id()].fetch_add(1, Ordering::SeqCst);
|
||||||
error!("{}", info);
|
error!("{}", info);
|
||||||
let str = format!("{}", info);
|
let str = format!("{}", info);
|
||||||
display_print(&str);
|
display_print(&str);
|
||||||
|
|
|
@ -27,15 +27,17 @@ bitfield! {
|
||||||
mask, set_mask: 16, 16;
|
mask, set_mask: 16, 16;
|
||||||
destination, set_destination: 63, 56;
|
destination, set_destination: 63, 56;
|
||||||
}
|
}
|
||||||
const EMPTY_IOAPIC: IOAPIC = IOAPIC {
|
|
||||||
address: AtomicPtr::new(null_mut()),
|
|
||||||
start_gsi: AtomicUsize::new(0),
|
|
||||||
end_gsi: AtomicUsize::new(0),
|
|
||||||
};
|
|
||||||
const REGISTER_VERSION: u8 = 1;
|
const REGISTER_VERSION: u8 = 1;
|
||||||
const REGISTER_REDIRECTION: u8 = 0x10;
|
const REGISTER_REDIRECTION: u8 = 0x10;
|
||||||
|
|
||||||
static IOAPICS: [IOAPIC; 32] = [EMPTY_IOAPIC; 32];
|
static IOAPICS: [IOAPIC; 32] = [const {
|
||||||
|
IOAPIC {
|
||||||
|
address: AtomicPtr::new(null_mut()),
|
||||||
|
start_gsi: AtomicUsize::new(0),
|
||||||
|
end_gsi: AtomicUsize::new(0),
|
||||||
|
}
|
||||||
|
}; 32];
|
||||||
static NEXT_IOAPIC_ID: AtomicUsize = AtomicUsize::new(0);
|
static NEXT_IOAPIC_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
fn read_register(apic_i: usize, reg_i: u8) -> u32 {
|
fn read_register(apic_i: usize, reg_i: u8) -> u32 {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use core::{
|
use core::{
|
||||||
|
arch::asm,
|
||||||
ptr::{copy, null_mut},
|
ptr::{copy, null_mut},
|
||||||
sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering},
|
sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
|
@ -6,7 +7,10 @@ use core::{
|
||||||
use alloc::{vec, vec::Vec};
|
use alloc::{vec, vec::Vec};
|
||||||
use kernel_common::{instructions::pause, paging::PageTable};
|
use kernel_common::{instructions::pause, paging::PageTable};
|
||||||
|
|
||||||
use crate::cpu::paging::{map_physical, map_range, unmap, virt_to_phys, CURRENT_PML4};
|
use crate::cpu::{
|
||||||
|
isr::{ISR_INVALIDATE_TLB, ISR_SCHEDULER},
|
||||||
|
paging::{map_physical, map_range, unmap, virt_to_phys, CURRENT_PML4},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
hpet::sleep,
|
hpet::sleep,
|
||||||
|
@ -36,14 +40,14 @@ const REGISTER_TIMER_DIVIDE: usize = 0xf8;
|
||||||
const IPI_INIT: u32 = 0x500;
|
const IPI_INIT: u32 = 0x500;
|
||||||
const IPI_STARTUP: u32 = 0x600;
|
const IPI_STARTUP: u32 = 0x600;
|
||||||
|
|
||||||
const EMPTY_LAPIC: LAPIC = LAPIC {
|
|
||||||
lapic_id: AtomicUsize::new(0),
|
|
||||||
present: AtomicBool::new(false),
|
|
||||||
};
|
|
||||||
|
|
||||||
static ADDRESS: AtomicPtr<u32> = AtomicPtr::new(null_mut());
|
static ADDRESS: AtomicPtr<u32> = AtomicPtr::new(null_mut());
|
||||||
pub static BSP_LAPIC_ID: AtomicUsize = AtomicUsize::new(0);
|
pub static BSP_LAPIC_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
static LAPICS: [LAPIC; 256] = [EMPTY_LAPIC; 256];
|
static LAPICS: [LAPIC; 256] = [const {
|
||||||
|
LAPIC {
|
||||||
|
lapic_id: AtomicUsize::new(0),
|
||||||
|
present: AtomicBool::new(false),
|
||||||
|
}
|
||||||
|
}; 256];
|
||||||
static TICKS_PER_MS: AtomicUsize = AtomicUsize::new(0);
|
static TICKS_PER_MS: AtomicUsize = AtomicUsize::new(0);
|
||||||
pub static NEXT_LAPIC_ID: AtomicUsize = AtomicUsize::new(0);
|
pub static NEXT_LAPIC_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
@ -55,7 +59,13 @@ pub fn send_eoi() {
|
||||||
}
|
}
|
||||||
pub fn get_current_lapic_id() -> usize {
|
pub fn get_current_lapic_id() -> usize {
|
||||||
let address = ADDRESS.load(Ordering::SeqCst);
|
let address = ADDRESS.load(Ordering::SeqCst);
|
||||||
unsafe { address.add(REGISTER_ID).read_volatile() as usize >> 24 }
|
let lapic_id = unsafe { address.add(REGISTER_ID).read_volatile() as usize >> 24 };
|
||||||
|
let rflags: u64;
|
||||||
|
unsafe {
|
||||||
|
asm!("pushfq; pop {};", out(reg) rflags);
|
||||||
|
}
|
||||||
|
assert!(rflags & (1 << 9) == 0);
|
||||||
|
lapic_id
|
||||||
}
|
}
|
||||||
pub fn setup_lapic(phys: u64) {
|
pub fn setup_lapic(phys: u64) {
|
||||||
if phys != 0 {
|
if phys != 0 {
|
||||||
|
@ -101,10 +111,11 @@ pub fn setup_lapic_timer(calibrate: bool) {
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
address.add(REGISTER_TIMER_INITIAL_COUNT).write_volatile(0);
|
address.add(REGISTER_TIMER_INITIAL_COUNT).write_volatile(0);
|
||||||
address.add(REGISTER_TIMER_LVT).write_volatile(254);
|
address.add(REGISTER_TIMER_LVT).write_volatile(ISR_SCHEDULER as u32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn add_lapic(lapic_id: usize) {
|
pub fn add_lapic(lapic_id: usize) {
|
||||||
|
assert!(lapic_id < 256);
|
||||||
let next_id = NEXT_LAPIC_ID.fetch_add(1, Ordering::SeqCst);
|
let next_id = NEXT_LAPIC_ID.fetch_add(1, Ordering::SeqCst);
|
||||||
LAPICS[next_id].lapic_id.store(lapic_id, Ordering::SeqCst);
|
LAPICS[next_id].lapic_id.store(lapic_id, Ordering::SeqCst);
|
||||||
LAPICS[next_id].present.store(true, Ordering::SeqCst);
|
LAPICS[next_id].present.store(true, Ordering::SeqCst);
|
||||||
|
@ -144,8 +155,20 @@ pub fn start_aps() {
|
||||||
pause();
|
pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ALL_APS_STARTED.store(true, Ordering::SeqCst);
|
||||||
unsafe {
|
unsafe {
|
||||||
unmap(0x1000);
|
unmap(0x1000);
|
||||||
}
|
}
|
||||||
ALL_APS_STARTED.store(true, Ordering::SeqCst);
|
}
|
||||||
|
pub fn smp_invalidate_tlb() {
|
||||||
|
if !ALL_APS_STARTED.load(Ordering::SeqCst) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for i in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
|
||||||
|
let lapic_id = LAPICS[i].lapic_id.load(Ordering::SeqCst);
|
||||||
|
if lapic_id == BSP_LAPIC_ID.load(Ordering::SeqCst) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
send_ipi(lapic_id, ISR_INVALIDATE_TLB as u32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use core::{arch::asm, sync::atomic::Ordering};
|
use core::{arch::asm, sync::atomic::Ordering};
|
||||||
|
|
||||||
use alloc::{collections::vec_deque::VecDeque, vec::Vec};
|
use alloc::{collections::vec_deque::VecDeque, vec::Vec};
|
||||||
|
use kernel_common::instructions::cli;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
use crate::cpu::isr::ISRState;
|
use crate::cpu::isr::ISRState;
|
||||||
|
@ -63,9 +64,11 @@ pub fn schedule_task(task: Task) {
|
||||||
scheduler_list.push_back(task);
|
scheduler_list.push_back(task);
|
||||||
}
|
}
|
||||||
pub fn yield_task() {
|
pub fn yield_task() {
|
||||||
assert!(!IN_ISR_HANDLER.load(Ordering::SeqCst));
|
cli();
|
||||||
assert_eq!(LOCKS_HELD.load(Ordering::SeqCst), 0);
|
let lapic_id = get_current_lapic_id();
|
||||||
|
assert!(!IN_ISR_HANDLER[lapic_id].load(Ordering::SeqCst));
|
||||||
|
assert_eq!(LOCKS_HELD[lapic_id].load(Ordering::SeqCst), 0);
|
||||||
unsafe {
|
unsafe {
|
||||||
asm!("int $254");
|
asm!("sti; int $254");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ use super::{
|
||||||
task::{Task, TaskState, CURRENT_TASKS, CURRENT_TASK_LOCK},
|
task::{Task, TaskState, CURRENT_TASKS, CURRENT_TASK_LOCK},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub static IN_ISR_HANDLER: AtomicBool = AtomicBool::new(false);
|
pub static IN_ISR_HANDLER: [AtomicBool; 256] = [const { AtomicBool::new(false) }; 256];
|
||||||
pub static LOCKS_HELD: AtomicUsize = AtomicUsize::new(0);
|
pub static LOCKS_HELD: [AtomicUsize; 256] = [const { AtomicUsize::new(0) }; 256];
|
||||||
|
|
||||||
pub struct Semaphore {
|
pub struct Semaphore {
|
||||||
spinlock: Spinlock,
|
spinlock: Spinlock,
|
||||||
|
@ -23,23 +23,30 @@ pub struct Semaphore {
|
||||||
}
|
}
|
||||||
pub struct Spinlock {
|
pub struct Spinlock {
|
||||||
locked: AtomicBool,
|
locked: AtomicBool,
|
||||||
|
lapic_id: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Spinlock {
|
impl Spinlock {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self { locked: AtomicBool::new(false) }
|
Self {
|
||||||
|
locked: AtomicBool::new(false),
|
||||||
|
lapic_id: AtomicUsize::new(0),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub fn lock(&self) {
|
pub fn lock(&self) {
|
||||||
assert!(MULTITASKING_ENABLED.load(Ordering::SeqCst));
|
assert!(MULTITASKING_ENABLED.load(Ordering::SeqCst));
|
||||||
cli();
|
cli();
|
||||||
while !self.locked.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst).is_ok() {}
|
while !self.locked.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst).is_ok() {}
|
||||||
LOCKS_HELD.fetch_add(1, Ordering::SeqCst);
|
let lapic_id = get_current_lapic_id();
|
||||||
|
LOCKS_HELD[lapic_id].fetch_add(1, Ordering::SeqCst);
|
||||||
|
self.lapic_id.store(lapic_id, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
pub fn unlock(&self) {
|
pub fn unlock(&self) {
|
||||||
assert!(self.locked.load(Ordering::SeqCst));
|
assert!(self.locked.load(Ordering::SeqCst));
|
||||||
|
let lapic_id = self.lapic_id.load(Ordering::SeqCst);
|
||||||
self.locked.store(false, Ordering::SeqCst);
|
self.locked.store(false, Ordering::SeqCst);
|
||||||
LOCKS_HELD.fetch_sub(1, Ordering::SeqCst);
|
LOCKS_HELD[lapic_id].fetch_sub(1, Ordering::SeqCst);
|
||||||
if !IN_ISR_HANDLER.load(Ordering::SeqCst) && LOCKS_HELD.load(Ordering::SeqCst) == 0 {
|
if !IN_ISR_HANDLER[lapic_id].load(Ordering::SeqCst) && LOCKS_HELD[lapic_id].load(Ordering::SeqCst) == 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
sti();
|
sti();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use core::{
|
||||||
|
|
||||||
use alloc::{sync::Arc, vec, vec::Vec};
|
use alloc::{sync::Arc, vec, vec::Vec};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use kernel_common::instructions::{hlt, pause};
|
use kernel_common::instructions::{cli, hlt, pause, sti};
|
||||||
use spin::{Lazy, Mutex};
|
use spin::{Lazy, Mutex};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -142,9 +142,13 @@ extern "C" fn task_entry() -> ! {
|
||||||
}
|
}
|
||||||
fn idle_main() {
|
fn idle_main() {
|
||||||
while !ALL_APS_STARTED.load(Ordering::SeqCst) {
|
while !ALL_APS_STARTED.load(Ordering::SeqCst) {
|
||||||
|
cli();
|
||||||
if STARTING_AP_ID.load(Ordering::SeqCst) == get_current_lapic_id() as i64 {
|
if STARTING_AP_ID.load(Ordering::SeqCst) == get_current_lapic_id() as i64 {
|
||||||
let _ = STARTING_AP_ID.compare_exchange(get_current_lapic_id() as i64, -1, Ordering::SeqCst, Ordering::SeqCst);
|
let _ = STARTING_AP_ID.compare_exchange(get_current_lapic_id() as i64, -1, Ordering::SeqCst, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
unsafe {
|
||||||
|
sti();
|
||||||
|
}
|
||||||
pause();
|
pause();
|
||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
|
|
Loading…
Add table
Reference in a new issue