patch-2.4.5 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.4.4/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
@@ -1,6 +1,7 @@
 /*
- * $Id: prom.c,v 1.79 1999/10/08 01:56:32 paulus Exp $
- *
+ * BK Id: SCCS/s.prom.c 1.20 05/23/01 00:38:42 cort
+ */
+/*
  * Procedures for interfacing to the Open Firmware PROM on
  * Power Macintosh computers.
  *
@@ -31,7 +32,7 @@
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
 #include <asm/bitops.h>
-/* for openpic_to_irq */
+#include <asm/bootinfo.h>
 #include "open_pic.h"
 
 #ifdef CONFIG_FB
@@ -182,26 +183,6 @@
 #endif
 unsigned long dev_tree_size;
 
-/*
- * prom_init() is called very early on, before the kernel text
- * and data have been mapped to KERNELBASE.  At this point the code
- * is running at whatever address it has been loaded at, so
- * references to extern and static variables must be relocated
- * explicitly.  The procedure reloc_offset() returns the address
- * we're currently running at minus the address we were linked at.
- * (Note that strings count as static variables.)
- *
- * Because OF may have mapped I/O devices into the area starting at
- * KERNELBASE, particularly on CHRP machines, we can't safely call
- * OF once the kernel has been mapped to KERNELBASE.  Therefore all
- * OF calls should be done within prom_init(), and prom_init()
- * and all routines called within it must be careful to relocate
- * references as necessary.
- */
-#define PTRRELOC(x)	((typeof(x))((unsigned long)(x) + offset))
-#define PTRUNRELOC(x)	((typeof(x))((unsigned long)(x) - offset))
-#define RELOC(x)	(*PTRRELOC(&(x)))
-
 #define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
 
 /* Is boot-info compatible ? */
@@ -616,30 +597,10 @@
 	char *p, *d;
 	int prom_version = 0;
  	unsigned long phys;
-	extern char __bss_start, _end;
-
-	/* First zero the BSS -- use memset, some arches don't have
-	 * caches on yet */
-	memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
 
  	/* Default */
  	phys = offset + KERNELBASE;
 
-	/* check if we're apus, return if we are */
-	if ( r3 == 0x61707573 )
-		return phys;
-
-	/* If we came here from BootX, clear the screen,
-	 * set up some pointers and return. */
-	if (r3 == 0x426f6f58 && pp == NULL) {
-		bootx_init(r4, phys);
-		return phys;
-	}
-
-	/* check if we're prep, return if we are */
-	if ( *(unsigned long *)(0) == 0xdeadc0de )
-		return phys;
-
 	/* First get a handle for the stdout device */
 	RELOC(prom) = pp;
 	RELOC(prom_chosen) = call_prom(RELOC("finddevice"), 1, 1,
@@ -757,14 +718,9 @@
 		setup_disp_fake_bi(RELOC(prom_disp_node));
 #endif
 
-	/* If pmac, then use quiesce call. We can't rely on prom_version
-	 * since some old iMacs appear to have an incorrect /openprom/model
-	 * entry in the device tree
-	 */
-	if (!chrp) {
-		prom_print(RELOC("Calling quiesce ...\n"));
-		call_prom(RELOC("quiesce"), 0, 0);
-	}
+	/* Use quiesce call to get OF to shut down any devices it's using */
+	prom_print(RELOC("Calling quiesce ...\n"));
+	call_prom(RELOC("quiesce"), 0, 0);
 
 #ifdef CONFIG_BOOTX_TEXT
 	if (!chrp && RELOC(disp_bi)) {
@@ -839,7 +795,7 @@
 	    __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
 	    prom_drawhex(flags);
 	}
-	if (pvr == 8 || pvr == 12) {
+	if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
 	    prom_drawstring(RELOC("\nICTC             : 0x"));
 	    __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
 	    prom_drawhex(flags);
@@ -986,9 +942,11 @@
 			prom_print(RELOC("... failed\n"));
 		} else {
 			prom_print(RELOC("... ok\n"));
-
-			/* Setup a useable color table when the appropriate
-			 * method is available. Should update this to set-colors */
+			/*
+			 * Setup a usable color table when the appropriate
+			 * method is available.
+			 * Should update this to use set-colors.
+			 */
 			for (i = 0; i < 32; i++)
 				if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
 						   RELOC(default_colors)[i*3+1],
@@ -1267,7 +1225,10 @@
 
 	np->name = get_property(np, "name", 0);
 	np->type = get_property(np, "device_type", 0);
-
+#if 0
+	np->n_addr_cells = naddrc;
+	np->n_size_cells = nsizec;
+#endif
 	/* get the device addresses and interrupts */
 	if (ifunc != NULL) {
 		mem_start = ifunc(np, mem_start, naddrc, nsizec);
@@ -1283,6 +1244,16 @@
 	ip = (int *) get_property(np, "#size-cells", 0);
 	if (ip != NULL)
 		nsizec = *ip;
+#if 0
+	if (np->parent == NULL) {
+		/*
+		 * Set the n_addr/size_cells on the root to its
+		 * own values, rather than 0.
+		 */
+		np->n_addr_cells = naddrc;
+		np->n_size_cells = nsizec;
+	}
+#endif	
 
 	/* the f50 sets the name to 'display' and 'compatible' to what we
 	 * expect for the name -- Cort
@@ -1497,6 +1468,34 @@
 	}
 }
 
+int
+prom_n_addr_cells(struct device_node* np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = (int *) get_property(np, "#address-cells", 0);
+		if (ip != NULL)
+			return *ip;
+	} while(np->parent);
+	return 0;
+}
+
+int
+prom_n_size_cells(struct device_node* np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = (int *) get_property(np, "#size-cells", 0);
+		if (ip != NULL)
+			return *ip;
+	} while(np->parent);
+	return 0;
+}
+
 __init
 static unsigned long
 interpret_pci_props(struct device_node *np, unsigned long mem_start,
@@ -1566,6 +1565,8 @@
 	}
 
 	ip = (int *) get_property(np, "AAPL,interrupts", &l);
+	if (ip == 0 && np->parent)
+		ip = (int *) get_property(np->parent, "AAPL,interrupts", &l);
 	if (ip == 0)
 		ip = (int *) get_property(np, "interrupts", &l);
 	if (ip != 0) {
@@ -1761,7 +1762,7 @@
 		i = 0;
 		adr = (struct address_range *) mem_start;
 		while ((l -= rpsize) >= 0) {
-			adr[i].space = 0;
+			adr[i].space = (naddrc >= 2? rp[naddrc-2]: 0);
 			adr[i].address = rp[naddrc - 1];
 			adr[i].size = rp[naddrc + nsizec - 1];
 			++i;
@@ -1978,12 +1979,13 @@
 {
 	struct property *pp;
 
-	for (pp = np->properties; pp != 0; pp = pp->next)
-		if (strcmp(pp->name, name) == 0) {
+	for (pp = np->properties; pp != 0; pp = pp->next) {
+		if (name && strcmp(pp->name, name) == 0) {
 			if (lenp != 0)
 				*lenp = pp->length;
 			return pp->value;
 		}
+	}
 	return 0;
 }
 
@@ -2161,9 +2163,10 @@
 {
 	if (disp_bi == 0)
 		return;
-	/* check it's the same frame buffer (within 16MB) */
-	if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xff000000)
+	/* check it's the same frame buffer (within 64MB) */
+	if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xfc000000) {
 		return;
+	}
 
 	disp_bi->dispDeviceBase = (__u8 *) phys;
 	disp_bi->dispDeviceRect[0] = 0;

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