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

1724 lines
46 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.5 $"
#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 <IP32_status.h>
#include "cache.h"
static jmp_buf fault_buf;
uint *K0_BASE = (uint *) PHYS_TO_K0 (PHYS_CHECK_LO);
uint *K1_BASE = (uint *) PHYS_TO_K1 (PHYS_CHECK_LO);
#define SC_ALL_TAGS 0
#define SC_TAG_NONZERO 1
uint save_tags1[0x8000];
uint save_tags2[0x8000];
uint save_tags3[0x8000];
uint save_tags4[0x8000];
code_t scache_ecode;
int scachedata(void);
int scacheaddr(void);
int scachepageinval(void);
int scacherandomline(void);
int scache2MBaddr(void);
void sc_fill_mem_uint(uint *, uint, uint);
void sc_fill_mem_addr(uint *, uint *, uint);
int sc_chk_mem_addr(uint *, uint *, uint, char *);
int sc_chk_mem_uint(uint *, uint, uint, char *);
void scache_close(void);
int scache_init(void);
void sc_flush_dcache(uint *);
/* enable the scache - set scache enable in CONFIG Register. */
void r5000_enable_scache(void)
{
int config_reg = 0;
config_reg = Read_C0_Config();
msg_printf(VDBG, "r5000_enable_scache read (0x%x)\n", config_reg);
config_reg |= CONFIG_TR_SE;
Write_C0_Config( config_reg );
msg_printf(VDBG, "r5000_enable_scache read2 (0x%x)\n", Read_C0_Config());
}
/* disable the scache - clear scache enable in CONFIG Register. */
void r5000_disable_scache(void)
{
int config_reg = 0;
config_reg = Read_C0_Config();
config_reg &= ~CONFIG_TR_SE;
msg_printf(VDBG, "r5000_disable_scache writing (0x%x)\n", config_reg);
Write_C0_Config( config_reg );
msg_printf(VDBG, "r5000_disable_scache readback (0x%x)\n", Read_C0_Config());
}
scache_save_tags(uint *sc_save_addr)
{
register uint *fillptr, i;
fillptr = K0_BASE;
for ( i=0; i < (SID_SIZE/SIDL_SIZE); i++, fillptr+=(SIDL_SIZE/sizeof(int)) ) {
_read_tag(CACH_SD,(ulong)fillptr,sc_save_addr++);
}
}
scache_cmp_tags(uint *sc_save_addr1, uint *sc_save_addr2)
{
register uint i;
register uint found_diff;
found_diff = 0;
for ( i=0; i < (SID_SIZE/SIDL_SIZE); i++ ) {
if ( *sc_save_addr1++ != *sc_save_addr2++ ) {
found_diff++;
}
}
return(found_diff);
}
scache_pr_cmp_tags(uint *sc_save_addr1, uint *sc_save_addr2)
{
register uint *fillptr, i;
fillptr = K0_BASE;
for ( i=0; i < (SID_SIZE/SIDL_SIZE); i++, fillptr+=(SIDL_SIZE/sizeof(int)) ) {
if ( *sc_save_addr1 != *sc_save_addr2 ) {
msg_printf(VDBG, "Tags for 0x%x differ, 0x%x != 0x%x\n", fillptr,
*sc_save_addr1, *sc_save_addr2);
}
sc_save_addr1++;
sc_save_addr2++;
}
}
#if 0
scache_is_invalid(uint *sc_addr)
{
uint tags;
_read_tag(CACH_SD,(ulong)sc_addr,&tags);
if ( (tags & XXXXXX) == 0 ) {
return(1);
}
return(0);
}
#endif /* 0 */
scache_print_tags(uint sc_prtype)
{
register uint *fillptr, i;
uint tags, one_nonzero;
fillptr = K0_BASE;
switch ( sc_prtype ) {
case SC_ALL_TAGS:
for ( i=0; i < (SID_SIZE/SIDL_SIZE); i++, fillptr+=(SIDL_SIZE/sizeof(int)) ) {
_read_tag(CACH_SD,(ulong)fillptr,&tags);
msg_printf(VDBG, "Read ALL TAGS for 0x%x==0x%x\n", fillptr, tags);
}
break;
case SC_TAG_NONZERO:
one_nonzero = 0;
for ( i=0; i < (SID_SIZE/SIDL_SIZE); i++, fillptr+=(SIDL_SIZE/sizeof(int)) ) {
_read_tag(CACH_SD,(ulong)fillptr,&tags);
if ( tags != 0 ) {
msg_printf(VDBG, "Read TAG NON-ZERO for 0x%x==0x%x\n",
fillptr, tags);
one_nonzero++;
}
}
if ( !one_nonzero ) {
msg_printf(VDBG, "All TAGS are ZERO\n");
}
break;
default:
msg_printf(ERR, "Illegal scache_print_tags TYPE (0x%x)\n",
sc_prtype);
}
}
int scache_init()
{
extern int _sidcache_size;
extern u_int _r5000_sidcache_size;
int tmp, config_reg = 0;
int r5000 = ((get_prid()&C0_IMPMASK)>>C0_IMPSHIFT) == C0_IMP_R5000;
if (!r5000) {
cache_K0();
return(0);
}
r5000_enable_scache();
tmp = config_cache();
tmp = size_2nd_cache();
msg_printf(VDBG,"size 2nd cache returned %x\n",tmp);
msg_printf(VDBG, "_r5000_sidcache_size==0x%x,_sidcache_size==0x%x\n",
_r5000_sidcache_size, _sidcache_size);
msg_printf(VDBG, "i_ls=0x%x,d_ls==0x%x,s_ls=0x%x\n", _icache_linesize,
_dcache_linesize, _scache_linesize);
if(! _sidcache_size) {
msg_printf(VRB, "*** No Secondary Cache detected, test skipped\n");
return(1);
}
if ( _r5000_sidcache_size != _sidcache_size ) {
msg_printf(ERR, "Config reg vs. Probed Scache Size Error\n");
msg_printf(ERR, "Probed Size==0x%x,Config Reg Size==0x%x\n",
_r5000_sidcache_size, _sidcache_size);
config_reg = Read_C0_Config();
msg_printf(ERR, "CONFIG Register==0x%x\n", config_reg);
return(1);
}
/* print warning if more than 2MB */
if ( _sidcache_size > MAXCACHE ) {
msg_printf(INFO, "Secondary Cache Greater than MAXCACHE\n");
}
msg_printf(VDBG, "Enabling S-Cache (bit 12 Config Register)\n");
uncache_K0();
r5000_enable_scache();
config_reg = Read_C0_Config();
msg_printf(VDBG, "New CONFIG Register==0x%x\n", config_reg);
msg_printf(VDBG,"Invalidate Caches\n");
invalidate_caches();
scache_print_tags(SC_TAG_NONZERO);
run_uncached();
cache_K0();
return(0);
}
void scache_close(void)
{
int r5000 = ((get_prid()&C0_IMPMASK)>>C0_IMPSHIFT) == C0_IMP_R5000;
if (!r5000) {
invalidate_caches();
cache_K0();
return;
}
uncache_K0();
invalidate_caches();
r5000_disable_scache();
run_cached();
cache_K0();
}
/*
* scache - secondary cache SRAM test
*/
u_int
scache_ad()
{
int error = 0;
int config_reg = 0;
scache_ecode.sw = 0x08;
scache_ecode.func = 0x03;
scache_ecode.test = 0x02;
scache_ecode.code = 0;
scache_ecode.w1 = 0;
scache_ecode.w2 = 0;
if ( scache_init() ) {
return(0);
}
config_reg = Read_C0_Config();
msg_printf(VDBG, "CONFIG Register==0x%x\n", config_reg);
msg_printf(VDBG,"Invalidate Caches\n");
invalidate_caches();
scache_print_tags(SC_TAG_NONZERO);
msg_printf(VRB, "Secondary cache data and address tests\n");
error += (scachedata() || scacheaddr());
scache_close();
if (error) {
sum_error("secondary cache data or address");
} else {
okydoky();
}
return error;
}
/*
* scache_addr - secondary cache address test
*/
u_int
scache_addr()
{
int error = 0;
int config_reg = 0;
scache_ecode.sw = 0x08;
scache_ecode.func = 0x03;
scache_ecode.test = 0x01;
scache_ecode.code = 0;
scache_ecode.w1 = 0;
scache_ecode.w2 = 0;
if ( scache_init() ) {
return(0);
}
config_reg = Read_C0_Config();
msg_printf(VDBG, "CONFIG Register==0x%x\n", config_reg);
msg_printf(VRB, "Secondary cache address tests\n");
error += (scacheaddr());
scache_close();
if (error) {
sum_error("secondary cache data or address");
} else {
okydoky();
}
return error;
}
/*
* scache_page_inval - secondary cache address test
*/
u_int
scache_page_inval()
{
int error = 0;
int config_reg = 0;
int r5000 = ((get_prid()&C0_IMPMASK)>>C0_IMPSHIFT) == C0_IMP_R5000;
scache_ecode.sw = 0x08;
scache_ecode.func = 0x03;
scache_ecode.test = 0x03;
scache_ecode.code = 0;
scache_ecode.w1 = 0;
scache_ecode.w2 = 0;
if ( scache_init() ) {
return(0);
}
config_reg = Read_C0_Config();
msg_printf(VDBG, "CONFIG Register==0x%x\n", config_reg);
msg_printf(VRB, "Secondary cache page invalidate test\n");
if (r5000)
error += (scachepageinval());
else
msg_printf(VRB, "skipping - N/A for R10000/R12000\n");
scache_close();
if (error) {
sum_error("secondary cache data or address");
} else {
okydoky();
}
return error;
}
/*
* scache_random_line - secondary cache random line miss test
*/
u_int
scache_random_line()
{
int error = 0;
int config_reg = 0;
scache_ecode.sw = 0x08;
scache_ecode.func = 0x03;
scache_ecode.test = 0x04;
scache_ecode.code = 0;
scache_ecode.w1 = 0;
scache_ecode.w2 = 0;
if ( scache_init() ) {
return(0);
}
config_reg = Read_C0_Config();
msg_printf(VDBG, "CONFIG Register==0x%x\n", config_reg);
msg_printf(VRB, "Secondary cache random line miss test\n");
error += (scacherandomline());
scache_close();
if (error) {
sum_error("secondary cache data or address");
} else {
okydoky();
}
return error;
}
/*
* scache - secondary cache SRAM test, using all memory
*/
u_int
scache_allmem()
{
int error = 0;
int config_reg = 0;
unsigned int mem_size;
uint *k0_base = K0_BASE;
uint *k1_base = K1_BASE;
extern unsigned int memsize;
scache_ecode.sw = 0x08;
scache_ecode.func = 0x03;
scache_ecode.test = 0x05;
scache_ecode.code = 0;
scache_ecode.w1 = 0;
scache_ecode.w2 = 0;
if ( scache_init() ) {
return(0);
}
config_reg = Read_C0_Config();
msg_printf(DBG, "CONFIG Register==0x%x\n", config_reg);
if (memsize < 0x10000000) /*less than 256Mbytes? */
mem_size = memsize - K1_TO_PHYS(K1_BASE);
else
mem_size = 0x10000000 - K1_TO_PHYS(K1_BASE);
msg_printf(DBG, "Memory size is 0x%x, using 0x%x (0x%x)\n",
memsize, mem_size, K1_TO_PHYS(K1_BASE));
while ( mem_size ) {
msg_printf(VDBG,"Invalidate Caches\n");
invalidate_caches();
scache_print_tags(SC_TAG_NONZERO);
msg_printf(DBG, "Scache data and address tests (0x%x,0x%x)\n",
K0_BASE, K1_BASE);
error += (scachedata() || scacheaddr());
mem_size -= SID_SIZE;
K0_BASE += (SID_SIZE/sizeof(int));
K1_BASE += (SID_SIZE/sizeof(int));
}
scache_close();
K0_BASE = k0_base;;
K1_BASE = k1_base;;
if (error) {
sum_error("secondary cache data or address");
} else {
okydoky();
}
return error;
}
/*
* scache_2M_addr - secondary cache address test through 2MB
* address space
*/
u_int
scache_2MB_addr()
{
int error = 0;
int config_reg = 0;
scache_ecode.sw = 0x08;
scache_ecode.func = 0x03;
scache_ecode.test = 0x06;
scache_ecode.code = 0;
scache_ecode.w1 = 0;
scache_ecode.w2 = 0;
if ( scache_init() ) {
return(0);
}
config_reg = Read_C0_Config();
msg_printf(VDBG, "CONFIG Register==0x%x\n", config_reg);
msg_printf(VRB, "Secondary cache addr test through 2MB\n");
error += (scache2MBaddr());
if ( error == 0 ) {
scache_close();
}
if (error) {
sum_error("secondary cache address in 2MB");
} else {
okydoky();
}
return error;
}
#define TWO_MEGABYTE (0x200000/sizeof(int))
/*
* scache2MBaddr - secondary address uniqueness test in 2MB
*
* 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 scache2MBaddr(void)
{
register uint *fillptr, *cfillptr, i;
uint *k0_base = K0_BASE;
uint *k1_base = K1_BASE;
uint fail = 0, inv = 0, config_reg = 0, config_reg_save = 0;
uint *Cfillptr, *UCfillptr;
msg_printf(DBG, "scache2MBaddr - test scache w/ addresses in 2MB\n");
config_reg = Read_C0_Config();
config_reg_save = config_reg;
msg_printf(VDBG, "Saved Config Register==0x%x\n", config_reg_save);
invalidate_caches();
/* Fill two megabyte range of memory, secondary and primary */
fillptr = k0_base;
msg_printf(VDBG, "Fill Scache/memory w/ addresses (address==0x%x)\n",
fillptr);
sc_fill_mem_addr(fillptr,fillptr,TWO_MEGABYTE);
/* Read back and check */
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address==0x%x)\n",
fillptr);
scache_ecode.code = 1; /* set error code before calling check that reports the error */
fail += sc_chk_mem_addr(fillptr,fillptr,TWO_MEGABYTE,
"Scache addr error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n");
/* Read memory back w/o Scache and check */
sc_flush_dcache(k0_base);
fillptr = k1_base;
cfillptr = k0_base; /* cached address was written */
msg_printf(VDBG, "Read/Check Memory (address==0x%x, cached==0x%x)\n",
fillptr, cfillptr);
scache_ecode.code = 2; /* set error code before calling check that reports the error */
fail += sc_chk_mem_addr(fillptr,cfillptr,TWO_MEGABYTE,
"Memory addr error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n");
/* again, with address inverted */
invalidate_caches();
/* Fill secondary through primary */
fillptr = k0_base;
msg_printf(VDBG, "Fill Scache/memory w/ ~addresses (address==0x%x)\n",
fillptr);
for (i = 0; i < TWO_MEGABYTE; i++) {
*fillptr++ = ~((uint)K0_TO_PHYS(fillptr));
}
msg_printf(VDBG, "Fill (complement) ended at 0x%x\n", fillptr);
/* Read back and check */
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address==0x%x)\n",
fillptr);
for (i = 0; i < TWO_MEGABYTE; i++, fillptr++) {
if (*fillptr != ~((uint)K0_TO_PHYS(fillptr))) {
scache_ecode.code = 3;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache address error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~((uint)K0_TO_PHYS(fillptr)));
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
msg_printf(VDBG, "Read and check (complement) ended at 0x%x\n", fillptr);
/* Read back memory w/o scache and check */
sc_flush_dcache(k0_base);
fillptr = k1_base;
cfillptr = k0_base; /* cached addres was used as data */
msg_printf(VDBG, "Read/Check Memory (address==0x%x)\n",
fillptr);
for (i = 0; i < TWO_MEGABYTE; i++, fillptr++, cfillptr++) {
if (*fillptr != ~((uint)K0_TO_PHYS(cfillptr))) {
scache_ecode.code = 4;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory address error (2): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~((uint)K0_TO_PHYS(cfillptr)));
fail++;
Cfillptr = (uint *)PHYS_TO_K0(K0_TO_PHYS(fillptr));
UCfillptr = (uint *)PHYS_TO_K1(K0_TO_PHYS(fillptr));
msg_printf(DBG, "Cached address contents (0x%x)==0x%x\n",
Cfillptr, *Cfillptr);
msg_printf(DBG, "Uncached address contents (0x%x)==0x%x\n",
UCfillptr, *UCfillptr);
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
msg_printf(VDBG, "Memory Read and check (complement) ended at 0x%x\n", fillptr);
/* Fill two megabyte range, backwards, of memory, secondary and primary */
fillptr = (k0_base+(TWO_MEGABYTE-1));
msg_printf(VDBG, "Fill Scache/memory w/ addresses (address==0x%x)\n",
fillptr);
for (i = 0; i < TWO_MEGABYTE; i++) {
*fillptr-- = (uint)K0_TO_PHYS(fillptr);
}
msg_printf(VDBG, "Fill ended at 0x%x\n", fillptr);
/* Read back and check */
fillptr = (k0_base+(TWO_MEGABYTE-1));
msg_printf(VDBG, "Read/Check Scache (address==0x%x)\n",
fillptr);
for (i = 0; i < TWO_MEGABYTE; i++, fillptr--) {
if (*fillptr != (uint)K0_TO_PHYS(fillptr)) {
scache_ecode.code = 5;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache addr error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, (uint)K0_TO_PHYS(fillptr));
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
msg_printf(VDBG, "Read and check ended at 0x%x\n", fillptr);
/* Read memory back w/o Scache and check */
__dcache_wb(fillptr,_dcache_size);
fillptr = k1_base;
cfillptr = k0_base; /* cached address was written */
msg_printf(VDBG, "Read/Check Memory (address==0x%x, cached==0x%x)\n",
fillptr, cfillptr);
for (i = 0; i < TWO_MEGABYTE; i++, fillptr++, cfillptr++) {
if (*fillptr != (uint)K0_TO_PHYS(cfillptr)) {
scache_ecode.code = 6;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory addr error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, (uint)K0_TO_PHYS(cfillptr));
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
msg_printf(VDBG, "Memory Read and check ended at 0x%x\n", fillptr);
/* again, with address inverted */
invalidate_caches();
/* Fill secondary through primary */
fillptr = k0_base;
msg_printf(VDBG, "Fill Scache/memory w/ ~addresses (address==0x%x)\n",
fillptr);
for (i = 0; i < TWO_MEGABYTE; i++) {
*fillptr++ = ~((uint)K0_TO_PHYS(fillptr));
}
msg_printf(VDBG, "Fill (complement) ended at 0x%x\n", fillptr);
/* Read back and check */
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address==0x%x)\n",
fillptr);
for (i = 0; i < TWO_MEGABYTE; i++, fillptr++) {
if (*fillptr != ~((uint)K0_TO_PHYS(fillptr))) {
scache_ecode.code = 7;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache address error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~((uint)K0_TO_PHYS(fillptr)));
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
msg_printf(VDBG, "Read and check (complement) ended at 0x%x\n", fillptr);
/* Read back memory w/o scache and check */
__dcache_wb(fillptr,_dcache_size);
fillptr = k1_base;
cfillptr = k0_base; /* cached addres was used as data */
msg_printf(VDBG, "Read/Check Memory (address==0x%x)\n",
fillptr);
for (i = 0; i < TWO_MEGABYTE; i++, fillptr++, cfillptr++) {
if (*fillptr != ~((uint)K0_TO_PHYS(fillptr))) {
scache_ecode.code = 8;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory address error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~((uint)K0_TO_PHYS(fillptr)));
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
msg_printf(VDBG, "Memory Read and check (complement) ended at 0x%x\n", fillptr);
return (fail);
}
/*
* scachepageinval - scache page invalidate test
*
*/
int scachepageinval(void)
{
register uint *fillptr, i, pattern;
uint *k0_base = K0_BASE;
uint *k1_base = K1_BASE;
uint fail = 0, odd = 0, config_reg = 0, config_reg_save;
uint tag1 = 0, tag2 = 0;
uint *page_base;
uint page_limit;
uint page_size;
msg_printf(DBG, "scachepageinval - test scache page invalidate operation\n");
config_reg_save = config_reg = Read_C0_Config();
msg_printf(VDBG, "Saved Config Register==0x%x\n", config_reg_save);
pattern = 0x1;
msg_printf(VDBG, "Invalidate Caches\n");
scache_save_tags(save_tags1);
invalidate_caches();
scache_save_tags(save_tags2);
scache_print_tags(SC_TAG_NONZERO);
/* Fill secondary and memory */
fillptr = k0_base;
msg_printf(VDBG, "Fill Scache/memory (address 0x%x)\n",
fillptr);
sc_fill_mem_uint(fillptr,pattern,(SID_SIZE / sizeof (uint)));
scache_save_tags(save_tags1);
/* Read back Scache and check */
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address 0x%x)\n",
fillptr);
sc_chk_mem_uint(fillptr,pattern,(SID_SIZE/sizeof(uint)),
"Scache data error (2): Address 0x%x, Actual 0x%x, Expected 0x%x\n");
scache_save_tags(save_tags2);
if ( i == 0 ) {
msg_printf(VDBG, "Scache check OK (1)\n");
}
/* now see that memory look good too */
fillptr = k1_base;
msg_printf(VDBG, "Read/Check memory (uncached 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != pattern) {
scache_ecode.code = 2;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory error (3): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, pattern);
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
if ( i == 0 ) {
msg_printf(VDBG, "Memory check OK\n");
}
/* now change memory w/o using scache */
fillptr = k1_base;
msg_printf(VDBG, "Fill memory (uncached 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i) {
*fillptr++ = ~pattern;
}
/* Read back and check */
fillptr = k1_base;
msg_printf(VDBG, "Read/Check memory (uncached 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != ~pattern) {
scache_ecode.code = 3;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory error (3): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~pattern);
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
if ( i == 0 ) {
msg_printf(VDBG, "Memory check OK\n");
}
/* Read back Scache and check */
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != pattern) {
scache_ecode.code = 4;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache data error (2): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, pattern);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
if ( i == 0 ) {
msg_printf(VDBG, "Scache check OK (2)\n");
}
page_base = K0_BASE;
page_limit = SID_SIZE;
page_size = 0x1000;
while ( page_limit ) {
if ( *Reportlevel < DBG ) {
busy (1);
}
msg_printf(VDBG, "Invalidate 0x%x based page\n", page_base);
scache_save_tags(save_tags2);
_read_tag(CACH_SD,(ulong)k0_base,&tag1);
invalidate_sc_page(page_base);
/* Read back Scache and check */
_read_tag(CACH_SD,(ulong)k0_base,&tag2);
scache_save_tags(save_tags3);
if ( scache_cmp_tags(save_tags2, save_tags3) ) {
if ( *Reportlevel == VDBG ) {
msg_printf(VDBG, "Below is after page invalidate\n");
scache_pr_cmp_tags(save_tags2, save_tags3);
}
} else {
scache_ecode.code = 5;
scache_ecode.w1 = 0;
scache_ecode.w2 = 0;
report_error(&scache_ecode);
msg_printf(ERR, "TAGS compare before/after page invalidate\n");
}
msg_printf(VDBG, "Before page invalidate==0x%x,after==0x%x\n", tag1, tag2);
fillptr = page_base;
msg_printf(VDBG, "Read/Check Scache (address 0x%x)\n",
fillptr);
for (i = (page_size / sizeof (uint)); i > 0; --i, fillptr++) {
if (*fillptr != ~pattern) {
scache_ecode.code = 6;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache data error (2): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~pattern);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
if ( i == 0 ) {
msg_printf(DBG, "Scache invalidate page address 0x%x check OK (3)\n",
page_base);
}
page_limit -= page_size;
page_base += (page_size/sizeof(uint));
}
if ( *Reportlevel < DBG ) {
busy (0);
}
return(fail);
_read_tag(CACH_SD,(ulong)k0_base,&tag1);
fillptr = k0_base;
for ( i=0; i<32; i++ ) {
invalidate_sc_line(fillptr);
fillptr += SIDL_SIZE/sizeof(uint);
}
/* Read back Scache and check */
_read_tag(CACH_SD,(ulong)k0_base,&tag2);
scache_save_tags(save_tags3);
if ( scache_cmp_tags(save_tags2, save_tags3) ) {
msg_printf(VDBG, "Below is after line invalidate\n");
scache_pr_cmp_tags(save_tags2, save_tags3);
} else {
msg_printf(VDBG, "TAGS compare before/after line invalidates\n");
}
scache_pr_cmp_tags(save_tags2,save_tags3);
msg_printf(VDBG, "Before line invalidate==0x%x,after==0x%x\n", tag1, tag2);
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != pattern) {
scache_ecode.code = 7;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache data error (2): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, pattern);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
if ( i == 0 ) {
msg_printf(VDBG, "Scache check OK (4)\n");
}
}
/*
* scachedata - secondary walking bit test
*
*/
int scachedata(void)
{
register uint *fillptr, i, pattern;
uint *k0_base = K0_BASE;
uint *k1_base = K1_BASE;
uint fail = 0, odd = 0, config_reg = 0, config_reg_save;
int r5000 = ((get_prid()&C0_IMPMASK)>>C0_IMPSHIFT) == C0_IMP_R5000;
msg_printf(DBG, "scachedata - test scache w/ walking ones/zeros\n");
config_reg_save = config_reg = Read_C0_Config();
msg_printf(VDBG, "Saved Config Register==0x%x\n", config_reg_save);
pattern = 0x1;
while (pattern != 0) {
if ( *Reportlevel < DBG ) {
busy (1);
}
msg_printf(DBG, "Test scache w/ 0x%x 0x%x for 0x%x\n",
pattern, k0_base, SID_SIZE);
msg_printf(DBG, "Invalidate Caches\n");
scache_save_tags(save_tags1);
invalidate_caches();
scache_save_tags(save_tags2);
scache_print_tags(SC_TAG_NONZERO);
/* disable scache and write ~pattern into memory, not */
/* scache. */
/* r5000_disable_scache(); */
fillptr = k1_base;
msg_printf(VDBG, "Fill memory (using uncached address 0x%x)\n",
fillptr);
scache_print_tags(SC_TAG_NONZERO);
for (i = SID_SIZE / sizeof (uint); i > 0; --i) {
*fillptr++ = ~pattern;
}
scache_print_tags(SC_TAG_NONZERO);
scache_save_tags(save_tags3);
/* Read back memory and and check */
fillptr = k1_base;
msg_printf(VDBG, "Read/Check memory (uncached address 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != ~pattern) {
scache_ecode.code = 1;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~pattern);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
scache_save_tags(save_tags4);
if ( i == 0 ) {
msg_printf(VDBG, "Memory check OK\n");
}
if ( scache_cmp_tags(save_tags1, save_tags2) ) {
msg_printf(DBG, "Below is before and after invalidate\n");
scache_pr_cmp_tags(save_tags1, save_tags2);
}
if ( scache_cmp_tags(save_tags2, save_tags3) ) {
msg_printf(DBG, "Below is after invalidate and non-cached write\n");
scache_pr_cmp_tags(save_tags2, save_tags3);
} else {
msg_printf(DBG, "TAGS compare before/after uncached write\n");
}
if ( scache_cmp_tags(save_tags3, save_tags4) ) {
msg_printf(DBG, "Below is after read non-cached\n");
scache_pr_cmp_tags(save_tags3, save_tags4);
} else {
msg_printf(DBG, "TAGS compare before/after uncached read\n");
}
/* Fill secondary and memory */
/* this should wipe out the ~pattern in memory */
/* r5000_enable_scache(); turn on scache */
fillptr = k0_base;
msg_printf(VDBG, "Fill Scache/memory (address 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i) {
*fillptr++ = pattern;
}
scache_save_tags(save_tags1);
/* Read back Scache and check */
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != pattern) {
scache_ecode.code = 2;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache data error (2): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, pattern);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
fillptr = k0_base;
__dcache_wb(fillptr,_sidcache_size);
scache_save_tags(save_tags2);
if ( i == 0 ) {
msg_printf(VDBG, "Scache check OK\n");
}
/* disable secondary cache */
/* r5000_disable_scache(); */
/* Read memory around secondary cache */
/* make sure it has what we wrote to secondary and memory */
/* it should have pattern, not ~pattern */
fillptr = k1_base;
msg_printf(VDBG, "Read mem w/o scache - check (address==0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != pattern) {
scache_ecode.code = 3;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory error (2): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, pattern);
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
scache_save_tags(save_tags3);
if ( i == 0 ) {
msg_printf(VDBG, "Memory check OK\n");
}
if ( scache_cmp_tags(save_tags2, save_tags3) ) {
msg_printf(DBG, "Below is before/after noncached read\n");
scache_pr_cmp_tags(save_tags2, save_tags3);
} else {
msg_printf(DBG, "TAGS compare before/after uncached read\n");
}
/* now change memory w/o using scache */
fillptr = k1_base;
msg_printf(VDBG, "Fill memory (uncached 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i) {
*fillptr++ = ~pattern;
}
scache_save_tags(save_tags3);
if ( scache_cmp_tags(save_tags2, save_tags3) ) {
msg_printf(DBG, "Below is before/after noncached write\n");
scache_pr_cmp_tags(save_tags2, save_tags3);
} else {
msg_printf(DBG, "TAGS compare before/after uncached write\n");
}
/* Read back and check */
fillptr = k1_base;
msg_printf(VDBG, "Read/Check memory (uncached 0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != ~pattern) {
scache_ecode.code = 4;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory error (3): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~pattern);
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
scache_save_tags(save_tags3);
if ( i == 0 ) {
msg_printf(VDBG, "Memory check OK\n");
}
if ( scache_cmp_tags(save_tags2, save_tags3) ) {
msg_printf(DBG, "Below is before/after noncached read\n");
scache_pr_cmp_tags(save_tags2, save_tags3);
} else {
msg_printf(DBG, "TAGS compare before/after uncached read\n");
}
/* restore secondary cache enable bit */
/* depending on orignal state, either enable or *
/* maintain disabled secondary cache */
/* Write_C0_Config(config_reg_save); */
msg_printf(VDBG, "Config register read (0x%x)\n",
Read_C0_Config());
if (r5000) {
/* now read the Scache and it should still be pattern */
fillptr = k0_base;
msg_printf(VDBG, "Read scache/check (address==0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != pattern) {
scache_ecode.code = 5;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache data error (3): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, pattern);
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
if ( i == 0 ) {
msg_printf(VDBG, "Scache check OK\n");
}
}
pattern = ~pattern; /* invert */
odd = !odd;
if (!odd) { /* every other time... */
pattern <<= 1; /* shift bit left */
}
}
if ( *Reportlevel < DBG ) {
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 uint *fillptr, *cfillptr, i;
uint *k0_base = K0_BASE;
uint *k1_base = K1_BASE;
uint fail = 0, inv = 0, config_reg = 0, config_reg_save = 0;
msg_printf(DBG, "scacheaddr - test scache w/ addresses\n");
config_reg = Read_C0_Config();
config_reg_save = config_reg;
msg_printf(VDBG, "Saved Config Register==0x%x\n", config_reg_save);
invalidate_caches();
/* Fill secondary through primary */
fillptr = k0_base;
msg_printf(VDBG, "Fill Scache/memory w/ addresses (address==0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i) {
*fillptr++ = (uint) fillptr;
}
/* Read back and check */
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address==0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != (uint) fillptr) {
scache_ecode.code = 1;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache addr error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, (uint) fillptr);
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
/* Read memory back w/o Scache and check */
fillptr = k0_base;
__dcache_wb(fillptr,_sidcache_size);
fillptr = k1_base;
cfillptr = k0_base; /* cached address was written */
msg_printf(VDBG, "Read/Check Memory (address==0x%x, cached==0x%x)\n",
fillptr, cfillptr);
for (i = SID_SIZE/sizeof (uint); i > 0; --i, fillptr++, cfillptr++) {
if (*fillptr != (uint) cfillptr) {
scache_ecode.code = 2;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory addr error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, (uint) cfillptr);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
/* again, with address inverted */
invalidate_caches();
/* Fill secondary through primary */
fillptr = k0_base;
msg_printf(VDBG, "Fill Scache/memory w/ ~addresses (address==0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i) {
*fillptr++ = ~(uint)fillptr;
}
/* Read back and check */
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address==0x%x)\n",
fillptr);
for (i = SID_SIZE / sizeof (uint); i > 0; --i, fillptr++) {
if (*fillptr != ~(uint)fillptr) {
scache_ecode.code = 3;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache address error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~(uint)fillptr);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
/* Read back memory w/o scache and check */
fillptr = k0_base;
__dcache_wb(fillptr,_sidcache_size);
fillptr = k1_base;
cfillptr = k0_base; /* cached addres was used as data */
msg_printf(VDBG, "Read/Check Memory (address==0x%x)\n",
fillptr);
for (i = SID_SIZE/sizeof (uint); i > 0; --i, fillptr++, cfillptr++) {
if (*fillptr != ~(uint)cfillptr) {
scache_ecode.code = 4;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory address error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, ~(uint)cfillptr);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
return (fail);
}
#define PATTERN1 0xaa
scacherandomline()
{
register unsigned char *fillptr, *fillptr1, pattern, pattern1;
register uint i, j;
char *k0_base = (char *)K0_BASE;
char *k1_base = (char *)K1_BASE;
uint fail = 0, inv = 0, config_reg = 0, config_reg_save = 0;
uint tag1, tag2;
int r5000 = ((get_prid()&C0_IMPMASK)>>C0_IMPSHIFT) == C0_IMP_R5000;
msg_printf(DBG, "scacheaddr - test scache w/ addresses\n");
config_reg = Read_C0_Config();
config_reg_save = config_reg;
msg_printf(VDBG, "Saved Config Register==0x%x\n", config_reg_save);
invalidate_caches();
/* Fill secondary through primary */
fillptr = k0_base;
msg_printf(VDBG, "Fill Scache/memory w/ addresses (address==0x%x)\n",
fillptr);
pattern = PATTERN1;
for (i = SID_SIZE; i > 0; --i) {
*fillptr++ = pattern;
}
fillptr = k0_base;
__dcache_wb(fillptr,_sidcache_size);
/* Read back and check */
fillptr = k0_base;
msg_printf(VDBG, "Read/Check Scache (address==0x%x)\n",
fillptr);
for (i = SID_SIZE; i > 0; --i, fillptr++) {
if (*fillptr != pattern) {
scache_ecode.code = 1;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache addr error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, pattern);
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
/* Read memory back w/o Scache and check */
msg_printf(VDBG, "Flush All caches/Invalidate primary data cache\n");
__dcache_wb(fillptr,_dcache_size);
invalidate_dcache(_dcache_size, _dcache_linesize);
fillptr = k1_base;
msg_printf(VDBG, "Read/Check Memory (address==0x%x)\n",
fillptr);
for (i = SID_SIZE; i > 0; --i, fillptr++) {
if (*fillptr != pattern) {
scache_ecode.code = 2;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory addr error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, pattern);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
return(fail);
break;
}
}
}
}
/* now change memory w/o using scache */
fillptr = k1_base;
msg_printf(VDBG, "Fill memory (uncached 0x%x)\n",
fillptr);
pattern = 0;
for (i = SID_SIZE; i > 0; --i, pattern++) {
*fillptr++ = (pattern % SIDL_SIZE);
}
msg_printf(VDBG, "memory filled OK (uncached 0x%x)\n",
fillptr);
/* Read back and check */
fillptr = k1_base;
msg_printf(VDBG, "Read/Check memory (uncached 0x%x)\n",
fillptr);
pattern = 0;
for (i = SID_SIZE; i > 0; --i, fillptr++, pattern++) {
if (*fillptr != (pattern % SIDL_SIZE)) {
scache_ecode.code = 3;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Memory error (3): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr, *fillptr, (pattern % SIDL_SIZE));
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
if ( i == 0 ) {
msg_printf(VDBG, "Memory check OK\n");
}
/* now go through a line at a time, check that scache is unchanged,
* invalidate the line, read from random location and validate data
* came from memory, then check all SIDL_SIZE bytes to ensure
* correct ordering
*/
fillptr = k0_base;
for (i = (SID_SIZE/SIDL_SIZE); i > 0; --i, fillptr+= SIDL_SIZE) {
if (!r5000)
if (i == (SID_SIZE/SIDL_SIZE))
i = i/2; /* half size for two set scache */
/* for each line, check that scache is unchanged */
if ( *Reportlevel < DBG ) {
busy (1);
}
pattern = PATTERN1;
msg_printf(DBG, "Check that Scache is unchanged (0x%x)\n", fillptr);
for ( j=0, fillptr1=fillptr; j < SIDL_SIZE; j++, fillptr1++ ) {
if (*fillptr1 != pattern) {
scache_ecode.code = 4;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache error (A): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr1, *fillptr1, pattern);
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
}
/* invalidate the line just checked */
msg_printf(DBG, "Invalidate line %d (0x%x) and primary dcache\n",
(((SID_SIZE/SIDL_SIZE)+1)-i), fillptr);
_read_tag(CACH_SD,(ulong)fillptr,&tag1);
invalidate_sc_line((uint *)fillptr);
invalidate_dcache(_dcache_size, _dcache_linesize);
_read_tag(CACH_SD,(ulong)fillptr,&tag2);
msg_printf(DBG, "TAG1==0x%x,TAG2==0x%x\n", tag1, tag2);
/* read from random location in the scache line */
pattern = (i & 0x1f);
fillptr1 = fillptr+pattern;
if ( (pattern1 = *fillptr1) != pattern ) {
scache_ecode.code = 5;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache random error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr1, pattern1, pattern);
fail++;
if ( *Reportlevel > DBG) {
if ( fail > 32 ) {
msg_printf(DBG, "Loop Break\n");
fail = 1;
break;
}
}
}
msg_printf(DBG, "Random at 0x%x, got 0x%x\n", fillptr1, pattern1);
/* now validate all of line is fetched from memory correctly */
/* each byte should contain its' offset into the line */
msg_printf(DBG, "Now check all bytes of line\n");
for ( j=0, fillptr1=fillptr; j < SIDL_SIZE; j++, fillptr1++ ) {
if (*fillptr1 != j) {
scache_ecode.code = 6;
scache_ecode.w1 =(uint) fillptr;
scache_ecode.w2 = *fillptr;
report_error(&scache_ecode);
msg_printf (ERR, "Scache byte error (1): Address 0x%x, Actual 0x%x, Expected 0x%x\n",
fillptr1, *fillptr1, j);
fail++;
}
}
if ( j == SIDL_SIZE ) {
msg_printf(DBG, "All byte OK in scache\n");
}
if ( fail ) {
fail = 1;
}
}
if ( *Reportlevel < DBG ) {
busy (0);
}
return(fail);
}
/*
* fill fillsize uint's with filldata starting at filladdr.
*/
void sc_fill_mem_uint(uint *filladdr, uint filldata, uint fillsize)
{
int i;
for ( i=0; i<fillsize; i++ ) {
*filladdr++ = filldata;
}
}
/*
* Check chksize uint's for equality with chkdata, starting at chkaddr
*/
int sc_chk_mem_uint(uint *chkaddr, uint chkdata, uint chksize, char *chkmsg)
{
int i, fail = 0;
for ( i=0; i<chksize; i++, chkaddr++ ) {
if (*chkaddr != chkdata) {
scache_ecode.code = 1;
scache_ecode.w1 =(uint) chkaddr;
scache_ecode.w2 = *chkaddr;
report_error(&scache_ecode);
msg_printf (ERR, chkmsg, chkaddr, *chkaddr, chkdata);
fail++;
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG,
"sc_chk_mem_uint Loop Break\n");
fail = 1;
break;
}
}
}
}
return(fail);
}
/*
* fill, from filladdr, fillsize uint's with addresses starting at fillstart.
*/
void sc_fill_mem_addr(uint *filladdr, uint *fillstart, uint fillsize)
{
int i;
for ( i=0; i<fillsize; i++, fillstart++ ) {
*filladdr++ = (uint)K0_TO_PHYS(fillstart);
}
}
/*
* Check, from chkaddr, chksize uint's for address match begining at chkstart
*/
int sc_chk_mem_addr(uint *chkaddr, uint *chkstart, uint chksize, char *chkmsg)
{
int i, fail = 0;
uint *cchkaddr; /* cached address */
uint *ucchkaddr; /* uncached address */
for ( i=0; i<chksize; i++, chkaddr++, chkstart++ ) {
if (*chkaddr != (uint)K0_TO_PHYS(chkstart)) {
scache_ecode.w1 =(uint) chkaddr;
scache_ecode.w2 = *chkaddr;
report_error(&scache_ecode);
msg_printf (ERR, chkmsg, chkaddr, *chkaddr,
K0_TO_PHYS(chkstart));
fail++;
cchkaddr = (uint *)PHYS_TO_K0(K0_TO_PHYS(chkaddr));
ucchkaddr = (uint *)PHYS_TO_K1(K0_TO_PHYS(chkaddr));
msg_printf(DBG, "Cached address contents (0x%x)==0x%x\n",
cchkaddr, *cchkaddr);
msg_printf(DBG, "Uncached address contents (0x%x)==0x%x\n",
ucchkaddr, *ucchkaddr);
if ( *Reportlevel > DBG ) {
if ( fail > 32 ) {
msg_printf(DBG,
"sc_chk_mem_addr Loop Break\n");
fail = 1;
break;
}
}
}
}
return(fail);
}
void sc_flush_dcache(uint *flushaddr)
{
int i, hit, first_time = 1;
uint *cflushaddr, *ucflushaddr;
uint *save_flushaddr;
uint tag1, tag2;
/* flush primary data cache */
save_flushaddr = flushaddr;
msg_printf(DBG, "sc_flush_dcache 0x%x, 0x%x\n", flushaddr,
(PD_SIZE / sizeof (uint)));
for (i = PD_SIZE / PDL_SIZE; i > 0; --i) {
cflushaddr = (uint *)PHYS_TO_K0(K0_TO_PHYS(flushaddr));
ucflushaddr = (uint *)PHYS_TO_K1(K0_TO_PHYS(flushaddr));
_read_tag(CACH_PD,(ulong)flushaddr,&tag1);
msg_printf(VDBG,"Before flush: 0x%x==0x%x,0x%x==0x%x (0x%x)\n",
cflushaddr, *cflushaddr, ucflushaddr, *ucflushaddr, tag1);
hit = pd_HWBINV (flushaddr);
_read_tag(CACH_PD,(ulong)flushaddr,&tag2);
msg_printf(VDBG,"After flush: cached data=0x%x,uncached data==0x%x (0x%x)\n",
*cflushaddr, *ucflushaddr, tag2);
if ( hit && first_time ) {
msg_printf(DBG, "sc_flush_dcache hit at 0x%x (0x%x)\n",
flushaddr, hit);
first_time = 0;
}
flushaddr += (PDL_SIZE/sizeof(uint));
}
msg_printf(DBG,"sc_flush_dcache ended at 0x%x\n", flushaddr);
invalidate_dcache(_dcache_size, _dcache_linesize);
flushaddr = save_flushaddr;
for (i = PD_SIZE / PDL_SIZE; i > 0; --i) {
cflushaddr = (uint *)PHYS_TO_K0(K0_TO_PHYS(flushaddr));
ucflushaddr = (uint *)PHYS_TO_K1(K0_TO_PHYS(flushaddr));
_read_tag(CACH_PD,(ulong)flushaddr,&tag1);
msg_printf(VDBG,"After Invalidate: 0x%x==0x%x,0x%x==0x%x (0x%x)\n",
cflushaddr, *cflushaddr, ucflushaddr, *ucflushaddr, tag1);
if ( *cflushaddr != *ucflushaddr ) {
save_flushaddr = (uint *)PHYS_TO_K0(*cflushaddr);
_read_tag(CACH_PD,(ulong)save_flushaddr,&tag1);
msg_printf(VDBG,"Before flush: 0x%x==0x%x,0x%x==0x%x (0x%x)\n",
cflushaddr, *cflushaddr, ucflushaddr, *ucflushaddr, tag1);
hit = pd_HWBINV (save_flushaddr);
_read_tag(CACH_PD,(ulong)save_flushaddr,&tag2);
msg_printf(VDBG,"After flush: cached data=0x%x,uncached data==0x%x (0x%x)\n",
*cflushaddr, *ucflushaddr, tag2);
}
flushaddr += (PDL_SIZE/sizeof(uint));
}
msg_printf(DBG,"sc_flush_dcache ended again at 0x%x\n", flushaddr);
}