Port-sparc64 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
OF_mapintr() problems
Having just acquired a couple of Ultra 45 machines, I tried booting a
NetBSD installation CD, and ran into the aceride timeout issued mentioned
here before. I then tried to set up netbooting, and after some
trial-and-errors, I was able to netboot the INSTALL kernel. At that point
I ran into the issues with bge(4), also mentioned here (and I think
current-users). I was able to use the INSTALL kernel to create a bootable
disk partition with the intall tools on ig, but even booting directly from
the disk, I could not get either bge0 or bge1 to work.
I enabled DEBUG and started getting information about the interrupt
mapping. One thing I noticed is that the interrupts for bge0 and bge1
were not getting swizzled like I expected. When looking at OF_mapintr()
and the various .properties from OpenBoot, I noticed that the Ultra45 had
the device-type "pciex" instead of the "pci" that NetBSD was looking for.
My first attempt at just changing "pci" to "pciex" changed the ivec
values, but only resulting in mpt(4) not working anymore.
That led me to look at the OpenBSD OF_mapintr(), and I found a number of
changes - including handling the device-type "pciex". Making those change
to me kernel got me to the point of no more aceride or ehci timeouts, and
I could configure the bge devices. I could see packets sent out, and the
input counters were increasing, but didn't seem to be processing any input
packets.
I burned a CD with my build, and was able to boot it, install NetBSD, and
both bge interfaces are now working. Also, I was able to insert a USB
flash drive and read from it.
The only thing now is I'm not sure if the changes I have might break
something else that is working.
If anyone wants to try out these changes, here they are:
Index: sys/arch/sparc64/sparc64/ofw_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/ofw_machdep.c,v
retrieving revision 1.38
diff -u -p -r1.38 ofw_machdep.c
--- sys/arch/sparc64/sparc64/ofw_machdep.c 17 Jul 2011 20:54:48 -0000
1.38
+++ sys/arch/sparc64/sparc64/ofw_machdep.c 8 Jul 2013 15:07:18 -0000
@@ -608,7 +608,7 @@ prom_has_stop_other(void)
#endif
#ifdef DEBUG
-int ofmapintrdebug = 0;
+int ofmapintrdebug = 1;
#define DPRINTF(x) if (ofmapintrdebug) printf x
#else
#define DPRINTF(x)
@@ -668,7 +668,8 @@ find_pci_host_node(int node)
&dev_type, sizeof(dev_type));
if (len <= 0)
continue;
- if (!strcmp(dev_type, "pci"))
+ if (!strcmp(dev_type, "pci") ||
+ !strcmp(dev_type, "pciex"))
pch = node;
}
return pch;
@@ -687,7 +688,7 @@ OF_mapintr(int node, int *interrupt, int
{
int i, len;
int address_cells, size_cells, interrupt_cells, interrupt_map_len;
- int static_interrupt_map[100];
+ int static_interrupt_map[256];
int interrupt_map_mask[10];
int *interrupt_map = &static_interrupt_map[0];
int maplen = sizeof static_interrupt_map;
@@ -698,7 +699,7 @@ OF_mapintr(int node, int *interrupt, int
int rc = -1;
/* Don't need to map OBP interrupt, it's already */
- if (*interrupt & 0x20)
+ if (*interrupt & 0x20 || *interrupt & 0x7c0)
return validlen;
/*
@@ -722,7 +723,7 @@ OF_mapintr(int node, int *interrupt, int
phc_node = find_pci_host_node(node);
- for (; node; node = OF_parent(node)) {
+ while (node) {
#ifdef DEBUG
char name[40];
@@ -740,7 +741,8 @@ OF_mapintr(int node, int *interrupt, int
/* Swizzle interrupt if this is a PCI bridge. */
if (((len = OF_getprop(node, "device_type", &dev_type,
sizeof(dev_type))) > 0) &&
- !strcmp(dev_type, "pci") &&
+ (!strcmp(dev_type, "pci") ||
+ !strcmp(dev_type, "pciex")) &&
(node != phc_node)) {
#ifdef DEBUG
int ointerrupt = *interrupt;
@@ -755,6 +757,8 @@ OF_mapintr(int node, int *interrupt, int
/* Get reg for next level compare. */
reg[0] = 0;
OF_getprop(node, "reg", ®, sizeof(reg));
+
+ node = OF_parent(node);
continue;
}
if (interrupt_map_len > maplen) {
@@ -813,7 +817,7 @@ OF_mapintr(int node, int *interrupt, int
/* finally we can attempt the compare */
i = 0;
- while (i < interrupt_map_len) {
+ while (i < interrupt_map_len + address_cells + interrupt_cells)
{
int pintr_cells;
int *imap = &interrupt_map[i];
int *parent = &imap[address_cells + interrupt_cells];
@@ -850,6 +854,7 @@ OF_mapintr(int node, int *interrupt, int
free(free_map, M_DEVBUF);
return (-1);
}
+ node = *parent;
parent++;
#ifdef DEBUG
DPRINTF(("Match! using "));
@@ -860,6 +865,8 @@ OF_mapintr(int node, int *interrupt, int
for (i = 0; i < pintr_cells; i++)
interrupt[i] = parent[i];
rc = validlen = pintr_cells;
+ if (node == phc_node)
+ return(rc);
break;
}
/* Move on to the next interrupt_map entry. */
@@ -877,14 +884,15 @@ OF_mapintr(int node, int *interrupt, int
/* Get reg for the next level search. */
if ((len = OF_getprop(node, "reg", ®, sizeof(reg))) <= 0) {
DPRINTF(("OF_mapintr: no reg property?\n"));
- continue;
+ } else {
+ DPRINTF(("reg len %d\n", len));
}
- DPRINTF(("reg len %d\n", len));
if (free_map) {
free(free_map, M_DEVBUF);
free_map = NULL;
}
+ node = OF_parent(node);
}
return (rc);
}
---
Michael L. Hitch mhitch%NetBSD.org@localhost
Operations Consulting, Information Technology Center
Montana State University, Bozeman, MT USA
Home |
Main Index |
Thread Index |
Old Index