Index: autoconf.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/autoconf.c,v retrieving revision 1.176 diff -p -r1.176 autoconf.c *** autoconf.c 11 Aug 2010 19:14:26 -0000 1.176 --- autoconf.c 15 Apr 2011 08:43:49 -0000 *************** __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v *** 91,96 **** --- 91,97 ---- #include #include #include + #include #include #include *************** struct evcnt intr_evcnts[] = { *** 128,134 **** EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev12"), EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev13"), EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "prof"), ! EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev15") }; void *bootinfo = 0; --- 129,142 ---- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev12"), EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev13"), EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "prof"), ! EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev15"), ! }; ! ! struct evcnt misc_evcnts[] = { ! EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "busdma", "null unload"), ! EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "busdma", "ds_addr unload"), ! EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "busdma", "null sync"), ! EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "busdma", "ds_addr sync"), }; void *bootinfo = 0; *************** extern struct sparc_bus_space_tag mainbu *** 589,598 **** panic("None of the CPUs found"); /* ! * Init static interrupt eventcounters */ for (i = 0; i < sizeof(intr_evcnts)/sizeof(intr_evcnts[0]); i++) evcnt_attach_static(&intr_evcnts[i]); node = findroot(); --- 597,610 ---- panic("None of the CPUs found"); /* ! * Init static event counters. We do this here as we need ! * evcnt_init() to be setup, and this is the most convient ! * place to do this afterwards. */ for (i = 0; i < sizeof(intr_evcnts)/sizeof(intr_evcnts[0]); i++) evcnt_attach_static(&intr_evcnts[i]); + for (i = 0; i < sizeof(misc_evcnts)/sizeof(misc_evcnts[0]); i++) + evcnt_attach_static(&misc_evcnts[i]); node = findroot(); Index: evcnts.h =================================================================== RCS file: evcnts.h diff -N evcnts.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- evcnts.h 15 Apr 2011 08:43:49 -0000 *************** *** 0 **** --- 1,64 ---- + /* $NetBSD$ */ + + /* + * Copyright (c) 2011 Matthew R. Green + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + /* + * declare the various evcnt(9) counters used in sparc64 MD code. + */ + #ifndef _SPARC64_EVCNTS_H_ + #define _SPARC64_EVCNTS_H_ + + #include + + /* + * Global interrupt counters, level 0 (spurious) to level 15. These + * are handled inside locore. + * + * XXX Make me per-CPU. + */ + extern struct evcnt intr_evcnts[]; + + /* + * Misc. counters: + * Count how many bus_dma load or sync operations happened with + * A NULL _ds_mlist, but a seemingly valid ds_addr, and those + * that also have a NULL ds_addr. + */ + extern struct evcnt misc_evcnts[]; + #define SP64_EVCNT_NULL_UNLOAD 0 /* got a NULL address + * in a bus_dmamem_unload */ + #define SP64_EVCNT_DSADDR_UNLOAD 1 /* using ds_addr, not _ds_mlist, + * in a bus_dmamem_unload */ + #define SP64_EVCNT_NULL_SYNC 2 /* got a NULL address + * in a bus_dmamem_sync */ + #define SP64_EVCNT_DSADDR_SYNC 3 /* using ds_addr, not _ds_mlist, + * in a bus_dmamem_sync */ + + + #endif /* _SPARC64_EVCNTS_H_ */ Index: machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/machdep.c,v retrieving revision 1.256 diff -p -r1.256 machdep.c *** machdep.c 4 Mar 2011 22:25:29 -0000 1.256 --- machdep.c 15 Apr 2011 08:43:49 -0000 *************** __KERNEL_RCSID(0, "$NetBSD: machdep.c,v *** 129,134 **** --- 129,135 ---- #include #include + #include /* #include "fb.h" */ *************** _bus_dmamap_unload(bus_dma_tag_t t, bus_ *** 1283,1295 **** for (i = 0; i < map->dm_nsegs; i++) { if ((pglist = map->dm_segs[i]._ds_mlist) == NULL) { ! /* ! * We were asked to load random VAs and lost the ! * PA info so just blow the entire cache away. ! */ ! blast_dcache(); ! break; } TAILQ_FOREACH(pg, pglist, pageq.queue) { pa = VM_PAGE_TO_PHYS(pg); --- 1284,1304 ---- for (i = 0; i < map->dm_nsegs; i++) { if ((pglist = map->dm_segs[i]._ds_mlist) == NULL) { + pa = map->dm_segs[i].ds_addr & ~PAGE_MASK; ! if (pa) { ! dcache_flush_page_all(pa); ! misc_evcnts[SP64_EVCNT_DSADDR_UNLOAD].ev_count++; ! continue; ! } else { ! /* ! * We were asked to load random VAs and lost the ! * PA info so just blow the entire cache away. ! */ ! blast_dcache(); ! misc_evcnts[SP64_EVCNT_NULL_UNLOAD].ev_count++; ! break; ! } } TAILQ_FOREACH(pg, pglist, pageq.queue) { pa = VM_PAGE_TO_PHYS(pg); *************** _bus_dmamap_sync(bus_dma_tag_t t, bus_dm *** 1337,1345 **** if (ops & BUS_DMASYNC_POSTREAD) { /* Invalidate the vcache */ for (i = 0; i < map->dm_nsegs; i++) { ! if ((pglist = map->dm_segs[i]._ds_mlist) == NULL) ! /* Should not really happen. */ continue; TAILQ_FOREACH(pg, pglist, pageq.queue) { paddr_t start; psize_t size = PAGE_SIZE; --- 1346,1374 ---- if (ops & BUS_DMASYNC_POSTREAD) { /* Invalidate the vcache */ for (i = 0; i < map->dm_nsegs; i++) { ! if ((pglist = map->dm_segs[i]._ds_mlist) == NULL) { ! paddr_t start, end; ! ! start = map->dm_segs[i].ds_addr; ! ! if (start) { ! paddr_t align = dcache_line_size - 1; ! ! end = start + offset + align; ! len = (end - start) & align; ! start &= ~align; ! cache_flush_phys(start, len, 0); ! misc_evcnts[SP64_EVCNT_DSADDR_SYNC].ev_count++; ! } else { ! /* ! * Someone did somerthing wrong. Panic? ! */ ! blast_dcache(); ! misc_evcnts[SP64_EVCNT_NULL_SYNC].ev_count++; ! goto done; ! } continue; + } TAILQ_FOREACH(pg, pglist, pageq.queue) { paddr_t start; psize_t size = PAGE_SIZE;