void dae_print(unsigned *eframe) { int x; unsigned dmax, dmdx, dmtx; if (!ISSET(eframe[EF_DMT0], DMT_VALID)) return; for (x = 0; x < 3; x++) { dmtx = eframe[EF_DMT0 + x * 3]; if (!ISSET(dmtx, DMT_VALID)) continue; dmdx = eframe[EF_DMD0 + x * 3]; dmax = eframe[EF_DMA0 + x * 3]; if (ISSET(dmtx, DMT_WRITE)) printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n", x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax, DMT_ENBITS(dmtx), dmtx & DMT_DOUB1 ? "double": "not double", dmtx & DMT_LOCKBAR ? "xmem": "not xmem"); else printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n", x, dmtx, dmtx & DMT_DAS ? 's' : 'u', DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx), dmtx & DMT_DOUB1 ? "double": "not double", dmtx & DMT_LOCKBAR ? "xmem": "not xmem"); } }
void dae_print_one(u_int x, u_int dmax, u_int dmdx, u_int dmtx) { if (!ISSET(dmtx, DMT_VALID)) return; if (ISSET(dmtx, DMT_WRITE)) printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n", x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax, DMT_ENBITS(dmtx), dmtx & DMT_DOUB1 ? "double": "not double", dmtx & DMT_LOCKBAR ? "xmem": "not xmem"); else printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n", x, dmtx, dmtx & DMT_DAS ? 's' : 'u', DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx), dmtx & DMT_DOUB1 ? "double": "not double", dmtx & DMT_LOCKBAR ? "xmem": "not xmem"); }
void dae_print_one(u_int x, u_int dmax, u_int dmdx, u_int dmtx) { u_int enbits; const char *width, *usr, *xmem; if (!ISSET(dmtx, DMT_VALID)) return; enbits = DMT_ENBITS(dmtx); dmax += dmt_en_info[enbits].offset; if (dmtx & DMT_DOUB1) width = ".d"; else { switch (dmt_en_info[enbits].size) { case DMT_BYTE: if (dmtx & DMT_SIGNED) width = ".b"; else width = ".bu"; break; case DMT_HALF: if (dmtx & DMT_SIGNED) width = ".h"; else width = ".hu"; break; case DMT_WORD: width = ""; break; default: width = ".???"; break; } } if (dmtx & DMT_DAS) usr = ""; else usr = "******"; if (dmtx & DMT_LOCKBAR) xmem = "(xmem)"; else xmem = ""; if (ISSET(dmtx, DMT_WRITE)) printf("[DMT%d=%x: %sst%s%s %08x to %08x]\n", x, dmtx, xmem, width, usr, dmdx, dmax); else printf("[DMT%d=%x: %sld%s%s r%d <- %x]\n", x, dmtx, xmem, width, usr, DMT_DREGBITS(dmtx), dmax); }
void dae_process(struct trapframe *eframe, u_int x, u_int dmax, u_int dmdx, u_int dmtx) { u_int v, reg; if (!ISSET(dmtx, DMT_VALID)) return; DAE_DEBUG( if (ISSET(dmtx, DMT_WRITE)) printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n", x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax, DMT_ENBITS(dmtx), dmtx & DMT_DOUB1 ? "double": "not double", dmtx & DMT_LOCKBAR ? "xmem": "not xmem"); else printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n", x, dmtx, dmtx & DMT_DAS ? 's' : 'u', DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx), dmtx & DMT_DOUB1 ? "double": "not double", dmtx & DMT_LOCKBAR ? "xmem": "not xmem") ); dmax += dmt_en_info[DMT_ENBITS(dmtx)].offset; reg = DMT_DREGBITS(dmtx); if (!ISSET(dmtx, DMT_LOCKBAR)) { /* the fault is not during an XMEM */ if (x == 2 && ISSET(dmtx, DMT_DOUB1)) { /* pipeline 2 (earliest stage) for a double */ if (ISSET(dmtx, DMT_WRITE)) { /* * STORE DOUBLE WILL BE REINITIATED BY rte */ } else { /* EMULATE ld.d INSTRUCTION */ v = do_load_word(dmax, dmtx & DMT_DAS); if (reg != 0) eframe->tf_r[reg] = v; v = do_load_word(dmax ^ 4, dmtx & DMT_DAS); if (reg != 31) eframe->tf_r[reg + 1] = v; } } else { /* not pipeline #2 with a double */ if (dmtx & DMT_WRITE) { switch (dmt_en_info[DMT_ENBITS(dmtx)].size) { case DMT_BYTE: DAE_DEBUG( printf("[byte %x -> [%x(%c)]\n", dmdx & 0xff, dmax, ISSET(dmtx, DMT_DAS) ? 's' : 'u') ); do_store_byte(dmax, dmdx, dmtx & DMT_DAS); break; case DMT_HALF: DAE_DEBUG( printf("[half %x -> [%x(%c)]\n", dmdx & 0xffff, dmax, ISSET(dmtx, DMT_DAS) ? 's' : 'u') ); do_store_half(dmax, dmdx, dmtx & DMT_DAS); break; case DMT_WORD: DAE_DEBUG( printf("[word %x -> [%x(%c)]\n", dmdx, dmax, ISSET(dmtx, DMT_DAS) ? 's' : 'u') ); do_store_word(dmax, dmdx, dmtx & DMT_DAS); break; } } else { /* else it's a read */ switch (dmt_en_info[DMT_ENBITS(dmtx)].size) { case DMT_BYTE: v = do_load_byte(dmax, dmtx & DMT_DAS); if (!ISSET(dmtx, DMT_SIGNED)) v &= 0x000000ff; break; case DMT_HALF: v = do_load_half(dmax, dmtx & DMT_DAS); if (!ISSET(dmtx, DMT_SIGNED)) v &= 0x0000ffff; break; case DMT_WORD: v = do_load_word(dmax, dmtx & DMT_DAS); break; } DAE_DEBUG( if (reg == 0) printf("[no write to r0 done]\n"); else printf("[r%d <- %x]\n", reg, v); ); if (reg != 0) eframe->tf_r[reg] = v; } } } else {
void data_access_emulation(unsigned *eframe) { int x; unsigned dmax, dmdx, dmtx; unsigned v, reg; dmtx = eframe[EF_DMT0]; if (!ISSET(dmtx, DMT_VALID)) return; for (x = 0; x < 3; x++) { dmtx = eframe[EF_DMT0 + x * 3]; if (!ISSET(dmtx, DMT_VALID) || ISSET(dmtx, DMT_SKIP)) continue; dmdx = eframe[EF_DMD0 + x * 3]; dmax = eframe[EF_DMA0 + x * 3]; DAE_DEBUG( if (ISSET(dmtx, DMT_WRITE)) printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n", x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax, DMT_ENBITS(dmtx), dmtx & DMT_DOUB1 ? "double": "not double", dmtx & DMT_LOCKBAR ? "xmem": "not xmem"); else printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n", x, dmtx, dmtx & DMT_DAS ? 's' : 'u', DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx), dmtx & DMT_DOUB1 ? "double": "not double", dmtx & DMT_LOCKBAR ? "xmem": "not xmem") ); dmax += dmt_en_info[DMT_ENBITS(dmtx)].offset; reg = DMT_DREGBITS(dmtx); if (!ISSET(dmtx, DMT_LOCKBAR)) { /* the fault is not during an XMEM */ if (x == 2 && ISSET(dmtx, DMT_DOUB1)) { /* pipeline 2 (earliest stage) for a double */ if (ISSET(dmtx, DMT_WRITE)) { /* * STORE DOUBLE WILL BE REINITIATED * BY rte */ } else { /* EMULATE ld.d INSTRUCTION */ v = do_load_word(dmax, dmtx & DMT_DAS); if (reg != 0) eframe[EF_R0 + reg] = v; v = do_load_word(dmax ^ 4, dmtx & DMT_DAS); if (reg != 31) eframe[EF_R0 + reg + 1] = v; } } else { /* not pipeline #2 with a double */ if (dmtx & DMT_WRITE) { switch (dmt_en_info[DMT_ENBITS(dmtx)].size) { case DMT_BYTE: DAE_DEBUG( printf("[byte %x -> [%x(%c)]\n", dmdx & 0xff, dmax, ISSET(dmtx, DMT_DAS) ? 's' : 'u') ); do_store_byte(dmax, dmdx, dmtx & DMT_DAS); break; case DMT_HALF: DAE_DEBUG( printf("[half %x -> [%x(%c)]\n", dmdx & 0xffff, dmax, ISSET(dmtx, DMT_DAS) ? 's' : 'u') ); do_store_half(dmax, dmdx, dmtx & DMT_DAS); break; case DMT_WORD: DAE_DEBUG( printf("[word %x -> [%x(%c)]\n", dmdx, dmax, ISSET(dmtx, DMT_DAS) ? 's' : 'u') ); do_store_word(dmax, dmdx, dmtx & DMT_DAS); break; } } else { /* else it's a read */ switch (dmt_en_info[DMT_ENBITS(dmtx)].size) { case DMT_BYTE: v = do_load_byte(dmax, dmtx & DMT_DAS); if (!ISSET(dmtx, DMT_SIGNED)) v &= 0x000000ff; break; case DMT_HALF: v = do_load_half(dmax, dmtx & DMT_DAS); if (!ISSET(dmtx, DMT_SIGNED)) v &= 0x0000ffff; break; case DMT_WORD: v = do_load_word(dmax, dmtx & DMT_DAS); break; } DAE_DEBUG( if (reg == 0) printf("[no write to r0 done]\n"); else printf("[r%d <- %x]\n", reg, v); ); if (reg != 0) eframe[EF_R0 + reg] = v; } } } else { /* if lockbar is set... it's part of an XMEM */ /* * According to Motorola's "General Information", * the DMT_DOUB1 bit is never set in this case, as it * should be. * If lockbar is set (as it is if we're here) and if * the write is not set, then it's the same as if DOUB1 * was set... */ if (!ISSET(dmtx, DMT_WRITE)) {