diff options
Diffstat (limited to 'arch/sparc64/kernel/head.S')
-rw-r--r-- | arch/sparc64/kernel/head.S | 167 |
1 files changed, 103 insertions, 64 deletions
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index ecc748fb9ad7..4c942f71184d 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -191,8 +191,9 @@ prom_boot_mapping_phys_low: | |||
191 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5 | 191 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5 |
192 | stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate" | 192 | stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate" |
193 | stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache | 193 | stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache |
194 | srlx %l0, 22, %l3 | 194 | /* PAGE align */ |
195 | sllx %l3, 22, %l3 | 195 | srlx %l0, 13, %l3 |
196 | sllx %l3, 13, %l3 | ||
196 | stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC | 197 | stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC |
197 | stx %g0, [%sp + 2047 + 128 + 0x30] ! res1 | 198 | stx %g0, [%sp + 2047 + 128 + 0x30] ! res1 |
198 | stx %g0, [%sp + 2047 + 128 + 0x38] ! res2 | 199 | stx %g0, [%sp + 2047 + 128 + 0x38] ! res2 |
@@ -211,6 +212,9 @@ prom_boot_mapping_phys_low: | |||
211 | ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high | 212 | ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high |
212 | stx %l2, [%l4 + 0x0] | 213 | stx %l2, [%l4 + 0x0] |
213 | ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low | 214 | ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low |
215 | /* 4MB align */ | ||
216 | srlx %l3, 22, %l3 | ||
217 | sllx %l3, 22, %l3 | ||
214 | stx %l3, [%l4 + 0x8] | 218 | stx %l3, [%l4 + 0x8] |
215 | 219 | ||
216 | /* Leave service as-is, "call-method" */ | 220 | /* Leave service as-is, "call-method" */ |
@@ -325,23 +329,7 @@ cheetah_tlb_fixup: | |||
325 | 1: sethi %hi(tlb_type), %g1 | 329 | 1: sethi %hi(tlb_type), %g1 |
326 | stw %g2, [%g1 + %lo(tlb_type)] | 330 | stw %g2, [%g1 + %lo(tlb_type)] |
327 | 331 | ||
328 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f) | 332 | /* Patch copy/page operations to cheetah optimized versions. */ |
329 | ba,pt %xcc, 2f | ||
330 | nop | ||
331 | |||
332 | 1: /* Patch context register writes to support nucleus page | ||
333 | * size correctly. | ||
334 | */ | ||
335 | call cheetah_plus_patch_etrap | ||
336 | nop | ||
337 | call cheetah_plus_patch_rtrap | ||
338 | nop | ||
339 | call cheetah_plus_patch_fpdis | ||
340 | nop | ||
341 | call cheetah_plus_patch_winfixup | ||
342 | nop | ||
343 | |||
344 | 2: /* Patch copy/page operations to cheetah optimized versions. */ | ||
345 | call cheetah_patch_copyops | 333 | call cheetah_patch_copyops |
346 | nop | 334 | nop |
347 | call cheetah_patch_copy_page | 335 | call cheetah_patch_copy_page |
@@ -398,32 +386,79 @@ tlb_fixup_done: | |||
398 | nop | 386 | nop |
399 | /* Not reached... */ | 387 | /* Not reached... */ |
400 | 388 | ||
401 | /* IMPORTANT NOTE: Whenever making changes here, check | 389 | /* This is meant to allow the sharing of this code between |
402 | * trampoline.S as well. -jj */ | 390 | * boot processor invocation (via setup_tba() below) and |
403 | .globl setup_tba | 391 | * secondary processor startup (via trampoline.S). The |
404 | setup_tba: /* i0 = is_starfire */ | 392 | * former does use this code, the latter does not yet due |
405 | save %sp, -160, %sp | 393 | * to some complexities. That should be fixed up at some |
394 | * point. | ||
395 | */ | ||
396 | .globl setup_trap_table | ||
397 | setup_trap_table: | ||
398 | save %sp, -192, %sp | ||
399 | |||
400 | /* Force interrupts to be disabled. Transferring over to | ||
401 | * the Linux trap table is a very delicate operation. | ||
402 | * Until we are actually on the Linux trap table, we cannot | ||
403 | * get the PAGE_OFFSET linear mappings translated. We need | ||
404 | * that mapping to be setup in order to initialize the firmware | ||
405 | * page tables. | ||
406 | * | ||
407 | * So there is this window of time, from the return from | ||
408 | * prom_set_trap_table() until inherit_prom_mappings_post() | ||
409 | * (in arch/sparc64/mm/init.c) completes, during which no | ||
410 | * firmware address space accesses can be made. | ||
411 | */ | ||
412 | rdpr %pstate, %o1 | ||
413 | andn %o1, PSTATE_IE, %o1 | ||
414 | wrpr %o1, 0x0, %pstate | ||
415 | wrpr %g0, 15, %pil | ||
406 | 416 | ||
407 | rdpr %tba, %g7 | 417 | /* Ok, now make the final valid firmware call to jump over |
408 | sethi %hi(prom_tba), %o1 | 418 | * to the Linux trap table. |
409 | or %o1, %lo(prom_tba), %o1 | 419 | */ |
410 | stx %g7, [%o1] | 420 | call prom_set_trap_table |
421 | sethi %hi(sparc64_ttable_tl0), %o0 | ||
422 | |||
423 | /* Start using proper page size encodings in ctx register. */ | ||
424 | sethi %hi(sparc64_kern_pri_context), %g3 | ||
425 | ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2 | ||
426 | mov PRIMARY_CONTEXT, %g1 | ||
427 | stxa %g2, [%g1] ASI_DMMU | ||
428 | membar #Sync | ||
429 | |||
430 | /* The Linux trap handlers expect various trap global registers | ||
431 | * to be setup with some fixed values. So here we set these | ||
432 | * up very carefully. These globals are: | ||
433 | * | ||
434 | * Alternate Globals (PSTATE_AG): | ||
435 | * | ||
436 | * %g6 --> current_thread_info() | ||
437 | * | ||
438 | * MMU Globals (PSTATE_MG): | ||
439 | * | ||
440 | * %g1 --> TLB_SFSR | ||
441 | * %g2 --> ((_PAGE_VALID | _PAGE_SZ4MB | | ||
442 | * _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W) | ||
443 | * ^ 0xfffff80000000000) | ||
444 | * (this %g2 value is used for computing the PAGE_OFFSET kernel | ||
445 | * TLB entries quickly, the virtual address of the fault XOR'd | ||
446 | * with this %g2 value is the PTE to load into the TLB) | ||
447 | * %g3 --> VPTE_BASE_CHEETAH or VPTE_BASE_SPITFIRE | ||
448 | * | ||
449 | * Interrupt Globals (PSTATE_IG, setup by init_irqwork_curcpu()): | ||
450 | * | ||
451 | * %g6 --> __irq_work[smp_processor_id()] | ||
452 | */ | ||
411 | 453 | ||
412 | /* Setup "Linux" globals 8-) */ | ||
413 | rdpr %pstate, %o1 | 454 | rdpr %pstate, %o1 |
414 | mov %g6, %o2 | 455 | mov %g6, %o2 |
415 | wrpr %o1, (PSTATE_AG|PSTATE_IE), %pstate | 456 | wrpr %o1, PSTATE_AG, %pstate |
416 | sethi %hi(sparc64_ttable_tl0), %g1 | ||
417 | wrpr %g1, %tba | ||
418 | mov %o2, %g6 | 457 | mov %o2, %g6 |
419 | 458 | ||
420 | /* Set up MMU globals */ | ||
421 | wrpr %o1, (PSTATE_MG|PSTATE_IE), %pstate | ||
422 | |||
423 | /* Set fixed globals used by dTLB miss handler. */ | ||
424 | #define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000) | 459 | #define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000) |
425 | #define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W) | 460 | #define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W) |
426 | 461 | wrpr %o1, PSTATE_MG, %pstate | |
427 | mov TSB_REG, %g1 | 462 | mov TSB_REG, %g1 |
428 | stxa %g0, [%g1] ASI_DMMU | 463 | stxa %g0, [%g1] ASI_DMMU |
429 | membar #Sync | 464 | membar #Sync |
@@ -435,17 +470,17 @@ setup_tba: /* i0 = is_starfire */ | |||
435 | sllx %g2, 32, %g2 | 470 | sllx %g2, 32, %g2 |
436 | or %g2, KERN_LOWBITS, %g2 | 471 | or %g2, KERN_LOWBITS, %g2 |
437 | 472 | ||
438 | BRANCH_IF_ANY_CHEETAH(g3,g7,cheetah_vpte_base) | 473 | BRANCH_IF_ANY_CHEETAH(g3,g7,8f) |
439 | ba,pt %xcc, spitfire_vpte_base | 474 | ba,pt %xcc, 9f |
440 | nop | 475 | nop |
441 | 476 | ||
442 | cheetah_vpte_base: | 477 | 8: |
443 | sethi %uhi(VPTE_BASE_CHEETAH), %g3 | 478 | sethi %uhi(VPTE_BASE_CHEETAH), %g3 |
444 | or %g3, %ulo(VPTE_BASE_CHEETAH), %g3 | 479 | or %g3, %ulo(VPTE_BASE_CHEETAH), %g3 |
445 | ba,pt %xcc, 2f | 480 | ba,pt %xcc, 2f |
446 | sllx %g3, 32, %g3 | 481 | sllx %g3, 32, %g3 |
447 | 482 | ||
448 | spitfire_vpte_base: | 483 | 9: |
449 | sethi %uhi(VPTE_BASE_SPITFIRE), %g3 | 484 | sethi %uhi(VPTE_BASE_SPITFIRE), %g3 |
450 | or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3 | 485 | or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3 |
451 | sllx %g3, 32, %g3 | 486 | sllx %g3, 32, %g3 |
@@ -471,36 +506,37 @@ spitfire_vpte_base: | |||
471 | sllx %o2, 32, %o2 | 506 | sllx %o2, 32, %o2 |
472 | wr %o2, %asr25 | 507 | wr %o2, %asr25 |
473 | 508 | ||
474 | /* Ok, we're done setting up all the state our trap mechanims needs, | ||
475 | * now get back into normal globals and let the PROM know what is up. | ||
476 | */ | ||
477 | 2: | 509 | 2: |
478 | wrpr %g0, %g0, %wstate | 510 | wrpr %g0, %g0, %wstate |
479 | wrpr %o1, PSTATE_IE, %pstate | 511 | wrpr %o1, 0x0, %pstate |
480 | 512 | ||
481 | call init_irqwork_curcpu | 513 | call init_irqwork_curcpu |
482 | nop | 514 | nop |
483 | 515 | ||
484 | call prom_set_trap_table | 516 | /* Now we can turn interrupts back on. */ |
485 | sethi %hi(sparc64_ttable_tl0), %o0 | ||
486 | |||
487 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g2,g3,1f) | ||
488 | ba,pt %xcc, 2f | ||
489 | nop | ||
490 | |||
491 | 1: /* Start using proper page size encodings in ctx register. */ | ||
492 | sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3 | ||
493 | mov PRIMARY_CONTEXT, %g1 | ||
494 | sllx %g3, 32, %g3 | ||
495 | sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2 | ||
496 | or %g3, %g2, %g3 | ||
497 | stxa %g3, [%g1] ASI_DMMU | ||
498 | membar #Sync | ||
499 | |||
500 | 2: | ||
501 | rdpr %pstate, %o1 | 517 | rdpr %pstate, %o1 |
502 | or %o1, PSTATE_IE, %o1 | 518 | or %o1, PSTATE_IE, %o1 |
503 | wrpr %o1, 0, %pstate | 519 | wrpr %o1, 0, %pstate |
520 | wrpr %g0, 0x0, %pil | ||
521 | |||
522 | ret | ||
523 | restore | ||
524 | |||
525 | .globl setup_tba | ||
526 | setup_tba: /* i0 = is_starfire */ | ||
527 | save %sp, -192, %sp | ||
528 | |||
529 | /* The boot processor is the only cpu which invokes this | ||
530 | * routine, the other cpus set things up via trampoline.S. | ||
531 | * So save the OBP trap table address here. | ||
532 | */ | ||
533 | rdpr %tba, %g7 | ||
534 | sethi %hi(prom_tba), %o1 | ||
535 | or %o1, %lo(prom_tba), %o1 | ||
536 | stx %g7, [%o1] | ||
537 | |||
538 | call setup_trap_table | ||
539 | nop | ||
504 | 540 | ||
505 | ret | 541 | ret |
506 | restore | 542 | restore |
@@ -540,8 +576,11 @@ bootup_user_stack_end: | |||
540 | prom_tba: .xword 0 | 576 | prom_tba: .xword 0 |
541 | tlb_type: .word 0 /* Must NOT end up in BSS */ | 577 | tlb_type: .word 0 /* Must NOT end up in BSS */ |
542 | .section ".fixup",#alloc,#execinstr | 578 | .section ".fixup",#alloc,#execinstr |
543 | .globl __ret_efault | 579 | |
580 | .globl __ret_efault, __retl_efault | ||
544 | __ret_efault: | 581 | __ret_efault: |
545 | ret | 582 | ret |
546 | restore %g0, -EFAULT, %o0 | 583 | restore %g0, -EFAULT, %o0 |
547 | 584 | __retl_efault: | |
585 | retl | ||
586 | mov -EFAULT, %o0 | ||