From: Toni Wilen Date: Sun, 8 Dec 2019 11:25:22 +0000 (+0200) Subject: CPU test prefetch bus error testing (does not return correct results yet) X-Git-Tag: 4300~20 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=88a279b151249ded9d713bb862424e741e8011f7;p=francis%2Fwinuae.git CPU test prefetch bus error testing (does not return correct results yet) --- diff --git a/cputest.cpp b/cputest.cpp index e9a8e5ee..2d17eca3 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -2479,8 +2479,9 @@ static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, i return offset; } -static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct instr *dp) +static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp) { + uae_u16 opc = regs.ir; uae_u16 opw1 = (opcode_memory[2] << 8) | (opcode_memory[3] << 0); uae_u16 opw2 = (opcode_memory[4] << 8) | (opcode_memory[5] << 0); if (opc == 0x4a10 @@ -2945,9 +2946,14 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi registers[8 + 7] = user_stack_memory_use; uae_u32 target_address = 0xffffffff; + uae_u32 target_opcode_address = 0xffffffff; target_ea[0] = 0xffffffff; target_ea[1] = 0xffffffff; target_ea[2] = 0xffffffff; + if (feature_target_ea[0][2] && feature_target_ea[0][2] != 0xffffffff) { + target_opcode_address = feature_target_ea[0][2]; + target_ea[2] = target_opcode_address; + } if (feature_target_ea[0][0] != 0xffffffff) { target_address = feature_target_ea[0][0]; target_ea[0] = target_address; @@ -3006,7 +3012,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi int sr_override = 0; - uae_u32 target_ea_bak[3], target_address_bak; + uae_u32 target_ea_bak[3], target_address_bak, target_opcode_address_bak; for (;;) { @@ -3014,6 +3020,16 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi target_ea_bak[1] = target_ea[1]; target_ea_bak[2] = target_ea[2]; target_address_bak = target_address; + target_opcode_address_bak = target_opcode_address; + + uae_u32 opcode_memory_address = opcode_memory_start; + uae_u8 *opcode_memory_ptr = opcode_memory; + if (target_opcode_address != 0xffffffff) { + opcode_memory_address += target_opcode_address; + opcode_memory_ptr = get_addr(opcode_memory_address, 2, 0); + if (opcode_memory_address >= safe_memory_start && opcode_memory_address < safe_memory_end) + break; + } if (quick) break; @@ -3070,6 +3086,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi target_ea[1] = target_ea_bak[1]; target_ea[2] = target_ea_bak[2]; target_address = target_address_bak; + target_opcode_address = target_opcode_address_bak; int extra_loops = 3; while (extra_loops-- > 0) { @@ -3102,6 +3119,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi target_ea[1] = target_ea_bak[1]; target_ea[2] = target_ea_bak[1]; target_address = target_address_bak; + target_opcode_address = target_opcode_address_bak; reset_ea_state(); // retry few times if out of bounds access @@ -3142,6 +3160,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi target_ea[1] = target_ea_bak[1]; target_ea[2] = target_ea_bak[2]; target_address = target_address_bak; + target_opcode_address = target_opcode_address_bak; if (opc == 0x4ed0) printf(""); @@ -3150,6 +3169,19 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi uaecptr pc = opcode_memory_start + 2; + if (target_opcode_address != 0xffffffff) { + pc -= 2; + int cnt = 0; + while (pc - 2 != opcode_memory_address) { + put_word_test(pc, 0x4e71); + pc += 2; + cnt++; + if (cnt >= 16) { + wprintf(_T("opcode target is too far from opcode address\n")); + abort(); + } + } + } if (dp->mnemo != i_ILLG) { @@ -3170,7 +3202,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi pc += o; } - uae_u8 *ao = opcode_memory + 2; + uae_u8 *ao = opcode_memory_ptr + 2; uae_u16 apw1 = (ao[0] << 8) | (ao[1] << 0); uae_u16 apw2 = (ao[2] << 8) | (ao[3] << 0); if (opc == 0x4eb1 @@ -3182,7 +3214,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi if (target_address != 0xffffffff && (dp->mnemo == i_MVMEL || dp->mnemo == i_MVMLE)) { // if MOVEM and more than 1 register: randomize address so that any MOVEM // access can hit target address - uae_u16 mask = (opcode_memory[2] << 8) | opcode_memory[3]; + uae_u16 mask = (opcode_memory_ptr[2] << 8) | opcode_memory_ptr[3]; int count = 0; for (int i = 0; i < 16; i++) { if (mask & (1 << i)) @@ -3231,7 +3263,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi // if destination EA modified opcode dp = table68k + opc; - uae_u8 *bo = opcode_memory + 2; + uae_u8 *bo = opcode_memory_ptr + 2; uae_u16 bopw1 = (bo[0] << 8) | (bo[1] << 0); uae_u16 bopw2 = (bo[2] << 8) | (bo[3] << 0); if (opc == 0x0662 @@ -3247,20 +3279,20 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi } - put_word_test(opcode_memory_start, opc); + put_word_test(opcode_memory_address, opc); if (extra_or || extra_and) { - uae_u16 ew = get_word_test(opcode_memory_start + 2); + uae_u16 ew = get_word_test(opcode_memory_address + 2); uae_u16 ew2 = (ew | extra_or) & ~extra_and; if (ew2 != ew) { - put_word_test(opcode_memory_start + 2, ew2); + put_word_test(opcode_memory_address + 2, ew2); } } // loop mode if (feature_loop_mode) { // dbf dn, opcode_memory_start - put_long_test(pc, ((0x51c8 | feature_loop_mode_register) << 16) | ((opcode_memory_start - pc - 2) & 0xffff)); + put_long_test(pc, ((0x51c8 | feature_loop_mode_register) << 16) | ((opcode_memory_address - pc - 2) & 0xffff)); pc += 4; } @@ -3268,7 +3300,14 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi // running on real hardware. uae_u32 originalendopcode = 0x4afc4e71; uae_u32 endopcode = originalendopcode; - put_long_test(pc, endopcode); // illegal instruction + nop + uae_u32 actualendpc = pc; + if (!is_nowrite_address(pc, 4)) { + put_long_test(pc, endopcode); // illegal instruction + nop + actualendpc += 4; + } else if (!is_nowrite_address(pc, 2)) { + put_word_test(pc, endopcode >> 16); + actualendpc += 2; + } pc += 4; if (isconstant_src < 0 || isconstant_dst < 0) { @@ -3289,7 +3328,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi abort(); } - dst = store_mem_bytes(dst, opcode_memory_start, pc - opcode_memory_start, subtest_count > 0 ? oldbytes : NULL); + dst = store_mem_bytes(dst, opcode_memory_start, actualendpc - opcode_memory_start, subtest_count > 0 ? oldbytes : NULL); ahcnt = 0; @@ -3305,7 +3344,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi uaecptr nextpc; srcaddr = 0xffffffff; dstaddr = 0xffffffff; - uae_u32 dflags = m68k_disasm_2(out, sizeof(out) / sizeof(TCHAR), opcode_memory_start, &nextpc, 1, &srcaddr, &dstaddr, 0xffffffff, 0); + uae_u32 dflags = m68k_disasm_2(out, sizeof(out) / sizeof(TCHAR), opcode_memory_address, &nextpc, 1, &srcaddr, &dstaddr, 0xffffffff, 0); if (verbose) { my_trim(out); wprintf(_T("%08u %s"), subtest_count, out); @@ -3474,9 +3513,16 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi // swap end opcode illegal/nop endopcode = (endopcode >> 16) | (endopcode << 16); noaccesshistory++; - put_long_test(pc - 4, endopcode); + int endopcodesize = 0; + if (!is_nowrite_address(pc - 4, 4)) { + put_long_test(pc - 4, endopcode); + endopcodesize = (endopcode >> 16) == 0x4e71 ? 2 : 4; + } else if (!is_nowrite_address(pc - 4, 2)) { + put_word_test(pc - 4, endopcode >> 16); + endopcodesize = 2; + } noaccesshistory--; - int endopcodesize = (endopcode >> 16) == 0x4e71 ? 2 : 4; + // swap branch target illegal/nop if (branch_target_swap_mode) { @@ -3560,7 +3606,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi if (subtest_count == 2052) printf(""); - execute_ins(opc, pc - endopcodesize, branch_target_pc, dp); + execute_ins(pc - endopcodesize, branch_target_pc, dp); if (regs.s) s_cnt++; @@ -3797,7 +3843,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi } dst = storage_buffer; - if (opcodecnt == 1 && target_address == 0xffffffff) + if (opcodecnt == 1 && target_address == 0xffffffff && target_opcode_address == 0xffffffff) break; if (lookup->mnemo == i_ILLG) break; @@ -3834,6 +3880,18 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi nextround = true; } + if (target_opcode_address != 0xffffffff) { + nextround = false; + target_ea_opcode_cnt++; + if (target_ea_opcode_cnt >= target_ea_opcode_max) { + target_ea_opcode_cnt = 0; + if (target_ea_opcode_max > 0) + nextround = true; + } + target_opcode_address = feature_target_ea[target_ea_opcode_cnt][2]; + target_ea[2] = opcode_memory_address + target_opcode_address; + } + if (nextround) { rounds--; if (rounds < 0) @@ -4067,7 +4125,7 @@ int __cdecl main(int argc, char *argv[]) feature_target_ea[i][2] = 0xffffffff; } for (int i = 0; i < 3; i++) { - if (ini_getstring(ini, INISECTION, i == 2 ? _T("feature_target_opcode") : (i ? _T("feature_target_dst_ea") : _T("feature_target_src_ea")), &vs)) { + if (ini_getstring(ini, INISECTION, i == 2 ? _T("feature_target_opcode_offset") : (i ? _T("feature_target_dst_ea") : _T("feature_target_src_ea")), &vs)) { int cnt = 0; TCHAR *p = vs; while (p && *p) { diff --git a/cputest/main.c b/cputest/main.c index 78660d0d..204794ff 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -219,6 +219,16 @@ static int is_valid_test_addr_read(uae_u32 a) (a >= test_memory_addr && a < test_memory_end); } +static int is_valid_test_addr_readwrite(uae_u32 a) +{ + if ((uae_u8 *)a >= safe_memory_start && (uae_u8 *)a < safe_memory_end) + return 0; + return (a >= test_low_memory_start && a < test_low_memory_end && test_low_memory_start != 0xffffffff) || + (a >= test_high_memory_start && a < test_high_memory_end && test_high_memory_start != 0xffffffff) || + (a >= test_memory_addr && a < test_memory_end); +} + + static void endinfo(void) { printf("Last test: %lu\n", testcnt); @@ -951,8 +961,11 @@ static void out_disasm(uae_u8 *mem) int lines = 0; while (lines++ < 5) { int v = 0; - if (!is_valid_test_addr_read((uae_u32)p) || !is_valid_test_addr_read((uae_u32)p + 1)) + if (!is_valid_test_addr_read((uae_u32)p) || !is_valid_test_addr_read((uae_u32)p + 1)) { + sprintf(outbp, "%08lx -- INACCESSIBLE --\n", p); + outbp += strlen(outbp); break; + } tmpbuffer[0] = 0; if (!(((uae_u32)code) & 1)) { v = disasm_instr(code + offset, tmpbuffer); @@ -962,6 +975,8 @@ static void out_disasm(uae_u8 *mem) uae_u16 v = (p[i * 2 + 0] << 8) | (p[i * 2 + 1]); sprintf(outbp, "%04x ", v); outbp += strlen(outbp); + if (v == 0x4e71) + lines--; } sprintf(outbp, " %s\n", tmpbuffer); outbp += strlen(outbp); @@ -1764,7 +1779,7 @@ static void process_test(uae_u8 *p) uae_u32 originalopcodeend = 0x4afc4e71; uae_u8 *opcode_memory_end = (uae_u8*)pc; for (;;) { - if (gl(opcode_memory_end) == originalopcodeend) + if (opcode_memory_end == safe_memory_start || gw(opcode_memory_end) == 0x4afc) break; opcode_memory_end += 2; if (opcode_memory_end > (uae_u8*)pc + 32) { @@ -1776,6 +1791,12 @@ static void process_test(uae_u8 *p) } uae_u32 opcodeend = originalopcodeend; int extraccr = 0; + int validendsize = 0; + if (is_valid_test_addr_readwrite((uae_u32)opcode_memory_end + 2)) { + validendsize = 2; + } else if (is_valid_test_addr_readwrite((uae_u32)opcode_memory_end)) { + validendsize = 1; + } uae_u32 last_pc = opcode_memory_addr; uae_u32 last_fpiar = opcode_memory_addr; @@ -1797,7 +1818,11 @@ static void process_test(uae_u8 *p) for (int ccr = 0; ccr < maxccr; ccr++) { opcodeend = (opcodeend >> 16) | (opcodeend << 16); - pl(opcode_memory_end, opcodeend); + if (validendsize == 2) { + pl(opcode_memory_end, opcodeend); + } else if (validendsize == 1) { + pw(opcode_memory_end, opcodeend >> 16); + } if (regs.branchtarget != 0xffffffff) { if (regs.branchtarget_mode == 1) { @@ -1932,7 +1957,11 @@ static void process_test(uae_u8 *p) } - pl(opcode_memory_end, originalopcodeend); + if (validendsize == 2) { + pl(opcode_memory_end, originalopcodeend); + } else if (validendsize == 1) { + pw(opcode_memory_end, originalopcodeend >> 16); + } restoreahist(); diff --git a/newcpu.cpp b/newcpu.cpp index 5f9a32cc..6bb92166 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -6906,6 +6906,7 @@ void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc) void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc) { + uae_u32 opcode = last_op_for_exception_3; last_addr_for_exception_3 = m68k_getpc() + bus_error_offset; last_fault_for_exception_3 = addr; last_writeaccess_for_exception_3 = read == 0; @@ -6917,11 +6918,14 @@ void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc) cpu_bus_error = 0; if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) { - if (generates_group1_exception(regs.ir)) { + if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) { last_notinstruction_for_exception_3 = true; fc = -1; } - last_op_for_exception_3 = regs.ir; + if (opcode & 0x10000) + last_notinstruction_for_exception_3 = true; + if (!(opcode & 0x20000)) + last_op_for_exception_3 = regs.ir; } } @@ -6942,30 +6946,24 @@ void exception2(uaecptr addr, bool read, int size, uae_u32 fc) void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc) { - exception2_setup(addr, true, size, fc); last_op_for_exception_3 = opcode; - if (opcode & 0x10000) - last_notinstruction_for_exception_3 = true; + exception2_setup(addr, true, size, fc); Exception(2); } void exception2_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc) { - exception2_setup(addr, false, size, fc); last_op_for_exception_3 = opcode; - if (opcode & 0x10000) - last_notinstruction_for_exception_3 = true; + exception2_setup(addr, false, size, fc); regs.write_buffer = val; Exception(2); } void exception2_fetch(uae_u32 opcode, uaecptr addr) { - exception2_setup(addr, true, 1, 2); last_op_for_exception_3 = opcode; + exception2_setup(addr, true, 1, 2); last_di_for_exception_3 = 0; - if (opcode & 0x10000) - last_notinstruction_for_exception_3 = true; Exception(2); }