1
0
Files
2022-09-29 17:59:04 +03:00

216 lines
4.7 KiB
C

/*
* scache.c
*
*
* Copyright 1993, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#ident "$Revision: 1.16 $"
#include <sys/param.h>
#include <sys/sbd.h>
#include <sys/cpu.h>
#include <fault.h>
#include <setjmp.h>
#include <uif.h>
#include <libsc.h>
#include <libsk.h>
#include <pon.h>
#include "cache.h"
static void
scache_error(char *type, void *addr, __psunsigned_t act, __psunsigned_t exp)
{
act = ip30_ssram_swizzle(act);
exp = ip30_ssram_swizzle(exp);
msg_printf(ERR|PRCPU,
"Secondary cache address error: Address 0x%x,"
" Actual 0x%x, Expected 0x%x (SRAM=%s)\n",
type,addr,act,exp,ip30_ssram(addr,act,exp,cpuid()));
}
/*
* scache - secondary cache SRAM test
*/
u_int
scache(void)
{
/* Secondary cache size, 0 if PC version */
extern int _sidcache_size;
int error = 0;
if(!_sidcache_size) {
msg_printf(VRB|PRCPU,
"*** No Secondary Cache detected, test skipped\n");
return(0);
}
msg_printf(VRB|PRCPU, "Secondary cache data and address tests\n");
FlushAllCaches();
setstackseg(K1BASE);
run_uncached();
error = scachedata() || scacheaddr();
flush_cache();
setstackseg(K0BASE);
run_cached();
FlushAllCaches();
if (error) {
sum_error("secondary cache data or address");
} else {
okydoky();
}
return error;
}
/*
* scachedata - secondary walking bit test
*
*/
int
scachedata(void)
{
register __psunsigned_t *fillptr;
register uint i, pattern;
__psunsigned_t *k0_base = (__psunsigned_t *) PHYS_TO_K0(PHYS_CHECK_LO);
uint fail = 0, odd = 0;
uint sid_size = (uint) (SID_SIZE / sizeof (__psunsigned_t));
uint pd_size = (uint) (PD_SIZE / sizeof (__psunsigned_t));
pattern = 0x1;
while (pattern != 0) {
busy (1);
invalidate_caches();
/* Fill secondary through primary */
fillptr = k0_base;
for (i = sid_size; i > 0; --i) {
*fillptr++ = pattern;
}
/* write final values to secondary and invalidate primary */
fillptr = k0_base;
for (i = pd_size; i > 0; --i) {
pd_HWBINV ((volatile uint *)fillptr++);
}
/* Read back and check */
fillptr = k0_base;
for (i = sid_size; i > 0; --i) {
if ((uint)*fillptr != pattern) {
scache_error("",fillptr,*fillptr,pattern);
fail = 1;
}
fillptr++;
}
pattern = ~pattern; /* invert */
odd = !odd;
if (!odd) { /* every other time... */
pattern <<= 1; /* shift bit left */
}
}
busy (0);
return (fail);
}
/*
* scacheaddr - secondary address uniqueness test
*
* does not provide the bit error coverage of icachedata, but by storing
* address-in-address and ~address-in-address, should find if each
* cache location is individually addressable
*/
int
scacheaddr(void)
{
register __psunsigned_t *fillptr;
uint i;
__psunsigned_t *k0_base = (__psunsigned_t *) PHYS_TO_K0(PHYS_CHECK_LO);
uint fail = 0;
uint sid_size = (uint) (SID_SIZE / sizeof (__psunsigned_t));
uint pd_size = (uint) (PD_SIZE / sizeof (__psunsigned_t));
invalidate_caches();
/* Fill secondary through primary */
fillptr = k0_base;
for (i = sid_size; i > 0; --i) {
*fillptr = (__psunsigned_t) fillptr;
fillptr++;
}
/* write final values to secondary and invalidate primary */
fillptr = k0_base;
for (i = pd_size; i > 0; --i) {
pd_HWBINV ((volatile uint *)fillptr);
fillptr++;
}
/* Read back and check */
fillptr = k0_base;
for (i = sid_size; i > 0; --i) {
if (*fillptr != (__psunsigned_t) fillptr) {
scache_error("data",fillptr,*fillptr,
(__psunsigned_t) fillptr);
fail = 1;
}
fillptr++;
}
/* again, with address inverted */
invalidate_caches();
/* Fill secondary through primary */
fillptr = k0_base;
for (i = sid_size; i > 0; --i) {
*fillptr = ~(__psunsigned_t)fillptr;
fillptr++;
}
/* write final values to secondary and invalidate primary */
fillptr = k0_base;
for (i = pd_size; i > 0; --i) {
pd_HWBINV ((volatile uint *)fillptr);
fillptr++;
}
/* Read back and check */
fillptr = k0_base;
for (i = sid_size; i > 0; --i) {
if (*fillptr != ~(__psunsigned_t)fillptr) {
scache_error("address",fillptr,*fillptr,
~(__psunsigned_t)fillptr);
fail = 1;
}
fillptr++;
}
return (fail);
}