diff --git a/tests/cacheoptest/llc/src/huancunop.c b/tests/cacheoptest/llc/src/huancunop.c index 1a2c9f22897a332b063adc2543c20bdd4c2819ff..1216f9b4260075e9cb32d67a54759b559eb3c44c 100644 --- a/tests/cacheoptest/llc/src/huancunop.c +++ b/tests/cacheoptest/llc/src/huancunop.c @@ -97,6 +97,7 @@ void test3() { } } +// Flush a cacheline (512 bit) to memory void flush_to_memory(uint64_t paddr) { // printf("l3 size is set to %d KB, nr_way is set to %d, nr_bank is set to %d, ", L3_SIZE_KB, L3_NR_WAY, L3_NR_BANK); unsigned int set_size = L3_SIZE_KB * 1024 / L3_NR_BANK / L3_NR_WAY / 64; @@ -117,6 +118,31 @@ void flush_to_memory(uint64_t paddr) { wait(100); } +// Flush an n*512 bit address region to memory +void flush_region_to_memory(uint64_t start_paddr, uint64_t size_in_bit) { + // pre-calcuated const + unsigned int set_size = L3_SIZE_KB * 1024 / L3_NR_BANK / L3_NR_WAY / 64; + unsigned int set_len = log2(set_size); + // printf("l3 size is set to %d KB, nr_way is set to %d, nr_bank is set to %d, ", L3_SIZE_KB, L3_NR_WAY, L3_NR_BANK); + // printf("nr_set is %u, set_len is %u\n", set_size, set_len); + + // flush sq and sbuffer + asm("fence\n"); + + // send l3 cache flush op to l3 cache controller + for(uint64_t current_paddr = start_paddr; current_paddr < (start_paddr + size_in_bit); current_paddr += 512){ + uint64_t tag = (current_paddr >> OFFSET_LEN) >> set_len; // paddr to l3 tag + uint64_t set = (current_paddr >> OFFSET_LEN) & (set_size-1); // paddr to l3 set + *(uint64_t*)(CACHE_CTRL_BASE + CTRL_TAG_OFFSET) = tag; + *(uint64_t*)(CACHE_CTRL_BASE + CTRL_SET_OFFSET) = set; + // printf("flush to memory: addr 0x%llx tag 0x%llx set 0x%llx\n", &test_buffer, tag, set); + (*(uint64_t*)CACHE_CMD_BASE) = CMD_CMO_CLEAN; // or CMD_CMO_FLUSH + } + + // wait for the last cache op to finish + wait(100); +} + int main() { printf("HuanCun op (mmio based) test. Note that --no-diff is required!\n"); printf("HuanCun l3 size is set to %d KB, nr_way is set to %d, nr_bank is set to %d, ", L3_SIZE_KB, L3_NR_WAY, L3_NR_BANK);