diff --git a/sys/arch/alpha/common/sgmap_typedep.c b/sys/arch/alpha/common/sgmap_typedep.c index 312ecdba13e4..510606c6060b 100644 --- a/sys/arch/alpha/common/sgmap_typedep.c +++ b/sys/arch/alpha/common/sgmap_typedep.c @@ -1,4 +1,4 @@ -/* $NetBSD: sgmap_typedep.c,v 1.3 1997/09/02 20:11:24 thorpej Exp $ */ +/* $NetBSD: sgmap_typedep.c,v 1.4 1997/09/05 02:21:49 thorpej Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -37,7 +37,21 @@ * POSSIBILITY OF SUCH DAMAGE. */ -__KERNEL_RCSID(0, "$NetBSD: sgmap_typedep.c,v 1.3 1997/09/02 20:11:24 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sgmap_typedep.c,v 1.4 1997/09/05 02:21:49 thorpej Exp $"); + +#ifdef SGMAP_LOG + +#ifndef SGMAP_LOGSIZE +#define SGMAP_LOGSIZE 4096 +#endif + +struct sgmap_log_entry __C(SGMAP_TYPE,_log)[SGMAP_LOGSIZE]; +int __C(SGMAP_TYPE,_log_next); +int __C(SGMAP_TYPE,_log_last); +u_long __C(SGMAP_TYPE,_log_loads); +u_long __C(SGMAP_TYPE,_log_unloads); + +#endif /* SGMAP_LOG */ int __C(SGMAP_TYPE,_load)(t, map, buf, buflen, p, flags, sgmap) @@ -56,15 +70,18 @@ __C(SGMAP_TYPE,_load)(t, map, buf, buflen, p, flags, sgmap) bus_size_t dmalen; SGMAP_PTE_TYPE *pte, *page_table = sgmap->aps_pt; int pteidx, error; - - if (buflen > map->_dm_size) - return (EINVAL); +#ifdef SGMAP_LOG + struct sgmap_log_entry sl; +#endif /* * Make sure that on error condition we return "no valid mappings". */ map->dm_nsegs = 0; + if (buflen > map->_dm_size) + return (EINVAL); + /* * Remember the offset into the first page and the total * transfer length. @@ -78,6 +95,16 @@ __C(SGMAP_TYPE,_load)(t, map, buf, buflen, p, flags, sgmap) dmaoffset, dmalen); #endif +#ifdef SGMAP_LOG + if (panicstr == NULL) { + sl.sl_op = 1; + sl.sl_sgmap = sgmap; + sl.sl_origbuf = buf; + sl.sl_pgoffset = dmaoffset; + sl.sl_origlen = dmalen; + } +#endif + /* * Allocate the necessary virtual address space for the * mapping. Round the size, since we deal with whole pages. @@ -105,6 +132,13 @@ __C(SGMAP_TYPE,_load)(t, map, buf, buflen, p, flags, sgmap) (pteidx << SGMAP_ADDR_PTEIDX_SHIFT) | dmaoffset; map->dm_segs[0].ds_len = dmalen; +#ifdef SGMAP_LOG + if (panicstr == NULL) { + sl.sl_sgva = a->apdc_sgva; + sl.sl_dmaaddr = map->dm_segs[0].ds_addr; + } +#endif + #ifdef SGMAP_DEBUG printf("sgmap_load: wbase = 0x%lx, vpage = 0x%x, dma addr = 0x%lx\n", sgmap->aps_wbase, (pteidx << SGMAP_ADDR_PTEIDX_SHIFT), @@ -136,6 +170,18 @@ __C(SGMAP_TYPE,_load)(t, map, buf, buflen, p, flags, sgmap) alpha_mb(); +#ifdef SGMAP_LOG + if (panicstr == NULL) { + sl.sl_ptecnt = a->apdc_ptecnt; + bcopy(&sl, &__C(SGMAP_TYPE,_log)[__C(SGMAP_TYPE,_log_next)], + sizeof(sl)); + __C(SGMAP_TYPE,_log_last) = __C(SGMAP_TYPE,_log_next); + if (++__C(SGMAP_TYPE,_log_next) == SGMAP_LOGSIZE) + __C(SGMAP_TYPE,_log_next) = 0; + __C(SGMAP_TYPE,_log_loads)++; + } +#endif + map->dm_nsegs = 1; return (0); } @@ -187,6 +233,24 @@ __C(SGMAP_TYPE,_unload)(t, map, sgmap) struct alpha_sgmap_cookie *a = map->_dm_sgcookie; SGMAP_PTE_TYPE *pte, *page_table = sgmap->aps_pt; int ptecnt; +#ifdef SGMAP_LOG + struct sgmap_log_entry *sl; + + if (panicstr == NULL) { + sl = &__C(SGMAP_TYPE,_log)[__C(SGMAP_TYPE,_log_next)]; + + bzero(sl, sizeof(*sl)); + sl->sl_op = 0; + sl->sl_sgmap = sgmap; + sl->sl_sgva = a->apdc_sgva; + sl->sl_dmaaddr = map->dm_segs[0].ds_addr; + + __C(SGMAP_TYPE,_log_last) = __C(SGMAP_TYPE,_log_next); + if (++__C(SGMAP_TYPE,_log_next) == SGMAP_LOGSIZE) + __C(SGMAP_TYPE,_log_next) = 0; + __C(SGMAP_TYPE,_log_unloads)++; + } +#endif /* * Invalidate the PTEs for the mapping. diff --git a/sys/arch/alpha/common/sgmapvar.h b/sys/arch/alpha/common/sgmapvar.h index 8c8524a1e0dd..73971c2d67e6 100644 --- a/sys/arch/alpha/common/sgmapvar.h +++ b/sys/arch/alpha/common/sgmapvar.h @@ -1,4 +1,6 @@ -/* $NetBSD: sgmapvar.h,v 1.2 1997/06/07 05:29:33 thorpej Exp $ */ +/* $NetBSD: sgmapvar.h,v 1.3 1997/09/05 02:21:51 thorpej Exp $ */ + +#define SGMAP_LOG /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -74,6 +76,22 @@ struct alpha_sgmap_cookie { /* apdc_flags */ #define APDC_HAS_SGMAP 0x01 /* sgva/len are valid */ +#ifdef SGMAP_LOG +/* + * Log entry, used for debugging SGMAPs. + */ +struct sgmap_log_entry { + int sl_op; /* op; 1 = load, 0 = unload */ + struct alpha_sgmap *sl_sgmap; /* sgmap for entry */ + void *sl_origbuf; /* original buffer */ + u_long sl_pgoffset; /* page offset of buffer start */ + u_long sl_origlen; /* length of transfer */ + u_long sl_sgva; /* sgva of transfer */ + u_long sl_dmaaddr; /* dma address */ + int sl_ptecnt; /* pte count */ +}; +#endif + void alpha_sgmap_init __P((bus_dma_tag_t, struct alpha_sgmap *, const char *, bus_addr_t, bus_addr_t, bus_size_t, size_t, void *));