Files
mango/arch/x86_64/init.c

165 lines
4.2 KiB
C

#include <socks/pmap.h>
#include <socks/device.h>
#include <socks/kext.h>
#include <socks/clock.h>
#include <socks/types.h>
#include <socks/object.h>
#include <arch/e820.h>
#include <socks/init.h>
#include <socks/percpu.h>
#include <socks/cpu.h>
#include <socks/memblock.h>
#include <socks/vm.h>
#include <socks/printk.h>
#include <socks/machine/cpu.h>
#include <socks/libc/stdio.h>
#include <arch/vgacon.h>
#include <arch/serial.h>
#ifdef KEXT_NET_DOORSTUCK_SOCKS_ACPI
#include <arch/acpi.h>
#endif
#define PTR32(x) ((void *)((uintptr_t)(x)))
static ml_cpu_block g_bootstrap_cpu = {0};
static struct framebuffer_varinfo __bootfb_varinfo;
static struct framebuffer_fixedinfo __bootfb_fixedinfo;
/* start and end of kernel image (physical addresses) */
extern char __pstart[], __pend[];
static void bootstrap_cpu_init(void)
{
ml_cpu_block_init(&g_bootstrap_cpu);
ml_cpu_block_use(&g_bootstrap_cpu);
}
static void early_vm_init(void)
{
uintptr_t alloc_start = VM_KERNEL_VOFFSET;
/* boot code mapped 2 GiB of memory from
VM_KERNEL_VOFFSET */
uintptr_t alloc_end = VM_KERNEL_VOFFSET + 0x7fffffff;
memblock_init(alloc_start, alloc_end, VM_KERNEL_VOFFSET);
printk("memblock: allocating from [0x%llx-0x%llx]", alloc_start, alloc_end);
memblock_reserve(0x00, (uintptr_t)__pend);
printk("memblock: reserved bios+kernel at [0x%016llx-0x%016llx]", 0, (uintptr_t)__pend);
}
static void init_bootfb(multiboot_info_t *mb)
{
__bootfb_varinfo.fb_xres = mb->framebuffer_width;
__bootfb_varinfo.fb_yres = mb->framebuffer_height;
__bootfb_varinfo.fb_bpp = mb->framebuffer_bpp;
__bootfb_varinfo.fb_stride = mb->framebuffer_pitch;
switch (mb->framebuffer_type) {
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
__bootfb_varinfo.fb_flags = FB_MODE_PALETTE;
__bootfb_varinfo.fb_palette_addr = mb->framebuffer_palette_addr;
__bootfb_varinfo.fb_palette_nr_colours = mb->framebuffer_palette_num_colors;
break;
case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
__bootfb_varinfo.fb_flags = FB_MODE_RGB;
__bootfb_varinfo.fb_red.b_length = mb->framebuffer_red_mask_size;
__bootfb_varinfo.fb_red.b_offset = mb->framebuffer_red_field_position;
__bootfb_varinfo.fb_green.b_length = mb->framebuffer_green_mask_size;
__bootfb_varinfo.fb_green.b_offset = mb->framebuffer_green_field_position;
__bootfb_varinfo.fb_blue.b_length = mb->framebuffer_blue_mask_size;
__bootfb_varinfo.fb_blue.b_offset = mb->framebuffer_blue_field_position;
__bootfb_varinfo.fb_alpha.b_length = 0;
__bootfb_varinfo.fb_alpha.b_offset = 0;
break;
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
__bootfb_varinfo.fb_flags = FB_MODE_VGATEXT;
__bootfb_varinfo.fb_xcells = 80;
__bootfb_varinfo.fb_ycells = 25;
break;
default:
break;
}
__bootfb_fixedinfo.fb_baseptr = mb->framebuffer_addr;
}
static void use_uniprocessor_topology(void)
{
cpu_set_available(0);
cpu_set_online(0);
}
int ml_init(uintptr_t arg)
{
multiboot_info_t *mb = (multiboot_info_t *)arg;
init_bootfb(mb);
bootstrap_cpu_init();
vgacon_init();
serialcon_init(115200);
clock_calibrate(500);
print_kernel_banner();
early_vm_init();
printk("video mode: %ux%u", mb->framebuffer_width, mb->framebuffer_height);
e820_scan(PTR32(mb->mmap_addr), mb->mmap_length);
pmap_bootstrap();
#ifdef KEXT_NET_DOORSTUCK_SOCKS_ACPI
acpi_scan_cpu_topology();
#else
use_uniprocessor_topology();
#endif
init_per_cpu_areas();
struct cpu_data *this_cpu = get_this_cpu();
memset(this_cpu, 0x0, sizeof *this_cpu);
this_cpu->c_flags = CPU_ONLINE;
this_cpu->c_id = this_cpu();
g_bootstrap_cpu.c_data = this_cpu;
put_cpu(this_cpu);
struct vm_zone_descriptor vm_zones[] = {
{ .zd_id = VM_ZONE_DMA, .zd_node = 0, .zd_name = "dma", .zd_base = 0x00, .zd_limit = 0xffffff },
{ .zd_id = VM_ZONE_NORMAL, .zd_node = 0, .zd_name = "normal", .zd_base = 0x1000000, .zd_limit = UINTPTR_MAX },
};
vm_bootstrap(vm_zones, sizeof vm_zones / sizeof vm_zones[0]);
object_bootstrap();
init_kernel_kext();
sched_init();
device_init();
#ifdef KEXT_NET_DOORSTUCK_SOCKS_ACPI
acpi_init();
#endif
ml_int_enable();
return 0;
}
const struct framebuffer_varinfo *bootfb_varinfo(void)
{
return &__bootfb_varinfo;
}
const struct framebuffer_fixedinfo *bootfb_fixedinfo(void)
{
return &__bootfb_fixedinfo;
}