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