diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 4551edc1..1378b660 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -264,7 +264,7 @@ size_t map_region(size_t viraddr, size_t phyaddr, uint32_t npages, uint32_t flag size_t index, i; size_t ret; - if (BUILTIN_EXPECT(!task || !task->pgd || !phyaddr, 0)) + if (BUILTIN_EXPECT(!task || !task->pgd, 0)) return 0; if (BUILTIN_EXPECT(!paging_enabled && (viraddr != phyaddr), 0)) @@ -667,6 +667,14 @@ int arch_paging_init(void) npages++; map_region((size_t)&kernel_start, (size_t)&kernel_start, npages, MAP_KERNEL_SPACE); +#if MAX_CORES > 1 + // Reserve page for smp boot code + if (!map_region(SMP_SETUP_ADDR, SMP_SETUP_ADDR, 1, MAP_KERNEL_SPACE|MAP_NO_CACHE)) { + kputs("could not reserve page for smp boot code\n"); + return -ENOMEM; + } +#endif + #ifdef CONFIG_VGA // map the video memory into the kernel space map_region(VIDEO_MEM_ADDR, VIDEO_MEM_ADDR, 1, MAP_KERNEL_SPACE|MAP_NO_CACHE); diff --git a/include/metalsvm/config.h.example b/include/metalsvm/config.h.example index a9e94864..f4582d8d 100644 --- a/include/metalsvm/config.h.example +++ b/include/metalsvm/config.h.example @@ -40,6 +40,7 @@ extern "C" { #define INT_SYSCALL 0x80 #define KERNEL_SPACE (1*1024*1024*1024) #define VIDEO_MEM_ADDR 0xB8000 // the video memora address +#define SMP_SETUP_ADDR 0x07000 #define BYTE_ORDER LITTLE_ENDIAN diff --git a/mm/memory.c b/mm/memory.c index 11f6fdce..1739d894 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -206,6 +206,12 @@ int mmu_init(void) if ((size_t) &kernel_end & (PAGE_SIZE-1)) alloc_start++; +#if MAX_CORES > 1 + // reserve physical page for SMP boot code + page_set_mark(SMP_SETUP_ADDR >> PAGE_SHIFT); + atomic_int32_add(&total_allocated_pages, 1); + atomic_int32_sub(&total_available_pages, 1); +#endif ret = paging_init(); #ifdef CONFIG_ROCKCREEK