metal-cos/sys/amd64/mbentry.c

215 lines
6.8 KiB
C
Raw Normal View History

2014-02-12 21:47:13 +00:00
/*
* Multiboot C Entry
*/
#include <stdint.h>
#include <kassert.h>
#include <cdefs.h>
#include "../dev/console.h"
#include "amd64.h"
#include "multiboot.h"
extern void *_end;
void mbentry(unsigned long magic, unsigned long addr);
#define CHECK_FLAG(flag, bit) ((flag) & (1 << (bit)))
#define PAGE_ALIGN __attribute__((aligned(PGSIZE)))
#define DATA_SECTION __attribute__((section(".data")))
extern void Machine_Init();
extern void PAlloc_Init();
extern void PAlloc_AddRegion(uintptr_t start, uintptr_t len);
#define GENTBL_2(base) (base + 0x183), (base + 0x200183),
#define GENTBL_8(base) GENTBL_2(base) GENTBL_2(base + 0x400000) \
GENTBL_2(base + 0x800000) GENTBL_2(base + 0xC00000)
#define GENTBL_32(base) GENTBL_8(base) GENTBL_8(base + 0x1000000) \
GENTBL_8(base + 0x2000000) GENTBL_8(base + 0x3000000)
#define GENTBL_128(base) GENTBL_32(base) GENTBL_32(base + 0x4000000) \
GENTBL_32(base + 0x8000000) GENTBL_32(base + 0xC000000)
#define GENTBL(base) GENTBL_128(base) GENTBL_128(base + 0x10000000) \
GENTBL_128(base + 0x20000000) GENTBL_128(base + 0x30000000)
PAGE_ALIGN DATA_SECTION PageTable bootpgtbl3a = { .entries = {
GENTBL(0x0)
}};
PAGE_ALIGN DATA_SECTION PageTable bootpgtbl3b = { .entries = {
GENTBL(0x40000000)
}};
PAGE_ALIGN DATA_SECTION PageTable bootpgtbl3c = { .entries = {
GENTBL(0x80000000)
}};
PAGE_ALIGN DATA_SECTION PageTable bootpgtbl3d = { .entries = {
GENTBL(0xC0000000)
}};
PAGE_ALIGN DATA_SECTION PageTable bootpgtbl2 = { .entries = {
(uint64_t)&bootpgtbl3a + 0x03,
(uint64_t)&bootpgtbl3b + 0x03,
(uint64_t)&bootpgtbl3c + 0x03,
(uint64_t)&bootpgtbl3d + 0x03,
0
}};
PAGE_ALIGN DATA_SECTION PageTable bootpgtbl1 = { .entries = {
(uint64_t)&bootpgtbl2 + 0x03,
0
}};
void
mb_entry(unsigned long magic, unsigned long addr)
{
multiboot_info_t *mbi = (multiboot_info_t *)addr;
Console_Init();
PAlloc_Init();
/* @r{Am I booted by a Multiboot-compliant boot loader?} */
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
{
kprintf("Invalid magic number: 0x%x\n", magic);
//return;
}
/* @r{Print out the flags.} */
kprintf("flags = 0x%x\n", (uint64_t) mbi->flags);
/* @r{Are mem_* valid?} */
if (CHECK_FLAG (mbi->flags, 0))
kprintf("mem_lower = %uKB, mem_upper = %uKB\n",
(unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);
/* @r{Is boot_device valid?} */
if (CHECK_FLAG (mbi->flags, 1))
kprintf("boot_device = 0x%x\n", (unsigned) mbi->boot_device);
/* @r{Is the command line passed?} */
if (CHECK_FLAG (mbi->flags, 2))
kprintf("cmdline = %s\n", (char *)(uintptr_t)mbi->cmdline);
/* @r{Are mods_* valid?} */
if (CHECK_FLAG (mbi->flags, 3))
{
multiboot_module_t *mod;
int i;
kprintf("mods_count = %d, mods_addr = 0x%x\n",
(int) mbi->mods_count, (int) mbi->mods_addr);
for (i = 0, mod = (multiboot_module_t *)(uintptr_t)mbi->mods_addr;
i < mbi->mods_count;
i++, mod++)
kprintf(" mod_start = 0x%x, mod_end = 0x%x, cmdline = %s\n",
(unsigned) mod->mod_start,
(unsigned) mod->mod_end,
(char *)(uintptr_t) mod->cmdline);
}
/* @r{Bits 4 and 5 are mutually exclusive!} */
if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
{
kprintf("Both bits 4 and 5 are set.\n");
return;
}
/* @r{Is the symbol table of a.out valid?} */
if (CHECK_FLAG (mbi->flags, 4))
{
multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
kprintf("multiboot_aout_symbol_table: tabsize = 0x%0x\n"
" strsize = 0x%x, addr = 0x%x\n",
(unsigned) multiboot_aout_sym->tabsize,
(unsigned) multiboot_aout_sym->strsize,
(unsigned) multiboot_aout_sym->addr);
}
/* @r{Is the section header table of ELF valid?} */
if (CHECK_FLAG (mbi->flags, 5))
{
multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
kprintf("multiboot_elf_sec: num = %u, size = 0x%x,"
" addr = 0x%x, shndx = 0x%x\n",
(unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size,
(unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx);
}
/* @r{Are mmap_* valid?} */
if (CHECK_FLAG (mbi->flags, 6))
{
multiboot_memory_map_t *mmap;
kprintf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
(unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
for (mmap = (multiboot_memory_map_t *)(uintptr_t) mbi->mmap_addr;
(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
mmap = (multiboot_memory_map_t *) ((unsigned long) mmap
+ mmap->size + sizeof (mmap->size)))
{
kprintf(" size = 0x%x, base_addr = 0x%x,"
" length = 0x%x, type = 0x%x\n",
(unsigned) mmap->size,
mmap->addr,
mmap->len,
(unsigned) mmap->type);
}
}
Machine_Init();
uint64_t memoryStart = (uintptr_t)&_end;
PAlloc_Init();
/* @r{Are mmap_* valid?} */
if (CHECK_FLAG (mbi->flags, 6))
{
multiboot_memory_map_t *mmap;
for (mmap = (multiboot_memory_map_t *)(uintptr_t) mbi->mmap_addr;
(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
mmap = (multiboot_memory_map_t *) ((unsigned long) mmap
+ mmap->size + sizeof (mmap->size)))
{
if (mmap->type == MULTIBOOT_MEMORY_AVAILABLE) {
kprintf(" size = 0x%x, base_addr = 0x%x,"
" length = 0x%x, type = 0x%x\n",
(unsigned) mmap->size,
mmap->addr,
mmap->len,
(unsigned) mmap->type);
uintptr_t start = mmap->addr;
uintptr_t len = mmap->len;
if (start + len > memoryStart)
{
if (start < memoryStart)
{
len = len - (memoryStart - start);
start = memoryStart;
}
if ((start % PGSIZE) != 0)
{
len = len - (PGSIZE - (start & PGMASK));
start = ROUNDUP_PGSIZE(start);
}
len = ROUNDDOWN_PGSIZE(len);
PAlloc_AddRegion(start, len);
}
}
}
}
}