[hatari-devel] SIGSEGV error with MMU

Eero Tamminen oak at helsinkinet.fi
Wed Feb 23 22:22:38 CET 2011


Hi,

On keskiviikko 23 helmikuu 2011, Laurent Sallafranque wrote:
> (gdb) p regs
> $1 = {regs = {47, 65535, 0, 0, 65535, 14680064, 0, 0, 14680064, 2368, 0,
> 14683474, 14683140, 512, 0, 34924}, pc = 14685088, pc_p = 0x0,

pc_p is zero so it's no wonder you get segfault.

It's supposed to correspond to the Atari PC instruction address in Hatari's
own memory:
-----
static inline uae_u8 *get_real_address(uaecptr addr)
{
    return get_mem_bank(addr).xlateaddr(addr);
}
...
STATIC_INLINE void m68k_setpc (uaecptr newpc)
{
        regs.pc_p = regs.pc_oldp = get_real_address (newpc);
        regs.fault_pc = regs.pc = newpc;
}

STATIC_INLINE uaecptr m68k_getpc (void)
{
        return (uaecptr)(regs.pc + ((uae_u8*)regs.pc_p - 
(uae_u8*)regs.pc_oldp));
}
-----


However, apparently it can be sometimes set zero:
------
STATIC_INLINE void m68k_setpc_mmu (uaecptr newpc)
{
        regs.fault_pc = regs.pc = newpc;
        regs.pc_p = regs.pc_oldp = 0;
}
...
$ grep m68k_setpc_mmu $(find -type f)
./cpu/newcpu.h:STATIC_INLINE void m68k_setpc_mmu (uaecptr newpc)
./cpu/gencpu.c:         printf ("\tm68k_setpc_mmu (%s);\n", buffer);
------


Or not be updated or used with PC register:
------
STATIC_INLINE void m68k_setpci (uaecptr newpc)
{
        regs.fault_pc = regs.pc = newpc;
}

STATIC_INLINE uaecptr m68k_getpci (void)
{
        return regs.pc;
}
...
STATIC_INLINE void m68k_do_rtsi (void)
{
        m68k_setpci (get_long (m68k_areg (regs, 7)));
        m68k_areg (regs, 7) += 4;
}
$ grep m68k_setpci $(find -type f)
./cpu/newcpu.h:STATIC_INLINE void m68k_setpci (uaecptr newpc)
./cpu/newcpu.h: m68k_setpci (get_long (m68k_areg (regs, 7)));
$ grep m68k_do_rtsi $(find -type f)
./cpu/newcpu.h:STATIC_INLINE void m68k_do_rtsi (void)
./cpu/gencpu.c:                 printf ("\tm68k_do_rtsi ();\n");
------

As you can see from above, these special cases (pc_p zeroing or not updating
or using it with PC) don't happen with the old AUE core, only with the new
one.


The WinAUE gencpu.c has this code generation function:
--------
static void setpc (const char *format, ...)
{
...
        if (using_mmu)
                printf ("\tm68k_setpc_mmu (%s);\n", buffer);
        else
                printf ("\tm68k_setpc (%s);\n", buffer);
}
--------
This is called for RTS, RTE etc instructions, which means that with MMU,
regs.pc_p get regularly zeroed with m68k_setpc_mmu() call.


According to your previous backtrace, next_iword() is called from:
#2  0x00000000006fe8d4 in op_11b0_31_ff (opcode=5040) at 
/home/laurent/Atari/hatari/build/src/cpu/cpuemu_31.c:7548

Can you paste here several lines before and after that line?


My wild guess is that with the settings you've selected, next_iwordi()
function should be called instead of the next_iword() function.

I'd suggest discussing this issue with upstream.


> pc_oldp = 0x0, irc = 65535, ir = 0, spcflags = 0, usp = 0, isp = 0, msp
> = 0,
> sr = 9984, t1 = 0 '\000', t0 = 0 '\000', s = 1 '\001', m = 0 '\000',
> x = 0 '\000', stopped = 0 '\000', intmask = 7, ipl = 0, ipl_pin = 0,
> vbr = 0, sfc = 0, dfc = 0, fp = {0, 0, 0, 0, 0, 0, 0, 0}, fp_result = 1,
> fpcr = 0, fpsr = 0, fpiar = 0, fpsr_highbyte = 0, cacr = 0, caar = 0,
> itt0 = 0, itt1 = 0, dtt0 = 0, dtt1 = 0, tcr = 0, mmusr = 0, urp = 0,
> srp = 0, buscr = 0, mmu_fslw = 0, mmu_fault_addr = 0, mmu_ssw = 0,
> wb3_data = 0, wb3_status = 0, mmu_enabled = 0, mmu_pagesize_8k = 0,

mmu_enabled = 0???


> fault_pc = 14681008, pcr = 0, address_space_mask = 0, panic = 0 '\000',
> panic_pc = 0, panic_addr = 0, prefetch020data = {0, 0}, prefetch020addr =
> { 4294967295, 4294967295}, ce020memcycles = 0}
> 
> 
> (gdb) p STRam

Sorry, I meant the address of STRam array, not its contents.
But if pc_p is zero, STRam address isn't relevant. :)


Btw. maccess.h & newcpu.h functions are supposed to be used only when
accessing emulated Atari memory through host (Hatari x86) pointers i.e.
addresses that are already converted from Atari to Hatari process addresses.

All emulated Atari memory accesses should go through the memory bank
functions define in memory.h.  If Hatari code needs to access memory for
which it got Atari addresses, it can use functions in stMemory.h.



> PS. I started reading cpu/memory.[ch]&  newcpu.h, but got confused with
> the large amount of functions, struct members[1] and functions that
> aren't used anywhere.  Is WinAUE code missing large pieces?
> 
> 
>  From now, I've just tried to change as little as possible the original
> code, but removing only what avoid compilation.

I was mainly wondering is some WinAUE code missing e.g. related to
the baseaddr.

I cannot quite get my head around what the JIT code defines are supposed
to do as it JIT code is using a "baseaddr" variable that's not set anywere,
it's just a member in memory bank structure...?


	- Eero



More information about the hatari-devel mailing list