* [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress
@ 2007-11-19 8:25 Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 1/9] powerpc: Make isa_mem_base common to 32 and 64 bits Benjamin Herrenschmidt
` (8 more replies)
0 siblings, 9 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
Because a mailing list is the best of backups and I've get something
working allright on ebony right now, I figured I would post my WIP
pile of patch bringing PCI to the 44x arch/powerpc world.
At this stage, only ebony is hooked up, there's a known problem with
the SCSI layer and non-coherent architecture that causes random
corruption for which I'm trying to find a solution, and e1000 has a
problem with resources > 32 bits for which I have a separate patch.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 1/9] powerpc: Make isa_mem_base common to 32 and 64 bits
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
@ 2007-11-19 8:25 ` Benjamin Herrenschmidt
2007-11-19 10:32 ` Christoph Hellwig
2007-11-19 8:25 ` [RFC/PATCH 2/9] powerpc: Merge pci_process_bridge_OF_ranges() Benjamin Herrenschmidt
` (7 subsequent siblings)
8 siblings, 1 reply; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
This defines isa_mem_base on both 32 and 64 bits (it used to be 32 bits
only). This avoids a few ifdef's in later patches and potentially can
allow support for VGA text mode on 64 bits powerpc.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Small cleanup pre-requisite for my next patch
arch/powerpc/kernel/pci-common.c | 4 ++++
arch/powerpc/kernel/pci_32.c | 1 -
include/asm-powerpc/io.h | 5 +++--
3 files changed, 7 insertions(+), 3 deletions(-)
Index: linux-work/arch/powerpc/kernel/pci-common.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci-common.c 2007-11-13 14:11:11.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c 2007-11-13 14:15:43.000000000 +1100
@@ -52,6 +52,10 @@ int global_phb_number; /* Global phb co
extern struct list_head hose_list;
+/* ISA Memory physical address (or 0 if none) */
+resource_size_t isa_mem_base = 0;
+
+
/*
* pci_controller(phb) initialized common variables.
*/
Index: linux-work/include/asm-powerpc/io.h
===================================================================
--- linux-work.orig/include/asm-powerpc/io.h 2007-11-13 14:12:01.000000000 +1100
+++ linux-work/include/asm-powerpc/io.h 2007-11-13 14:12:48.000000000 +1100
@@ -50,15 +50,16 @@ extern int check_legacy_ioport(unsigned
#define PCI_DRAM_OFFSET pci_dram_offset
#else
#define _IO_BASE pci_io_base
-#define _ISA_MEM_BASE 0
+#define _ISA_MEM_BASE isa_mem_base
#define PCI_DRAM_OFFSET 0
#endif
extern unsigned long isa_io_base;
-extern unsigned long isa_mem_base;
extern unsigned long pci_io_base;
extern unsigned long pci_dram_offset;
+extern resource_size_t isa_mem_base;
+
#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_INDIRECT_IO)
#error CONFIG_PPC_INDIRECT_IO is not yet supported on 32 bits
#endif
Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c 2007-11-13 14:16:15.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c 2007-11-13 14:16:17.000000000 +1100
@@ -32,7 +32,6 @@
#endif
unsigned long isa_io_base = 0;
-unsigned long isa_mem_base = 0;
unsigned long pci_dram_offset = 0;
int pcibios_assign_bus_offset = 1;
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 2/9] powerpc: Merge pci_process_bridge_OF_ranges()
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 1/9] powerpc: Make isa_mem_base common to 32 and 64 bits Benjamin Herrenschmidt
@ 2007-11-19 8:25 ` Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 3/9] powerpc: Fix declaration of pcibios_free_controller Benjamin Herrenschmidt
` (6 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
This patch merges the 32 and 64 bits implementations of
pci_process_bridge_OF_ranges(). The new function is cleaner than both
the old ones supports 64 bits ranges on ppc32 which is necessary for
the 4xx port.
It also adds some better (hopefully) output to the kernel log which
should help disagnose problems and makes better use of existing OF
parsing helpers (avoiding a few bugs of both implementations along
the way).
There are still a few unfortunate ifdef's but there is no way around
these for now at least not until some other bits of the PCI code are
made common.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Tested on a few pSeries, PowerMac G5, and a 32 bits PowerMacs and
a BriQ. Please let me know if it misbehaves anywhere else.
arch/powerpc/kernel/pci-common.c | 176 +++++++++++++++++++++++++++++++++++++++
arch/powerpc/kernel/pci_32.c | 114 -------------------------
arch/powerpc/kernel/pci_64.c | 93 --------------------
include/asm-powerpc/pci-bridge.h | 1
4 files changed, 177 insertions(+), 207 deletions(-)
Index: linux-work/arch/powerpc/kernel/pci-common.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci-common.c 2007-11-13 14:15:43.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c 2007-11-13 16:04:06.000000000 +1100
@@ -479,3 +479,179 @@ void pci_resource_to_user(const struct p
*start = rsrc->start - offset;
*end = rsrc->end - offset;
}
+
+/**
+ * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
+ * @hose: newly allocated pci_controller to be setup
+ * @dev: device node of the host bridge
+ * @primary: set if primary bus (32 bits only, soon to be deprecated)
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping of a pci controller based on its
+ * content.
+ *
+ * Life would be boring if it wasn't for a few issues that we have to deal
+ * with here:
+ *
+ * - We can only cope with one IO space range and up to 3 Memory space
+ * ranges. However, some machines (thanks Apple !) tend to split their
+ * space into lots of small contiguous ranges. So we have to coalesce.
+ *
+ * - We can only cope with all memory ranges having the same offset
+ * between CPU addresses and PCI addresses. Unfortunately, some bridges
+ * are setup for a large 1:1 mapping along with a small "window" which
+ * maps PCI address 0 to some arbitrary high address of the CPU space in
+ * order to give access to the ISA memory hole.
+ * The way out of here that I've chosen for now is to always set the
+ * offset based on the first resource found, then override it if we
+ * have a different offset and the previous was set by an ISA hole.
+ *
+ * - Some busses have IO space not starting at 0, which causes trouble with
+ * the way we do our IO resource renumbering. The code somewhat deals with
+ * it for 64 bits but I would expect problems on 32 bits.
+ *
+ * - Some 32 bits platforms such as 4xx can have physical space larger than
+ * 32 bits so we need to use 64 bits values for the parsing
+ */
+void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+ struct device_node *dev,
+ int primary)
+{
+ const u32 *ranges;
+ int rlen;
+ int pna = of_n_addr_cells(dev);
+ int np = pna + 5;
+ int memno = 0, isa_hole = -1;
+ u32 pci_space;
+ unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
+ unsigned long long isa_mb = 0;
+ struct resource *res;
+
+ printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
+ dev->full_name, primary ? "(primary)" : "");
+
+ /* Get ranges property */
+ ranges = of_get_property(dev, "ranges", &rlen);
+ if (ranges == NULL)
+ return;
+
+ /* Parse it */
+ while ((rlen -= np * 4) >= 0) {
+ /* Read next ranges element */
+ pci_space = ranges[0];
+ pci_addr = of_read_number(ranges + 1, 2);
+ cpu_addr = of_translate_address(dev, ranges + 3);
+ size = of_read_number(ranges + pna + 3, 2);
+ ranges += np;
+ if (cpu_addr == OF_BAD_ADDR || size == 0)
+ continue;
+
+ /* Now consume following elements while they are contiguous */
+ for (;rlen >= np * sizeof(u32); ranges += np, rlen -= np * 4) {
+ if (ranges[0] != pci_space)
+ break;
+ pci_next = of_read_number(ranges + 1, 2);
+ cpu_next = of_translate_address(dev, ranges + 3);
+ if (pci_next != pci_addr + size ||
+ cpu_next != cpu_addr + size)
+ break;
+ size += of_read_number(ranges + pna + 3, 2);
+ }
+
+ /* Act based on address space type */
+ res = NULL;
+ switch ((pci_space >> 24) & 0x3) {
+ case 1: /* PCI IO space */
+ printk(KERN_INFO
+ " IO 0x%016llx..0x%016llx -> 0x%016llx\n",
+ cpu_addr, cpu_addr + size - 1, pci_addr);
+
+ /* We support only one IO range */
+ if (hose->pci_io_size) {
+ printk(KERN_WARNING
+ " \\--> Skipped (too many) !\n");
+ continue;
+ }
+#ifdef CONFIG_PPC32
+ /* On 32 bits, limit I/O space to 16MB */
+ if (size > 0x01000000)
+ size = 0x01000000;
+
+ /* 32 bits needs to map IOs here */
+ hose->io_base_virt = ioremap(cpu_addr, size);
+
+ /* Expect trouble if pci_addr is not 0 */
+ if (primary)
+ isa_io_base =
+ (unsigned long)hose->io_base_virt;
+#endif /* CONFIG_PPC32 */
+ /* pci_io_size and io_base_phys always represent IO
+ * space starting at 0 so we factor in pci_addr
+ */
+ hose->pci_io_size = pci_addr + size;
+ hose->io_base_phys = cpu_addr - pci_addr;
+
+ /* Build resource */
+ res = &hose->io_resource;
+ res->flags = IORESOURCE_IO;
+ res->start = pci_addr;
+ break;
+ case 2: /* PCI Memory space */
+ printk(KERN_INFO
+ " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
+ cpu_addr, cpu_addr + size - 1, pci_addr,
+ (pci_space & 0x40000000) ? "Prefetch" : "");
+
+ /* We support only 3 memory ranges */
+ if (memno >= 3) {
+ printk(KERN_WARNING
+ " \\--> Skipped (too many) !\n");
+ continue;
+ }
+ /* Handles ISA memory hole space here */
+ if (pci_addr == 0) {
+ isa_mb = cpu_addr;
+ isa_hole = memno;
+ if (primary || isa_mem_base == 0)
+ isa_mem_base = cpu_addr;
+ }
+
+ /* We get the PCI/Mem offset from the first range or the,
+ * current one if the offset came from an ISA hole.
+ * If they don't match, bugger.
+ */
+ if (memno == 0 ||
+ (isa_hole >= 0 && pci_addr != 0 &&
+ hose->pci_mem_offset == isa_mb))
+ hose->pci_mem_offset = cpu_addr - pci_addr;
+ else if (pci_addr != 0 &&
+ hose->pci_mem_offset != cpu_addr - pci_addr) {
+ printk(KERN_WARNING
+ " \\--> Skipped (offset mismatch) !\n");
+ continue;
+ }
+
+ /* Build resource */
+ res = &hose->mem_resources[memno++];
+ res->flags = IORESOURCE_MEM;
+ if (pci_space & 0x40000000)
+ res->flags |= IORESOURCE_PREFETCH;
+ res->start = cpu_addr;
+ break;
+ }
+ if (res != NULL) {
+ res->name = dev->full_name;
+ res->end = res->start + size - 1;
+ res->parent = NULL;
+ res->sibling = NULL;
+ res->child = NULL;
+ }
+ }
+
+ /* Out of paranoia, let's put the ISA hole last if any */
+ if (isa_hole >= 0 && memno > 0 && isa_hole != (memno-1)) {
+ struct resource tmp = hose->mem_resources[isa_hole];
+ hose->mem_resources[isa_hole] = hose->mem_resources[memno-1];
+ hose->mem_resources[memno-1] = tmp;
+ }
+}
Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c 2007-11-13 14:16:17.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c 2007-11-13 14:16:24.000000000 +1100
@@ -842,120 +842,6 @@ pci_device_from_OF_node(struct device_no
}
EXPORT_SYMBOL(pci_device_from_OF_node);
-void __init
-pci_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev, int primary)
-{
- static unsigned int static_lc_ranges[256] __initdata;
- const unsigned int *dt_ranges;
- unsigned int *lc_ranges, *ranges, *prev, size;
- int rlen = 0, orig_rlen;
- int memno = 0;
- struct resource *res;
- int np, na = of_n_addr_cells(dev);
- np = na + 5;
-
- /* First we try to merge ranges to fix a problem with some pmacs
- * that can have more than 3 ranges, fortunately using contiguous
- * addresses -- BenH
- */
- dt_ranges = of_get_property(dev, "ranges", &rlen);
- if (!dt_ranges)
- return;
- /* Sanity check, though hopefully that never happens */
- if (rlen > sizeof(static_lc_ranges)) {
- printk(KERN_WARNING "OF ranges property too large !\n");
- rlen = sizeof(static_lc_ranges);
- }
- lc_ranges = static_lc_ranges;
- memcpy(lc_ranges, dt_ranges, rlen);
- orig_rlen = rlen;
-
- /* Let's work on a copy of the "ranges" property instead of damaging
- * the device-tree image in memory
- */
- ranges = lc_ranges;
- prev = NULL;
- while ((rlen -= np * sizeof(unsigned int)) >= 0) {
- if (prev) {
- if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
- (prev[2] + prev[na+4]) == ranges[2] &&
- (prev[na+2] + prev[na+4]) == ranges[na+2]) {
- prev[na+4] += ranges[na+4];
- ranges[0] = 0;
- ranges += np;
- continue;
- }
- }
- prev = ranges;
- ranges += np;
- }
-
- /*
- * The ranges property is laid out as an array of elements,
- * each of which comprises:
- * cells 0 - 2: a PCI address
- * cells 3 or 3+4: a CPU physical address
- * (size depending on dev->n_addr_cells)
- * cells 4+5 or 5+6: the size of the range
- */
- ranges = lc_ranges;
- rlen = orig_rlen;
- while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
- res = NULL;
- size = ranges[na+4];
- switch ((ranges[0] >> 24) & 0x3) {
- case 1: /* I/O space */
- if (ranges[2] != 0)
- break;
- hose->io_base_phys = ranges[na+2];
- /* limit I/O space to 16MB */
- if (size > 0x01000000)
- size = 0x01000000;
- hose->io_base_virt = ioremap(ranges[na+2], size);
- if (primary)
- isa_io_base = (unsigned long) hose->io_base_virt;
- res = &hose->io_resource;
- res->flags = IORESOURCE_IO;
- res->start = ranges[2];
- DBG("PCI: IO 0x%llx -> 0x%llx\n",
- (u64)res->start, (u64)res->start + size - 1);
- break;
- case 2: /* memory space */
- memno = 0;
- if (ranges[1] == 0 && ranges[2] == 0
- && ranges[na+4] <= (16 << 20)) {
- /* 1st 16MB, i.e. ISA memory area */
- if (primary)
- isa_mem_base = ranges[na+2];
- memno = 1;
- }
- while (memno < 3 && hose->mem_resources[memno].flags)
- ++memno;
- if (memno == 0)
- hose->pci_mem_offset = ranges[na+2] - ranges[2];
- if (memno < 3) {
- res = &hose->mem_resources[memno];
- res->flags = IORESOURCE_MEM;
- if(ranges[0] & 0x40000000)
- res->flags |= IORESOURCE_PREFETCH;
- res->start = ranges[na+2];
- DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
- (u64)res->start, (u64)res->start + size - 1);
- }
- break;
- }
- if (res != NULL) {
- res->name = dev->full_name;
- res->end = res->start + size - 1;
- res->parent = NULL;
- res->sibling = NULL;
- res->child = NULL;
- }
- ranges += np;
- }
-}
-
/* We create the "pci-OF-bus-map" property now so it appears in the
* /proc device tree
*/
Index: linux-work/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_64.c 2007-11-13 14:15:43.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_64.c 2007-11-13 14:16:24.000000000 +1100
@@ -592,99 +592,6 @@ int pci_proc_domain(struct pci_bus *bus)
}
}
-void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev, int prim)
-{
- const unsigned int *ranges;
- unsigned int pci_space;
- unsigned long size;
- int rlen = 0;
- int memno = 0;
- struct resource *res;
- int np, na = of_n_addr_cells(dev);
- unsigned long pci_addr, cpu_phys_addr;
-
- np = na + 5;
-
- /* From "PCI Binding to 1275"
- * The ranges property is laid out as an array of elements,
- * each of which comprises:
- * cells 0 - 2: a PCI address
- * cells 3 or 3+4: a CPU physical address
- * (size depending on dev->n_addr_cells)
- * cells 4+5 or 5+6: the size of the range
- */
- ranges = of_get_property(dev, "ranges", &rlen);
- if (ranges == NULL)
- return;
- hose->io_base_phys = 0;
- while ((rlen -= np * sizeof(unsigned int)) >= 0) {
- res = NULL;
- pci_space = ranges[0];
- pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
- cpu_phys_addr = of_translate_address(dev, &ranges[3]);
- size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
- ranges += np;
- if (size == 0)
- continue;
-
- /* Now consume following elements while they are contiguous */
- while (rlen >= np * sizeof(unsigned int)) {
- unsigned long addr, phys;
-
- if (ranges[0] != pci_space)
- break;
- addr = ((unsigned long)ranges[1] << 32) | ranges[2];
- phys = ranges[3];
- if (na >= 2)
- phys = (phys << 32) | ranges[4];
- if (addr != pci_addr + size ||
- phys != cpu_phys_addr + size)
- break;
-
- size += ((unsigned long)ranges[na+3] << 32)
- | ranges[na+4];
- ranges += np;
- rlen -= np * sizeof(unsigned int);
- }
-
- switch ((pci_space >> 24) & 0x3) {
- case 1: /* I/O space */
- hose->io_base_phys = cpu_phys_addr - pci_addr;
- /* handle from 0 to top of I/O window */
- hose->pci_io_size = pci_addr + size;
-
- res = &hose->io_resource;
- res->flags = IORESOURCE_IO;
- res->start = pci_addr;
- DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number,
- res->start, res->start + size - 1);
- break;
- case 2: /* memory space */
- memno = 0;
- while (memno < 3 && hose->mem_resources[memno].flags)
- ++memno;
-
- if (memno == 0)
- hose->pci_mem_offset = cpu_phys_addr - pci_addr;
- if (memno < 3) {
- res = &hose->mem_resources[memno];
- res->flags = IORESOURCE_MEM;
- res->start = cpu_phys_addr;
- DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number,
- res->start, res->start + size - 1);
- }
- break;
- }
- if (res != NULL) {
- res->name = dev->full_name;
- res->end = res->start + size - 1;
- res->parent = NULL;
- res->sibling = NULL;
- res->child = NULL;
- }
- }
-}
#ifdef CONFIG_HOTPLUG
Index: linux-work/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-work.orig/include/asm-powerpc/pci-bridge.h 2007-11-13 14:15:43.000000000 +1100
+++ linux-work/include/asm-powerpc/pci-bridge.h 2007-11-13 14:16:24.000000000 +1100
@@ -27,6 +27,7 @@ struct pci_controller {
void __iomem *io_base_virt;
resource_size_t io_base_phys;
+ resource_size_t pci_io_size;
/* Some machines (PReP) have a non 1:1 mapping of
* the PCI memory space in the CPU bus space
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 3/9] powerpc: Fix declaration of pcibios_free_controller
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 1/9] powerpc: Make isa_mem_base common to 32 and 64 bits Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 2/9] powerpc: Merge pci_process_bridge_OF_ranges() Benjamin Herrenschmidt
@ 2007-11-19 8:25 ` Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 4/9] powerpc: Fix powerpc 32 bits resource fixup for 64 bits resources Benjamin Herrenschmidt
` (5 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
pcibios_free_controller() is now available for both 32 and 64 bits
but the header only declares it for 64 bits. This moves the
declaration down next to the pcibios_alloc_controller() one.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
include/asm-powerpc/pci-bridge.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
Index: linux-work/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-work.orig/include/asm-powerpc/pci-bridge.h 2007-11-16 13:44:32.000000000 +1100
+++ linux-work/include/asm-powerpc/pci-bridge.h 2007-11-16 13:46:40.000000000 +1100
@@ -247,7 +247,6 @@ static inline struct pci_controller *pci
return PCI_DN(busdn)->phb;
}
-extern void pcibios_free_controller(struct pci_controller *phb);
extern void isa_bridge_find_early(struct pci_controller *hose);
@@ -283,9 +282,11 @@ extern void
pci_process_bridge_OF_ranges(struct pci_controller *hose,
struct device_node *dev, int primary);
-/* Allocate a new PCI host bridge structure */
+/* Allocate & free a PCI host bridge structure */
extern struct pci_controller *
pcibios_alloc_controller(struct device_node *dev);
+extern void pcibios_free_controller(struct pci_controller *phb);
+
#ifdef CONFIG_PCI
extern unsigned long pci_address_to_pio(phys_addr_t address);
extern int pcibios_vaddr_is_ioport(void __iomem *address);
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 4/9] powerpc: Fix powerpc 32 bits resource fixup for 64 bits resources
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
` (2 preceding siblings ...)
2007-11-19 8:25 ` [RFC/PATCH 3/9] powerpc: Fix declaration of pcibios_free_controller Benjamin Herrenschmidt
@ 2007-11-19 8:25 ` Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 5/9] powerpc: Fix 440/440A machine check handling Benjamin Herrenschmidt
` (4 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
The 32bits powerpc resource fixup code uses unsigned longs to do the
offseting of resources which overflows on platforms such as 4xx where
resources can be 64 bits.
This fixes it by using resource_size_t instead.
However, the IO stuff does rely on some 32 bits arithmetic, so we hack
by cropping the result of the fixups for IO resources with a 32 bits
mask.
This isn't the prettiest but should work for now until we change the
32 bits PCI code to do IO mappings like 64 bits does, within a reserved
are of the kernel address space.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
DO NOT MERGE YET ! This has only been tested with some preliminary PCI
support code I have for Ebony, I haven't yet verified that the masking
stuff works fine on 32 bits machines with multiple busses and negative
offsets.
arch/powerpc/kernel/pci_32.c | 44 +++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c 2007-11-16 15:48:27.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c 2007-11-16 15:55:54.000000000 +1100
@@ -104,7 +104,7 @@ pcibios_fixup_resources(struct pci_dev *
{
struct pci_controller* hose = (struct pci_controller *)dev->sysdata;
int i;
- unsigned long offset;
+ resource_size_t offset, mask;
if (!hose) {
printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev));
@@ -123,15 +123,17 @@ pcibios_fixup_resources(struct pci_dev *
continue;
}
offset = 0;
+ mask = (resource_size_t)-1;
if (res->flags & IORESOURCE_MEM) {
offset = hose->pci_mem_offset;
} else if (res->flags & IORESOURCE_IO) {
offset = (unsigned long) hose->io_base_virt
- isa_io_base;
+ mask = 0xffffffffu;
}
if (offset != 0) {
- res->start += offset;
- res->end += offset;
+ res->start = (res->start + offset) & mask;
+ res->end = (res->end + offset) & mask;
DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n",
i, res->flags, pci_name(dev),
(u64)res->start - offset, (u64)res->start);
@@ -147,30 +149,32 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PC
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
struct resource *res)
{
- unsigned long offset = 0;
+ resource_size_t offset = 0, mask = (resource_size_t)-1;
struct pci_controller *hose = dev->sysdata;
- if (hose && res->flags & IORESOURCE_IO)
+ if (hose && res->flags & IORESOURCE_IO) {
offset = (unsigned long)hose->io_base_virt - isa_io_base;
- else if (hose && res->flags & IORESOURCE_MEM)
+ mask = 0xffffffffu;
+ } else if (hose && res->flags & IORESOURCE_MEM)
offset = hose->pci_mem_offset;
- region->start = res->start - offset;
- region->end = res->end - offset;
+ region->start = (res->start - offset) & mask;
+ region->end = (res->end - offset) & mask;
}
EXPORT_SYMBOL(pcibios_resource_to_bus);
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region)
{
- unsigned long offset = 0;
+ resource_size_t offset = 0, mask = (resource_size_t)-1;
struct pci_controller *hose = dev->sysdata;
- if (hose && res->flags & IORESOURCE_IO)
+ if (hose && res->flags & IORESOURCE_IO) {
offset = (unsigned long)hose->io_base_virt - isa_io_base;
- else if (hose && res->flags & IORESOURCE_MEM)
+ mask = 0xffffffffu;
+ } else if (hose && res->flags & IORESOURCE_MEM)
offset = hose->pci_mem_offset;
- res->start = region->start + offset;
- res->end = region->end + offset;
+ res->start = (region->start + offset) & mask;
+ res->end = (region->end + offset) & mask;
}
EXPORT_SYMBOL(pcibios_bus_to_resource);
@@ -334,9 +338,9 @@ static int __init
pci_relocate_bridge_resource(struct pci_bus *bus, int i)
{
struct resource *res, *pr, *conflict;
- unsigned long try, size;
- int j;
+ resource_size_t try, size;
struct pci_bus *parent = bus->parent;
+ int j;
if (parent == NULL) {
/* shouldn't ever happen */
@@ -438,7 +442,7 @@ update_bridge_resource(struct pci_dev *d
u8 io_base_lo, io_limit_lo;
u16 mem_base, mem_limit;
u16 cmd;
- unsigned long start, end, off;
+ resource_size_t start, end, off;
struct pci_controller *hose = dev->sysdata;
if (!hose) {
@@ -1157,8 +1161,8 @@ void pcibios_fixup_bus(struct pci_bus *b
res->end = IO_SPACE_LIMIT;
res->flags = IORESOURCE_IO;
}
- res->start += io_offset;
- res->end += io_offset;
+ res->start = (res->start + io_offset) & 0xffffffffu;
+ res->end = (res->end + io_offset) & 0xffffffffu;
for (i = 0; i < 3; ++i) {
res = &hose->mem_resources[i];
@@ -1183,8 +1187,8 @@ void pcibios_fixup_bus(struct pci_bus *b
if (!res->flags || bus->self->transparent)
continue;
if (io_offset && (res->flags & IORESOURCE_IO)) {
- res->start += io_offset;
- res->end += io_offset;
+ res->start = (res->start + io_offset) & 0xffffffffu;
+ res->end = (res->end + io_offset) & 0xffffffffu;
} else if (hose->pci_mem_offset
&& (res->flags & IORESOURCE_MEM)) {
res->start += hose->pci_mem_offset;
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 5/9] powerpc: Fix 440/440A machine check handling
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
` (3 preceding siblings ...)
2007-11-19 8:25 ` [RFC/PATCH 4/9] powerpc: Fix powerpc 32 bits resource fixup for 64 bits resources Benjamin Herrenschmidt
@ 2007-11-19 8:25 ` Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 6/9] powerpc: Add xmon function to dump 44x TLB Benjamin Herrenschmidt
` (3 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
This removes CONFIG_440A which was a problem for multiplatform
kernels and instead fixes up the IVOR at runtime from a setup_cpu
function. The "A" version of the machine check also tweaks the
regs->trap value to differenciate the 2 versions at the C level.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/cpu_setup_44x.S | 4 +-
arch/powerpc/kernel/cputable.c | 5 +++
arch/powerpc/kernel/head_44x.S | 14 ++++++--
arch/powerpc/kernel/head_booke.h | 2 -
arch/powerpc/kernel/traps.c | 58 +++++++++++++++++++++++++++++-------
arch/powerpc/platforms/44x/Kconfig | 5 ---
include/asm-powerpc/ptrace.h | 3 +
include/asm-powerpc/reg_booke.h | 3 -
8 files changed, 70 insertions(+), 24 deletions(-)
Index: linux-work/arch/powerpc/kernel/cpu_setup_44x.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/cpu_setup_44x.S 2007-11-19 16:38:11.000000000 +1100
+++ linux-work/arch/powerpc/kernel/cpu_setup_44x.S 2007-11-19 16:58:25.000000000 +1100
@@ -23,11 +23,13 @@ _GLOBAL(__setup_cpu_440epx)
mflr r4
bl __init_fpu_44x
bl __plb_disable_wrp
+ bl __fixup_440A_mcheck
mtlr r4
blr
_GLOBAL(__setup_cpu_440grx)
b __plb_disable_wrp
-
+_GLOBAL(__setup_cpu_440gx)
+ b __fixup_440A_mcheck
/* enable APU between CPU and FPU */
_GLOBAL(__init_fpu_44x)
Index: linux-work/arch/powerpc/kernel/cputable.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/cputable.c 2007-11-19 16:36:53.000000000 +1100
+++ linux-work/arch/powerpc/kernel/cputable.c 2007-11-19 16:37:31.000000000 +1100
@@ -33,6 +33,7 @@ EXPORT_SYMBOL(cur_cpu_spec);
#ifdef CONFIG_PPC32
extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
@@ -1193,6 +1194,7 @@ static struct cpu_spec __initdata cpu_sp
.cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32,
.dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_440gx,
.platform = "ppc440",
},
{ /* 440GX Rev. B */
@@ -1203,6 +1205,7 @@ static struct cpu_spec __initdata cpu_sp
.cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32,
.dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_440gx,
.platform = "ppc440",
},
{ /* 440GX Rev. C */
@@ -1213,6 +1216,7 @@ static struct cpu_spec __initdata cpu_sp
.cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32,
.dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_440gx,
.platform = "ppc440",
},
{ /* 440GX Rev. F */
@@ -1223,6 +1227,7 @@ static struct cpu_spec __initdata cpu_sp
.cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32,
.dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_440gx,
.platform = "ppc440",
},
{ /* 440SP Rev. A */
Index: linux-work/arch/powerpc/kernel/head_44x.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_44x.S 2007-11-19 16:41:48.000000000 +1100
+++ linux-work/arch/powerpc/kernel/head_44x.S 2007-11-19 16:58:53.000000000 +1100
@@ -289,11 +289,8 @@ interrupt_base:
CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
/* Machine Check Interrupt */
-#ifdef CONFIG_440A
- MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
-#else
CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
-#endif
+ MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception)
/* Data Storage Interrupt */
START_EXCEPTION(DataStorage)
@@ -674,6 +671,15 @@ finish_tlb_load:
*/
/*
+ * Adjust the machine check IVOR on 440A cores
+ */
+_GLOBAL(__fixup_440A_mcheck)
+ li r3,MachineCheckA@l
+ mtspr SPRN_IVOR1,r3
+ sync
+ blr
+
+/*
* extern void giveup_altivec(struct task_struct *prev)
*
* The 44x core does not have an AltiVec unit.
Index: linux-work/arch/powerpc/kernel/traps.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/traps.c 2007-11-19 16:44:07.000000000 +1100
+++ linux-work/arch/powerpc/kernel/traps.c 2007-11-19 17:19:44.000000000 +1100
@@ -334,18 +334,25 @@ static inline int check_io_access(struct
#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE)
#endif
-static int generic_machine_check_exception(struct pt_regs *regs)
+#if defined(CONFIG_4xx)
+static int decode_machine_check_4xx(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
-#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
if (reason & ESR_IMCP) {
printk("Instruction");
mtspr(SPRN_ESR, reason & ~ESR_IMCP);
} else
printk("Data");
printk(" machine check in kernel mode.\n");
-#elif defined(CONFIG_440A)
+
+ return 0;
+}
+
+static int decode_machine_check_4xxA(struct pt_regs *regs)
+{
+ unsigned long reason = get_mc_reason(regs);
+
printk("Machine check in kernel mode.\n");
if (reason & ESR_IMCP){
printk("Instruction Synchronous Machine Check exception\n");
@@ -375,7 +382,13 @@ static int generic_machine_check_excepti
/* Clear MCSR */
mtspr(SPRN_MCSR, mcsr);
}
-#elif defined (CONFIG_E500)
+ return 0;
+}
+#elif defined(CONFIG_E500)
+static int decode_machine_check_e500(struct pt_regs *regs)
+{
+ unsigned long reason = get_mc_reason(regs);
+
printk("Machine check in kernel mode.\n");
printk("Caused by (from MCSR=%lx): ", reason);
@@ -403,7 +416,14 @@ static int generic_machine_check_excepti
printk("Bus - Instruction Parity Error\n");
if (reason & MCSR_BUS_RPERR)
printk("Bus - Read Parity Error\n");
-#elif defined (CONFIG_E200)
+
+ return 0;
+}
+#elif defined(CONFIG_E200)
+static int decode_machine_check_e200(struct pt_regs *regs)
+{
+ unsigned long reason = get_mc_reason(regs);
+
printk("Machine check in kernel mode.\n");
printk("Caused by (from MCSR=%lx): ", reason);
@@ -421,7 +441,14 @@ static int generic_machine_check_excepti
printk("Bus - Read Bus Error on data load\n");
if (reason & MCSR_BUS_WRERR)
printk("Bus - Write Bus Error on buffered store or cache line push\n");
-#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
+
+ return 0;
+}
+#else
+static int decode_machine_check_generic(struct pt_regs *regs)
+{
+ unsigned long reason = get_mc_reason(regs);
+
printk("Machine check in kernel mode.\n");
printk("Caused by (from SRR1=%lx): ", reason);
switch (reason & 0x601F0000) {
@@ -451,10 +478,9 @@ static int generic_machine_check_excepti
default:
printk("Unknown values in msr\n");
}
-#endif /* CONFIG_4xx */
-
return 0;
}
+#endif /* everything else */
void machine_check_exception(struct pt_regs *regs)
{
@@ -463,8 +489,20 @@ void machine_check_exception(struct pt_r
/* See if any machine dependent calls */
if (ppc_md.machine_check_exception)
recover = ppc_md.machine_check_exception(regs);
- else
- recover = generic_machine_check_exception(regs);
+ else {
+#ifdef CONFIG_4xx
+ if (IS_MCHECK_EXC(regs))
+ recover = decode_machine_check_4xxA(regs);
+ else
+ recover = decode_machine_check_4xx(regs);
+#elif defined (CONFIG_E500)
+ recover = decode_machine_check_e500(regs);
+#elif defined (CONFIG_E200)
+ recover = decode_machine_check_e200(regs);
+#else
+ recover = decode_machine_check_generic(regs);
+#endif
+ }
if (recover)
return;
Index: linux-work/arch/powerpc/platforms/44x/Kconfig
===================================================================
--- linux-work.orig/arch/powerpc/platforms/44x/Kconfig 2007-11-19 17:10:21.000000000 +1100
+++ linux-work/arch/powerpc/platforms/44x/Kconfig 2007-11-19 17:10:25.000000000 +1100
@@ -62,11 +62,6 @@ config 440GX
config 440SP
bool
-config 440A
- bool
- depends on 440GX || 440EPX
- default y
-
# 44x errata/workaround config symbols, selected by the CPU models above
config IBM440EP_ERR42
bool
Index: linux-work/arch/powerpc/kernel/head_booke.h
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_booke.h 2007-11-19 17:16:25.000000000 +1100
+++ linux-work/arch/powerpc/kernel/head_booke.h 2007-11-19 17:16:29.000000000 +1100
@@ -166,7 +166,7 @@ label:
mfspr r5,SPRN_ESR; \
stw r5,_ESR(r11); \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+ EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
NOCOPY, mcheck_transfer_to_handler, \
ret_from_mcheck_exc)
Index: linux-work/include/asm-powerpc/ptrace.h
===================================================================
--- linux-work.orig/include/asm-powerpc/ptrace.h 2007-11-19 17:14:07.000000000 +1100
+++ linux-work/include/asm-powerpc/ptrace.h 2007-11-19 17:17:14.000000000 +1100
@@ -106,7 +106,8 @@ extern int ptrace_put_reg(struct task_st
*/
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#ifndef __powerpc64__
-#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0)
+#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
+#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
#endif /* ! __powerpc64__ */
#define TRAP(regs) ((regs)->trap & ~0xF)
#ifdef __powerpc64__
Index: linux-work/include/asm-powerpc/reg_booke.h
===================================================================
--- linux-work.orig/include/asm-powerpc/reg_booke.h 2007-11-19 17:20:54.000000000 +1100
+++ linux-work/include/asm-powerpc/reg_booke.h 2007-11-19 17:20:59.000000000 +1100
@@ -207,7 +207,6 @@
#define CCR1_TCS 0x00000080 /* Timer Clock Select */
/* Bit definitions for the MCSR. */
-#ifdef CONFIG_440A
#define MCSR_MCS 0x80000000 /* Machine Check Summary */
#define MCSR_IB 0x40000000 /* Instruction PLB Error */
#define MCSR_DRB 0x20000000 /* Data Read PLB Error */
@@ -217,7 +216,7 @@
#define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */
#define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */
#define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */
-#endif
+
#ifdef CONFIG_E500
#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */
#define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 6/9] powerpc: Add xmon function to dump 44x TLB
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
` (4 preceding siblings ...)
2007-11-19 8:25 ` [RFC/PATCH 5/9] powerpc: Fix 440/440A machine check handling Benjamin Herrenschmidt
@ 2007-11-19 8:25 ` Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 7/9] powerpc: Fix kmalloc alignmenent on non-coherent DMA Benjamin Herrenschmidt
` (2 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
This adds a function to xmon to dump the content of the 44x processor
TLB with a little bit of decoding (but not much).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Did that to track down some machine checks I was having while working
on PCI support due to 32/64 bits resource screwage.
Useful to see where a given MMIO virtual address really maps to.
arch/powerpc/xmon/xmon.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
Index: linux-work/arch/powerpc/xmon/xmon.c
===================================================================
--- linux-work.orig/arch/powerpc/xmon/xmon.c 2007-11-16 16:33:03.000000000 +1100
+++ linux-work/arch/powerpc/xmon/xmon.c 2007-11-16 16:50:45.000000000 +1100
@@ -153,6 +153,10 @@ static const char *getvecname(unsigned l
static int do_spu_cmd(void);
+#ifdef CONFIG_44x
+static void dump_tlb_44x(void);
+#endif
+
int xmon_no_auto_backtrace;
extern void xmon_enter(void);
@@ -231,6 +235,9 @@ Commands:\n\
#ifdef CONFIG_PPC_STD_MMU_32
" u dump segment registers\n"
#endif
+#ifdef CONFIG_44x
+" u dump TLB\n"
+#endif
" ? help\n"
" zr reboot\n\
zh halt\n"
@@ -856,6 +863,11 @@ cmds(struct pt_regs *excp)
dump_segments();
break;
#endif
+#ifdef CONFIG_4xx
+ case 'u':
+ dump_tlb_44x();
+ break;
+#endif
default:
printf("Unrecognized command: ");
do {
@@ -2581,6 +2593,32 @@ void dump_segments(void)
}
#endif
+#ifdef CONFIG_44x
+static void dump_tlb_44x(void)
+{
+ int i;
+
+ for (i = 0; i < PPC44x_TLB_SIZE; i++) {
+ unsigned long w0,w1,w2;
+ asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
+ asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
+ asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
+ printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
+ if (w0 & PPC44x_TLB_VALID) {
+ printf("V %08x -> %01x%08x %c%c%c%c%c",
+ w0 & PPC44x_TLB_EPN_MASK,
+ w1 & PPC44x_TLB_ERPN_MASK,
+ w1 & PPC44x_TLB_RPN_MASK,
+ (w2 & PPC44x_TLB_W) ? 'W' : 'w',
+ (w2 & PPC44x_TLB_I) ? 'I' : 'i',
+ (w2 & PPC44x_TLB_M) ? 'M' : 'm',
+ (w2 & PPC44x_TLB_G) ? 'G' : 'g',
+ (w2 & PPC44x_TLB_E) ? 'E' : 'e');
+ }
+ printf("\n");
+ }
+}
+#endif /* CONFIG_44x */
void xmon_init(int enable)
{
#ifdef CONFIG_PPC_ISERIES
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 7/9] powerpc: Fix kmalloc alignmenent on non-coherent DMA
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
` (5 preceding siblings ...)
2007-11-19 8:25 ` [RFC/PATCH 6/9] powerpc: Add xmon function to dump 44x TLB Benjamin Herrenschmidt
@ 2007-11-19 8:25 ` Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 8/9] powerpc 4xx PCI support Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 9/9] powerpc: PCI support for 4xx Ebony board Benjamin Herrenschmidt
8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
On platforms doing non-coherent DMA (4xx, 8xx, ...), it's important that
kmalloc minimum alignment is set to the cache line size, to avoid sharing
cache lines between different objects.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
include/asm-powerpc/page_32.h | 4 ++++
1 file changed, 4 insertions(+)
Index: linux-work/include/asm-powerpc/page_32.h
===================================================================
--- linux-work.orig/include/asm-powerpc/page_32.h 2007-11-19 15:01:08.000000000 +1100
+++ linux-work/include/asm-powerpc/page_32.h 2007-11-19 15:01:17.000000000 +1100
@@ -6,6 +6,10 @@
#define PPC_MEMSTART 0
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES
+#endif
+
#ifndef __ASSEMBLY__
/*
* The basic type of a PTE - 64 bits for those CPUs with > 32 bit
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 8/9] powerpc 4xx PCI support
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
` (6 preceding siblings ...)
2007-11-19 8:25 ` [RFC/PATCH 7/9] powerpc: Fix kmalloc alignmenent on non-coherent DMA Benjamin Herrenschmidt
@ 2007-11-19 8:25 ` Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 9/9] powerpc: PCI support for 4xx Ebony board Benjamin Herrenschmidt
8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
This is the common 4xx PCI support code for PCI, PCI-X and PCI-E bridges
The bridges are configured based on device-tree properties.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Only PCI-X in this version, I'll do 405-type PCI soon and will wait for
others to do PCI-E unless somebody sends me hardware :-)
arch/powerpc/sysdev/Makefile | 4
arch/powerpc/sysdev/ppc4xx_pci.c | 315 +++++++++++++++++++++++++++++++++++++++
arch/powerpc/sysdev/ppc4xx_pci.h | 106 +++++++++++++
include/asm-powerpc/pci-bridge.h | 3
4 files changed, 428 insertions(+)
Index: linux-work/arch/powerpc/sysdev/Makefile
===================================================================
--- linux-work.orig/arch/powerpc/sysdev/Makefile 2007-11-19 15:01:08.000000000 +1100
+++ linux-work/arch/powerpc/sysdev/Makefile 2007-11-19 15:01:17.000000000 +1100
@@ -29,6 +29,10 @@ obj-$(CONFIG_4xx) += uic.o
obj-$(CONFIG_XILINX_VIRTEX) += xilinx_intc.o
endif
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_4xx) += ppc4xx_pci.o
+endif
+
# Temporary hack until we have migrated to asm-powerpc
ifeq ($(ARCH),powerpc)
obj-$(CONFIG_CPM) += cpm_common.o
Index: linux-work/arch/powerpc/sysdev/ppc4xx_pci.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/sysdev/ppc4xx_pci.c 2007-11-19 15:01:17.000000000 +1100
@@ -0,0 +1,315 @@
+/*
+ * PCI / PCI-X / PCI-Express support for 4xx parts
+ *
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/of.h>
+
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+
+#include "ppc4xx_pci.h"
+
+static int dma_offset_set;
+
+/* Move that to a useable header */
+extern unsigned long total_memory;
+
+/* Defined in drivers/pci/pci.c but not exposed by a header */
+extern u8 pci_cache_line_size;
+
+static int __init ppc4xx_parse_dma_window(struct pci_controller *hose,
+ void __iomem *reg,
+ struct resource *res)
+{
+ struct device_node *np = hose->arch_data;
+ u64 size;
+ const u32 *dmaw;
+
+ /* Default */
+ res->start = 0;
+ res->end = 0x80000000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+
+ /* Get dma-window property */
+ dmaw = of_get_property(np, "dma-window", NULL);
+ if (dmaw == NULL)
+ goto out;
+
+ /* Check if it makes sense (ie. it encodes memory */
+ if ((dmaw[0] & 0x03000000) != 0x02000000) {
+ printk(KERN_ERR "%s: non-memory dma-window\n",
+ np->full_name);
+ return -ENXIO;
+ }
+
+ /* Check if not prefetchable */
+ if (!(dmaw[0] & 0x40000000))
+ res->flags &= ~IORESOURCE_PREFETCH;
+
+ /* Read the DMA window. We should sanity check that it's
+ * not overlapping with the outbound ranges.
+ */
+ res->start = of_read_number(dmaw + 1, 2);
+ size = of_read_number(dmaw + 3, 2);
+ res->end = res->start + size - 1;
+
+ /* We only support one global DMA offset */
+ if (dma_offset_set && pci_dram_offset != res->start) {
+ printk(KERN_ERR "%s: dma-window(s) mismatch\n",
+ np->full_name);
+ return -ENXIO;
+ }
+
+ /* Check that we can fit all of memory as we don't support
+ * DMA bounce buffers
+ */
+ if (size < total_memory) {
+ printk(KERN_ERR "%s: dma-window too small\n",
+ np->full_name);
+ return -ENXIO;
+ }
+
+ /* Check we are a power of 2 size and that base is a multiple of size*/
+ if (!is_power_of_2(size) ||
+ (res->start & (size - 1)) != 0) {
+ printk(KERN_ERR "%s: dma-window unaligned\n",
+ np->full_name);
+ return -ENXIO;
+ }
+
+ /* Check that we are fully contained within 32 bits space */
+ if (res->end > 0xffffffff) {
+ printk(KERN_ERR "%s: dma-window outside of 32 bits space\n",
+ np->full_name);
+ return -ENXIO;
+ }
+ out:
+ dma_offset_set = 1;
+ pci_dram_offset = res->start;
+
+ printk(KERN_INFO "4xx PCI DMA offset set to 0x%08lx\n",
+ pci_dram_offset);
+ return 0;
+}
+
+/*
+ * 4xx PCI 2.x part
+ */
+static void __init ppc4xx_probe_pci_bridge(struct device_node *np)
+{
+ /* NYI */
+}
+
+/*
+ * 4xx PCI-X part
+ */
+
+static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose,
+ void __iomem *reg)
+{
+ struct device_node *np = hose->arch_data;
+ u32 lah, lal, pciah, pcial, sa;
+ int i, j;
+
+ /* Setup outbound memory windows */
+ for(i = j = 0; i < 3; i++) {
+ /* we only care about memory windows */
+ if (!(hose->mem_resources[i].flags & IORESOURCE_MEM))
+ continue;
+ if (j > 1) {
+ printk(KERN_WARNING "%s: Too many ranges\n",
+ np->full_name);
+ break;
+ }
+
+ /* Calculate register values */
+#ifdef CONFIG_PTE_64BIT
+ lah = hose->mem_resources[i].start >> 32;
+ lal = hose->mem_resources[i].start & 0xffffffffu;
+ pciah = (hose->mem_resources[i].start -
+ hose->pci_mem_offset) >> 32;
+ pcial = (hose->mem_resources[i].start -
+ hose->pci_mem_offset) & 0xffffffffu;
+#else
+ lah = pciah = 0;
+ lal = hose->mem_resources[i].start;
+ pcial = hose->mem_resources[i].start -
+ hose->pci_mem_offset;
+#endif
+ sa = hose->mem_resources[i].end + 1 -
+ hose->mem_resources[i].start;
+ if (!is_power_of_2(sa) || sa < 0x100000 ||
+ sa > 0xffffffffu) {
+ printk(KERN_WARNING "%s: Resource out of range\n",
+ np->full_name);
+ continue;
+ }
+ sa = (0xffffffffu << ilog2(sa)) | 0x1;
+
+ /* Program register values */
+ if (j == 0) {
+ writel(lah, reg + PCIX0_POM0LAH);
+ writel(lal, reg + PCIX0_POM0LAL);
+ writel(pciah, reg + PCIX0_POM0PCIAH);
+ writel(pcial, reg + PCIX0_POM0PCIAL);
+ writel(sa, reg + PCIX0_POM0SA);
+ } else {
+ writel(lah, reg + PCIX0_POM1LAH);
+ writel(lal, reg + PCIX0_POM1LAL);
+ writel(pciah, reg + PCIX0_POM1PCIAH);
+ writel(pcial, reg + PCIX0_POM1PCIAL);
+ writel(sa, reg + PCIX0_POM1SA);
+ }
+ j++;
+ }
+}
+
+static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose,
+ void __iomem *reg,
+ const struct resource *res,
+ int big_pim,
+ int enable_msi_hole)
+{
+ resource_size_t size = res->end - res->start + 1;
+ u32 sa;
+
+ /* RAM is always at 0 */
+ writel(0x00000000, reg + PCIX0_PIM0LAH);
+ writel(0x00000000, reg + PCIX0_PIM0LAL);
+
+ /* Calculate window size */
+ sa = (0xffffffffu << ilog2(size)) | 1;
+ sa |= 0x1;
+ if (res->flags & IORESOURCE_PREFETCH)
+ sa |= 0x2;
+ if (enable_msi_hole)
+ sa |= 0x4;
+ writel(sa, reg + PCIX0_PIM0SA);
+ if (big_pim)
+ writel(0xffffffff, reg + PCIX0_PIM0SAH);
+
+ /* Map on PCI side */
+ writel(0x00000000, reg + PCIX0_BAR0H);
+ writel(res->start, reg + PCIX0_BAR0L);
+ writew(0x0006, reg + PCIX0_COMMAND);
+}
+
+static void __init ppc4xx_probe_pcix_bridge(struct device_node *np)
+{
+ struct resource rsrc_cfg;
+ struct resource rsrc_reg;
+ struct resource dma_window;
+ struct pci_controller *hose = NULL;
+ void __iomem *reg = NULL;
+ const int *bus_range;
+ int big_pim = 0, msi = 0, primary = 0;
+
+ /* Fetch config space registers address */
+ if (of_address_to_resource(np, 0, &rsrc_cfg)) {
+ printk(KERN_ERR "%s:Can't get PCI-X config register base !",
+ np->full_name);
+ return;
+ }
+ /* Fetch host bridge internal registers address */
+ if (of_address_to_resource(np, 1, &rsrc_reg)) {
+ printk(KERN_ERR "%s: Can't get PCI-X internal register base !",
+ np->full_name);
+ return;
+ }
+
+ /* Check if it supports large PIMs (440GX) */
+ if (of_get_property(np, "large-inbound-windows", NULL))
+ big_pim = 1;
+
+ /* Check if we should enable MSIs inbound hole */
+ if (of_get_property(np, "enable-msi-hole", NULL))
+ msi = 1;
+
+ /* Check if primary bridge */
+ if (of_get_property(np, "primary", NULL))
+ primary = 1;
+
+ /* Get bus range if any */
+ bus_range = of_get_property(np, "bus-range", NULL);
+
+ /* Map registers */
+ reg = ioremap(rsrc_reg.start, rsrc_reg.end + 1 - rsrc_reg.start);
+ if (reg == NULL) {
+ printk(KERN_ERR "%s: Can't map registers !", np->full_name);
+ goto fail;
+ }
+
+ /* Allocate the host controller data structure */
+ hose = pcibios_alloc_controller(np);
+ if (!hose)
+ goto fail;
+
+ hose->first_busno = bus_range ? bus_range[0] : 0x0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+ /* Setup config space */
+ setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0);
+
+ /* Disable all windows */
+ writel(0, reg + PCIX0_POM0SA);
+ writel(0, reg + PCIX0_POM1SA);
+ writel(0, reg + PCIX0_POM2SA);
+ writel(0, reg + PCIX0_PIM0SA);
+ writel(0, reg + PCIX0_PIM1SA);
+ writel(0, reg + PCIX0_PIM2SA);
+ if (big_pim) {
+ writel(0, reg + PCIX0_PIM0SAH);
+ writel(0, reg + PCIX0_PIM2SAH);
+ }
+
+ /* Parse outbound mapping resources */
+ pci_process_bridge_OF_ranges(hose, np, primary);
+
+ /* Parse inbound mapping resources */
+ if (ppc4xx_parse_dma_window(hose, reg, &dma_window) != 0)
+ goto fail;
+
+ /* Configure outbound ranges POMs */
+ ppc4xx_configure_pcix_POMs(hose, reg);
+
+ /* Configure inbound ranges PIMs */
+ ppc4xx_configure_pcix_PIMs(hose, reg, &dma_window, big_pim, msi);
+
+ /* We don't need the registers anymore */
+ iounmap(reg);
+ return;
+
+ fail:
+ if (hose)
+ pcibios_free_controller(hose);
+ if (reg)
+ iounmap(reg);
+}
+
+/*
+ * 4xx PCI-Express part
+ */
+static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
+{
+ /* NYI */
+}
+
+void __init ppc4xx_pci_find_bridges(void)
+{
+ struct device_node *np;
+
+ for_each_compatible_node(np, NULL, "ibm,plb-pciex")
+ ppc4xx_probe_pciex_bridge(np);
+ for_each_compatible_node(np, NULL, "ibm,plb-pcix")
+ ppc4xx_probe_pcix_bridge(np);
+ for_each_compatible_node(np, NULL, "ibm,plb-pci")
+ ppc4xx_probe_pci_bridge(np);
+}
Index: linux-work/arch/powerpc/sysdev/ppc4xx_pci.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/sysdev/ppc4xx_pci.h 2007-11-19 15:01:17.000000000 +1100
@@ -0,0 +1,106 @@
+/*
+ * PCI / PCI-X / PCI-Express support for 4xx parts
+ *
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * Bits and pieces extracted from arch/ppc support by
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * Copyright 2002-2005 MontaVista Software Inc.
+ */
+#ifndef __PPC4XX_PCI_H__
+#define __PPC4XX_PCI_H__
+
+/*
+ * 4xx PCI-X bridge register definitions
+ */
+#define PCIX0_VENDID 0x000
+#define PCIX0_DEVID 0x002
+#define PCIX0_COMMAND 0x004
+#define PCIX0_STATUS 0x006
+#define PCIX0_REVID 0x008
+#define PCIX0_CLS 0x009
+#define PCIX0_CACHELS 0x00c
+#define PCIX0_LATTIM 0x00d
+#define PCIX0_HDTYPE 0x00e
+#define PCIX0_BIST 0x00f
+#define PCIX0_BAR0L 0x010
+#define PCIX0_BAR0H 0x014
+#define PCIX0_BAR1 0x018
+#define PCIX0_BAR2L 0x01c
+#define PCIX0_BAR2H 0x020
+#define PCIX0_BAR3 0x024
+#define PCIX0_CISPTR 0x028
+#define PCIX0_SBSYSVID 0x02c
+#define PCIX0_SBSYSID 0x02e
+#define PCIX0_EROMBA 0x030
+#define PCIX0_CAP 0x034
+#define PCIX0_RES0 0x035
+#define PCIX0_RES1 0x036
+#define PCIX0_RES2 0x038
+#define PCIX0_INTLN 0x03c
+#define PCIX0_INTPN 0x03d
+#define PCIX0_MINGNT 0x03e
+#define PCIX0_MAXLTNCY 0x03f
+#define PCIX0_BRDGOPT1 0x040
+#define PCIX0_BRDGOPT2 0x044
+#define PCIX0_ERREN 0x050
+#define PCIX0_ERRSTS 0x054
+#define PCIX0_PLBBESR 0x058
+#define PCIX0_PLBBEARL 0x05c
+#define PCIX0_PLBBEARH 0x060
+#define PCIX0_POM0LAL 0x068
+#define PCIX0_POM0LAH 0x06c
+#define PCIX0_POM0SA 0x070
+#define PCIX0_POM0PCIAL 0x074
+#define PCIX0_POM0PCIAH 0x078
+#define PCIX0_POM1LAL 0x07c
+#define PCIX0_POM1LAH 0x080
+#define PCIX0_POM1SA 0x084
+#define PCIX0_POM1PCIAL 0x088
+#define PCIX0_POM1PCIAH 0x08c
+#define PCIX0_POM2SA 0x090
+#define PCIX0_PIM0SAL 0x098
+#define PCIX0_PIM0SA PCIX0_PIM0SAL
+#define PCIX0_PIM0LAL 0x09c
+#define PCIX0_PIM0LAH 0x0a0
+#define PCIX0_PIM1SA 0x0a4
+#define PCIX0_PIM1LAL 0x0a8
+#define PCIX0_PIM1LAH 0x0ac
+#define PCIX0_PIM2SAL 0x0b0
+#define PCIX0_PIM2SA PCIX0_PIM2SAL
+#define PCIX0_PIM2LAL 0x0b4
+#define PCIX0_PIM2LAH 0x0b8
+#define PCIX0_OMCAPID 0x0c0
+#define PCIX0_OMNIPTR 0x0c1
+#define PCIX0_OMMC 0x0c2
+#define PCIX0_OMMA 0x0c4
+#define PCIX0_OMMUA 0x0c8
+#define PCIX0_OMMDATA 0x0cc
+#define PCIX0_OMMEOI 0x0ce
+#define PCIX0_PMCAPID 0x0d0
+#define PCIX0_PMNIPTR 0x0d1
+#define PCIX0_PMC 0x0d2
+#define PCIX0_PMCSR 0x0d4
+#define PCIX0_PMCSRBSE 0x0d6
+#define PCIX0_PMDATA 0x0d7
+#define PCIX0_PMSCRR 0x0d8
+#define PCIX0_CAPID 0x0dc
+#define PCIX0_NIPTR 0x0dd
+#define PCIX0_CMD 0x0de
+#define PCIX0_STS 0x0e0
+#define PCIX0_IDR 0x0e4
+#define PCIX0_CID 0x0e8
+#define PCIX0_RID 0x0ec
+#define PCIX0_PIM0SAH 0x0f8
+#define PCIX0_PIM2SAH 0x0fc
+#define PCIX0_MSGIL 0x100
+#define PCIX0_MSGIH 0x104
+#define PCIX0_MSGOL 0x108
+#define PCIX0_MSGOH 0x10c
+#define PCIX0_IM 0x1f8
+
+
+
+#endif /* __PPC4XX_PCI_H__ */
Index: linux-work/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-work.orig/include/asm-powerpc/pci-bridge.h 2007-11-19 15:01:08.000000000 +1100
+++ linux-work/include/asm-powerpc/pci-bridge.h 2007-11-19 15:01:17.000000000 +1100
@@ -290,6 +290,7 @@ extern void pcibios_free_controller(stru
#ifdef CONFIG_PCI
extern unsigned long pci_address_to_pio(phys_addr_t address);
extern int pcibios_vaddr_is_ioport(void __iomem *address);
+extern void ppc4xx_pci_find_bridges(void);
#else
static inline unsigned long pci_address_to_pio(phys_addr_t address)
{
@@ -299,6 +300,8 @@ static inline int pcibios_vaddr_is_iopor
{
return 0;
}
+static inline void ppc4xx_pci_find_bridges(void) { }
+
#endif
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 9/9] powerpc: PCI support for 4xx Ebony board
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
` (7 preceding siblings ...)
2007-11-19 8:25 ` [RFC/PATCH 8/9] powerpc 4xx PCI support Benjamin Herrenschmidt
@ 2007-11-19 8:25 ` Benjamin Herrenschmidt
8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 8:25 UTC (permalink / raw)
To: linuxppc-dev
Based on the previous patch, this hooks up PCI for Ebony.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/boot/dts/ebony.dts | 39 ++++++++++++++++++++++++++++++++-----
arch/powerpc/platforms/44x/ebony.c | 7 ++++++
2 files changed, 41 insertions(+), 5 deletions(-)
Index: linux-work/arch/powerpc/boot/dts/ebony.dts
===================================================================
--- linux-work.orig/arch/powerpc/boot/dts/ebony.dts 2007-11-19 15:01:08.000000000 +1100
+++ linux-work/arch/powerpc/boot/dts/ebony.dts 2007-11-19 15:01:17.000000000 +1100
@@ -284,12 +284,41 @@
};
- PCIX0: pci@1234 {
+ PCIX0: pci@20ec00000 {
device_type = "pci";
- /* FIXME */
- reg = <2 0ec00000 8
- 2 0ec80000 f0
- 2 0ec80100 fc>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb440gp-pcix", "ibm,plb-pcix";
+ primary;
+ reg = <2 0ec00000 8 /* Config space access */
+ 2 0ec80000 f0 /* Internal registers */
+ 2 0ec80100 fc>; /* Internal messaging registers */
+
+ /* Outbound ranges, one memory and one IO,
+ * later cannot be changed
+ */
+ ranges = <02000000 0 80000000 00000003 80000000 0 80000000
+ 01000000 0 00000000 00000002 08000000 0 00010000>;
+
+ /* Inbound 2GB range starting at 0 */
+ dma-window = <42000000 0 0 0 80000000>;
+
+ /* Ebony has all 4 IRQ pins tied together per slot */
+ interrupt-map-mask = <f800 0 0 0>;
+ interrupt-map = <
+ /* IDSEL 1 */
+ 0800 0 0 0 &UIC0 17 8
+
+ /* IDSEL 2 */
+ 1000 0 0 0 &UIC0 18 8
+
+ /* IDSEL 3 */
+ 1800 0 0 0 &UIC0 19 8
+
+ /* IDSEL 4 */
+ 2000 0 0 0 &UIC0 1a 8
+ >;
};
};
Index: linux-work/arch/powerpc/platforms/44x/ebony.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/44x/ebony.c 2007-11-19 15:01:08.000000000 +1100
+++ linux-work/arch/powerpc/platforms/44x/ebony.c 2007-11-19 15:01:17.000000000 +1100
@@ -23,6 +23,7 @@
#include <asm/time.h>
#include <asm/uic.h>
#include <asm/of_platform.h>
+#include <asm/pci-bridge.h>
#include "44x.h"
@@ -44,6 +45,11 @@ static int __init ebony_device_probe(voi
}
device_initcall(ebony_device_probe);
+static void __init ebony_setup_arch(void)
+{
+ ppc4xx_pci_find_bridges();
+}
+
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
@@ -60,6 +66,7 @@ static int __init ebony_probe(void)
define_machine(ebony) {
.name = "Ebony",
.probe = ebony_probe,
+ .setup_arch = ebony_setup_arch,
.progress = udbg_progress,
.init_IRQ = uic_init_tree,
.get_irq = uic_get_irq,
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC/PATCH 1/9] powerpc: Make isa_mem_base common to 32 and 64 bits
2007-11-19 8:25 ` [RFC/PATCH 1/9] powerpc: Make isa_mem_base common to 32 and 64 bits Benjamin Herrenschmidt
@ 2007-11-19 10:32 ` Christoph Hellwig
2007-11-19 19:49 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2007-11-19 10:32 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
On Mon, Nov 19, 2007 at 07:25:00PM +1100, Benjamin Herrenschmidt wrote:
> +/* ISA Memory physical address (or 0 if none) */
> +resource_size_t isa_mem_base = 0;
No need to initialize this.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC/PATCH 1/9] powerpc: Make isa_mem_base common to 32 and 64 bits
2007-11-19 10:32 ` Christoph Hellwig
@ 2007-11-19 19:49 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2007-11-19 19:49 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linuxppc-dev
On Mon, 2007-11-19 at 11:32 +0100, Christoph Hellwig wrote:
> On Mon, Nov 19, 2007 at 07:25:00PM +1100, Benjamin Herrenschmidt wrote:
> > +/* ISA Memory physical address (or 0 if none) */
> > +resource_size_t isa_mem_base = 0;
>
> No need to initialize this.
True. I copy/pasted as-is but you are right, I can remove the
initializer.
Ben.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2007-11-19 19:49 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-19 8:25 [RFC/PATCH 0/9] powerpc: 4xx PCI work in progress Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 1/9] powerpc: Make isa_mem_base common to 32 and 64 bits Benjamin Herrenschmidt
2007-11-19 10:32 ` Christoph Hellwig
2007-11-19 19:49 ` Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 2/9] powerpc: Merge pci_process_bridge_OF_ranges() Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 3/9] powerpc: Fix declaration of pcibios_free_controller Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 4/9] powerpc: Fix powerpc 32 bits resource fixup for 64 bits resources Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 5/9] powerpc: Fix 440/440A machine check handling Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 6/9] powerpc: Add xmon function to dump 44x TLB Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 7/9] powerpc: Fix kmalloc alignmenent on non-coherent DMA Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 8/9] powerpc 4xx PCI support Benjamin Herrenschmidt
2007-11-19 8:25 ` [RFC/PATCH 9/9] powerpc: PCI support for 4xx Ebony board Benjamin Herrenschmidt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).