Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ The Pure64 information table is located at `0x0000000000005000` and ends at `0x0
<tr><th>Memory Address</th><th>Variable Size</th><th>Name</th><th>Description</th></tr>
<tr><td>0x5000</td><td>64-bit</td><td>ACPI</td><td>Address of the ACPI tables</td></tr>
<tr><td>0x5008</td><td>32-bit</td><td>CPU_BSP_ID</td><td>APIC ID of the BSP</td></tr>
<tr><td>0x5010</td><td>16-bit</td><td>CPU_SPEED</td><td>Speed of the CPUs in MegaHertz (<a href="http://en.wikipedia.org/wiki/Hertz">MHz</a>)</td></tr>
<tr><td>0x500C - 0x5011</td><td>&nbsp;</td><td>&nbsp;</td><td>For future use</td></tr>
<tr><td>0x5012</td><td>16-bit</td><td>CPU_CORES_ACTIVE</td><td>The number of CPU cores that were activated in the system</td></tr>
<tr><td>0x5014</td><td>16-bit</td><td>CPU_CORES_DETECT</td><td>The number of CPU cores that were detected in the system</td></tr>
<tr><td>0x5016</td><td>8-bit</td><td>CPU_MEM_PHYSICAL</td><td>The number of bits that are valid for a physical address</td></tr>
Expand All @@ -200,6 +200,8 @@ The Pure64 information table is located at `0x0000000000005000` and ends at `0x0
<tr><td>0x504C</td><td>16-bit</td><td>HPET Counter Minumum</td><td>Minimum Counter for the High Precision Event Timer</td></tr>
<tr><td>0x504E</td><td>8-bit</td><td>HPET Counters</td><td>Number of Counter in the High Precision Event Timer</td></tr>
<tr><td>0x504F</td><td>&nbsp;</td><td>&nbsp;</td><td>For future use</td></tr>
<tr><td>0x5050</td><td>64-bit</td><td>T0</td><td>RDTSC at Pure64 start</td></tr>
<tr><td>0x5058</td><td>64-bit</td><td>T1</td><td>RDTSC at Pure64 end</td></tr>
<tr><td>0x5060</td><td>64-bit</td><td>LAPIC</td><td>Local APIC address</td></tr>
<tr><td>0x5068 - 0x507F</td><td>&nbsp;</td><td>&nbsp;</td><td>For future use</td></tr>
<tr><td>0x5080</td><td>64-bit</td><td>VIDEO_BASE</td><td>Base memory for video (if graphics mode set)</td></tr>
Expand Down
2 changes: 1 addition & 1 deletion src/boot/bios-pxe.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 6 additions & 1 deletion src/boot/uefi.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -367,6 +367,11 @@ get_memmap:
; Stop interrupts
cli

; Get T0 timestamp
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
Expand Down
58 changes: 32 additions & 26 deletions src/init/acpi.asm
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,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

Expand Down Expand Up @@ -320,28 +316,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
; -----------------------------------------------------------------------------

Expand Down
4 changes: 2 additions & 2 deletions src/init/serial.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
39 changes: 14 additions & 25 deletions src/init/smp.asm
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@
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
Expand Down Expand Up @@ -60,8 +66,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
Expand Down Expand Up @@ -97,9 +103,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

Expand All @@ -111,28 +117,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


Expand Down
30 changes: 15 additions & 15 deletions src/init/timer.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -140,24 +146,17 @@ 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
mov ecx, HPET_MAIN_COUNTER
pause
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
Expand Down Expand Up @@ -291,6 +290,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
Expand Down
22 changes: 0 additions & 22 deletions src/interrupt.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading
Loading