101 lines
3.1 KiB
C
101 lines
3.1 KiB
C
#include "multiboot2.h"
|
|
#include "fb.h"
|
|
#include "mem.h"
|
|
#include <stdint.h>
|
|
#include "klog.h"
|
|
#include "mm.h"
|
|
|
|
static uint32_t mbinfo[2048];
|
|
|
|
static void mbinfo_process_tag(const multiboot2_info_tag_t * tag)
|
|
{
|
|
switch (tag->type)
|
|
{
|
|
case MULTIBOOT2_INFO_BOOT_COMMAND_LINE:
|
|
{
|
|
multiboot2_info_boot_command_line_t * cl =
|
|
(multiboot2_info_boot_command_line_t *)tag;
|
|
klog_printf("Kernel boot command line: '%s'\n", cl->string);
|
|
}
|
|
break;
|
|
|
|
case MULTIBOOT2_INFO_BOOT_LOADER_NAME:
|
|
{
|
|
multiboot2_info_boot_loader_name_t * bln =
|
|
(multiboot2_info_boot_loader_name_t *)tag;
|
|
klog_printf("Boot loader: '%s'\n", bln->string);
|
|
}
|
|
break;
|
|
|
|
case MULTIBOOT2_INFO_MEMORY_MAP:
|
|
{
|
|
multiboot2_info_memory_map_t * mmap_info =
|
|
(multiboot2_info_memory_map_t *)tag;
|
|
size_t sz = sizeof(mmap_info->header) +
|
|
sizeof(mmap_info->entry_size) +
|
|
sizeof(mmap_info->entry_version);
|
|
multiboot2_info_memory_map_entry_t * entry = &mmap_info->entries[0];
|
|
for (;;)
|
|
{
|
|
sz += mmap_info->entry_size;
|
|
if (sz > mmap_info->header.size)
|
|
{
|
|
break;
|
|
}
|
|
if (entry->type == MULTIBOOT2_MEMORY_MAP_TYPE_RAM)
|
|
{
|
|
klog_printf("Memory region %16lx : %16lx\n",
|
|
entry->base_addr,
|
|
entry->length);
|
|
mm_register_ram_region(entry->base_addr, entry->length);
|
|
}
|
|
entry = (multiboot2_info_memory_map_entry_t *)((uintptr_t)entry + mmap_info->entry_size);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case MULTIBOOT2_INFO_FRAMEBUFFER_INFO:
|
|
{
|
|
multiboot2_info_framebuffer_info_t * fbinfo =
|
|
(multiboot2_info_framebuffer_info_t *)tag;
|
|
fb_init((uint32_t *)(uintptr_t)fbinfo->framebuffer_addr,
|
|
fbinfo->framebuffer_width,
|
|
fbinfo->framebuffer_height,
|
|
fbinfo->framebuffer_pitch);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void process_tags(const multiboot2_info_tag_t * tag, bool init)
|
|
{
|
|
while (tag->type != 0u)
|
|
{
|
|
if ((init && (tag->type == MULTIBOOT2_INFO_FRAMEBUFFER_INFO)) ||
|
|
(!init && (tag->type != MULTIBOOT2_INFO_FRAMEBUFFER_INFO)))
|
|
{
|
|
mbinfo_process_tag(tag);
|
|
}
|
|
tag = multiboot2_info_next_tag(tag);
|
|
}
|
|
}
|
|
|
|
bool mbinfo_init(uint32_t mbinfo_addr)
|
|
{
|
|
multiboot2_info_header_t * mbinfo_header = (multiboot2_info_header_t *)mbinfo_addr;
|
|
if (mbinfo_header->total_size <= sizeof(mbinfo))
|
|
{
|
|
memcpy32(mbinfo, mbinfo_header, mbinfo_header->total_size / 4u);
|
|
multiboot2_info_tag_t * tag = (multiboot2_info_tag_t *)(mbinfo + sizeof(multiboot2_info_header_t) / 4u);
|
|
process_tags(tag, true);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void mbinfo_load(void)
|
|
{
|
|
multiboot2_info_tag_t * tag = (multiboot2_info_tag_t *)(mbinfo + sizeof(multiboot2_info_header_t) / 4u);
|
|
process_tags(tag, false);
|
|
}
|