patch-2.2.14 linux/arch/ppc/kernel/prom.c

Next file: linux/arch/ppc/kernel/ptrace.c
Previous file: linux/arch/ppc/kernel/process.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.13/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
@@ -25,6 +25,7 @@
 #include <asm/smp.h>
 #include <asm/bootx.h>
 #include <asm/system.h>
+#include <asm/gemini.h>
 
 /*
  * Properties whose value is longer than this get excluded from our
@@ -263,7 +264,7 @@
  * handling exceptions and the MMU hash table for us.
  */
 __init
-void
+unsigned long
 prom_init(int r3, int r4, prom_entry pp)
 {
 #ifdef CONFIG_SMP	
@@ -272,14 +273,23 @@
 	char type[16], *path;
 #endif	
 	unsigned long mem;
-	ihandle prom_rtas;
+	ihandle prom_rtas, prom_mmu;
 	unsigned long offset = reloc_offset();
 	int l;
 	char *p, *d;
+ 	unsigned long phys;
+ 	
+ 	/* Default */
+ 	phys = offset + KERNELBASE;
+	
+#ifdef CONFIG_GEMINI
+	gemini_prom_init();
+		return phys;
+#endif /* CONFIG_GEMINI */
 	
 	/* check if we're apus, return if we are */
 	if ( r3 == 0x61707573 )
-		return;
+ 		return phys;
 
 	/* If we came here from BootX, clear the screen,
 	 * set up some pointers and return. */
@@ -375,12 +385,12 @@
 		prom_print(RELOC("booting...\n"));
 		flushscreen();
 #endif
-		return;
+		return phys;
 	}
 	
 	/* check if we're prep, return if we are */
 	if ( *(unsigned long *)(0) == 0xdeadc0de )
-		return;
+		return phys;
 
 	/* First get a handle for the stdout device */
 	RELOC(prom) = pp;
@@ -472,6 +482,29 @@
 			prom_print(RELOC(" done\n"));
 	}
 
+	if ((int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen),
+			    RELOC("mmu"), &prom_mmu, sizeof(prom_mmu)) <= 0) {	
+		prom_print(RELOC(" no MMU found\n"));
+	} else {
+		int nargs;
+		struct prom_args prom_args;
+		nargs = 4;
+		prom_args.service = RELOC("call-method");
+		prom_args.nargs = nargs;
+		prom_args.nret = 4;
+		prom_args.args[0] = RELOC("translate");
+		prom_args.args[1] = prom_mmu;
+		prom_args.args[2] = (void *)(offset + KERNELBASE);
+		prom_args.args[3] = (void *)1;
+		RELOC(prom)(&prom_args);
+
+		/* We assume the phys. address size is 3 cells */
+		if (prom_args.args[nargs] != 0)
+			prom_print(RELOC(" (translate failed) "));
+		else
+			phys = (unsigned long)prom_args.args[nargs+3];
+	}
+
 #ifdef CONFIG_SMP
 	/*
 	 * With CHRP SMP we need to use the OF to start the other
@@ -506,7 +539,7 @@
 		node = call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));
 		if ( (int)call_prom(RELOC("getprop"), 4, 1, node,
 			    RELOC("device_type"),type, sizeof(type)) <= 0)
-			return;
+			return phys;
 		
 		/* copy the holding pattern code to someplace safe (8M) */
 		memcpy( (void *)(8<<20), RELOC(__secondary_hold), 0x100 );
@@ -548,6 +581,7 @@
 			prom_print(RELOC("...failed\n"));
 	}
 #endif	
+	return phys;
 }
 
 /*
@@ -1428,6 +1462,21 @@
 	}
 }
 
+/* Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+__openfirmware
+int
+machine_is_compatible(const char *compat)
+{
+	struct device_node *root;
+	
+	root = find_path_device("/");
+	if (root == 0)
+		return 0;
+	return device_is_compatible(root, compat);
+}
+
 #ifdef CONFIG_BOOTX_TEXT
 
 __pmac
@@ -1986,20 +2035,5 @@
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 
 };
-
-/* Indicates whether the root node has a given value in its
- * compatible property.
- */
-__openfirmware
-int
-machine_is_compatible(const char *compat)
-{
-	struct device_node *root;
-	
-	root = find_path_device("/");
-	if (root == 0)
-		return 0;
-	return device_is_compatible(root, compat);
-}
 
 #endif /* CONFIG_BOOTX_TEXT */

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