Changeset e386cbf in mainline
- Timestamp:
- 2006-08-01T15:58:32Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e12ccc5
- Parents:
- b3e8c90
- Location:
- kernel/arch/sparc64
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc64/include/arch.h
rb3e8c90 re386cbf 36 36 #define __sparc64_ARCH_H__ 37 37 38 #include <arch/types.h>39 40 extern void take_over_tlb_and_tt(uintptr_t base);41 42 38 #endif 43 39 -
kernel/arch/sparc64/include/boot/boot.h
rb3e8c90 re386cbf 40 40 #define LMA VMA 41 41 42 #ifndef __ASM__ 42 43 #ifndef __LINKER__ 43 44 … … 92 93 93 94 #endif 95 #endif 94 96 95 97 #endif -
kernel/arch/sparc64/include/mm/mmu.h
rb3e8c90 re386cbf 104 104 typedef union lsu_cr_reg lsu_cr_reg_t; 105 105 106 #endif /* ! __ASM__ */106 #endif /* !def __ASM__ */ 107 107 108 108 #endif -
kernel/arch/sparc64/include/mm/tlb.h
rb3e8c90 re386cbf 36 36 #define __sparc64_TLB_H__ 37 37 38 39 #define ITLB_ENTRY_COUNT 64 40 #define DTLB_ENTRY_COUNT 64 41 42 #define MEM_CONTEXT_KERNEL 0 43 #define MEM_CONTEXT_TEMP 1 44 45 /** Page sizes. */ 46 #define PAGESIZE_8K 0 47 #define PAGESIZE_64K 1 48 #define PAGESIZE_512K 2 49 #define PAGESIZE_4M 3 50 51 /** Bit width of the TLB-locked portion of kernel address space. */ 52 #define KERNEL_PAGE_WIDTH 22 /* 4M */ 53 54 /* TLB Demap Operation types. */ 55 #define TLB_DEMAP_PAGE 0 56 #define TLB_DEMAP_CONTEXT 1 57 58 #define TLB_DEMAP_TYPE_SHIFT 6 59 60 /* TLB Demap Operation Context register encodings. */ 61 #define TLB_DEMAP_PRIMARY 0 62 #define TLB_DEMAP_SECONDARY 1 63 #define TLB_DEMAP_NUCLEUS 2 64 65 #define TLB_DEMAP_CONTEXT_SHIFT 4 66 67 /* TLB Tag Access shifts */ 68 #define TLB_TAG_ACCESS_CONTEXT_SHIFT 0 69 #define TLB_TAG_ACCESS_VPN_SHIFT 13 70 71 #ifndef __ASM__ 72 38 73 #include <arch/mm/tte.h> 39 74 #include <arch/mm/mmu.h> … … 43 78 #include <arch/types.h> 44 79 #include <typedefs.h> 45 46 #define ITLB_ENTRY_COUNT 6447 #define DTLB_ENTRY_COUNT 6448 49 /** Page sizes. */50 #define PAGESIZE_8K 051 #define PAGESIZE_64K 152 #define PAGESIZE_512K 253 #define PAGESIZE_4M 354 55 /** Bit width of the TLB-locked portion of kernel address space. */56 #define KERNEL_PAGE_WIDTH 22 /* 4M */57 80 58 81 union tlb_context_reg { … … 91 114 typedef union tlb_tag_read_reg tlb_tag_access_reg_t; 92 115 93 /** TLB Demap Operation types. */94 #define TLB_DEMAP_PAGE 095 #define TLB_DEMAP_CONTEXT 196 97 /** TLB Demap Operation Context register encodings. */98 #define TLB_DEMAP_PRIMARY 099 #define TLB_DEMAP_SECONDARY 1100 #define TLB_DEMAP_NUCLEUS 2101 116 102 117 /** TLB Demap Operation Address. */ … … 385 400 da.vpn = pg.vpn; 386 401 387 asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); 402 asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the address within the ASI */ 388 403 flush(); 389 404 } … … 407 422 da.vpn = pg.vpn; 408 423 409 asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); 424 asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the address within the ASI */ 410 425 membar(); 411 426 } … … 417 432 extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable); 418 433 434 #endif /* !def __ASM__ */ 435 419 436 #endif 420 437 -
kernel/arch/sparc64/include/mm/tte.h
rb3e8c90 re386cbf 35 35 #ifndef __sparc64_TTE_H__ 36 36 #define __sparc64_TTE_H__ 37 38 #define TTE_G (1<<0) 39 #define TTE_W (1<<1) 40 #define TTE_P (1<<2) 41 #define TTE_E (1<<3) 42 #define TTE_CV (1<<4) 43 #define TTE_CP (1<<5) 44 #define TTE_L (1<<6) 45 46 #define TTE_V_SHIFT 63 47 #define TTE_SIZE_SHIFT 61 48 49 #ifndef __ASM__ 37 50 38 51 #include <arch/types.h> … … 76 89 typedef union tte_data tte_data_t; 77 90 91 #endif /* !def __ASM__ */ 92 78 93 #endif 79 94 -
kernel/arch/sparc64/include/trap/trap.h
rb3e8c90 re386cbf 36 36 #define __sparc64_TRAP_H__ 37 37 38 #include <arch/trap/trap_table.h>39 #include <arch/asm.h>40 41 /** Switch to in-kernel trap table. */42 static inline void trap_switch_trap_table(void)43 {44 /* Point TBA to kernel trap table. */45 tba_write((uint64_t) trap_table);46 }47 48 38 extern void trap_init(void); 49 39 -
kernel/arch/sparc64/src/sparc64.c
rb3e8c90 re386cbf 92 92 } 93 93 94 /** Take over TLB and trap table.95 *96 * Initialize ITLB and DTLB and switch to kernel97 * trap table.98 *99 * First, demap context 0 and install the100 * global 4M locked kernel mapping.101 *102 * Second, prepare a temporary IMMU mapping in103 * context 1, switch to it, demap context 0,104 * install the global 4M locked kernel mapping105 * in context 0 and switch back to context 0.106 *107 * @param base Base address that will be hardwired in both TLBs.108 */109 void take_over_tlb_and_tt(uintptr_t base)110 {111 tlb_tag_access_reg_t tag;112 tlb_data_t data;113 frame_address_t fr;114 page_address_t pg;115 116 /*117 * Switch to the kernel trap table.118 */119 trap_switch_trap_table();120 121 fr.address = base;122 pg.address = base;123 124 /*125 * We do identity mapping of 4M-page at 4M.126 */127 tag.value = 0;128 tag.context = 0;129 tag.vpn = pg.vpn;130 131 data.value = 0;132 data.v = true;133 data.size = PAGESIZE_4M;134 data.pfn = fr.pfn;135 data.l = true;136 data.cp = 1;137 data.cv = 0;138 data.p = true;139 data.w = true;140 data.g = true;141 142 /*143 * Straightforwardly demap DMUU context 0,144 * and replace it with the locked kernel mapping.145 */146 dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);147 dtlb_tag_access_write(tag.value);148 dtlb_data_in_write(data.value);149 150 /*151 * Install kernel code mapping in context 1152 * and switch to it.153 */154 tag.context = 1;155 data.g = false;156 itlb_tag_access_write(tag.value);157 itlb_data_in_write(data.value);158 mmu_primary_context_write(1);159 160 /*161 * Demap old context 0.162 */163 itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);164 165 /*166 * Install the locked kernel mapping in context 0167 * and switch to it.168 */169 tag.context = 0;170 data.g = true;171 itlb_tag_access_write(tag.value);172 itlb_data_in_write(data.value);173 mmu_primary_context_write(0);174 }175 176 94 /** @} 177 95 */ -
kernel/arch/sparc64/src/start.S
rb3e8c90 re386cbf 28 28 29 29 #include <arch/regdef.h> 30 #include <arch/boot/boot.h> 31 32 #include <arch/mm/mmu.h> 33 #include <arch/mm/tlb.h> 34 #include <arch/mm/tte.h> 30 35 31 36 .register %g2, #scratch … … 53 58 .global kernel_image_start 54 59 kernel_image_start: 60 61 /* 62 * Setup basic runtime environment. 63 */ 64 55 65 flushw ! flush all but the active register window 56 57 /* 58 * Disable interrupts and disable 32-bit address masking. 59 */ 60 rdpr %pstate, %l0 61 and %l0, ~(PSTATE_AM_BIT|PSTATE_IE_BIT), %l0 62 wrpr %l0, 0, %pstate 66 wrpr %g0, 0, %tl ! TL = 0, primary context register is used 67 68 ! Disable interrupts and disable 32-bit address masking. 69 rdpr %pstate, %g1 70 and %g1, ~(PSTATE_AM_BIT|PSTATE_IE_BIT), %g1 71 wrpr %g1, 0, %pstate 72 73 wrpr %r0, 0, %pil ! intialize %pil 63 74 64 75 /* … … 72 83 nop 73 84 74 set kernel_image_start, %o0 75 /* 76 * Take over control of MMU. 77 * 78 * First, take over DMMU for which we don't need to issue 79 * any FLUSH instructions. Because of that, we can 80 * demap the old DTLB pretty straightforwardly. 81 */ 82 call take_over_tlb_and_tt 83 nop 84 85 wrpr %r0, 0, %pil 86 85 /* 86 * Switch to kernel trap table. 87 */ 88 set trap_table, %g1 89 wrpr %g1, 0, %tba 90 91 /* 92 * Take over the DMMU by installing global locked 93 * TTE entry identically mapping the first 4M 94 * of memory. 95 * 96 * In case of DMMU, no FLUSH instructions need to be 97 * issued. Because of that, the old DTLB contents can 98 * be demapped pretty straightforwardly and without 99 * causing any traps. 100 */ 101 102 wr %g0, ASI_DMMU, %asi 103 104 #define SET_TLB_DEMAP_CMD(r1, context_id) \ 105 set (TLB_DEMAP_CONTEXT<<TLB_DEMAP_TYPE_SHIFT) | (context_id<<TLB_DEMAP_CONTEXT_SHIFT), %r1 106 107 ! demap context 0 108 SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS) 109 stxa %g0, [%g1] ASI_DMMU_DEMAP 110 membar #Sync 111 112 #define SET_TLB_TAG(r1, context) \ 113 set VMA | (context<<TLB_TAG_ACCESS_CONTEXT_SHIFT), %r1 114 115 ! write DTLB tag 116 SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL) 117 stxa %g1, [VA_DMMU_TAG_ACCESS] %asi 118 membar #Sync 119 120 #define SET_TLB_DATA(r1, r2, imm) \ 121 set TTE_L | TTE_CP | TTE_P | TTE_W | LMA | imm, %r1; \ 122 set PAGESIZE_4M, %r2; \ 123 sllx %r2, TTE_SIZE_SHIFT, %r2; \ 124 or %r1, %r2, %r1; \ 125 set 1, %r2; \ 126 sllx %r2, TTE_V_SHIFT, %r2; \ 127 or %r1, %r2, %r1; 128 129 ! write DTLB data and install the kernel mapping 130 SET_TLB_DATA(g1, g2, TTE_G) 131 stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG 132 membar #Sync 133 134 /* 135 * Now is time to take over the IMMU. 136 * Unfortunatelly, it cannot be done as easily as the DMMU, 137 * because the IMMU is mapping the code it executes. 138 * 139 * [ Note that brave experiments with disabling the IMMU 140 * and using the DMMU approach failed after a dozen 141 * of desparate days with only little success. ] 142 * 143 * The approach used here is inspired from OpenBSD. 144 * First, the kernel creates IMMU mapping for itself 145 * in context 1 (MEM_CONTEXT_TEMP) and switches to 146 * it. Context 0 (MEM_CONTEXT_KERNEL) can be demapped 147 * afterwards and replaced with the kernel permanent 148 * mapping. Finally, the kernel switches back to 149 * context 0 and demaps context 1. 150 * 151 * Moreover, the IMMU requires use of the FLUSH instructions. 152 * But that is OK because we always use operands with 153 * addresses already mapped by the taken over DTLB. 154 */ 155 156 set kernel_image_start, %g7 157 158 ! write ITLB tag of context 1 159 SET_TLB_TAG(g1, MEM_CONTEXT_TEMP) 160 set VA_DMMU_TAG_ACCESS, %g2 161 stxa %g1, [%g2] ASI_IMMU 162 flush %g7 163 164 ! write ITLB data and install the temporary mapping in context 1 165 SET_TLB_DATA(g1, g2, 0) ! use non-global mapping 166 stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG 167 flush %g7 168 169 ! switch to context 1 170 set MEM_CONTEXT_TEMP, %g1 171 stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!! 172 flush %g7 173 174 ! demap context 0 175 SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS) 176 stxa %g0, [%g1] ASI_IMMU_DEMAP 177 flush %g7 178 179 ! write ITLB tag of context 0 180 SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL) 181 set VA_DMMU_TAG_ACCESS, %g2 182 stxa %g1, [%g2] ASI_IMMU 183 flush %g7 184 185 ! write ITLB data and install the permanent kernel mapping in context 0 186 SET_TLB_DATA(g1, g2, 0) ! use non-global mapping 187 stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG 188 flush %g7 189 190 ! switch to context 0 191 stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!! 192 flush %g7 193 194 ! ensure nucleus mapping 195 wrpr %g0, 1, %tl 196 197 ! set context 1 in the primary context register 198 set MEM_CONTEXT_TEMP, %g1 199 stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!! 200 flush %g7 201 202 ! demap context 1 203 SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_PRIMARY) 204 stxa %g0, [%g1] ASI_IMMU_DEMAP 205 flush %g7 206 207 ! set context 0 in the primary context register 208 stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!! 209 flush %g7 210 211 ! set TL back to 0 212 wrpr %g0, 0, %tl 213 87 214 call main_bsp 88 215 nop
Note:
See TracChangeset
for help on using the changeset viewer.