1 /* 2 * Copyright 2007-2010, François Revol, revol@free.fr. 3 * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. 4 * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 5 * Distributed under the terms of the MIT License. 6 * 7 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 8 * Distributed under the terms of the NewOS License. 9 */ 10 11 #include <KernelExport.h> 12 #include <kernel.h> 13 #include <vm/vm.h> 14 #include <vm/vm_priv.h> 15 #include <vm/VMAddressSpace.h> 16 #include <int.h> 17 #include <boot/kernel_args.h> 18 #include <arch/vm_translation_map.h> 19 #include <arch/cpu.h> 20 #include <arch_mmu.h> 21 #include <stdlib.h> 22 23 #include "generic_vm_physical_page_mapper.h" 24 //#include "paging/030/M68KPagingMethod030.h" 25 #include "paging/040/M68KPagingMethod040.h" 26 //#include "paging/060/M68KPagingMethod060.h" 27 28 29 #define TRACE_VM_TMAP 30 #ifdef TRACE_VM_TMAP 31 # define TRACE(x...) dprintf(x) 32 #else 33 # define TRACE(x...) ; 34 #endif 35 36 37 /* 38 * Each mmu of the m68k family has its own tricks, registers and opcodes... 39 * so they all have a specific paging method class. 40 */ 41 42 #warning M68K: 060: must *not* have pgtables in copyback cachable mem!!! 43 44 static union { 45 uint64 align; 46 //char m68851[sizeof(M68KPagingMethod851)]; 47 //char m68030[sizeof(M68KPagingMethod030)]; 48 char m68040[sizeof(M68KPagingMethod040)]; 49 // 060 should be identical to 040 except for copyback issue 50 //char m68060[sizeof(M68KPagingMethod060)]; 51 } sPagingMethodBuffer; 52 53 54 #if 0 55 void * 56 m68k_translation_map_get_pgdir(VMTranslationMap *map) 57 { 58 return get_vm_ops()->m68k_translation_map_get_pgdir(map); 59 } 60 #endif 61 62 // #pragma mark - 63 // VM API 64 65 66 status_t 67 arch_vm_translation_map_create_map(bool kernel, VMTranslationMap** _map) 68 { 69 return gM68KPagingMethod->CreateTranslationMap(kernel, _map); 70 } 71 72 73 status_t 74 arch_vm_translation_map_init(kernel_args *args, 75 VMPhysicalPageMapper** _physicalPageMapper) 76 { 77 TRACE("vm_translation_map_init: entry\n"); 78 79 #ifdef TRACE_VM_TMAP 80 TRACE("physical memory ranges:\n"); 81 for (uint32 i = 0; i < args->num_physical_memory_ranges; i++) { 82 phys_addr_t start = args->physical_memory_range[i].start; 83 phys_addr_t end = start + args->physical_memory_range[i].size; 84 TRACE(" %#10" B_PRIxPHYSADDR " - %#10" B_PRIxPHYSADDR "\n", start, 85 end); 86 } 87 88 TRACE("allocated physical ranges:\n"); 89 for (uint32 i = 0; i < args->num_physical_allocated_ranges; i++) { 90 phys_addr_t start = args->physical_allocated_range[i].start; 91 phys_addr_t end = start + args->physical_allocated_range[i].size; 92 TRACE(" %#10" B_PRIxPHYSADDR " - %#10" B_PRIxPHYSADDR "\n", start, 93 end); 94 } 95 96 TRACE("allocated virtual ranges:\n"); 97 for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) { 98 addr_t start = args->virtual_allocated_range[i].start; 99 addr_t end = start + args->virtual_allocated_range[i].size; 100 TRACE(" %#10" B_PRIxADDR " - %#10" B_PRIxADDR "\n", start, end); 101 } 102 #endif 103 switch (arch_mmu_type) { 104 /* 105 case 68030: 106 gM68KPagingMethod = new(&sPagingMethodBuffer) M68KPagingMethod030; 107 break; 108 */ 109 case 68040: 110 gM68KPagingMethod = new(&sPagingMethodBuffer) M68KPagingMethod040; 111 break; 112 /* 113 case 68060: 114 gM68KPagingMethod = new(&sPagingMethodBuffer) M68KPagingMethod060; 115 break; 116 */ 117 default: 118 break; 119 } 120 return gM68KPagingMethod->Init(args, _physicalPageMapper); 121 } 122 123 124 status_t 125 arch_vm_translation_map_init_post_sem(kernel_args *args) 126 { 127 return B_OK; 128 } 129 130 131 status_t 132 arch_vm_translation_map_init_post_area(kernel_args *args) 133 { 134 TRACE("vm_translation_map_init_post_area: entry\n"); 135 136 return gM68KPagingMethod->InitPostArea(args); 137 } 138 139 140 /** Directly maps a page without having knowledge of any kernel structures. 141 * Used only during VM setup. 142 * It currently ignores the "attributes" parameter and sets all pages 143 * read/write. 144 */ 145 status_t 146 arch_vm_translation_map_early_map(kernel_args *args, addr_t va, phys_addr_t pa, 147 uint8 attributes, phys_addr_t (*get_free_page)(kernel_args *)) 148 { 149 TRACE("early_tmap: entry pa 0x%lx va 0x%lx\n", pa, va); 150 151 return gM68KPagingMethod->MapEarly(args, va, pa, attributes, get_free_page); 152 } 153 154 155 // XXX currently assumes this translation map is active 156 /* 157 status_t 158 arch_vm_translation_map_early_query(addr_t va, addr_t *out_physical) 159 { 160 return get_vm_ops()->arch_vm_translation_map_early_query(va, out_physical); 161 } 162 */ 163 164 165 // #pragma mark - 166 167 168 bool 169 arch_vm_translation_map_is_kernel_page_accessible(addr_t virtualAddress, 170 uint32 protection) 171 { 172 return gM68KPagingMethod->IsKernelPageAccessible(virtualAddress, protection); 173 } 174 175