Changeset 6c3106f in mainline
- Timestamp:
- 2011-05-18T17:16:06Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9c757820
- Parents:
- 1182d79
- Location:
- kernel/arch/ppc32
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ppc32/include/interrupt.h
r1182d79 r6c3106f 45 45 #define VECTOR_EXTERNAL 4 46 46 #define VECTOR_DECREMENTER 8 47 #define VECTOR_ITLB_MISS 13 48 #define VECTOR_DTLB_MISS_LOAD 14 49 #define VECTOR_DTLB_MISS_STORE 15 47 50 48 51 extern void start_decrementer(void); -
kernel/arch/ppc32/include/mm/tlb.h
r1182d79 r6c3106f 77 77 extern void pht_init(void); 78 78 extern void pht_refill(unsigned int, istate_t *); 79 80 extern bool pht_refill_real(unsigned int, istate_t *) 81 __attribute__ ((section("K_UNMAPPED_TEXT_START"))); 82 extern void tlb_refill_real(unsigned int, uint32_t, ptehi_t, ptelo_t, 83 istate_t *) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); 79 extern void tlb_refill(unsigned int, istate_t *); 84 80 85 81 #endif -
kernel/arch/ppc32/src/exception.S
r1182d79 r6c3106f 142 142 CONTEXT_STORE 143 143 144 b data_storage 144 li r3, 2 145 b jump_to_kernel 145 146 146 147 .org 0x400 … … 149 150 CONTEXT_STORE 150 151 151 b instruction_storage 152 li r3, 3 153 b jump_to_kernel 152 154 153 155 .org 0x500 … … 227 229 CONTEXT_STORE 228 230 229 b tlb_miss 231 li r3, 13 232 b jump_to_kernel 230 233 231 234 .org 0x1100 … … 234 237 CONTEXT_STORE 235 238 236 b tlb_miss 239 li r3, 14 240 b jump_to_kernel 237 241 238 242 .org 0x1200 … … 241 245 CONTEXT_STORE 242 246 243 b tlb_miss 247 li r3, 15 248 b jump_to_kernel 244 249 245 250 .org 0x4000 246 data_storage:247 li r3, 2248 mr r4, sp249 addi r4, r4, 8250 bl pht_refill_real251 252 cmpwi r3, 0253 bne iret_real254 255 li r3, 2256 b jump_to_kernel257 258 instruction_storage:259 li r3, 3260 mr r4, sp261 addi r4, r4, 8262 bl pht_refill_real263 264 cmpwi r3, 0265 bne iret_real266 267 li r3, 3268 b jump_to_kernel269 270 tlb_miss:271 li r3, 16272 mfspr r4, tlbmiss273 mfspr r5, ptehi274 mfspr r6, ptelo275 mr r7, sp276 addi r7, r7, 20277 278 bl tlb_refill_real279 b iret_real280 281 251 jump_to_kernel: 282 252 lis r12, iret@ha … … 313 283 addis sp, sp, 0x8000 314 284 rfi 315 316 iret_real:317 lwz r0, 8(sp)318 lwz r2, 12(sp)319 lwz r3, 16(sp)320 lwz r4, 20(sp)321 lwz r5, 24(sp)322 lwz r6, 28(sp)323 lwz r7, 32(sp)324 lwz r8, 36(sp)325 lwz r9, 40(sp)326 lwz r10, 44(sp)327 lwz r11, 48(sp)328 lwz r13, 52(sp)329 lwz r14, 56(sp)330 lwz r15, 60(sp)331 lwz r16, 64(sp)332 lwz r17, 68(sp)333 lwz r18, 72(sp)334 lwz r19, 76(sp)335 lwz r20, 80(sp)336 lwz r21, 84(sp)337 lwz r22, 88(sp)338 lwz r23, 92(sp)339 lwz r24, 96(sp)340 lwz r25, 100(sp)341 lwz r26, 104(sp)342 lwz r27, 108(sp)343 lwz r28, 112(sp)344 lwz r29, 116(sp)345 lwz r30, 120(sp)346 lwz r31, 124(sp)347 348 lwz r12, 128(sp)349 mtcr r12350 351 lwz r12, 132(sp)352 mtsrr0 r12353 354 lwz r12, 136(sp)355 mtsrr1 r12356 357 lwz r12, 140(sp)358 mtlr r12359 360 lwz r12, 144(sp)361 mtctr r12362 363 lwz r12, 148(sp)364 mtxer r12365 366 lwz r12, 156(sp)367 lwz sp, 160(sp)368 369 rfi -
kernel/arch/ppc32/src/interrupt.c
r1182d79 r6c3106f 153 153 exc_register(VECTOR_DECREMENTER, "timer", true, 154 154 exception_decrementer); 155 exc_register(VECTOR_ITLB_MISS, "itlb_miss", true, 156 tlb_refill); 157 exc_register(VECTOR_DTLB_MISS_LOAD, "dtlb_miss_load", true, 158 tlb_refill); 159 exc_register(VECTOR_DTLB_MISS_STORE, "dtlb_miss_store", true, 160 tlb_refill); 155 161 } 156 162 -
kernel/arch/ppc32/src/mm/tlb.c
r1182d79 r6c3106f 44 44 #include <symtab.h> 45 45 46 static unsigned int seed = 10; 47 static unsigned int seed_real 48 __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42; 46 static unsigned int seed = 42; 49 47 50 48 /** Try to find PTE for faulting address … … 251 249 } 252 250 253 /** Process Instruction/Data Storage Exception in Real Mode 254 * 255 * @param n Exception vector number. 256 * @param istate Interrupted register context. 257 * 258 */ 259 bool pht_refill_real(unsigned int n, istate_t *istate) 260 { 261 uintptr_t badvaddr; 262 263 if (n == VECTOR_DATA_STORAGE) 264 badvaddr = istate->dar; 265 else 266 badvaddr = istate->pc; 267 268 uint32_t physmem = physmem_top(); 269 270 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) 271 return false; 272 273 uint32_t page = (badvaddr >> 12) & 0xffff; 274 uint32_t api = (badvaddr >> 22) & 0x3f; 275 276 uint32_t vsid = sr_get(badvaddr); 277 uint32_t sdr1 = sdr1_get(); 278 279 // FIXME: compute size of PHT exactly 280 phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000); 281 282 /* Primary hash (xor) */ 283 uint32_t h = 0; 284 uint32_t hash = vsid ^ page; 285 uint32_t base = (hash & 0x3ff) << 3; 286 uint32_t i; 287 bool found = false; 288 289 /* Find colliding PTE in PTEG */ 290 for (i = 0; i < 8; i++) { 291 if ((phte_real[base + i].v) 292 && (phte_real[base + i].vsid == vsid) 293 && (phte_real[base + i].api == api) 294 && (phte_real[base + i].h == 0)) { 295 found = true; 296 break; 297 } 298 } 299 300 if (!found) { 301 /* Find unused PTE in PTEG */ 302 for (i = 0; i < 8; i++) { 303 if (!phte_real[base + i].v) { 304 found = true; 305 break; 306 } 307 } 308 } 309 310 if (!found) { 311 /* Secondary hash (not) */ 312 uint32_t base2 = (~hash & 0x3ff) << 3; 313 314 /* Find colliding PTE in PTEG */ 315 for (i = 0; i < 8; i++) { 316 if ((phte_real[base2 + i].v) 317 && (phte_real[base2 + i].vsid == vsid) 318 && (phte_real[base2 + i].api == api) 319 && (phte_real[base2 + i].h == 1)) { 320 found = true; 321 base = base2; 322 h = 1; 323 break; 324 } 325 } 326 327 if (!found) { 328 /* Find unused PTE in PTEG */ 329 for (i = 0; i < 8; i++) { 330 if (!phte_real[base2 + i].v) { 331 found = true; 332 base = base2; 333 h = 1; 334 break; 335 } 336 } 337 } 338 339 if (!found) { 340 /* Use secondary hash to avoid collisions 341 with usual PHT refill handler. */ 342 i = RANDI(seed_real) % 8; 343 base = base2; 344 h = 1; 345 } 346 } 347 348 phte_real[base + i].v = 1; 349 phte_real[base + i].vsid = vsid; 350 phte_real[base + i].h = h; 351 phte_real[base + i].api = api; 352 phte_real[base + i].rpn = KA2PA(badvaddr) >> 12; 353 phte_real[base + i].r = 0; 354 phte_real[base + i].c = 0; 355 phte_real[base + i].wimg = 0; 356 phte_real[base + i].pp = 2; // FIXME 357 358 return true; 359 } 360 361 /** Process ITLB/DTLB Miss Exception in Real Mode 362 * 363 * 364 */ 365 void tlb_refill_real(unsigned int n, uint32_t tlbmiss, ptehi_t ptehi, 366 ptelo_t ptelo, istate_t *istate) 367 { 251 void tlb_refill(unsigned int n, istate_t *istate) 252 { 253 uint32_t tlbmiss; 254 ptehi_t ptehi; 255 ptelo_t ptelo; 256 257 asm volatile ( 258 "mfspr %[tlbmiss], 980\n" 259 "mfspr %[ptehi], 981\n" 260 "mfspr %[ptelo], 982\n" 261 : [tlbmiss] "=r" (tlbmiss), 262 [ptehi] "=r" (ptehi), 263 [ptelo] "=r" (ptelo) 264 ); 265 368 266 uint32_t badvaddr = tlbmiss & 0xfffffffc; 369 267 uint32_t physmem = physmem_top();
Note:
See TracChangeset
for help on using the changeset viewer.