From 4a5994dcefe0008c967e011ed4c11d0c0fe30cdd Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 23 Feb 2024 12:40:16 -0500 Subject: [PATCH 01/13] Initial I/O APIC additions --- src/init/acpi.asm | 26 ++++++++++++++++++-------- src/pure64.asm | 4 +++- src/sysvar.asm | 27 +++++++++++++++------------ 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/init/acpi.asm b/src/init/acpi.asm index 3eca13d..c07f146 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -151,7 +151,7 @@ parseAPICTable: xor eax, eax lodsd ; Local APIC Address mov [os_LocalAPICAddress], rax ; Save the Address of the Local APIC - lodsd ; Flags + lodsd ; Flags (1 = Dual 8259 Legacy PICs Installed) add ebx, 44 mov rdi, 0x0000000000005100 ; Valid CPU IDs @@ -201,7 +201,7 @@ APICioapic: lodsb ; IO APIC ID lodsb ; Reserved xor eax, eax - lodsd ; IO APIC Address + lodsd ; I/O APIC Address push rdi push rcx mov rdi, os_IOAPICAddress @@ -210,9 +210,9 @@ APICioapic: shl cx, 3 ; Quick multiply by 8 add rdi, rcx pop rcx - stosd ; Store the IO APIC Address - lodsd ; System Vector Base - stosd ; Store the IO APIC Vector Base + stosd ; Store the I/O APIC Address + lodsd ; Global System Interrupt Base + stosd ; Store the Global System Interrupt Base pop rdi inc byte [os_IOAPICCount] jmp readAPICstructures ; Read the next structure @@ -221,10 +221,20 @@ APICinterruptsourceoverride: xor eax, eax lodsb ; Length (will be set to 10) add ebx, eax - lodsb ; Bus - lodsb ; Source + mov rdi, os_IOAPICIntSource + xor ecx, ecx + mov cl, [os_IOAPICIntSourceC] + shl cx, 3 ; Quick multiply by 8 + add rdi, rcx + lodsb ; Bus Source + stosb + lodsb ; IRQ Source + stosb lodsd ; Global System Interrupt - lodsw ; Flags + stosd + lodsw ; Flags - bit 1 Low(1)/High(0), Bit 3 Level(1)/Edge(0) + stosw + inc byte [os_IOAPICIntSourceC] jmp readAPICstructures ; Read the next structure APICx2apic: diff --git a/src/pure64.asm b/src/pure64.asm index e239737..f1b7721 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -506,8 +506,10 @@ clearmapnext: mov cl, [os_IOAPICCount] mov rsi, os_IOAPICAddress nextIOAPIC: - lodsq + lodsq ; I/O APIC Address stosq + lodsq ; Global System Interrupt Base + stosq sub cl, 1 cmp cl, 0 jne nextIOAPIC diff --git a/src/sysvar.asm b/src/sysvar.asm index 346c0f2..c901107 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -14,7 +14,7 @@ cfg_smpinit: db 1 ; By default SMP is enabled. Set to 0 to disable. ; Memory locations E820Map: equ 0x0000000000004000 InfoMap: equ 0x0000000000005000 -SystemVariables: equ 0x0000000000005A00 +SystemVariables: equ 0x0000000000005800 VBEModeInfoBlock: equ 0x0000000000005C00 ; 256 bytes ; DQ - Starting at offset 0, increments by 0x8 @@ -23,22 +23,25 @@ os_LocalX2APICAddress: equ SystemVariables + 0x10 os_Counter_Timer: equ SystemVariables + 0x18 os_Counter_RTC: equ SystemVariables + 0x20 os_LocalAPICAddress: equ SystemVariables + 0x28 -os_IOAPICAddress: equ SystemVariables + 0x30 os_HPETAddress: equ SystemVariables + 0x38 -; DD - Starting at offset 128, increments by 4 -os_BSP: equ SystemVariables + 128 -mem_amount: equ SystemVariables + 132 ; in MiB +; DD - Starting at offset 0x80, increments by 4 +os_BSP: equ SystemVariables + 0x80 +mem_amount: equ SystemVariables + 0x84 ; in MiB -; DW - Starting at offset 256, increments by 2 -cpu_speed: equ SystemVariables + 256 -cpu_activated: equ SystemVariables + 258 -cpu_detected: equ SystemVariables + 260 +; DW - Starting at offset 0x100, increments by 2 +cpu_speed: equ SystemVariables + 0x100 +cpu_activated: equ SystemVariables + 0x102 +cpu_detected: equ SystemVariables + 0x104 -; DB - Starting at offset 384, increments by 1 -os_IOAPICCount: equ SystemVariables + 384 -BootMode: equ SystemVariables + 385 ; 'U' for UEFI, otherwise BIOS +; DB - Starting at offset 0x180, increments by 1 +os_IOAPICCount: equ SystemVariables + 0x180 +BootMode: equ SystemVariables + 0x181 ; 'U' for UEFI, otherwise BIOS +os_IOAPICIntSourceC: equ SystemVariables + 0x182 +; Lists - Starting at offset 0x200 +os_IOAPICAddress: equ SystemVariables + 0x200 ; 16 bytes each +os_IOAPICIntSource: equ SystemVariables + 0x280 ; 8 bytes each align 16 GDTR32: ; Global Descriptors Table Register From f2942122e5d75b386f569c9c942c3c2f9e5a0a62 Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 26 Feb 2024 17:45:23 -0500 Subject: [PATCH 02/13] Cleanup. Moved VBE data storage to 0x5F00 Commented ACPI code for further debugging --- src/boot/mbr.asm | 2 +- src/boot/pxestart.asm | 2 +- src/init/acpi.asm | 20 ++++++++++---------- src/pure64.asm | 6 +++--- src/sysvar.asm | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/boot/mbr.asm b/src/boot/mbr.asm index 8104aab..3d6ff0c 100644 --- a/src/boot/mbr.asm +++ b/src/boot/mbr.asm @@ -225,7 +225,7 @@ times 510-$+$$ db 0 sign dw 0xAA55 -VBEModeInfoBlock: equ 0x5C00 +VBEModeInfoBlock: equ 0x5F00 ; VESA ; Mandatory information for all VBE revisions VBEModeInfoBlock.ModeAttributes equ VBEModeInfoBlock + 0 ; DW - mode attributes diff --git a/src/boot/pxestart.asm b/src/boot/pxestart.asm index fefdad9..dc3d030 100644 --- a/src/boot/pxestart.asm +++ b/src/boot/pxestart.asm @@ -191,7 +191,7 @@ sign dw 0xAA55 ; BIOS boot sector signature times 1024-$+$$ db 0 ; Padding so that Pure64 will be aligned at 0x8000 -VBEModeInfoBlock: equ 0x5C00 +VBEModeInfoBlock: equ 0x5F00 ; VESA ; Mandatory information for all VBE revisions VBEModeInfoBlock.ModeAttributes equ VBEModeInfoBlock + 0 ; DW - mode attributes diff --git a/src/init/acpi.asm b/src/init/acpi.asm index c07f146..a17d94e 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -221,20 +221,20 @@ APICinterruptsourceoverride: xor eax, eax lodsb ; Length (will be set to 10) add ebx, eax - mov rdi, os_IOAPICIntSource - xor ecx, ecx - mov cl, [os_IOAPICIntSourceC] - shl cx, 3 ; Quick multiply by 8 - add rdi, rcx +; mov rdi, os_IOAPICIntSource +; xor ecx, ecx +; mov cl, [os_IOAPICIntSourceC] +; shl cx, 3 ; Quick multiply by 8 +; add rdi, rcx lodsb ; Bus Source - stosb +; stosb lodsb ; IRQ Source - stosb +; stosb lodsd ; Global System Interrupt - stosd +; stosd lodsw ; Flags - bit 1 Low(1)/High(0), Bit 3 Level(1)/Edge(0) - stosw - inc byte [os_IOAPICIntSourceC] +; stosw +; inc byte [os_IOAPICIntSourceC] jmp readAPICstructures ; Read the next structure APICx2apic: diff --git a/src/pure64.asm b/src/pure64.asm index f1b7721..422e532 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -57,10 +57,10 @@ start32: mov fs, ax mov gs, ax - mov edi, 0x5000 ; Clear the info map and system variable + mov edi, 0x5000 ; Clear the info map and system variable memory xor eax, eax - mov ecx, 768 - rep stosd + mov ecx, 960 ; 3840 bytes (Range is 0x5000 - 0x5EFF) + rep stosd ; Don't overwrite the VBE data at 0x5F00 xor eax, eax ; Clear all registers xor ebx, ebx diff --git a/src/sysvar.asm b/src/sysvar.asm index c901107..ea34a17 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -15,7 +15,7 @@ cfg_smpinit: db 1 ; By default SMP is enabled. Set to 0 to disable. E820Map: equ 0x0000000000004000 InfoMap: equ 0x0000000000005000 SystemVariables: equ 0x0000000000005800 -VBEModeInfoBlock: equ 0x0000000000005C00 ; 256 bytes +VBEModeInfoBlock: equ 0x0000000000005F00 ; 256 bytes ; DQ - Starting at offset 0, increments by 0x8 os_ACPITableAddress: equ SystemVariables + 0x00 From e56cd294ec9b83e91960f2b627d88a4768b73813 Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 26 Feb 2024 18:59:18 -0500 Subject: [PATCH 03/13] Store I/O APIC Interrupt Source Override Entries --- docs/README.md | 11 +++++++---- src/init/acpi.asm | 24 ++++++++++++++---------- src/pure64.asm | 2 ++ src/sysvar.asm | 2 +- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/docs/README.md b/docs/README.md index 233793e..56d4374 100644 --- a/docs/README.md +++ b/docs/README.md @@ -175,18 +175,21 @@ The Pure64 information table is located at `0x0000000000005000` and ends at `0x0 0x5016 - 0x501F  For future use 0x502032-bitRAMAMOUNTAmount of system RAM in Mebibytes (MiB) 0x5022 - 0x502F  For future use -0x50308-bitIOAPIC_COUNTNumber of IO-APICs in the system -0x5031 - 0x503F  For future use +0x50308-bitIOAPIC_COUNTNumber of I/O APICs in the system +0x50318-bitIOAPIC_INTSOURCE_COUNTNumber of I/O APIC Interrupt Source Override +0x5032 - 0x503F  For future use 0x504064-bitHPETBase memory address for the High Precision Event Timer 0x5048 - 0x505F  For future use 0x506064-bitLAPICLocal APIC address -0x5068 - 0x507F64-bitIOAPICIO-APIC addresses (based on IOAPIC_COUNT) +0x5068 - 0x507F64-bitIOAPICI/O APIC addresses (based on IOAPIC_COUNT) 0x508032-bitVIDEO_BASEBase memory for video (if graphics mode set) 0x508416-bitVIDEO_XX resolution 0x508616-bitVIDEO_YY resolution 0x50888-bitVIDEO_DEPTHColor depth 0x5089 - 0x50FF  For future use -0x5100...8-bitAPIC_IDAPIC ID's for valid CPU cores (based on CORES_ACTIVE) +0x5100 - 0x51FF8-bitAPIC_IDAPIC ID's for valid CPU cores (based on CORES_ACTIVE) +0x5200 - 0x56FF  For future use +0x5700 - 0x57FF64-bitIOAPIC_INTSOURCEI/O APIC Interrupt Source Override Entries (based on IOAPIC_INTSOURCE_COUNT) A copy of the E820 System Memory Map is stored at memory address `0x0000000000006000`. Each E820 record is 32 bytes in length and the memory map is terminated by a blank record. diff --git a/src/init/acpi.asm b/src/init/acpi.asm index a17d94e..b45cdbf 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -221,20 +221,24 @@ APICinterruptsourceoverride: xor eax, eax lodsb ; Length (will be set to 10) add ebx, eax -; mov rdi, os_IOAPICIntSource -; xor ecx, ecx -; mov cl, [os_IOAPICIntSourceC] -; shl cx, 3 ; Quick multiply by 8 -; add rdi, rcx + push rdi + push rcx + mov rdi, IM_IOAPICIntSource ; Copy this data directly to the InfoMap + xor ecx, ecx + mov cl, [os_IOAPICIntSourceC] + shl cx, 3 ; Quick multiply by 8 + add rdi, rcx lodsb ; Bus Source -; stosb + stosb lodsb ; IRQ Source -; stosb + stosb lodsd ; Global System Interrupt -; stosd + stosd lodsw ; Flags - bit 1 Low(1)/High(0), Bit 3 Level(1)/Edge(0) -; stosw -; inc byte [os_IOAPICIntSourceC] + stosw + pop rcx + pop rdi + inc byte [os_IOAPICIntSourceC] jmp readAPICstructures ; Read the next structure APICx2apic: diff --git a/src/pure64.asm b/src/pure64.asm index 422e532..a1dd285 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -494,6 +494,8 @@ clearmapnext: mov di, 0x5030 mov al, [os_IOAPICCount] stosb + mov al, [os_IOAPICIntSourceC] + stosb mov di, 0x5040 mov rax, [os_HPETAddress] diff --git a/src/sysvar.asm b/src/sysvar.asm index ea34a17..98602bb 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -14,6 +14,7 @@ cfg_smpinit: db 1 ; By default SMP is enabled. Set to 0 to disable. ; Memory locations E820Map: equ 0x0000000000004000 InfoMap: equ 0x0000000000005000 +IM_IOAPICIntSource: equ 0x0000000000005700 SystemVariables: equ 0x0000000000005800 VBEModeInfoBlock: equ 0x0000000000005F00 ; 256 bytes @@ -41,7 +42,6 @@ os_IOAPICIntSourceC: equ SystemVariables + 0x182 ; Lists - Starting at offset 0x200 os_IOAPICAddress: equ SystemVariables + 0x200 ; 16 bytes each -os_IOAPICIntSource: equ SystemVariables + 0x280 ; 8 bytes each align 16 GDTR32: ; Global Descriptors Table Register From 276f7f4e20848ba729ffa12e099687d4096606f4 Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 26 Feb 2024 19:40:49 -0500 Subject: [PATCH 04/13] Save I/O APIC info to a proper memory location Also store the I/O APIC ID --- docs/README.md | 5 +++-- src/init/acpi.asm | 17 +++++++++-------- src/pure64.asm | 11 ----------- src/sysvar.asm | 6 ++---- 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/docs/README.md b/docs/README.md index 56d4374..b3a0c56 100644 --- a/docs/README.md +++ b/docs/README.md @@ -181,7 +181,7 @@ The Pure64 information table is located at `0x0000000000005000` and ends at `0x0 0x504064-bitHPETBase memory address for the High Precision Event Timer 0x5048 - 0x505F  For future use 0x506064-bitLAPICLocal APIC address -0x5068 - 0x507F64-bitIOAPICI/O APIC addresses (based on IOAPIC_COUNT) +0x5068 - 0x507F  For future use 0x508032-bitVIDEO_BASEBase memory for video (if graphics mode set) 0x508416-bitVIDEO_XX resolution 0x508616-bitVIDEO_YY resolution @@ -189,7 +189,8 @@ The Pure64 information table is located at `0x0000000000005000` and ends at `0x0 0x5089 - 0x50FF  For future use 0x5100 - 0x51FF8-bitAPIC_IDAPIC ID's for valid CPU cores (based on CORES_ACTIVE) 0x5200 - 0x56FF  For future use -0x5700 - 0x57FF64-bitIOAPIC_INTSOURCEI/O APIC Interrupt Source Override Entries (based on IOAPIC_INTSOURCE_COUNT) +0x5600 - 0x56FF16 byte entriesIOAPICI/O APIC addresses (based on IOAPIC_COUNT) +0x5700 - 0x57FF8 byte entriesIOAPIC_INTSOURCEI/O APIC Interrupt Source Override Entries (based on IOAPIC_INTSOURCE_COUNT) A copy of the E820 System Memory Map is stored at memory address `0x0000000000006000`. Each E820 record is 32 bytes in length and the memory map is terminated by a blank record. diff --git a/src/init/acpi.asm b/src/init/acpi.asm index b45cdbf..f12a5fb 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -198,21 +198,22 @@ APICioapic: xor eax, eax lodsb ; Length (will be set to 12) add ebx, eax - lodsb ; IO APIC ID - lodsb ; Reserved - xor eax, eax - lodsd ; I/O APIC Address push rdi push rcx - mov rdi, os_IOAPICAddress + mov rdi, IM_IOAPICAddress ; Copy this data directly to the InfoMap xor ecx, ecx mov cl, [os_IOAPICCount] - shl cx, 3 ; Quick multiply by 8 + shl cx, 4 ; Quick multiply by 16 add rdi, rcx pop rcx - stosd ; Store the I/O APIC Address + xor eax, eax + lodsb ; IO APIC ID + stosd + lodsb ; Reserved + lodsd ; I/O APIC Address + stosd lodsd ; Global System Interrupt Base - stosd ; Store the Global System Interrupt Base + stosd pop rdi inc byte [os_IOAPICCount] jmp readAPICstructures ; Read the next structure diff --git a/src/pure64.asm b/src/pure64.asm index a1dd285..0b34375 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -504,17 +504,6 @@ clearmapnext: mov di, 0x5060 mov rax, [os_LocalAPICAddress] stosq - xor ecx, ecx - mov cl, [os_IOAPICCount] - mov rsi, os_IOAPICAddress -nextIOAPIC: - lodsq ; I/O APIC Address - stosq - lodsq ; Global System Interrupt Base - stosq - sub cl, 1 - cmp cl, 0 - jne nextIOAPIC mov di, 0x5080 mov eax, [VBEModeInfoBlock.PhysBasePtr] ; Base address of video memory (if graphics mode is set) diff --git a/src/sysvar.asm b/src/sysvar.asm index 98602bb..f00abb9 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -14,7 +14,8 @@ cfg_smpinit: db 1 ; By default SMP is enabled. Set to 0 to disable. ; Memory locations E820Map: equ 0x0000000000004000 InfoMap: equ 0x0000000000005000 -IM_IOAPICIntSource: equ 0x0000000000005700 +IM_IOAPICAddress: equ 0x0000000000005600 ; 16 bytes per entry +IM_IOAPICIntSource: equ 0x0000000000005700 ; 8 bytes per entry SystemVariables: equ 0x0000000000005800 VBEModeInfoBlock: equ 0x0000000000005F00 ; 256 bytes @@ -40,9 +41,6 @@ os_IOAPICCount: equ SystemVariables + 0x180 BootMode: equ SystemVariables + 0x181 ; 'U' for UEFI, otherwise BIOS os_IOAPICIntSourceC: equ SystemVariables + 0x182 -; Lists - Starting at offset 0x200 -os_IOAPICAddress: equ SystemVariables + 0x200 ; 16 bytes each - align 16 GDTR32: ; Global Descriptors Table Register dw gdt32_end - gdt32 - 1 ; limit of GDT (size minus one) From 3d15b5addd12e10927b0df4e319da72e26c10423 Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 26 Feb 2024 19:54:23 -0500 Subject: [PATCH 05/13] Add support for the Local APIC Address Override --- src/init/acpi.asm | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/init/acpi.asm b/src/init/acpi.asm index f12a5fb..7e2ceb3 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -169,8 +169,8 @@ readAPICstructures: ; je APICnmi ; cmp al, 0x04 ; Local APIC NMI ; je APIClocalapicnmi -; cmp al, 0x05 ; Local APIC Address Override -; je APICaddressoverride + cmp al, 0x05 ; Local APIC Address Override + je APICaddressoverride cmp al, 0x09 ; Processor Local x2APIC je APICx2apic ; cmp al, 0x0A ; Local x2APIC NMI @@ -178,7 +178,7 @@ readAPICstructures: jmp APICignore -APICapic: +APICapic: ; Entry Type 0 xor eax, eax xor edx, edx lodsb ; Length (will be set to 8) @@ -194,7 +194,7 @@ APICapic: stosb jmp readAPICstructures ; Read the next structure -APICioapic: +APICioapic: ; Entry Type 1 xor eax, eax lodsb ; Length (will be set to 12) add ebx, eax @@ -218,7 +218,7 @@ APICioapic: inc byte [os_IOAPICCount] jmp readAPICstructures ; Read the next structure -APICinterruptsourceoverride: +APICinterruptsourceoverride: ; Entry Type 2 xor eax, eax lodsb ; Length (will be set to 10) add ebx, eax @@ -242,7 +242,14 @@ APICinterruptsourceoverride: inc byte [os_IOAPICIntSourceC] jmp readAPICstructures ; Read the next structure -APICx2apic: +APICaddressoverride: ; Entry Type 5 + lodsb ; Length (will be set to 10) + lodsw ; Reserved + lodsq ; 64-bit physical address of Local APIC + mov [os_ACPITableAddress], rax ; Overwrite the initial value from the MADT header + jmp readAPICstructures ; Read the next structure + +APICx2apic: ; Entry Type 9 xor eax, eax xor edx, edx lodsb ; Length (will be set to 16) From 2f65256d5fdc16b0fa432900fe468b0410a9a298 Mon Sep 17 00:00:00 2001 From: Ian Date: Tue, 27 Feb 2024 14:54:11 -0500 Subject: [PATCH 06/13] Cleanup --- src/init/cpu.asm | 33 ++++++++++++++++++++------------- src/init/smp.asm | 2 -- src/init/smp_ap.asm | 22 ++++++---------------- src/pure64.asm | 2 +- 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/init/cpu.asm b/src/init/cpu.asm index 6105e94..a4434ad 100644 --- a/src/init/cpu.asm +++ b/src/init/cpu.asm @@ -88,22 +88,19 @@ init_cpu: finit ; Enable AVX - mov eax, 1 ; CPUID Feature information 1 - cpuid ; Sets info in eax and ecx - bt ecx, 28 ; AVX is supported if bit 28 is set in ecx - jnc avx_not_supported ; Skip activating AVX if not supported - + mov eax, 1 ; CPUID Feature information 1 + cpuid ; Sets info in eax and ecx + bt ecx, 28 ; AVX is supported if bit 28 is set in ecx + jnc avx_not_supported ; Skip activating AVX if not supported avx_supported: - mov rax, cr4 bts rax, 18 ; Enable OSXSAVE (Bit 18) mov cr4, rax - - mov rcx, 0 ; Set load XCR Nr. 0 + mov rcx, 0 ; Set load XCR Nr. 0 xgetbv ; Load XCR0 register - bts rax, 0 ; Set X87 enable (Bit 0) - bts rax, 1 ; Set SSE enable (Bit 1) - bts rax, 2 ; Set AVX enable (Bit 2) + bts rax, 0 ; Set X87 enable (Bit 0) + bts rax, 1 ; Set SSE enable (Bit 1) + bts rax, 2 ; Set AVX enable (Bit 2) xsetbv ; Save XCR0 register avx_not_supported: @@ -154,8 +151,18 @@ avx_not_supported: ; bts eax, 16 ;bit16:Mask interrupts (0==Unmasked, 1== Masked) ; mov dword [rsi+0x370], eax - -ret + lock inc word [cpu_activated] + xor eax, eax + mov rsi, [os_LocalAPICAddress] + add rsi, 0x20 ; Add the offset for the APIC ID location + lodsd ; APIC ID is stored in bits 31:24 + shr rax, 24 ; AL now holds the CPU's APIC ID (0 - 255) + mov rdi, 0x00005700 ; The location where the cpu values are stored + add rdi, rax ; RDI points to InfoMap CPU area + APIC ID. ex 0x5701 would be APIC ID 1 + mov al, 1 + stosb + + ret ; ============================================================================= diff --git a/src/init/smp.asm b/src/init/smp.asm index cb93e34..55fe3ce 100644 --- a/src/init/smp.asm +++ b/src/init/smp.asm @@ -93,8 +93,6 @@ smp_wait2: ; Finish up noMP: - lock inc word [cpu_activated] ; BSP adds one here - xor eax, eax mov rsi, [os_LocalAPICAddress] add rsi, 0x20 ; Add the offset for the APIC ID location diff --git a/src/init/smp_ap.asm b/src/init/smp_ap.asm index 9591644..fbb109e 100644 --- a/src/init/smp_ap.asm +++ b/src/init/smp_ap.asm @@ -135,25 +135,15 @@ clearcs64_ap: lidt [IDTR64] ; load IDT register ; Enable Local APIC on AP - mov rsi, [os_LocalAPICAddress] - add rsi, 0x00f0 ; Offset to Spurious Interrupt Register - mov rdi, rsi - lodsd - or eax, 0000000100000000b - stosd +; mov rsi, [os_LocalAPICAddress] +; add rsi, 0x00f0 ; Offset to Spurious Interrupt Register +; mov rdi, rsi +; lodsd +; or eax, 0000000100000000b +; stosd call init_cpu ; Setup CPU - lock inc word [cpu_activated] - xor eax, eax - mov rsi, [os_LocalAPICAddress] - add rsi, 0x20 ; Add the offset for the APIC ID location - lodsd ; APIC ID is stored in bits 31:24 - shr rax, 24 ; AL now holds the CPU's APIC ID (0 - 255) - mov rdi, 0x00005700 ; The location where the cpu values are stored - add rdi, rax ; RDI points to infomap CPU area + APIC ID. ex F701 would be APIC ID 1 - mov al, 1 - stosb sti ; Activate interrupts for SMP jmp ap_sleep diff --git a/src/pure64.asm b/src/pure64.asm index 0b34375..f9e89d7 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -471,7 +471,7 @@ clearmapnext: add rax, 0x0000000000050400 ; stacks decrement when you "push", start at 1024 bytes in mov rsp, rax ; Pure64 leaves 0x50000-0x9FFFF free so we use that -; Build the infomap +; Build the InfoMap xor edi, edi mov di, 0x5000 mov rax, [os_ACPITableAddress] From 7f2a4513ddd5efb536f1ef04bae45d4f55447626 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 28 Feb 2024 18:27:47 -0500 Subject: [PATCH 07/13] Doc updates --- docs/README.md | 9 +++++++++ src/init/acpi.asm | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/docs/README.md b/docs/README.md index b3a0c56..ec1beff 100644 --- a/docs/README.md +++ b/docs/README.md @@ -193,6 +193,15 @@ The Pure64 information table is located at `0x0000000000005000` and ends at `0x0 0x5700 - 0x57FF8 byte entriesIOAPIC_INTSOURCEI/O APIC Interrupt Source Override Entries (based on IOAPIC_INTSOURCE_COUNT) +IOAPIC list format: + + + + + + +
OffsetVariable SizeNameDescription
0x0032-bitI/O APIC IDThe ID of an I/O APIC
0x0032-bitI/O APIC AddressThe 32-bit physical address to access this I/O APIC
0x0032-bitGlobal System Interrupt BaseThe global system interrupt number where this I/O APIC’s interrupt inputs start
0x0032-bitReservedThis value should be 0
+ A copy of the E820 System Memory Map is stored at memory address `0x0000000000006000`. Each E820 record is 32 bytes in length and the memory map is terminated by a blank record. diff --git a/src/init/acpi.asm b/src/init/acpi.asm index 7e2ceb3..d7b5702 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -171,6 +171,12 @@ readAPICstructures: ; je APIClocalapicnmi cmp al, 0x05 ; Local APIC Address Override je APICaddressoverride +; cmp al, 0x06 ; I/O SAPIC Structure +; je APICiosapic +; cmp al, 0x07 ; Local SAPIC Structure +; je APIClocalsapic +; cmp al, 0x08 ; Platform Interrupt Source Structure +; je APICplatformint cmp al, 0x09 ; Processor Local x2APIC je APICx2apic ; cmp al, 0x0A ; Local x2APIC NMI From fed4c9e362cfb50e3017f1ffa7938567c6f28c0d Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 28 Feb 2024 18:40:33 -0500 Subject: [PATCH 08/13] Add initial code for gathering PCIe data from ACPI --- src/init/acpi.asm | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/init/acpi.asm b/src/init/acpi.asm index d7b5702..b886dcb 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -112,6 +112,9 @@ nextACPITable: mov ebx, 'HPET' ; Signature for the HPET Description Table cmp eax, ebx je foundHPETTable +; mov ebx, 'MCFG' ; Signature for the PCIe Enhanced Configuration Mechanism +; cmp eax, ebx +; je foundMCFGTable cmp ecx, edx jne nextACPITable jmp init_smp_acpi_done ;noACPIAPIC @@ -124,6 +127,10 @@ foundHPETTable: call parseHPETTable jmp nextACPITable +;foundMCFGTable: +; call parseMCFGTable +; jmp nextACPITable + init_smp_acpi_done: ret @@ -309,5 +316,29 @@ parseHPETTable: ; ----------------------------------------------------------------------------- +; ----------------------------------------------------------------------------- +;parseMCFGTable: +; lodsd ; Length of MCFG in bytes +; lodsb ; Revision +; lodsb ; Checksum +; lodsd ; OEMID (First 4 bytes) +; lodsw ; OEMID (Last 2 bytes) +; lodsq ; OEM Table ID +; lodsd ; OEM Revision +; lodsd ; Creator ID +; lodsd ; Creator Revision +; lodsq ; Reserved +; +; ; Loop through each entry +; lodsq ; Base address of enhanced configuration mechanism +; lodsw ; PCI Segment Group Number +; lodsb ; Start PCI bus number decoded by this host bridge +; lodsb ; End PCI bus number decoded by this host bridge +; lodsd ; Reserved +; +; ret +; ----------------------------------------------------------------------------- + + ; ============================================================================= ; EOF From 36218eb4ce595e84c2dbbd81043bc8443fc0e9df Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 28 Feb 2024 18:42:18 -0500 Subject: [PATCH 09/13] Doc updates --- docs/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/README.md b/docs/README.md index ec1beff..32d9a3d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -202,6 +202,22 @@ IOAPIC list format:
VariableVariable SizeDescription
0x0032-bitReservedThis value should be 0
+IOAPIC_INTSOURCE list format: + + + + + + +
OffsetVariable SizeNameDescription
0x008-bitBus0
0x008-bitSourceBus-relative interrupt source
0x0032-bitGlobal System InterruptThe Global System Interrupt that this bus-relative interrupt source will signal
0x0016-bitFlagsMPS INTI flags
+ +MPS INTI flags: + + + + +
FlagsBit LengthBit OffsetDescription
Polarity2001 Active high, 11 Active low
Trigger Mode2201 Edge-triggered, 11 Level-triggered
+ A copy of the E820 System Memory Map is stored at memory address `0x0000000000006000`. Each E820 record is 32 bytes in length and the memory map is terminated by a blank record. From f75f21d5858a8f686cd0b91816e6a6cc98f4da3c Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 28 Feb 2024 21:53:41 -0500 Subject: [PATCH 10/13] Cleanup of init_cpu --- src/init/cpu.asm | 143 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 45 deletions(-) diff --git a/src/init/cpu.asm b/src/init/cpu.asm index a4434ad..27c2592 100644 --- a/src/init/cpu.asm +++ b/src/init/cpu.asm @@ -109,53 +109,44 @@ avx_not_supported: test rsi, rsi je noMP ; Skip MP init if we didn't get a valid LAPIC address - xor eax, eax ; Clear Task Priority (bits 7:4) and Priority Sub-Class (bits 3:0) - mov dword [rsi+0x80], eax ; Task Priority Register (TPR) - - mov eax, 0x01000000 ; Set bits 31-24 for all cores to be in Group 1 - mov dword [rsi+0xD0], eax ; Logical Destination Register - - xor eax, eax - not eax ; Set EAX to 0xFFFFFFFF; Bits 31-28 set for Flat Mode - mov dword [rsi+0xE0], eax ; Destination Format Register - - mov eax, dword [rsi+0xF0] ; Spurious Interrupt Vector Register - mov al, 0xF8 - bts eax, 8 ; Enable APIC (Set bit 8) - mov dword [rsi+0xF0], eax - - mov eax, dword [rsi+0x320] ; LVT Timer Register - bts eax, 16 ; Set bit 16 for mask interrupts - mov dword [rsi+0x320], eax - -; mov eax, dword [rsi+0x350] ; LVT LINT0 Register -; mov al, 0 ;Set interrupt vector (bits 7:0) -; bts eax, 8 ;Delivery Mode (111b==ExtlNT] (bits 10:8) -; bts eax, 9 -; bts eax, 10 -; bts eax, 15 ;bit15:Set trigger mode to Level (0== Edge, 1== Level) -; btr eax, 16 ;bit16:unmask interrupts (0==Unmasked, 1== Masked) -; mov dword [rsi+0x350], eax - -; mov eax, dword [rsi+0x360] ; LVT LINT1 Register -; mov al, 0 ;Set interrupt vector (bits 7:0) -; bts eax, 8 ;Delivery Mode (111b==ExtlNT] (bits 10:8) -; bts eax, 9 -; bts eax, 10 -; bts eax, 15 ;bit15:Set trigger mode to Edge (0== Edge, 1== Level) -; btr eax, 16 ;bit16:unmask interrupts (0==Unmasked, 1== Masked) -; mov dword [rsi+0x360], eax - -; mov eax, dword [rsi+0x370] ; LVT Error Register -; mov al, 0 ;Set interrupt vector (bits 7:0) -; bts eax, 16 ;bit16:Mask interrupts (0==Unmasked, 1== Masked) -; mov dword [rsi+0x370], eax + mov ecx, APIC_TPR + mov eax, 0x00000020 + call apic_write ; Disable softint delivery + + mov ecx, APIC_LVT_TMR + mov eax, 0x00010000 + call apic_write ; Disable timer interrupts + + mov ecx, APIC_LVT_PERF + mov eax, 0x00010000 + call apic_write ; Disable performance counter interrupts + +; mov eax, 0x01000000 ; Set bits 31-24 for all cores to be in Group 1 +; mov dword [rsi+0xD0], eax ; Logical Destination Register + +; xor eax, eax +; not eax ; Set EAX to 0xFFFFFFFF; Bits 31-28 set for Flat Mode +; mov dword [rsi+0xE0], eax ; Destination Format Register + + mov ecx, APIC_SPURIOUS + mov eax, 0x000001FF + call apic_write ; Enable the APIC (bit 8) and set spurious vector to 0xFF + + mov ecx, APIC_LVT_LINT0 + mov eax, 0x00008700 ; Bit 15 (1 = Level), Bits 10:8 for Ext + call apic_write ; Enable normal external interrupts + + mov ecx, APIC_LVT_LINT1 + mov eax, 0x00000400 + call apic_write ; Enable normal NMI processing + + mov ecx, APIC_LVT_ERR + mov eax, 0x00010000 + call apic_write ; Disable error interrupts lock inc word [cpu_activated] - xor eax, eax - mov rsi, [os_LocalAPICAddress] - add rsi, 0x20 ; Add the offset for the APIC ID location - lodsd ; APIC ID is stored in bits 31:24 + mov ecx, APIC_ID + call apic_read ; APIC ID is stored in bits 31:24 shr rax, 24 ; AL now holds the CPU's APIC ID (0 - 255) mov rdi, 0x00005700 ; The location where the cpu values are stored add rdi, rax ; RDI points to InfoMap CPU area + APIC ID. ex 0x5701 would be APIC ID 1 @@ -164,6 +155,68 @@ avx_not_supported: ret +; ----------------------------------------------------------------------------- +; apic_read -- Read from a register in the APIC +; IN: ECX = Register to read +; OUT: EAX = Register value +; All other registers preserved +apic_read: + push rsi + mov rsi, [os_LocalAPICAddress] + add rsi, rcx ; Add offset + lodsd + pop rsi + ret +; ----------------------------------------------------------------------------- + + +; ----------------------------------------------------------------------------- +; apic_write -- Write to a register in the APIC +; IN: ECX = Register to write +; EAX = Value to write +; OUT: All registers preserved +apic_write: + push rdi + mov rdi, [os_LocalAPICAddress] + add rdi, rcx ; Add offset + stosd + pop rdi + ret +; ----------------------------------------------------------------------------- + + +; Register list +; 0x000 - 0x010 are Reserved +APIC_ID equ 0x020 ; ID Register +APIC_VER equ 0x030 ; Version Register +; 0x040 - 0x070 are Reserved +APIC_TPR equ 0x080 ; Task Priority Register +APIC_APR equ 0x090 ; Arbitration Priority Register +APIC_PPR equ 0x0A0 ; Processor Priority Register +APIC_EOI equ 0x0B0 ; End Of Interrupt +APIC_RRD equ 0x0C0 ; Remote Read Register +APIC_LDR equ 0x0D0 ; Logical Destination Register +APIC_DFR equ 0x0E0 ; Destination Format Register +APIC_SPURIOUS equ 0x0F0 ; Spurious Interrupt Vector Register +APIC_ISR equ 0x100 ; In-Service Register (Starting Address) +APIC_TMR equ 0x180 ; Trigger Mode Register (Starting Address) +APIC_IRR equ 0x200 ; Interrupt Request Register (Starting Address) +APIC_ESR equ 0x280 ; Error Status Register +; 0x290 - 0x2E0 are Reserved +APIC_ICRL equ 0x300 ; Interrupt Command Register (low 32 bits) +APIC_ICRH equ 0x310 ; Interrupt Command Register (high 32 bits) +APIC_LVT_TMR equ 0x320 ; LVT Timer Register +APIC_LVT_TSR equ 0x330 ; LVT Thermal Sensor Register +APIC_LVT_PERF equ 0x340 ; LVT Performance Monitoring Counters Register +APIC_LVT_LINT0 equ 0x350 ; LVT LINT0 Register +APIC_LVT_LINT1 equ 0x360 ; LVT LINT1 Register +APIC_LVT_ERR equ 0x370 ; LVT Error Register +APIC_TMRINITCNT equ 0x380 ; Initial Count Register (for Timer) +APIC_TMRCURRCNT equ 0x390 ; Current Count Register (for Timer) +; 0x3A0 - 0x3D0 are Reserved +APIC_TMRDIV equ 0x3E0 ; Divide Configuration Register (for Timer) +; 0x3F0 is Reserved + ; ============================================================================= ; EOF From c95f47af710bf603d150a9640d9b80c2711697b9 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 1 Mar 2024 14:56:49 -0500 Subject: [PATCH 11/13] Get APIC ID from MSR instead of ACPI Cleanup local APIC setup code --- src/init/acpi.asm | 15 +++------------ src/init/cpu.asm | 29 +++++++++-------------------- src/pure64.asm | 10 +++++++++- 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/src/init/acpi.asm b/src/init/acpi.asm index b886dcb..5334b78 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -155,9 +155,7 @@ parseAPICTable: lodsd ; OEM Revision lodsd ; Creator ID lodsd ; Creator Revision - xor eax, eax - lodsd ; Local APIC Address - mov [os_LocalAPICAddress], rax ; Save the Address of the Local APIC + lodsd ; Local APIC Address (This should match what was pulled already via the MSR) lodsd ; Flags (1 = Dual 8259 Legacy PICs Installed) add ebx, 44 mov rdi, 0x0000000000005100 ; Valid CPU IDs @@ -176,8 +174,8 @@ readAPICstructures: ; je APICnmi ; cmp al, 0x04 ; Local APIC NMI ; je APIClocalapicnmi - cmp al, 0x05 ; Local APIC Address Override - je APICaddressoverride +; cmp al, 0x05 ; Local APIC Address Override +; je APICaddressoverride ; cmp al, 0x06 ; I/O SAPIC Structure ; je APICiosapic ; cmp al, 0x07 ; Local SAPIC Structure @@ -255,13 +253,6 @@ APICinterruptsourceoverride: ; Entry Type 2 inc byte [os_IOAPICIntSourceC] jmp readAPICstructures ; Read the next structure -APICaddressoverride: ; Entry Type 5 - lodsb ; Length (will be set to 10) - lodsw ; Reserved - lodsq ; 64-bit physical address of Local APIC - mov [os_ACPITableAddress], rax ; Overwrite the initial value from the MADT header - jmp readAPICstructures ; Read the next structure - APICx2apic: ; Entry Type 9 xor eax, eax xor edx, edx diff --git a/src/init/cpu.asm b/src/init/cpu.asm index 27c2592..7c72217 100644 --- a/src/init/cpu.asm +++ b/src/init/cpu.asm @@ -105,44 +105,33 @@ avx_supported: avx_not_supported: ; Enable and Configure Local APIC - mov rsi, [os_LocalAPICAddress] - test rsi, rsi - je noMP ; Skip MP init if we didn't get a valid LAPIC address - mov ecx, APIC_TPR mov eax, 0x00000020 call apic_write ; Disable softint delivery - mov ecx, APIC_LVT_TMR mov eax, 0x00010000 call apic_write ; Disable timer interrupts - mov ecx, APIC_LVT_PERF mov eax, 0x00010000 call apic_write ; Disable performance counter interrupts - -; mov eax, 0x01000000 ; Set bits 31-24 for all cores to be in Group 1 -; mov dword [rsi+0xD0], eax ; Logical Destination Register - -; xor eax, eax -; not eax ; Set EAX to 0xFFFFFFFF; Bits 31-28 set for Flat Mode -; mov dword [rsi+0xE0], eax ; Destination Format Register - - mov ecx, APIC_SPURIOUS - mov eax, 0x000001FF - call apic_write ; Enable the APIC (bit 8) and set spurious vector to 0xFF - + mov ecx, APIC_LDR + xor eax, eax + call apic_write ; Set Logical Destination Register + mov ecx, APIC_DFR + not eax ; Set EAX to 0xFFFFFFFF; Bits 31-28 set for Flat Mode + call apic_write ; Set Destination Format Register mov ecx, APIC_LVT_LINT0 mov eax, 0x00008700 ; Bit 15 (1 = Level), Bits 10:8 for Ext call apic_write ; Enable normal external interrupts - mov ecx, APIC_LVT_LINT1 mov eax, 0x00000400 call apic_write ; Enable normal NMI processing - mov ecx, APIC_LVT_ERR mov eax, 0x00010000 call apic_write ; Disable error interrupts + mov ecx, APIC_SPURIOUS + mov eax, 0x000001FF + call apic_write ; Enable the APIC (bit 8) and set spurious vector to 0xFF lock inc word [cpu_activated] mov ecx, APIC_ID diff --git a/src/pure64.asm b/src/pure64.asm index f9e89d7..2d6fd34 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -444,7 +444,7 @@ make_interrupt_gates: ; make gates for the other interrupts lidt [IDTR64] ; load IDT register -; Clear memory 0xf000 - 0xf7ff for the infomap (2048 bytes) +; Clear memory 0xf000 - 0xf7ff for the InfoMap (2048 bytes) xor eax, eax mov ecx, 256 mov edi, 0x0000F000 @@ -454,6 +454,14 @@ clearmapnext: cmp ecx, 0 jne clearmapnext +; Read APIC Address from MSR + mov ecx, 0x0000001B ; APIC_BASE + rdmsr ; Returns APIC in EDX:EAX + and eax, 0xFFFFF000 ; Clear lower 12 bits + shl rdx, 32 ; Shift lower 32 bits to upper 32 bits + add rax, rdx + mov [os_LocalAPICAddress], rax + call init_acpi ; Find and process the ACPI tables call init_cpu ; Configure the BSP CPU From 7cf77f0d19e2c941993d2cead5a34aa3033d1adf Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 1 Mar 2024 15:09:34 -0500 Subject: [PATCH 12/13] It is 2024 now. --- LICENSE | 2 +- docs/CREDITS.TXT | 2 +- src/boot/mbr.asm | 2 +- src/boot/multiboot.asm | 2 +- src/boot/multiboot2.asm | 2 +- src/boot/pxestart.asm | 2 +- src/boot/uefi.asm | 2 +- src/init/acpi.asm | 2 +- src/init/cpu.asm | 2 +- src/init/pic.asm | 2 +- src/init/smp.asm | 2 +- src/init/smp_ap.asm | 2 +- src/interrupt.asm | 2 +- src/pure64.asm | 2 +- src/sysvar.asm | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/LICENSE b/LICENSE index a6281eb..003b733 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Return Infinity +Copyright (c) 2024 Return Infinity Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/docs/CREDITS.TXT b/docs/CREDITS.TXT index f7fd74d..e82f2e1 100644 --- a/docs/CREDITS.TXT +++ b/docs/CREDITS.TXT @@ -1,6 +1,6 @@ =============================================================================== Pure64 -- a 64-bit loader written in Assembly for x86-64 systems -Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT =============================================================================== diff --git a/src/boot/mbr.asm b/src/boot/mbr.asm index 3d6ff0c..03e7ba1 100644 --- a/src/boot/mbr.asm +++ b/src/boot/mbr.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 MBR -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; This Master Boot Record will load Pure64 from a pre-defined location on the ; hard drive without making use of the file system. diff --git a/src/boot/multiboot.asm b/src/boot/multiboot.asm index cc796f6..33e7199 100644 --- a/src/boot/multiboot.asm +++ b/src/boot/multiboot.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 Multiboot -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; http://stackoverflow.com/questions/33488194/creating-a-simple-multiboot-kernel-loaded-with-grub2 ; https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format diff --git a/src/boot/multiboot2.asm b/src/boot/multiboot2.asm index 6656884..bee725b 100644 --- a/src/boot/multiboot2.asm +++ b/src/boot/multiboot2.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 Multiboot 2 -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; http://nongnu.askapache.com/grub/phcoder/multiboot.pdf ; ============================================================================= diff --git a/src/boot/pxestart.asm b/src/boot/pxestart.asm index dc3d030..67667ae 100644 --- a/src/boot/pxestart.asm +++ b/src/boot/pxestart.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 PXE Start -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; This is a stub file for loading Pure64 and a kernel/software package via PXE. ; diff --git a/src/boot/uefi.asm b/src/boot/uefi.asm index 9c620bc..9804d61 100644 --- a/src/boot/uefi.asm +++ b/src/boot/uefi.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; UEFI loader for Pure64 -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; Adapted from https://stackoverflow.com/questions/72947069/how-to-write-hello-world-efi-application-in-nasm ; and https://github.com/charlesap/nasm-uefi/blob/master/shoe-x64.asm diff --git a/src/init/acpi.asm b/src/init/acpi.asm index 5334b78..99de471 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; INIT ACPI ; ============================================================================= diff --git a/src/init/cpu.asm b/src/init/cpu.asm index 7c72217..7a64bd5 100644 --- a/src/init/cpu.asm +++ b/src/init/cpu.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; INIT CPU - This code is called by all activated CPU cores in the system ; ============================================================================= diff --git a/src/init/pic.asm b/src/init/pic.asm index 77ee67a..0fde33e 100644 --- a/src/init/pic.asm +++ b/src/init/pic.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; INIT PIC ; ============================================================================= diff --git a/src/init/smp.asm b/src/init/smp.asm index 55fe3ce..184f3a9 100644 --- a/src/init/smp.asm +++ b/src/init/smp.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; INIT SMP ; ============================================================================= diff --git a/src/init/smp_ap.asm b/src/init/smp_ap.asm index fbb109e..aa5b760 100644 --- a/src/init/smp_ap.asm +++ b/src/init/smp_ap.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; INIT SMP AP ; ============================================================================= diff --git a/src/interrupt.asm b/src/interrupt.asm index 43d7a6a..a715ee4 100644 --- a/src/interrupt.asm +++ b/src/interrupt.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; Interrupts ; ============================================================================= diff --git a/src/pure64.asm b/src/pure64.asm index 2d6fd34..fb0d244 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; The first stage loader is required to gather information about the system ; while the BIOS or UEFI is still available and load the Pure64 binary to diff --git a/src/sysvar.asm b/src/sysvar.asm index f00abb9..c26b655 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -1,6 +1,6 @@ ; ============================================================================= ; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems -; Copyright (C) 2008-2023 Return Infinity -- see LICENSE.TXT +; Copyright (C) 2008-2024 Return Infinity -- see LICENSE.TXT ; ; System Variables ; ============================================================================= From 3b20e5eb681f57c058a2c0160e0c449509e3a997 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 1 Mar 2024 18:12:45 -0500 Subject: [PATCH 13/13] Detect x2APIC from CPUID Standardize variable names --- src/init/acpi.asm | 54 ++++++++++++++++++++++----------------------- src/init/cpu.asm | 6 ++--- src/init/smp.asm | 28 +++++++++++------------ src/init/smp_ap.asm | 4 ++-- src/interrupt.asm | 2 +- src/pure64.asm | 39 ++++++++++++++++++-------------- src/sysvar.asm | 28 +++++++++++------------ 7 files changed, 84 insertions(+), 77 deletions(-) diff --git a/src/init/acpi.asm b/src/init/acpi.asm index 99de471..221d911 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -7,7 +7,7 @@ init_acpi: - mov al, [BootMode] + mov al, [p_BootMode] cmp al, 'U' je foundACPIfromUEFI mov esi, 0x000E0000 ; Start looking for the Root System Description Pointer Structure @@ -58,7 +58,7 @@ foundACPIv1: cmp eax, 'RSDT' ; Make sure the signature is valid jne novalidacpi ; Not the same? Bail out sub rsi, 4 - mov [os_ACPITableAddress], rsi ; Save the RSDT Table Address + mov [p_ACPITableAddress], rsi ; Save the RSDT Table Address add rsi, 4 xor eax, eax lodsd ; Length @@ -84,7 +84,7 @@ foundACPIv2: cmp eax, 'XSDT' ; Make sure the signature is valid jne novalidacpi ; Not the same? Bail out sub rsi, 4 - mov [os_ACPITableAddress], rsi ; Save the XSDT Table Address + mov [p_ACPITableAddress], rsi ; Save the XSDT Table Address add rsi, 4 xor eax, eax lodsd ; Length @@ -182,8 +182,8 @@ readAPICstructures: ; je APIClocalsapic ; cmp al, 0x08 ; Platform Interrupt Source Structure ; je APICplatformint - cmp al, 0x09 ; Processor Local x2APIC - je APICx2apic +; cmp al, 0x09 ; Processor Local x2APIC +; je APICx2apic ; cmp al, 0x0A ; Local x2APIC NMI ; je APICx2nmi @@ -200,7 +200,7 @@ APICapic: ; Entry Type 0 lodsd ; Flags (Bit 0 set if enabled/usable) bt eax, 0 ; Test to see if usable jnc readAPICstructures ; Read the next structure if CPU not usable - inc word [cpu_detected] + inc word [p_cpu_detected] xchg eax, edx ; Restore the APIC ID back to EAX stosb jmp readAPICstructures ; Read the next structure @@ -213,7 +213,7 @@ APICioapic: ; Entry Type 1 push rcx mov rdi, IM_IOAPICAddress ; Copy this data directly to the InfoMap xor ecx, ecx - mov cl, [os_IOAPICCount] + mov cl, [p_IOAPICCount] shl cx, 4 ; Quick multiply by 16 add rdi, rcx pop rcx @@ -226,7 +226,7 @@ APICioapic: ; Entry Type 1 lodsd ; Global System Interrupt Base stosd pop rdi - inc byte [os_IOAPICCount] + inc byte [p_IOAPICCount] jmp readAPICstructures ; Read the next structure APICinterruptsourceoverride: ; Entry Type 2 @@ -237,7 +237,7 @@ APICinterruptsourceoverride: ; Entry Type 2 push rcx mov rdi, IM_IOAPICIntSource ; Copy this data directly to the InfoMap xor ecx, ecx - mov cl, [os_IOAPICIntSourceC] + mov cl, [p_IOAPICIntSourceC] shl cx, 3 ; Quick multiply by 8 add rdi, rcx lodsb ; Bus Source @@ -250,25 +250,25 @@ APICinterruptsourceoverride: ; Entry Type 2 stosw pop rcx pop rdi - inc byte [os_IOAPICIntSourceC] + inc byte [p_IOAPICIntSourceC] jmp readAPICstructures ; Read the next structure -APICx2apic: ; Entry Type 9 - xor eax, eax - xor edx, edx - lodsb ; Length (will be set to 16) - add ebx, eax - lodsw ; Reserved; Must be Zero - lodsd - xchg eax, edx ; Save the x2APIC ID to EDX - lodsd ; Flags (Bit 0 set if enabled/usable) - bt eax, 0 ; Test to see if usable - jnc APICx2apicEnd ; Read the next structure if CPU not usable - xchg eax, edx ; Restore the x2APIC ID back to EAX - ; TODO - Save the ID's somewhere -APICx2apicEnd: - lodsd ; ACPI Processor UID - jmp readAPICstructures ; Read the next structure +;APICx2apic: ; Entry Type 9 +; xor eax, eax +; xor edx, edx +; lodsb ; Length (will be set to 16) +; add ebx, eax +; lodsw ; Reserved; Must be Zero +; lodsd +; xchg eax, edx ; Save the x2APIC ID to EDX +; lodsd ; Flags (Bit 0 set if enabled/usable) +; bt eax, 0 ; Test to see if usable +; jnc APICx2apicEnd ; Read the next structure if CPU not usable +; xchg eax, edx ; Restore the x2APIC ID back to EAX +; ; TODO - Save the ID's somewhere +;APICx2apicEnd: +; lodsd ; ACPI Processor UID +; jmp readAPICstructures ; Read the next structure APICignore: xor eax, eax @@ -299,7 +299,7 @@ parseHPETTable: lodsd ; Event Timer Block ID lodsd ; Base Address Settings lodsq ; Base Address Value - mov [os_HPETAddress], rax ; Save the Address of the HPET + mov [p_HPETAddress], rax ; Save the Address of the HPET lodsb ; HPET Number lodsw ; Main Counter Minimum lodsw ; Page Protection And OEM Attribute diff --git a/src/init/cpu.asm b/src/init/cpu.asm index 7a64bd5..030a359 100644 --- a/src/init/cpu.asm +++ b/src/init/cpu.asm @@ -133,7 +133,7 @@ avx_not_supported: mov eax, 0x000001FF call apic_write ; Enable the APIC (bit 8) and set spurious vector to 0xFF - lock inc word [cpu_activated] + lock inc word [p_cpu_activated] mov ecx, APIC_ID call apic_read ; APIC ID is stored in bits 31:24 shr rax, 24 ; AL now holds the CPU's APIC ID (0 - 255) @@ -151,7 +151,7 @@ avx_not_supported: ; All other registers preserved apic_read: push rsi - mov rsi, [os_LocalAPICAddress] + mov rsi, [p_LocalAPICAddress] add rsi, rcx ; Add offset lodsd pop rsi @@ -166,7 +166,7 @@ apic_read: ; OUT: All registers preserved apic_write: push rdi - mov rdi, [os_LocalAPICAddress] + mov rdi, [p_LocalAPICAddress] add rdi, rcx ; Add offset stosd pop rdi diff --git a/src/init/smp.asm b/src/init/smp.asm index 184f3a9..842a26a 100644 --- a/src/init/smp.asm +++ b/src/init/smp.asm @@ -14,7 +14,7 @@ init_smp: ; Start the AP's one by one xor eax, eax xor edx, edx - mov rsi, [os_LocalAPICAddress] + mov rsi, [p_LocalAPICAddress] mov eax, [rsi+0x20] ; Add the offset for the APIC ID location shr rax, 24 ; APIC ID is stored in bits 31:24 mov dl, al ; Store BSP APIC ID in DL @@ -22,7 +22,7 @@ init_smp: mov esi, 0x00005100 xor eax, eax xor ecx, ecx - mov cx, [cpu_detected] + mov cx, [p_cpu_detected] smp_send_INIT: cmp cx, 0 je smp_send_INIT_done @@ -32,7 +32,7 @@ smp_send_INIT: je smp_send_INIT_skipcore ; Send 'INIT' IPI to APIC ID in AL - mov rdi, [os_LocalAPICAddress] + mov rdi, [p_LocalAPICAddress] shl eax, 24 mov dword [rdi+0x310], eax ; Interrupt Command Register (ICR); bits 63-32 mov eax, 0x00004500 @@ -48,16 +48,16 @@ smp_send_INIT_skipcore: smp_send_INIT_done: - mov rax, [os_Counter_RTC] + mov rax, [p_Counter_RTC] add rax, 10 smp_wait1: - mov rbx, [os_Counter_RTC] + mov rbx, [p_Counter_RTC] cmp rax, rbx jg smp_wait1 mov esi, 0x00005100 xor ecx, ecx - mov cx, [cpu_detected] + mov cx, [p_cpu_detected] smp_send_SIPI: cmp cx, 0 je smp_send_SIPI_done @@ -67,7 +67,7 @@ smp_send_SIPI: je smp_send_SIPI_skipcore ; Send 'Startup' IPI to destination using vector 0x08 to specify entry-point is at the memory-address 0x00008000 - mov rdi, [os_LocalAPICAddress] + mov rdi, [p_LocalAPICAddress] shl eax, 24 mov dword [rdi+0x310], eax ; Interrupt Command Register (ICR); bits 63-32 mov eax, 0x00004608 ; Vector 0x08 @@ -84,32 +84,32 @@ smp_send_SIPI_skipcore: smp_send_SIPI_done: ; Let things settle (Give the AP's some time to finish) - mov rax, [os_Counter_RTC] + mov rax, [p_Counter_RTC] add rax, 20 smp_wait2: - mov rbx, [os_Counter_RTC] + mov rbx, [p_Counter_RTC] cmp rax, rbx jg smp_wait2 ; Finish up noMP: xor eax, eax - mov rsi, [os_LocalAPICAddress] + mov rsi, [p_LocalAPICAddress] add rsi, 0x20 ; Add the offset for the APIC ID location lodsd ; APIC ID is stored in bits 31:24 shr rax, 24 ; AL now holds the CPU's APIC ID (0 - 255) - mov [os_BSP], eax ; Store the BSP APIC ID + mov [p_BSP], eax ; Store the BSP APIC ID ; Calculate speed of CPU (At this point the RTC is firing at 1024Hz) cpuid xor edx, edx xor eax, eax - mov rcx, [os_Counter_RTC] + mov rcx, [p_Counter_RTC] add rcx, 10 rdtsc push rax speedtest: - mov rbx, [os_Counter_RTC] + mov rbx, [p_Counter_RTC] cmp rbx, rcx jl speedtest rdtsc @@ -118,7 +118,7 @@ speedtest: xor edx, edx mov rcx, 10240 div rcx - mov [cpu_speed], ax + mov [p_cpu_speed], ax cli ; Disable Interrupts diff --git a/src/init/smp_ap.asm b/src/init/smp_ap.asm index aa5b760..0e8f60a 100644 --- a/src/init/smp_ap.asm +++ b/src/init/smp_ap.asm @@ -123,7 +123,7 @@ clearcs64_ap: xor eax, eax ; Reset the stack. Each CPU gets a 1024-byte unique stack location - mov rsi, [os_LocalAPICAddress] ; We would call os_smp_get_id here but the stack is not ... + mov rsi, [p_LocalAPICAddress] ; We would call p_smp_get_id here but the stack is not ... add rsi, 0x20 ; ... yet defined. It is safer to find the value directly. lodsd ; Load a 32-bit value. We only want the high 8 bits shr rax, 24 ; Shift to the right and AL now holds the CPU's APIC ID @@ -135,7 +135,7 @@ clearcs64_ap: lidt [IDTR64] ; load IDT register ; Enable Local APIC on AP -; mov rsi, [os_LocalAPICAddress] +; mov rsi, [p_LocalAPICAddress] ; add rsi, 0x00f0 ; Offset to Spurious Interrupt Register ; mov rdi, rsi ; lodsd diff --git a/src/interrupt.asm b/src/interrupt.asm index a715ee4..6ad9de4 100644 --- a/src/interrupt.asm +++ b/src/interrupt.asm @@ -67,7 +67,7 @@ rtc: push rdi push rax - add qword [os_Counter_RTC], 1 ; 64-bit counter started at boot up + add qword [p_Counter_RTC], 1 ; 64-bit counter started at boot up mov al, 0x0C ; Select RTC register C out 0x70, al ; Port 0x70 is the RTC index, and 0x71 is the RTC data diff --git a/src/pure64.asm b/src/pure64.asm index fb0d244..b0f9ec7 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -263,7 +263,7 @@ clearcs64: ; Save the Boot Mode (it will be 'U' if started via UEFI) mov al, [0x8005] - mov [BootMode], al ; Save the byte as a Boot Mode flag + mov [p_BootMode], al ; Save the byte as a Boot Mode flag ; Patch Pure64 AP code ; The AP's will be told to start execution at 0x8000 mov edi, start ; We need to remove the BSP Jump call to get the AP's @@ -271,7 +271,7 @@ clearcs64: stosd stosd ; Write 8 bytes in total to overwrite the 'far jump' and marker - mov al, [BootMode] + mov al, [p_BootMode] cmp al, 'U' je uefi_memmap ; Process the E820 memory map to find all possible 2MiB pages that are free to use @@ -313,7 +313,7 @@ processfree: end820: shl ebx, 1 - mov dword [mem_amount], ebx + mov dword [p_mem_amount], ebx shr ebx, 1 jmp memmap_end @@ -323,7 +323,7 @@ uefi_memmap: ; TODO fix this as it is a terrible hack mov rcx, 32 rep stosb mov ebx, 64 - mov dword [mem_amount], ebx + mov dword [p_mem_amount], ebx memmap_end: ; Create the high memory map @@ -460,7 +460,14 @@ clearmapnext: and eax, 0xFFFFF000 ; Clear lower 12 bits shl rdx, 32 ; Shift lower 32 bits to upper 32 bits add rax, rdx - mov [os_LocalAPICAddress], rax + mov [p_LocalAPICAddress], rax + +; Check for x2APIC support + mov eax, 1 + cpuid ; x2APIC is supported if bit 21 is set + shr ecx, 21 + and cl, 1 + mov byte [p_x2APIC], cl call init_acpi ; Find and process the ACPI tables @@ -471,7 +478,7 @@ clearmapnext: call init_smp ; Init of SMP ; Reset the stack to the proper location (was set to 0x8000 previously) - mov rsi, [os_LocalAPICAddress] ; We would call os_smp_get_id here but the stack is not ... + mov rsi, [p_LocalAPICAddress] ; We would call p_smp_get_id here but the stack is not ... add rsi, 0x20 ; ... yet defined. It is safer to find the value directly. lodsd ; Load a 32-bit value. We only want the high 8 bits shr rax, 24 ; Shift to the right and AL now holds the CPU's APIC ID @@ -482,35 +489,35 @@ clearmapnext: ; Build the InfoMap xor edi, edi mov di, 0x5000 - mov rax, [os_ACPITableAddress] + mov rax, [p_ACPITableAddress] stosq - mov eax, [os_BSP] + mov eax, [p_BSP] stosd mov di, 0x5010 - mov ax, [cpu_speed] + mov ax, [p_cpu_speed] stosw - mov ax, [cpu_activated] + mov ax, [p_cpu_activated] stosw - mov ax, [cpu_detected] + mov ax, [p_cpu_detected] stosw mov di, 0x5020 - mov ax, [mem_amount] + mov ax, [p_mem_amount] stosd mov di, 0x5030 - mov al, [os_IOAPICCount] + mov al, [p_IOAPICCount] stosb - mov al, [os_IOAPICIntSourceC] + mov al, [p_IOAPICIntSourceC] stosb mov di, 0x5040 - mov rax, [os_HPETAddress] + mov rax, [p_HPETAddress] stosq mov di, 0x5060 - mov rax, [os_LocalAPICAddress] + mov rax, [p_LocalAPICAddress] stosq mov di, 0x5080 diff --git a/src/sysvar.asm b/src/sysvar.asm index c26b655..e581954 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -20,26 +20,26 @@ SystemVariables: equ 0x0000000000005800 VBEModeInfoBlock: equ 0x0000000000005F00 ; 256 bytes ; DQ - Starting at offset 0, increments by 0x8 -os_ACPITableAddress: equ SystemVariables + 0x00 -os_LocalX2APICAddress: equ SystemVariables + 0x10 -os_Counter_Timer: equ SystemVariables + 0x18 -os_Counter_RTC: equ SystemVariables + 0x20 -os_LocalAPICAddress: equ SystemVariables + 0x28 -os_HPETAddress: equ SystemVariables + 0x38 +p_ACPITableAddress: equ SystemVariables + 0x00 +p_LocalAPICAddress: equ SystemVariables + 0x10 +p_Counter_Timer: equ SystemVariables + 0x18 +p_Counter_RTC: equ SystemVariables + 0x20 +p_HPETAddress: equ SystemVariables + 0x28 ; DD - Starting at offset 0x80, increments by 4 -os_BSP: equ SystemVariables + 0x80 -mem_amount: equ SystemVariables + 0x84 ; in MiB +p_BSP: equ SystemVariables + 0x80 +p_mem_amount: equ SystemVariables + 0x84 ; in MiB ; DW - Starting at offset 0x100, increments by 2 -cpu_speed: equ SystemVariables + 0x100 -cpu_activated: equ SystemVariables + 0x102 -cpu_detected: equ SystemVariables + 0x104 +p_cpu_speed: equ SystemVariables + 0x100 +p_cpu_activated: equ SystemVariables + 0x102 +p_cpu_detected: equ SystemVariables + 0x104 ; DB - Starting at offset 0x180, increments by 1 -os_IOAPICCount: equ SystemVariables + 0x180 -BootMode: equ SystemVariables + 0x181 ; 'U' for UEFI, otherwise BIOS -os_IOAPICIntSourceC: equ SystemVariables + 0x182 +p_IOAPICCount: equ SystemVariables + 0x180 +p_BootMode: equ SystemVariables + 0x181 ; 'U' for UEFI, otherwise BIOS +p_IOAPICIntSourceC: equ SystemVariables + 0x182 +p_x2APIC: equ SystemVariables + 0x183 align 16 GDTR32: ; Global Descriptors Table Register
VariableVariable SizeDescription