URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 412 to Rev 413
- ↔ Reverse comparison
Rev 412 → Rev 413
/trunk/or1ksim/testbench/mmu.c
6,11 → 6,14
/* Define RAM physical location and size |
Bottom half will be used for this program, the rest |
will be used for testing */ |
#define RAM_START 0x40000000 |
#define RAM_SIZE 0x00200000 |
#define FLASH_START 0x00000000 |
#define FLASH_SIZE 0x00200000 |
#define RAM_START 0x40000000 |
#define RAM_SIZE 0x00200000 |
|
/* What is the last address in ram that is used by this program */ |
#define CODE_END_ADD (RAM_START + (RAM_SIZE / 2)) |
#define TEXT_END_ADD (FLASH_START + (FLASH_SIZE / 2)) |
#define DATA_END_ADD (RAM_START + (RAM_SIZE / 2)) |
|
/* MMU page size */ |
#define PAGE_SIZE 4096 |
43,6 → 46,8
/* fails if x is false */ |
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__)) |
|
#define TEST_JUMP(x) |
|
/* Extern functions */ |
extern void lo_dmmu_en (void); |
extern void lo_immu_en (void); |
106,7 → 111,7
|
printf("ea = %.8lx set = %d way = %d\n", ea, set, way); |
|
if ((RAM_START <= ea) && (ea < CODE_END_ADD)) { |
if ((RAM_START <= ea) && (ea < DATA_END_ADD)) { |
/* If this is acces to data of this program set one to one translation */ |
mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V); |
mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | TLB_PR_NOLIMIT); |
118,7 → 123,7
dtlb_miss_ea = ea; |
|
/* Whatever access is in progress, translated address have to point to physical RAM */ |
ta = (ea & ((RAM_SIZE/2) - 1)) + RAM_START + (RAM_SIZE/2); |
ta = (ea & ((RAM_SIZE/2) - 1)) + DATA_END_ADD; |
printf("ta = %.8lx\n", ta); |
|
/* Set appropriate TLB entry */ |
154,8 → 159,66
/* ITLB miss exception handler */ |
void itlb_miss_handler (void) |
{ |
unsigned long ea, ta, tlbtr; |
int set, way = 0; |
int i; |
|
/* Get EA that cause the exception */ |
ea = mfspr (SPR_EEAR_BASE); |
|
/* Find TLB set and LRU way */ |
set = (ea / PAGE_SIZE) % ITLB_SETS; |
for (i = 0; i < ITLB_WAYS; i++) { |
if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_LRU) == 0) { |
way = i; |
break; |
} |
} |
|
printf("ea = %.8lx set = %d way = %d\n", ea, set, way); |
|
if ((FLASH_START <= ea) && (ea < TEXT_END_ADD)) { |
/* If this is acces to data of this program set one to one translation */ |
mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V); |
mtspr (SPR_ITLBTR_BASE(way) + set, (ea & SPR_ITLBTR_PPN) | TLB_PR_NOLIMIT); |
return; |
} |
|
/* Update ITLB miss counter and EA */ |
itlb_miss_count++; |
itlb_miss_ea = ea; |
|
/* Whatever access is in progress, translated address have to point to physical RAM */ |
ta = (ea & ((FLASH_SIZE/2) - 1)) + TEXT_END_ADD; |
printf("ta = %.8lx\n", ta); |
|
/* Set appropriate TLB entry */ |
switch (itlb_val & TLB_CODE_MASK) { |
case TLB_CODE_ONE_TO_ONE: |
tlbtr = (ta & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK); |
printf("1: tlbtr = %.8lx\n", tlbtr); |
break; |
case TLB_CODE_PLUS_ONE_PAGE: |
if ((ta + PAGE_SIZE) >= (FLASH_START + FLASH_SIZE)) |
/* Wrapp last page */ |
tlbtr = (((ta & ((FLASH_SIZE/2) - 1)) + TEXT_END_ADD) & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK); |
else |
tlbtr = ((ta + PAGE_SIZE) & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK); |
printf("2: tlbtr = %.8lx\n", tlbtr); |
break; |
case TLB_CODE_MINUS_ONE_PAGE: |
if ((ta - PAGE_SIZE) < TEXT_END_ADD) |
/* Wrapp first page */ |
tlbtr = ((ta - PAGE_SIZE + (FLASH_SIZE/2)) & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK); |
else |
tlbtr = ((ta - PAGE_SIZE) & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK); |
printf("3: tlbtr = %.8lx\n", tlbtr); |
break; |
} |
|
/* Set ITLB entry */ |
mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V); |
mtspr (SPR_ITLBTR_BASE(way) + set, tlbtr); |
} |
|
/* Invalidate all entries in DTLB and enable DMMU */ |
268,15 → 331,64
return 0; |
} |
|
|
|
/* Valid bit test |
Set all ways of one set to be invalid, perform |
access so miss handler will set them to valid, |
try access again - there should be no miss exceptions */ |
int itlb_valid_bit_test (int set) |
{ |
int i; |
|
|
|
/* Reset ITLB miss counter and EA */ |
itlb_miss_count = 0; |
itlb_miss_ea = 0; |
|
/* Set itlb permisions */ |
itlb_val = TLB_PR_NOLIMIT; |
|
|
/* Resetv ITLBMR for every way */ |
for (i = 0; i < ITLB_WAYS; i++) { |
mtspr (SPR_ITLBMR_BASE(i) + set, 0); |
} |
|
/* Perform jumps to address, that is not in ITLB */ |
for (i = 0; i < ITLB_WAYS; i++) { |
TEST_JUMP(FLASH_START + FLASH_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)); |
|
/* Check if there was ITLB miss */ |
ASSERT(itlb_miss_count == (i + 1)); |
ASSERT(itlb_miss_ea == (FLASH_START + FLASH_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE))); |
} |
|
/* Reset ITLB miss counter and EA */ |
itlb_miss_count = 0; |
itlb_miss_ea = 0; |
|
/* Perform jumps to address, that is now in ITLB */ |
for (i = 0; i < ITLB_WAYS; i++) { |
TEST_JUMP(FLASH_START + FLASH_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)); |
|
/* Check if there was ITLB miss */ |
ASSERT(itlb_miss_count == 0); |
} |
|
/* Reset valid bits */ |
for (i = 0; i < ITLB_WAYS; i++) { |
mtspr (SPR_ITLBMR_BASE(i) + set, mfspr (SPR_ITLBMR_BASE(i) + set) & ~SPR_ITLBMR_V); |
} |
|
/* Perform jumps to address, that is now in ITLB but is invalid */ |
for (i = 0; i < ITLB_WAYS; i++) { |
TEST_JUMP(FLASH_START + FLASH_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)); |
|
/* Check if there was ITLB miss */ |
ASSERT(itlb_miss_count == (i + 1)); |
ASSERT(itlb_miss_ea == (FLASH_START + FLASH_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE))); |
} |
|
return 0; |
} |
|
int main (void) |
{ |
int i; |
287,6 → 399,10
/* Valid bit testing */ |
for (i = 0; i < 15; i++) |
dtlb_valid_bit_test (DTLB_SETS - i - 1); |
|
/* Valid bit testing */ |
for (i = 0; i < 15; i++) |
itlb_valid_bit_test (ITLB_SETS - i - 1); |
|
/* Write pattern */ |
// write_pattern(0x40000000, 0x40100000); |
/trunk/or1ksim/testbench/Makefile.in
240,10 → 240,10
DIST_SUBDIRS = support uos support |
DEP_FILES = .deps/acv_uart.P .deps/basic.P .deps/cache.P .deps/cbasic.P \ |
.deps/cfg.P .deps/dhry.P .deps/dmatest.P .deps/eth.P .deps/except.P \ |
.deps/excpt.P .deps/exit.P .deps/local_global.P .deps/mmu.P \ |
.deps/mmu_asm.P .deps/mul.P .deps/mycompress.P |
SOURCES = $(exit_SOURCES) $(cbasic_SOURCES) $(local_global_SOURCES) $(mul_SOURCES) $(mycompress_SOURCES) $(dhry_SOURCES) $(basic_SOURCES) $(cache_SOURCES) $(excpt_SOURCES) $(cfg_SOURCES) $(dmatest_SOURCES) $(eth_SOURCES) $(mmu_SOURCES) $(acv_uart_SOURCES) |
OBJECTS = $(exit_OBJECTS) $(cbasic_OBJECTS) $(local_global_OBJECTS) $(mul_OBJECTS) $(mycompress_OBJECTS) $(dhry_OBJECTS) $(basic_OBJECTS) $(cache_OBJECTS) $(excpt_OBJECTS) $(cfg_OBJECTS) $(dmatest_OBJECTS) $(eth_OBJECTS) $(mmu_OBJECTS) $(acv_uart_OBJECTS) |
.deps/excpt.P .deps/exit.P .deps/functest.P .deps/local_global.P \ |
.deps/mmu.P .deps/mmu_asm.P .deps/mul.P .deps/mycompress.P |
SOURCES = $(exit_SOURCES) $(cbasic_SOURCES) $(local_global_SOURCES) $(mul_SOURCES) $(mycompress_SOURCES) $(dhry_SOURCES) $(functest_SOURCES) $(basic_SOURCES) $(cache_SOURCES) $(excpt_SOURCES) $(cfg_SOURCES) $(dmatest_SOURCES) $(eth_SOURCES) $(mmu_SOURCES) $(acv_uart_SOURCES) |
OBJECTS = $(exit_OBJECTS) $(cbasic_OBJECTS) $(local_global_OBJECTS) $(mul_OBJECTS) $(mycompress_OBJECTS) $(dhry_OBJECTS) $(functest_OBJECTS) $(basic_OBJECTS) $(cache_OBJECTS) $(excpt_OBJECTS) $(cfg_OBJECTS) $(dmatest_OBJECTS) $(eth_OBJECTS) $(mmu_OBJECTS) $(acv_uart_OBJECTS) |
|
all: all-redirect |
.SUFFIXES: |
/trunk/or1ksim/testbench/except.S
30,8 → 30,7
l.movhi r1,hi(_stack) |
l.ori r1,r1,lo(_stack) |
|
.if COPY_SECTIONS |
|
.if 1 /*COPY_SECTIONS */ |
l.movhi r3,hi(_src_beg) |
l.ori r3,r3,lo(_src_beg) |
l.movhi r4,hi(_dst_beg) |
312,4 → 311,4
l.lwz r31,0x70(r1) |
l.addi r1,r1,116 |
l.rfe |
l.nop |
l.nop |
/trunk/or1ksim/testbench/mmu_asm.S
2,6 → 2,7
|
.global _lo_dmmu_en |
.global _lo_immu_en |
.global _lo_ |
|
_lo_dmmu_en: |
l.mfspr r3,r0,SPR_SR |
20,4 → 21,6
l.mtspr r0,r9,SPR_EPCR_BASE |
l.rfe |
l.nop |
|
_lo_ |
|
/trunk/or1ksim/testbench/basic.s
7,7 → 7,9
.org 0x100 |
_reset: |
l.nop |
l.j _regs |
l.movhi r1,hi(_regs) |
l.ori r1,r1,lo(_regs) |
l.jr r1 |
l.nop |
|
.section .text |
/trunk/or1ksim/testbench/except.ld
1,7 → 1,7
MEMORY |
{ |
flash : ORIGIN = 0x00000000, LENGTH = 0x00001fff |
ram : ORIGIN = 0x00002000, LENGTH = 0x00010000 |
flash : ORIGIN = 0x00000000, LENGTH = 0x00010000 |
ram : ORIGIN = 0x40000000, LENGTH = 0x00100000 |
} |
|
SECTIONS |
8,7 → 8,7
{ |
.except : |
{ |
*(.reset) |
*(.except) |
} > flash |
.text : |
{ |
/trunk/or1ksim/testbench/cfg.S
5,11 → 5,12
.org 0x100 |
_reset: |
l.addi r1,r0,0x7f00 |
l.jal _main |
l.movhi r2,hi(_main) |
l.ori r2,r2,lo(_main) |
l.jr r2 |
l.nop |
|
|
|
.section .text |
_main: |
l.addi r2,r0,0 |