Closed stffrdhrn closed 3 years ago
Find the test newlib binaries and vcd files attached.
The file *mtspr.sw*
is case 1, 0x300c
is the pc address where the issue happens
The file *mtspr.mtspr*
is case 2, 0x2fb4
is the pc address where the issue happens
I was able to fix case 2 with patch https://github.com/stffrdhrn/mor1kx/commit/8d7b044e0675817bae0546579e66cf894c372259
The test still fails due to case 1.
We can see itlb_trans_we
goes high indicating a successful write
We can see that after the invalidate the cpu_req_i
signal is not high during the WRITE
phase causing the dcache to miss the write`
To test this I am using fusesoc
with iverilog a fusesoc.conf
as:
[library.elf-loader]
location = /home/shorne/work/openrisc/local-cores/elf-loader
sync-uri = /home/shorne/work/openrisc/local-cores/elf-loader/
sync-type = local
auto-sync = true
[library.intgen]
location = fusesoc_libraries/intgen
sync-uri = https://github.com/stffrdhrn/intgen.git
sync-type = git
auto-sync = true
[library.mor1kx-generic]
location = /home/shorne/work/openrisc/local-cores/mor1kx-generic
sync-uri = /home/shorne/work/openrisc/local-cores/mor1kx-generic
sync-type = local
auto-sync = true
[library.mor1kx]
location = /home/shorne/work/openrisc/local-cores/mor1kx
sync-uri = /home/shorne/work/openrisc/local-cores/mor1kx
sync-type = local
auto-sync = true
Then running fusesoc: fusesoc run --target mor1kx_tb mor1kx-generic --elf_load /home/shorne/work/openrisc/or1k-tests/native/build/or1k/or1k-mmu --vcd
The or1k-mmu
version is the same as or1k-mmu.fail.0x2fb4.mtspr.mtspr.elf.gz
uploaded earlier.
The investigation so far:
PC 0x2b10 store FFFF FFFE into the dcache at way location 0x7ed
PC 0x2f1c store 0041 6000 into the dcache at way location 0x7ed - this fails
PC 0x2f68 load FFFF FFFE from way location 0x7ed - this is written to the IMMU and causes a failure
I have converted to or1k-tests to use inline calls to
mtspr()
andmfspr()
. This causes failures in the following cases inor1k-mmu
.See: https://github.com/openrisc/or1k-tests/commit/32f0ba26bd581ca8cf7d3b4c46a53e2509acdcce
Case 1 - this happens when 1 nop after mtspr.
The first case is where we have
mtspr
following by al.sw
, this causes an invalidate to be sent to the dcache. At the same time as the write operation. The write fails.Case 2 - this happens with 0 nop after mtspr.
The mtspr followed by mtspr causes the second write to OR1K_SPR_IMMU_ITLBW_TR_ADDR to be lost.
Workaround
Adding 2
l.nop
s aftermtspr
fixes the issue. Below in case 1 thel.sw
came before thel.nop
due to some optimizations from gcc, to fix it theasm
forl.mtspr
contains the nop inline i.e.l.mtspr %0, %1, 0; l.nop; l.nop
. But the below is without the fix exposing the CPU issue, but it should still work.Trace case1 - dcache spr mix with l.sw fails
Trace case2 - immu spr fails
When we have a l.mtspr writing to the IMMU followed by another l.mtspr writing to the IMMU the second spr write may fail.