Sync with BSuSP
This commit is contained in:
@ -4,8 +4,8 @@ void *startupCodeMemory = memoryService.mapIO(0x8000, Util::PAGESIZE);
|
||||
|
||||
// Identity map the allocated physical memory to the kernel address space
|
||||
memoryService.unmap(reinterpret_cast<uint32_t>(startupCodeMemory));
|
||||
memoryService.mapPhysicalAddress(0x8000, 0x8000,
|
||||
Kernel::Paging::PRESENT | Kernel::Paging::READ_WRITE);
|
||||
memoryService.mapPhysicalAddress(0x8000, 0x8000, Kernel::Paging::PRESENT
|
||||
| Kernel::Paging::READ_WRITE);
|
||||
|
||||
// Copy the startup routine and prepared variables to the identity mapped page
|
||||
auto startupCode = Util::Address<uint32_t>(reinterpret_cast<uint32_t>(&boot_ap));
|
||||
|
||||
@ -6,18 +6,18 @@
|
||||
mov edi, ebx ; Now the ID is in EDI
|
||||
|
||||
; Load the AP's prepared GDT and TSS
|
||||
mov ebx, [boot_ap_gdts - boot_ap + startup_address]
|
||||
mov eax, [ebx + edi * 0x4]
|
||||
mov ebx, [boot_ap_gdts - boot_ap + 0x8000]
|
||||
mov eax, [ebx + edi * 0x4] ; Select the GDT
|
||||
lgdt [eax]
|
||||
mov ax, 0x28
|
||||
ltr ax
|
||||
|
||||
; Load the correct stack for this AP
|
||||
mov ebx, [boot_ap_stacks - boot_ap + startup_address]
|
||||
mov esp, [ebx + edi * 0x4]
|
||||
add esp, stack_size ; Stack starts at the bottom
|
||||
mov ebx, [boot_ap_stacks - boot_ap + 0x8000]
|
||||
mov esp, [ebx + edi * 0x4] ; Select the stack
|
||||
add esp, 0x1000 ; Stack starts at the bottom
|
||||
mov ebp, esp
|
||||
|
||||
; Call the entry function
|
||||
; Call the entry function smpEntry(uint8_t cpuid)
|
||||
push edi
|
||||
call [boot_ap_entry - boot_ap + startup_address]
|
||||
call [boot_ap_entry - boot_ap + 0x8000]
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
; This section has to be compiled for 32-bit protected mode
|
||||
bits 32
|
||||
boot_ap_32:
|
||||
; Set cr3, cr0 and cr4 to the BSP's values for paging
|
||||
mov eax, [boot_ap_cr3 - boot_ap + startup_address]
|
||||
mov eax, [boot_ap_cr3 - boot_ap + 0x8000]
|
||||
mov cr3, eax
|
||||
mov eax, [boot_ap_cr0 - boot_ap + startup_address]
|
||||
mov eax, [boot_ap_cr0 - boot_ap + 0x8000]
|
||||
mov cr0, eax
|
||||
mov eax, [boot_ap_cr4 - boot_ap + startup_address]
|
||||
mov eax, [boot_ap_cr4 - boot_ap + 0x8000]
|
||||
mov cr4, eax
|
||||
|
||||
; Load the system IDT
|
||||
lidt [boot_ap_idtr - boot_ap + startup_address]
|
||||
lidt [boot_ap_idtr - boot_ap + 0x8000]
|
||||
@ -1,4 +1,6 @@
|
||||
; This section has to be compiled for 16-bit real mode
|
||||
[SECTION .text]
|
||||
bits 16
|
||||
boot_ap:
|
||||
; Disable interrupts
|
||||
cli
|
||||
|
||||
43
code/ap_boot_variables.asm
Normal file
43
code/ap_boot_variables.asm
Normal file
@ -0,0 +1,43 @@
|
||||
; Export the variables to allow initialization by C++ code
|
||||
global boot_ap_idtr
|
||||
global boot_ap_cr0
|
||||
global boot_ap_cr3
|
||||
global boot_ap_cr4
|
||||
global boot_ap_gdts
|
||||
global boot_ap_stacks
|
||||
global boot_ap_entry
|
||||
|
||||
[SECTION .text]
|
||||
align 8
|
||||
bits 16
|
||||
boot_ap:
|
||||
; [...] boot_ap 16-bit
|
||||
|
||||
; The variables initialized during runtime
|
||||
align 8
|
||||
boot_ap_idtr:
|
||||
dw 0x0
|
||||
dd 0x0
|
||||
align 8
|
||||
boot_ap_cr0:
|
||||
dd 0x0
|
||||
align 8
|
||||
boot_ap_cr3:
|
||||
dd 0x0
|
||||
align 8
|
||||
boot_ap_cr4:
|
||||
dd 0x0
|
||||
align 8
|
||||
boot_ap_gdts:
|
||||
dd 0x0
|
||||
align 8
|
||||
boot_ap_stacks:
|
||||
dd 0x0
|
||||
align 8
|
||||
boot_ap_entry:
|
||||
dd 0x0
|
||||
|
||||
bits 32
|
||||
align 8
|
||||
boot_ap_32:
|
||||
; [...] boot_ap_32 32-bit
|
||||
@ -13,7 +13,7 @@ void ApicTimer::trigger(const InterruptFrame &frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger preemption
|
||||
// BSP triggers preemption
|
||||
if (time.toMilliseconds() % yieldInterval == 0) {
|
||||
System::getService<SchedulerService>().yield();
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
void IoApic::initializeREDTBL() {
|
||||
// GSI2 belongs to the PIT in many systems
|
||||
auto gsi = GlobalSystemInterrupt(2);
|
||||
IrqOverride *override = getOverride(gsi);
|
||||
|
||||
REDTBLEntry redtblEntry{};
|
||||
redtblEntry.deliveryMode = REDTBLEntry::DeliveryMode::FIXED;
|
||||
@ -10,6 +9,7 @@ void IoApic::initializeREDTBL() {
|
||||
redtblEntry.isMasked = true;
|
||||
redtblEntry.destination = LocalApic::getId(); // Redirect to BSP
|
||||
|
||||
IrqOverride *override = getOverride(gsi);
|
||||
if (override != nullptr) {
|
||||
// Apply any information provided by an interrupt override
|
||||
redtblEntry.vector = override->source + 32;
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
LVTEntry lvtEntry{};
|
||||
lvtEntry.deliveryMode = LVTEntry::DeliveryMode::FIXED;
|
||||
lvtEntry.pinPolarity = LVTEntry::PinPolarity::HIGH;
|
||||
lvtEntry.triggerMode = LVTEntry::TriggerMode::EDGE;
|
||||
lvtEntry.isMasked = true;
|
||||
lvtEntry.vector = InterruptVector::LINT0;
|
||||
writeLVT(LINT0, lvtEntry);
|
||||
// Excerpt from the initializeLVT function
|
||||
void LocalApic::initializeLVT() {
|
||||
LVTEntry lvtEntry{};
|
||||
lvtEntry.deliveryMode = LVTEntry::DeliveryMode::FIXED;
|
||||
lvtEntry.pinPolarity = LVTEntry::PinPolarity::HIGH;
|
||||
lvtEntry.triggerMode = LVTEntry::TriggerMode::EDGE;
|
||||
lvtEntry.isMasked = true;
|
||||
lvtEntry.vector = InterruptVector::ERROR;
|
||||
writeLVT(ERROR, lvtEntry);
|
||||
}
|
||||
@ -1,4 +1,7 @@
|
||||
SVREntry svrEntry{};
|
||||
svrEntry.vector = InterruptVector::SPURIOUS;
|
||||
svrEntry.isSWEnabled = true; // Keep the APIC software enabled
|
||||
writeSVR(svrEntry);
|
||||
// Excerpt from the initialize function
|
||||
void LocalApic::initialize() {
|
||||
SVREntry svrEntry{};
|
||||
svrEntry.vector = InterruptVector::SPURIOUS;
|
||||
svrEntry.isSWEnabled = true; // Keep the APIC software enabled
|
||||
writeSVR(svrEntry);
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
void Pit::earlyDelay(uint16_t us) {
|
||||
uint32_t counter = (static_cast<double>(BASE_FREQUENCY) / 1'000'000) * us;
|
||||
|
||||
controlPort.writeByte(0b110000); // Channel 0, mode 0
|
||||
controlPort.writeByte(0b110000); // Channel 0, mode 0
|
||||
dataPort0.writeByte(static_cast<uint8_t>(counter & 0xFF)); // Low byte
|
||||
dataPort0.writeByte(static_cast<uint8_t>((counter >> 8) & 0xFF)); // High byte
|
||||
|
||||
|
||||
Reference in New Issue
Block a user