diff options
author | Kyle McMartin <kyle@mcmartin.ca> | 2008-07-29 00:11:13 -0400 |
---|---|---|
committer | Kyle McMartin <kyle@hera.kernel.org> | 2008-10-10 16:32:30 +0000 |
commit | 089d55289db5d58d938d73b47a415b2b82ee19ac (patch) | |
tree | 4d7cdbc5a7dc8fb7fccf0d579f4296197f05f086 /arch | |
parent | 24b574d052a1996bac42fbd56715ab602092c291 (diff) |
parisc: hijack jump to start_kernel
Bang in our own start_parisc call, which initializes the PDC
width, and turns on the FPU.
Previously, if CONFIG_PRINTK_TIME was on, we'd attempt to use
the FPU before we had enabled it, resulting in a difficult
to diagnose panic.
This patch causes init_per_cpu to redundantly set these for
cpu0, but this is harmless.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/parisc/kernel/head.S | 2 | ||||
-rw-r--r-- | arch/parisc/kernel/setup.c | 27 |
2 files changed, 27 insertions, 2 deletions
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index a84e31e8287..0e3d9f9b9e3 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -121,7 +121,7 @@ $pgt_fill_loop: copy %r0,%r2 /* And the RFI Target address too */ - load32 start_kernel,%r11 + load32 start_parisc,%r11 /* And the initial task pointer */ load32 init_thread_union,%r6 diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 39e7c5a5946..a59b71efdbe 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -368,6 +368,31 @@ static int __init parisc_init(void) return 0; } - arch_initcall(parisc_init); +void start_parisc(void) +{ + extern void start_kernel(void); + + int ret, cpunum; + struct pdc_coproc_cfg coproc_cfg; + + cpunum = smp_processor_id(); + + set_firmware_width_unlocked(); + + ret = pdc_coproc_cfg_unlocked(&coproc_cfg); + if (ret >= 0 && coproc_cfg.ccr_functional) { + mtctl(coproc_cfg.ccr_functional, 10); + + cpu_data[cpunum].fp_rev = coproc_cfg.revision; + cpu_data[cpunum].fp_model = coproc_cfg.model; + + asm volatile ("fstd %fr0,8(%sp)"); + } else { + panic("must have an fpu to boot linux"); + } + + start_kernel(); + // not reached +} |