Fix inverted sc return code (argh) and lr/sc tests which also assumed the sc code was inverted
This commit is contained in:
parent
4090f4eb24
commit
66965ac073
|
@ -1036,7 +1036,8 @@ always @ (*) begin
|
||||||
m_result = bus_rdata_d;
|
m_result = bus_rdata_d;
|
||||||
end else if (|EXTENSION_A && xm_memop == MEMOP_SC_W) begin
|
end else if (|EXTENSION_A && xm_memop == MEMOP_SC_W) begin
|
||||||
// sc.w may fail due to negative response from either local or global monitor.
|
// sc.w may fail due to negative response from either local or global monitor.
|
||||||
m_result = {31'h0, mw_local_exclusive_reserved && bus_dph_exokay_d};
|
// Note the polarity of the result: 0 for success, 1 for failure.
|
||||||
|
m_result = {31'h0, !(mw_local_exclusive_reserved && bus_dph_exokay_d)};
|
||||||
end else if (xm_memop != MEMOP_NONE && xm_memop != MEMOP_AMO) begin
|
end else if (xm_memop != MEMOP_NONE && xm_memop != MEMOP_AMO) begin
|
||||||
m_result = m_rdata_pick_sext;
|
m_result = m_rdata_pick_sext;
|
||||||
end else if (MUL_FAST && m_fast_mul_result_vld) begin
|
end else if (MUL_FAST && m_fast_mul_result_vld) begin
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
/*EXPECTED-OUTPUT***************************************************************
|
/*EXPECTED-OUTPUT***************************************************************
|
||||||
|
|
||||||
lr -> mv: 12345678
|
lr -> mv: 12345678
|
||||||
lr -> sc: sc returned 1
|
lr -> sc: sc returned 0
|
||||||
scratch[1] = deadbeef
|
scratch[1] = deadbeef
|
||||||
sc -> mv: sc returned 0
|
sc -> mv: sc returned 1
|
||||||
scratch[0] = 5678a5a5
|
scratch[0] = 5678a5a5
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
Failed load, suppressed store
|
Failed load, suppressed store
|
||||||
-> exception, mcause = 5
|
-> exception, mcause = 5
|
||||||
exception instr: 100627af
|
exception instr: 100627af
|
||||||
sc.w result: 0
|
sc.w result: 1
|
||||||
Good load, failed store
|
Good load, failed store
|
||||||
-> exception, mcause = 7
|
-> exception, mcause = 7
|
||||||
exception instr: 18a5a52f
|
exception instr: 18a5a52f
|
||||||
sc.w result: 123
|
sc.w result: 123
|
||||||
Repeated failed store
|
Repeated failed store
|
||||||
sc.w result: 0
|
sc.w result: 1
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ int main() {
|
||||||
// suppressing the sc.w.
|
// suppressing the sc.w.
|
||||||
tb_puts("Failed load, suppressed store\n");
|
tb_puts("Failed load, suppressed store\n");
|
||||||
sc_result = do_lr_sc(123, bad_addr, bad_addr);
|
sc_result = do_lr_sc(123, bad_addr, bad_addr);
|
||||||
// Failing sc.w must write 0 to the success register.
|
// Failing sc.w must write 1 to the success register.
|
||||||
tb_printf("sc.w result: %u\n", sc_result);
|
tb_printf("sc.w result: %u\n", sc_result);
|
||||||
|
|
||||||
// This time the sc.w should fault, after the successful lr.w.
|
// This time the sc.w should fault, after the successful lr.w.
|
||||||
|
@ -58,7 +58,7 @@ int main() {
|
||||||
"sc.w %0, zero, (%1)\n"
|
"sc.w %0, zero, (%1)\n"
|
||||||
: "+r" (sc_result) : "r" (bad_addr)
|
: "+r" (sc_result) : "r" (bad_addr)
|
||||||
);
|
);
|
||||||
// Failing sc.w must write 0 to result register.
|
// Failing sc.w must write 1 to result register.
|
||||||
tb_printf("sc.w result: %u\n", sc_result);
|
tb_printf("sc.w result: %u\n", sc_result);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -17,7 +17,7 @@ OK
|
||||||
volatile uint32_t scratch[2];
|
volatile uint32_t scratch[2];
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
uint32_t load_result, success;
|
uint32_t load_result, sc_fail;
|
||||||
tb_puts("Test 1: lr.w -> nop -> sc.w\n");
|
tb_puts("Test 1: lr.w -> nop -> sc.w\n");
|
||||||
scratch[0] = 0x1234;
|
scratch[0] = 0x1234;
|
||||||
asm volatile (
|
asm volatile (
|
||||||
|
@ -26,12 +26,12 @@ int main() {
|
||||||
"sc.w %1, %3, (%2)\n"
|
"sc.w %1, %3, (%2)\n"
|
||||||
// Note the "&": this marks an "earlyclobber" operand, telling GCC it can't
|
// Note the "&": this marks an "earlyclobber" operand, telling GCC it can't
|
||||||
// allocate this output to an input register. (particularly, %0 to %2)
|
// allocate this output to an input register. (particularly, %0 to %2)
|
||||||
: "=&r" (load_result), "=r" (success)
|
: "=&r" (load_result), "=r" (sc_fail)
|
||||||
: "r" (&scratch[0]), "r" (0x5678)
|
: "r" (&scratch[0]), "r" (0x5678)
|
||||||
);
|
);
|
||||||
tb_assert(load_result == 0x1234, "Bad load result %08x\n", load_result);
|
tb_assert(load_result == 0x1234, "Bad load result %08x\n", load_result);
|
||||||
tb_assert(scratch[0] == 0x5678, "Store didn't write memory\n");
|
tb_assert(scratch[0] == 0x5678, "Store didn't write memory\n");
|
||||||
tb_assert(success == 1, "Should report success\n");
|
tb_assert(sc_fail == 0, "Should report success\n");
|
||||||
tb_puts("OK\n");
|
tb_puts("OK\n");
|
||||||
|
|
||||||
tb_puts("Test 2: lr.w -> sc.w\n");
|
tb_puts("Test 2: lr.w -> sc.w\n");
|
||||||
|
@ -39,23 +39,23 @@ int main() {
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"lr.w %0, (%2)\n"
|
"lr.w %0, (%2)\n"
|
||||||
"sc.w %1, %3, (%2)\n"
|
"sc.w %1, %3, (%2)\n"
|
||||||
: "=&r" (load_result), "=r" (success)
|
: "=&r" (load_result), "=r" (sc_fail)
|
||||||
: "r" (&scratch[0]), "r" (0xa5a5)
|
: "r" (&scratch[0]), "r" (0xa5a5)
|
||||||
);
|
);
|
||||||
tb_assert(load_result == 0xabcd, "Bad load result %08x\n", load_result);
|
tb_assert(load_result == 0xabcd, "Bad load result %08x\n", load_result);
|
||||||
tb_assert(scratch[0] == 0xa5a5, "Store didn't write memory\n");
|
tb_assert(scratch[0] == 0xa5a5, "Store didn't write memory\n");
|
||||||
tb_assert(success == 1, "Should report success\n");
|
tb_assert(sc_fail == 0, "Should report success\n");
|
||||||
tb_puts("OK\n");
|
tb_puts("OK\n");
|
||||||
|
|
||||||
tb_puts("Test 3: sc.w with no preceding lr.w\n");
|
tb_puts("Test 3: sc.w with no preceding lr.w\n");
|
||||||
scratch[0] = 0x1234;
|
scratch[0] = 0x1234;
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"sc.w %0, %2, (%1)\n"
|
"sc.w %0, %2, (%1)\n"
|
||||||
: "=r" (success)
|
: "=r" (sc_fail)
|
||||||
: "r" (&scratch[0]), "r" (0x5678)
|
: "r" (&scratch[0]), "r" (0x5678)
|
||||||
);
|
);
|
||||||
tb_assert(scratch[0] == 0x1234, "Store shouldn't write memory\n");
|
tb_assert(scratch[0] == 0x1234, "Store shouldn't write memory\n");
|
||||||
tb_assert(success == 0, "Should report failure\n");
|
tb_assert(sc_fail == 1, "Should report failure\n");
|
||||||
tb_puts("OK\n");
|
tb_puts("OK\n");
|
||||||
|
|
||||||
// Reservation is only cleared by other harts' stores.
|
// Reservation is only cleared by other harts' stores.
|
||||||
|
@ -66,12 +66,12 @@ int main() {
|
||||||
"lr.w %0, (%2)\n"
|
"lr.w %0, (%2)\n"
|
||||||
"sw %3, 4(%2)\n"
|
"sw %3, 4(%2)\n"
|
||||||
"sc.w %1, %4, (%2)\n"
|
"sc.w %1, %4, (%2)\n"
|
||||||
: "=&r" (load_result), "=r" (success)
|
: "=&r" (load_result), "=r" (sc_fail)
|
||||||
: "r" (&scratch[0]), "r" (0xabcd), "r" (0x5678)
|
: "r" (&scratch[0]), "r" (0xabcd), "r" (0x5678)
|
||||||
);
|
);
|
||||||
tb_assert(scratch[1] == 0xabcd, "Regular store should succeed\n");
|
tb_assert(scratch[1] == 0xabcd, "Regular store should succeed\n");
|
||||||
tb_assert(scratch[0] == 0x5678, "sc didn't write memory\n");
|
tb_assert(scratch[0] == 0x5678, "sc didn't write memory\n");
|
||||||
tb_assert(success == 1, "Should report success\n");
|
tb_assert(sc_fail == 0, "Should report success\n");
|
||||||
tb_puts("OK\n");
|
tb_puts("OK\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue