diff --git a/docs/README.md b/docs/README.md
index 492ad39..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 Address | Variable Size | Name | Description |
| 0x5000 | 64-bit | ACPI | Address of the ACPI tables |
| 0x5008 | 32-bit | CPU_BSP_ID | APIC ID of the BSP |
-| 0x5010 | 16-bit | CPU_SPEED | Speed of the CPUs in MegaHertz (MHz) |
+| 0x500C - 0x5011 | | | For future use |
| 0x5012 | 16-bit | CPU_CORES_ACTIVE | The number of CPU cores that were activated in the system |
| 0x5014 | 16-bit | CPU_CORES_DETECT | The number of CPU cores that were detected in the system |
| 0x5016 | 8-bit | CPU_MEM_PHYSICAL | The number of bits that are valid for a physical address |
@@ -200,6 +200,8 @@ The Pure64 information table is located at `0x0000000000005000` and ends at `0x0
| 0x504C | 16-bit | HPET Counter Minumum | Minimum Counter for the High Precision Event Timer |
| 0x504E | 8-bit | HPET Counters | Number of Counter in the High Precision Event Timer |
| 0x504F | | | For future use |
+| 0x5050 | 64-bit | T0 | RDTSC at Pure64 start |
+| 0x5058 | 64-bit | T1 | RDTSC at Pure64 end |
| 0x5060 | 64-bit | LAPIC | Local APIC address |
| 0x5068 - 0x507F | | | For future use |
| 0x5080 | 64-bit | VIDEO_BASE | Base memory for video (if graphics mode set) |
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/acpi.asm b/src/init/acpi.asm
index 301957d..198b102 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
@@ -119,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
@@ -320,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
; -----------------------------------------------------------------------------
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/smp.asm b/src/init/smp.asm
index 1903817..beb2873 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
@@ -60,8 +63,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 +100,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,28 +114,11 @@ smp_send_SIPI_skipcore:
smp_send_SIPI_done:
- ; Wait 10000 microseconds for the AP's to finish
- mov eax, 10000
- call timer_delay
-
-noMP:
-
- ; Calculate base speed of CPU
- cpuid
- xor edx, edx
- xor eax, eax
- rdtsc
- push rax
- mov rax, 1024
+ ; Wait for the AP's to finish
+ mov eax, 10000 ; 10000 microseconds (10ms)
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/init/timer.asm b/src/init/timer.asm
index 0b87585..e925abd 100644
--- a/src/init/timer.asm
+++ b/src/init/timer.asm
@@ -65,10 +65,16 @@ 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
- div rbx ; RDX:RAX / RBX
+ mov rax, 1000000000000000 ; femtoseconds per second
+ 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/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 655bf0c..1080b02 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
@@ -113,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
@@ -145,8 +144,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
@@ -200,17 +198,17 @@ 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
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
@@ -291,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
@@ -376,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
@@ -435,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
@@ -684,8 +663,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
@@ -705,15 +683,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:
@@ -807,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]
@@ -850,6 +825,10 @@ no_address_size:
mov al, [p_HPET_Timers]
stosb
+ mov esi, 0x5FF8 ; Address of T0
+ mov di, 0x5050
+ movsq
+
mov di, 0x5060
mov rax, [p_LocalAPICAddress]
stosq
@@ -958,6 +937,12 @@ lfb_wc_end:
call read_floppy ; Then load whole floppy at memory
%endif
+ mov edi, 0x5058
+ rdtsc ; Gather T1 to EDX:EAX
+ shl rdx, 32 ; Shift low bits to high
+ 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
diff --git a/src/sysvar.asm b/src/sysvar.asm
index af8779a..759aba3 100644
--- a/src/sysvar.asm
+++ b/src/sysvar.asm
@@ -38,9 +38,11 @@ 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
+p_EBDA: equ SystemVariables + 0x38
; DD - Starting at offset 0x80, increments by 4
p_BSP: equ SystemVariables + 0x80
@@ -48,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