IP12 (and perhaps other systems) appear to be buggy and incapable of
reliably supporting badaddr(). False negatives appear to occur approximately 1.8 percent of the time, although neither false positives nor consecutive false negatives occur. We take advantage of the latter property and always use a wrapper that makes multiple checks. My IP12 no longer sees occasional ghost devices and related panics during boot.
This commit is contained in:
parent
ebc746c114
commit
1426ceeded
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: gio.c,v 1.25 2006/12/29 00:42:01 rumble Exp $ */
|
||||
/* $NetBSD: gio.c,v 1.26 2006/12/29 05:26:30 rumble Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Soren S. Jorvang
|
||||
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: gio.c,v 1.25 2006/12/29 00:42:01 rumble Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: gio.c,v 1.26 2006/12/29 05:26:30 rumble Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
@ -44,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: gio.c,v 1.25 2006/12/29 00:42:01 rumble Exp $");
|
||||
#define _SGIMIPS_BUS_DMA_PRIVATE
|
||||
#include <machine/bus.h>
|
||||
#include <machine/machtype.h>
|
||||
#include <machine/sysconf.h>
|
||||
|
||||
#include <sgimips/gio/gioreg.h>
|
||||
#include <sgimips/gio/giovar.h>
|
||||
@ -215,7 +216,7 @@ gio_attach(struct device *parent, struct device *self, void *aux)
|
||||
ga.ga_dmat = &sgimips_default_bus_dma_tag;
|
||||
ga.ga_product = -1;
|
||||
|
||||
if (badaddr((void *)ga.ga_ioh, sizeof(uint32_t)))
|
||||
if (platform.badaddr((void *)ga.ga_ioh, sizeof(uint32_t)))
|
||||
continue;
|
||||
|
||||
if (config_found_sm_loc(self, "gio", NULL, &ga, gio_print,
|
||||
@ -258,7 +259,7 @@ gio_attach(struct device *parent, struct device *self, void *aux)
|
||||
ga.ga_ioh = MIPS_PHYS_TO_KSEG1(ga.ga_addr);
|
||||
ga.ga_dmat = &sgimips_default_bus_dma_tag;
|
||||
|
||||
if (badaddr((void *)ga.ga_ioh, sizeof(uint32_t)))
|
||||
if (platform.badaddr((void *)ga.ga_ioh, sizeof(uint32_t)))
|
||||
continue;
|
||||
|
||||
ga.ga_product = bus_space_read_4(ga.ga_iot, ga.ga_ioh, 0);
|
||||
@ -375,7 +376,7 @@ gio_cnattach()
|
||||
ga.ga_dmat = &sgimips_default_bus_dma_tag;
|
||||
ga.ga_product = -1;
|
||||
|
||||
if (badaddr((void *)ga.ga_ioh,sizeof(uint32_t)))
|
||||
if (platform.badaddr((void *)ga.ga_ioh,sizeof(uint32_t)))
|
||||
continue;
|
||||
|
||||
#if (NGRTWO > 0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: grtwo.c,v 1.8 2006/12/28 22:10:05 rumble Exp $ */
|
||||
/* $NetBSD: grtwo.c,v 1.9 2006/12/29 05:26:30 rumble Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Christopher SEKIYA
|
||||
@ -35,13 +35,15 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: grtwo.c,v 1.8 2006/12/28 22:10:05 rumble Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: grtwo.c,v 1.9 2006/12/29 05:26:30 rumble Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <machine/sysconf.h>
|
||||
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/wsfont/wsfont.h>
|
||||
@ -452,7 +454,8 @@ grtwo_match(struct device * parent, struct cfdata * self, void *aux)
|
||||
* ID. Instead, we determine presence by looking at the HQ2 "mystery"
|
||||
* register, which contains a magic number.
|
||||
*/
|
||||
if ( badaddr((void *) (ga->ga_ioh + HQ2_MYSTERY), sizeof(u_int32_t)) )
|
||||
if ( platform.badaddr((void *) (ga->ga_ioh + HQ2_MYSTERY),
|
||||
sizeof(u_int32_t)) )
|
||||
return 0;
|
||||
|
||||
if ( (bus_space_read_4(ga->ga_iot, ga->ga_ioh, HQ2_MYSTERY)) != 0xdeadbeef)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: light.c,v 1.3 2006/12/29 00:31:48 rumble Exp $ */
|
||||
/* $Id: light.c,v 1.4 2006/12/29 05:26:30 rumble Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Stephen M. Rumble
|
||||
@ -43,13 +43,15 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: light.c,v 1.3 2006/12/29 00:31:48 rumble Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: light.c,v 1.4 2006/12/29 05:26:30 rumble Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <machine/sysconf.h>
|
||||
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/wsfont/wsfont.h>
|
||||
@ -270,7 +272,8 @@ light_match(struct device *parent, struct cfdata *self, void *aux)
|
||||
if (ga->ga_addr != LIGHT_ADDR_0 && ga->ga_addr != LIGHT_ADDR_1)
|
||||
return (0);
|
||||
|
||||
if (badaddr((void *)(ga->ga_ioh + REX_PAGE1_SET + REX_P1REG_XYOFFSET),
|
||||
if (platform.badaddr(
|
||||
(void *)(ga->ga_ioh + REX_PAGE1_SET + REX_P1REG_XYOFFSET),
|
||||
sizeof(uint32_t)))
|
||||
return (0);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: newport.c,v 1.8 2006/12/28 22:08:04 rumble Exp $ */
|
||||
/* $NetBSD: newport.c,v 1.9 2006/12/29 05:26:30 rumble Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Ilpo Ruotsalainen
|
||||
@ -30,13 +30,15 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: newport.c,v 1.8 2006/12/28 22:08:04 rumble Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: newport.c,v 1.9 2006/12/29 05:26:30 rumble Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <machine/sysconf.h>
|
||||
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/wsfont/wsfont.h>
|
||||
@ -575,11 +577,11 @@ newport_match(struct device *parent, struct cfdata *self, void *aux)
|
||||
if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr)
|
||||
return 1;
|
||||
|
||||
if (badaddr(
|
||||
if (platform.badaddr(
|
||||
(void *)(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI),
|
||||
sizeof(uint32_t)))
|
||||
return 0;
|
||||
if (badaddr(
|
||||
if (platform.badaddr(
|
||||
(void *)(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTART),
|
||||
sizeof(uint32_t)))
|
||||
return 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: haltwo.c,v 1.10 2006/09/04 22:06:06 rumble Exp $ */
|
||||
/* $NetBSD: haltwo.c,v 1.11 2006/12/29 05:26:30 rumble Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Ilpo Ruotsalainen
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: haltwo.c,v 1.10 2006/09/04 22:06:06 rumble Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: haltwo.c,v 1.11 2006/12/29 05:26:30 rumble Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -44,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: haltwo.c,v 1.10 2006/09/04 22:06:06 rumble Exp $");
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/sysconf.h>
|
||||
|
||||
#include <sgimips/hpc/hpcvar.h>
|
||||
#include <sgimips/hpc/hpcreg.h>
|
||||
@ -266,10 +267,12 @@ haltwo_match(struct device *parent, struct cfdata *cf, void *aux)
|
||||
if (strcmp(haa->ha_name, cf->cf_name))
|
||||
return 0;
|
||||
|
||||
if ( badaddr((void *)(haa->ha_sh + haa->ha_devoff), sizeof(u_int32_t)) )
|
||||
if ( platform.badaddr((void *)(haa->ha_sh + haa->ha_devoff),
|
||||
sizeof(u_int32_t)) )
|
||||
return 0;
|
||||
|
||||
if ( badaddr((void *)(haa->ha_sh + haa->ha_devoff + HAL2_REG_CTL_REV),
|
||||
if ( platform.badaddr(
|
||||
(void *)(haa->ha_sh + haa->ha_devoff + HAL2_REG_CTL_REV),
|
||||
sizeof(u_int32_t)) )
|
||||
return 0;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hpc.c,v 1.49 2006/12/22 23:36:42 rumble Exp $ */
|
||||
/* $NetBSD: hpc.c,v 1.50 2006/12/29 05:26:30 rumble Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Soren S. Jorvang
|
||||
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hpc.c,v 1.49 2006/12/22 23:36:42 rumble Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hpc.c,v 1.50 2006/12/29 05:26:30 rumble Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -47,6 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: hpc.c,v 1.49 2006/12/22 23:36:42 rumble Exp $");
|
||||
#define _SGIMIPS_BUS_DMA_PRIVATE
|
||||
#include <machine/bus.h>
|
||||
#include <machine/machtype.h>
|
||||
#include <machine/sysconf.h>
|
||||
|
||||
#include <sgimips/gio/gioreg.h>
|
||||
#include <sgimips/gio/giovar.h>
|
||||
@ -360,7 +361,8 @@ hpc_match(struct device *parent, struct cfdata *cf, void *aux)
|
||||
struct gio_attach_args* ga = aux;
|
||||
|
||||
/* Make sure it's actually there and readable */
|
||||
if (badaddr((void*)MIPS_PHYS_TO_KSEG1(ga->ga_addr), sizeof(u_int32_t)))
|
||||
if (platform.badaddr((void*)MIPS_PHYS_TO_KSEG1(ga->ga_addr),
|
||||
sizeof(u_int32_t)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@ -519,7 +521,7 @@ hpc_revision(struct hpc_softc *sc, struct gio_attach_args *ga)
|
||||
if (mach_type == MACH_SGI_IP12 || mach_type == MACH_SGI_IP20) {
|
||||
u_int32_t reg;
|
||||
|
||||
if (!badaddr((void *)MIPS_PHYS_TO_KSEG1(ga->ga_addr +
|
||||
if (!platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga->ga_addr +
|
||||
HPC1_BIGENDIAN), 4)) {
|
||||
reg = *(uint32_t *)MIPS_PHYS_TO_KSEG1(ga->ga_addr +
|
||||
HPC1_BIGENDIAN);
|
||||
@ -553,7 +555,7 @@ hpc_revision(struct hpc_softc *sc, struct gio_attach_args *ga)
|
||||
* that this probe succeeds with my E++ adapter in slot 1,
|
||||
* but it appears to do the right thing in slot 0!
|
||||
*/
|
||||
if (badaddr((void *)MIPS_PHYS_TO_KSEG1(ga->ga_addr +
|
||||
if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga->ga_addr +
|
||||
HPC3_PBUS_CH7_BP), 4))
|
||||
return (15);
|
||||
else
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysconf.h,v 1.6 2005/12/11 12:18:53 christos Exp $ */
|
||||
/* $NetBSD: sysconf.h,v 1.7 2006/12/29 05:26:30 rumble Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
|
||||
@ -56,6 +56,7 @@
|
||||
struct platform {
|
||||
/*
|
||||
* Platform Specific Function Hooks
|
||||
* bad_addr - badaddr, or workaround replacement
|
||||
* bus_reset - clear memory error condition
|
||||
* cons_init - console initialization
|
||||
* intr_establish - establish interrupt handler
|
||||
@ -66,6 +67,7 @@ struct platform {
|
||||
* intr0-intr5 - CPU interrupt handler
|
||||
*/
|
||||
|
||||
int (*badaddr)(void *, size_t);
|
||||
void (*bus_reset)(void);
|
||||
void (*cons_init)(void);
|
||||
void *(*intr_establish)(int , int, int (*)(void *), void *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.102 2006/12/28 16:15:11 rumble Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.103 2006/12/29 05:26:30 rumble Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Soren S. Jorvang
|
||||
@ -34,7 +34,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.102 2006/12/28 16:15:11 rumble Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.103 2006/12/29 05:26:30 rumble Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_kgdb.h"
|
||||
@ -210,7 +210,10 @@ static void nullvoid(void);
|
||||
|
||||
void ddb_trap_hook(int where);
|
||||
|
||||
static int badaddr_workaround(void *, size_t);
|
||||
|
||||
struct platform platform = {
|
||||
.badaddr = badaddr_workaround,
|
||||
.bus_reset = unimpl_bus_reset,
|
||||
.cons_init = unimpl_cons_init,
|
||||
.intr_establish = unimpl_intr_establish,
|
||||
@ -758,6 +761,26 @@ void delay(unsigned long n)
|
||||
} while (__N > 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* IP12 appears to be buggy and unable to support reliably support badaddr.
|
||||
* The problem is that approximately 1.8% of the time a false negative is
|
||||
* generated and we stomp on invalid registers. Testing shows that neither
|
||||
* false negatives, nor consecutive false positives appear to occur.
|
||||
*/
|
||||
static int
|
||||
badaddr_workaround(void *addr, size_t size)
|
||||
{
|
||||
int i, bad;
|
||||
|
||||
for (i = bad = 0; i < 100; i++) {
|
||||
if (badaddr(addr, size))
|
||||
bad++;
|
||||
}
|
||||
|
||||
/* false positives appear not to occur */
|
||||
return (bad != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure all platform vectors are always initialized.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user