Leverage the PROM's ability to identify the on-board location of a

physical memory address.
This commit is contained in:
pk 2004-03-22 12:37:43 +00:00
parent 3aa621c910
commit b744961066
4 changed files with 64 additions and 7 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: promlib.h,v 1.18 2004/03/21 13:52:00 pk Exp $ */
/* $NetBSD: promlib.h,v 1.19 2004/03/22 12:37:43 pk Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -136,6 +136,7 @@ int prom_makememarr(struct memarr *, int max, int which);
struct idprom *prom_getidprom(void);
void prom_getether(int, u_char *);
char *prom_pa_location(u_int, u_int);
void prom_init(void); /* To setup promops */

View File

@ -1,4 +1,4 @@
/* $NetBSD: memecc.c,v 1.7 2003/07/15 00:05:06 lukem Exp $ */
/* $NetBSD: memecc.c,v 1.8 2004/03/22 12:37:43 pk Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: memecc.c,v 1.7 2003/07/15 00:05:06 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: memecc.c,v 1.8 2004/03/22 12:37:43 pk Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -142,6 +142,8 @@ memecc_error()
printf("\tMBus transaction: %s\n",
bitmask_snprintf(efar0, ECC_AFR_BITS, bits, sizeof(bits)));
printf("\taddress: 0x%x%x\n", efar0 & ECC_AFR_PAH, efar1);
printf("\tmodule location: %s\n",
prom_pa_location(efar1, efar0 & ECC_AFR_PAH));
/* Unlock registers and clear interrupt */
bus_space_write_4(memecc_sc->sc_bt, bh, ECC_FSR_REG, efsr);

View File

@ -1,4 +1,4 @@
/* $NetBSD: memreg.c,v 1.37 2003/07/15 00:05:07 lukem Exp $ */
/* $NetBSD: memreg.c,v 1.38 2004/03/22 12:37:43 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: memreg.c,v 1.37 2003/07/15 00:05:07 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: memreg.c,v 1.38 2004/03/22 12:37:43 pk Exp $");
#include "opt_sparc_arch.h"
@ -64,6 +64,7 @@ __KERNEL_RCSID(0, "$NetBSD: memreg.c,v 1.37 2003/07/15 00:05:07 lukem Exp $");
#include <sparc/sparc/asm.h>
#include <sparc/sparc/cpuvar.h>
#include <machine/pte.h>
#include <machine/reg.h> /* for trapframe */
#include <machine/trap.h> /* for trap types */
@ -192,6 +193,7 @@ memerr4_4c(issync, ser, sva, aer, ava, tf)
struct trapframe *tf; /* XXX - unused/invalid */
{
char bits[64];
u_int pte;
printf("%ssync mem arr: ser=%s sva=0x%x ",
issync ? "" : "a",
@ -199,6 +201,21 @@ memerr4_4c(issync, ser, sva, aer, ava, tf)
sva);
printf("aer=%s ava=0x%x\n", bitmask_snprintf(aer & 0xff,
AER_BITS, bits, sizeof(bits)), ava);
pte = getpte4(sva);
if ((pte & PG_V) != 0 && (pte & PG_TYPE) == PG_OBMEM) {
u_int pa = (pte & PG_PFNUM) << PGSHIFT;
printf(" spa=0x%x, module location: %s\n", pa,
prom_pa_location(pa, 0));
}
pte = getpte4(ava);
if ((pte & PG_V) != 0 && (pte & PG_TYPE) == PG_OBMEM) {
u_int pa = (pte & PG_PFNUM) << PGSHIFT;
printf(" apa=0x%x, module location: %s\n", pa,
prom_pa_location(pa, 0));
}
if (par_err_reg)
printf("parity error register = %s\n",
bitmask_snprintf(*par_err_reg, PER_BITS,

View File

@ -1,4 +1,4 @@
/* $NetBSD: promlib.c,v 1.31 2004/03/21 13:57:58 pk Exp $ */
/* $NetBSD: promlib.c,v 1.32 2004/03/22 12:37:43 pk Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: promlib.c,v 1.31 2004/03/21 13:57:58 pk Exp $");
__KERNEL_RCSID(0, "$NetBSD: promlib.c,v 1.32 2004/03/22 12:37:43 pk Exp $");
#if defined(_KERNEL_OPT)
#include "opt_sparc_arch.h"
@ -1093,6 +1093,43 @@ read_idprom:
memcpy(cp, idp->id_ether, 6);
}
/*
* The integer property "get-unum" on the root device is the address
* of a callable function in the PROM that takes a physical address
* (in lo/hipart format) and returns a string identifying the chip
* location of the corresponding memory cell.
*/
char *
prom_pa_location(u_int phys_lo, u_int phys_hi)
{
static char *(*unum)(u_int,u_int);
char *str, *unk = "<Unknown>";
switch (prom_version()) {
case PROM_OLDMON:
case PROM_OBP_V0:
case PROM_OPENFIRM:
default:
return (unk);
case PROM_OBP_V2:
case PROM_OBP_V3:
break;
}
if (unum == 0)
unum = (char *(*)(u_int,u_int))
prom_getpropint(prom_findroot(), "get-unum", 0);
if (unum == NULL)
return (unk);
str = unum(phys_lo, phys_hi);
if (str == NULL)
return (unk);
return (str);
}
static void prom_init_oldmon(void);
static void prom_init_obp(void);
static void prom_init_opf(void);