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
- Lines: 230
- Date:
Thu May 24 15:03:05 2001
- Orig file:
v2.4.4/linux/arch/ppc/kernel/prom.c
- Orig date:
Sat Mar 3 10:52:14 2001
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)