diff options
Diffstat (limited to 'arch/sparc64/prom/misc.c')
-rw-r--r-- | arch/sparc64/prom/misc.c | 99 |
1 files changed, 89 insertions, 10 deletions
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c index 2a45a4bb5..8d6404fea 100644 --- a/arch/sparc64/prom/misc.c +++ b/arch/sparc64/prom/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.15 1999/08/31 19:25:41 davem Exp $ +/* $Id: misc.c,v 1.16 1999/11/19 05:53:04 davem Exp $ * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * @@ -10,6 +10,8 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/delay.h> #include <asm/openprom.h> #include <asm/oplib.h> @@ -37,6 +39,11 @@ extern void (*prom_palette)(int); extern int serial_console; #endif +#ifdef __SMP__ +extern void smp_capture(void); +extern void smp_release(void); +#endif + /* Drop into the prom, with the chance to continue with the 'go' * prom command. */ @@ -44,26 +51,57 @@ void prom_cmdline(void) { unsigned long flags; - + + __save_and_cli(flags); + #ifdef CONFIG_SUN_CONSOLE if(!serial_console && prom_palette) prom_palette (1); #endif - __save_and_cli(flags); + + /* We always arrive here via a serial interrupt. + * So in order for everything to work reliably, even + * on SMP, we need to drop the IRQ locks we hold. + */ +#ifdef __SMP__ + hardirq_exit(smp_processor_id()); + smp_capture(); +#else + local_irq_count--; +#endif + p1275_cmd ("enter", P1275_INOUT(0,0)); - __restore_flags(flags); + +#ifdef __SMP__ + smp_release(); + hardirq_enter(smp_processor_id()); + spin_unlock_wait(&global_irq_lock); +#else + local_irq_count++; +#endif + #ifdef CONFIG_SUN_CONSOLE if(!serial_console && prom_palette) prom_palette (0); #endif + + __restore_flags(flags); } +#ifdef __SMP__ +extern void smp_promstop_others(void); +#endif + /* Drop into the prom, but completely terminate the program. * No chance of continuing. */ void prom_halt(void) { +#ifdef __SMP__ + smp_promstop_others(); + udelay(8000); +#endif again: p1275_cmd ("exit", P1275_INOUT(0,0)); goto again; /* PROM is out to get me -DaveM */ @@ -122,10 +160,10 @@ void prom_set_trap_table(unsigned long tba) p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba); } -/* This is only used internally below. */ -static int prom_get_mmu_ihandle(void) +int mmu_ihandle_cache = 0; + +int prom_get_mmu_ihandle(void) { - static int mmu_ihandle_cache = 0; int node, ret; if (mmu_ihandle_cache != 0) @@ -165,7 +203,10 @@ long prom_itlb_load(unsigned long index, unsigned long vaddr) { return p1275_cmd("call-method", - (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 1)), + (P1275_ARG(0, P1275_ARG_IN_STRING) | + P1275_ARG(2, P1275_ARG_IN_64B) | + P1275_ARG(3, P1275_ARG_IN_64B) | + P1275_INOUT(5, 1)), "SUNW,itlb-load", prom_get_mmu_ihandle(), /* And then our actual args are pushed backwards. */ @@ -179,7 +220,10 @@ long prom_dtlb_load(unsigned long index, unsigned long vaddr) { return p1275_cmd("call-method", - (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 1)), + (P1275_ARG(0, P1275_ARG_IN_STRING) | + P1275_ARG(2, P1275_ARG_IN_64B) | + P1275_ARG(3, P1275_ARG_IN_64B) | + P1275_INOUT(5, 1)), "SUNW,dtlb-load", prom_get_mmu_ihandle(), /* And then our actual args are pushed backwards. */ @@ -188,6 +232,41 @@ long prom_dtlb_load(unsigned long index, index); } +int prom_map(int mode, unsigned long size, + unsigned long vaddr, unsigned long paddr) +{ + int ret = p1275_cmd("call-method", + (P1275_ARG(0, P1275_ARG_IN_STRING) | + P1275_ARG(3, P1275_ARG_IN_64B) | + P1275_ARG(4, P1275_ARG_IN_64B) | + P1275_ARG(6, P1275_ARG_IN_64B) | + P1275_INOUT(7, 1)), + "map", + prom_get_mmu_ihandle(), + mode, + size, + vaddr, + 0, + paddr); + + if (ret == 0) + ret = -1; + return ret; +} + +void prom_unmap(unsigned long size, unsigned long vaddr) +{ + p1275_cmd("call-method", + (P1275_ARG(0, P1275_ARG_IN_STRING) | + P1275_ARG(2, P1275_ARG_IN_64B) | + P1275_ARG(3, P1275_ARG_IN_64B) | + P1275_INOUT(4, 0)), + "unmap", + prom_get_mmu_ihandle(), + size, + vaddr); +} + /* Set aside physical memory which is not touched or modified * across soft resets. */ @@ -226,7 +305,7 @@ int prom_getunumber(int syndrome_code, return p1275_cmd("call-method", (P1275_ARG(0, P1275_ARG_IN_STRING) | P1275_ARG(3, P1275_ARG_OUT_BUF) | - P1275_ARG(5, P1275_ARG_IN_64B) | + P1275_ARG(6, P1275_ARG_IN_64B) | P1275_INOUT(8, 2)), "SUNW,get-unumber", prom_get_memory_ihandle(), buflen, buf, P1275_SIZE(buflen), |