1 /* 2 * Copyright 2008-2010, François Revol, revol@free.fr. All rights reserved. 3 * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. 4 * Based on code written by Travis Geiselbrecht for NewOS. 5 * 6 * Distributed under the terms of the MIT License. 7 */ 8 9 10 #include "nextrom.h" 11 #include "mmu.h" 12 13 #include <boot/platform.h> 14 #include <boot/stdio.h> 15 #include <boot/kernel_args.h> 16 #include <boot/stage2.h> 17 #include <arch/cpu.h> 18 #include <arch_kernel.h> 19 #include <kernel.h> 20 21 #include <OS.h> 22 23 #include <string.h> 24 25 #warning TODO: M68K: NEXT: mmu 26 27 //XXX: x86 28 /** The (physical) memory layout of the boot loader is currently as follows: 29 * 0x0500 - 0x10000 protected mode stack 30 * 0x0500 - 0x09000 real mode stack 31 * 0x10000 - ? code (up to ~500 kB) 32 * 0x90000 1st temporary page table (identity maps 0-4 MB) 33 * 0x91000 2nd (4-8 MB) 34 * 0x92000 - 0x92000 further page tables 35 * 0x9e000 - 0xa0000 SMP trampoline code 36 * [0xa0000 - 0x100000 BIOS/ROM/reserved area] 37 * 0x100000 page directory 38 * ... boot loader heap (32 kB) 39 * ... free physical memory 40 * 41 * The first 8 MB are identity mapped (0x0 - 0x0800000); paging is turned 42 * on. The kernel is mapped at 0x80000000, all other stuff mapped by the 43 * loader (kernel args, modules, driver settings, ...) comes after 44 * 0x81000000 which means that there is currently only 1 MB reserved for 45 * the kernel itself (see kMaxKernelSize). 46 */ 47 48 // notes m68k: 49 /** The (physical) memory layout of the boot loader is currently as follows: 50 * 0x0800 - 0x10000 supervisor mode stack (1) XXX: more ? x86 starts at 500 51 * 0x10000 - ? code (up to ~500 kB) 52 * 0x100000 or FAST_RAM_BASE if any: 53 * ... page root directory 54 * ... interrupt vectors (VBR) 55 * ... page directory 56 * ... boot loader heap (32 kB) 57 * ... free physical memory 58 * 0xdNNNNN video buffer usually there, as per v_bas_ad 59 * (=Logbase() but Physbase() is better) 60 * 61 * The first 32 MB (2) are identity mapped (0x0 - 0x1000000); paging 62 * is turned on. The kernel is mapped at 0x80000000, all other stuff 63 * mapped by the loader (kernel args, modules, driver settings, ...) 64 * comes after 0x81000000 which means that there is currently only 65 * 1 MB reserved for the kernel itself (see kMaxKernelSize). 66 * 67 * (1) no need for user stack, we are already in supervisor mode in the 68 * loader. 69 * (2) maps the whole regular ST space; transparent translation registers 70 * have larger granularity anyway. 71 */ 72 #warning M68K: check for Physbase() < ST_RAM_TOP 73 74 #define TRACE_MMU 75 #ifdef TRACE_MMU 76 # define TRACE(x) dprintf x 77 #else 78 # define TRACE(x) ; 79 #endif 80 81 82 // since the page root directory doesn't take a full page (1k) 83 // we stuff some other stuff after it, like the interrupt vectors (1k) 84 #define VBR_PAGE_OFFSET 1024 85 86 static const uint32 kDefaultPageTableFlags = 0x07; // present, user, R/W 87 static const size_t kMaxKernelSize = 0x200000; // 2 MB for the kernel 88 89 // working page directory and page table 90 addr_t gPageRoot = 0; 91 92 static addr_t sNextPhysicalAddress = 0x100000; 93 static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE + kMaxKernelSize; 94 static addr_t sMaxVirtualAddress = KERNEL_LOAD_BASE /*+ 0x400000*/; 95 96 #if 0 97 static addr_t sNextPageTableAddress = 0x90000; 98 static const uint32 kPageTableRegionEnd = 0x9e000; 99 // we need to reserve 2 pages for the SMP trampoline code XXX:no 100 #endif 101 102 103 104 /** This will unmap the allocated chunk of memory from the virtual 105 * address space. It might not actually free memory (as its implementation 106 * is very simple), but it might. 107 */ 108 109 extern "C" void 110 mmu_free(void *virtualAddress, size_t size) 111 { 112 TRACE(("mmu_free(virtualAddress = %p, size: %ld)\n", virtualAddress, size)); 113 } 114 115 116 /** Sets up the final and kernel accessible GDT and IDT tables. 117 * BIOS calls won't work any longer after this function has 118 * been called. 119 */ 120 121 extern "C" void 122 mmu_init_for_kernel(void) 123 { 124 TRACE(("mmu_init_for_kernel\n")); 125 } 126 127 128 extern "C" void 129 mmu_init(void) 130 { 131 TRACE(("mmu_init\n")); 132 } 133 134 135 // #pragma mark - 136 137 138 extern "C" status_t 139 platform_allocate_region(void **_address, size_t size, uint8 protection, 140 bool /*exactAddress*/) 141 { 142 return B_UNSUPPORTED; 143 } 144 145 146 extern "C" status_t 147 platform_free_region(void *address, size_t size) 148 { 149 return B_UNSUPPORTED; 150 } 151 152 153 void 154 platform_release_heap(struct stage2_args *args, void *base) 155 { 156 // It will be freed automatically, since it is in the 157 // identity mapped region, and not stored in the kernel's 158 // page tables. 159 } 160 161 162 status_t 163 platform_init_heap(struct stage2_args *args, void **_base, void **_top) 164 { 165 return B_UNSUPPORTED; 166 } 167 168 169 extern "C" status_t 170 platform_bootloader_address_to_kernel_address(void *address, addr_t *_result) 171 { 172 TRACE(("%s: called\n", __func__)); 173 // next_m68k really doesn't need an address conversion 174 *_result = (addr_t)address; 175 return B_OK; 176 } 177 178 179 extern "C" status_t 180 platform_kernel_address_to_bootloader_address(addr_t address, void **_result) 181 { 182 TRACE(("%s: called\n", __func__)); 183 // next_m68k really doesn't need an address conversion 184 *_result = (void*)address; 185 return B_OK; 186 } 187