diff --git a/cMIPS/tests/ll_sc.s b/cMIPS/tests/ll_sc.s index 6f5f22d46e6523bc32877b24d1ca6e590d8aa5f4..610d369aee2def06b60bd3263be916465b65e996 100644 --- a/cMIPS/tests/ll_sc.s +++ b/cMIPS/tests/ll_sc.s @@ -7,10 +7,10 @@ .ent _start _start: nop - li $k0,0x10000002 # RESET_STATUS, kernel mode, all else disabled + li $k0,0x10000002 # RESET_STATUS, EXL=1, all else disabled mtc0 $k0,c0_status li $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) # initialize SP: memTop-8 - li $k0, 0x1000ff01 # enable interrupts + li $k0, 0x1000ff01 # enable interrupts, EXL=0 mtc0 $k0, c0_status nop j main @@ -58,8 +58,6 @@ _excp_0100: excp_180: mfc0 $k0, c0_cause # show cause sw $k0, 0($15) - li $k0, 0x10000000 # disable interrupts, kernel mode - mtc0 $k0, c0_status li $k1, 0x00000000 # remove SW interrupt request mtc0 $k1, c0_cause li $k0, 0x1000ff03 # enable interrupts, user mode, EXL=1 @@ -96,13 +94,14 @@ _excp_BFC0: ## .org x_ENTRY_POINT,0 .ent main -main: la $15,x_IO_BASE_ADDR # print $5=8 and count downwards - li $5,8 - li $6,4 - li $t1,0 +main: la $15, x_IO_BASE_ADDR # print $5=8 and count downwards + li $5, 8 + li $6, 4 + li $t1, 0 la $t0, x_DATA_BASE_ADDR li $s0, 's' li $s1, '\n' + li $k1, 0x00000100 # cause SW interrupt after 4 rounds sw $zero, 0($t0) nop loop: sw $5, 0($15) # print-out $5 @@ -112,7 +111,6 @@ L: ll $t1, 0($t0) # load-linked bne $5, $6, fwd # four rounds yet? nop - li $k1, 0x00000100 # cause SW interrupt after 4 rounds mtc0 $k1, c0_cause # causes SC to fail and prints 0000.0000=CAUSE nop # must delay SC so that interrupt starts before the SC @@ -139,7 +137,7 @@ fwd: addi $t2, $t1, 1 # increment value read by LL li $k1, 0x00000000 # clear CAUSE mtc0 $k1, c0_cause - li $k0, 0x10000000 # RESET_STATUS, kernel mode, all else disabled + li $k0, 0x10000002 # RESET_STATUS, EXL=1, all else disabled mtc0 $k0, c0_status @@ -160,7 +158,7 @@ test1: li $30, '\n' # print a blank line to separate tests nop li $a2, 256-1 sc $a2, 0($t0) # same address -- must succeed - + nop beq $a2, $zero, error nop lw $a3, 0($t0) @@ -182,22 +180,55 @@ test2: li $30, '\n' # print a blank line to separate tests ll $a1, 0($t0) # load-linked from data[0] li $a2, 4096-1 # attempt to write 0x0ffff to data[1] sw $a1, 0($15) # display data[0] - nop - sc $a2, 4($t0) # different address from ll -- must fail + sc $a2, 4($t0) # different address from ll -- must fail + ## branch forwarding clears this hazard on $a2 beq $a2, $zero, did_ok nop -succ_nok: # should never come here +succ_nok: # should never get here lw $a3, 4($t0) sw $a2, 0($15) # print out wrong value stored to data[1] beq $a3, $a2, error # sc did change data[1] nop - # sc ought to have failed, which is good + # sc ought to have failed, which is the expected result, good! did_ok: jal fail_ok nop + + ## + ## repeat above test, with different branch forwarding (one nop) + ## +test3: li $30, '\n' # print a blank line to separate tests + sw $30, x_IO_ADDR_RANGE($15) + + la $t0, x_DATA_BASE_ADDR + li $a0, 0x55555555 # store -1 to data[0] + li $a1, 0x88442211 # store 88442211 to data[1] + sw $a0, 0($t0) + sw $a1, 4($t0) # address to store_c != addr to load_l + + ll $a1, 0($t0) # load-linked from data[0] + li $a2, 4096-1 # attempt to write 0x0ffff to data[1] + sw $a1, 0($15) # display data[0] + + sc $a2, 4($t0) # different address from ll -- must fail + nop ## branch forwarding clears this hazard on $a2 + beq $a2, $zero, did_ok3 + nop + +succ_nok3: # should never get here + lw $a3, 4($t0) + sw $a2, 0($15) # print out wrong value stored to data[1] + beq $a3, $a2, error # sc did change data[1] + nop + # sc ought to have failed, which is the expected result, good! + +did_ok3: + jal fail_ok + nop + ## ## check forwarding from SC to ALU inputs ##