diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/head_8xx.S | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 6478a963255..1f1a04b5c2a 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S | |||
@@ -71,9 +71,6 @@ _ENTRY(_start); | |||
71 | * in the first level table, but that would require many changes to the | 71 | * in the first level table, but that would require many changes to the |
72 | * Linux page directory/table functions that I don't want to do right now. | 72 | * Linux page directory/table functions that I don't want to do right now. |
73 | * | 73 | * |
74 | * I used to use SPRG2 for a temporary register in the TLB handler, but it | ||
75 | * has since been put to other uses. I now use a hack to save a register | ||
76 | * and the CCR at memory location 0.....Someday I'll fix this..... | ||
77 | * -- Dan | 74 | * -- Dan |
78 | */ | 75 | */ |
79 | .globl __start | 76 | .globl __start |
@@ -302,8 +299,13 @@ InstructionTLBMiss: | |||
302 | DO_8xx_CPU6(0x3f80, r3) | 299 | DO_8xx_CPU6(0x3f80, r3) |
303 | mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ | 300 | mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ |
304 | mfcr r10 | 301 | mfcr r10 |
302 | #ifdef CONFIG_8xx_CPU6 | ||
305 | stw r10, 0(r0) | 303 | stw r10, 0(r0) |
306 | stw r11, 4(r0) | 304 | stw r11, 4(r0) |
305 | #else | ||
306 | mtspr SPRN_DAR, r10 | ||
307 | mtspr SPRN_SPRG2, r11 | ||
308 | #endif | ||
307 | mfspr r10, SPRN_SRR0 /* Get effective address of fault */ | 309 | mfspr r10, SPRN_SRR0 /* Get effective address of fault */ |
308 | #ifdef CONFIG_8xx_CPU15 | 310 | #ifdef CONFIG_8xx_CPU15 |
309 | addi r11, r10, 0x1000 | 311 | addi r11, r10, 0x1000 |
@@ -359,13 +361,19 @@ InstructionTLBMiss: | |||
359 | DO_8xx_CPU6(0x2d80, r3) | 361 | DO_8xx_CPU6(0x2d80, r3) |
360 | mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ | 362 | mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ |
361 | 363 | ||
362 | mfspr r10, SPRN_M_TW /* Restore registers */ | 364 | /* Restore registers */ |
365 | #ifndef CONFIG_8xx_CPU6 | ||
366 | mfspr r10, SPRN_DAR | ||
367 | mtcr r10 | ||
368 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
369 | mfspr r11, SPRN_SPRG2 | ||
370 | #else | ||
363 | lwz r11, 0(r0) | 371 | lwz r11, 0(r0) |
364 | mtcr r11 | 372 | mtcr r11 |
365 | lwz r11, 4(r0) | 373 | lwz r11, 4(r0) |
366 | #ifdef CONFIG_8xx_CPU6 | ||
367 | lwz r3, 8(r0) | 374 | lwz r3, 8(r0) |
368 | #endif | 375 | #endif |
376 | mfspr r10, SPRN_M_TW | ||
369 | rfi | 377 | rfi |
370 | 2: | 378 | 2: |
371 | mfspr r11, SPRN_SRR1 | 379 | mfspr r11, SPRN_SRR1 |
@@ -375,13 +383,20 @@ InstructionTLBMiss: | |||
375 | rlwinm r11, r11, 0, 0xffff | 383 | rlwinm r11, r11, 0, 0xffff |
376 | mtspr SPRN_SRR1, r11 | 384 | mtspr SPRN_SRR1, r11 |
377 | 385 | ||
378 | mfspr r10, SPRN_M_TW /* Restore registers */ | 386 | /* Restore registers */ |
387 | #ifndef CONFIG_8xx_CPU6 | ||
388 | mfspr r10, SPRN_DAR | ||
389 | mtcr r10 | ||
390 | li r11, 0x00f0 | ||
391 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
392 | mfspr r11, SPRN_SPRG2 | ||
393 | #else | ||
379 | lwz r11, 0(r0) | 394 | lwz r11, 0(r0) |
380 | mtcr r11 | 395 | mtcr r11 |
381 | lwz r11, 4(r0) | 396 | lwz r11, 4(r0) |
382 | #ifdef CONFIG_8xx_CPU6 | ||
383 | lwz r3, 8(r0) | 397 | lwz r3, 8(r0) |
384 | #endif | 398 | #endif |
399 | mfspr r10, SPRN_M_TW | ||
385 | b InstructionAccess | 400 | b InstructionAccess |
386 | 401 | ||
387 | . = 0x1200 | 402 | . = 0x1200 |
@@ -392,8 +407,13 @@ DataStoreTLBMiss: | |||
392 | DO_8xx_CPU6(0x3f80, r3) | 407 | DO_8xx_CPU6(0x3f80, r3) |
393 | mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ | 408 | mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ |
394 | mfcr r10 | 409 | mfcr r10 |
410 | #ifdef CONFIG_8xx_CPU6 | ||
395 | stw r10, 0(r0) | 411 | stw r10, 0(r0) |
396 | stw r11, 4(r0) | 412 | stw r11, 4(r0) |
413 | #else | ||
414 | mtspr SPRN_DAR, r10 | ||
415 | mtspr SPRN_SPRG2, r11 | ||
416 | #endif | ||
397 | mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ | 417 | mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ |
398 | 418 | ||
399 | /* If we are faulting a kernel address, we have to use the | 419 | /* If we are faulting a kernel address, we have to use the |
@@ -461,18 +481,24 @@ DataStoreTLBMiss: | |||
461 | * of the MMU. | 481 | * of the MMU. |
462 | */ | 482 | */ |
463 | 2: li r11, 0x00f0 | 483 | 2: li r11, 0x00f0 |
464 | mtspr SPRN_DAR,r11 /* Tag DAR */ | ||
465 | rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ | 484 | rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ |
466 | DO_8xx_CPU6(0x3d80, r3) | 485 | DO_8xx_CPU6(0x3d80, r3) |
467 | mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ | 486 | mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ |
468 | 487 | ||
469 | mfspr r10, SPRN_M_TW /* Restore registers */ | 488 | /* Restore registers */ |
489 | #ifndef CONFIG_8xx_CPU6 | ||
490 | mfspr r10, SPRN_DAR | ||
491 | mtcr r10 | ||
492 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
493 | mfspr r11, SPRN_SPRG2 | ||
494 | #else | ||
495 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
470 | lwz r11, 0(r0) | 496 | lwz r11, 0(r0) |
471 | mtcr r11 | 497 | mtcr r11 |
472 | lwz r11, 4(r0) | 498 | lwz r11, 4(r0) |
473 | #ifdef CONFIG_8xx_CPU6 | ||
474 | lwz r3, 8(r0) | 499 | lwz r3, 8(r0) |
475 | #endif | 500 | #endif |
501 | mfspr r10, SPRN_M_TW | ||
476 | rfi | 502 | rfi |
477 | 503 | ||
478 | /* This is an instruction TLB error on the MPC8xx. This could be due | 504 | /* This is an instruction TLB error on the MPC8xx. This could be due |
@@ -684,9 +710,6 @@ start_here: | |||
684 | tophys(r4,r2) | 710 | tophys(r4,r2) |
685 | addi r4,r4,THREAD /* init task's THREAD */ | 711 | addi r4,r4,THREAD /* init task's THREAD */ |
686 | mtspr SPRN_SPRG_THREAD,r4 | 712 | mtspr SPRN_SPRG_THREAD,r4 |
687 | li r3,0 | ||
688 | /* XXX What is that for ? SPRG2 appears otherwise unused on 8xx */ | ||
689 | mtspr SPRN_SPRG2,r3 /* 0 => r1 has kernel sp */ | ||
690 | 713 | ||
691 | /* stack */ | 714 | /* stack */ |
692 | lis r1,init_thread_union@ha | 715 | lis r1,init_thread_union@ha |