Subject: Re: "Blue & White" G3 (long)
To: None <port-macppc@netbsd.org>
From: Dan Winship <danw@MIT.EDU>
List: port-macppc
Date: 03/13/1999 17:21:45
OK, as suggested by Jason, here's a badaddr() for powerpc, and patches
to pci_machdep.c to use it to prevent the trap 300 while probing
non-existent PCI devices. The prototype obviously doesn't belong in
pci_machdep.c, but I couldn't put it in trap.h because locore.S
includes that, and I didn't know where else would be better.
This could probably also be used to replace some of the other code in
pci_machdep.c that hardcodes what devices it should look at when
probing the pci bus.
*** arch/powerpc/powerpc/trap.c.orig Sat Mar 13 14:59:34 1999
--- arch/powerpc/powerpc/trap.c Sat Mar 13 16:18:11 1999
***************
*** 64,69 ****
--- 64,70 ----
volatile int astpending;
volatile int want_resched;
+ static int mchk_expected, mchk_received;
void
trap(frame)
***************
*** 291,296 ****
--- 292,304 ----
trapsignal(p, SIGILL, EXC_PGM);
break;
+ case EXC_MCHK:
+ if (mchk_expected)
+ mchk_received++;
+ else
+ goto brain_damage;
+ break;
+
default:
brain_damage:
printf("trap type %x at %x\n", type, frame->srr0);
***************
*** 479,481 ****
--- 487,532 ----
return 0;
}
#endif
+
+ int
+ badaddr(addr, size)
+ void *addr;
+ size_t size;
+ {
+ long rcpt;
+
+ /* Get rid of any stale machine checks that have been waiting. */
+ __asm__ volatile ("eieio; sync;");
+
+ /* Tell the trap code to expect a machine check. */
+ mchk_received = 0;
+ mchk_expected = 1;
+
+ /* Read from the test address. */
+ switch (size) {
+ case sizeof (u_int8_t):
+ rcpt = *(volatile u_int8_t *)addr;
+ break;
+
+ case sizeof (u_int16_t):
+ rcpt = *(volatile u_int16_t *)addr;
+ break;
+
+ case sizeof (u_int32_t):
+ rcpt = *(volatile u_int32_t *)addr;
+ break;
+
+ case sizeof (u_int64_t):
+ rcpt = *(volatile u_int64_t *)addr;
+ break;
+
+ default:
+ panic("badaddr: invalid size (%ld)\n", size);
+ }
+
+ /* Make sure we took the machine check, if we caused one. */
+ __asm__ volatile ("eieio; sync;");
+ mchk_expected = 0;
+
+ return mchk_received;
+ }
*** arch/macppc/pci/pci_machdep.c.orig Sat Mar 13 15:20:08 1999
--- arch/macppc/pci/pci_machdep.c Sat Mar 13 15:32:19 1999
***************
*** 59,64 ****
--- 59,66 ----
#include <machine/pio.h>
#include <machine/intr.h>
+ int badaddr __P((void *addr, size_t size));
+
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
***************
*** 147,153 ****
r = &pci_bridges[0];
out32rb(r->addr, tag | reg);
! data = in32rb(r->data);
out32rb(r->addr, 0);
} else {
int bus, dev, func;
--- 149,158 ----
r = &pci_bridges[0];
out32rb(r->addr, tag | reg);
! if (badaddr(r->data, sizeof(r->data)))
! data = 0xffffffff;
! else
! data = in32rb(r->data);
out32rb(r->addr, 0);
} else {
int bus, dev, func;
***************
*** 174,180 ****
} else
out32rb(r->addr, tag | reg | 1);
DELAY(10);
! data = in32rb(r->data);
DELAY(10);
out32rb(r->addr, 0);
DELAY(10);
--- 179,188 ----
} else
out32rb(r->addr, tag | reg | 1);
DELAY(10);
! if (badaddr(r->data, sizeof(r->data)))
! data = 0xffffffff;
! else
! data = in32rb(r->data);
DELAY(10);
out32rb(r->addr, 0);
DELAY(10);