Files
mango/arch/x86_64/init.c

172 lines
4.0 KiB
C
Raw Normal View History

#include <arch/e820.h>
#include <arch/pit.h>
2026-02-03 21:28:15 +00:00
#include <arch/serial.h>
#include <arch/vgacon.h>
#include <kernel/arg.h>
#include <kernel/bsp.h>
#include <kernel/clock.h>
#include <kernel/console.h>
#include <kernel/cpu.h>
#include <kernel/init.h>
#include <kernel/libc/stdio.h>
#include <kernel/machine/cpu.h>
#include <kernel/memblock.h>
#include <kernel/object.h>
#include <kernel/percpu.h>
#include <kernel/pmap.h>
#include <kernel/printk.h>
#include <kernel/types.h>
#include <kernel/vm.h>
#define PTR32(x) ((void *)((uintptr_t)(x)))
/* the physical address of the start of the memblock heap.
* this is an arbirary value; the heap can start anywhere in memory.
* any reserved areas of memory (the kernel, bsp, bios data, etc) are
* automatically taken into account.
* HOWEVER, this value will dictate how much physical memory is required for
* the kernel to boot successfully.
* the value of 16MiB (0x1000000) means that all heap allocations will be
* above 16MiB, leaving the area below free for DMA operations.
* this value CAN be reduced all the way to zero to minimise the amount of
* memory required to boot, but this may leave you with no DMA memory available.
*/
#define MEMBLOCK_HEAP_START 0x1000000
2023-02-05 10:50:13 +00:00
static ml_cpu_block g_bootstrap_cpu = {0};
2023-02-05 10:50:13 +00:00
/* 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(uintptr_t reserve_end)
2023-02-05 10:50:13 +00:00
{
uintptr_t alloc_start = VM_KERNEL_VOFFSET + MEMBLOCK_HEAP_START;
2023-02-05 10:50:13 +00:00
/* 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);
2023-02-05 10:50:13 +00:00
memblock_reserve(0x00, reserve_end);
printk("memblock: reserved bios+kernel at [0x%016llx-0x%016llx]",
0,
reserve_end);
2023-02-05 10:50:13 +00:00
}
void early_console_init(void)
{
const char *dest = arg_value("kernel.early-console");
if (!dest) {
2026-02-03 21:28:15 +00:00
dest = "tty0";
}
if (!strcmp(dest, "tty0")) {
/* show log messages on VGA */
2026-02-03 21:28:15 +00:00
vgacon_init();
} else if (!strcmp(dest, "ttyS0")) {
/* write log messages to serial port */
early_serialcon_init(115200);
}
2023-06-08 20:46:43 +01:00
}
2023-06-09 19:31:30 +01:00
static void use_uniprocessor_topology(void)
{
cpu_set_available(0);
cpu_set_online(0);
}
static void find_bsp(multiboot_info_t *mb, struct boot_module *out)
{
memset(out, 0x0, sizeof *out);
printk("modules=%u: %llx", mb->mods_count, mb->mods_addr);
multiboot_module_t *mods = PTR32(mb->mods_addr);
size_t nr_mods = mb->mods_count;
if (nr_mods < 1) {
return;
}
out->mod_base = mods[0].mod_start;
out->mod_size = mods[0].mod_end - mods[0].mod_start;
}
int ml_init(uintptr_t arg)
{
2023-02-05 10:50:13 +00:00
multiboot_info_t *mb = (multiboot_info_t *)arg;
2023-02-07 16:00:45 +00:00
2023-12-27 17:34:59 +00:00
parse_cmdline(PTR32(mb->cmdline));
early_console_init();
2023-06-08 20:46:43 +01:00
bootstrap_cpu_init();
2023-04-28 20:51:51 +01:00
clock_calibrate(500);
2023-02-04 19:19:48 +00:00
print_kernel_banner();
struct boot_module bsp;
find_bsp(mb, &bsp);
bsp_set_location(&bsp);
uintptr_t reserve_end = (uintptr_t)__pend;
if (bsp.mod_base + bsp.mod_size > reserve_end) {
reserve_end = bsp.mod_base + bsp.mod_size;
}
early_vm_init(reserve_end);
2023-02-05 10:50:13 +00:00
e820_scan(PTR32(mb->mmap_addr), mb->mmap_length);
pmap_bootstrap();
2023-06-09 19:31:30 +01:00
use_uniprocessor_topology();
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);
2023-02-09 19:09:07 +00:00
struct vm_zone_descriptor vm_zones[] = {
2026-02-08 11:36:16 +00:00
{
.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,
},
2023-02-07 16:00:45 +00:00
};
vm_bootstrap(vm_zones, sizeof vm_zones / sizeof vm_zones[0]);
object_bootstrap();
sched_init();
pit_start(500);
ml_int_enable();
return 0;
}