Hi ! Here's some code to help you in doing speculative stores/loads/calls in a controlled way. I used it to examine and learn about IP28's state under the condition of speculative bus-errors. /* * Doing deliberate speculative memory accesses (to invalid addresses) ... * * Copyright (C) 2005 Peter Fuerst (pf@net.alphadv.de) */ #include #include #include int enforce_speculative_load_dword ( long *cond, unsigned long addr ) { __asm__ __volatile__( /* make operand to "bnel" unavailable long enough */ " cache %0, 0(%1) \n" /* force cpu to fetch "ld", "bnel" simultaneously */ " .align 6 \n" " .set push \n" " .set noreorder \n" " ld $2, 0(%1) \n" " bnel $2, $0, 1f \n" " nop \n" " move $2, $0 \n" " b 2f \n" " nop \n" "1: \n" " ld $2, 0(%2) \n" " nop \n" "2: \n" " .set pop \n" : : "i" (Hit_Writeback_Inv_S), "r" (cond), "r" (addr)); } int enforce_speculative_store_dword ( long *cond, unsigned long addr ) { __asm__ __volatile__( /* make operand to "bnel" unavailable long enough */ " cache %0, 0(%1) \n" /* force cpu to fetch "ld", "bnel" simultaneously */ " .align 6 \n" " .set push \n" " .set noreorder \n" " ld $2, 0(%1) \n" " bnel $2, $0, 1f \n" " nop \n" " move $2, $0 \n" " b 2f \n" " nop \n" "1: \n" " sd $0, 0(%2) \n" " li $2, 1 \n" "2: \n" " .set pop \n" : : "i" (Hit_Writeback_Inv_S), "r" (cond), "r" (addr)); } int enforce_speculative_call ( long *cond, unsigned long addr ) { __asm__ __volatile__( /* make operand to "bnel" unavailable long enough */ " cache %0, 0(%1) \n" /* force cpu to fetch "ld", "bnel" simultaneously */ " .align 6 \n" " .set push \n" " .set noreorder \n" " ld $2, 0(%1) \n" " bnel $2, $0, 1f \n" " nop \n" " move $2, $0 \n" " b 2f \n" " nop \n" "1: \n" " jr %2 \n" " nop \n" " li $2, 1 \n" "2: \n" " .set pop \n" : : "i" (Hit_Writeback_Inv_S), "r" (cond), "r" (addr)); } You would apply it (by a dedicated syscall or just at the end of kernel-init) in a fashion similar to: unsigned long null = 0; /* ! */ unsigned long addr = some_invalid_xkphys_address; /* e.g. for IP28 * addr = PHYS_TO_XKSEG_CACHED(0x62449e78); * addr = 0xa800000064400000LL|0x44470; * ... */ ignore_this_bus_error = 1; enforce_speculative_store_dword( &null, addr ); ignore_this_bus_error = 1; enforce_speculative_load_dword( &null, addr ); ignore_this_bus_error = 1; enforce_speculative_call( &null, addr ); ignore_this_bus_error = 0; to become acqauinted with the machine's state in case of speculative bus-errors. To handle these bus errors you would modify ip32_be_handler similar to: int ip32_be_handler(struct pt_regs *regs, int is_fixup) { int data = regs->cp0_cause & 4; if (is_fixup) return MIPS_BE_FIXUP; printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc); show_regs(regs); dump_tlb_all(); if (ignore_this_bus_error) { ignore_this_bus_error = 0; /* * Dump here as much information about the machine, as you can get. * CRIME, MACE, Cache-tags, ... (Have a look at print_buserr(), * print_cache_tags() in ip28-berr.c for this) */ show_code((unsigned int *) regs->cp0_epc); /* Of course, the faint at heart may decide not to return here, * but to reboot instead :) */ return MIPS_BE_DISCARD; } while(1); force_sig(SIGBUS, current); } kind regards pf