summaryrefslogtreecommitdiff
path: root/src/arch/amd64/mboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/amd64/mboot.c')
-rw-r--r--src/arch/amd64/mboot.c138
1 files changed, 75 insertions, 63 deletions
diff --git a/src/arch/amd64/mboot.c b/src/arch/amd64/mboot.c
index 6c3c413..b7124df 100644
--- a/src/arch/amd64/mboot.c
+++ b/src/arch/amd64/mboot.c
@@ -1,17 +1,25 @@
-#include "mboot.h"
-#include "serial.h"
-#include "shim.h"
-
+#include <shim.h>
#include <lib.h>
#include <stdint.h>
+#include <panic.h>
+
+#include "mboot.h"
+
+#define MBOOT_HEADER_MAGIC 0x36D76289
+
+#define MBOOT_CMDLINE 1
+#define MBOOT_MEMORY_MAP 6
+#define MBOOT_ELF_SYMBOLS 9
+#define MBOOT_OLD_RSDP 14
+#define MBOOT_NEW_RSDP 15
extern char symtab;
#define kaddr(addr) ((uintptr_t)(&addr))
-typedef unsigned char mboot_uint8_t;
-typedef unsigned short mboot_uint16_t;
-typedef unsigned int mboot_uint32_t;
-typedef unsigned long long mboot_uint64_t;
+typedef uint8_t mboot_uint8_t;
+typedef uint16_t mboot_uint16_t;
+typedef uint32_t mboot_uint32_t;
+typedef uint64_t mboot_uint64_t;
struct mboot_info {
mboot_uint32_t total_size;
@@ -25,24 +33,17 @@ struct mboot_tag {
char data[];
};
-enum mboot_tag_type {
- MBOOT_CMDLINE = 0,
- MBOOT_MEMORYMAP = 6,
- MBOOT_SYMBOLS = 9,
- MBOOT_RSDP = 14,
- MBOOT_XSDP = 15,
-};
-
-struct mboot_elf_header_layout {
+struct mboot_tag_elf_sections {
mboot_uint32_t type;
mboot_uint32_t size;
- mboot_uint32_t num;
- mboot_uint32_t entsize;
- mboot_uint32_t shndx;
- char elf_section_headers[];
+ mboot_uint16_t num;
+ mboot_uint16_t entsize;
+ mboot_uint16_t shndx;
+ mboot_uint16_t reserved;
+ char sections[];
};
-struct mboot_elf_section_header {
+struct mboot_tag_elf_sections_entry {
mboot_uint32_t sh_name;
mboot_uint32_t sh_type;
mboot_uint64_t sh_flags;
@@ -55,45 +56,46 @@ struct mboot_elf_section_header {
mboot_uint64_t sh_entsize;
};
-struct mboot_memory_segment {
+struct mboot_mmap_entry {
mboot_uint64_t addr;
mboot_uint64_t len;
mboot_uint32_t type;
- mboot_uint32_t reserved;
+ mboot_uint32_t zero;
};
-struct mboot_memory_map {
- mboot_uint32_t tag;
+struct mboot_tag_mmap {
+ mboot_uint32_t type;
mboot_uint32_t size;
mboot_uint32_t entry_size;
mboot_uint32_t entry_version;
- struct memory_segment entries[];
+ struct mboot_mmap_entry entries[];
};
-struct mboot_rsdp {
- mboot_uint32_t tag;
+
+struct mboot_tag_old_rsdp {
+ mboot_uint32_t type;
mboot_uint32_t size;
mboot_uint8_t rsdp[];
};
-struct mboot_xsdp {
- mboot_uint32_t tag;
+struct mboot_tag_new_rsdp {
+ mboot_uint32_t type;
mboot_uint32_t size;
- mboot_uint8_t xsdp[];
+ mboot_uint8_t rsdp[];
};
-struct mboot_cmdline {
- mboot_uint32_t tag;
+struct mboot_tag_cmdline {
+ mboot_uint32_t type;
mboot_uint32_t size;
- char cmdline[];
+ mboot_uint8_t cmdline[];
};
static void read_symbols(
struct boot_info *shim_info,
- struct mboot_elf_header_layout *layout
+ struct mboot_tag_elf_sections *sections
) {
- shim_info->symbol_table = layout->elf_section_headers;
+ shim_info->symbol_table = sections->sections;
// struct mboot_elf_section_header *section =
// (struct mboot_elf_section_header *) (layout->elf_section_headers);
@@ -130,7 +132,7 @@ static void read_symbols(
static void read_cmdline(
struct boot_info *shim_info,
- struct mboot_cmdline *cmdline
+ struct mboot_tag_cmdline *cmdline
) {
mboot_uint32_t size = cmdline->size - 8;
if (size >= CMDLINE_MAX)
@@ -139,39 +141,49 @@ static void read_cmdline(
shim_info->cmdline[size] = '\0';
}
-static void read_memorymap(
+static void read_memory_map(
struct boot_info *shim_info,
- struct mboot_memory_map *map
+ struct mboot_tag_mmap *map
) {
- int size = map->size - sizeof(mboot_uint32_t) * 4;
- int count = size / map->entry_size;
-
- shim_info->map.entry_count = count;
- shim_info->map.entry_length = map->entry_size;
- shim_info->map.entries = map->entries;
+ int idx = 0;
+ uintptr_t i = (uintptr_t)map->entries;
+ for ( ;
+ i < (uintptr_t)map->entries + map->size;
+ i += map->entry_size, idx++
+ ) {
+ struct mboot_mmap_entry *seg = (struct mboot_mmap_entry *) i;
+ shim_info->map.entries[idx].addr = seg->addr;
+ shim_info->map.entries[idx].type = seg->type;
+ shim_info->map.entries[idx].len = seg->len;
+ }
+ shim_info->map.entry_count = idx;
}
-static void read_rsdp(
+static void read_old_rsdp(
struct boot_info *shim_info,
- struct mboot_rsdp *rsdp
+ struct mboot_tag_old_rsdp *rsdp
) {
if (shim_info->acpi_table != NULL)
return; // xsdp is newer and has been loaded
shim_info->acpi_table = rsdp->rsdp;
}
-static void read_xsdp(
+static void read_new_rsdp(
struct boot_info *shim_info,
- struct mboot_xsdp *xsdp
+ struct mboot_tag_new_rsdp *rsdp
) {
- shim_info->acpi_table = xsdp->xsdp;
+ shim_info->acpi_table = rsdp->rsdp;
}
void mboot_load_info(
+ long mboot_magic,
const void *mboot_data_ptr,
struct boot_info *shim_info
) {
+ if (mboot_magic != MBOOT_HEADER_MAGIC)
+ panic("invalid multiboot magic");
+
memset(shim_info, 0, sizeof(struct boot_info));
struct mboot_info *mboot_info = (struct mboot_info *) mboot_data_ptr;
@@ -186,31 +198,31 @@ void mboot_load_info(
case MBOOT_CMDLINE:
read_cmdline(
shim_info,
- (struct mboot_cmdline *) tag
+ (struct mboot_tag_cmdline *) tag
);
break;
- case MBOOT_MEMORYMAP:
- read_memorymap(
+ case MBOOT_MEMORY_MAP:
+ read_memory_map(
shim_info,
- (struct mboot_memory_map *) tag
+ (struct mboot_tag_mmap *) tag
);
break;
- case MBOOT_SYMBOLS:
+ case MBOOT_ELF_SYMBOLS:
read_symbols(
shim_info,
- (struct mboot_elf_header_layout *) tag
+ (struct mboot_tag_elf_sections *) tag
);
break;
- case MBOOT_RSDP:
- read_rsdp(
+ case MBOOT_OLD_RSDP:
+ read_old_rsdp(
shim_info,
- (struct mboot_rsdp *) tag
+ (struct mboot_tag_old_rsdp *) tag
);
break;
- case MBOOT_XSDP:
- read_xsdp(
+ case MBOOT_NEW_RSDP:
+ read_new_rsdp(
shim_info,
- (struct mboot_xsdp *) tag
+ (struct mboot_tag_new_rsdp *) tag
);
break;
default: