OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [testbench/] [cache.c] - Diff between revs 322 and 349

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 322 Rev 349
/* Cache test */
/* Cache test */
#include "support.h"
#include "support.h"
#include "spr_defs.h"
#include "spr_defs.h"
 
 
/* Number of IC sets (power of 2) */
/* Number of IC sets (power of 2) */
#define IC_SETS 512
#define IC_SETS 512
#define DC_SETS 512
#define DC_SETS 512
 
 
/* Block size in bytes (1, 2, 4, 8, 16, 32 etc.) */
/* Block size in bytes (1, 2, 4, 8, 16, 32 etc.) */
#define IC_BLOCK_SIZE 16
#define IC_BLOCK_SIZE 16
#define DC_BLOCK_SIZE 16
#define DC_BLOCK_SIZE 16
 
 
/* Number of IC ways (1, 2, 3 etc.). */
/* Number of IC ways (1, 2, 3 etc.). */
#define IC_WAYS 1
#define IC_WAYS 1
#define DC_WAYS 1
#define DC_WAYS 1
 
 
/* Cache size */
/* Cache size */
#define IC_SIZE (IC_WAYS*IC_SETS*IC_BLOCK_SIZE)
#define IC_SIZE (IC_WAYS*IC_SETS*IC_BLOCK_SIZE)
#define DC_SIZE (DC_WAYS*DC_SETS*DC_BLOCK_SIZE)
#define DC_SIZE (DC_WAYS*DC_SETS*DC_BLOCK_SIZE)
 
 
/* Memory access macros */
/* Memory access macros */
#define REG8(add) *((volatile unsigned char *)(add))
#define REG8(add) *((volatile unsigned char *)(add))
#define REG16(add) *((volatile unsigned short *)(add))
#define REG16(add) *((volatile unsigned short *)(add))
#define REG32(add) *((volatile unsigned long *)(add))
#define REG32(add) *((volatile unsigned long *)(add))
 
 
extern void (*jalr)(void);
extern void (*jalr)(void);
extern void (*jr)(void);
extern void (*jr)(void);
 
 
void dummy();
void dummy();
 
 
void jump_and_link(void)
void jump_and_link(void)
{
{
        asm("_jalr:");
        asm("_jalr:");
}
}
 
 
void jump(void)
void jump(void)
{
{
        asm("_jr:");
        asm("_jr:");
        /* Read and increment index */
        /* Read and increment index */
        asm("l.lwz\t\tr3,0(r0)");
        asm("l.lwz\t\tr3,0(r0)");
        asm("l.addi\t\tr3,r3,4");
        asm("l.addi\t\tr3,r3,4");
        asm("l.sw\t\t0(r0),r3");
        asm("l.sw\t\t0(r0),r3");
        /* Load next executin address from table */
        /* Load next executin address from table */
        asm("l.lwz\t\tr3,0(r3)");
        asm("l.lwz\t\tr3,0(r3)");
        /* Jump to that address */
        /* Jump to that address */
        asm("l.jr\t\tr3") ;
        asm("l.jr\t\tr3") ;
        /* Report that we succeeded */
        /* Report that we succeeded */
        asm("l.mtspr\t\tr0,r3,0x1234");
        asm("l.mtspr\t\tr0,r3,0x1234");
}
}
 
 
void copy_jr(unsigned long add)
void copy_jr(unsigned long add)
{
{
        memcpy((void *)add, (void *)&jr, 24);
        memcpy((void *)add, (void *)&jr, 24);
}
}
 
 
void call(unsigned long add)
void call(unsigned long add)
{
{
        asm("l.jr\t\t%0" : : "r" (add) : "r11");
        asm("l.jr\t\t%0" : : "r" (add) : "r11");
        asm("l.nop" : :);
        asm("l.nop" : :);
}
}
 
 
void icache_enable(void)
void icache_enable(void)
{
{
        unsigned long add;
        unsigned long add;
 
 
        /* First invalidate the cache. As at this point cache is disabled,
        /* First invalidate the cache. As at this point cache is disabled,
           the cache acts as it contains image of lowest memory block */
           the cache acts as it contains image of lowest memory block */
        for(add = 1; add <= IC_SIZE; add += IC_BLOCK_SIZE)
        for(add = 1; add <= IC_SIZE; add += IC_BLOCK_SIZE)
                mtspr(SPR_ICBIR, add);
                mtspr(SPR_ICBIR, add);
 
 
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
}
}
 
 
void dcache_enable(void)
void dcache_enable(void)
{
{
        unsigned long add;
        unsigned long add;
 
 
        /* First invalidate the cache. As at this point cache is disabled,
        /* First invalidate the cache. As at this point cache is disabled,
           the cache acts as it contains image of lowest memory block */
           the cache acts as it contains image of lowest memory block */
        for(add = 1; add <= DC_SIZE; add += DC_BLOCK_SIZE)
        for(add = 1; add <= DC_SIZE; add += DC_BLOCK_SIZE)
                mtspr(SPR_DCBIR, add);
                mtspr(SPR_DCBIR, add);
 
 
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
}
}
 
 
void icache_disable(void)
void icache_disable(void)
{
{
 
 
        /* This is write trough cache so we dont have to flush it */
        /* This is write trough cache so we dont have to flush it */
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
}
}
 
 
void dcache_disable(void)
void dcache_disable(void)
{
{
 
 
        /* This is write trough cache so we dont have to flush it */
        /* This is write trough cache so we dont have to flush it */
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
}
}
 
 
int dc_test(void)
int dc_test(void)
{
{
        int i;
        int i;
        unsigned long base, add, ul;
        unsigned long base, add, ul;
 
 
        base = (((unsigned long)&dummy / (IC_SETS*IC_BLOCK_SIZE)) * IC_SETS*IC_BLOCK_SIZE) + IC_SETS*IC_BLOCK_SIZE;
        base = (((unsigned long)&dummy / (IC_SETS*IC_BLOCK_SIZE)) * IC_SETS*IC_BLOCK_SIZE) + IC_SETS*IC_BLOCK_SIZE;
 
 
        dcache_enable();
        dcache_enable();
 
 
        /* Cache miss r */
        /* Cache miss r */
        add = base;
        add = base;
        for(i = 0; i < DC_WAYS; i++) {
        for(i = 0; i < DC_WAYS; i++) {
                ul = REG32(add);
                ul = REG32(add);
                ul = REG32(add + DC_BLOCK_SIZE);
                ul = REG32(add + DC_BLOCK_SIZE);
                ul = REG32(add + 2*DC_BLOCK_SIZE);
                ul = REG32(add + 2*DC_BLOCK_SIZE);
                ul = REG32(add + 3*DC_BLOCK_SIZE);
                ul = REG32(add + 3*DC_BLOCK_SIZE);
                add += DC_SETS*DC_BLOCK_SIZE;
                add += DC_SETS*DC_BLOCK_SIZE;
        }
        }
 
 
        /* Cache hit w */
        /* Cache hit w */
        add = base;
        add = base;
        for(i = 0; i < DC_WAYS; i++) {
        for(i = 0; i < DC_WAYS; i++) {
                REG32(add + 0) = 0x00000001;
                REG32(add + 0) = 0x00000001;
                REG32(add + DC_BLOCK_SIZE + 4) = 0x00000002;
                REG32(add + DC_BLOCK_SIZE + 4) = 0x00000002;
                REG32(add + 2*DC_BLOCK_SIZE + 8) = 0x00000003;
                REG32(add + 2*DC_BLOCK_SIZE + 8) = 0x00000003;
                REG32(add + 3*DC_BLOCK_SIZE + 12) = 0x00000004;
                REG32(add + 3*DC_BLOCK_SIZE + 12) = 0x00000004;
                add += DC_SETS*DC_BLOCK_SIZE;
                add += DC_SETS*DC_BLOCK_SIZE;
        }
        }
 
 
        /* Cache hit r/w */
        /* Cache hit r/w */
        add = base;
        add = base;
        for(i = 0; i < DC_WAYS; i++) {
        for(i = 0; i < DC_WAYS; i++) {
                REG8(add + DC_BLOCK_SIZE - 4) = REG8(add + 3);
                REG8(add + DC_BLOCK_SIZE - 4) = REG8(add + 3);
                REG8(add + 2*DC_BLOCK_SIZE - 8) = REG8(add + DC_BLOCK_SIZE + 7);
                REG8(add + 2*DC_BLOCK_SIZE - 8) = REG8(add + DC_BLOCK_SIZE + 7);
                REG8(add + 3*DC_BLOCK_SIZE - 12) = REG8(add + 2*DC_BLOCK_SIZE + 11);
                REG8(add + 3*DC_BLOCK_SIZE - 12) = REG8(add + 2*DC_BLOCK_SIZE + 11);
                REG8(add + 4*DC_BLOCK_SIZE - 16) = REG8(add + 3*DC_BLOCK_SIZE + 15);
                REG8(add + 4*DC_BLOCK_SIZE - 16) = REG8(add + 3*DC_BLOCK_SIZE + 15);
                add += DC_SETS*DC_BLOCK_SIZE;
                add += DC_SETS*DC_BLOCK_SIZE;
        }
        }
 
 
        /* Cache hit/miss r/w */
        /* Cache hit/miss r/w */
        add = base;
        add = base;
        for(i = 0; i < DC_WAYS; i++) {
        for(i = 0; i < DC_WAYS; i++) {
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE) = REG16(add + DC_BLOCK_SIZE - 4) + REG16(add + 2);
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE) = REG16(add + DC_BLOCK_SIZE - 4) + REG16(add + 2);
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 2) = REG16(add + DC_BLOCK_SIZE - 8) + REG16(add + DC_BLOCK_SIZE + 6);
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 2) = REG16(add + DC_BLOCK_SIZE - 8) + REG16(add + DC_BLOCK_SIZE + 6);
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 4) = REG16(add + DC_BLOCK_SIZE - 12) + REG16(add + 2*DC_BLOCK_SIZE + 10);
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 4) = REG16(add + DC_BLOCK_SIZE - 12) + REG16(add + 2*DC_BLOCK_SIZE + 10);
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 6) = REG16(add+ DC_BLOCK_SIZE - 16) + REG16(add + 2*DC_BLOCK_SIZE + 14);
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 6) = REG16(add+ DC_BLOCK_SIZE - 16) + REG16(add + 2*DC_BLOCK_SIZE + 14);
                add += DC_SETS*DC_BLOCK_SIZE;
                add += DC_SETS*DC_BLOCK_SIZE;
        }
        }
 
 
        /* Fill cache with unused data */
        /* Fill cache with unused data */
        add = base + DC_WAYS*DC_SETS*DC_BLOCK_SIZE;
        add = base + DC_WAYS*DC_SETS*DC_BLOCK_SIZE;
        for(i = 0; i < DC_WAYS; i++) {
        for(i = 0; i < DC_WAYS; i++) {
                ul = REG32(add);
                ul = REG32(add);
                ul = REG32(add + DC_BLOCK_SIZE);
                ul = REG32(add + DC_BLOCK_SIZE);
                ul = REG32(add + 2*DC_BLOCK_SIZE);
                ul = REG32(add + 2*DC_BLOCK_SIZE);
                ul = REG32(add + 3*DC_BLOCK_SIZE);
                ul = REG32(add + 3*DC_BLOCK_SIZE);
                add += DC_SETS*DC_BLOCK_SIZE;
                add += DC_SETS*DC_BLOCK_SIZE;
        }
        }
 
 
        /* Cache hit/miss r */
        /* Cache hit/miss r */
        ul = 0;
        ul = 0;
        add = base;
        add = base;
        for(i = 0; i < DC_WAYS; i++) {
        for(i = 0; i < DC_WAYS; i++) {
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE) +
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE) +
                        REG16(add + DC_BLOCK_SIZE - 4) +
                        REG16(add + DC_BLOCK_SIZE - 4) +
                        REG16(add + 2);
                        REG16(add + 2);
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 2) +
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 2) +
                        REG16(add + DC_BLOCK_SIZE - 8) +
                        REG16(add + DC_BLOCK_SIZE - 8) +
                        REG16(add + DC_BLOCK_SIZE + 6);
                        REG16(add + DC_BLOCK_SIZE + 6);
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 4) +
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 4) +
                        REG16(add + DC_BLOCK_SIZE - 12) +
                        REG16(add + DC_BLOCK_SIZE - 12) +
                        REG16(add + 2*DC_BLOCK_SIZE + 10);
                        REG16(add + 2*DC_BLOCK_SIZE + 10);
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 6) +
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 6) +
                        REG16(add+ DC_BLOCK_SIZE - 16) +
                        REG16(add+ DC_BLOCK_SIZE - 16) +
                        REG16(add + 2*DC_BLOCK_SIZE + 14);
                        REG16(add + 2*DC_BLOCK_SIZE + 14);
                add += DC_SETS*DC_BLOCK_SIZE;
                add += DC_SETS*DC_BLOCK_SIZE;
        }
        }
 
 
        dcache_disable();
        dcache_disable();
 
 
        return ul;
        return ul;
}
}
 
 
int ic_test(void)
int ic_test(void)
{
{
        int i;
        int i;
        unsigned long base, add;
        unsigned long base, add;
 
 
        base = (((unsigned long)&dummy / (IC_SETS*IC_BLOCK_SIZE)) * IC_SETS*IC_BLOCK_SIZE) + IC_SETS*IC_BLOCK_SIZE;
        base = (((unsigned long)&dummy / (IC_SETS*IC_BLOCK_SIZE)) * IC_SETS*IC_BLOCK_SIZE) + IC_SETS*IC_BLOCK_SIZE;
 
 
        icache_enable();
 
 
 
        /* Copy jr to various location */
        /* Copy jr to various location */
        add = base;
        add = base;
        for(i = 0; i < IC_WAYS; i++) {
        for(i = 0; i < IC_WAYS; i++) {
                copy_jr(add);
                copy_jr(add);
                copy_jr(add + 2*IC_BLOCK_SIZE + 4);
                copy_jr(add + 2*IC_BLOCK_SIZE + 4);
                copy_jr(add + 4*IC_BLOCK_SIZE + 8);
                copy_jr(add + 4*IC_BLOCK_SIZE + 8);
                copy_jr(add + 6*IC_BLOCK_SIZE + 12);
                copy_jr(add + 6*IC_BLOCK_SIZE + 12);
 
 
                copy_jr(add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0);
                copy_jr(add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0);
                copy_jr(add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4);
                copy_jr(add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4);
                copy_jr(add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8);
                copy_jr(add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8);
                copy_jr(add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12);
                copy_jr(add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12);
                add += IC_SETS*IC_BLOCK_SIZE;
                add += IC_SETS*IC_BLOCK_SIZE;
        }
        }
 
 
        /* Load execution table which starts at address 4 (at address 0 is table index) */
        /* Load execution table which starts at address 4 (at address 0 is table index) */
        add = base;
        add = base;
        for(i = 0; i < IC_WAYS; i++) {
        for(i = 0; i < IC_WAYS; i++) {
                /* Cache miss */
                /* Cache miss */
                REG32(0x3c*i + 0x04) = add + 2*IC_BLOCK_SIZE + 4;
                REG32(0x3c*i + 0x04) = add + 2*IC_BLOCK_SIZE + 4;
                REG32(0x3c*i + 0x08) = add + 4*IC_BLOCK_SIZE + 8;
                REG32(0x3c*i + 0x08) = add + 4*IC_BLOCK_SIZE + 8;
                REG32(0x3c*i + 0x0c) = add + 6*IC_BLOCK_SIZE + 12;
                REG32(0x3c*i + 0x0c) = add + 6*IC_BLOCK_SIZE + 12;
                /* Cache hit/miss */
                /* Cache hit/miss */
                REG32(0x3c*i + 0x10) = add;
                REG32(0x3c*i + 0x10) = add;
                REG32(0x3c*i + 0x14) = add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0;
                REG32(0x3c*i + 0x14) = add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0;
                REG32(0x3c*i + 0x18) = add + 2*IC_BLOCK_SIZE + 4;
                REG32(0x3c*i + 0x18) = add + 2*IC_BLOCK_SIZE + 4;
                REG32(0x3c*i + 0x1c) = add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4;
                REG32(0x3c*i + 0x1c) = add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4;
                REG32(0x3c*i + 0x20) = add + 4*IC_BLOCK_SIZE + 8;
                REG32(0x3c*i + 0x20) = add + 4*IC_BLOCK_SIZE + 8;
                REG32(0x3c*i + 0x24) = add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8;
                REG32(0x3c*i + 0x24) = add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8;
                REG32(0x3c*i + 0x28) = add + 6*IC_BLOCK_SIZE + 12;
                REG32(0x3c*i + 0x28) = add + 6*IC_BLOCK_SIZE + 12;
                REG32(0x3c*i + 0x2c) = add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12;
                REG32(0x3c*i + 0x2c) = add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12;
                /* Cache hit */
                /* Cache hit */
                REG32(0x3c*i + 0x30) = add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0;
                REG32(0x3c*i + 0x30) = add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0;
                REG32(0x3c*i + 0x34) = add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4;
                REG32(0x3c*i + 0x34) = add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4;
                REG32(0x3c*i + 0x38) = add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8;
                REG32(0x3c*i + 0x38) = add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8;
                REG32(0x3c*i + 0x3c) = add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12;
                REG32(0x3c*i + 0x3c) = add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12;
 
 
                add += IC_SETS*IC_BLOCK_SIZE;
                add += IC_SETS*IC_BLOCK_SIZE;
        }
        }
 
 
        /* Go home */
        /* Go home */
        REG32(0x3c*i + 4) = (unsigned long)&jalr;
        REG32(0x3c*i + 4) = (unsigned long)&jalr;
 
 
        /* Initilalize table index */
        /* Initilalize table index */
        REG32(0) = 0;
        REG32(0) = 0;
 
 
 
        icache_enable();
 
 
        /* Go */
        /* Go */
        call(base);
        call(base);
 
 
        icache_disable();
        icache_disable();
 
 
        return 0xdeaddead;
        return 0xdeaddead;
}
}
 
 
int main(void)
int main(void)
{
{
        int rc;
        int rc;
 
 
        rc = dc_test();
        rc = dc_test();
        report(rc + 0xdeaddca1);
        report(rc + 0xdeaddca1);
 
 
        /* Be aware that this test doesn't report result troug report call.
        /* Be aware that this test doesn't report result troug report call.
           It writes to spr 0x1234 directly (in jump function)!!!
           It writes to spr 0x1234 directly (in jump function)!!!
 
 
           This test can not be run on or1ksim. */
           This test can not be run on or1ksim. */
        rc = ic_test();
        rc = ic_test();
        report(rc);
        report(rc);
 
 
        exit(0);
        exit(0);
}
}
 
 
/* just for size calculation */
/* just for size calculation */
void dummy()
void dummy()
{
{
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.