patch-2.2.14 linux/arch/sparc64/prom/misc.c

Next file: linux/arch/sparc64/prom/p1275.c
Previous file: linux/arch/sparc64/prom/map.S
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.13/linux/arch/sparc64/prom/misc.c linux/arch/sparc64/prom/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.14.2.1 1999/08/19 01:11:18 davem Exp $
+/* $Id: misc.c,v 1.14.2.3 1999/10/27 00:22:26 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 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 @@
 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 @@
 	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 @@
 		    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 @@
 		    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 @@
 			 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 @@
 	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),

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)