2018-01-26 08:43:22 +00:00
|
|
|
|
|
|
|
#include "type.h"
|
|
|
|
#include "hal/mem.h"
|
|
|
|
#include "hal/cpu.h"
|
|
|
|
#include "lib/salloc.h"
|
|
|
|
#include "hal/intr.h"
|
2016-07-09 03:01:33 +00:00
|
|
|
|
2016-10-17 06:05:34 +00:00
|
|
|
static uint8_t _gdts[HAL_CORE_COUNT][GDT_ENTRY_NUM * GDT_ENTRY_SIZE];
|
2016-07-09 03:01:33 +00:00
|
|
|
static hal_gdt_ptr_t _gdt_ptrs[HAL_CORE_COUNT];
|
2015-02-04 07:55:38 +00:00
|
|
|
|
2016-05-22 08:24:08 +00:00
|
|
|
#define KERNEL_HEAP_SIZE 8192
|
2016-05-16 07:34:41 +00:00
|
|
|
|
|
|
|
char kernel_heap[KERNEL_HEAP_SIZE];
|
|
|
|
|
2018-02-08 19:51:29 +00:00
|
|
|
/**
|
|
|
|
* helper for boot.asm, not open to C headers
|
|
|
|
* @param k_start kernel start paddr
|
|
|
|
* @param k_end kernel end paddr
|
|
|
|
* @param multiboot_info multibootinfo paddr
|
|
|
|
* @param pt_base page table base paddr
|
|
|
|
* @param pt_end page table entry paddr
|
|
|
|
*/
|
|
|
|
void KABI hal_write_initial_page_table(void* k_start, void* k_end, void* multiboot_info, void* pt_base, void* pt_end)
|
|
|
|
{
|
|
|
|
uint32_t pt_num = 0;
|
|
|
|
uint32_t pd_num = 0;
|
|
|
|
uint32_t pdpt_num = 0;
|
|
|
|
uint32_t pml4_num = 0;
|
|
|
|
|
|
|
|
// calculate the number of page tables required:
|
|
|
|
uint64_t k_size = (uintptr_t)k_start - (uintptr_t)k_end;
|
|
|
|
//
|
|
|
|
uint32_t m_size = *(uint32_t *)multiboot_info;
|
|
|
|
|
|
|
|
|
|
|
|
// construct recursive mapping with the first page table
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KABI hal_write_pt(void *const base, uintptr_t const p_addr, uint64_t const attr)
|
2015-02-01 22:14:44 +00:00
|
|
|
{
|
2015-11-14 22:53:30 +00:00
|
|
|
if (base == NULL)
|
2015-02-01 22:14:44 +00:00
|
|
|
return;
|
2015-02-04 07:55:38 +00:00
|
|
|
uint64_t entry = (p_addr & 0xFFFFFFFFFF000) | attr;
|
2015-11-14 22:53:30 +00:00
|
|
|
((uint8_t *) base)[0] = (uint8_t) (entry & 0xFF);
|
|
|
|
((uint8_t *) base)[1] = (uint8_t) ((entry >> 8) & 0xFF);
|
|
|
|
((uint8_t *) base)[2] = (uint8_t) ((entry >> 16) & 0xFF);
|
|
|
|
((uint8_t *) base)[3] = (uint8_t) ((entry >> 24) & 0xFF);
|
|
|
|
((uint8_t *) base)[4] = (uint8_t) ((entry >> 32) & 0xFF);
|
|
|
|
((uint8_t *) base)[5] = (uint8_t) ((entry >> 40) & 0xFF);
|
|
|
|
((uint8_t *) base)[6] = (uint8_t) ((entry >> 48) & 0xFF);
|
|
|
|
((uint8_t *) base)[7] = (uint8_t) ((entry >> 56) & 0xFF);
|
2015-02-01 22:14:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-08 19:51:29 +00:00
|
|
|
void KABI hal_write_pd(void *const base, uintptr_t const pt_addr, uint64_t const attr)
|
2015-02-01 22:14:44 +00:00
|
|
|
{
|
2015-11-14 22:53:30 +00:00
|
|
|
if (base == NULL)
|
2015-02-01 22:14:44 +00:00
|
|
|
return;
|
2015-02-04 07:55:38 +00:00
|
|
|
uint64_t entry = (pt_addr & 0xFFFFFFFFFF000) | attr;
|
2015-11-14 22:53:30 +00:00
|
|
|
((uint8_t *) base)[0] = (uint8_t) (entry & 0xFF);
|
|
|
|
((uint8_t *) base)[1] = (uint8_t) ((entry >> 8) & 0xFF);
|
|
|
|
((uint8_t *) base)[2] = (uint8_t) ((entry >> 16) & 0xFF);
|
|
|
|
((uint8_t *) base)[3] = (uint8_t) ((entry >> 24) & 0xFF);
|
|
|
|
((uint8_t *) base)[4] = (uint8_t) ((entry >> 32) & 0xFF);
|
|
|
|
((uint8_t *) base)[5] = (uint8_t) ((entry >> 40) & 0xFF);
|
|
|
|
((uint8_t *) base)[6] = (uint8_t) ((entry >> 48) & 0xFF);
|
|
|
|
((uint8_t *) base)[7] = (uint8_t) ((entry >> 56) & 0xFF);
|
2015-02-01 22:14:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-08 19:51:29 +00:00
|
|
|
void KABI hal_write_pdpt(void *const base, uintptr_t const pd_addr, uint64_t const attr)
|
2015-02-01 22:14:44 +00:00
|
|
|
{
|
2015-11-14 22:53:30 +00:00
|
|
|
if (base == NULL)
|
2015-02-01 22:14:44 +00:00
|
|
|
return;
|
2015-02-04 07:55:38 +00:00
|
|
|
uint64_t entry = (pd_addr & 0xFFFFFFFFFF000) | attr;
|
2015-11-14 22:53:30 +00:00
|
|
|
((uint8_t *) base)[0] = (uint8_t) (entry & 0xFF);
|
|
|
|
((uint8_t *) base)[1] = (uint8_t) ((entry >> 8) & 0xFF);
|
|
|
|
((uint8_t *) base)[2] = (uint8_t) ((entry >> 16) & 0xFF);
|
|
|
|
((uint8_t *) base)[3] = (uint8_t) ((entry >> 24) & 0xFF);
|
|
|
|
((uint8_t *) base)[4] = (uint8_t) ((entry >> 32) & 0xFF);
|
|
|
|
((uint8_t *) base)[5] = (uint8_t) ((entry >> 40) & 0xFF);
|
|
|
|
((uint8_t *) base)[6] = (uint8_t) ((entry >> 48) & 0xFF);
|
|
|
|
((uint8_t *) base)[7] = (uint8_t) ((entry >> 56) & 0xFF);
|
2015-02-01 22:14:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-08 19:51:29 +00:00
|
|
|
void KABI hal_write_pml4(void *const base, uintptr_t const pdpt_addr, uint64_t const attr)
|
2015-02-01 22:14:44 +00:00
|
|
|
{
|
2015-11-14 22:53:30 +00:00
|
|
|
if (base == NULL)
|
2015-02-01 22:14:44 +00:00
|
|
|
return;
|
2015-02-04 07:55:38 +00:00
|
|
|
uint64_t const entry = (pdpt_addr & 0xFFFFFFFFFF000) | attr;
|
2015-11-14 22:53:30 +00:00
|
|
|
((uint8_t *) base)[0] = (uint8_t) (entry & 0xFF);
|
|
|
|
((uint8_t *) base)[1] = (uint8_t) ((entry >> 8) & 0xFF);
|
|
|
|
((uint8_t *) base)[2] = (uint8_t) ((entry >> 16) & 0xFF);
|
|
|
|
((uint8_t *) base)[3] = (uint8_t) ((entry >> 24) & 0xFF);
|
|
|
|
((uint8_t *) base)[4] = (uint8_t) ((entry >> 32) & 0xFF);
|
|
|
|
((uint8_t *) base)[5] = (uint8_t) ((entry >> 40) & 0xFF);
|
|
|
|
((uint8_t *) base)[6] = (uint8_t) ((entry >> 48) & 0xFF);
|
|
|
|
((uint8_t *) base)[7] = (uint8_t) ((entry >> 56) & 0xFF);
|
2015-02-01 22:14:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-02-01 03:26:08 +00:00
|
|
|
void KABI hal_write_segment_descriptor(void *const gdt, uint32_t const base, uint32_t const limit,
|
2016-05-23 03:19:56 +00:00
|
|
|
uint64_t const attr)
|
2015-02-01 22:14:44 +00:00
|
|
|
{
|
2015-02-04 07:55:38 +00:00
|
|
|
if (gdt == NULL)
|
|
|
|
return;
|
2015-11-14 22:53:30 +00:00
|
|
|
uint64_t const seg_desc = (((uint64_t) base & 0xFFFF) << 16) | ((((uint64_t) base >> 16) & 0xFF) << 32) |
|
|
|
|
((((uint64_t) base >> 24) & 0xFF) << 56) | ((uint64_t) limit & 0xFFFF) |
|
|
|
|
((((uint64_t) limit >> 16) & 0xF) << 48) | attr;
|
|
|
|
((uint8_t *) gdt)[0] = (uint8_t) (seg_desc & 0xFF);
|
|
|
|
((uint8_t *) gdt)[1] = (uint8_t) ((seg_desc >> 8) & 0xFF);
|
|
|
|
((uint8_t *) gdt)[2] = (uint8_t) ((seg_desc >> 16) & 0xFF);
|
|
|
|
((uint8_t *) gdt)[3] = (uint8_t) ((seg_desc >> 24) & 0xFF);
|
|
|
|
((uint8_t *) gdt)[4] = (uint8_t) ((seg_desc >> 32) & 0xFF);
|
|
|
|
((uint8_t *) gdt)[5] = (uint8_t) ((seg_desc >> 40) & 0xFF);
|
|
|
|
((uint8_t *) gdt)[6] = (uint8_t) ((seg_desc >> 48) & 0xFF);
|
|
|
|
((uint8_t *) gdt)[7] = (uint8_t) ((seg_desc >> 56) & 0xFF);
|
2015-02-04 07:55:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2015-09-02 21:37:15 +00:00
|
|
|
|
2017-02-01 03:26:08 +00:00
|
|
|
void *KABI halloc(uint32_t size)
|
2015-09-02 21:37:15 +00:00
|
|
|
{
|
2017-02-01 03:26:08 +00:00
|
|
|
return lb_salloc(kernel_heap, size);
|
2016-05-17 19:03:18 +00:00
|
|
|
}
|
2015-09-02 21:37:15 +00:00
|
|
|
|
2017-02-01 03:26:08 +00:00
|
|
|
void KABI hfree(void *ptr)
|
2015-02-08 08:18:22 +00:00
|
|
|
{
|
2017-02-01 03:26:08 +00:00
|
|
|
lb_sfree(kernel_heap, ptr);
|
2016-05-22 01:54:29 +00:00
|
|
|
return;
|
2015-03-16 02:02:45 +00:00
|
|
|
}
|
|
|
|
|
2018-02-07 05:42:59 +00:00
|
|
|
static void KABI _hal_init_gdt(void)
|
2016-07-09 03:01:33 +00:00
|
|
|
{
|
|
|
|
uint32_t coreid = hal_get_core_id();
|
|
|
|
// get gdt ready
|
|
|
|
hal_write_segment_descriptor((void *) &_gdts[coreid][0], 0, 0, 0);
|
|
|
|
hal_write_segment_descriptor((void *) &_gdts[coreid][8], 0, 0,
|
|
|
|
SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X);
|
|
|
|
hal_write_segment_descriptor((void *) &_gdts[coreid][16], 0, 0,
|
|
|
|
SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW);
|
|
|
|
hal_write_segment_descriptor((void *) &_gdts[coreid][24], 0, 0,
|
|
|
|
SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X);
|
|
|
|
hal_write_segment_descriptor((void *) &_gdts[coreid][32], 0, 0,
|
|
|
|
SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW);
|
|
|
|
|
|
|
|
hal_write_segment_descriptor((void *) &_gdts[coreid][40], 0, 0xFFFFF,
|
|
|
|
SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS |
|
|
|
|
SEG_TYPE_CODE_X);
|
|
|
|
hal_write_segment_descriptor((void *) &_gdts[coreid][48], 0, 0xFFFFF,
|
|
|
|
SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS |
|
|
|
|
SEG_TYPE_DATA_RW);
|
|
|
|
hal_write_segment_descriptor((void *) &_gdts[coreid][56], 0, 0xFFFFF,
|
|
|
|
SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS |
|
|
|
|
SEG_TYPE_CODE_X);
|
|
|
|
hal_write_segment_descriptor((void *) &_gdts[coreid][64], 0, 0xFFFFF,
|
|
|
|
SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS |
|
|
|
|
SEG_TYPE_DATA_RW);
|
|
|
|
_gdt_ptrs[coreid].base = (uint64_t) &_gdts[coreid];
|
|
|
|
_gdt_ptrs[coreid].limit = GDT_ENTRY_NUM * GDT_ENTRY_SIZE - 1;
|
|
|
|
hal_flush_gdt(&_gdt_ptrs[coreid], seg_selector(1, 0), seg_selector(2, 0));
|
2018-02-07 05:42:59 +00:00
|
|
|
}
|
2016-07-09 03:01:33 +00:00
|
|
|
|
2017-02-01 03:26:08 +00:00
|
|
|
void KABI hal_mem_init()
|
2015-03-16 02:02:45 +00:00
|
|
|
{
|
2016-07-09 03:01:33 +00:00
|
|
|
_hal_init_gdt();
|
2017-02-01 03:26:08 +00:00
|
|
|
lb_salloc_init(kernel_heap, KERNEL_HEAP_SIZE);
|
2015-03-16 02:02:45 +00:00
|
|
|
return;
|
2016-05-22 01:54:29 +00:00
|
|
|
}
|