157 lines
4.8 KiB
C
157 lines
4.8 KiB
C
/*
|
|
Copyright 2025 Kamil Kowalczyk
|
|
|
|
Redistribution and use in source and binary forms, with or
|
|
without modification, are permitted provided that the following
|
|
conditions are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
3. Neither the name of the copyright holder nor the names of its
|
|
contributors may be used to endorse or promote products derived from
|
|
this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
“AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <libk/types.h>
|
|
#include <libk/util.h>
|
|
#include <libk/string.h>
|
|
#include <sys/cpu.h>
|
|
#include <sys/multiboot.h>
|
|
#include <sys/serialdbg.h>
|
|
#include <sys/mm.h>
|
|
#include <sys/pic.h>
|
|
#include <sys/pit.h>
|
|
#include <sys/isr.h>
|
|
#include <acpi/acpi.h>
|
|
#include <mm/pmm.h>
|
|
#include <mm/bba.h>
|
|
#include <mm/liballoc.h>
|
|
#include <mm/mregmap.h>
|
|
#include <ramdisk/tar.h>
|
|
#include <config.h>
|
|
|
|
extern byte_t __kernel_end;
|
|
|
|
static void dump_multiboot_header(void) {
|
|
struct multiboot *mb = multiboot_get();
|
|
|
|
dbgf("multiboot=%p, flags=%08x\n", mb, mb->flags);
|
|
dbgf("multiboot sanity dump:\n");
|
|
dbgf("flags=%08x, mem_lower=%08x, mem_upper=%08x\n",
|
|
mb->flags, mb->mem_lower, mb->mem_upper);
|
|
}
|
|
|
|
static void mregmap_init1(void) {
|
|
struct multiboot *mb = multiboot_get();
|
|
|
|
mregmap_init();
|
|
|
|
struct multiboot_mmap_entry *mmap;
|
|
usize_t i = 0;
|
|
for (mmap = (struct multiboot_mmap_entry *)(mb->mmap_addr + VIRT_BASE);
|
|
(uptr_t)mmap < (mb->mmap_addr + VIRT_BASE + mb->mmap_length);
|
|
mmap = (struct multiboot_mmap_entry *)((uptr_t)mmap + mmap->size + sizeof(mmap->size))) {
|
|
dbgf("mmap entry: size=%08x, addr=%08x, len=%08x, type=%u\n",
|
|
mmap->size, mmap->addr1, mmap->len1, mmap->type);
|
|
|
|
/* always skip the first memory map region, because we can't use it */
|
|
if (i == 0) {
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
static int type_map[] = {
|
|
[1] = MREG_AVAIL_RAM,
|
|
[2] = MREG_I386_PC_RESERVED,
|
|
[3] = MREG_ACPI,
|
|
[4] = MREG_MEM_HBRNT,
|
|
[5] = MREG_DEFCT_RMOD,
|
|
};
|
|
|
|
struct mreg mreg = {
|
|
.start = (uptr_t)mmap->addr1,
|
|
.size = (usize_t)mmap->len1,
|
|
.type = type_map[mmap->type],
|
|
};
|
|
|
|
mregmap_add_region(&mreg);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
static void ramdisk_init(void) {
|
|
struct multiboot *mb = multiboot_get();
|
|
|
|
/* TODO: for now we assert that the first module is the ramdisk */
|
|
struct multiboot_mod_list *module = (struct multiboot_mod_list *)((uptr_t)mb->mods_addr + VIRT_BASE);
|
|
uptr_t module_start = (uptr_t)module->mod_start + VIRT_BASE;
|
|
usize_t total = tar_parse(module_start);
|
|
dbgf("ramdisk: total=%zu\n", total);
|
|
}
|
|
|
|
static void pmm_init1(void) {
|
|
struct mreg *avail_ram = mregmap_first_avail();
|
|
|
|
usize_t usable_ram_bytes = avail_ram->size;
|
|
dbgf("usable ram = %08x\n", usable_ram_bytes);
|
|
|
|
uptr_t ram_start = ALIGN_UP((uptr_t)&__kernel_end + 0x1000 - VIRT_BASE, 0x1000);
|
|
uptr_t ram_end = ALIGN_DOWN(0x100000 + usable_ram_bytes, 0x1000);
|
|
|
|
usize_t block_size = CFG_I386_PC_PMM_BLOCK_SIZE;
|
|
usize_t block_count = (ram_end - ram_start) / block_size;
|
|
|
|
usize_t pmm_bm_bytes = ALIGN_UP((block_count + 7) / 8, block_size);
|
|
|
|
uptr_t pmm_bm_baseptr = ram_start;
|
|
uptr_t pmm_baseptr = ram_start + pmm_bm_bytes;
|
|
|
|
usize_t remaining_blocks = (ram_end - pmm_baseptr) / block_size;
|
|
|
|
dbgf("ram_start=%p, pmm_bm_baseptr=%p, pmm_baseptr=%p\n",
|
|
ram_start, pmm_bm_baseptr, pmm_baseptr);
|
|
pmm_init(pmm_baseptr, pmm_bm_baseptr, remaining_blocks, block_size);
|
|
}
|
|
|
|
void bootmain(void *mbootptr) {
|
|
multiboot_set((struct multiboot *)((uptr_t)mbootptr + VIRT_BASE));
|
|
|
|
cpu_init();
|
|
|
|
#if CFG_I386_PC_DEBUG == CFG_I386_PC_DEBUG_SERIAL
|
|
serialdbg_init();
|
|
#endif
|
|
dbgf("dbgf() test...\n");
|
|
dbgf("-------------------------------------------------------------\n");
|
|
|
|
dump_multiboot_header();
|
|
mregmap_init1();
|
|
pmm_init1();
|
|
bba_init();
|
|
mm_init();
|
|
acpi_init();
|
|
/* ramdisk_init(); */
|
|
/* pit_init(); */
|
|
|
|
__asm__ volatile("sti");
|
|
|
|
for (;;);
|
|
}
|