Commit 8f11eb1d authored by Paul Mackerras's avatar Paul Mackerras

PPC32: translate addresses in the Open Firmware device tree correctly.

parent 6648f308
...@@ -519,6 +519,38 @@ prom_n_size_cells(struct device_node* np) ...@@ -519,6 +519,38 @@ prom_n_size_cells(struct device_node* np)
return 1; return 1;
} }
static unsigned long __init
map_addr(struct device_node *np, unsigned long space, unsigned long addr)
{
int na;
unsigned int *ranges;
int rlen = 0;
unsigned int type;
type = (space >> 24) & 3;
if (type == 0)
return addr;
while ((np = np->parent) != NULL) {
if (strcmp(np->type, "pci") != 0)
continue;
/* PCI bridge: map the address through the ranges property */
na = prom_n_addr_cells(np);
ranges = (unsigned int *) get_property(np, "ranges", &rlen);
while ((rlen -= (na + 5) * sizeof(unsigned int)) >= 0) {
if (((ranges[0] >> 24) & 3) == type
&& ranges[2] <= addr
&& addr - ranges[2] < ranges[na+4]) {
/* ok, this matches, translate it */
addr += ranges[na+2] - ranges[2];
break;
}
ranges += na + 5;
}
}
return addr;
}
static unsigned long __init static unsigned long __init
interpret_pci_props(struct device_node *np, unsigned long mem_start, interpret_pci_props(struct device_node *np, unsigned long mem_start,
int naddrc, int nsizec) int naddrc, int nsizec)
...@@ -533,9 +565,9 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start, ...@@ -533,9 +565,9 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start,
i = 0; i = 0;
adr = (struct address_range *) mem_start; adr = (struct address_range *) mem_start;
while ((l -= sizeof(struct pci_reg_property)) >= 0) { while ((l -= sizeof(struct pci_reg_property)) >= 0) {
/* XXX assumes PCI addresses mapped 1-1 to physical */
adr[i].space = pci_addrs[i].addr.a_hi; adr[i].space = pci_addrs[i].addr.a_hi;
adr[i].address = pci_addrs[i].addr.a_lo; adr[i].address = map_addr(np, pci_addrs[i].addr.a_hi,
pci_addrs[i].addr.a_lo);
adr[i].size = pci_addrs[i].size_lo; adr[i].size = pci_addrs[i].size_lo;
++i; ++i;
} }
...@@ -772,13 +804,14 @@ prom_get_irq_senses(unsigned char *senses, int off, int max) ...@@ -772,13 +804,14 @@ prom_get_irq_senses(unsigned char *senses, int off, int max)
for (np = allnodes; np != 0; np = np->allnext) { for (np = allnodes; np != 0; np = np->allnext) {
for (j = 0; j < np->n_intrs; j++) { for (j = 0; j < np->n_intrs; j++) {
i = np->intrs[j].line; i = np->intrs[j].line;
if (i >= off && i < max) if (i >= off && i < max) {
if (np->intrs[j].sense == 1) if (np->intrs[j].sense == 1)
senses[i-off] = (IRQ_SENSE_LEVEL senses[i-off] = (IRQ_SENSE_LEVEL
| IRQ_POLARITY_NEGATIVE); | IRQ_POLARITY_NEGATIVE);
else else
senses[i-off] = (IRQ_SENSE_EDGE senses[i-off] = (IRQ_SENSE_EDGE
| IRQ_POLARITY_POSITIVE); | IRQ_POLARITY_POSITIVE);
}
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment