1

Sync with BSuSP

This commit is contained in:
2023-03-03 15:40:25 +01:00
parent 8bec9735e3
commit 5349bca520
27 changed files with 804 additions and 2523 deletions

View File

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

View File

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

View File

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

View File

@ -1,4 +1,6 @@
; This section has to be compiled for 16-bit real mode
[SECTION .text]
bits 16
boot_ap:
; Disable interrupts
cli

View 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

View File

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

View File

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

View File

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

View File

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

View File

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