summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/prom/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/prom/misc.c')
-rw-r--r--arch/sparc64/prom/misc.c99
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),