Subject: Re: port-alpha/36628: cdhdtape image panics with memory management
To: None <tsutsui@NetBSD.org, gnats-admin@netbsd.org,>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 07/20/2007 20:25:02
The following reply was made to PR port-alpha/36628; it has been noted by GNATS.
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
To: gnats-bugs@NetBSD.org
Cc: ChristophFranzen@gmx.net, tsutsui@ceres.dti.ne.jp
Subject: Re: port-alpha/36628: cdhdtape image panics with memory management
trap on Jensen
Date: Sat, 21 Jul 2007 05:24:22 +0900
ChristophFranzen@gmx.net wrote:
> the Result is attached.
:
> > http://www.ceres.dti.ne.jp/~tsutsui/netbsd/cdhdtape-20070719.gz
>
> I did not send this to GNATS because the attachment ist rather large,
> and I don't know which information you need so I haven't shortened
> the file.
Thanks, it shows that reading config data region of invalid slots
causes the problem:
---
:
eisa0 at jensenio0
EISA config header at 0x1ac061000
EISA config at 0x1a0000000
EISA config stride: 512
SLOT 0: offset 0x18386800 eisaid DEC2400
SLOT 1: offset 0x18397000 eisaid ELS8041
SLOT 2: offset 0x183b4800 eisaid ADP0002
SLOT 3: offset 0x183c6400 eisaid CPQ6101
SLOT 8: offset 0x00000008 eisaid <DD><DD><DD><DD><DD><DD><DD>
SLOT 9: offset 0x00009b63 eisaid <FF><FF><FF><FF><FF><FF><FF>
SLOT 10: offset 0xffffffff eisaid <FF><FF><FF><FF><FF><FF><FF>
SLOT 11: offset 0xffffffff eisaid <FF><FF><FF><FF><FF><FF><FF>
SLOT 12: offset 0xffffffff eisaid <FF><FF><FF><FF><FF><FF><FF>
SLOT 13: offset 0xffffffff eisaid <FF><FF><FF><FF><FF><FF><FF>
SLOT 14: offset 0xffffffff eisaid <FF><FF><FF><FF><FF><FF><FF>
SLOT 15: offset 0xffffffff eisaid <FF><FF><FF><FF><FF><FF><FF>
:
SLOT 8 compressed data length 48:
0x01 0x09 0x10 0x01 0x55 0x00 0xaa 0xff 0x56 0x31 0x2e 0x31 0x20 0x20 0x20 0x20
0x44 0x45 0x43 0x20 0x20 0x20 0x20 0x20 0x4a 0x45 0x4e 0x53 0x5f 0x53 0x59 0x53
0x41 0x4c 0x50 0x48 0xff 0xff 0xff 0xff 0x17 0x01 0x01 0x00 0xc0 0x03 0x00 0x00
SLOT 8 uncompressed header data:
0x01 0x09 0x10 0x01 0x55 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
SLOT 8: ndevfuncs 0
Slot 8:0 done
Reading config bytes to cdata[0] at 0x1a0009b63
Reading config bytes to cdata[1] at 0x1a0009d63
:
Reading config bytes to cdata[62463] at 0x1a1e89963
Reading config bytes to cdata[62464] at 0x1a1e89b63
CPU 0: fatal kernel trap:
CPU 0 trap entry = 0x2 (memory management fault)
CPU 0 a0 = 0xfffffe0000058000
CPU 0 a1 = 0x1
CPU 0 a2 = 0x0
CPU 0 pc = 0xfffffc000058fa10
CPU 0 ra = 0xfffffc000059008c
:
---
Maybe we shouldn't check slots more than 8 at least on Jensen
(though I'm not sure how it worked in the past).
How about this one?
http://www.ceres.dti.ne.jp/~tsutsui/netbsd/cdhdtape-20070720.gz
---
Index: eisa/eisa_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/eisa/eisa_machdep.c,v
retrieving revision 1.5
diff -u -r1.5 eisa_machdep.c
--- eisa/eisa_machdep.c 1 Jun 2002 23:50:53 -0000 1.5
+++ eisa/eisa_machdep.c 20 Jul 2007 20:20:21 -0000
@@ -79,6 +79,7 @@
#define ECUF_DMA_ENTRY_CNT 4
#define ECUF_IO_ENTRY_CNT 20
+#define CBUFSIZE 512
/*
* EISA configuration space, as set up by the ECU, may be sparse.
*/
@@ -162,7 +163,9 @@
int i;
for (i = 0; i < ECUF_MEM_ENTRY_CNT; i++) {
- ecum = malloc(sizeof(*ecum), M_DEVBUF, M_WAITOK);
+ ecum = malloc(sizeof(*ecum), M_DEVBUF, M_ZERO|M_WAITOK);
+ if (ecum == NULL)
+ panic("%s: can't allocate memory for ecum", __func__);
ecum->ecum_mem.ecm_isram = dp[0] & 0x1;
ecum->ecum_mem.ecm_unitsize = dp[1] & 0x3;
@@ -174,7 +177,7 @@
ecum->ecum_mem.ecm_size = (1 << 26);
SIMPLEQ_INSERT_TAIL(&ecuf->ecuf_mem, ecum, ecum_list);
-#if 0
+#ifdef EISA_DEBUG
printf("MEM 0x%lx 0x%lx %d %d %d\n",
ecum->ecum_mem.ecm_addr, ecum->ecum_mem.ecm_size,
ecum->ecum_mem.ecm_isram, ecum->ecum_mem.ecm_unitsize,
@@ -194,17 +197,19 @@
int i;
for (i = 0; i < ECUF_IRQ_ENTRY_CNT; i++) {
- ecui = malloc(sizeof(*ecui), M_DEVBUF, M_WAITOK);
+ ecui = malloc(sizeof(*ecui), M_DEVBUF, M_ZERO|M_WAITOK);
+ if (ecui == NULL)
+ panic("%s: can't allocate memory for ecui", __func__);
ecui->ecui_irq.eci_irq = dp[0] & 0xf;
ecui->ecui_irq.eci_ist = (dp[0] & 0x20) ? IST_LEVEL : IST_EDGE;
ecui->ecui_irq.eci_shared = (dp[0] & 0x40) ? 1 : 0;
SIMPLEQ_INSERT_TAIL(&ecuf->ecuf_irq, ecui, ecui_list);
-#if 0
- printf("IRQ %d %s%s\n", ecui->eci_irq.ecui_irq,
- ecui->eci_irq.ecui_ist == IST_LEVEL ? "level" : "edge",
- ecui->eci_irq.ecui_shared ? " shared" : "");
+#ifdef EISA_DEBUG
+ printf("IRQ %d %s%s\n", ecui->ecui_irq.eci_irq,
+ ecui->ecui_irq.eci_ist == IST_LEVEL ? "level" : "edge",
+ ecui->ecui_irq.eci_shared ? " shared" : "");
#endif
if ((dp[0] & 0x80) == 0)
@@ -220,7 +225,9 @@
int i;
for (i = 0; i < ECUF_DMA_ENTRY_CNT; i++) {
- ecud = malloc(sizeof(*ecud), M_DEVBUF, M_WAITOK);
+ ecud = malloc(sizeof(*ecud), M_DEVBUF, M_ZERO|M_WAITOK);
+ if (ecud == NULL)
+ panic("%s: can't allocate memory for ecud", __func__);
ecud->ecud_dma.ecd_drq = dp[0] & 0x7;
ecud->ecud_dma.ecd_shared = dp[0] & 0x40;
@@ -228,7 +235,7 @@
ecud->ecud_dma.ecd_timing = (dp[1] >> 4) & 0x3;
SIMPLEQ_INSERT_TAIL(&ecuf->ecuf_dma, ecud, ecud_list);
-#if 0
+#ifdef EISA_DEBUG
printf("DRQ %d%s %d %d\n", ecud->ecud_dma.ecd_drq,
ecud->ecud_dma.ecd_shared ? " shared" : "",
ecud->ecud_dma.ecd_size, ecud->ecud_dma.ecd_timing);
@@ -247,13 +254,15 @@
int i;
for (i = 0; i < ECUF_IO_ENTRY_CNT; i++) {
- ecuio = malloc(sizeof(*ecuio), M_DEVBUF, M_WAITOK);
+ ecuio = malloc(sizeof(*ecuio), M_DEVBUF, M_ZERO|M_WAITOK);
+ if (ecuio == NULL)
+ panic("%s: can't allocate memory for ecuio", __func__);
ecuio->ecuio_io.ecio_addr = dp[1] | (dp[2] << 8);
ecuio->ecuio_io.ecio_size = (dp[0] & 0x1f) + 1;
ecuio->ecuio_io.ecio_shared = (dp[0] & 0x40) ? 1 : 0;
-#if 0
+#ifdef EISA_DEBUG
printf("IO 0x%lx 0x%lx%s\n", ecuio->ecuio_io.ecio_addr,
ecuio->ecuio_io.ecio_size,
ecuio->ecuio_io.ecio_shared ? " shared" : "");
@@ -285,7 +294,7 @@
int i;
for (i = 0; i < sizeof(val); i++) {
- val |= (u_int)(*src << (i * 8));
+ val |= (u_int)*src << (i * 8);
src += eisa_config_stride;
}
@@ -314,7 +323,7 @@
}
void
-eisa_init()
+eisa_init(eisa_chipset_tag_t ec)
{
struct ecu_data *ecud;
paddr_t cfgaddr;
@@ -340,30 +349,36 @@
}
eisa_config_header_addr = hwrpb->rpb_condat_off;
-#if 0
- printf("\nEISA config header at 0x%lx\n", eisa_config_header_addr);
-#endif
if (eisa_config_stride == 0)
eisa_config_stride = 1;
+#ifdef EISA_DEBUG
+ printf("\nEISA config header at 0x%lx\n", eisa_config_header_addr);
+ printf("EISA config at 0x%lx\n", eisa_config_addr);
+ printf("EISA config stride: %ld\n", eisa_config_stride);
+#endif
+
/*
* Read the slot headers, and allocate config structures for
* valid slots.
*/
- for (cfgaddr = eisa_config_header_addr, i = 0; i < 16 /* XXX */; i++) {
+ for (cfgaddr = eisa_config_header_addr, i = 0;
+ i < eisa_maxslots(ec); i++) {
eisa_read_config_bytes(cfgaddr, eisaid, sizeof(eisaid));
eisaid[EISA_IDSTRINGLEN - 1] = '\0'; /* sanity */
cfgaddr += sizeof(eisaid) * eisa_config_stride;
eisa_read_config_word(cfgaddr, &offset);
cfgaddr += sizeof(offset) * eisa_config_stride;
- if (offset != 0) {
-#if 0
+ if (offset != 0 || offset != 0xffffffff) {
+#ifdef EISA_DEBUG
printf("SLOT %d: offset 0x%08x eisaid %s\n",
i, offset, eisaid);
#endif
- ecud = malloc(sizeof(*ecud), M_DEVBUF, M_WAITOK);
- memset(ecud, 0, sizeof(*ecud));
+ ecud = malloc(sizeof(*ecud), M_DEVBUF, M_ZERO|M_WAITOK);
+ if (ecud == NULL)
+ panic("%s: can't allocate memory for ecud",
+ __func__);
SIMPLEQ_INIT(&ecud->ecud_funcs);
@@ -378,22 +393,42 @@
* Now traverse the valid slots and read the info.
*/
- cdata = malloc(512, M_TEMP, M_WAITOK);
- data = malloc(512, M_TEMP, M_WAITOK);
+ cdata = malloc(CBUFSIZE, M_TEMP, M_ZERO|M_WAITOK);
+ if (cdata == NULL)
+ panic("%s: can't allocate memory for cdata", __func__);
+ data = malloc(CBUFSIZE, M_TEMP, M_ZERO|M_WAITOK);
+ if (data == NULL)
+ panic("%s: can't allocate memory for data", __func__);
SIMPLEQ_FOREACH(ecud, &ecu_data_list, ecud_list) {
cfgaddr = eisa_config_addr + ecud->ecud_offset;
+#ifdef EISA_DEBUG
+ printf("Checking SLOT %d\n", ecud->ecud_slot);
+ printf("Reading config bytes at 0x%lx to cdata[0]\n", cfgaddr);
+#endif
eisa_read_config_bytes(cfgaddr, &cdata[0], 1);
cfgaddr += eisa_config_stride;
- for (i = 1; ; cfgaddr += eisa_config_stride, i++) {
+ for (i = 1; i < CBUFSIZE; cfgaddr += eisa_config_stride, i++) {
+#ifdef EISA_DEBUG
+ printf("Reading config bytes at 0x%lx to cdata[%d]\n",
+ cfgaddr, i);
+#endif
eisa_read_config_bytes(cfgaddr, &cdata[i], 1);
if (cdata[i - 1] == 0 && cdata[i] == 0)
break;
}
+ if (i == CBUFSIZE) {
+ /* assume this compressed data invalid */
+#ifdef EISA_DEBUG
+ printf("SLOT %d has invalid config\n", ecud->ecud_slot);
+#endif
+ continue;
+ }
+
i++; /* index -> length */
-#if 0
+#ifdef EISA_DEBUG
printf("SLOT %d compressed data length %d:",
ecud->ecud_slot, i);
{
@@ -413,7 +448,7 @@
/* Uncompress the slot header. */
cdp += eisa_uncompress(cdp, dp, EISA_SLOT_HEADER_SIZE);
-#if 0
+#ifdef EISA_DEBUG
printf("SLOT %d uncompressed header data:",
ecud->ecud_slot);
{
@@ -439,7 +474,7 @@
memcpy(&ecud->ecud_comp_id, dp, sizeof(ecud->ecud_comp_id));
dp += sizeof(ecud->ecud_comp_id);
-#if 0
+#ifdef EISA_DEBUG
printf("SLOT %d: ndevfuncs %d\n", ecud->ecud_slot,
ecud->ecud_ndevfuncs);
#endif
@@ -447,7 +482,7 @@
for (func = 0; func < ecud->ecud_ndevfuncs; func++) {
dp = data;
cdp += eisa_uncompress(cdp, dp, EISA_CONFIG_BLOCK_SIZE);
-#if 0
+#ifdef EISA_DEBUG
printf("SLOT %d:%d uncompressed data:",
ecud->ecud_slot, func);
{
@@ -464,7 +499,7 @@
/* Skip disabled functions. */
if (dp[EISA_FUNC_INFO_OFFSET] & ECUF_DISABLED) {
-#if 0
+#ifdef EISA_DEBUG
printf("SLOT %d:%d disabled\n",
ecud->ecud_slot, func);
#endif
@@ -472,6 +507,9 @@
}
ecuf = malloc(sizeof(*ecuf), M_DEVBUF, M_WAITOK);
+ if (ecuf == NULL)
+ panic("%s: can't allocate memory for ecuf",
+ __func__);
ecuf_init(ecuf);
ecuf->ecuf_funcno = func;
SIMPLEQ_INSERT_TAIL(&ecud->ecud_funcs, ecuf,
Index: include/eisa_machdep.h
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/include/eisa_machdep.h,v
retrieving revision 1.7
diff -u -r1.7 eisa_machdep.h
--- include/eisa_machdep.h 11 Aug 2000 00:43:20 -0000 1.7
+++ include/eisa_machdep.h 20 Jul 2007 20:20:21 -0000
@@ -78,7 +78,7 @@
* Internal functions, NOT TO BE USED BY MACHINE-INDEPENDENT CODE!
*/
-void eisa_init(void);
+void eisa_init(eisa_chipset_tag_t);
extern bus_size_t eisa_config_stride;
extern paddr_t eisa_config_addr;
Index: jensenio/jensenio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/jensenio/jensenio.c,v
retrieving revision 1.13
diff -u -r1.13 jensenio.c
--- jensenio/jensenio.c 11 Dec 2005 12:16:17 -0000 1.13
+++ jensenio/jensenio.c 20 Jul 2007 20:20:21 -0000
@@ -244,7 +244,7 @@
*/
eisa_config_stride = 0x200;
eisa_config_addr = JENSEN_FEPROM1;
- eisa_init();
+ eisa_init(eba->eba_ec);
#endif
}
@@ -252,7 +252,7 @@
jensenio_eisa_maxslots(void *v)
{
- return (16); /* as good a number as any. only 8, maybe? */
+ return (8); /* jensen seems to have only 8 valid slots */
}
void
Index: pci/sio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/pci/sio.c,v
retrieving revision 1.40
diff -u -r1.40 sio.c
--- pci/sio.c 11 Dec 2005 12:16:17 -0000 1.40
+++ pci/sio.c 20 Jul 2007 20:20:21 -0000
@@ -318,7 +318,7 @@
{
#if NEISA > 0
- eisa_init();
+ eisa_init(eba->eba_ec);
#endif
}
---
Izumi Tsutsui