PERFORCE change 172675 for review
Rafal Jaworowski
raj at FreeBSD.org
Wed Jan 6 21:54:05 UTC 2010
http://p4web.freebsd.org/chv.cgi?CH=172675
Change 172675 by raj at raj_fdt on 2010/01/06 21:53:13
Refactor simplebus and MPC85XX definitions.
- Merge sys/powerpc/include/ocpbus.h into mpc85xx.h (this is the first
step towards recycling ocbush.h)
- Factor out a fdt_common.c from simplebus.c so that routines could be
used by other FDT drivers as well (the upcoming LBC rework)
- Imrove fdtbus driver a bit.
- Temporarily disconnect LBC driver from the build.
Affected files ...
.. //depot/projects/fdt/sys/conf/files.powerpc#10 edit
.. //depot/projects/fdt/sys/powerpc/booke/machdep.c#4 edit
.. //depot/projects/fdt/sys/powerpc/booke/platform_bare.c#2 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/atpic.c#2 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/fdt_common.c#1 add
.. //depot/projects/fdt/sys/powerpc/mpc85xx/fdt_common.h#1 add
.. //depot/projects/fdt/sys/powerpc/mpc85xx/fdtbus.c#4 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/i2c.c#3 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/mpc85xx.h#2 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/ocpbus.c#2 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/simplebus.c#5 edit
Differences ...
==== //depot/projects/fdt/sys/conf/files.powerpc#10 (text+ko) ====
@@ -119,10 +119,11 @@
powerpc/mpc85xx/atpic.c optional mpc85xx isa
powerpc/mpc85xx/ds1553_bus_lbc.c optional ds1553 mpc85xx
powerpc/mpc85xx/ds1553_core.c optional ds1553
+powerpc/mpc85xx/fdt_common.c optional fdt
powerpc/mpc85xx/fdtbus.c optional fdt
powerpc/mpc85xx/i2c.c optional iicbus fdt
powerpc/mpc85xx/isa.c optional mpc85xx isa
-powerpc/mpc85xx/lbc.c optional mpc85xx
+#powerpc/mpc85xx/lbc.c optional mpc85xx
powerpc/mpc85xx/mpc85xx.c optional mpc85xx
powerpc/mpc85xx/nexus.c optional mpc85xx
powerpc/mpc85xx/ocpbus.c optional mpc85xx
==== //depot/projects/fdt/sys/powerpc/booke/machdep.c#4 (text+ko) ====
@@ -137,7 +137,6 @@
#include <dev/ofw/openfirm.h>
-#include <powerpc/mpc85xx/ocpbus.h>
#include <powerpc/mpc85xx/mpc85xx.h>
#ifdef DDB
==== //depot/projects/fdt/sys/powerpc/booke/platform_bare.c#2 (text+ko) ====
@@ -46,7 +46,6 @@
#include <machine/vmparam.h>
#include <powerpc/mpc85xx/mpc85xx.h>
-#include <powerpc/mpc85xx/ocpbus.h>
#include "platform_if.h"
==== //depot/projects/fdt/sys/powerpc/mpc85xx/atpic.c#2 (text+ko) ====
@@ -39,7 +39,7 @@
#include <machine/intr_machdep.h>
#include <machine/pio.h>
-#include <powerpc/mpc85xx/ocpbus.h>
+#include <powerpc/mpc85xx/mpc85xx.h>
#include <dev/ic/i8259.h>
==== //depot/projects/fdt/sys/powerpc/mpc85xx/fdtbus.c#4 (text+ko) ====
@@ -43,6 +43,7 @@
#include <machine/intr_machdep.h>
+#include "fdt_common.h"
#include "ofw_bus_if.h"
#define DEBUG
@@ -60,10 +61,14 @@
extern struct bus_space bs_be_tag;
struct fdtbus_devinfo {
- phandle_t di_node;
- const char *di_name;
- const char *di_type;
- const char *di_compat;
+ phandle_t di_node;
+ char *di_name;
+ char *di_type;
+ char *di_compat;
+ struct resource_list di_res;
+
+ /* Interrupts sense-level info for this device */
+ struct sense_level di_intr_sl[DI_MAX_INTR_NUM];
};
struct fdtbus_softc {
@@ -77,6 +82,7 @@
static int fdtbus_probe(device_t);
static int fdtbus_attach(device_t);
+static int fdtbus_print_child(device_t, device_t);
static struct resource *fdtbus_alloc_resource(device_t, device_t, int,
int *, u_long, u_long, u_long, u_int);
static int fdtbus_release_resource(device_t, device_t, int, int,
@@ -113,6 +119,7 @@
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
+ DEVMETHOD(bus_print_child, fdtbus_print_child),
DEVMETHOD(bus_alloc_resource, fdtbus_alloc_resource),
DEVMETHOD(bus_release_resource, fdtbus_release_resource),
DEVMETHOD(bus_activate_resource, fdtbus_activate_resource),
@@ -143,7 +150,7 @@
fdtbus_probe(device_t dev)
{
- device_set_desc(dev, "FDTbus");
+ device_set_desc(dev, "FDT main bus");
if (!bootverbose)
device_quiet(dev);
return (BUS_PROBE_DEFAULT);
@@ -203,8 +210,6 @@
return (error);
}
- debugf("rmans initialized\n");
-
/*
* Walk the FDT root node and add top-level devices as our children.
*/
@@ -214,6 +219,16 @@
return (bus_generic_attach(dev));
}
+static int
+fdtbus_print_child(device_t bus, device_t child)
+{
+ int rv;
+
+ rv = bus_print_child_header(bus, child);
+ rv += printf("\n");
+ return (rv);
+}
+
/*
* These FDT nodes do not need a corresponding newbus device object.
*/
@@ -223,6 +238,21 @@
NULL
};
+static void
+newbus_device_destroy(device_t dev)
+{
+ struct fdtbus_devinfo *di;
+
+ di = device_get_ivars(dev);
+
+ free(di->di_name, M_OFWPROP);
+ free(di->di_type, M_OFWPROP);
+ free(di->di_compat, M_OFWPROP);
+
+ resource_list_free(&di->di_res);
+ free(di, M_FDTBUS);
+}
+
static device_t
newbus_device_from_fdt_node(device_t parent, phandle_t node)
{
@@ -249,8 +279,33 @@
di->di_name = name;
di->di_type = type;
di->di_compat = compat;
- device_set_ivars(child, di);
- debugf("added child name='%s', node=%p\n", name, (void *)node);
+
+ resource_list_init(&di->di_res);
+
+ /*
+ * XXX this 0x1ef00000 offset is a gross hack, which assumes:
+ * - physical addresses in the DTS are 0xe0000000 range, and
+ * - virtual CCSR base in kernel is 0xfef00000
+ */
+ if (fdt_reg_to_rl(node, &di->di_res, 0x1ef00000)) {
+ device_printf(child, "could not process 'reg' "
+ "property\n");
+ newbus_device_destroy(child);
+ child = NULL;
+ }
+
+ if (fdt_intr_to_rl(node, &di->di_res, di->di_intr_sl)) {
+ device_printf(child, "could not process 'interrupts' "
+ "property\n");
+ newbus_device_destroy(child);
+ child = NULL;
+ }
+
+ if (child != NULL) {
+ device_set_ivars(child, di);
+ debugf("added child name='%s', node=%p\n", name,
+ (void *)node);
+ }
} else {
free(name, M_OFWPROP);
free(type, M_OFWPROP);
@@ -267,8 +322,32 @@
struct fdtbus_softc *sc;
struct resource *res;
struct rman *rm;
+ struct fdtbus_devinfo *di;
+ struct resource_list_entry *rle;
int needactivate;
+ /*
+ * Request for the default allocation with a given rid: use resource
+ * list stored in the local device info.
+ */
+ if ((start == 0UL) && (end == ~0UL)) {
+ if ((di = device_get_ivars(child)) == NULL)
+ return (NULL);
+
+ if (type == SYS_RES_IOPORT)
+ type = SYS_RES_MEMORY;
+
+ rle = resource_list_find(&di->di_res, type, *rid);
+ if (rle == NULL) {
+ device_printf(bus, "no default resources for "
+ "rid = %d, type = %d\n", *rid, type);
+ return (NULL);
+ }
+ start = rle->start;
+ end = rle->end;
+ count = rle->count;
+ }
+
sc = device_get_softc(bus);
needactivate = flags & RF_ACTIVE;
==== //depot/projects/fdt/sys/powerpc/mpc85xx/i2c.c#3 (text+ko) ====
@@ -36,7 +36,6 @@
#include <machine/bus.h>
#include <machine/resource.h>
-#include <machine/ocpbus.h>
#include <sys/rman.h>
#include <sys/lock.h>
==== //depot/projects/fdt/sys/powerpc/mpc85xx/mpc85xx.h#2 (text+ko) ====
@@ -1,5 +1,6 @@
/*-
* Copyright (C) 2008 Semihalf, Rafal Jaworowski
+ * Copyright 2006 by Juniper Networks.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,6 +30,109 @@
#ifndef _MPC85XX_H_
#define _MPC85XX_H_
+/*
+ * Configuration control and status registers
+ */
+#define OCP85XX_CCSRBAR (CCSRBAR_VA + 0x0)
+#define OCP85XX_BPTR (CCSRBAR_VA + 0x20)
+
+/*
+ * E500 Coherency Module registers
+ */
+#define OCP85XX_EEBPCR (CCSRBAR_VA + 0x1010)
+
+/*
+ * Local access registers
+ */
+#define OCP85XX_LAWBAR(n) (CCSRBAR_VA + 0xc08 + 0x20 * (n))
+#define OCP85XX_LAWSR(n) (CCSRBAR_VA + 0xc10 + 0x20 * (n))
+
+#define OCP85XX_TGTIF_PCI0 2
+#define OCP85XX_TGTIF_PCI1 1
+#define OCP85XX_TGTIF_PCI2 0
+#if 0
+#define OCP85XX_TGTIF_PCI0 0
+#define OCP85XX_TGTIF_PCI1 1
+#define OCP85XX_TGTIF_PCI2 2
+#endif
+
+#define OCP85XX_TGTIF_LBC 4
+#define OCP85XX_TGTIF_RAM_INTL 11
+#define OCP85XX_TGTIF_RIO 12
+#define OCP85XX_TGTIF_RAM1 15
+#define OCP85XX_TGTIF_RAM2 22
+
+/*
+ * L2 cache registers
+ */
+#define OCP85XX_L2CTL (CCSRBAR_VA + 0x20000)
+
+/*
+ * Power-On Reset configuration
+ */
+#define OCP85XX_PORDEVSR (CCSRBAR_VA + 0xe000c)
+#define OCP85XX_PORDEVSR_IO_SEL 0x00780000
+#define OCP85XX_PORDEVSR_IO_SEL_SHIFT 19
+
+#define OCP85XX_PORDEVSR2 (CCSRBAR_VA + 0xe0014)
+
+#define OCP85XX_DEVDISR (CCSRBAR_VA + 0xe0070)
+#define OCP85XX_DEVDISR_PCIE0 0x20000000
+#define OCP85XX_DEVDISR_PCIE1 0x04000000
+#define OCP85XX_DEVDISR_PCIE2 0x02000000
+
+/*
+ * Status Registers.
+ */
+#define OCP85XX_RSTCR (CCSRBAR_VA + 0xe00b0)
+
+/*
+ * OCP Bus Definitions
+ */
+#define OCP85XX_I2C0_OFF 0x03000
+#define OCP85XX_I2C1_OFF 0x03100
+#define OCP85XX_I2C_SIZE 0x16
+#define OCP85XX_UART0_OFF 0x04500
+#define OCP85XX_UART1_OFF 0x04600
+#define OCP85XX_UART_SIZE 0x10
+#define OCP85XX_LBC_OFF 0x05000
+#define OCP85XX_LBC_SIZE 0x1000
+
+#define OCP85XX_PCI0_OFF 0x0A000
+#define OCP85XX_PCI1_OFF 0x09000
+#define OCP85XX_PCI2_OFF 0x08000
+#if 0
+#define OCP85XX_PCI0_OFF 0x08000
+#define OCP85XX_PCI1_OFF 0x09000
+#define OCP85XX_PCI2_OFF 0x0A000
+#endif
+
+#define OCP85XX_PCI_SIZE 0x1000
+#define OCP85XX_TSEC0_OFF 0x24000
+#define OCP85XX_TSEC1_OFF 0x25000
+#define OCP85XX_TSEC2_OFF 0x26000
+#define OCP85XX_TSEC3_OFF 0x27000
+#define OCP85XX_TSEC_SIZE 0x1000
+#define OCP85XX_OPENPIC_OFF 0x40000
+#define OCP85XX_OPENPIC_SIZE 0x200B4
+#define OCP85XX_QUICC_OFF 0x80000
+#define OCP85XX_QUICC_SIZE 0x20000
+#define OCP85XX_SEC_OFF 0x30000
+#define OCP85XX_SEC_SIZE 0x10000
+
+/*
+ * PIC definitions
+ */
+#define ISA_IRQ_START 0
+#define PIC_IRQ_START (ISA_IRQ_START + 16)
+
+#define ISA_IRQ(n) (ISA_IRQ_START + (n))
+#define PIC_IRQ_EXT(n) (PIC_IRQ_START + (n))
+#define PIC_IRQ_INT(n) (PIC_IRQ_START + 16 + (n))
+
+/*
+ * Prototypes.
+ */
uint32_t ccsr_read4(uintptr_t addr);
void ccsr_write4(uintptr_t addr, uint32_t val);
int law_enable(int trgt, u_long addr, u_long size);
==== //depot/projects/fdt/sys/powerpc/mpc85xx/ocpbus.c#2 (text+ko) ====
@@ -45,7 +45,6 @@
#include <machine/vmparam.h>
#include <machine/bootinfo.h>
-#include <powerpc/mpc85xx/ocpbus.h>
#include <powerpc/mpc85xx/mpc85xx.h>
#include "pic_if.h"
==== //depot/projects/fdt/sys/powerpc/mpc85xx/simplebus.c#5 (text+ko) ====
@@ -48,7 +48,7 @@
#include "ofw_bus_if.h"
-#include "../../contrib/dtc/libfdt/libfdt_env.h"
+#include "fdt_common.h"
#define DEBUG
#undef DEBUG
@@ -70,27 +70,14 @@
u_long sc_size;
};
-struct sense_level {
- enum intr_trigger trig;
- enum intr_polarity pol;
-};
-
-#define DI_MAX_INTR_NUM 8
-
struct simplebus_devinfo {
struct ofw_bus_devinfo di_ofw;
struct resource_list di_res;
- /* Interrupt-parent phandle */
- phandle_t di_intr_par;
- int di_intr_cells;
-
/* Interrupts sense-level info for this device */
struct sense_level di_intr_sl[DI_MAX_INTR_NUM];
- int di_intr_num;
};
-
/*
* Prototypes.
*/
@@ -155,371 +142,30 @@
{
if (ofw_bus_is_compatible(dev, "simple-bus")) {
- device_set_desc(dev, "Flattened Device Tree simple bus");
+ device_set_desc(dev, "Flattened device tree simple bus");
return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
-static int
-fdt_parent_addr_cells(phandle_t node)
-{
- pcell_t addr_cells;
-
- /* Find out #address-cells of the superior bus. */
- if (OF_searchprop(node, "#address-cells", &addr_cells,
- sizeof(addr_cells)) <= 0)
- addr_cells = 1;
-
- return ((int)addr_cells);
-}
-
-static void
-fdt_ranges_dump(pcell_t *ranges, int tuples, int par_addr_cells,
- int this_addr_cells, int this_size_cells)
-{
-#ifdef DEBUG
- int i, n;
-
- for (i = 0; i < tuples; i++) {
- printf("par addr = ");
- for (n = 0; n < par_addr_cells; n++)
- printf("%x ", ranges[n]);
- printf("\n");
-
- printf("this addr = ");
- for (; n < par_addr_cells + this_addr_cells; n++)
- printf("%x ", ranges[n]);
- printf("\n");
-
- printf("this size = ");
- for (; n < par_addr_cells + this_addr_cells + this_size_cells;
- n++)
- printf("%x ", ranges[n]);
- printf("\n");
- }
-#endif
-}
-
-static int
-fdt_data_verify(void *data, int cells)
-{
- uint64_t d64;
-
- if (cells > 1) {
- d64 = fdt64_to_cpu(*((uint64_t *)data));
- if (((d64 > 32) & 0xffffffffull) != 0)
- return (ERANGE);
- }
-
- return (0);
-}
-
-static u_long
-fdt_data_get(void *data, int cells)
-{
-
- if (cells == 1)
- return (fdt32_to_cpu(*((uint32_t *)data)));
-
- return (fdt64_to_cpu(*((uint64_t *)data)));
-}
-
-static int
-fdt_ranges_verify(pcell_t *ranges, int tuples, int par_addr_cells,
- int this_addr_cells, int this_size_cells)
-{
- int i, rv, ulsz;
-
- if (par_addr_cells > 2 || this_addr_cells > 2 || this_size_cells > 2)
- return (ERANGE);
-
- /*
- * This is the max size the resource manager can handle for addresses
- * and sizes.
- */
- ulsz = sizeof(u_long);
- if (par_addr_cells <= ulsz && this_addr_cells <= ulsz &&
- this_size_cells <= ulsz)
- /* We can handle everything */
- return (0);
-
- rv = 0;
- for (i = 0; i < tuples; i++) {
-
- if (fdt_data_verify((void *)ranges, par_addr_cells))
- goto err;
- ranges += par_addr_cells;
-
- if (fdt_data_verify((void *)ranges, this_addr_cells))
- goto err;
- ranges += this_addr_cells;
-
- if (fdt_data_verify((void *)ranges, this_size_cells))
- goto err;
- ranges += this_size_cells;
- }
-
- return (0);
-
-err:
- printf("using address range >%d-bit not supported\n", ulsz * 8);
- return (ERANGE);
-}
-
-static int
-simplebus_add_reg(phandle_t node, struct simplebus_devinfo *di,
- struct simplebus_softc *sc)
-{
- pcell_t *reg;
- u_long start, end, count;
- int tuple_size, tuples;
- int i;
-
- /* XXX free reg prop? */
- tuple_size = sizeof(pcell_t) * (sc->sc_addr_cells + sc->sc_size_cells);
- tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)®);
- if (tuples <= 0)
- /* No 'reg' property in this node. */
- return (0);
-
- for (i = 0; i < tuples; i++) {
- /* Address portion. */
- if (fdt_data_verify((void *)reg, sc->sc_addr_cells)) {
- debugf("tuple #%d: unsupported addr value in 'reg' "
- "property\n", i);
- goto err;
- }
- start = fdt_data_get((void *)reg, sc->sc_addr_cells);
- reg += sc->sc_addr_cells;
-
- /* Size portion. */
- if (fdt_data_verify((void *)reg, sc->sc_size_cells)) {
- debugf("tuple #%d: unsupported size value in 'reg' "
- "property\n", i);
- goto err;
- }
- count = fdt_data_get((void *)reg, sc->sc_size_cells);
- reg += sc->sc_size_cells;
-
- /* Calculate address range relative to simple-bus VA base. */
- start = sc->sc_start_va + start;
- end = start + count - 1;
-
- debugf("reg addr start = %lx, end = %lx, count = %lx\n", start,
- end, count);
-
- if (end > sc->sc_start_va + sc->sc_size) {
- debugf("end out of simple-bus range: %lx\n", end);
- goto err;
- }
-
- resource_list_add(&di->di_res, SYS_RES_MEMORY, i, start, end,
- count);
- }
- return (0);
-
-err:
- resource_list_free(&di->di_res);
- return (ERANGE);
-}
-
-static int
-fdt_pic_decode_iic(phandle_t node, pcell_t *intr, int intr_cells,
- int *interrupt, int *trig, int *pol)
-{
-
- /* TODO */
- return (ENXIO);
-}
-
-static int
-fdt_pic_decode_openpic(phandle_t node, pcell_t *intr, int intr_cells,
- int *interrupt, int *trig, int *pol)
-{
- char *compat;
- ssize_t prop_len;
- int rv;
-
- prop_len = OF_getprop_alloc(node, "compatible", 1, (void **)&compat);
- if (prop_len <= 0)
- return (ENXIO);
-
- rv = 0;
- if (strncmp("open-pic", compat, 8) < 0) {
- rv = ENXIO;
- goto out;
- }
-
- /*
- * XXX The interrupt number read out from the device tree is already
- * offset by 16 to reflect the 'internal' IRQ range shift on the
- * OpenPIC. We still however need to account for the ISA IRQ block,
- * potentially in use as well.
- */
- *interrupt = ISA_IRQ_COUNT + intr[0];
-
- if (intr_cells == 2)
- switch (intr[1]) {
- case 0:
- /* L to H edge */
- *trig = INTR_TRIGGER_EDGE;
- *pol = INTR_POLARITY_HIGH;
- break;
- case 1:
- /* Active L level */
- *trig = INTR_TRIGGER_LEVEL;
- *pol = INTR_POLARITY_LOW;
- break;
- case 2:
- /* Active H level */
- *trig = INTR_TRIGGER_LEVEL;
- *pol = INTR_POLARITY_HIGH;
- break;
- case 3:
- /* H to L edge */
- *trig = INTR_TRIGGER_EDGE;
- *pol = INTR_POLARITY_LOW;
- break;
- default:
- *trig = INTR_TRIGGER_CONFORM;
- *pol = INTR_POLARITY_CONFORM;
- }
- else {
- *trig = INTR_TRIGGER_CONFORM;
- *pol = INTR_POLARITY_CONFORM;
- }
-
-out:
- free(compat, M_OFWPROP);
- return (rv);
-}
-
-typedef int (*fdt_pic_decode_t)(phandle_t, pcell_t *, int, int *, int *,
- int *);
-
-static fdt_pic_decode_t fdt_pic_table[] = {
- &fdt_pic_decode_iic,
- &fdt_pic_decode_openpic,
- NULL
-};
-
-static int
-fdt_intr_decode(struct simplebus_devinfo *di, pcell_t *intr,
- int *interrupt, int *trig, int *pol)
-{
- fdt_pic_decode_t intr_decode;
- int i, rv;
-
- for (i = 0; fdt_pic_table[i] != NULL; i++) {
-
- /* XXX check if pic_handle has interrupt-controller prop? */
-
- intr_decode = fdt_pic_table[i];
- rv = intr_decode(di->di_intr_par, intr, di->di_intr_cells,
- interrupt, trig, pol);
-
- if (rv == 0)
- /* This was recognized as our PIC and decoded. */
- return (0);
- }
-
- return (ENXIO);
-}
-
-static int
-simplebus_add_one_intr(struct simplebus_devinfo *di, pcell_t *intr)
-{
- int interrupt, trig, pol;
- int intr_num;
-
- intr_num = di->di_intr_num;
-
- if (intr_num > DI_MAX_INTR_NUM) {
- debugf("max intr num reached: %d\n", DI_MAX_INTR_NUM);
- return (ENOMEM);
- }
-
- interrupt = trig = pol = 0;
-
- if (fdt_intr_decode(di, intr, &interrupt, &trig, &pol) != 0)
- return (ENXIO);
-
- if (interrupt <= 0)
- return (ERANGE);
-
- debugf("decoded intr = %d, trig = %d, pol = %d\n", interrupt, trig,
- pol);
-
- di->di_intr_sl[intr_num].trig = trig;
- di->di_intr_sl[intr_num].pol = pol;
-
- resource_list_add(&di->di_res, SYS_RES_IRQ, intr_num,
- interrupt, interrupt, 1);
-
- di->di_intr_num++;
-
- return (0);
-}
-
-static int
-simplebus_add_intr(phandle_t node, struct simplebus_devinfo *di)
-{
- phandle_t intr_par;
- ihandle_t iph;
- pcell_t *intr;
- pcell_t intr_cells;
- int i, intr_num, rv;
-
- if (OF_getproplen(node, "interrupts") <= 0)
- /* Node does not have 'interrupts' property. */
- return (0);
-
- /*
- * Find #interrupt-cells of the interrupt domain.
- */
- if (OF_getprop(node, "interrupt-parent", &iph, sizeof(iph)) <= 0) {
- debugf("no intr-parent phandle\n");
- intr_par = OF_parent(node);
- } else
- intr_par = OF_instance_to_package(iph);
-
- if (OF_getprop(intr_par, "#interrupt-cells", &intr_cells,
- sizeof(intr_cells)) <= 0) {
- debugf("no intr-cells defined, defaulting to 1\n");
- intr_cells = 1;
- }
-
- intr_num = OF_getprop_alloc(node, "interrupts",
- intr_cells * sizeof(pcell_t), (void **)&intr);
- if (intr_num <= 0)
- return (ERANGE);
-
- rv = 0;
- di->di_intr_num = 0;
- di->di_intr_par = intr_par;
- di->di_intr_cells = intr_cells;
- for (i = 0; i < intr_num; i++) {
- rv = simplebus_add_one_intr(di, &intr[i * intr_cells]);
- if (rv != 0) {
- /* XXX resource_list_free(&di->di_res); ??? */
- goto out;
- }
- }
-
-out:
- free(intr, M_OFWPROP);
- return (rv);
-}
-
static void
simplebus_fixup(phandle_t node)
{
- phandle_t cpus, child;
+ phandle_t cpus, child, root;
+ char *model;
pcell_t freq;
+ int len;
- /* XXX this whole fixup should depend on 8555 SOC */
+ /* Fixup handling is platform specific. */
+ if ((root = OF_finddevice("/")) == 0)
+ panic("simplebus: no root node");
+ len = OF_getprop_alloc(root, "model", 1, (void **)&model);
+ if (len <= 0)
+ return;
+ if (!(strcmp(model, "fsl,MPC8572DS") == 0 ||
+ strcmp(model, "MPC8555CDS") == 0))
+ goto out;
if ((cpus = OF_finddevice("/cpus")) == 0)
panic("simplebus: no /cpus node");
@@ -532,6 +178,8 @@
return;
OF_setprop(node, "bus-frequency", (void *)&freq, sizeof(freq));
+out:
+ free(model, M_OFWPROP);
}
static int
@@ -543,34 +191,19 @@
struct simplebus_devinfo *di;
struct simplebus_softc *sc;
phandle_t node, child;
- pcell_t cell;
- ssize_t prop_len;
- int cell_size, tuple_size, tuples;
+ int tuple_size, tuples;
int par_addr_cells;
sc = device_get_softc(dev);
node = ofw_bus_get_node(dev);
- cell_size = sizeof(cell);
+
+ if ((fdt_addrsize_cells(node, &sc->sc_addr_cells,
+ &sc->sc_size_cells)) != 0)
+ return (ENXIO);
simplebus_fixup(node);
/*
- * Retrieve #{address,size}-cells.
- */
- if (OF_getprop(node, "#address-cells", &cell, cell_size) < cell_size)
- cell = 2;
- sc->sc_addr_cells = (int)cell;
-
- if (OF_getprop(node, "#size-cells", &cell, cell_size) < cell_size)
- cell = 1;
- sc->sc_size_cells = (int)cell;
-
- if (sc->sc_addr_cells > 2 || sc->sc_size_cells > 2) {
- device_printf(dev, "unsupported # of cells\n");
- return (ERANGE);
- }
-
- /*
* Process 'ranges' property.
*/
par_addr_cells = fdt_parent_addr_cells(node);
@@ -578,22 +211,16 @@
device_printf(dev, "unsupported parent #addr-cells\n");
return (ERANGE);
}
- tuple_size = cell_size * (sc->sc_addr_cells + par_addr_cells +
+ tuple_size = sizeof(pcell_t) * (sc->sc_addr_cells + par_addr_cells +
sc->sc_size_cells);
- /* XXX free ranges prop? */
- prop_len = OF_getprop_alloc(node, "ranges", 1, (void **)&ranges);
+ /* TODO free ranges prop */
+ tuples = OF_getprop_alloc(node, "ranges", tuple_size,
+ (void **)&ranges);
start = 0;
size = 0;
- if (prop_len >= 0) {
-
- if (prop_len % tuple_size) {
- device_printf(dev, "inconsistent 'ranges' property\n");
- return (ENXIO);
- }
- tuples = prop_len / tuple_size;
-
+ if (tuples > 0) {
fdt_ranges_dump(ranges, tuples, par_addr_cells,
sc->sc_addr_cells, sc->sc_size_cells);
@@ -631,14 +258,15 @@
resource_list_init(&di->di_res);
- if (simplebus_add_reg(child, di, sc)) {
+ if (fdt_reg_to_rl(child, &di->di_res, sc->sc_start_va)) {
device_printf(dev, "could not process 'reg' "
"property\n");
ofw_bus_gen_destroy_devinfo(&di->di_ofw);
free(di, M_SIMPLEBUS);
continue;
}
- if (simplebus_add_intr(child, di)) {
+
+ if (fdt_intr_to_rl(child, &di->di_res, di->di_intr_sl)) {
device_printf(dev, "could not process 'interrupts' "
"property\n");
resource_list_free(&di->di_res);
More information about the p4-projects
mailing list