Skip to content

Commit

Permalink
e820 map -> ACPI address map
Browse files Browse the repository at this point in the history
  • Loading branch information
phaubertin committed Dec 1, 2024
1 parent 86880af commit 200576b
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 63 deletions.
2 changes: 1 addition & 1 deletion doc/layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ looks like this:
| kernel command line | | allocations
+---------------------------------------+ bootinfo.cmdline |
| BIOS physical memory map | |
+---------------------------------------+ bootinfo.e820_map |
+---------------------------------------+ bootinfo.acpi_addr_map |
| kernel data segment | | ^
| | | |
+---------------------------------------+ bootinfo.data_physaddr -+- address |
Expand Down
2 changes: 1 addition & 1 deletion include/kernel/infrastructure/i686/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ typedef struct {
uint64_t addr;
uint64_t size;
uint32_t type;
} e820_t;
} acpi_addr_range_t;

typedef uint64_t seg_descriptor_t;

Expand Down
8 changes: 4 additions & 4 deletions include/kernel/interface/i686/asm/bootinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@
/** Offset of the ramdisk_size bootinfo_t member */
#define BOOTINFO_RAMDISK_SIZE 28

/** Offset of the e820_entries bootinfo_t member */
#define BOOTINFO_E820_ENTRIES 32
/** Offset of the acpi_addr_map bootinfo_t member */
#define BOOTINFO_ACPI_ADDR_MAP 32

/** Offset of the e820_map bootinfo_t member */
#define BOOTINFO_E820_MAP 36
/** Offset of the addr_map_entries bootinfo_t member */
#define BOOTINFO_ADDR_MAP_ENTRIES 36

/** Offset of the cmdline bootinfo_t member */
#define BOOTINFO_CMDLINE 40
Expand Down
42 changes: 21 additions & 21 deletions include/kernel/interface/i686/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,27 +43,27 @@
*
* See also the setup code, i.e. kernel/i686/setup32.asm. */
typedef struct {
Elf32_Ehdr *kernel_start;
size_t kernel_size;
Elf32_Ehdr *loader_start;
size_t loader_size;
void *image_start;
void *image_top;
kern_paddr_t ramdisk_start;
size_t ramdisk_size;
uint32_t e820_entries;
const e820_t *e820_map;
void *cmdline;
void *boot_heap;
void *boot_end;
pte_t *page_table_1mb;
pte_t *page_table_16mb;
pte_t *page_table_klimit;
pte_t *page_directory;
uint32_t setup_signature;
void *data_start;
size_t data_size;
size_t data_physaddr;
Elf32_Ehdr *kernel_start;
size_t kernel_size;
Elf32_Ehdr *loader_start;
size_t loader_size;
void *image_start;
void *image_top;
kern_paddr_t ramdisk_start;
size_t ramdisk_size;
const acpi_addr_range_t *acpi_addr_map;
uint32_t addr_map_entries;
void *cmdline;
void *boot_heap;
void *boot_end;
pte_t *page_table_1mb;
pte_t *page_table_16mb;
pte_t *page_table_klimit;
pte_t *page_directory;
uint32_t setup_signature;
void *data_start;
size_t data_size;
size_t data_physaddr;
} bootinfo_t;

typedef struct {
Expand Down
53 changes: 32 additions & 21 deletions kernel/infrastructure/i686/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ static bool range_is_in_available_memory(

bool retval = false;

for(int idx = 0; idx < bootinfo->e820_entries; ++idx) {
for(int idx = 0; idx < bootinfo->addr_map_entries; ++idx) {
memory_range_t entry_range;

const e820_t *entry = &bootinfo->e820_map[idx];
entry_range.start = entry->addr;
entry_range.end = entry->addr + entry->size;
const acpi_addr_range_t *entry = &bootinfo->acpi_addr_map[idx];
entry_range.start = entry->addr;
entry_range.end = entry->addr + entry->size;

if(entry->type == ACPI_ADDR_RANGE_MEMORY) {
if(memory_range_is_within(range, &entry_range)) {
Expand Down Expand Up @@ -172,8 +172,8 @@ void check_memory(const bootinfo_t *bootinfo) {
static uint64_t memory_find_top(const bootinfo_t *bootinfo) {
uint64_t memory_top = 0;

for(int idx = 0; idx < bootinfo->e820_entries; ++idx) {
const e820_t *entry = &bootinfo->e820_map[idx];
for(int idx = 0; idx < bootinfo->addr_map_entries; ++idx) {
const acpi_addr_range_t *entry = &bootinfo->acpi_addr_map[idx];

/* Only consider available memory entries. */
if(entry->type != ACPI_ADDR_RANGE_MEMORY) {
Expand Down Expand Up @@ -252,21 +252,32 @@ void *memory_lookup_page(uint64_t paddr) {
}

static int map_memory_type(uint32_t e820_type) {
/* The values of the JINUE_MEMYPE_... constants are based on the ACPI
* address range types, i.e. all non OEM-defined values are the same
* between both.
*
* We reserve the OEM defined range from 0xf0000000 for Jinue-specific
* values, so we fold all OEM defined values from the system address map
* into a single value that means "OEM defined". */
if(e820_type >= ACPI_ADDR_RANGE_OEM_START) {
return JINUE_MEMYPE_OEM;
}

switch(e820_type) {
case ACPI_ADDR_RANGE_MEMORY:
case ACPI_ADDR_RANGE_RESERVED:
case ACPI_ADDR_RANGE_ACPI:
case ACPI_ADDR_RANGE_NVS:
case ACPI_ADDR_RANGE_UNUSABLE:
case ACPI_ADDR_RANGE_DISABLED:
case ACPI_ADDR_RANGE_PERSISTENT:
case ACPI_ADDR_RANGE_OEM:
/* ACPI address range types and Jinue memory type have the same value
* for these types. */
return e820_type;
case ACPI_ADDR_RANGE_RESERVED:
default:
/* The ACPI specification states that any undefined type value should
* be treated as reserved. */
return JINUE_MEMYPE_RESERVED;
}
}
Expand All @@ -284,7 +295,7 @@ static void align_range(memory_range_t *dest, bool is_available) {
}
}

static void assign_and_align_entry(memory_range_t *dest, const e820_t *entry) {
static void assign_and_align_entry(memory_range_t *dest, const acpi_addr_range_t *entry) {
dest->start = entry->addr;
dest->end = entry->addr + entry->size;
align_range(dest, entry->type == ACPI_ADDR_RANGE_MEMORY);
Expand Down Expand Up @@ -326,8 +337,8 @@ static void clip_memory_range(memory_range_t *dest, const memory_range_t *clippi
}

static void clip_available_range(memory_range_t *dest, const bootinfo_t *bootinfo) {
for(int idx = 0; idx < bootinfo->e820_entries; ++idx) {
const e820_t *entry = &bootinfo->e820_map[idx];
for(int idx = 0; idx < bootinfo->addr_map_entries; ++idx) {
const acpi_addr_range_t *entry = &bootinfo->acpi_addr_map[idx];

if(entry->type == ACPI_ADDR_RANGE_MEMORY) {
continue;
Expand All @@ -350,8 +361,8 @@ static void find_range_for_loader(memory_range_t *dest, const bootinfo_t *bootin
/* First, find the largest available range over the 4GB mark. */
memory_range_t largest_over_4gb = {0};

for(int idx = 0; idx < bootinfo->e820_entries; ++idx) {
const e820_t *entry = &bootinfo->e820_map[idx];
for(int idx = 0; idx < bootinfo->addr_map_entries; ++idx) {
const acpi_addr_range_t *entry = &bootinfo->acpi_addr_map[idx];

if(entry->type != ACPI_ADDR_RANGE_MEMORY) {
continue;
Expand All @@ -376,8 +387,8 @@ static void find_range_for_loader(memory_range_t *dest, const bootinfo_t *bootin
/* Then, compare this to the region just above the kernel data. */
memory_range_t under_4gb = {0};

for(int idx = 0; idx < bootinfo->e820_entries; ++idx) {
const e820_t *entry = &bootinfo->e820_map[idx];
for(int idx = 0; idx < bootinfo->addr_map_entries; ++idx) {
const acpi_addr_range_t *entry = &bootinfo->acpi_addr_map[idx];

if(entry->type != ACPI_ADDR_RANGE_MEMORY) {
continue;
Expand Down Expand Up @@ -439,9 +450,9 @@ int machine_get_address_map(const jinue_buffer_t *buffer) {
}
};

const size_t e820_entries = bootinfo->e820_entries;
const size_t addr_map_entries = bootinfo->addr_map_entries;
const size_t kernel_entries = sizeof(kernel_regions) / sizeof(kernel_regions[0]);
const size_t total_entries = e820_entries + kernel_entries;
const size_t total_entries = addr_map_entries + kernel_entries;
const size_t result_size =
sizeof(jinue_addr_map_t) + total_entries * sizeof(jinue_addr_map_entry_t);

Expand All @@ -455,14 +466,14 @@ int machine_get_address_map(const jinue_buffer_t *buffer) {
return -JINUE_E2BIG;
}

for(unsigned int idx = 0; idx < e820_entries; ++idx) {
map->entry[idx].addr = bootinfo->e820_map[idx].addr;
map->entry[idx].size = bootinfo->e820_map[idx].size;
map->entry[idx].type = map_memory_type(bootinfo->e820_map[idx].type);
for(unsigned int idx = 0; idx < addr_map_entries; ++idx) {
map->entry[idx].addr = bootinfo->acpi_addr_map[idx].addr;
map->entry[idx].size = bootinfo->acpi_addr_map[idx].size;
map->entry[idx].type = map_memory_type(bootinfo->acpi_addr_map[idx].type);
}

for(unsigned int idx = 0; idx < kernel_entries; ++idx) {
map->entry[e820_entries + idx] = kernel_regions[idx];
map->entry[addr_map_entries + idx] = kernel_regions[idx];
}

return 0;
Expand Down
30 changes: 15 additions & 15 deletions kernel/interface/i686/setup32.asm
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
; | kernel command line | | allocations
; +-----------------------------------+ bootinfo.cmdline |
; | BIOS physical memory map | |
; +-----------------------------------+ bootinfo.e820_map |
; +-----------------------------------+ bootinfo.acpi_addr_map |
; | kernel data segment | |
; | (copied from ELF binary) | v
; +-----------------------------------+ bootinfo.data_physaddr ---
Expand Down Expand Up @@ -291,7 +291,7 @@ start:
add dword [ebp + BOOTINFO_LOADER_START], BOOT_OFFSET_FROM_1MB
add dword [ebp + BOOTINFO_IMAGE_START], BOOT_OFFSET_FROM_1MB
add dword [ebp + BOOTINFO_IMAGE_TOP], BOOT_OFFSET_FROM_1MB
add dword [ebp + BOOTINFO_E820_MAP], BOOT_OFFSET_FROM_1MB
add dword [ebp + BOOTINFO_ACPI_ADDR_MAP], BOOT_OFFSET_FROM_1MB
add dword [ebp + BOOTINFO_CMDLINE], BOOT_OFFSET_FROM_1MB
add dword [ebp + BOOTINFO_BOOT_HEAP], BOOT_OFFSET_FROM_1MB
add dword [ebp + BOOTINFO_BOOT_END], BOOT_OFFSET_FROM_1MB
Expand Down Expand Up @@ -347,13 +347,13 @@ just_right_here:
; ecx, esi are caller saved
copy_e820_memory_map:
; Set memory map address in bootinfo_t structure
mov dword [ebp + BOOTINFO_E820_MAP], edi
mov dword [ebp + BOOTINFO_ACPI_ADDR_MAP], edi

; Source address
add esi, BOOT_E820_MAP

; Compute size to copy
mov ecx, dword [ebp + BOOTINFO_E820_ENTRIES]
mov ecx, dword [ebp + BOOTINFO_ADDR_MAP_ENTRIES]
lea ecx, [5 * ecx] ; times 20 (size of one entry), which is 5 ...
shl ecx, 2 ; ... times 2^2

Expand Down Expand Up @@ -407,16 +407,16 @@ copy_cmdline:
; --------------------------------------------------------------------------
; Initialize most fields in the bootinfo_t structure, specifically:
;
; kernel_start (ebp + BOOTINFO_KERNEL_START)
; kernel_size (ebp + BOOTINFO_KERNEL_SIZE)
; loader_start (ebp + BOOTINFO_LOADER_START)
; loader_size (ebp + BOOTINFO_LOADER_SIZE)
; image_start (ebp + BOOTINFO_IMAGE_START)
; image_top (ebp + BOOTINFO_IMAGE_TOP)
; ramdisk_start (ebp + BOOTINFO_RAMDISK_START)
; ramdisk_size (ebp + BOOTINFO_RAMDISK_SIZE)
; setup_signature (ebp + BOOTINFO_SETUP_SIGNATURE)
; e820_entries (ebp + BOOTINFO_E820_ENTRIES)
; kernel_start (ebp + BOOTINFO_KERNEL_START)
; kernel_size (ebp + BOOTINFO_KERNEL_SIZE)
; loader_start (ebp + BOOTINFO_LOADER_START)
; loader_size (ebp + BOOTINFO_LOADER_SIZE)
; image_start (ebp + BOOTINFO_IMAGE_START)
; image_top (ebp + BOOTINFO_IMAGE_TOP)
; ramdisk_start (ebp + BOOTINFO_RAMDISK_START)
; ramdisk_size (ebp + BOOTINFO_RAMDISK_SIZE)
; setup_signature (ebp + BOOTINFO_SETUP_SIGNATURE)
; addr_map_entries (ebp + BOOTINFO_ADDR_MAP_ENTRIES)
;
; Arguments:
; esi real mode code start/zero-page address
Expand Down Expand Up @@ -448,7 +448,7 @@ initialize_bootinfo:
; Number of entries in BIOS memory map
mov al, byte [esi + BOOT_E820_ENTRIES]
movzx eax, al
mov dword [ebp + BOOTINFO_E820_ENTRIES], eax
mov dword [ebp + BOOTINFO_ADDR_MAP_ENTRIES], eax

ret

Expand Down

0 comments on commit 200576b

Please sign in to comment.