From edbba9db8477005452502758a40a4d8370a4d73c Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Tue, 5 May 2026 21:09:41 -0400 Subject: [PATCH 01/11] Gather TSC values --- docs/README.md | 2 ++ src/pure64.asm | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/docs/README.md b/docs/README.md index 492ad39..2322065 100644 --- a/docs/README.md +++ b/docs/README.md @@ -200,6 +200,8 @@ The Pure64 information table is located at `0x0000000000005000` and ends at `0x0 0x504C16-bitHPET Counter MinumumMinimum Counter for the High Precision Event Timer 0x504E8-bitHPET CountersNumber of Counter in the High Precision Event Timer 0x504F  For future use +0x505064-bitT0RDTSC at Pure64 start +0x505864-bitT1RDTSC at Pure64 end 0x506064-bitLAPICLocal APIC address 0x5068 - 0x507F  For future use 0x508064-bitVIDEO_BASEBase memory for video (if graphics mode set) diff --git a/src/pure64.asm b/src/pure64.asm index 655bf0c..e8161ed 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -64,6 +64,10 @@ bootmode: %ifdef BIOS mov [p_BootDisk], bh ; Save disk from where system was booted from + rdtsc ; Read the timestamp counter into EDX:EAX + mov [0x5FFC], edx + mov [0x5FF8], eax + mov eax, 16 ; Set the correct segment registers mov ds, ax mov es, ax @@ -850,6 +854,14 @@ no_address_size: mov al, [p_HPET_Timers] stosb + mov esi, 0x5FF8 ; Address of T0 + mov di, 0x5050 + movsq + rdtsc ; Gather T1 + stosd + mov eax, edx + stosd + mov di, 0x5060 mov rax, [p_LocalAPICAddress] stosq From a19260c491e8b2213e216cacbe1d543531b0b4b9 Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Thu, 7 May 2026 21:12:01 -0400 Subject: [PATCH 02/11] Boot performance --- src/init/acpi.asm | 42 +++++++++++++++++++++++++++--------------- src/pure64.asm | 5 +++++ src/sysvar.asm | 1 + 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/init/acpi.asm b/src/init/acpi.asm index 301957d..bf6fb79 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -17,16 +17,32 @@ init_acpi: je foundACPIfromUEFI ; If so, jump - otherwise fall thru for BIOS ; Find the ACPI RSDP Structure on a BIOS system -; It's supposed to be somewhere in the first MiB of memory but some systems don't adhere to that - mov esi, 0x00000007 ; Start looking for the Root System Description Pointer Structure -searchingforACPI: - sub esi, 0x7 - lodsq ; Load a quad word from RSI and store in RAX, then increment RSI by 8 - cmp rax, rbx ; Verify the Signature +; The RSDP is potentially located in 2 places: +; 1) Within the first 1 KiB of the EBDA (Extended BIOS Data Area; a 2 byte address to the start of it is located at 0x40E) +; 2) In the BIOS ROM memory region from 0x000E0000 to 0x000FFFFF +; The signature always starts on a 16 byte boundary. +; If the system does not adhere to the standard then this will fail. + +; ; Check EBDA (first 1KB) +; mov rsi, [p_EBDA] +; mov ecx, 64 ; 0x400 / 16 = 64 iterations +;acpi_search_ebda: +; cmp qword [rsi], rbx ; Compare the Signature +; je foundACPI +; add esi, 16 +; dec ecx +; jnz acpi_search_ebda + + ; Check BIOS ROM area (0xE0000–0xFFFFF) + mov esi, 0xE0000 ; Start of BIOS ROM + mov ecx, 8192 ; 0x20000 / 16 = 8192 iterations +acpi_search_rom: + cmp qword [rsi], rbx ; Compare the Signature je foundACPI - cmp esi, 0xFFFFFFF8 ; Keep looking until we get here - ja noACPI ; ACPI tables couldn't be found, fail - jmp searchingforACPI + add esi, 16 + dec ecx + jnz acpi_search_rom + jmp noACPI ; ACPI tables couldn't be found, fail ; Find the ACPI RSDP Structure on a UEFI system foundACPIfromUEFI: @@ -41,7 +57,6 @@ foundACPI: ; Found a Pointer Structure, verify the checksum push rbx xor ebx, ebx mov ecx, 20 ; As per the spec only the first 20 bytes matter - sub esi, 8 ; Bytes 0 thru 19 must sum to zero nextchecksum: lodsb ; Get a byte add bl, al ; Add it to the running total @@ -51,11 +66,8 @@ nextchecksum: pop rbx pop rsi ; Restore the RSDP location cmp al, 0 ; Verify the checksum is zero - jne searchingforACPI ; Checksum didn't check out? Keep looking for a valid record - - lodsb ; Checksum - lodsd ; OEMID (First 4 bytes) - lodsw ; OEMID (Last 2 bytes) + jne noACPI ; Checksum invalid? Bail out + add esi, 15 ; Skip to the Revision byte lodsb ; Revision (0 is v1.0, 1 is v2.0, 2 is v3.0, etc) cmp al, 0 je foundACPIv1 ; If AL is 0 then the system is using ACPI v1.0 diff --git a/src/pure64.asm b/src/pure64.asm index e8161ed..879a2f3 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -215,6 +215,11 @@ start64: mov ax, 0x03 ; Set flags for legacy ports (in case of no ACPI data) mov [p_IAPC_BOOT_ARCH], ax + ; Save EBDA segment from BDA (BIOS Data Area) + movzx esi, word [0x040E] ; EBDA segment + shl esi, 4 ; Convert to proper address + mov [p_EBDA], rsi + ; Mask all PIC interrupts mov al, 0xFF out 0x21, al diff --git a/src/sysvar.asm b/src/sysvar.asm index af8779a..d0c7a59 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -41,6 +41,7 @@ p_ACPITableAddress: equ SystemVariables + 0x00 p_LocalAPICAddress: equ SystemVariables + 0x10 p_HPET_Address: equ SystemVariables + 0x28 sys_timer: equ SystemVariables + 0x30 +p_EBDA: equ SystemVariables + 0x38 ; DD - Starting at offset 0x80, increments by 4 p_BSP: equ SystemVariables + 0x80 From 1984eac45a99f1adf40f3cbcf215a59a093139dd Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Fri, 8 May 2026 16:59:13 -0400 Subject: [PATCH 03/11] Tidy --- src/init/acpi.asm | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/init/acpi.asm b/src/init/acpi.asm index bf6fb79..5492e64 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -131,17 +131,13 @@ nextACPITable: pop rsi ; Pop an Entry address from the stack lodsd add ecx, 1 - mov ebx, 'APIC' ; Signature for the Multiple APIC Description Table - cmp eax, ebx + cmp eax, 'APIC' ; Signature for the Multiple APIC Description Table je foundAPICTable - mov ebx, 'HPET' ; Signature for the HPET Description Table - cmp eax, ebx + cmp eax, 'HPET' ; Signature for the HPET Description Table je foundHPETTable - mov ebx, 'MCFG' ; Signature for the PCIe Enhanced Configuration Mechanism - cmp eax, ebx + cmp eax, 'MCFG' ; Signature for the PCIe Enhanced Configuration Mechanism je foundMCFGTable - mov ebx, 'FACP' ; Signature for the Fixed ACPI Description Table - cmp eax, ebx + cmp eax, 'FACP' ; Signature for the Fixed ACPI Description Table je foundFADTTable jmp nextACPITable From c1f7f0413f1224cb5982aef23119b19744425ee6 Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Fri, 8 May 2026 17:17:06 -0400 Subject: [PATCH 04/11] Simplify HPET ACPI parsing --- src/init/acpi.asm | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/init/acpi.asm b/src/init/acpi.asm index 5492e64..198b102 100644 --- a/src/init/acpi.asm +++ b/src/init/acpi.asm @@ -328,28 +328,38 @@ parseAPICTable_done: ; ----------------------------------------------------------------------------- ; High Precision Event Timer (HPET) +; +; ACPI Memory Layout +; 4 byte - Signature +; 4 byte - Length of HPET in bytes +; 1 byte - Revision +; 1 byte - Checksum +; 6 byte - OEMID +; 8 byte - OEM Table ID +; 4 byte - OEM Revision +; 4 byte - Creator ID +; 4 byte - Creator Revision +; 1 byte - Hardware Revision ID +; 1 byte - # of Comparators (5:0), COUNT_SIZE_CAP (6), Legacy IRQ (7) +; 2 byte - PCI Vendor ID +; 1 byte - Address Space ID +; 1 byte - Register bit width +; 1 byte - Register bit offset +; 1 byte - Reserved +; 8 byte - Base Address Value +; 1 byte - HPET Number +; 2 byte - Main Counter Minimum +; 1 byte - Page Protection +; ; http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf parseHPETTable: - lodsd ; Length of HPET 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 - - lodsb ; Hardware Revision ID - lodsb ; # of Comparators (5:0), COUNT_SIZE_CAP (6), Legacy IRQ (7) - lodsw ; PCI Vendor ID - lodsd ; Generic Address Structure - lodsq ; Base Address Value + ; At this point RSI points to the Length of HPET in bytes + mov ebx, [rsi] ; Should be 0x38 + mov rax, [rsi + 40] ; Base Address Value mov [p_HPET_Address], rax ; Save the Address of the HPET - lodsb ; HPET Number - lodsw ; Main Counter Minimum + mov ax, [rsi + 49] ; Main Counter Minimum mov [p_HPET_CounterMin], ax ; Save the Counter Minimum - lodsb ; Page Protection And OEM Attribute + add rsi, rbx ; Add the table length to RSI ret ; ----------------------------------------------------------------------------- From a8e13b20e65c64a7249d7c871c6e67da4233f3d9 Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Sat, 9 May 2026 13:28:21 -0400 Subject: [PATCH 05/11] Update smp.asm --- src/init/smp.asm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/init/smp.asm b/src/init/smp.asm index 1903817..0dd40cf 100644 --- a/src/init/smp.asm +++ b/src/init/smp.asm @@ -60,8 +60,8 @@ smp_send_INIT_skipcore: smp_send_INIT_done: - ; Wait 500 microseconds - mov eax, 500 + ; Wait + mov eax, 500 ; 500 microseconds (0.5ms) call timer_delay mov esi, IM_DetectedCoreIDs @@ -97,9 +97,9 @@ smp_send_SIPI_verify: smp_send_SIPI_x2APIC: ; Send 'Startup' IPI to destination using vector 0x08 to specify entry-point is at the memory-address 0x00008000 push rcx - mov ecx, APIC_ICR ; Interrupt Command Register (ICR); bits 63-0 + mov ecx, APIC_ICR ; Interrupt Command Register (ICR); bits 63-0 shl rax, 32 - mov ax, 0x4608 ; Vector 0x08 + mov ax, 0x4608 ; Vector 0x08 call apic_write pop rcx @@ -111,8 +111,8 @@ smp_send_SIPI_skipcore: smp_send_SIPI_done: - ; Wait 10000 microseconds for the AP's to finish - mov eax, 10000 + ; Wait for the AP's to finish + mov eax, 10000 ; 10000 microseconds (10ms) call timer_delay noMP: @@ -123,7 +123,7 @@ noMP: xor eax, eax rdtsc push rax - mov rax, 1024 + mov rax, 1024 ; 1024 microseconds (1ms) call timer_delay rdtsc pop rdx From e05f19f474d11fc073eee1683cecab5466fda4b7 Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Sat, 9 May 2026 17:33:40 -0400 Subject: [PATCH 06/11] Tidy --- src/init/smp.asm | 30 +++++++++++++++--------------- src/init/timer.asm | 27 ++++++++++++++------------- src/pure64.asm | 13 +++++-------- src/sysvar.asm | 3 ++- 4 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/init/smp.asm b/src/init/smp.asm index 0dd40cf..173180a 100644 --- a/src/init/smp.asm +++ b/src/init/smp.asm @@ -117,21 +117,21 @@ smp_send_SIPI_done: noMP: - ; Calculate base speed of CPU - cpuid - xor edx, edx - xor eax, eax - rdtsc - push rax - mov rax, 1024 ; 1024 microseconds (1ms) - call timer_delay - rdtsc - pop rdx - sub rax, rdx - xor edx, edx - mov rcx, 1024 - div rcx - mov [p_cpu_speed], ax +; ; Calculate base speed of CPU +; cpuid +; xor edx, edx +; xor eax, eax +; rdtsc +; push rax +; mov rax, 1024 ; 1024 microseconds (1ms) +; call timer_delay +; rdtsc +; pop rdx +; sub rax, rdx +; xor edx, edx +; mov rcx, 1024 +; div rcx +; mov [p_cpu_speed], ax ret diff --git a/src/init/timer.asm b/src/init/timer.asm index 0b87585..5b4e28d 100644 --- a/src/init/timer.asm +++ b/src/init/timer.asm @@ -66,9 +66,15 @@ init_timer_hpet: mov rbx, rax ; Move Counter Clock Period to RBX xor rdx, rdx mov rax, 1000000000000000 ; femotoseconds per second - div rbx ; RDX:RAX / RBX + div rbx ; RDX:RAX / RBX = frequency in Hz mov [p_HPET_Frequency], eax ; Save the HPET frequency + ; Precompute cycles per microsecond (freq_Hz / 1,000,000) + xor rdx, rdx + mov ecx, 1000000 + div rcx + mov [p_HPET_CyclesPerUs], rax + ; Disable interrupts on all timers xor ebx, ebx mov bl, [p_HPET_Timers] @@ -140,24 +146,18 @@ hpet_delay: push rax mov rbx, rax ; Save delay to RBX - xor edx, edx - xor ecx, ecx - call hpet_read ; Get HPET General Capabilities and ID Register - shr rax, 32 - mov rcx, rax ; RCX = RAX >> 32 (timer period in femtoseconds) - mov rax, 1000000000 - div rcx ; Divide 1000000000 (RDX:RAX) / RCX (converting from period in femtoseconds to frequency in MHz) - mul rbx ; RAX *= RBX, should get number of HPET cycles to wait, save result in RBX + mov rax, [p_HPET_CyclesPerUs] ; Use precomputed cycles per microsecond + mul rbx ; RAX = cycles to wait mov rbx, rax mov ecx, HPET_MAIN_COUNTER call hpet_read ; Get HPET counter in RAX - add rbx, rax ; RBX += RAX Until when to wait + add rbx, rax ; RBX = target counter value hpet_delay_loop: ; Stay in this loop until the HPET timer reaches the expected value + pause mov ecx, HPET_MAIN_COUNTER call hpet_read ; Get HPET counter in RAX - cmp rax, rbx ; If RAX >= RBX then jump to end, otherwise jump to loop - jae hpet_delay_end - jmp hpet_delay_loop + cmp rax, rbx + jb hpet_delay_loop hpet_delay_end: pop rax @@ -291,6 +291,7 @@ kvm_delay: call kvm_get_usec add rbx, rax ; Add elapsed time kvm_delay_wait: + pause call kvm_get_usec cmp rax, rbx jb kvm_delay_wait diff --git a/src/pure64.asm b/src/pure64.asm index 879a2f3..44fd2d8 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -149,8 +149,7 @@ pdpte_low_32: pop eax add eax, 0x00001000 ; 4KiB later (512 records x 8 bytes) dec ecx - cmp ecx, 0 - jne pdpte_low_32 + jnz pdpte_low_32 ; Create the temporary low Page-Directory Entries (PDE). ; A single PDE can map 2MiB of RAM @@ -693,8 +692,7 @@ create_pdpe_high: stosq add rax, 0x00001000 ; 4K later (512 records x 8 bytes) dec ecx - cmp ecx, 0 - jne create_pdpe_high + jnz create_pdpe_high ; Create the High Page-Directory Entries (PDE). ; A single PDE can map 2MiB of RAM @@ -714,15 +712,14 @@ pde_next_range: sub rcx, 2 ; Subtract 2 MiB from the length skipfirst4mb: shr ecx, 1 ; Quick divide by 2 for 2 MB pages + cmp ecx, 0 + je pde_next_range add rax, 0x00000083 ; Bits 0 (P), 1 (R/W), and 7 (PS) set pde_high: ; Create a 2MiB page stosq add rax, 0x00200000 ; Increment by 2MiB - cmp ecx, 0 - je pde_next_range dec ecx - cmp ecx, 0 - jne pde_high + jnz pde_high jmp pde_next_range pde_end: diff --git a/src/sysvar.asm b/src/sysvar.asm index d0c7a59..6d17d06 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -24,7 +24,7 @@ msg_kernel: db 13, 10, 'kernel start', 13, 10, 0 %endif ;CONFIG -cfg_smpinit: db 1 ; By default SMP is enabled. Set to 0 to disable. +cfg_smpinit: db 0 ; By default SMP is enabled. Set to 0 to disable. ; Memory locations InfoMap: equ 0x0000000000005000 @@ -38,6 +38,7 @@ VBEModeInfoBlock: equ 0x0000000000005F00 ; 256 bytes ; DQ - Starting at offset 0, increments by 0x8 p_ACPITableAddress: equ SystemVariables + 0x00 +p_HPET_CyclesPerUs: equ SystemVariables + 0x08 ; Precomputed HPET cycles per microsecond p_LocalAPICAddress: equ SystemVariables + 0x10 p_HPET_Address: equ SystemVariables + 0x28 sys_timer: equ SystemVariables + 0x30 From f0bcf3072d5005101a8c86a4a83172b70b6a85fe Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Sat, 9 May 2026 19:06:35 -0400 Subject: [PATCH 07/11] Remove memory clearing --- src/pure64.asm | 53 +++++++++++++------------------------------------- 1 file changed, 13 insertions(+), 40 deletions(-) diff --git a/src/pure64.asm b/src/pure64.asm index 44fd2d8..ed446f6 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -117,11 +117,6 @@ bootmode: stosw ; BitsPerPixel %endif - ; Clear memory for the Page Descriptor Entries (0x10000 - 0x5FFFF) - mov edi, 0x00210000 - mov ecx, 81920 - rep stosd ; Write 320KiB - ; Create the temporary Page Map Level 4 Entries (PML4E) ; PML4 is stored at 0x0000000000202000, create the first entry there ; A single PML4 entry can map 512GiB with 2MiB pages @@ -203,11 +198,6 @@ BITS 64 start64: mov esp, 0x8000 ; Set a known free location for the stack - mov edi, 0x5000 ; Clear the info map and system variable memory - xor eax, eax - mov ecx, 960 ; 3840 bytes (Range is 0x5000 - 0x5EFF) - rep stosd ; Don't overwrite the UEFI/BIOS data at 0x5F00 - mov [p_BootMode], bl mov [p_BootDisk], bh @@ -299,17 +289,6 @@ boot_uefi: msg_boot_done: %endif -; Clear out the first 20KiB of memory. This will store the 64-bit IDT, GDT, PML4, PDP Low, and PDP High - mov ecx, 5120 - xor eax, eax - mov edi, eax - rep stosd - -; Clear memory for the Page Descriptor Entries (0x10000 - 0x5FFFF) - mov edi, 0x00010000 - mov ecx, 81920 - rep stosd ; Write 320KiB - ; Copy the GDT to its final location in memory mov esi, gdt64 mov edi, 0x00001000 ; GDT address @@ -384,7 +363,7 @@ pml4_low_1GB: dec ecx jnz pml4_low_1GB - mov ecx, 8191 ; number of PDPE's to make.. each PDPE maps 1GiB of physical memory + mov ecx, 7 ; number of PDPE's to make.. each PDPE maps 1GiB of physical memory mov edi, 0x00010000 ; location of low PDPE mov eax, 0x00000083 ; Bits 0 (P), 1 (R/W), 7 (PS) pdpte_low_1GB: ; Create a 1GiB page @@ -443,41 +422,33 @@ clearcs64: ; Build the IDT xor edi, edi ; create the 64-bit IDT (at linear address 0x0000000000000000) + ; exception_gate and interrupt_gate are within the Pure64 binary (0x8000-0x97FF), + ; so bits 31:16 and 63:32 of their addresses are always 0. mov ecx, 32 make_exception_gates: ; make gates for exception handlers mov eax, exception_gate - push rax ; save the exception gate to the stack for later use stosw ; store the low word (15:0) of the address mov ax, SYS64_CODE_SEL stosw ; store the segment selector mov ax, 0x8E00 stosw ; store exception gate marker - pop rax ; get the exception gate back - shr rax, 16 - stosw ; store the high word (31:16) of the address - shr rax, 16 - stosd ; store the extra high dword (63:32) of the address. xor eax, eax - stosd ; reserved + stosw ; store the high word (31:16) of the address (always 0) + stosq ; store bits 63:32 of address + reserved (always 0) dec ecx jnz make_exception_gates mov ecx, 256-32 make_interrupt_gates: ; make gates for the other interrupts mov eax, interrupt_gate - push rax ; save the interrupt gate to the stack for later use stosw ; store the low word (15:0) of the address mov ax, SYS64_CODE_SEL stosw ; store the segment selector mov ax, 0x8F00 stosw ; store interrupt gate marker - pop rax ; get the interrupt gate back - shr rax, 16 - stosw ; store the high word (31:16) of the address - shr rax, 16 - stosd ; store the extra high dword (63:32) of the address. xor eax, eax - stosd ; reserved + stosw ; store the high word (31:16) of the address (always 0) + stosq ; store bits 63:32 of address + reserved (always 0) dec ecx jnz make_interrupt_gates @@ -859,10 +830,6 @@ no_address_size: mov esi, 0x5FF8 ; Address of T0 mov di, 0x5050 movsq - rdtsc ; Gather T1 - stosd - mov eax, edx - stosd mov di, 0x5060 mov rax, [p_LocalAPICAddress] @@ -972,6 +939,12 @@ lfb_wc_end: call read_floppy ; Then load whole floppy at memory %endif + mov edi, 0x5058 + rdtsc ; Gather T1 + shr rdx, 32 ; Shift high bits to low + or rax, rdx + stosq + ; Clear all registers (skip the stack pointer) clear_regs: xor eax, eax ; These 32-bit calls also clear the upper bits of the 64-bit registers From a8c80701a22198ae14b47fe3102eabcc3678e546 Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Sat, 9 May 2026 19:06:58 -0400 Subject: [PATCH 08/11] Restore default --- src/sysvar.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sysvar.asm b/src/sysvar.asm index 6d17d06..eb46fa2 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -24,7 +24,7 @@ msg_kernel: db 13, 10, 'kernel start', 13, 10, 0 %endif ;CONFIG -cfg_smpinit: db 0 ; By default SMP is enabled. Set to 0 to disable. +cfg_smpinit: db 1 ; By default SMP is enabled. Set to 0 to disable. ; Memory locations InfoMap: equ 0x0000000000005000 From ddd6cf738ec1780869bf64d44adc02df32d5b851 Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Sun, 10 May 2026 11:14:42 -0400 Subject: [PATCH 09/11] Remove CPU speed detection Tweak SMP startup --- docs/README.md | 2 +- src/init/smp.asm | 28 +++++++--------------------- src/pure64.asm | 4 +--- src/sysvar.asm | 1 - 4 files changed, 9 insertions(+), 26 deletions(-) diff --git a/docs/README.md b/docs/README.md index 2322065..15413d8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -183,7 +183,7 @@ The Pure64 information table is located at `0x0000000000005000` and ends at `0x0 Memory AddressVariable SizeNameDescription 0x500064-bitACPIAddress of the ACPI tables 0x500832-bitCPU_BSP_IDAPIC ID of the BSP -0x501016-bitCPU_SPEEDSpeed of the CPUs in MegaHertz (MHz) +0x500C - 0x5011  For future use 0x501216-bitCPU_CORES_ACTIVEThe number of CPU cores that were activated in the system 0x501416-bitCPU_CORES_DETECTThe number of CPU cores that were detected in the system 0x50168-bitCPU_MEM_PHYSICALThe number of bits that are valid for a physical address diff --git a/src/init/smp.asm b/src/init/smp.asm index 173180a..f133d6e 100644 --- a/src/init/smp.asm +++ b/src/init/smp.asm @@ -9,13 +9,16 @@ init_smp: ; Check if we want the AP's to be enabled.. if not then skip to end cmp byte [cfg_smpinit], 1 ; Check if SMP should be enabled - jne noMP ; If not then skip SMP init + jne init_smp_done ; If not then skip SMP init + ; Check if multiple CPUs were detected via the ACPI tables + xor ecx, ecx + mov cx, [p_cpu_detected] + cmp cx, 1 + je init_smp_done ; Only 1 CPU detected, skip SMP init mov edx, [p_BSP] ; Get the BSP APIC ID mov esi, IM_DetectedCoreIDs ; List of 32-bit APIC IDs xor eax, eax - xor ecx, ecx - mov cx, [p_cpu_detected] smp_send_INIT: cmp cx, 0 je smp_send_INIT_done @@ -115,24 +118,7 @@ smp_send_SIPI_done: mov eax, 10000 ; 10000 microseconds (10ms) call timer_delay -noMP: - -; ; Calculate base speed of CPU -; cpuid -; xor edx, edx -; xor eax, eax -; rdtsc -; push rax -; mov rax, 1024 ; 1024 microseconds (1ms) -; call timer_delay -; rdtsc -; pop rdx -; sub rax, rdx -; xor edx, edx -; mov rcx, 1024 -; div rcx -; mov [p_cpu_speed], ax - +init_smp_done: ret diff --git a/src/pure64.asm b/src/pure64.asm index ed446f6..1aa99d9 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -784,9 +784,7 @@ pde_end: mov eax, [p_BSP] stosd - mov di, 0x5010 - mov ax, [p_cpu_speed] - stosw + mov di, 0x5012 mov ax, [p_cpu_activated] stosw mov ax, [p_cpu_detected] diff --git a/src/sysvar.asm b/src/sysvar.asm index eb46fa2..759aba3 100644 --- a/src/sysvar.asm +++ b/src/sysvar.asm @@ -50,7 +50,6 @@ p_mem_amount: equ SystemVariables + 0x84 ; in MiB p_HPET_Frequency: equ SystemVariables + 0x88 ; DW - Starting at offset 0x100, increments by 2 -p_cpu_speed: equ SystemVariables + 0x100 p_cpu_activated: equ SystemVariables + 0x102 p_cpu_detected: equ SystemVariables + 0x104 p_PCIECount: equ SystemVariables + 0x106 From 8603c0654c4fe547c0e5c68b9b7f0b12be187d5d Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Sun, 10 May 2026 16:06:13 -0400 Subject: [PATCH 10/11] Fix comment alignment --- src/init/smp.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init/smp.asm b/src/init/smp.asm index f133d6e..beb2873 100644 --- a/src/init/smp.asm +++ b/src/init/smp.asm @@ -115,7 +115,7 @@ smp_send_SIPI_skipcore: smp_send_SIPI_done: ; Wait for the AP's to finish - mov eax, 10000 ; 10000 microseconds (10ms) + mov eax, 10000 ; 10000 microseconds (10ms) call timer_delay init_smp_done: From 1b2e0d064704aecf048c19fb44253e74927308fa Mon Sep 17 00:00:00 2001 From: Ian Seyler Date: Sun, 10 May 2026 16:25:45 -0400 Subject: [PATCH 11/11] Cleanup --- src/boot/bios-pxe.asm | 2 +- src/boot/uefi.asm | 6 +++++- src/init/serial.asm | 4 ++-- src/init/timer.asm | 2 +- src/interrupt.asm | 22 ---------------------- src/pure64.asm | 4 ++-- 6 files changed, 11 insertions(+), 29 deletions(-) diff --git a/src/boot/bios-pxe.asm b/src/boot/bios-pxe.asm index f695018..184e5b9 100644 --- a/src/boot/bios-pxe.asm +++ b/src/boot/bios-pxe.asm @@ -121,7 +121,7 @@ check_A20: cmp ax, 0x004F ; Return value in AX should equal 0x004F if command supported and successful jne halt - cmp byte [VBEModeInfoBlock.BitsPerPixel], 24 ; Make sure this matches the number of bits for the mode! + cmp byte [VBEModeInfoBlock.BitsPerPixel], 32 ; Make sure this matches the number of bits for the mode! jne halt ; If set bit mode was unsuccessful then bail out or bx, 0x4000 ; Use linear/flat frame buffer model (set bit 14) mov ax, 0x4F02 ; SET SuperVGA VIDEO MODE - http://www.ctyme.com/intr/rb-0275.htm diff --git a/src/boot/uefi.asm b/src/boot/uefi.asm index 9588654..877eecf 100644 --- a/src/boot/uefi.asm +++ b/src/boot/uefi.asm @@ -139,7 +139,7 @@ EntryPoint: ; Find the address of the ACPI data from the UEFI configuration table mov rax, [EFI_SYSTEM_TABLE] mov rcx, [rax + EFI_SYSTEM_TABLE_NUMBEROFENTRIES] - shl rcx, 3 ; Quick multiply by 4 + shl rcx, 3 ; Quick multiply by 8 mov rsi, [CONFIG] nextentry: dec rcx @@ -367,6 +367,10 @@ get_memmap: ; Stop interrupts cli + rdtsc ; Read the timestamp counter into EDX:EAX + mov [0x5FFC], edx + mov [0x5FF8], eax + ; Copy Pure64 to the correct memory address mov rsi, PAYLOAD mov rdi, 0x8000 diff --git a/src/init/serial.asm b/src/init/serial.asm index b784e2a..c4c674d 100644 --- a/src/init/serial.asm +++ b/src/init/serial.asm @@ -14,7 +14,7 @@ init_serial: ; Enable divisor register for setting baud rate mov dx, COM_PORT_LINE_CONTROL - mov dl, 0x80 ; DLB (7 set) + mov al, 0x80 ; DLB (7 set) out dx, al ; Send the divisor (baud rate will be 115200 / divisor) @@ -27,7 +27,7 @@ init_serial: ; Disable divisor register and set values mov dx, COM_PORT_LINE_CONTROL - mov al, 00000111b ; 8 data bits (0-1 set), one stop bit (2 set), no parity (3-5 clear), DLB (7 clear) + mov al, 00000011b ; 8 data bits (0-1 set), one stop bit (2 clear), no parity (3-5 clear), DLB (7 clear) out dx, al ; Disable modem control diff --git a/src/init/timer.asm b/src/init/timer.asm index 5b4e28d..e925abd 100644 --- a/src/init/timer.asm +++ b/src/init/timer.asm @@ -65,7 +65,7 @@ init_timer_hpet: ; Calculate the HPET frequency mov rbx, rax ; Move Counter Clock Period to RBX xor rdx, rdx - mov rax, 1000000000000000 ; femotoseconds per second + mov rax, 1000000000000000 ; femtoseconds per second div rbx ; RDX:RAX / RBX = frequency in Hz mov [p_HPET_Frequency], eax ; Save the HPET frequency diff --git a/src/interrupt.asm b/src/interrupt.asm index 0897f80..dda8092 100644 --- a/src/interrupt.asm +++ b/src/interrupt.asm @@ -159,27 +159,5 @@ exception_gate_main_hang: ; ----------------------------------------------------------------------------- -; ----------------------------------------------------------------------------- -; create_gate -; rax = address of handler -; rdi = gate # to configure -create_gate: - push rdi - push rax - - shl rdi, 4 ; quickly multiply rdi by 16 - stosw ; store the low word (15:0) - shr rax, 16 - add rdi, 4 ; skip the gate marker - stosw ; store the high word (31:16) - shr rax, 16 - stosd ; store the high dword (63:32) - - pop rax - pop rdi - ret -; ----------------------------------------------------------------------------- - - ; ============================================================================= ; EOF diff --git a/src/pure64.asm b/src/pure64.asm index 1aa99d9..1080b02 100644 --- a/src/pure64.asm +++ b/src/pure64.asm @@ -938,8 +938,8 @@ lfb_wc_end: %endif mov edi, 0x5058 - rdtsc ; Gather T1 - shr rdx, 32 ; Shift high bits to low + rdtsc ; Gather T1 to EDX:EAX + shl rdx, 32 ; Shift low bits to high or rax, rdx stosq