[hatari-devel] MegaSTE cache emulation issues

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Hi,

while investigating why Spectre stopped working on Hatari 2.6.0 in MegaSTE 16 MHz + cache mode (reported here https://www.atari-forum.com/viewtopic.php?p=482013#p482013), I found three issues with the cache emulation. The attached test program illustrates all three. The first two were "red herrings" as far as Spectre is concerned, the third is the reason for the regression w.r.t. Spectre.

#1: When no further files are found, Fsnext() zeroes the file name in the DTA: https://framagit.org/hatari/hatari/-/blob/v2.6.0/src/gemdos.c?ref_type=tags#L2965. However, it does not flush/invalidate the cache, as M68000_Flush_Data_Cache is only called in PopulateDTA. (This would presumably also affect CPUs with built-in data cache.) Note: As stated in the comments, C:\TEST.TXT must exist for the test program to demonstrate this issue.

#2: When a write fails with a bus error (e.g. because of an attempted write to ROM), the cache is still updated. I would have expected the bus error to clear the entire cache as it happens on a real MegaSTE. The bus error handling needs to be checked.

#3: Due to the 24-bit address bus of the 68000, the MegaSTE does not care about the top eight bits of the address. However, the current code in Hatari https://framagit.org/hatari/hatari/-/blob/v2.6.0/src/m68000.c?ref_type=tags#L1242 treats addresses where the top bits are not zero as uncacheable. The address should be taken AND 0xFFFFFF before doing this check.

All of these issues can potentially cause hard-to-debug problems in MegaSTE 16 MHz + cache mode in Hatari 2.6.0.

Regards
Christian
#include <stdint.h>
#include <stdio.h>
#include <osbind.h>

#define TEST_ADDR_1 0u

#define TEST_ADDR_2A 0x000003f0ul
#define TEST_ADDR_2B 0x800003f0ul

_DTA *mydta;

void safe_write(uint32_t addr, uint16_t val)
{
    __asm ("move.l 8.w,-(sp)\n"
           "move.l #1f,8.w\n"
           "move.l sp,a5\n"
           "move.w %1,(%0)\n"
           "1: move.l a5,sp\n"
           "move.l (sp)+,8.w"
           : : "a"(addr), "r"(val) : "a5","memory");
}

int main(void)
{
    long ret1, ret2;
    long old_ssp = Super(0ul);
    uint16_t val1, val2;

    // Fsfirst/Fsnext specific issue (C: needs to be a GEMDOS drive, and C:\TEST.TXT needs to exist)
    mydta = (_DTA*)Fgetdta();
    ret1 = Fsfirst("C:\\TEST.TXT", 0x27); // will succeed
    val1 = *(volatile uint16_t*)(mydta->dta_name);
    ret2 = Fsnext(); // will fail
    // note that Fsnext will have zeroed out dta_name[0]
    val2 = *(volatile uint16_t*)(mydta->dta_name);
    printf("ret1 = %ld, ret2 = %ld\r\n", ret1, ret2);
    printf("val = %04x (expected 5445)\r\n", val1);
    printf("val = %04x (expected 0045)\r\n", val2);

    // test a write that fails with a bus error
    safe_write(TEST_ADDR_1, 0xaaaa);
    printf("val = %04x (expected 602e)\r\n", *(volatile uint16_t*)TEST_ADDR_1);

    // test a write to an address that aliases
    *(volatile uint16_t*)TEST_ADDR_2A = 0xaaaa;
    *(volatile uint16_t*)TEST_ADDR_2B = 0x5555;
    printf("val = %04x (expected 5555)\r\n", *(volatile uint16_t*)TEST_ADDR_2A);

    Super(old_ssp);
    return 0;
}

Attachment: grab0046.png
Description: PNG image

Attachment: grab0047.png
Description: PNG image



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/