[SPARC64]: Detect sun4v early in boot process.
We look for "SUNW,sun4v" in the 'compatible' property of the root OBP device tree node. Protect every %ver register access, to make sure it is not touched on sun4v, as %ver is hyperprivileged there. Lock kernel TLB entries using hypervisor calls instead of calls into OBP. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1d2f1f90a1
commit
d82ace7dc4
|
@ -71,6 +71,12 @@ void __init cpu_probe(void)
|
||||||
unsigned long ver, fpu_vers, manuf, impl, fprs;
|
unsigned long ver, fpu_vers, manuf, impl, fprs;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (tlb_type == hypervisor) {
|
||||||
|
sparc_cpu_type = "UltraSparc T1 (Niagara)";
|
||||||
|
sparc_fpu_type = "UltraSparc T1 integrated FPU";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fprs = fprs_read();
|
fprs = fprs_read();
|
||||||
fprs_write(FPRS_FEF);
|
fprs_write(FPRS_FEF);
|
||||||
__asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]"
|
__asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]"
|
||||||
|
|
|
@ -95,12 +95,17 @@ sparc64_boot:
|
||||||
wrpr %g1, 0x0, %pstate
|
wrpr %g1, 0x0, %pstate
|
||||||
ba,a,pt %xcc, 1f
|
ba,a,pt %xcc, 1f
|
||||||
|
|
||||||
.globl prom_finddev_name, prom_chosen_path
|
.globl prom_finddev_name, prom_chosen_path, prom_root_node
|
||||||
.globl prom_getprop_name, prom_mmu_name
|
.globl prom_getprop_name, prom_mmu_name, prom_peer_name
|
||||||
.globl prom_callmethod_name, prom_translate_name
|
.globl prom_callmethod_name, prom_translate_name, prom_root_compatible
|
||||||
.globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache
|
.globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache
|
||||||
.globl prom_boot_mapped_pc, prom_boot_mapping_mode
|
.globl prom_boot_mapped_pc, prom_boot_mapping_mode
|
||||||
.globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
|
.globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
|
||||||
|
.globl is_sun4v
|
||||||
|
prom_peer_name:
|
||||||
|
.asciz "peer"
|
||||||
|
prom_compatible_name:
|
||||||
|
.asciz "compatible"
|
||||||
prom_finddev_name:
|
prom_finddev_name:
|
||||||
.asciz "finddevice"
|
.asciz "finddevice"
|
||||||
prom_chosen_path:
|
prom_chosen_path:
|
||||||
|
@ -117,7 +122,13 @@ prom_map_name:
|
||||||
.asciz "map"
|
.asciz "map"
|
||||||
prom_unmap_name:
|
prom_unmap_name:
|
||||||
.asciz "unmap"
|
.asciz "unmap"
|
||||||
|
prom_sun4v_name:
|
||||||
|
.asciz "SUNW,sun4v"
|
||||||
.align 4
|
.align 4
|
||||||
|
prom_root_compatible:
|
||||||
|
.skip 64
|
||||||
|
prom_root_node:
|
||||||
|
.word 0
|
||||||
prom_mmu_ihandle_cache:
|
prom_mmu_ihandle_cache:
|
||||||
.word 0
|
.word 0
|
||||||
prom_boot_mapped_pc:
|
prom_boot_mapped_pc:
|
||||||
|
@ -129,8 +140,54 @@ prom_boot_mapping_phys_high:
|
||||||
.xword 0
|
.xword 0
|
||||||
prom_boot_mapping_phys_low:
|
prom_boot_mapping_phys_low:
|
||||||
.xword 0
|
.xword 0
|
||||||
|
is_sun4v:
|
||||||
|
.word 0
|
||||||
1:
|
1:
|
||||||
rd %pc, %l0
|
rd %pc, %l0
|
||||||
|
|
||||||
|
mov (1b - prom_peer_name), %l1
|
||||||
|
sub %l0, %l1, %l1
|
||||||
|
mov 0, %l2
|
||||||
|
|
||||||
|
/* prom_root_node = prom_peer(0) */
|
||||||
|
stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "peer"
|
||||||
|
mov 1, %l3
|
||||||
|
stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1
|
||||||
|
stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
|
||||||
|
stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, 0
|
||||||
|
stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1
|
||||||
|
call %l7
|
||||||
|
add %sp, (2047 + 128), %o0 ! argument array
|
||||||
|
|
||||||
|
ldx [%sp + 2047 + 128 + 0x20], %l4 ! prom root node
|
||||||
|
mov (1b - prom_root_node), %l1
|
||||||
|
sub %l0, %l1, %l1
|
||||||
|
stw %l4, [%l1]
|
||||||
|
|
||||||
|
mov (1b - prom_getprop_name), %l1
|
||||||
|
mov (1b - prom_compatible_name), %l2
|
||||||
|
mov (1b - prom_root_compatible), %l5
|
||||||
|
sub %l0, %l1, %l1
|
||||||
|
sub %l0, %l2, %l2
|
||||||
|
sub %l0, %l5, %l5
|
||||||
|
|
||||||
|
/* prom_getproperty(prom_root_node, "compatible",
|
||||||
|
* &prom_root_compatible, 64)
|
||||||
|
*/
|
||||||
|
stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop"
|
||||||
|
mov 4, %l3
|
||||||
|
stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4
|
||||||
|
mov 1, %l3
|
||||||
|
stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
|
||||||
|
stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, prom_root_node
|
||||||
|
stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "compatible"
|
||||||
|
stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_root_compatible
|
||||||
|
mov 64, %l3
|
||||||
|
stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, size
|
||||||
|
stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1
|
||||||
|
call %l7
|
||||||
|
add %sp, (2047 + 128), %o0 ! argument array
|
||||||
|
|
||||||
mov (1b - prom_finddev_name), %l1
|
mov (1b - prom_finddev_name), %l1
|
||||||
mov (1b - prom_chosen_path), %l2
|
mov (1b - prom_chosen_path), %l2
|
||||||
mov (1b - prom_boot_mapped_pc), %l3
|
mov (1b - prom_boot_mapped_pc), %l3
|
||||||
|
@ -239,6 +296,27 @@ prom_boot_mapping_phys_low:
|
||||||
add %sp, (192 + 128), %sp
|
add %sp, (192 + 128), %sp
|
||||||
|
|
||||||
sparc64_boot_after_remap:
|
sparc64_boot_after_remap:
|
||||||
|
sethi %hi(prom_root_compatible), %g1
|
||||||
|
or %g1, %lo(prom_root_compatible), %g1
|
||||||
|
sethi %hi(prom_sun4v_name), %g7
|
||||||
|
or %g7, %lo(prom_sun4v_name), %g7
|
||||||
|
mov 10, %g3
|
||||||
|
1: ldub [%g7], %g2
|
||||||
|
ldub [%g1], %g4
|
||||||
|
cmp %g2, %g4
|
||||||
|
bne,pn %icc, 2f
|
||||||
|
add %g7, 1, %g7
|
||||||
|
subcc %g3, 1, %g3
|
||||||
|
bne,pt %xcc, 1b
|
||||||
|
add %g1, 1, %g1
|
||||||
|
|
||||||
|
sethi %hi(is_sun4v), %g1
|
||||||
|
or %g1, %lo(is_sun4v), %g1
|
||||||
|
mov 1, %g7
|
||||||
|
stw %g7, [%g1]
|
||||||
|
|
||||||
|
2:
|
||||||
|
BRANCH_IF_SUN4V(g1, jump_to_sun4u_init)
|
||||||
BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot)
|
BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot)
|
||||||
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot)
|
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot)
|
||||||
ba,pt %xcc, spitfire_boot
|
ba,pt %xcc, spitfire_boot
|
||||||
|
@ -323,14 +401,12 @@ sun4u_init:
|
||||||
|
|
||||||
membar #Sync
|
membar #Sync
|
||||||
|
|
||||||
|
BRANCH_IF_SUN4V(g1, niagara_tlb_fixup)
|
||||||
BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup)
|
BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup)
|
||||||
|
|
||||||
ba,pt %xcc, spitfire_tlb_fixup
|
ba,pt %xcc, spitfire_tlb_fixup
|
||||||
nop
|
nop
|
||||||
|
|
||||||
/* XXX Nothing branches to here yet, when %ver register indicates
|
|
||||||
* XXX Niagara we should do this.
|
|
||||||
*/
|
|
||||||
niagara_tlb_fixup:
|
niagara_tlb_fixup:
|
||||||
mov 3, %g2 /* Set TLB type to hypervisor. */
|
mov 3, %g2 /* Set TLB type to hypervisor. */
|
||||||
sethi %hi(tlb_type), %g1
|
sethi %hi(tlb_type), %g1
|
||||||
|
@ -346,6 +422,9 @@ niagara_tlb_fixup:
|
||||||
call hypervisor_patch_cachetlbops
|
call hypervisor_patch_cachetlbops
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
ba,pt %xcc, tlb_fixup_done
|
||||||
|
nop
|
||||||
|
|
||||||
cheetah_tlb_fixup:
|
cheetah_tlb_fixup:
|
||||||
mov 2, %g2 /* Set TLB type to cheetah+. */
|
mov 2, %g2 /* Set TLB type to cheetah+. */
|
||||||
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f)
|
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f)
|
||||||
|
@ -464,6 +543,7 @@ setup_trap_table:
|
||||||
sllx %o2, 32, %o2
|
sllx %o2, 32, %o2
|
||||||
wr %o2, 0, %tick_cmpr
|
wr %o2, 0, %tick_cmpr
|
||||||
|
|
||||||
|
BRANCH_IF_SUN4V(o2, 1f)
|
||||||
BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
|
BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
|
||||||
|
|
||||||
ba,pt %xcc, 2f
|
ba,pt %xcc, 2f
|
||||||
|
|
|
@ -150,6 +150,9 @@ void enable_irq(unsigned int irq)
|
||||||
|
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
|
|
||||||
|
if (tlb_type == hypervisor) {
|
||||||
|
/* XXX SUN4V: implement me... XXX */
|
||||||
|
} else {
|
||||||
if (tlb_type == cheetah || tlb_type == cheetah_plus) {
|
if (tlb_type == cheetah || tlb_type == cheetah_plus) {
|
||||||
unsigned long ver;
|
unsigned long ver;
|
||||||
|
|
||||||
|
@ -178,7 +181,8 @@ void enable_irq(unsigned int irq)
|
||||||
tid = ((tid & UPA_CONFIG_MID) << 9);
|
tid = ((tid & UPA_CONFIG_MID) << 9);
|
||||||
tid &= IMAP_TID_UPA;
|
tid &= IMAP_TID_UPA;
|
||||||
} else {
|
} else {
|
||||||
tid = (starfire_translate(imap, smp_processor_id()) << 26);
|
tid = (starfire_translate(imap,
|
||||||
|
smp_processor_id()) << 26);
|
||||||
tid &= IMAP_TID_UPA;
|
tid &= IMAP_TID_UPA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +192,11 @@ void enable_irq(unsigned int irq)
|
||||||
* However for Graphics and UPA Slave devices the full
|
* However for Graphics and UPA Slave devices the full
|
||||||
* IMAP_INR field can be set by the programmer here.
|
* IMAP_INR field can be set by the programmer here.
|
||||||
*
|
*
|
||||||
* Things like FFB can now be handled via the new IRQ mechanism.
|
* Things like FFB can now be handled via the new IRQ
|
||||||
|
* mechanism.
|
||||||
*/
|
*/
|
||||||
upa_writel(tid | IMAP_VALID, imap);
|
upa_writel(tid | IMAP_VALID, imap);
|
||||||
|
}
|
||||||
|
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,9 +504,12 @@ static void __init per_cpu_patch(void)
|
||||||
if (tlb_type == spitfire && !this_is_starfire)
|
if (tlb_type == spitfire && !this_is_starfire)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
is_jbus = 0;
|
||||||
|
if (tlb_type != hypervisor) {
|
||||||
__asm__ ("rdpr %%ver, %0" : "=r" (ver));
|
__asm__ ("rdpr %%ver, %0" : "=r" (ver));
|
||||||
is_jbus = ((ver >> 32) == __JALAPENO_ID ||
|
is_jbus = ((ver >> 32) == __JALAPENO_ID ||
|
||||||
(ver >> 32) == __SERRANO_ID);
|
(ver >> 32) == __SERRANO_ID);
|
||||||
|
}
|
||||||
|
|
||||||
p = &__cpuid_patch;
|
p = &__cpuid_patch;
|
||||||
while (p < &__cpuid_patch_end) {
|
while (p < &__cpuid_patch_end) {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/thread_info.h>
|
#include <asm/thread_info.h>
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
|
#include <asm/hypervisor.h>
|
||||||
|
|
||||||
.data
|
.data
|
||||||
.align 8
|
.align 8
|
||||||
|
@ -34,6 +35,7 @@ dtlb_load:
|
||||||
sparc64_cpu_startup:
|
sparc64_cpu_startup:
|
||||||
flushw
|
flushw
|
||||||
|
|
||||||
|
BRANCH_IF_SUN4V(g1, niagara_startup)
|
||||||
BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup)
|
BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup)
|
||||||
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup)
|
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup)
|
||||||
|
|
||||||
|
@ -70,7 +72,9 @@ cheetah_generic_startup:
|
||||||
stxa %g0, [%g3] ASI_DMMU
|
stxa %g0, [%g3] ASI_DMMU
|
||||||
stxa %g0, [%g3] ASI_IMMU
|
stxa %g0, [%g3] ASI_IMMU
|
||||||
membar #Sync
|
membar #Sync
|
||||||
|
/* fallthru */
|
||||||
|
|
||||||
|
niagara_startup:
|
||||||
/* Disable STICK_INT interrupts. */
|
/* Disable STICK_INT interrupts. */
|
||||||
sethi %hi(0x80000000), %g5
|
sethi %hi(0x80000000), %g5
|
||||||
sllx %g5, 32, %g5
|
sllx %g5, 32, %g5
|
||||||
|
@ -91,6 +95,8 @@ startup_continue:
|
||||||
sllx %g2, 32, %g2
|
sllx %g2, 32, %g2
|
||||||
wr %g2, 0, %tick_cmpr
|
wr %g2, 0, %tick_cmpr
|
||||||
|
|
||||||
|
BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
|
||||||
|
|
||||||
/* Call OBP by hand to lock KERNBASE into i/d tlbs.
|
/* Call OBP by hand to lock KERNBASE into i/d tlbs.
|
||||||
* We lock 2 consequetive entries if we are 'bigkernel'.
|
* We lock 2 consequetive entries if we are 'bigkernel'.
|
||||||
*/
|
*/
|
||||||
|
@ -142,8 +148,7 @@ startup_continue:
|
||||||
|
|
||||||
sethi %hi(bigkernel), %g2
|
sethi %hi(bigkernel), %g2
|
||||||
lduw [%g2 + %lo(bigkernel)], %g2
|
lduw [%g2 + %lo(bigkernel)], %g2
|
||||||
cmp %g2, 0
|
brz,pt %g2, do_dtlb
|
||||||
be,pt %icc, do_dtlb
|
|
||||||
nop
|
nop
|
||||||
|
|
||||||
sethi %hi(call_method), %g2
|
sethi %hi(call_method), %g2
|
||||||
|
@ -214,8 +219,7 @@ do_dtlb:
|
||||||
|
|
||||||
sethi %hi(bigkernel), %g2
|
sethi %hi(bigkernel), %g2
|
||||||
lduw [%g2 + %lo(bigkernel)], %g2
|
lduw [%g2 + %lo(bigkernel)], %g2
|
||||||
cmp %g2, 0
|
brz,pt %g2, do_unlock
|
||||||
be,pt %icc, do_unlock
|
|
||||||
nop
|
nop
|
||||||
|
|
||||||
sethi %hi(call_method), %g2
|
sethi %hi(call_method), %g2
|
||||||
|
@ -257,6 +261,52 @@ do_unlock:
|
||||||
stb %g0, [%g2 + %lo(prom_entry_lock)]
|
stb %g0, [%g2 + %lo(prom_entry_lock)]
|
||||||
membar #StoreStore | #StoreLoad
|
membar #StoreStore | #StoreLoad
|
||||||
|
|
||||||
|
ba,pt %xcc, after_lock_tlb
|
||||||
|
nop
|
||||||
|
|
||||||
|
niagara_lock_tlb:
|
||||||
|
mov HV_FAST_MMU_MAP_PERM_ADDR, %o0
|
||||||
|
sethi %hi(KERNBASE), %o1
|
||||||
|
clr %o2
|
||||||
|
sethi %hi(kern_locked_tte_data), %o3
|
||||||
|
ldx [%o3 + %lo(kern_locked_tte_data)], %o3
|
||||||
|
mov HV_MMU_IMMU, %o4
|
||||||
|
ta HV_FAST_TRAP
|
||||||
|
|
||||||
|
mov HV_FAST_MMU_MAP_PERM_ADDR, %o0
|
||||||
|
sethi %hi(KERNBASE), %o1
|
||||||
|
clr %o2
|
||||||
|
sethi %hi(kern_locked_tte_data), %o3
|
||||||
|
ldx [%o3 + %lo(kern_locked_tte_data)], %o3
|
||||||
|
mov HV_MMU_DMMU, %o4
|
||||||
|
ta HV_FAST_TRAP
|
||||||
|
|
||||||
|
sethi %hi(bigkernel), %g2
|
||||||
|
lduw [%g2 + %lo(bigkernel)], %g2
|
||||||
|
brz,pt %g2, after_lock_tlb
|
||||||
|
nop
|
||||||
|
|
||||||
|
mov HV_FAST_MMU_MAP_PERM_ADDR, %o0
|
||||||
|
sethi %hi(KERNBASE + 0x400000), %o1
|
||||||
|
clr %o2
|
||||||
|
sethi %hi(kern_locked_tte_data), %o3
|
||||||
|
ldx [%o3 + %lo(kern_locked_tte_data)], %o3
|
||||||
|
sethi %hi(0x400000), %o4
|
||||||
|
add %o3, %o4, %o3
|
||||||
|
mov HV_MMU_IMMU, %o4
|
||||||
|
ta HV_FAST_TRAP
|
||||||
|
|
||||||
|
mov HV_FAST_MMU_MAP_PERM_ADDR, %o0
|
||||||
|
sethi %hi(KERNBASE + 0x400000), %o1
|
||||||
|
clr %o2
|
||||||
|
sethi %hi(kern_locked_tte_data), %o3
|
||||||
|
ldx [%o3 + %lo(kern_locked_tte_data)], %o3
|
||||||
|
sethi %hi(0x400000), %o4
|
||||||
|
add %o3, %o4, %o3
|
||||||
|
mov HV_MMU_DMMU, %o4
|
||||||
|
ta HV_FAST_TRAP
|
||||||
|
|
||||||
|
after_lock_tlb:
|
||||||
mov %l1, %sp
|
mov %l1, %sp
|
||||||
flushw
|
flushw
|
||||||
|
|
||||||
|
|
|
@ -346,6 +346,9 @@ static int __init us2e_freq_init(void)
|
||||||
unsigned long manuf, impl, ver;
|
unsigned long manuf, impl, ver;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (tlb_type != spitfire)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
__asm__("rdpr %%ver, %0" : "=r" (ver));
|
__asm__("rdpr %%ver, %0" : "=r" (ver));
|
||||||
manuf = ((ver >> 48) & 0xffff);
|
manuf = ((ver >> 48) & 0xffff);
|
||||||
impl = ((ver >> 32) & 0xffff);
|
impl = ((ver >> 32) & 0xffff);
|
||||||
|
|
|
@ -203,6 +203,9 @@ static int __init us3_freq_init(void)
|
||||||
unsigned long manuf, impl, ver;
|
unsigned long manuf, impl, ver;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (tlb_type != cheetah && tlb_type != cheetah_plus)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
__asm__("rdpr %%ver, %0" : "=r" (ver));
|
__asm__("rdpr %%ver, %0" : "=r" (ver));
|
||||||
manuf = ((ver >> 48) & 0xffff);
|
manuf = ((ver >> 48) & 0xffff);
|
||||||
impl = ((ver >> 32) & 0xffff);
|
impl = ((ver >> 32) & 0xffff);
|
||||||
|
|
|
@ -514,6 +514,29 @@ static void __init read_obp_translations(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init hypervisor_tlb_lock(unsigned long vaddr,
|
||||||
|
unsigned long pte,
|
||||||
|
unsigned long mmu)
|
||||||
|
{
|
||||||
|
register unsigned long func asm("%o0");
|
||||||
|
register unsigned long arg0 asm("%o1");
|
||||||
|
register unsigned long arg1 asm("%o2");
|
||||||
|
register unsigned long arg2 asm("%o3");
|
||||||
|
register unsigned long arg3 asm("%o4");
|
||||||
|
|
||||||
|
func = HV_FAST_MMU_MAP_PERM_ADDR;
|
||||||
|
arg0 = vaddr;
|
||||||
|
arg1 = 0;
|
||||||
|
arg2 = pte;
|
||||||
|
arg3 = mmu;
|
||||||
|
__asm__ __volatile__("ta 0x80"
|
||||||
|
: "=&r" (func), "=&r" (arg0),
|
||||||
|
"=&r" (arg1), "=&r" (arg2),
|
||||||
|
"=&r" (arg3)
|
||||||
|
: "0" (func), "1" (arg0), "2" (arg1),
|
||||||
|
"3" (arg2), "4" (arg3));
|
||||||
|
}
|
||||||
|
|
||||||
static void __init remap_kernel(void)
|
static void __init remap_kernel(void)
|
||||||
{
|
{
|
||||||
unsigned long phys_page, tte_vaddr, tte_data;
|
unsigned long phys_page, tte_vaddr, tte_data;
|
||||||
|
@ -527,7 +550,17 @@ static void __init remap_kernel(void)
|
||||||
|
|
||||||
kern_locked_tte_data = tte_data;
|
kern_locked_tte_data = tte_data;
|
||||||
|
|
||||||
/* Now lock us into the TLBs via OBP. */
|
/* Now lock us into the TLBs via Hypervisor or OBP. */
|
||||||
|
if (tlb_type == hypervisor) {
|
||||||
|
hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
|
||||||
|
hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
|
||||||
|
if (bigkernel) {
|
||||||
|
tte_vaddr += 0x400000;
|
||||||
|
tte_data += 0x400000;
|
||||||
|
hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
|
||||||
|
hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
|
prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
|
||||||
prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
|
prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
|
||||||
if (bigkernel) {
|
if (bigkernel) {
|
||||||
|
@ -540,6 +573,7 @@ static void __init remap_kernel(void)
|
||||||
tte_vaddr + 0x400000);
|
tte_vaddr + 0x400000);
|
||||||
}
|
}
|
||||||
sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
|
sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
|
||||||
|
}
|
||||||
if (tlb_type == cheetah_plus) {
|
if (tlb_type == cheetah_plus) {
|
||||||
sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 |
|
sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 |
|
||||||
CTX_CHEETAH_PLUS_NUC);
|
CTX_CHEETAH_PLUS_NUC);
|
||||||
|
|
|
@ -18,7 +18,6 @@ enum prom_major_version prom_vers;
|
||||||
unsigned int prom_rev, prom_prev;
|
unsigned int prom_rev, prom_prev;
|
||||||
|
|
||||||
/* The root node of the prom device tree. */
|
/* The root node of the prom device tree. */
|
||||||
int prom_root_node;
|
|
||||||
int prom_stdin, prom_stdout;
|
int prom_stdin, prom_stdout;
|
||||||
int prom_chosen_node;
|
int prom_chosen_node;
|
||||||
|
|
||||||
|
@ -41,10 +40,6 @@ void __init prom_init(void *cif_handler, void *cif_stack)
|
||||||
|
|
||||||
prom_cif_init(cif_handler, cif_stack);
|
prom_cif_init(cif_handler, cif_stack);
|
||||||
|
|
||||||
prom_root_node = prom_getsibling(0);
|
|
||||||
if((prom_root_node == 0) || (prom_root_node == -1))
|
|
||||||
prom_halt();
|
|
||||||
|
|
||||||
prom_chosen_node = prom_finddevice(prom_chosen_path);
|
prom_chosen_node = prom_finddevice(prom_chosen_path);
|
||||||
if (!prom_chosen_node || prom_chosen_node == -1)
|
if (!prom_chosen_node || prom_chosen_node == -1)
|
||||||
prom_halt();
|
prom_halt();
|
||||||
|
@ -88,6 +83,7 @@ void __init prom_init(void *cif_handler, void *cif_stack)
|
||||||
prom_prev = (ints[0] << 16) | (ints[1] << 8) | ints[2];
|
prom_prev = (ints[0] << 16) | (ints[1] << 8) | ints[2];
|
||||||
|
|
||||||
printk("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + bufadjust);
|
printk("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + bufadjust);
|
||||||
|
printk("PROMLIB: Root node compatible: %s\n", prom_root_compatible);
|
||||||
|
|
||||||
/* Initialization successful. */
|
/* Initialization successful. */
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -51,7 +51,7 @@ prom_getparent(int node)
|
||||||
__inline__ int
|
__inline__ int
|
||||||
__prom_getsibling(int node)
|
__prom_getsibling(int node)
|
||||||
{
|
{
|
||||||
return p1275_cmd ("peer", P1275_INOUT(1, 1), node);
|
return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
__inline__ int
|
__inline__ int
|
||||||
|
@ -59,9 +59,12 @@ prom_getsibling(int node)
|
||||||
{
|
{
|
||||||
int sibnode;
|
int sibnode;
|
||||||
|
|
||||||
if(node == -1) return 0;
|
if (node == -1)
|
||||||
|
return 0;
|
||||||
sibnode = __prom_getsibling(node);
|
sibnode = __prom_getsibling(node);
|
||||||
if(sibnode == -1) return 0;
|
if (sibnode == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return sibnode;
|
return sibnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,12 @@
|
||||||
#define PANTHER_IMPL 0x0019 /* Ultra-IV+ */
|
#define PANTHER_IMPL 0x0019 /* Ultra-IV+ */
|
||||||
#define SERRANO_IMPL 0x0022 /* Ultra-IIIi+ */
|
#define SERRANO_IMPL 0x0022 /* Ultra-IIIi+ */
|
||||||
|
|
||||||
|
#define BRANCH_IF_SUN4V(tmp1,label) \
|
||||||
|
sethi %hi(is_sun4v), %tmp1; \
|
||||||
|
lduw [%tmp1 + %lo(is_sun4v)], %tmp1; \
|
||||||
|
brnz,pn %tmp1, label; \
|
||||||
|
nop
|
||||||
|
|
||||||
#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label) \
|
#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label) \
|
||||||
rdpr %ver, %tmp1; \
|
rdpr %ver, %tmp1; \
|
||||||
sethi %hi(__CHEETAH_ID), %tmp2; \
|
sethi %hi(__CHEETAH_ID), %tmp2; \
|
||||||
|
|
|
@ -39,6 +39,9 @@ extern int prom_stdin, prom_stdout;
|
||||||
extern int prom_chosen_node;
|
extern int prom_chosen_node;
|
||||||
|
|
||||||
/* Helper values and strings in arch/sparc64/kernel/head.S */
|
/* Helper values and strings in arch/sparc64/kernel/head.S */
|
||||||
|
extern const char prom_peer_name[];
|
||||||
|
extern const char prom_compatible_name[];
|
||||||
|
extern const char prom_root_compatible[];
|
||||||
extern const char prom_finddev_name[];
|
extern const char prom_finddev_name[];
|
||||||
extern const char prom_chosen_path[];
|
extern const char prom_chosen_path[];
|
||||||
extern const char prom_getprop_name[];
|
extern const char prom_getprop_name[];
|
||||||
|
|
Reference in New Issue