Commit eec090b4 authored by Ian Seyler's avatar Ian Seyler

Memory mapping cleanup

parent 6f649988
......@@ -86,14 +86,14 @@ This memory map shows how physical memory looks after Pure64 is finished.
<tr><td>0x0000000000004000</td><td>0x0000000000004FFF</td><td>4 KiB</td><td>PDP High - 512 enties</td></tr>
<tr><td>0x0000000000005000</td><td>0x0000000000007FFF</td><td>12 KiB</td><td>Pure64 Data</td></tr>
<tr><td>0x0000000000008000</td><td>0x000000000000FFFF</td><td>32 KiB</td><td>Pure64 - After the OS is loaded and running this memory is free again</td></tr>
<tr><td>0x0000000000010000</td><td>0x000000000001FFFF</td><td>64 KiB</td><td>PD Low</td></tr>
<tr><td>0x0000000000020000</td><td>0x000000000005FFFF</td><td>256 KiB</td><td>PD High</td></tr>
<tr><td>0x0000000000010000</td><td>0x000000000001FFFF</td><td>64 KiB</td><td>PD Low - Entries are 8 bytes per 2MiB page</td></tr>
<tr><td>0x0000000000020000</td><td>0x000000000005FFFF</td><td>256 KiB</td><td>PD High - Entries are 8 bytes per 2MiB page</td></tr>
<tr><td>0x0000000000060000</td><td>0x000000000009FFFF</td><td>256 KiB</td><td>Free</td></tr>
<tr><td>0x00000000000A0000</td><td>0x00000000000FFFFF</td><td>384 KiB</td><td>ROM Area</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>VGA mem at 0xA0000 (128 KiB) Color text starts at 0xB8000</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>Video BIOS at 0xC0000 (64 KiB)</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>Motherboard BIOS at F0000 (64 KiB)</td></tr>
<tr><td>0x0000000000100000</td><td>0xFFFFFFFFFFFFFFFF</td><td>1+ MiB</td><td>Your software is loaded here</td></tr>
<tr><td>0x0000000000100000</td><td>0xFFFFFFFFFFFFFFFF</td><td>1+ MiB</td><td>The software payload is loaded here</td></tr>
</table>
When creating your Operating System or Demo you can use the sections marked free, however it is the safest to use memory above 1 MiB.
......
......@@ -179,20 +179,6 @@ create_pdpe_low:
cmp ecx, 0
jne create_pdpe_low
mov ecx, 64 ; number of PDPE's to make.. each PDPE maps 1GB of physical memory
mov edi, 0x00004000 ; location of high PDPE
mov eax, 0x00020007 ; location of first high PD. Bits (0) P, 1 (R/W), and 2 (U/S) set
create_pdpe_high:
stosd
push eax
xor eax, eax
stosd
pop eax
add eax, 0x00001000 ; 4K later (512 records x 8 bytes)
dec ecx
cmp ecx, 0
jne create_pdpe_high
; Create the low PD entries.
mov edi, 0x00010000
mov eax, 0x0000008F ; Bits 0 (P), 1 (R/W), 2 (U/S), 3 (PWT), and 7 (PS) set
......@@ -278,17 +264,91 @@ clearcs64:
stosd
stosd ; Write 8 bytes in total to overwrite the 'far jump' and marker
; Process the E820 memory map to find all possible 2MiB pages that are free to use
; Build a map at 0x400000
xor ecx, ecx
xor ebx, ebx ; Counter for pages found
mov esi, 0x00006000 ; E820 Map location
nextentry:
add esi, 16 ; Skip ESI to type marker
mov eax, [esi] ; Load the 32-bit type marker
cmp eax, 0 ; End of the list?
je end820
cmp eax, 1 ; Is it marked as free?
je processfree
add esi, 16 ; Skip ESI to start of next entry
jmp nextentry
processfree:
sub esi, 16
mov rax, [rsi] ; Physical start address
add esi, 8
mov rcx, [rsi] ; Physical length
add esi, 24
shr rcx, 21 ; Convert bytes to # of 2 MiB pages
cmp rcx, 0 ; Do we have at least 1 page?
je nextentry
shl rax, 1
mov edx, 0x1FFFFF
not rdx ; Clear bits 20 - 0
and rax, rdx
; At this point RAX points to the start and RCX has the # of pages
shr rax, 21 ; page # to start on
mov rdi, 0x400000 ; 4 MiB into physical memory
add rdi, rax
mov al, 1
add ebx, ecx
rep stosb
jmp nextentry
end820:
shl ebx, 1
mov dword [mem_amount], ebx
shr ebx, 1
; Create the high memory map
mov rcx, rbx
shr rcx, 9 ; TODO - This isn't the exact math but good enough
add rcx, 1 ; number of PDPE's to make.. each PDPE maps 1GB of physical memory
mov edi, 0x00004000 ; location of high PDPE
mov eax, 0x00020007 ; location of first high PD. Bits (0) P, 1 (R/W), and 2 (U/S) set
create_pdpe_high:
stosq
add rax, 0x00001000 ; 4K later (512 records x 8 bytes)
dec ecx
cmp ecx, 0
jne create_pdpe_high
; Create the high PD entries
mov rax, 0x000000000000008F ; Bits 0 (P), 1 (R/W), 2 (U/S), 3 (PWT), and 7 (PS) set
mov rdi, 0x0000000000020000 ; Location of high PD entries
add rax, 0x0000000000400000 ; Add 4MiB offset
; EBX contains the number of pages that should exist in the map, once they are all found bail out
xor ecx, ecx
xor eax, eax
xor edx, edx
mov edi, 0x00020000 ; Location of high PD entries
mov esi, 0x00400000 ; Location of free pages map
pd_high:
cmp rdx, rbx ; Compare mapped pages to max pages
je pd_high_done
lodsb
cmp al, 1
je pd_high_entry
add rcx, 1
jmp pd_high
pd_high_entry:
mov eax, 0x0000008F ; Bits 0 (P), 1 (R/W), 2 (U/S), 3 (PWT), and 7 (PS) set
shl rcx, 21
add rax, rcx
shr rcx, 21
stosq
add rax, 0x0000000000200000
add rcx, 1
cmp rcx, 8192 ; Map 16 GiB
jne pd_high
add rdx, 1 ; We have mapped a valid page
jmp pd_high
pd_high_done:
jmp $
; Build a temporary IDT
xor rdi, rdi ; create the 64-bit IDT (at linear address 0x0000000000000000)
......@@ -394,36 +454,36 @@ clearmapnext:
mov rsp, rax ; Pure64 leaves 0x50000-0x9FFFF free so we use that
; Calculate amount of usable RAM from Memory Map
xor ecx, ecx
mov rsi, 0x0000000000006000 ; E820 Map location
readnextrecord:
lodsq
lodsq
lodsd
cmp eax, 0 ; Are we at the end?
je endmemcalc
cmp eax, 1 ; Useable RAM
je goodmem
cmp eax, 3 ; ACPI Reclaimable
je goodmem
cmp eax, 6 ; BIOS Reclaimable
je goodmem
lodsd
lodsq
jmp readnextrecord
goodmem:
sub rsi, 12
lodsq
add rcx, rax
lodsq
lodsq
jmp readnextrecord
endmemcalc:
shr rcx, 20 ; Value is in bytes so do a quick divide by 1048576 to get MiB's
add ecx, 1 ; The BIOS will usually report actual memory minus 1
and ecx, 0xFFFFFFFE ; Make sure it is an even number (in case we added 1 to an even number)
mov dword [mem_amount], ecx
; xor ecx, ecx
; mov rsi, 0x0000000000006000 ; E820 Map location
;readnextrecord:
; lodsq
; lodsq
; lodsd
; cmp eax, 0 ; Are we at the end?
; je endmemcalc
; cmp eax, 1 ; Useable RAM
; je goodmem
; cmp eax, 3 ; ACPI Reclaimable
; je goodmem
; cmp eax, 6 ; BIOS Reclaimable
; je goodmem
; lodsd
; lodsq
; jmp readnextrecord
;goodmem:
; sub rsi, 12
; lodsq
; add rcx, rax
; lodsq
; lodsq
; jmp readnextrecord
;
;endmemcalc:
; shr rcx, 20 ; Value is in bytes so do a quick divide by 1048576 to get MiB's
; add ecx, 1 ; The BIOS will usually report actual memory minus 1
; and ecx, 0xFFFFFFFE ; Make sure it is an even number (in case we added 1 to an even number)
; mov dword [mem_amount], ecx
; Build the infomap
xor edi, edi
......
......@@ -28,7 +28,7 @@ os_HPETAddress: equ SystemVariables + 0x38
; DD - Starting at offset 128, increments by 4
os_BSP: equ SystemVariables + 128
mem_amount: equ SystemVariables + 132
mem_amount: equ SystemVariables + 132 ; in MiB
; DW - Starting at offset 256, increments by 2
cpu_speed: equ SystemVariables + 256
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment