Fix some models missmatch

Add more SBI
Add hardware LR/SC support in dbus cacheless
This commit is contained in:
Dolu1990 2019-03-26 01:25:18 +01:00
parent 1c3fd5c38b
commit 94fc2c3ecf
14 changed files with 886 additions and 433 deletions

View File

@ -12,19 +12,19 @@ Disassembly of section .init:
#endif*/ #endif*/
la sp, _sp la sp, _sp
80000000: 00001117 auipc sp,0x1 80000000: 00001117 auipc sp,0x1
80000004: dd810113 addi sp,sp,-552 # 80000dd8 <_sp> 80000004: f3810113 addi sp,sp,-200 # 80000f38 <_sp>
/* Load data section */ /* Load data section */
la a0, _data_lma la a0, _data_lma
80000008: 00000517 auipc a0,0x0 80000008: 00000517 auipc a0,0x0
8000000c: 55c50513 addi a0,a0,1372 # 80000564 <__init_array_end> 8000000c: 6b850513 addi a0,a0,1720 # 800006c0 <__init_array_end>
la a1, _data la a1, _data
80000010: 00000597 auipc a1,0x0 80000010: 00000597 auipc a1,0x0
80000014: 55458593 addi a1,a1,1364 # 80000564 <__init_array_end> 80000014: 6b058593 addi a1,a1,1712 # 800006c0 <__init_array_end>
la a2, _edata la a2, _edata
80000018: 00000617 auipc a2,0x0 80000018: 00000617 auipc a2,0x0
8000001c: 5c060613 addi a2,a2,1472 # 800005d8 <__bss_start> 8000001c: 72060613 addi a2,a2,1824 # 80000738 <__bss_start>
bgeu a1, a2, 2f bgeu a1, a2, 2f
80000020: 00c5fc63 bleu a2,a1,80000038 <_start+0x38> 80000020: 00c5fc63 bleu a2,a1,80000038 <_start+0x38>
1: 1:
@ -43,10 +43,10 @@ Disassembly of section .init:
/* Clear bss section */ /* Clear bss section */
la a0, __bss_start la a0, __bss_start
80000038: 00000517 auipc a0,0x0 80000038: 00000517 auipc a0,0x0
8000003c: 5a050513 addi a0,a0,1440 # 800005d8 <__bss_start> 8000003c: 70050513 addi a0,a0,1792 # 80000738 <__bss_start>
la a1, _end la a1, _end
80000040: 00000597 auipc a1,0x0 80000040: 00000597 auipc a1,0x0
80000044: 59858593 addi a1,a1,1432 # 800005d8 <__bss_start> 80000044: 6f858593 addi a1,a1,1784 # 80000738 <__bss_start>
bgeu a0, a1, 2f bgeu a0, a1, 2f
80000048: 00b57863 bleu a1,a0,80000058 <_start+0x58> 80000048: 00b57863 bleu a1,a0,80000058 <_start+0x58>
1: 1:
@ -59,16 +59,16 @@ Disassembly of section .init:
2: 2:
call __libc_init_array call __libc_init_array
80000058: 474000ef jal ra,800004cc <__libc_init_array> 80000058: 5d0000ef jal ra,80000628 <__libc_init_array>
call init call init
8000005c: 128000ef jal ra,80000184 <init> 8000005c: 128000ef jal ra,80000184 <init>
la ra, done la ra, done
80000060: 00000097 auipc ra,0x0 80000060: 00000097 auipc ra,0x0
80000064: 01408093 addi ra,ra,20 # 80000074 <done> 80000064: 01408093 addi ra,ra,20 # 80000074 <done>
li a0, DTB li a0, 0
80000068: 81000537 lui a0,0x81000 80000068: 00000513 li a0,0
li a1, 0 li a1, DTB
8000006c: 00000593 li a1,0 8000006c: 810005b7 lui a1,0x81000
mret mret
80000070: 30200073 mret 80000070: 30200073 mret
@ -156,7 +156,7 @@ trapEntry:
sw x31, 31*4(sp) sw x31, 31*4(sp)
800000f8: 07f12e23 sw t6,124(sp) 800000f8: 07f12e23 sw t6,124(sp)
call trap call trap
800000fc: 1e8000ef jal ra,800002e4 <trap> 800000fc: 1ec000ef jal ra,800002e8 <trap>
lw x0, 0*4(sp) lw x0, 0*4(sp)
80000100: 00012003 lw zero,0(sp) 80000100: 00012003 lw zero,0(sp)
lw x1, 1*4(sp) lw x1, 1*4(sp)
@ -231,79 +231,70 @@ extern void trapEntry();
extern void emulationTrap(); extern void emulationTrap();
void init() { void init() {
unsigned int sp = (unsigned int) (&_sp); uint32_t sp = (uint32_t) (&_sp);
csr_write(mtvec, trapEntry); csr_write(mtvec, trapEntry);
80000184: 800007b7 lui a5,0x80000 80000184: 800007b7 lui a5,0x80000
80000188: 07c78793 addi a5,a5,124 # 8000007c <_sp+0xfffff2a4> 80000188: 07c78793 addi a5,a5,124 # 8000007c <_sp+0xfffff144>
8000018c: 30579073 csrw mtvec,a5 8000018c: 30579073 csrw mtvec,a5
csr_write(mscratch, sp -32*4); csr_write(mscratch, sp -32*4);
80000190: 800017b7 lui a5,0x80001 80000190: 800017b7 lui a5,0x80001
80000194: dd878793 addi a5,a5,-552 # 80000dd8 <_sp+0x0> 80000194: f3878793 addi a5,a5,-200 # 80000f38 <_sp+0x0>
80000198: f8078793 addi a5,a5,-128 80000198: f8078793 addi a5,a5,-128
8000019c: 34079073 csrw mscratch,a5 8000019c: 34079073 csrw mscratch,a5
csr_write(mstatus, 0x0800); csr_write(mstatus, 0x0800 | MSTATUS_MPIE);
800001a0: 000017b7 lui a5,0x1 800001a0: 000017b7 lui a5,0x1
800001a4: 80078793 addi a5,a5,-2048 # 800 <__stack_size> 800001a4: 88078793 addi a5,a5,-1920 # 880 <__stack_size+0x80>
800001a8: 30079073 csrw mstatus,a5 800001a8: 30079073 csrw mstatus,a5
csr_write(mie, 0);
800001ac: 30405073 csrwi mie,0
csr_write(mepc, OS_CALL); csr_write(mepc, OS_CALL);
800001ac: c00007b7 lui a5,0xc0000 800001b0: c00007b7 lui a5,0xc0000
800001b0: 34179073 csrw mepc,a5 800001b4: 34179073 csrw mepc,a5
csr_write(medeleg, MDELEG_INSTRUCTION_PAGE_FAULT | MDELEG_LOAD_PAGE_FAULT | MDELEG_STORE_PAGE_FAULT); csr_write(medeleg, MEDELEG_INSTRUCTION_PAGE_FAULT | MEDELEG_LOAD_PAGE_FAULT | MEDELEG_STORE_PAGE_FAULT);
800001b4: 0000b7b7 lui a5,0xb 800001b8: 0000b7b7 lui a5,0xb
800001b8: 30279073 csrw medeleg,a5 800001bc: 30279073 csrw medeleg,a5
csr_write(mideleg, MIDELEG_SUPERVISOR_TIMER);
800001c0: 02000793 li a5,32
800001c4: 30379073 csrw mideleg,a5
csr_write(sbadaddr, 0); //Used to avoid simulation missmatch
800001c8: 14305073 csrwi sbadaddr,0
} }
800001bc: 00008067 ret 800001cc: 00008067 ret
800001c0 <readRegister>: 800001d0 <readRegister>:
int readRegister(int id){ int readRegister(uint32_t id){
unsigned int sp = (unsigned int) (&_sp); unsigned int sp = (unsigned int) (&_sp);
return ((int*) sp)[id-32]; return ((int*) sp)[id-32];
800001c0: 00251513 slli a0,a0,0x2 800001d0: 00251513 slli a0,a0,0x2
800001c4: 800017b7 lui a5,0x80001 800001d4: 800017b7 lui a5,0x80001
800001c8: dd878793 addi a5,a5,-552 # 80000dd8 <_sp+0x0> 800001d8: f3878793 addi a5,a5,-200 # 80000f38 <_sp+0x0>
800001cc: 00f50533 add a0,a0,a5 800001dc: 00f50533 add a0,a0,a5
} }
800001d0: f8052503 lw a0,-128(a0) # 80ffff80 <_sp+0xfff1a8> 800001e0: f8052503 lw a0,-128(a0)
800001d4: 00008067 ret 800001e4: 00008067 ret
800001d8 <writeRegister>: 800001e8 <writeRegister>:
void writeRegister(int id, int value){ void writeRegister(uint32_t id, int value){
unsigned int sp = (unsigned int) (&_sp); uint32_t sp = (uint32_t) (&_sp);
((int*) sp)[id-32] = value; ((uint32_t*) sp)[id-32] = value;
800001d8: 00251513 slli a0,a0,0x2 800001e8: 00251513 slli a0,a0,0x2
800001dc: 800017b7 lui a5,0x80001 800001ec: 800017b7 lui a5,0x80001
800001e0: dd878793 addi a5,a5,-552 # 80000dd8 <_sp+0x0> 800001f0: f3878793 addi a5,a5,-200 # 80000f38 <_sp+0x0>
800001e4: 00f50533 add a0,a0,a5 800001f4: 00f50533 add a0,a0,a5
800001e8: f8b52023 sw a1,-128(a0) 800001f8: f8b52023 sw a1,-128(a0)
}
800001ec: 00008067 ret
800001f0 <stopSim>:
void stopSim(){
*((volatile int*) SIM_STOP) = 0;
800001f0: fe002e23 sw zero,-4(zero) # fffffffc <_sp+0x7ffff224>
}
800001f4: 00008067 ret
800001f8 <putC>:
void putC(char c){
*((volatile int*) PUTC) = c;
800001f8: fea02c23 sw a0,-8(zero) # fffffff8 <_sp+0x7ffff220>
} }
800001fc: 00008067 ret 800001fc: 00008067 ret
80000200 <redirectTrap>: 80000200 <redirectTrap>:
void redirectTrap(){ void redirectTrap(){
80000200: ff010113 addi sp,sp,-16 80000200: ff010113 addi sp,sp,-16
80000204: 00112623 sw ra,12(sp) 80000204: 00112623 sw ra,12(sp)
stopSim(); stopSim();
80000208: fe9ff0ef jal ra,800001f0 <stopSim> 80000208: 3e8000ef jal ra,800005f0 <stopSim>
csr_write(sbadaddr, csr_read(mbadaddr)); csr_write(sbadaddr, csr_read(mbadaddr));
8000020c: 343027f3 csrr a5,mbadaddr 8000020c: 343027f3 csrr a5,mbadaddr
80000210: 14379073 csrw sbadaddr,a5 80000210: 14379073 csrw sbadaddr,a5
@ -346,286 +337,436 @@ void emulationTrapToSupervisorTrap(uint32_t sepc, uint32_t mstatus){
80000268: 000027b7 lui a5,0x2 80000268: 000027b7 lui a5,0x2
8000026c: 80078793 addi a5,a5,-2048 # 1800 <__stack_size+0x1000> 8000026c: 80078793 addi a5,a5,-2048 # 1800 <__stack_size+0x1000>
80000270: 3007b073 csrc mstatus,a5 80000270: 3007b073 csrc mstatus,a5
csr_set(mstatus, 0x8000); csr_set(mstatus, 0x8000 | MSTATUS_MPIE);
80000274: 000087b7 lui a5,0x8 80000274: 000087b7 lui a5,0x8
80000278: 3007a073 csrs mstatus,a5 80000278: 08078793 addi a5,a5,128 # 8080 <__stack_size+0x7880>
8000027c: 3007a073 csrs mstatus,a5
} }
8000027c: 00008067 ret 80000280: 00008067 ret
80000280 <readWord>: 80000284 <readWord>:
//Will modify MEPC //Will modify MEPC
int readWord(int address, int *data){ int32_t readWord(uint32_t address, int32_t *data){
int result, tmp; int32_t result, tmp;
int failed; int32_t failed;
__asm__ __volatile__ ( __asm__ __volatile__ (
80000280: 00020737 lui a4,0x20 80000284: 00020737 lui a4,0x20
80000284: 30072073 csrs mstatus,a4 80000288: 30072073 csrs mstatus,a4
80000288: 00000717 auipc a4,0x0 8000028c: 00000717 auipc a4,0x0
8000028c: 01870713 addi a4,a4,24 # 800002a0 <readWord+0x20> 80000290: 01870713 addi a4,a4,24 # 800002a4 <readWord+0x20>
80000290: 34171073 csrw mepc,a4 80000294: 34171073 csrw mepc,a4
80000294: 00100693 li a3,1 80000298: 00100693 li a3,1
80000298: 00052783 lw a5,0(a0) 8000029c: 00052783 lw a5,0(a0)
8000029c: 00000693 li a3,0 800002a0: 00000693 li a3,0
800002a0: 00020737 lui a4,0x20 800002a4: 00020737 lui a4,0x20
800002a4: 30073073 csrc mstatus,a4 800002a8: 30073073 csrc mstatus,a4
800002a8: 00068513 mv a0,a3 800002ac: 00068513 mv a0,a3
: [result]"=&r" (result), [failed]"=&r" (failed), [tmp]"=&r" (tmp) : [result]"=&r" (result), [failed]"=&r" (failed), [tmp]"=&r" (tmp)
: [address]"r" (address) : [address]"r" (address)
: "memory" : "memory"
); );
*data = result; *data = result;
800002ac: 00f5a023 sw a5,0(a1) 800002b0: 00f5a023 sw a5,0(a1) # 81000000 <_sp+0xfff0c8>
return failed; return failed;
} }
800002b0: 00008067 ret 800002b4: 00008067 ret
800002b4 <writeWord>: 800002b8 <writeWord>:
//Will modify MEPC //Will modify MEPC
int writeWord(uint32_t address, uint32_t data){ int32_t writeWord(uint32_t address, int32_t data){
int result, tmp; int32_t result, tmp;
int failed; int32_t failed;
__asm__ __volatile__ ( __asm__ __volatile__ (
800002b4: 00020737 lui a4,0x20 800002b8: 00020737 lui a4,0x20
800002b8: 30072073 csrs mstatus,a4 800002bc: 30072073 csrs mstatus,a4
800002bc: 00000717 auipc a4,0x0 800002c0: 00000717 auipc a4,0x0
800002c0: 01870713 addi a4,a4,24 # 800002d4 <writeWord+0x20> 800002c4: 01870713 addi a4,a4,24 # 800002d8 <writeWord+0x20>
800002c4: 34171073 csrw mepc,a4 800002c8: 34171073 csrw mepc,a4
800002c8: 00100793 li a5,1 800002cc: 00100793 li a5,1
800002cc: 00b52023 sw a1,0(a0) 800002d0: 00b52023 sw a1,0(a0)
800002d0: 00000793 li a5,0 800002d4: 00000793 li a5,0
800002d4: 00020737 lui a4,0x20 800002d8: 00020737 lui a4,0x20
800002d8: 30073073 csrc mstatus,a4 800002dc: 30073073 csrc mstatus,a4
800002dc: 00078513 mv a0,a5 800002e0: 00078513 mv a0,a5
: [address]"r" (address), [data]"r" (data) : [address]"r" (address), [data]"r" (data)
: "memory" : "memory"
); );
return failed; return failed;
} }
800002e0: 00008067 ret 800002e4: 00008067 ret
800002e4 <trap>:
800002e8 <trap>:
void trap(){ void trap(){
800002e4: fd010113 addi sp,sp,-48 800002e8: fd010113 addi sp,sp,-48
800002e8: 02112623 sw ra,44(sp) 800002ec: 02112623 sw ra,44(sp)
800002ec: 02812423 sw s0,40(sp) 800002f0: 02812423 sw s0,40(sp)
800002f0: 02912223 sw s1,36(sp) 800002f4: 02912223 sw s1,36(sp)
800002f4: 03212023 sw s2,32(sp) 800002f8: 03212023 sw s2,32(sp)
800002f8: 01312e23 sw s3,28(sp) 800002fc: 01312e23 sw s3,28(sp)
800002fc: 01412c23 sw s4,24(sp) 80000300: 01412c23 sw s4,24(sp)
80000300: 01512a23 sw s5,20(sp) 80000304: 01512a23 sw s5,20(sp)
int cause = csr_read(mcause); int32_t cause = csr_read(mcause);
80000304: 342027f3 csrr a5,mcause 80000308: 342027f3 csrr a5,mcause
if(cause < 0){ if(cause < 0){ //interrupt
80000308: 0207ce63 bltz a5,80000344 <trap+0x60> 8000030c: 0007ce63 bltz a5,80000328 <trap+0x40>
redirectTrap(); csr_clear(mie, MIE_MTIE);
} else { }break;
default: redirectTrap(); break;
}
} else { //exception
switch(cause){ switch(cause){
8000030c: 00200713 li a4,2 80000310: 00200713 li a4,2
80000310: 02e78e63 beq a5,a4,8000034c <trap+0x68> 80000314: 04e78e63 beq a5,a4,80000370 <trap+0x88>
80000314: 00900713 li a4,9 80000318: 00900713 li a4,9
80000318: 16e78e63 beq a5,a4,80000494 <trap+0x1b0> 8000031c: 24e78e63 beq a5,a4,80000578 <trap+0x290>
csr_write(mepc, csr_read(mepc) + 4); csr_write(mepc, csr_read(mepc) + 4);
}break; }break;
default: stopSim(); break; default: stopSim(); break;
} }
}break; }break;
default: redirectTrap(); break; default: redirectTrap(); break;
8000031c: ee5ff0ef jal ra,80000200 <redirectTrap> 80000320: ee1ff0ef jal ra,80000200 <redirectTrap>
80000324: 0200006f j 80000344 <trap+0x5c>
switch(cause & 0xFF){
80000328: 0ff7f793 andi a5,a5,255
8000032c: 00700713 li a4,7
80000330: 02e79c63 bne a5,a4,80000368 <trap+0x80>
csr_set(sip, MIP_STIP);
80000334: 02000793 li a5,32
80000338: 1447a073 csrs sip,a5
csr_clear(mie, MIE_MTIE);
8000033c: 08000793 li a5,128
80000340: 3047b073 csrc mie,a5
} }
} }
} }
80000320: 02c12083 lw ra,44(sp) 80000344: 02c12083 lw ra,44(sp)
80000324: 02812403 lw s0,40(sp) 80000348: 02812403 lw s0,40(sp)
80000328: 02412483 lw s1,36(sp) 8000034c: 02412483 lw s1,36(sp)
8000032c: 02012903 lw s2,32(sp) 80000350: 02012903 lw s2,32(sp)
80000330: 01c12983 lw s3,28(sp) 80000354: 01c12983 lw s3,28(sp)
80000334: 01812a03 lw s4,24(sp) 80000358: 01812a03 lw s4,24(sp)
80000338: 01412a83 lw s5,20(sp) 8000035c: 01412a83 lw s5,20(sp)
8000033c: 03010113 addi sp,sp,48 80000360: 03010113 addi sp,sp,48
80000340: 00008067 ret 80000364: 00008067 ret
redirectTrap(); default: redirectTrap(); break;
80000344: ebdff0ef jal ra,80000200 <redirectTrap> 80000368: e99ff0ef jal ra,80000200 <redirectTrap>
80000348: fd9ff06f j 80000320 <trap+0x3c> 8000036c: fd9ff06f j 80000344 <trap+0x5c>
int mepc = csr_read(mepc); uint32_t mepc = csr_read(mepc);
8000034c: 341024f3 csrr s1,mepc 80000370: 341024f3 csrr s1,mepc
int mstatus = csr_read(mstatus); uint32_t mstatus = csr_read(mstatus);
80000350: 300029f3 csrr s3,mstatus 80000374: 30002a73 csrr s4,mstatus
int instruction = csr_read(mbadaddr); uint32_t instruction = csr_read(mbadaddr);
80000354: 34302473 csrr s0,mbadaddr 80000378: 34302473 csrr s0,mbadaddr
int opcode = instruction & 0x7F; uint32_t opcode = instruction & 0x7F;
80000358: 07f47693 andi a3,s0,127 8000037c: 07f47713 andi a4,s0,127
int funct3 = (instruction >> 12) & 0x7; uint32_t funct3 = (instruction >> 12) & 0x7;
8000035c: 40c45793 srai a5,s0,0xc 80000380: 00c45793 srli a5,s0,0xc
80000360: 0077f793 andi a5,a5,7 80000384: 0077f613 andi a2,a5,7
switch(opcode){ switch(opcode){
80000364: 02f00713 li a4,47 80000388: 02f00693 li a3,47
80000368: fae69ce3 bne a3,a4,80000320 <trap+0x3c> 8000038c: 00d70a63 beq a4,a3,800003a0 <trap+0xb8>
80000390: 07300693 li a3,115
80000394: 12d70a63 beq a4,a3,800004c8 <trap+0x1e0>
default: redirectTrap(); break;
80000398: e69ff0ef jal ra,80000200 <redirectTrap>
8000039c: fa9ff06f j 80000344 <trap+0x5c>
switch(funct3){ switch(funct3){
8000036c: 00200713 li a4,2 800003a0: 00200793 li a5,2
80000370: 10e79e63 bne a5,a4,8000048c <trap+0x1a8> 800003a4: 10f61e63 bne a2,a5,800004c0 <trap+0x1d8>
int sel = instruction >> 27; uint32_t sel = instruction >> 27;
80000374: 41b45913 srai s2,s0,0x1b 800003a8: 01b45913 srli s2,s0,0x1b
int addr = readRegister((instruction >> 15) & 0x1F); uint32_t addr = readRegister((instruction >> 15) & 0x1F);
80000378: 40f45513 srai a0,s0,0xf 800003ac: 00f45513 srli a0,s0,0xf
8000037c: 01f57513 andi a0,a0,31 800003b0: 01f57513 andi a0,a0,31
80000380: e41ff0ef jal ra,800001c0 <readRegister> 800003b4: e1dff0ef jal ra,800001d0 <readRegister>
80000384: 00050a93 mv s5,a0 800003b8: 00050a93 mv s5,a0
int src = readRegister((instruction >> 20) & 0x1F); int32_t src = readRegister((instruction >> 20) & 0x1F);
80000388: 41445513 srai a0,s0,0x14 800003bc: 01445513 srli a0,s0,0x14
8000038c: 01f57513 andi a0,a0,31 800003c0: 01f57513 andi a0,a0,31
80000390: e31ff0ef jal ra,800001c0 <readRegister> 800003c4: e0dff0ef jal ra,800001d0 <readRegister>
80000394: 00050a13 mv s4,a0 800003c8: 00050993 mv s3,a0
int rd = (instruction >> 7) & 0x1F; uint32_t rd = (instruction >> 7) & 0x1F;
80000398: 40745413 srai s0,s0,0x7 800003cc: 00745413 srli s0,s0,0x7
8000039c: 01f47413 andi s0,s0,31 800003d0: 01f47413 andi s0,s0,31
if(readWord(addr, &readValue)){ if(readWord(addr, &readValue)){
800003a0: 00c10593 addi a1,sp,12 800003d4: 00c10593 addi a1,sp,12
800003a4: 000a8513 mv a0,s5 800003d8: 000a8513 mv a0,s5
800003a8: ed9ff0ef jal ra,80000280 <readWord> 800003dc: ea9ff0ef jal ra,80000284 <readWord>
800003ac: 02051263 bnez a0,800003d0 <trap+0xec> 800003e0: 02051263 bnez a0,80000404 <trap+0x11c>
switch(sel){ switch(sel){
800003b0: 01c00793 li a5,28 800003e4: 01c00793 li a5,28
800003b4: 0d27e063 bltu a5,s2,80000474 <trap+0x190> 800003e8: 0d27e063 bltu a5,s2,800004a8 <trap+0x1c0>
800003b8: 00291913 slli s2,s2,0x2 800003ec: 00291913 slli s2,s2,0x2
800003bc: 800007b7 lui a5,0x80000 800003f0: 800007b7 lui a5,0x80000
800003c0: 56478793 addi a5,a5,1380 # 80000564 <_sp+0xfffff78c> 800003f4: 6c078793 addi a5,a5,1728 # 800006c0 <_sp+0xfffff788>
800003c4: 00f90933 add s2,s2,a5 800003f8: 00f90933 add s2,s2,a5
800003c8: 00092783 lw a5,0(s2) 800003fc: 00092783 lw a5,0(s2)
800003cc: 00078067 jr a5 80000400: 00078067 jr a5
emulationTrapToSupervisorTrap(mepc, mstatus); emulationTrapToSupervisorTrap(mepc, mstatus);
800003d0: 00098593 mv a1,s3 80000404: 000a0593 mv a1,s4
800003d4: 00048513 mv a0,s1 80000408: 00048513 mv a0,s1
800003d8: e61ff0ef jal ra,80000238 <emulationTrapToSupervisorTrap> 8000040c: e2dff0ef jal ra,80000238 <emulationTrapToSupervisorTrap>
return; return;
800003dc: f45ff06f j 80000320 <trap+0x3c> 80000410: f35ff06f j 80000344 <trap+0x5c>
case 0x0: writeValue = src + readValue; break; case 0x0: writeValue = src + readValue; break;
800003e0: 00c12783 lw a5,12(sp) 80000414: 00c12783 lw a5,12(sp)
800003e4: 00fa0a33 add s4,s4,a5 80000418: 00f989b3 add s3,s3,a5
writeRegister(rd, readValue); writeRegister(rd, readValue);
800003e8: 00c12583 lw a1,12(sp) 8000041c: 00c12583 lw a1,12(sp)
800003ec: 00040513 mv a0,s0 80000420: 00040513 mv a0,s0
800003f0: de9ff0ef jal ra,800001d8 <writeRegister> 80000424: dc5ff0ef jal ra,800001e8 <writeRegister>
if(writeWord(addr, writeValue)){ if(writeWord(addr, writeValue)){
800003f4: 000a0593 mv a1,s4 80000428: 00098593 mv a1,s3
800003f8: 000a8513 mv a0,s5 8000042c: 000a8513 mv a0,s5
800003fc: eb9ff0ef jal ra,800002b4 <writeWord> 80000430: e89ff0ef jal ra,800002b8 <writeWord>
80000400: 06051e63 bnez a0,8000047c <trap+0x198> 80000434: 06051e63 bnez a0,800004b0 <trap+0x1c8>
csr_write(mepc, mepc + 4); csr_write(mepc, mepc + 4);
80000404: 00448493 addi s1,s1,4 80000438: 00448493 addi s1,s1,4
80000408: 34149073 csrw mepc,s1 8000043c: 34149073 csrw mepc,s1
}break; }break;
8000040c: f15ff06f j 80000320 <trap+0x3c> 80000440: f05ff06f j 80000344 <trap+0x5c>
case 0x4: writeValue = src ^ readValue; break; case 0x4: writeValue = src ^ readValue; break;
80000410: 00c12783 lw a5,12(sp)
80000414: 00fa4a33 xor s4,s4,a5
80000418: fd1ff06f j 800003e8 <trap+0x104>
case 0xC: writeValue = src & readValue; break;
8000041c: 00c12783 lw a5,12(sp)
80000420: 00fa7a33 and s4,s4,a5
80000424: fc5ff06f j 800003e8 <trap+0x104>
case 0x8: writeValue = src | readValue; break;
80000428: 00c12783 lw a5,12(sp)
8000042c: 00fa6a33 or s4,s4,a5
80000430: fb9ff06f j 800003e8 <trap+0x104>
case 0x10: writeValue = min(src, readValue); break;
80000434: 00c12783 lw a5,12(sp)
80000438: fb47d8e3 ble s4,a5,800003e8 <trap+0x104>
8000043c: 00078a13 mv s4,a5
80000440: fa9ff06f j 800003e8 <trap+0x104>
case 0x14: writeValue = max(src, readValue); break;
80000444: 00c12783 lw a5,12(sp) 80000444: 00c12783 lw a5,12(sp)
80000448: fafa50e3 ble a5,s4,800003e8 <trap+0x104> 80000448: 00f9c9b3 xor s3,s3,a5
8000044c: 00078a13 mv s4,a5 8000044c: fd1ff06f j 8000041c <trap+0x134>
80000450: f99ff06f j 800003e8 <trap+0x104> case 0xC: writeValue = src & readValue; break;
80000450: 00c12783 lw a5,12(sp)
80000454: 00f9f9b3 and s3,s3,a5
80000458: fc5ff06f j 8000041c <trap+0x134>
case 0x8: writeValue = src | readValue; break;
8000045c: 00c12783 lw a5,12(sp)
80000460: 00f9e9b3 or s3,s3,a5
80000464: fb9ff06f j 8000041c <trap+0x134>
case 0x10: writeValue = min(src, readValue); break;
80000468: 00c12783 lw a5,12(sp)
8000046c: fb37d8e3 ble s3,a5,8000041c <trap+0x134>
80000470: 00078993 mv s3,a5
80000474: fa9ff06f j 8000041c <trap+0x134>
case 0x14: writeValue = max(src, readValue); break;
80000478: 00c12783 lw a5,12(sp)
8000047c: faf9d0e3 ble a5,s3,8000041c <trap+0x134>
80000480: 00078993 mv s3,a5
80000484: f99ff06f j 8000041c <trap+0x134>
case 0x18: writeValue = min((unsigned int)src, (unsigned int)readValue); break; case 0x18: writeValue = min((unsigned int)src, (unsigned int)readValue); break;
80000454: 00c12783 lw a5,12(sp) 80000488: 00c12783 lw a5,12(sp)
80000458: f947f8e3 bleu s4,a5,800003e8 <trap+0x104> 8000048c: f937f8e3 bleu s3,a5,8000041c <trap+0x134>
8000045c: 00078a13 mv s4,a5 80000490: 00078993 mv s3,a5
80000460: f89ff06f j 800003e8 <trap+0x104> 80000494: f89ff06f j 8000041c <trap+0x134>
case 0x1C: writeValue = max((unsigned int)src, (unsigned int)readValue); break; case 0x1C: writeValue = max((unsigned int)src, (unsigned int)readValue); break;
80000464: 00c12783 lw a5,12(sp) 80000498: 00c12783 lw a5,12(sp)
80000468: f8fa70e3 bleu a5,s4,800003e8 <trap+0x104> 8000049c: f8f9f0e3 bleu a5,s3,8000041c <trap+0x134>
8000046c: 00078a13 mv s4,a5 800004a0: 00078993 mv s3,a5
80000470: f79ff06f j 800003e8 <trap+0x104> 800004a4: f79ff06f j 8000041c <trap+0x134>
default: redirectTrap(); return; break; default: redirectTrap(); return; break;
80000474: d8dff0ef jal ra,80000200 <redirectTrap> 800004a8: d59ff0ef jal ra,80000200 <redirectTrap>
80000478: ea9ff06f j 80000320 <trap+0x3c> 800004ac: e99ff06f j 80000344 <trap+0x5c>
emulationTrapToSupervisorTrap(mepc, mstatus); emulationTrapToSupervisorTrap(mepc, mstatus);
8000047c: 00098593 mv a1,s3 800004b0: 000a0593 mv a1,s4
80000480: 00048513 mv a0,s1 800004b4: 00048513 mv a0,s1
80000484: db5ff0ef jal ra,80000238 <emulationTrapToSupervisorTrap> 800004b8: d81ff0ef jal ra,80000238 <emulationTrapToSupervisorTrap>
return; return;
80000488: e99ff06f j 80000320 <trap+0x3c> 800004bc: e89ff06f j 80000344 <trap+0x5c>
default: redirectTrap(); break; default: redirectTrap(); break;
8000048c: d75ff0ef jal ra,80000200 <redirectTrap> 800004c0: d41ff0ef jal ra,80000200 <redirectTrap>
80000490: e91ff06f j 80000320 <trap+0x3c> 800004c4: e81ff06f j 80000344 <trap+0x5c>
int which = readRegister(17); switch (funct3 & 0x3) {
80000494: 01100513 li a0,17 800004c8: 0037f793 andi a5,a5,3
80000498: d29ff0ef jal ra,800001c0 <readRegister> 800004cc: 00100713 li a4,1
800004d0: 06e78263 beq a5,a4,80000534 <trap+0x24c>
800004d4: 02078c63 beqz a5,8000050c <trap+0x224>
800004d8: 00200713 li a4,2
800004dc: 02e78c63 beq a5,a4,80000514 <trap+0x22c>
800004e0: 00300713 li a4,3
800004e4: 04e78063 beq a5,a4,80000524 <trap+0x23c>
uint32_t csrAddress = instruction >> 20;
800004e8: 01445713 srli a4,s0,0x14
switch(csrAddress){
800004ec: 000017b7 lui a5,0x1
800004f0: c0178793 addi a5,a5,-1023 # c01 <__stack_size+0x401>
800004f4: 04f70463 beq a4,a5,8000053c <trap+0x254>
800004f8: 000017b7 lui a5,0x1
800004fc: c8178793 addi a5,a5,-895 # c81 <__stack_size+0x481>
80000500: 06f70263 beq a4,a5,80000564 <trap+0x27c>
default: redirectTrap(); break;
80000504: cfdff0ef jal ra,80000200 <redirectTrap>
80000508: 03c0006f j 80000544 <trap+0x25c>
case 0: redirectTrap(); break;
8000050c: cf5ff0ef jal ra,80000200 <redirectTrap>
80000510: fd9ff06f j 800004e8 <trap+0x200>
case 2: clear = 0; set = input; write = ((instruction >> 15) & 0x1F) != 0; break;
80000514: 00f45993 srli s3,s0,0xf
80000518: 01f9f993 andi s3,s3,31
8000051c: 013039b3 snez s3,s3
80000520: fc9ff06f j 800004e8 <trap+0x200>
case 3: clear = input; set = 0; write = ((instruction >> 15) & 0x1F) != 0; break;
80000524: 00f45993 srli s3,s0,0xf
80000528: 01f9f993 andi s3,s3,31
8000052c: 013039b3 snez s3,s3
80000530: fb9ff06f j 800004e8 <trap+0x200>
case 1: clear = ~0; set = input; write = 1; break;
80000534: 00100993 li s3,1
80000538: fb1ff06f j 800004e8 <trap+0x200>
case RDTIME : old = rdtime(); break;
8000053c: 0c4000ef jal ra,80000600 <rdtime>
80000540: 00050913 mv s2,a0
if(write) {
80000544: 02099663 bnez s3,80000570 <trap+0x288>
writeRegister((instruction >> 7) & 0x1F, old);
80000548: 00745513 srli a0,s0,0x7
8000054c: 00090593 mv a1,s2
80000550: 01f57513 andi a0,a0,31
80000554: c95ff0ef jal ra,800001e8 <writeRegister>
csr_write(mepc, mepc + 4);
80000558: 00448493 addi s1,s1,4
8000055c: 34149073 csrw mepc,s1
}break;
80000560: de5ff06f j 80000344 <trap+0x5c>
case RDTIMEH : old = rdtimeh(); break;
80000564: 0a4000ef jal ra,80000608 <rdtimeh>
80000568: 00050913 mv s2,a0
8000056c: fd9ff06f j 80000544 <trap+0x25c>
default: redirectTrap(); break;
80000570: c91ff0ef jal ra,80000200 <redirectTrap>
80000574: fd5ff06f j 80000548 <trap+0x260>
uint32_t which = readRegister(17);
80000578: 01100513 li a0,17
8000057c: c55ff0ef jal ra,800001d0 <readRegister>
80000580: 00050413 mv s0,a0
uint32_t a0 = readRegister(10);
80000584: 00a00513 li a0,10
80000588: c49ff0ef jal ra,800001d0 <readRegister>
8000058c: 00050493 mv s1,a0
uint32_t a1 = readRegister(11);
80000590: 00b00513 li a0,11
80000594: c3dff0ef jal ra,800001d0 <readRegister>
switch(which){ switch(which){
8000049c: 00100793 li a5,1 80000598: 02040263 beqz s0,800005bc <trap+0x2d4>
800004a0: 02f51263 bne a0,a5,800004c4 <trap+0x1e0> 8000059c: 00100793 li a5,1
putC(readRegister(10)); 800005a0: 04f41463 bne s0,a5,800005e8 <trap+0x300>
800004a4: 00a00513 li a0,10 putC(a0);
800004a8: d19ff0ef jal ra,800001c0 <readRegister> 800005a4: 0ff4f513 andi a0,s1,255
800004ac: 0ff57513 andi a0,a0,255 800005a8: 050000ef jal ra,800005f8 <putC>
800004b0: d49ff0ef jal ra,800001f8 <putC>
csr_write(mepc, csr_read(mepc) + 4); csr_write(mepc, csr_read(mepc) + 4);
800004b4: 341027f3 csrr a5,mepc 800005ac: 341027f3 csrr a5,mepc
800004b8: 00478793 addi a5,a5,4 800005b0: 00478793 addi a5,a5,4
800004bc: 34179073 csrw mepc,a5 800005b4: 34179073 csrw mepc,a5
}break; }break;
800004c0: e61ff06f j 80000320 <trap+0x3c> 800005b8: d8dff06f j 80000344 <trap+0x5c>
setMachineTimerCmp(a0, a1);
800005bc: 00050593 mv a1,a0
800005c0: 00048513 mv a0,s1
800005c4: 04c000ef jal ra,80000610 <setMachineTimerCmp>
csr_set(mie, MIE_MTIE);
800005c8: 08000793 li a5,128
800005cc: 3047a073 csrs mie,a5
csr_clear(sip, MIP_STIP);
800005d0: 02000793 li a5,32
800005d4: 1447b073 csrc sip,a5
csr_write(mepc, csr_read(mepc) + 4);
800005d8: 341027f3 csrr a5,mepc
800005dc: 00478793 addi a5,a5,4
800005e0: 34179073 csrw mepc,a5
}break;
800005e4: d61ff06f j 80000344 <trap+0x5c>
default: stopSim(); break; default: stopSim(); break;
800004c4: d2dff0ef jal ra,800001f0 <stopSim> 800005e8: 008000ef jal ra,800005f0 <stopSim>
800004c8: e59ff06f j 80000320 <trap+0x3c> 800005ec: d59ff06f j 80000344 <trap+0x5c>
800004cc <__libc_init_array>: 800005f0 <stopSim>:
800004cc: ff010113 addi sp,sp,-16 #include "hal.h"
800004d0: 00812423 sw s0,8(sp)
800004d4: 00912223 sw s1,4(sp) void stopSim(){
800004d8: 00000417 auipc s0,0x0 *((volatile uint32_t*) 0xFFFFFFFC) = 0;
800004dc: 08c40413 addi s0,s0,140 # 80000564 <__init_array_end> 800005f0: fe002e23 sw zero,-4(zero) # fffffffc <_sp+0x7ffff0c4>
800004e0: 00000497 auipc s1,0x0 }
800004e4: 08448493 addi s1,s1,132 # 80000564 <__init_array_end> 800005f4: 00008067 ret
800004e8: 408484b3 sub s1,s1,s0
800004ec: 01212023 sw s2,0(sp) 800005f8 <putC>:
800004f0: 00112623 sw ra,12(sp)
800004f4: 4024d493 srai s1,s1,0x2 void putC(char c){
800004f8: 00000913 li s2,0 *((volatile uint32_t*) 0xFFFFFFF8) = c;
800004fc: 04991063 bne s2,s1,8000053c <__libc_init_array+0x70> 800005f8: fea02c23 sw a0,-8(zero) # fffffff8 <_sp+0x7ffff0c0>
80000500: 00000417 auipc s0,0x0 }
80000504: 06440413 addi s0,s0,100 # 80000564 <__init_array_end> 800005fc: 00008067 ret
80000508: 00000497 auipc s1,0x0
8000050c: 05c48493 addi s1,s1,92 # 80000564 <__init_array_end> 80000600 <rdtime>:
80000510: 408484b3 sub s1,s1,s0
80000514: b65ff0ef jal ra,80000078 <_init> uint32_t rdtime(){
80000518: 4024d493 srai s1,s1,0x2 return *((volatile uint32_t*) 0xFFFFFFE0);
8000051c: 00000913 li s2,0 80000600: fe002503 lw a0,-32(zero) # ffffffe0 <_sp+0x7ffff0a8>
80000520: 02991863 bne s2,s1,80000550 <__libc_init_array+0x84> }
80000524: 00c12083 lw ra,12(sp) 80000604: 00008067 ret
80000528: 00812403 lw s0,8(sp)
8000052c: 00412483 lw s1,4(sp) 80000608 <rdtimeh>:
80000530: 00012903 lw s2,0(sp)
80000534: 01010113 addi sp,sp,16 uint32_t rdtimeh(){
80000538: 00008067 ret return *((volatile uint32_t*) 0xFFFFFFE4);
8000053c: 00042783 lw a5,0(s0) 80000608: fe402503 lw a0,-28(zero) # ffffffe4 <_sp+0x7ffff0ac>
80000540: 00190913 addi s2,s2,1 }
80000544: 00440413 addi s0,s0,4 8000060c: 00008067 ret
80000548: 000780e7 jalr a5
8000054c: fb1ff06f j 800004fc <__libc_init_array+0x30> 80000610 <setMachineTimerCmp>:
80000550: 00042783 lw a5,0(s0)
80000554: 00190913 addi s2,s2,1
80000558: 00440413 addi s0,s0,4 void setMachineTimerCmp(uint32_t low, uint32_t high){
8000055c: 000780e7 jalr a5 volatile uint32_t* base = (volatile uint32_t*) 0xFFFFFFE8;
80000560: fc1ff06f j 80000520 <__libc_init_array+0x54> base[1] = 0xffffffff;
80000610: fec00793 li a5,-20
80000614: fff00713 li a4,-1
80000618: 00e7a023 sw a4,0(a5)
base[0] = low;
8000061c: fea02423 sw a0,-24(zero) # ffffffe8 <_sp+0x7ffff0b0>
base[1] = high;
80000620: 00b7a023 sw a1,0(a5)
}
80000624: 00008067 ret
80000628 <__libc_init_array>:
80000628: ff010113 addi sp,sp,-16
8000062c: 00812423 sw s0,8(sp)
80000630: 00912223 sw s1,4(sp)
80000634: 00000417 auipc s0,0x0
80000638: 08c40413 addi s0,s0,140 # 800006c0 <__init_array_end>
8000063c: 00000497 auipc s1,0x0
80000640: 08448493 addi s1,s1,132 # 800006c0 <__init_array_end>
80000644: 408484b3 sub s1,s1,s0
80000648: 01212023 sw s2,0(sp)
8000064c: 00112623 sw ra,12(sp)
80000650: 4024d493 srai s1,s1,0x2
80000654: 00000913 li s2,0
80000658: 04991063 bne s2,s1,80000698 <__libc_init_array+0x70>
8000065c: 00000417 auipc s0,0x0
80000660: 06440413 addi s0,s0,100 # 800006c0 <__init_array_end>
80000664: 00000497 auipc s1,0x0
80000668: 05c48493 addi s1,s1,92 # 800006c0 <__init_array_end>
8000066c: 408484b3 sub s1,s1,s0
80000670: a09ff0ef jal ra,80000078 <_init>
80000674: 4024d493 srai s1,s1,0x2
80000678: 00000913 li s2,0
8000067c: 02991863 bne s2,s1,800006ac <__libc_init_array+0x84>
80000680: 00c12083 lw ra,12(sp)
80000684: 00812403 lw s0,8(sp)
80000688: 00412483 lw s1,4(sp)
8000068c: 00012903 lw s2,0(sp)
80000690: 01010113 addi sp,sp,16
80000694: 00008067 ret
80000698: 00042783 lw a5,0(s0)
8000069c: 00190913 addi s2,s2,1
800006a0: 00440413 addi s0,s0,4
800006a4: 000780e7 jalr a5
800006a8: fb1ff06f j 80000658 <__libc_init_array+0x30>
800006ac: 00042783 lw a5,0(s0)
800006b0: 00190913 addi s2,s2,1
800006b4: 00440413 addi s0,s0,4
800006b8: 000780e7 jalr a5
800006bc: fc1ff06f j 8000067c <__libc_init_array+0x54>

View File

@ -1,11 +1,11 @@
:0200000480007A :0200000480007A
:1000000017110000130181DD170500001305C55508 :1000000017110000130181F3170500001305856B1C
:100010009705000093854555170600001306065CFA :10001000970500009385056B17060000130606720E
:1000200063FCC5008322050023A05500130545008D :1000200063FCC5008322050023A05500130545008D
:1000300093854500E3E8C5FE170500001305055A42 :1000300093854500E3E8C5FE17050000130505702C
:1000400097050000938585596378B5002320050046 :10004000970500009385856F6378B5002320050030
:1000500013054500E36CB5FEEF004047EF0080124A :1000500013054500E36CB5FEEF00005DEF00801274
:100060009700000093804001370500819305000050 :10006000970000009380400113050000B705008150
:10007000730020306F0000006780000073110134AE :10007000730020306F0000006780000073110134AE
:1000800023200100232211002326310023284100D0 :1000800023200100232211002326310023284100D0
:10009000232A5100232C6100232E7100232081028A :10009000232A5100232C6100232E7100232081028A
@ -14,7 +14,7 @@
:1000C0002322110523242105232631052328410558 :1000C0002322110523242105232631052328410558
:1000D000232A5105232C6105232E71052320810736 :1000D000232A5105232C6105232E71052320810736
:1000E000232291072324A1072326B1072328C10730 :1000E000232291072324A1072326B1072328C10730
:1000F000232AD107232CE107232EF107EF00801ECE :1000F000232AD107232CE107232EF107EF00C01E8E
:1001000003200100832041008321C100032201015B :1001000003200100832041008321C100032201015B
:1001100083224101032381018323C10103240102BE :1001100083224101032381018323C10103240102BE
:1001200083244102032581028325C10203260103A2 :1001200083244102032581028325C10203260103A2
@ -25,74 +25,96 @@
:10017000832E4107032F8107832FC1077311013499 :10017000832E4107032F8107832FC1077311013499
:0401800073002030B8 :0401800073002030B8
:10018400B70700809387C70773905730B71700806D :10018400B70700809387C70773905730B71700806D
:10019400938787DD938707F873900734B7170000B8 :10019400938787F3938707F873900734B7170000A2
:1001A4009387078073900730B70700C073901734A4 :1001A400938707887390073073504030B70700C0B7
:1001B400B7B700007390273067800000131525003F :1001B40073901734B7B70000739027309307000289
:1001C400B7170080938787DD3305F500032505F80D :1001C4007390373073503014678000001315250086
:1001D4006780000013152500B7170080938787DD1B :1001D400B7170080938787F33305F500032505F8E7
:1001E4003305F5002320B5F867800000232E00FEB8 :1001E4006780000013152500B7170080938787F3F5
:1001F40067800000232CA0FE67800000130101FF2C :1001F4003305F5002320B5F867800000130101FFE3
:1002040023261100EFF09FFEF32730347390371448 :1002040023261100EF00803EF32730347390371417
:10021400F327103473901714F327203473902714A2 :10021400F327103473901714F327203473902714A2
:10022400F3275010739017348320C1001301010188 :10022400F3275010739017348320C1001301010188
:1002340067800000F327303473903714F327203499 :1002340067800000F327303473903714F327203499
:100244007390271473101514F327501073901734F8 :100244007390271473101514F327501073901734F8
:100254009307001073B0071093D5350093F505107C :100254009307001073B0071093D5350093F505107C
:1002640073A00510B72700009387078073B0073089 :1002640073A00510B72700009387078073B0073089
:10027400B787000073A007306780000037070200CB :10027400B78700009387070873A0073067800000E2
:100284007320073017070000130787017310173412 :1002840037070200732007301707000013078701A0
:100294009306100083270500930600003707020029 :10029400731017349306100083270500930600009B
:1002A400733007301385060023A0F5006780000033 :1002A40037070200733007301385060023A0F500DA
:1002B4003707020073200730170700001307870170 :1002B400678000003707020073200730170700002B
:1002C40073101734930710002320B5009307000020 :1002C4001307870173101734930710002320B50018
:1002D400370702007330073013850700678000007A :1002D40093070000370702007330073013850700C7
:1002E400130101FD232611022324810223229102FA :1002E40067800000130101FD2326110223248102EB
:1002F40023202103232E3101232C4101232A5101E0 :1002F4002322910223202103232E3101232C4101A7
:10030400F327203463CE070213072000638EE7022D :10030400232A5101F327203463CE0700130720006A
:1003140013079000638EE716EFF05FEE8320C102AF :10031400638EE70413079000638EE724EFF01FEE6B
:100324000324810283244102032901028329C10198 :100324006F00000293F7F70F13077000639CE70256
:10033400032A8101832A410113010103678000001C :100334009307000273A047149307000873B0473073
:10034400EFF0DFEB6FF09FFDF3241034F32900305E :100344008320C10203248102832441020329010280
:10035400732430349376F4079357C44093F77700AB :100354008329C101032A8101832A41011301010375
:100364001307F002E39CE6FA13072000639EE710EC :1003640067800000EFF09FE96FF09FFDF3241034E5
:100374001359B4411355F4401375F501EFF01FE41C :10037400732A0030732430341377F4079357C4007E
:10038400930A0500135544411375F501EFF01FE37B :1003840013F677009306F002630AD700930630074A
:10039400130A0500135474401374F4019305C10047 :10039400630AD712EFF09FE66FF09FFA93072000ED
:1003A40013850A00EFF09FED631205029307C00165 :1003A400631EF6101359B4011355F4001375F501C7
:1003B40063E0270D13192900B70700809387475678 :1003B400EFF0DFE1930A0500135544011375F501CD
:1003C4003309F90083270900678007009385090032 :1003C400EFF0DFE093090500135474001374F40193
:1003D40013850400EFF01FE66FF05FF48327C1007C :1003D4009305C10013850A00EFF09FEA631205023A
:1003E400330AFA008325C10013050400EFF09FDEF1 :1003E4009307C00163E0270D13192900B7070080A4
:1003F40093050A0013850A00EFF09FEB631E0506C0 :1003F4009387076C3309F900832709006780070096
:1004040093844400739014346FF05FF18327C10028 :1004040093050A0013850400EFF0DFE26FF05FF359
:10041400334AFA006FF01FFD8327C100337AFA00D4 :100414008327C100B389F9008325C10013050400B3
:100424006FF05FFC8327C100336AFA006FF09FFB13 :10042400EFF05FDC9385090013850A00EFF09FE885
:100434008327C100E3D847FB138A07006FF09FFAB4 :10043400631E050693844400739014346FF05FF0D8
:100444008327C100E350FAFA138A07006FF09FF97B :100444008327C100B3C9F9006FF01FFD8327C100E2
:100454008327C100E3F847F9138A07006FF09FF878 :10045400B3F9F9006FF05FFC8327C100B3E9F90039
:100464008327C100E370FAF8138A07006FF09FF73F :100464006FF09FFB8327C100E3D837FB9389070014
:10047400EFF0DFD86FF09FEA93850900138504003D :100474006FF09FFA8327C100E3D0F9FA938907004C
:10048400EFF05FDB6FF09FE9EFF05FD76FF01FE9EC :100484006FF09FF98327C100E3F837F993890700D8
:1004940013051001EFF09FD2930710006312F502C9 :100494006FF09FF88327C100E3F0F9F89389070010
:1004A4001305A000EFF09FD11375F50FEFF09FD463 :1004A4006FF09FF7EFF09FD56FF09FE993050A0077
:1004B400F327103493874700739017346FF01FE6C7 :1004B40013850400EFF01FD86FF09FE8EFF01FD40E
:1004C400EFF0DFD26FF09FE5130101FF23248100D9 :1004C4006FF01FE893F73700130710006382E70605
:1004D40023229100170400001304C40897040000A9 :1004D400638C070213072000638CE70213073000C4
:1004E40093844408B38484402320210123261100EB :1004E4006380E70413574401B7170000938717C0CC
:1004F40093D42440130900006310990417040000E6 :1004F4006304F704B7170000938717C86302F7066D
:1005040013044406970400009384C405B384844010 :10050400EFF0DFCF6F00C003EFF05FCF6FF09FFD20
:10051400EFF05FB693D424401309000063189902E6 :100514009359F40093F9F901B33930016FF09FFC5A
:100524008320C100032481008324410003290100A6 :100524009359F40093F9F901B33930016FF09FFB4B
:1005340013010101678000008327040013091900D7 :10053400930910006FF01FFBEF00400C1309050036
:1005440013044400E78007006FF01FFB83270400B7 :100544006396090213557400930509001375F501A8
:100554001309190013044400E78007006FF01FFC1F :10055400EFF05FC993844400739014346FF05FDE4E
:10056400E0030080E80300807404008074040080C9 :10056400EF00400A130905006FF09FFDEFF01FC96B
:1005740010040080740400807404008074040080FB :100574006FF05FFD13051001EFF05FC51304050074
:1005840028040080740400807404008074040080D3 :100584001305A000EFF09FC4930405001305B00009
:100594001C040080740400807404008074040080CF :10059400EFF0DFC363020402930710006314F40452
:1005A40034040080740400807404008074040080A7 :1005A40013F5F40FEF000005F32710349387470089
:1005B4004404008074040080740400807404008087 :1005B400739017346FF0DFD893050500138504009A
:1005C4005404008074040080740400807404008067 :1005C400EF00C0049307000873A0473093070002AC
:0405D400640400803B :1005D40073B04714F327103493874700739017348C
:1005E4006FF01FD6EF0080006FF09FD5232E00FE22
:1005F40067800000232CA0FE67800000032500FE16
:1006040067800000032540FE678000009307C0FE5A
:100614001307F0FF23A0E7002324A0FE23A0B700C4
:1006240067800000130101FF23248100232291002D
:10063400170400001304C4089704000093844408BA
:10064400B3848440232021012326110093D4244021
:1006540013090000631099041704000013044406EE
:10066400970400009384C405B3848440EFF09FA0F2
:1006740093D4244013090000631899028320C10015
:100684000324810083244100032901001301010193
:100694006780000083270400130919001304440031
:1006A400E78007006FF01FFB83270400130919007C
:0C06B40013044400E78007006FF01FFCF7
:1006C000140400801C040080A8040080A80400809A
:1006D00044040080A8040080A8040080A8040080CE
:1006E0005C040080A8040080A8040080A8040080A6
:1006F00050040080A8040080A8040080A8040080A2
:1007000068040080A8040080A8040080A804008079
:1007100078040080A8040080A8040080A804008059
:1007200088040080A8040080A8040080A804008039
:080730009804008000000000A5
:040000058000000077 :040000058000000077
:00000001FF :00000001FF

View File

@ -3,8 +3,5 @@
#define OS_CALL 0xC0000000 #define OS_CALL 0xC0000000
#define DTB 0x81000000 #define DTB 0x81000000
#define SIM_STOP 0xFFFFFFFC
#define PUTC 0xFFFFFFF8
#endif #endif

View File

@ -0,0 +1,25 @@
#include "hal.h"
void stopSim(){
*((volatile uint32_t*) 0xFFFFFFFC) = 0;
}
void putC(char c){
*((volatile uint32_t*) 0xFFFFFFF8) = c;
}
uint32_t rdtime(){
return *((volatile uint32_t*) 0xFFFFFFE0);
}
uint32_t rdtimeh(){
return *((volatile uint32_t*) 0xFFFFFFE4);
}
void setMachineTimerCmp(uint32_t low, uint32_t high){
volatile uint32_t* base = (volatile uint32_t*) 0xFFFFFFE8;
base[1] = 0xffffffff;
base[0] = low;
base[1] = high;
}

View File

@ -0,0 +1,23 @@
#ifndef HAL_H
#define HAL_H
#include <stdint.h>
#define SBI_SET_TIMER 0
#define SBI_CONSOLE_PUTCHAR 1
#define SBI_CONSOLE_GETCHAR 2
#define SBI_CLEAR_IPI 3
#define SBI_SEND_IPI 4
#define SBI_REMOTE_FENCE_I 5
#define SBI_REMOTE_SFENCE_VMA 6
#define SBI_REMOTE_SFENCE_VMA_ASID 7
#define SBI_SHUTDOWN 8
void stopSim();
void putC(char c);
uint32_t rdtime();
uint32_t rdtimeh();
void setMachineTimerCmp(uint32_t low, uint32_t high);
#endif

View File

@ -1,38 +1,34 @@
#include <stdint.h> #include <stdint.h>
#include "riscv.h" #include "riscv.h"
#include "config.h" #include "config.h"
#include "hal.h"
extern const unsigned int _sp; extern const uint32_t _sp;
extern void trapEntry(); extern void trapEntry();
extern void emulationTrap(); extern void emulationTrap();
void init() { void init() {
unsigned int sp = (unsigned int) (&_sp); uint32_t sp = (uint32_t) (&_sp);
csr_write(mtvec, trapEntry); csr_write(mtvec, trapEntry);
csr_write(mscratch, sp -32*4); csr_write(mscratch, sp -32*4);
csr_write(mstatus, 0x0800); csr_write(mstatus, 0x0800 | MSTATUS_MPIE);
csr_write(mie, 0);
csr_write(mepc, OS_CALL); csr_write(mepc, OS_CALL);
csr_write(medeleg, MDELEG_INSTRUCTION_PAGE_FAULT | MDELEG_LOAD_PAGE_FAULT | MDELEG_STORE_PAGE_FAULT); csr_write(medeleg, MEDELEG_INSTRUCTION_PAGE_FAULT | MEDELEG_LOAD_PAGE_FAULT | MEDELEG_STORE_PAGE_FAULT);
csr_write(mideleg, MIDELEG_SUPERVISOR_TIMER);
csr_write(sbadaddr, 0); //Used to avoid simulation missmatch
} }
int readRegister(int id){ int readRegister(uint32_t id){
unsigned int sp = (unsigned int) (&_sp); unsigned int sp = (unsigned int) (&_sp);
return ((int*) sp)[id-32]; return ((int*) sp)[id-32];
} }
void writeRegister(int id, int value){ void writeRegister(uint32_t id, int value){
unsigned int sp = (unsigned int) (&_sp); uint32_t sp = (uint32_t) (&_sp);
((int*) sp)[id-32] = value; ((uint32_t*) sp)[id-32] = value;
} }
void stopSim(){
*((volatile int*) SIM_STOP) = 0;
}
void putC(char c){
*((volatile int*) PUTC) = c;
}
void redirectTrap(){ void redirectTrap(){
stopSim(); stopSim();
@ -50,7 +46,7 @@ void emulationTrapToSupervisorTrap(uint32_t sepc, uint32_t mstatus){
csr_clear(sstatus, MSTATUS_SPP); csr_clear(sstatus, MSTATUS_SPP);
csr_set(sstatus, (mstatus >> 3) & MSTATUS_SPP); csr_set(sstatus, (mstatus >> 3) & MSTATUS_SPP);
csr_clear(mstatus, MSTATUS_MPP); csr_clear(mstatus, MSTATUS_MPP);
csr_set(mstatus, 0x8000); csr_set(mstatus, 0x8000 | MSTATUS_MPIE);
} }
#define max(a,b) \ #define max(a,b) \
@ -67,9 +63,9 @@ void emulationTrapToSupervisorTrap(uint32_t sepc, uint32_t mstatus){
//Will modify MEPC //Will modify MEPC
int readWord(int address, int *data){ int32_t readWord(uint32_t address, int32_t *data){
int result, tmp; int32_t result, tmp;
int failed; int32_t failed;
__asm__ __volatile__ ( __asm__ __volatile__ (
" li %[tmp], 0x00020000\n" " li %[tmp], 0x00020000\n"
" csrs mstatus, %[tmp]\n" " csrs mstatus, %[tmp]\n"
@ -91,9 +87,9 @@ int readWord(int address, int *data){
} }
//Will modify MEPC //Will modify MEPC
int writeWord(uint32_t address, uint32_t data){ int32_t writeWord(uint32_t address, int32_t data){
int result, tmp; int32_t result, tmp;
int failed; int32_t failed;
__asm__ __volatile__ ( __asm__ __volatile__ (
" li %[tmp], 0x00020000\n" " li %[tmp], 0x00020000\n"
" csrs mstatus, %[tmp]\n" " csrs mstatus, %[tmp]\n"
@ -116,30 +112,33 @@ int writeWord(uint32_t address, uint32_t data){
void trap(){ void trap(){
int cause = csr_read(mcause); int32_t cause = csr_read(mcause);
if(cause < 0){ if(cause < 0){ //interrupt
redirectTrap(); switch(cause & 0xFF){
} else { case CAUSE_MACHINE_TIMER:{
csr_set(sip, MIP_STIP);
csr_clear(mie, MIE_MTIE);
}break;
default: redirectTrap(); break;
}
} else { //exception
switch(cause){ switch(cause){
case CAUSE_ILLEGAL_INSTRUCTION:{ case CAUSE_ILLEGAL_INSTRUCTION:{
int mepc = csr_read(mepc); uint32_t mepc = csr_read(mepc);
int mstatus = csr_read(mstatus); uint32_t mstatus = csr_read(mstatus);
int instruction = csr_read(mbadaddr); uint32_t instruction = csr_read(mbadaddr);
int opcode = instruction & 0x7F; uint32_t opcode = instruction & 0x7F;
int funct3 = (instruction >> 12) & 0x7; uint32_t funct3 = (instruction >> 12) & 0x7;
switch(opcode){ switch(opcode){
case 0x2F: //Atomic case 0x2F: //Atomic
switch(funct3){ switch(funct3){
case 0x2:{ case 0x2:{
int sel = instruction >> 27; uint32_t sel = instruction >> 27;
int addr = readRegister((instruction >> 15) & 0x1F); uint32_t addr = readRegister((instruction >> 15) & 0x1F);
int src = readRegister((instruction >> 20) & 0x1F); int32_t src = readRegister((instruction >> 20) & 0x1F);
int rd = (instruction >> 7) & 0x1F; uint32_t rd = (instruction >> 7) & 0x1F;
int readValue; int32_t readValue;
if(readWord(addr, &readValue)){ if(readWord(addr, &readValue)){
emulationTrapToSupervisorTrap(mepc, mstatus); emulationTrapToSupervisorTrap(mepc, mstatus);
return; return;
@ -148,6 +147,11 @@ void trap(){
switch(sel){ switch(sel){
case 0x0: writeValue = src + readValue; break; case 0x0: writeValue = src + readValue; break;
case 0x1: writeValue = src; break; case 0x1: writeValue = src; break;
//LR SC done in hardware (cheap), and require to keep track of context switches
// case 0x2:{ //LR
// }break;
// case 0x3:{ //SC
// }break;
case 0x4: writeValue = src ^ readValue; break; case 0x4: writeValue = src ^ readValue; break;
case 0xC: writeValue = src & readValue; break; case 0xC: writeValue = src & readValue; break;
case 0x8: writeValue = src | readValue; break; case 0x8: writeValue = src | readValue; break;
@ -165,14 +169,53 @@ void trap(){
csr_write(mepc, mepc + 4); csr_write(mepc, mepc + 4);
}break; }break;
default: redirectTrap(); break; default: redirectTrap(); break;
} } break;
case 0x73:{
//CSR
uint32_t input = (instruction & 0x4000) ? ((instruction >> 15) & 0x1F) : readRegister((instruction >> 15) & 0x1F);;
uint32_t clear, set;
uint32_t write;
switch (funct3 & 0x3) {
case 0: redirectTrap(); break;
case 1: clear = ~0; set = input; write = 1; break;
case 2: clear = 0; set = input; write = ((instruction >> 15) & 0x1F) != 0; break;
case 3: clear = input; set = 0; write = ((instruction >> 15) & 0x1F) != 0; break;
}
uint32_t csrAddress = instruction >> 20;
uint32_t old;
switch(csrAddress){
case RDTIME : old = rdtime(); break;
case RDTIMEH : old = rdtimeh(); break;
default: redirectTrap(); break;
}
if(write) {
uint32_t newValue = (old & ~clear) | set;
switch(csrAddress){
default: redirectTrap(); break;
}
}
writeRegister((instruction >> 7) & 0x1F, old);
csr_write(mepc, mepc + 4);
}break;
default: redirectTrap(); break;
} }
}break; }break;
case CAUSE_SCALL:{ case CAUSE_SCALL:{
int which = readRegister(17); uint32_t which = readRegister(17);
uint32_t a0 = readRegister(10);
uint32_t a1 = readRegister(11);
uint32_t a2 = readRegister(12);
switch(which){ switch(which){
case 1:{ case SBI_CONSOLE_PUTCHAR:{
putC(readRegister(10)); putC(a0);
csr_write(mepc, csr_read(mepc) + 4);
}break;
case SBI_SET_TIMER:{
setMachineTimerCmp(a0, a1);
csr_set(mie, MIE_MTIE);
csr_clear(sip, MIP_STIP);
csr_write(mepc, csr_read(mepc) + 4); csr_write(mepc, csr_read(mepc) + 4);
}break; }break;
default: stopSim(); break; default: stopSim(); break;

View File

@ -2,11 +2,16 @@
#define RISCV_H #define RISCV_H
#define CAUSE_ILLEGAL_INSTRUCTION 2 #define CAUSE_ILLEGAL_INSTRUCTION 2
#define CAUSE_MACHINE_TIMER 7
#define CAUSE_SCALL 9 #define CAUSE_SCALL 9
#define MDELEG_INSTRUCTION_PAGE_FAULT (1 << 12) #define MEDELEG_INSTRUCTION_PAGE_FAULT (1 << 12)
#define MDELEG_LOAD_PAGE_FAULT (1 << 13) #define MEDELEG_LOAD_PAGE_FAULT (1 << 13)
#define MDELEG_STORE_PAGE_FAULT (1 << 15) #define MEDELEG_STORE_PAGE_FAULT (1 << 15)
#define MIDELEG_SUPERVISOR_TIMER (1 << 5)
#define MIE_MTIE (1 << 7)
#define MIP_STIP (1 << 5)
#define MSTATUS_UIE 0x00000001 #define MSTATUS_UIE 0x00000001
#define MSTATUS_SIE 0x00000002 #define MSTATUS_SIE 0x00000002
@ -46,6 +51,13 @@
#define SSTATUS64_SD 0x8000000000000000 #define SSTATUS64_SD 0x8000000000000000
#define RDCYCLE 0xC00 //Read-only cycle Cycle counter for RDCYCLE instruction.
#define RDTIME 0xC01 //Read-only time Timer for RDTIME instruction.
#define RDINSTRET 0xC02 //Read-only instret Instructions-retired counter for RDINSTRET instruction.
#define RDCYCLEH 0xC80 //Read-only cycleh Upper 32 bits of cycle, RV32I only.
#define RDTIMEH 0xC81 //Read-only timeh Upper 32 bits of time, RV32I only.
#define RDINSTRETH 0xC82 //Read-only instreth Upper 32 bits of instret, RV32I only.
#define csr_swap(csr, val) \ #define csr_swap(csr, val) \
({ \ ({ \

View File

@ -39,8 +39,8 @@ _start:
call __libc_init_array call __libc_init_array
call init call init
la ra, done la ra, done
li a0, DTB li a0, 0
li a1, 0 li a1, DTB
mret mret
done: done:
j done j done

View File

@ -0,0 +1,47 @@
#include "riscv.h"
/*
.section .init
.globl readMemory
.type readMemory,@function
readWord:
csrr a4, mepc
li a2, MSTATUS_MPRV
csrs mstatus, a2
li a3, emulationTrap
csrw mepc, a3
lw a0, 0(a0)
li a3, trapEntry
csrw mepc, a3
csrc mstatus, a2
writeWord:
csrr a4, mepc
li a2, MSTATUS_MPRV
csrs mstatus, a2
li a3, emulationTrap
csrw mepc, a3
sw a1, 0(a0)
li a3, trapEntry
csrw mepc, a3
csrc mstatus, a2
*/
//Redirect trap to supervisor
/*
.section .init
.globl emulationTrap
.type emulationTrap,@function
emulationTrap:
li a0, MSTATUS_MPRV
csrc mstatus, a0
la sp, _sp
csrw sepc, a4
csrr a0, mcause
csrw scause, a0
csrr a0, mbadaddr
csrw sbadaddr, a0
call init
mret
*/

View File

@ -46,9 +46,8 @@ make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes LITEX=yes
Other commands (Memo): Other commands (Memo):
cp litex_default_configuration .config cp litex_default_configuration .config
ARCH=riscv CROSS_COMPILE=riscv64-unknown-elf- make -j`nproc` ARCH=riscv CROSS_COMPILE=riscv64-unknown-elf- make -j`nproc`; riscv64-unknown-elf-objcopy -O binary vmlinux vmlinux.bin
riscv64-unknown-elf-objcopy -O binary vmlinux vmlinux.bin riscv64-unknown-elf-objdump -S -d vmlinux > vmlinux.asm; split -b 1M vmlinux.asm
riscv64-unknown-elf-objdump -S -d vmlinux > vmlinux.asm
split -b 1M vmlinux.asm split -b 1M vmlinux.asm
dtc -O dtb -o rv32.dtb rv32.dts dtc -O dtb -o rv32.dtb rv32.dts
@ -56,10 +55,13 @@ make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes LITEX=yes
*/ */
//TODO have to check, look like supervisor can't get interrupt if the machine mod didn't delegated it, have to check exactly
object LinuxGen { object LinuxGen {
def configFull(litex : Boolean, withMmu : Boolean) = { def configFull(litex : Boolean, withMmu : Boolean) = {
val config = VexRiscvConfig( val config = VexRiscvConfig(
plugins = List( plugins = List(
new DummyFencePlugin(), //TODO should be removed for design with caches
new IBusSimplePlugin( new IBusSimplePlugin(
resetVector = 0x80000000l, resetVector = 0x80000000l,
cmdForkOnSecondStage = false, cmdForkOnSecondStage = false,
@ -102,6 +104,7 @@ object LinuxGen {
catchAddressMisaligned = true, catchAddressMisaligned = true,
catchAccessFault = true, catchAccessFault = true,
earlyInjection = false, earlyInjection = false,
atomicEntriesCount = 1,
memoryTranslatorPortConfig = withMmu generate MmuPortConfig( memoryTranslatorPortConfig = withMmu generate MmuPortConfig(
portTlbSize = 4 portTlbSize = 4
) )
@ -200,7 +203,8 @@ object LinuxGen {
) )
) )
if(withMmu) config.plugins += new MmuPlugin( if(withMmu) config.plugins += new MmuPlugin(
virtualRange = a => True, // virtualRange = a => True,
virtualRange = x => x(31 downto 24) =/= 0x81, //TODO It fix the DTB kernel access (workaround)
ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE || x(31 downto 28) === 0xF else x(31 downto 28) === 0xF), ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE || x(31 downto 28) === 0xF else x(31 downto 28) === 0xF),
allowUserIo = true allowUserIo = true
) )

View File

@ -781,7 +781,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
scause.interrupt := !hadException scause.interrupt := !hadException
scause.exceptionCode := trapCause scause.exceptionCode := trapCause
sepc := mepcCaptureStage.input(PC) sepc := mepcCaptureStage.input(PC)
if (exceptionPortCtrl != null) { if (exceptionPortCtrl != null) when(hadException){
stval := exceptionPortCtrl.exceptionContext.badAddr stval := exceptionPortCtrl.exceptionContext.badAddr
} }
} }
@ -793,7 +793,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
mcause.interrupt := !hadException mcause.interrupt := !hadException
mcause.exceptionCode := trapCause mcause.exceptionCode := trapCause
mepc := mepcCaptureStage.input(PC) mepc := mepcCaptureStage.input(PC)
if(exceptionPortCtrl != null) { if(exceptionPortCtrl != null) when(hadException){
mtval := exceptionPortCtrl.exceptionContext.badAddr mtval := exceptionPortCtrl.exceptionContext.badAddr
} }
} }
@ -872,7 +872,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
if(selfException != null) { if(selfException != null) {
selfException.valid := False selfException.valid := False
selfException.code.assignDontCare() selfException.code.assignDontCare()
selfException.badAddr := 0 selfException.badAddr := input(INSTRUCTION).asUInt
if(catchIllegalAccess) when(illegalAccess || illegalInstruction){ if(catchIllegalAccess) when(illegalAccess || illegalInstruction){
selfException.valid := True selfException.valid := True
selfException.code := 2 selfException.code := 2

View File

@ -205,17 +205,21 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
earlyInjection : Boolean = false, /*, idempotentRegions : (UInt) => Bool = (x) => False*/ earlyInjection : Boolean = false, /*, idempotentRegions : (UInt) => Bool = (x) => False*/
emitCmdInMemoryStage : Boolean = false, emitCmdInMemoryStage : Boolean = false,
onlyLoadWords : Boolean = false, onlyLoadWords : Boolean = false,
atomicEntriesCount : Int = 0,
memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService { memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService {
var dBus : DBusSimpleBus = null var dBus : DBusSimpleBus = null
assert(!(emitCmdInMemoryStage && earlyInjection)) assert(!(emitCmdInMemoryStage && earlyInjection))
def genAtomic = atomicEntriesCount != 0
object MEMORY_ENABLE extends Stageable(Bool) object MEMORY_ENABLE extends Stageable(Bool)
object MEMORY_READ_DATA extends Stageable(Bits(32 bits)) object MEMORY_READ_DATA extends Stageable(Bits(32 bits))
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits)) object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
object ALIGNEMENT_FAULT extends Stageable(Bool) object ALIGNEMENT_FAULT extends Stageable(Bool)
object MMU_FAULT extends Stageable(Bool) object MMU_FAULT extends Stageable(Bool)
object MMU_RSP extends Stageable(MemoryTranslatorRsp()) object MMU_RSP extends Stageable(MemoryTranslatorRsp())
object MEMORY_ATOMIC extends Stageable(Bool)
object ATOMIC_HIT extends Stageable(Bool)
object MEMORY_STORE extends Stageable(Bool)
var memoryExceptionPort : Flow[ExceptionCause] = null var memoryExceptionPort : Flow[ExceptionCause] = null
var rspStage : Stage = null var rspStage : Stage = null
@ -248,12 +252,14 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
SRC2_CTRL -> Src2CtrlEnum.IMI, SRC2_CTRL -> Src2CtrlEnum.IMI,
REGFILE_WRITE_VALID -> True, REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False, BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> Bool(earlyInjection) BYPASSABLE_MEMORY_STAGE -> Bool(earlyInjection),
MEMORY_STORE -> False
) ++ (if(catchAccessFault || catchAddressMisaligned) List(HAS_SIDE_EFFECT -> True) else Nil) ) ++ (if(catchAccessFault || catchAddressMisaligned) List(HAS_SIDE_EFFECT -> True) else Nil)
val storeActions = stdActions ++ List( val storeActions = stdActions ++ List(
SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_CTRL -> Src2CtrlEnum.IMS,
RS2_USE -> True RS2_USE -> True,
MEMORY_STORE -> True
) )
decoderService.addDefault(MEMORY_ENABLE, False) decoderService.addDefault(MEMORY_ENABLE, False)
@ -263,6 +269,29 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
) )
if(genAtomic){
List(LB, LH, LW, LBU, LHU, LWU, SB, SH, SW).foreach(e =>
decoderService.add(e, Seq(MEMORY_ATOMIC -> False))
)
decoderService.add(
key = LR,
values = loadActions.filter(_._1 != SRC2_CTRL) ++ Seq(
SRC2_CTRL -> Src2CtrlEnum.RS,
MEMORY_ATOMIC -> True
)
)
//TODO probably the cached implemention of SC is bugy (address calculation)
decoderService.add(
key = SC,
values = storeActions.filter(_._1 != SRC2_CTRL) ++ Seq(
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> False,
MEMORY_ATOMIC -> True
)
)
}
rspStage = if(stages.last == execute) execute else (if(emitCmdInMemoryStage) writeBack else memory) rspStage = if(stages.last == execute) execute else (if(emitCmdInMemoryStage) writeBack else memory)
if(catchSomething) { if(catchSomething) {
@ -300,7 +329,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
skipCmd setWhen(input(ALIGNEMENT_FAULT)) skipCmd setWhen(input(ALIGNEMENT_FAULT))
dBus.cmd.valid := arbitration.isValid && input(MEMORY_ENABLE) && !arbitration.isStuckByOthers && !arbitration.isFlushed && !skipCmd && !cmdSent dBus.cmd.valid := arbitration.isValid && input(MEMORY_ENABLE) && !arbitration.isStuckByOthers && !arbitration.isFlushed && !skipCmd && !cmdSent
dBus.cmd.wr := input(INSTRUCTION)(5) dBus.cmd.wr := input(MEMORY_STORE)
dBus.cmd.size := input(INSTRUCTION)(13 downto 12).asUInt dBus.cmd.size := input(INSTRUCTION)(13 downto 12).asUInt
dBus.cmd.payload.data := dBus.cmd.size.mux ( dBus.cmd.payload.data := dBus.cmd.size.mux (
U(0) -> input(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0), U(0) -> input(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0),
@ -332,7 +361,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
dBus.cmd.address := mmuBus.rsp.physicalAddress dBus.cmd.address := mmuBus.rsp.physicalAddress
//do not emit memory request if MMU refilling //do not emit memory request if MMU refilling
insert(MMU_FAULT) := input(MMU_RSP).exception || (!input(MMU_RSP).allowWrite && input(INSTRUCTION)(5)) || (!input(MMU_RSP).allowRead && !input(INSTRUCTION)(5)) || (!input(MMU_RSP).allowUser && privilegeService.isUser()) insert(MMU_FAULT) := input(MMU_RSP).exception || (!input(MMU_RSP).allowWrite && input(MEMORY_STORE)) || (!input(MMU_RSP).allowRead && !input(MEMORY_STORE)) || (!input(MMU_RSP).allowUser && privilegeService.isUser())
skipCmd.setWhen(input(MMU_FAULT) || input(MMU_RSP).refilling) skipCmd.setWhen(input(MMU_FAULT) || input(MMU_RSP).refilling)
insert(MMU_RSP) := mmuBus.rsp insert(MMU_RSP) := mmuBus.rsp
@ -341,6 +370,40 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
val mmuLess = (mmuBus == null) generate new Area{ val mmuLess = (mmuBus == null) generate new Area{
dBus.cmd.address := input(SRC_ADD).asUInt dBus.cmd.address := input(SRC_ADD).asUInt
} }
val atomic = genAtomic generate new Area{
val address = input(SRC1).asUInt //TODO could avoid 32 muxes if SRC_ADD can be disabled
case class AtomicEntry() extends Bundle{
val valid = Bool()
val address = UInt(32 bits)
def init: this.type ={
valid init(False)
this
}
}
val entries = Vec(Reg(AtomicEntry()).init, atomicEntriesCount)
val entriesAllocCounter = Counter(atomicEntriesCount)
insert(ATOMIC_HIT) := entries.map(e => e.valid && e.address === address).orR
when(arbitration.isValid && input(MEMORY_ENABLE) && input(MEMORY_ATOMIC) && !input(MEMORY_STORE)){
entries(entriesAllocCounter).valid := True
entries(entriesAllocCounter).address := address
when(!arbitration.isStuck){
entriesAllocCounter.increment()
}
}
when(service(classOf[IContextSwitching]).isContextSwitching){
entries.foreach(_.valid := False)
}
when(input(MEMORY_STORE) && input(MEMORY_ATOMIC) && !input(ATOMIC_HIT)){
skipCmd := True
}
when(input(MEMORY_ATOMIC)){
mmuBus.cmd.virtualAddress := address
}
}
} }
//Collect dBus.rsp read responses //Collect dBus.rsp read responses
@ -349,20 +412,21 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
insert(MEMORY_READ_DATA) := dBus.rsp.data insert(MEMORY_READ_DATA) := dBus.rsp.data
arbitration.haltItself setWhen(arbitration.isValid && input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && !dBus.rsp.ready)
arbitration.haltItself setWhen(arbitration.isValid && input(MEMORY_ENABLE) && !input(MEMORY_STORE) && !dBus.rsp.ready)
if(catchSomething) { if(catchSomething) {
memoryExceptionPort.valid := False memoryExceptionPort.valid := False
memoryExceptionPort.code.assignDontCare() memoryExceptionPort.code.assignDontCare()
memoryExceptionPort.badAddr := input(REGFILE_WRITE_DATA).asUInt memoryExceptionPort.badAddr := input(REGFILE_WRITE_DATA).asUInt
if(catchAccessFault) when(dBus.rsp.ready && dBus.rsp.error && !input(INSTRUCTION)(5)) { if(catchAccessFault) when(dBus.rsp.ready && dBus.rsp.error && !input(MEMORY_STORE)) {
memoryExceptionPort.valid := True memoryExceptionPort.valid := True
memoryExceptionPort.code := 5 memoryExceptionPort.code := 5
} }
if(catchAddressMisaligned) when(input(ALIGNEMENT_FAULT)){ if(catchAddressMisaligned) when(input(ALIGNEMENT_FAULT)){
memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(6) | U(4)).resized memoryExceptionPort.code := (input(MEMORY_STORE) ? U(6) | U(4)).resized
memoryExceptionPort.valid := True memoryExceptionPort.valid := True
} }
@ -375,7 +439,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
memoryExceptionPort.valid := False memoryExceptionPort.valid := False
} elsewhen(input(MMU_FAULT)) { } elsewhen(input(MMU_FAULT)) {
memoryExceptionPort.valid := True memoryExceptionPort.valid := True
memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(15) | U(13)).resized memoryExceptionPort.code := (input(MEMORY_STORE) ? U(15) | U(13)).resized
} }
arbitration.flushAll setWhen(redoBranch.valid) arbitration.flushAll setWhen(redoBranch.valid)
@ -414,10 +478,15 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
when(arbitration.isValid && input(MEMORY_ENABLE)) { when(arbitration.isValid && input(MEMORY_ENABLE)) {
output(REGFILE_WRITE_DATA) := (if(!onlyLoadWords) rspFormated else input(MEMORY_READ_DATA)) output(REGFILE_WRITE_DATA) := (if(!onlyLoadWords) rspFormated else input(MEMORY_READ_DATA))
if(genAtomic){
when(input(MEMORY_ATOMIC) && input(MEMORY_STORE)){
output(REGFILE_WRITE_DATA) := (!input(ATOMIC_HIT)).asBits.resized
}
}
} }
if(!earlyInjection && !emitCmdInMemoryStage && config.withWriteBackStage) if(!earlyInjection && !emitCmdInMemoryStage && config.withWriteBackStage)
assert(!(arbitration.isValid && input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && arbitration.isStuck),"DBusSimplePlugin doesn't allow writeback stage stall when read happend") assert(!(arbitration.isValid && input(MEMORY_ENABLE) && !input(MEMORY_STORE) && arbitration.isStuck),"DBusSimplePlugin doesn't allow writeback stage stall when read happend")
//formal //formal
insert(FORMAL_MEM_RDATA) := input(MEMORY_READ_DATA) insert(FORMAL_MEM_RDATA) := input(MEMORY_READ_DATA)

View File

@ -365,7 +365,14 @@ public:
}; };
}; };
#define RESERVED_ENTRY_COUNT 1
struct ReservedEntry{
bool valid;
uint32_t address;
};
ReservedEntry reservedEntries[RESERVED_ENTRY_COUNT];
int reservedEntriesPtr = 0;
RiscvGolden() { RiscvGolden() {
pc = 0x80000000; pc = 0x80000000;
@ -373,6 +380,9 @@ public:
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
regs[i] = 0; regs[i] = 0;
for(int i = 0;i < RESERVED_ENTRY_COUNT;i++) reservedEntries[i].valid = false;
status.raw = 0; status.raw = 0;
ie.raw = 0; ie.raw = 0;
mtvec.raw = 0x80000020; mtvec.raw = 0x80000020;
@ -412,9 +422,10 @@ public:
virtual void dWrite(int32_t address, int32_t size, uint32_t data) = 0; virtual void dWrite(int32_t address, int32_t size, uint32_t data) = 0;
enum AccessKind {READ,WRITE,EXECUTE}; enum AccessKind {READ,WRITE,EXECUTE};
virtual bool isMmuRegion(uint32_t v) = 0;
bool v2p(uint32_t v, uint32_t *p, AccessKind kind){ bool v2p(uint32_t v, uint32_t *p, AccessKind kind){
uint32_t effectivePrivilege = status.mprv && kind != EXECUTE ? status.mpp : privilege; uint32_t effectivePrivilege = status.mprv && kind != EXECUTE ? status.mpp : privilege;
if(effectivePrivilege == 3 || satp.mode == 0){ if(effectivePrivilege == 3 || satp.mode == 0 || !isMmuRegion(v)){
*p = v; *p = v;
} else { } else {
Tlb tlb; Tlb tlb;
@ -440,7 +451,7 @@ public:
} }
void trap(bool interrupt,int32_t cause) { void trap(bool interrupt,int32_t cause) {
trap(interrupt, cause, true, 0); trap(interrupt, cause, false, 0);
} }
void trap(bool interrupt,int32_t cause, uint32_t value) { void trap(bool interrupt,int32_t cause, uint32_t value) {
trap(interrupt, cause, true, value); trap(interrupt, cause, true, value);
@ -452,6 +463,7 @@ public:
cout << hex << " a7=0x" << regs[17] << " a0=0x" << regs[10] << " a1=0x" << regs[11] << " a2=0x" << regs[12] << dec << endl; cout << hex << " a7=0x" << regs[17] << " a0=0x" << regs[10] << " a1=0x" << regs[11] << " a2=0x" << regs[12] << dec << endl;
} }
#endif #endif
for(int i = 0;i < RESERVED_ENTRY_COUNT;i++) reservedEntries[i].valid = false;
//Check leguality of the interrupt //Check leguality of the interrupt
if(interrupt) { if(interrupt) {
bool hit = false; bool hit = false;
@ -673,7 +685,7 @@ public:
if (pc & 2) { if (pc & 2) {
if(v2p(pc - 2, &pAddr, EXECUTE)){ trap(0, 12, pc - 2); return; } if(v2p(pc - 2, &pAddr, EXECUTE)){ trap(0, 12, pc - 2); return; }
if(iRead(pAddr, &i)){ if(iRead(pAddr, &i)){
trap(0, 1); trap(0, 1, 0);
return; return;
} }
i >>= 16; i >>= 16;
@ -681,7 +693,7 @@ public:
uint32_t u32Buf; uint32_t u32Buf;
if(v2p(pc + 2, &pAddr, EXECUTE)){ trap(0, 12, pc + 2); return; } if(v2p(pc + 2, &pAddr, EXECUTE)){ trap(0, 12, pc + 2); return; }
if(iRead(pAddr, &u32Buf)){ if(iRead(pAddr, &u32Buf)){
trap(0, 1); trap(0, 1, 0);
return; return;
} }
i |= u32Buf << 16; i |= u32Buf << 16;
@ -689,7 +701,7 @@ public:
} else { } else {
if(v2p(pc, &pAddr, EXECUTE)){ trap(0, 12, pc); return; } if(v2p(pc, &pAddr, EXECUTE)){ trap(0, 12, pc); return; }
if(iRead(pAddr, &i)){ if(iRead(pAddr, &i)){
trap(0, 1); trap(0, 1, 0);
return; return;
} }
} }
@ -855,6 +867,56 @@ public:
} }
break; break;
} }
case 0x2F: // Atomic stuff
switch(i32_func3){
case 0x2:
switch(iBits(27,5)){
case 0x2:{ //LR
uint32_t data;
uint32_t address = i32_rs1;
if(address & 3){
trap(0, 4, address);
} else {
if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; }
if(dRead(pAddr, 4, &data)){
trap(0, 5, address);
} else {
reservedEntries[reservedEntriesPtr].valid = true;
reservedEntries[reservedEntriesPtr].address = address;
reservedEntriesPtr = (reservedEntriesPtr + 1) % RESERVED_ENTRY_COUNT;
rfWrite(rd32, data);
pcWrite(pc + 4);
}
}
} break;
case 0x3:{ //SC
uint32_t address = i32_rs1;
if(address & 3){
trap(0, 6, address);
} else {
if(v2p(address, &pAddr, WRITE)){ trap(0, 15, address); return; }
bool hit = false;
for(int i = 0;i < RESERVED_ENTRY_COUNT;i++) hit |= reservedEntries[i].valid && reservedEntries[i].address == address;
rfWrite(rd32, !hit);
if(hit){
dWrite(pAddr, 4, i32_rs2);
}
pcWrite(pc + 4);
}
} break;
default: ilegalInstruction(); break;
}
break;
default: ilegalInstruction(); break;
}
break;
case 0x0f:
if(i == 0x100F || (i & 0xF00FFFFF) == 0x000F){ // FENCE FENCE.I
pcWrite(pc + 4);
} else{
ilegalInstruction();
}
break;
default: ilegalInstruction(); break; default: ilegalInstruction(); break;
} }
} else { } else {
@ -868,7 +930,7 @@ public:
} else { } else {
if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; }
if(dRead(address, 4, &data)) { if(dRead(address, 4, &data)) {
trap(1, 5, address); trap(0, 5, address);
} else { } else {
rfWrite(i16_addr2, data); pcWrite(pc + 2); rfWrite(i16_addr2, data); pcWrite(pc + 2);
} }
@ -917,7 +979,7 @@ public:
} else { } else {
if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; }
if(dRead(pAddr, 4, &data)){ if(dRead(pAddr, 4, &data)){
trap(1, 5, address); trap(0, 5, address);
} else { } else {
rfWrite(rd32, data); pcWrite(pc + 2); rfWrite(rd32, data); pcWrite(pc + 2);
} }
@ -1032,6 +1094,9 @@ public:
virtual void fail() { ws->fail(); } virtual void fail() { ws->fail(); }
virtual bool isMmuRegion(uint32_t v) {return ws->isMmuRegion(v);}
bool rfWriteValid; bool rfWriteValid;
int32_t rfWriteAddress; int32_t rfWriteAddress;
int32_t rfWriteData; int32_t rfWriteData;
@ -1172,7 +1237,7 @@ public:
} }
virtual bool isPerifRegion(uint32_t addr) { return false; } virtual bool isPerifRegion(uint32_t addr) { return false; }
virtual bool isMmuRegion(uint32_t addr) { return true;}
virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error) { virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error) {
if(addr % 4 != 0) { if(addr % 4 != 0) {
cout << "Warning, unaligned IBusAccess : " << addr << endl; cout << "Warning, unaligned IBusAccess : " << addr << endl;
@ -1186,7 +1251,7 @@ public:
} }
virtual bool isDBusCheckedRegion(uint32_t address){ return isPerifRegion(address);}
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) { virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) {
assertEq(addr % (1 << size), 0); assertEq(addr % (1 << size), 0);
if(isPerifRegion(addr)){ if(isPerifRegion(addr)){
@ -1448,7 +1513,7 @@ public:
(rfWriteValid && (rfWriteAddress!= riscvRef.rfWriteAddress || rfWriteData!= riscvRef.rfWriteData))){ (rfWriteValid && (rfWriteAddress!= riscvRef.rfWriteAddress || rfWriteData!= riscvRef.rfWriteData))){
cout << "regFile write missmatch :" << endl; cout << "regFile write missmatch :" << endl;
if(rfWriteValid) cout << " REF: RF[" << riscvRef.rfWriteAddress << "] = 0x" << hex << riscvRef.rfWriteData << dec << endl; if(rfWriteValid) cout << " REF: RF[" << riscvRef.rfWriteAddress << "] = 0x" << hex << riscvRef.rfWriteData << dec << endl;
if(rfWriteValid) cout << " RTL: RF[" << rfWriteAddress << "] = 0x" << hex << rfWriteData << dec << endl; if(rfWriteValid) cout << " DUT: RF[" << rfWriteAddress << "] = 0x" << hex << rfWriteData << dec << endl;
fail(); fail();
} }
} }
@ -1566,7 +1631,7 @@ public:
break; break;
#endif #endif
case 0xF00FFF48u: mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data;break; case 0xF00FFF48u: mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data;break;
case 0xF00FFF4Cu: mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); /*cout << "mTimeCmp <= " << mTimeCmp << endl; */break; case 0xF00FFF4Cu: mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); break;
} }
}else{ }else{
switch(addr){ switch(addr){
@ -2882,19 +2947,25 @@ public:
} }
virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xB0000000 || (addr & 0xF0000000) == 0xE0000000;} virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xB0000000 || (addr & 0xE0000000) == 0xE0000000;}
virtual bool isMmuRegion(uint32_t addr) { return (addr & 0xFF000000) != 0x81000000;}
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) { virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) {
switch(addr){ if(isPerifRegion(addr)) switch(addr){
//TODO Emulate peripherals here //TODO Emulate peripherals here
case 0xFFFFFFFC: fail(); break; //Simulation end case 0xFFFFFFE0: if(wr) fail(); else *data = mTime; break;
case 0xFFFFFFE4: if(wr) fail(); else *data = mTime >> 32; break;
case 0xFFFFFFE8: if(wr) mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data; else *data = mTimeCmp; break;
case 0xFFFFFFEC: if(wr) mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); else *data = mTimeCmp >> 32; break;
case 0xFFFFFFF8: case 0xFFFFFFF8:
if(wr){ if(wr){
cout << (char)*data; cout << (char)*data;
logTraces << (char)*data; logTraces << (char)*data;
} logTraces.flush();
} else fail();
break; break;
case 0xFFFFFFFC: fail(); break; //Simulation end
default: cout << "Unmapped peripheral access : addr=0x" << hex << addr << " wr=" << wr << " mask=0x" << mask << " data=0x" << data << dec << endl; fail(); break;
} }
Workspace::dBusAccess(addr,wr,size,mask,data,error); Workspace::dBusAccess(addr,wr,size,mask,data,error);
@ -3180,7 +3251,6 @@ int main(int argc, char **argv, char **env) {
->setDStall(false) ->setDStall(false)
->bootAt(0x80000000) ->bootAt(0x80000000)
->run(0); ->run(0);
return 1;
#endif #endif
// #ifdef MMU // #ifdef MMU

View File

@ -1,4 +1,4 @@
DEBUG?=yes DEBUG?=no
IBUS?=CACHED IBUS?=CACHED
IBUS_TC?=no IBUS_TC?=no