Commit d82ace7d authored by David S. Miller's avatar David S. Miller

[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: default avatarDavid S. Miller <davem@davemloft.net>
parent 1d2f1f90
...@@ -71,6 +71,12 @@ void __init cpu_probe(void) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -323,14 +401,12 @@ sun4u_init:
membar #Sync membar #Sync
BRANCH_IF_ANY_CHEETAH(g1,g7,cheetah_tlb_fixup) BRANCH_IF_SUN4V(g1, niagara_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: ...@@ -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,7 +543,8 @@ setup_trap_table: ...@@ -464,7 +543,8 @@ setup_trap_table:
sllx %o2, 32, %o2 sllx %o2, 32, %o2
wr %o2, 0, %tick_cmpr wr %o2, 0, %tick_cmpr
BRANCH_IF_ANY_CHEETAH(o2,o3,1f) BRANCH_IF_SUN4V(o2, 1f)
BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
ba,pt %xcc, 2f ba,pt %xcc, 2f
nop nop
......
...@@ -150,47 +150,53 @@ void enable_irq(unsigned int irq) ...@@ -150,47 +150,53 @@ void enable_irq(unsigned int irq)
preempt_disable(); preempt_disable();
if (tlb_type == cheetah || tlb_type == cheetah_plus) { if (tlb_type == hypervisor) {
unsigned long ver; /* XXX SUN4V: implement me... XXX */
} else {
__asm__ ("rdpr %%ver, %0" : "=r" (ver)); if (tlb_type == cheetah || tlb_type == cheetah_plus) {
if ((ver >> 32) == __JALAPENO_ID || unsigned long ver;
(ver >> 32) == __SERRANO_ID) {
/* We set it to our JBUS ID. */ __asm__ ("rdpr %%ver, %0" : "=r" (ver));
if ((ver >> 32) == __JALAPENO_ID ||
(ver >> 32) == __SERRANO_ID) {
/* We set it to our JBUS ID. */
__asm__ __volatile__("ldxa [%%g0] %1, %0"
: "=r" (tid)
: "i" (ASI_JBUS_CONFIG));
tid = ((tid & (0x1fUL<<17)) << 9);
tid &= IMAP_TID_JBUS;
} else {
/* We set it to our Safari AID. */
__asm__ __volatile__("ldxa [%%g0] %1, %0"
: "=r" (tid)
: "i"(ASI_SAFARI_CONFIG));
tid = ((tid & (0x3ffUL<<17)) << 9);
tid &= IMAP_AID_SAFARI;
}
} else if (this_is_starfire == 0) {
/* We set it to our UPA MID. */
__asm__ __volatile__("ldxa [%%g0] %1, %0" __asm__ __volatile__("ldxa [%%g0] %1, %0"
: "=r" (tid) : "=r" (tid)
: "i" (ASI_JBUS_CONFIG)); : "i" (ASI_UPA_CONFIG));
tid = ((tid & (0x1fUL<<17)) << 9); tid = ((tid & UPA_CONFIG_MID) << 9);
tid &= IMAP_TID_JBUS; tid &= IMAP_TID_UPA;
} else { } else {
/* We set it to our Safari AID. */ tid = (starfire_translate(imap,
__asm__ __volatile__("ldxa [%%g0] %1, %0" smp_processor_id()) << 26);
: "=r" (tid) tid &= IMAP_TID_UPA;
: "i" (ASI_SAFARI_CONFIG));
tid = ((tid & (0x3ffUL<<17)) << 9);
tid &= IMAP_AID_SAFARI;
} }
} else if (this_is_starfire == 0) {
/* We set it to our UPA MID. */
__asm__ __volatile__("ldxa [%%g0] %1, %0"
: "=r" (tid)
: "i" (ASI_UPA_CONFIG));
tid = ((tid & UPA_CONFIG_MID) << 9);
tid &= IMAP_TID_UPA;
} else {
tid = (starfire_translate(imap, smp_processor_id()) << 26);
tid &= IMAP_TID_UPA;
}
/* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product /* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product
* of this SYSIO's preconfigured IGN in the SYSIO Control * of this SYSIO's preconfigured IGN in the SYSIO Control
* Register, the hardware just mirrors that value here. * Register, the hardware just mirrors that value here.
* 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) ...@@ -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;
__asm__ ("rdpr %%ver, %0" : "=r" (ver)); is_jbus = 0;
is_jbus = ((ver >> 32) == __JALAPENO_ID || if (tlb_type != hypervisor) {
(ver >> 32) == __SERRANO_ID); __asm__ ("rdpr %%ver, %0" : "=r" (ver));
is_jbus = ((ver >> 32) == __JALAPENO_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 @@ ...@@ -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,8 +35,9 @@ dtlb_load: ...@@ -34,8 +35,9 @@ dtlb_load:
sparc64_cpu_startup: sparc64_cpu_startup:
flushw flushw
BRANCH_IF_CHEETAH_BASE(g1,g5,cheetah_startup) BRANCH_IF_SUN4V(g1, niagara_startup)
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g5,cheetah_plus_startup) BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup)
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup)
ba,pt %xcc, spitfire_startup ba,pt %xcc, spitfire_startup
nop nop
...@@ -70,7 +72,9 @@ cheetah_generic_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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,19 +550,30 @@ static void __init remap_kernel(void) ...@@ -527,19 +550,30 @@ 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. */
prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); if (tlb_type == hypervisor) {
prom_itlb_load(tlb_ent, tte_data, tte_vaddr); hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
if (bigkernel) { hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
tlb_ent -= 1; if (bigkernel) {
prom_dtlb_load(tlb_ent, tte_vaddr += 0x400000;
tte_data + 0x400000, tte_data += 0x400000;
tte_vaddr + 0x400000); hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
prom_itlb_load(tlb_ent, hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
tte_data + 0x400000, }
tte_vaddr + 0x400000); } else {
prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
if (bigkernel) {
tlb_ent -= 1;
prom_dtlb_load(tlb_ent,
tte_data + 0x400000,
tte_vaddr + 0x400000);
prom_itlb_load(tlb_ent,
tte_data + 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; ...@@ -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,26 +40,22 @@ void __init prom_init(void *cif_handler, void *cif_stack) ...@@ -41,26 +40,22 @@ 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();
prom_stdin = prom_getint (prom_chosen_node, "stdin"); prom_stdin = prom_getint(prom_chosen_node, "stdin");
prom_stdout = prom_getint (prom_chosen_node, "stdout"); prom_stdout = prom_getint(prom_chosen_node, "stdout");
node = prom_finddevice("/openprom"); node = prom_finddevice("/openprom");
if (!node || node == -1) if (!node || node == -1)
prom_halt(); prom_halt();
prom_getstring (node, "version", buffer, sizeof (buffer)); prom_getstring(node, "version", buffer, sizeof (buffer));
prom_printf ("\n"); prom_printf("\n");
if (strncmp (buffer, "OBP ", 4)) if (strncmp(buffer, "OBP ", 4))
goto strange_version; goto strange_version;
/* /*
...@@ -70,7 +65,7 @@ void __init prom_init(void *cif_handler, void *cif_stack) ...@@ -70,7 +65,7 @@ void __init prom_init(void *cif_handler, void *cif_stack)
* accordingly. -spot * accordingly. -spot
*/ */
if (strncmp (buffer, "OBP ", 5)) if (strncmp(buffer, "OBP ", 5))
bufadjust = 4; bufadjust = 4;
else else
bufadjust = 5; bufadjust = 5;
...@@ -87,7 +82,8 @@ void __init prom_init(void *cif_handler, void *cif_stack) ...@@ -87,7 +82,8 @@ void __init prom_init(void *cif_handler, void *cif_stack)
prom_rev = ints[1]; prom_rev = ints[1];
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) ...@@ -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) ...@@ -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 @@ ...@@ -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; ...@@ -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[];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment