[PATCH] Tracing and run-time configuration for MegaSTE/TT VME/SCU regs access |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
- Subject: [PATCH] Tracing and run-time configuration for MegaSTE/TT VME/SCU regs access
- From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
- Date: Sat, 2 Jan 2021 21:04:39 +0200
Run-time configuration is needed because TOS v2 / v3 fail to boot on
MegaSTE / TT unless SCU register access is allowed, but that causes
Linux boot to fail on them, due to missing VME SCU interrupt
emulation.
---
doc/hatari.1 | 11 ++
doc/manual.html | 15 +++
src/CMakeLists.txt | 2 +-
src/configuration.c | 5 +
src/debug/log.c | 2 +
src/debug/log.h | 2 +
src/includes/configuration.h | 7 ++
src/includes/vme.h | 14 +++
src/ioMem.c | 11 +-
src/ioMemTabTT.c | 9 +-
src/options.c | 20 ++++
src/reset.c | 6 +-
src/vme.c | 219 +++++++++++++++++++++++++++++++++++
13 files changed, 306 insertions(+), 17 deletions(-)
create mode 100644 src/includes/vme.h
create mode 100644 src/vme.c
diff --git a/doc/hatari.1 b/doc/hatari.1
index 8940400c..2892484b 100644
--- a/doc/hatari.1
+++ b/doc/hatari.1
@@ -484,6 +484,17 @@ Enable blitter emulation (ST only)
.B \-\-dsp <x>
Falcon DSP emulation (x = none, dummy or emu, Falcon only)
.TP
+.B \-\-vme <x>
+Hatari doesn't have proper MegaSTE/TT VME emulation yet, but this
+controls access to related SCU registers (MegaSTE/TT only).
+
+With "dummy", (no-op) access is allowed (=VME HW), otherwise TOS v2
+and v3 crash on bootup on MegaSTE and TT. Supports VME tracing.
+
+With "none", register access causes errors (=no VME HW), which is
+needed for Linux to boot with TT emulation until there's full SCU
+interrupt support. No VME tracing support.
+.TP
.B \-\-timer\-d <bool>
Patch redundantly high Timer-D frequency set by TOS. This about doubles
Hatari speed (for ST/e emulation) as the original Timer-D frequency causes
diff --git a/doc/manual.html b/doc/manual.html
index fc8b5628..6032c8f3 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -997,6 +997,21 @@ megaste, tt or falcon)</p>
<p class="parameter">--blitter
<bool></p>
<p class="paramdesc">Enable blitter emulation (ST only)</p>
+<p class="parameter">--vme <x></p>
+<p class="paramdesc">
+Hatari doesn't have proper MegaSTE/TT VME emulation yet, but this
+controls access to related SCU registers (MegaSTE/TT only).
+</br></br>
+With "dummy", (no-op) access is allowed (=VME HW), otherwise TOS v2
+and v3 crash on bootup on MegaSTE and TT. Supports VME tracing.
+</br></br>
+With "empty", there's experimental, partial VME / SCU interrupt
+emulation, with no VME device.
+</br></br>
+With "none", register access causes errors (=no VME HW), which is
+needed for Linux to boot with TT emulation until there's full SCU
+interrupt support. No VME tracing support.
+</p>
<p class="parameter">--dsp <x></p>
<p class="paramdesc">Falcon DSP emulation (x = none, dummy
or emu, Falcon only)</p>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 390deca7..cec05b0a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -9,7 +9,7 @@ set(SOURCES
ncr5380.c paths.c psg.c printer.c resolution.c rs232.c reset.c rtc.c
scandir.c scc.c stMemory.c screen.c screenConvert.c screenSnapShot.c
shortcut.c sound.c spec512.c statusbar.c str.c tos.c utils.c
- vdi.c inffile.c video.c wavFormat.c xbios.c ymFormat.c lilo.c)
+ vdi.c vme.c inffile.c video.c wavFormat.c xbios.c ymFormat.c lilo.c)
# Disk image code is shared with the hmsa tool, so we put it into a library:
add_library(Floppy createBlankImage.c dim.c msa.c st.c zip.c)
diff --git a/src/configuration.c b/src/configuration.c
index cd43fbc6..339e469e 100644
--- a/src/configuration.c
+++ b/src/configuration.c
@@ -603,6 +603,7 @@ static const struct Config_Tag configs_System[] =
{ "nModelType", Int_Tag, &ConfigureParams.System.nMachineType },
{ "bBlitter", Bool_Tag, &ConfigureParams.System.bBlitter },
{ "nDSPType", Int_Tag, &ConfigureParams.System.nDSPType },
+ { "nVMEType", Int_Tag, &ConfigureParams.System.nVMEType },
{ "bPatchTimerD", Bool_Tag, &ConfigureParams.System.bPatchTimerD },
{ "bFastBoot", Bool_Tag, &ConfigureParams.System.bFastBoot },
{ "bFastForward", Bool_Tag, &ConfigureParams.System.bFastForward },
@@ -885,6 +886,7 @@ void Configuration_SetDefault(void)
ConfigureParams.System.nCpuLevel = 0;
ConfigureParams.System.nCpuFreq = 8; nCpuFreqShift = 0;
ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
+ ConfigureParams.System.nVMEType = VME_TYPE_DUMMY; /* for TOS MegaSTE detection */
ConfigureParams.System.bAddressSpace24 = true;
ConfigureParams.System.n_FPUType = FPU_NONE;
ConfigureParams.System.bCompatibleFPU = true; /* JIT */
@@ -1283,6 +1285,9 @@ void Configuration_MemorySnapShot_Capture(bool bSave)
MemorySnapShot_Store(&ConfigureParams.System.nMachineType, sizeof(ConfigureParams.System.nMachineType));
MemorySnapShot_Store(&ConfigureParams.System.bBlitter, sizeof(ConfigureParams.System.bBlitter));
MemorySnapShot_Store(&ConfigureParams.System.nDSPType, sizeof(ConfigureParams.System.nDSPType));
+ /* TODO: enable after VME_TYPE_EMPTY VME/SCU interrupt emulation is implemented
+ MemorySnapShot_Store(&ConfigureParams.System.nVMEType, sizeof(ConfigureParams.System.nVMEType));
+ */
MemorySnapShot_Store(&bOldRealTimeClock, sizeof(bOldRealTimeClock)); /* TODO: Can be removed later */
MemorySnapShot_Store(&ConfigureParams.System.bPatchTimerD, sizeof(ConfigureParams.System.bPatchTimerD));
MemorySnapShot_Store(&ConfigureParams.System.bAddressSpace24, sizeof(ConfigureParams.System.bAddressSpace24));
diff --git a/src/debug/log.c b/src/debug/log.c
index e52033cb..eb437479 100644
--- a/src/debug/log.c
+++ b/src/debug/log.c
@@ -150,6 +150,8 @@ static flagname_t TraceFlags[] = {
{ TRACE_MEM , "mem" } ,
+ { TRACE_VME , "vme" } ,
+
{ TRACE_ALL , "all" }
};
#endif /* ENABLE_TRACING */
diff --git a/src/debug/log.h b/src/debug/log.h
index bed5754e..9be233f9 100644
--- a/src/debug/log.h
+++ b/src/debug/log.h
@@ -182,6 +182,8 @@ extern char *Log_MatchTrace(const char *text, int state);
#define TRACE_MEM (1ll<<54)
+#define TRACE_VME (1ll<<55)
+
#define TRACE_NONE (0)
#define TRACE_ALL (~0)
diff --git a/src/includes/configuration.h b/src/includes/configuration.h
index 464e04d0..2b86203b 100644
--- a/src/includes/configuration.h
+++ b/src/includes/configuration.h
@@ -354,6 +354,12 @@ typedef enum
DSP_TYPE_EMU
} DSPTYPE;
+typedef enum
+{
+ VME_TYPE_NONE,
+ VME_TYPE_DUMMY
+} VMETYPE;
+
typedef enum
{
FPU_NONE = 0,
@@ -379,6 +385,7 @@ typedef struct
MACHINETYPE nMachineType;
bool bBlitter; /* TRUE if Blitter is enabled */
DSPTYPE nDSPType; /* how to "emulate" DSP */
+ VMETYPE nVMEType; /* how to "emulate" SCU/VME */
bool bPatchTimerD;
bool bFastBoot; /* Enable to patch TOS for fast boot */
bool bFastForward;
diff --git a/src/includes/vme.h b/src/includes/vme.h
new file mode 100644
index 00000000..0d788d9c
--- /dev/null
+++ b/src/includes/vme.h
@@ -0,0 +1,14 @@
+/*
+ Hatari - vme.h
+
+ This file is distributed under the GNU General Public License, version 2
+ or at your option any later version. Read the file gpl.txt for details.
+*/
+
+#ifndef HATARI_VME_H
+#define HATARI_VME_H
+
+extern void VME_SetAccess(void (**readtab)(void), void (**writetab)(void));
+extern void VME_Reset(void);
+
+#endif
diff --git a/src/ioMem.c b/src/ioMem.c
index 6b3c92e8..42f2b4cc 100644
--- a/src/ioMem.c
+++ b/src/ioMem.c
@@ -41,6 +41,7 @@ const char IoMem_fileid[] = "Hatari ioMem.c";
#include "log.h"
#include "scc.h"
#include "fdc.h"
+#include "vme.h"
static void (*pInterceptReadTable[0x8000])(void); /* Table with read access handlers */
@@ -202,13 +203,6 @@ static void IoMem_FixAccessForMegaSTE(void)
pInterceptReadTable[0xff8e23 - 0xff8000] = IoMem_VoidRead;
pInterceptWriteTable[0xff8e23 - 0xff8000] = IoMem_VoidWrite;
- /* VME bus - we don't support it yet, but TOS uses FF8E09 to detect the Mega-STE */
- for (addr = 0xff8e01; addr <= 0xff8e0f; addr += 2)
- {
- pInterceptReadTable[addr - 0xff8000] = IoMem_ReadWithoutInterception;
- pInterceptWriteTable[addr - 0xff8000] = IoMem_WriteWithoutInterception;
- }
-
/* The Mega-STE has a Z85C30 SCC serial port, too: */
for (addr = 0xff8c80; addr <= 0xff8c87; addr++)
{
@@ -328,6 +322,9 @@ void IoMem_Init(void)
else if ( ConfigureParams.System.nMachineType == MACHINE_MEGA_STE )
IoMem_FixAccessForMegaSTE();
+ /* Whether to support VME / SCU register access */
+ if (Config_IsMachineTT() || Config_IsMachineMegaSTE())
+ VME_SetAccess(pInterceptReadTable, pInterceptWriteTable);
/* Set registers for Falcon */
if (Config_IsMachineFalcon())
diff --git a/src/ioMemTabTT.c b/src/ioMemTabTT.c
index 4de5f246..8db2bc9e 100644
--- a/src/ioMemTabTT.c
+++ b/src/ioMemTabTT.c
@@ -180,14 +180,7 @@ const INTERCEPT_ACCESS_FUNC IoMemTable_TT[] =
{ 0xff8c80, 8, SCC_IoMem_ReadByte, SCC_IoMem_WriteByte }, /* SCC */
{ 0xff8c88, 8, IoMem_VoidRead_00, IoMem_VoidWrite }, /* No bus error here */
- { 0xff8e01, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception }, /* SCU system interrupt mask */
- { 0xff8e03, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception }, /* SCU system interrupt state */
- { 0xff8e05, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception }, /* SCU system interrupter */
- { 0xff8e07, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception }, /* SCU VME interrupter */
- { 0xff8e09, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception }, /* SCU general purpose 1 */
- { 0xff8e0b, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception }, /* SCU general purpose 2 */
- { 0xff8e0d, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception }, /* SCU VME interrupt mask */
- { 0xff8e0f, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception }, /* SCU VME interrupt state */
+ /* VME/SCU 0xff8e01-0xff8e0f registers set set at run-time in ioMem.c/vme.c for MegaSTE & TT */
{ 0xff9000, SIZE_WORD, IoMem_VoidRead, IoMem_VoidWrite }, /* No bus error here */
{ 0xff9200, SIZE_WORD, IoMemTabTT_ReadDIPSwitches, IoMem_VoidWrite }, /* DIP switches */
diff --git a/src/options.c b/src/options.c
index 7f852373..a4ccf3c0 100644
--- a/src/options.c
+++ b/src/options.c
@@ -157,6 +157,7 @@ enum {
OPT_MMU,
OPT_MACHINE, /* system options */
OPT_BLITTER,
+ OPT_VME,
OPT_DSP,
OPT_TIMERD,
OPT_FASTBOOT,
@@ -434,6 +435,8 @@ static const opt_t HatariOptions[] = {
"<bool>", "Use blitter emulation (ST only)" },
{ OPT_DSP, NULL, "--dsp",
"<x>", "DSP emulation (x = none/dummy/emu, Falcon only)" },
+ { OPT_VME, NULL, "--vme",
+ "<x>", "VME mode (x = none/dummy, MegaSTE/TT only)" },
{ OPT_TIMERD, NULL, "--timer-d",
"<bool>", "Patch Timer-D (about doubles ST emulation speed)" },
{ OPT_FASTBOOT, NULL, "--fast-boot",
@@ -1977,6 +1980,23 @@ bool Opt_ParseParameters(int argc, const char * const argv[])
bLoadAutoSave = false;
break;
+ case OPT_VME:
+ i += 1;
+ if (strcasecmp(argv[i], "dummy") == 0)
+ {
+ ConfigureParams.System.nVMEType = VME_TYPE_DUMMY;
+ }
+ else if (strcasecmp(argv[i], "none") == 0)
+ {
+ ConfigureParams.System.nVMEType = VME_TYPE_NONE;
+ }
+ else
+ {
+ return Opt_ShowError(OPT_VME, argv[i], "Unknown VME type");
+ }
+ bLoadAutoSave = false; /* TODO: needed? */
+ break;
+
/* sound options */
case OPT_YM_MIXING:
i += 1;
diff --git a/src/reset.c b/src/reset.c
index 83c18d73..3f668be5 100644
--- a/src/reset.c
+++ b/src/reset.c
@@ -36,6 +36,7 @@ const char Reset_fileid[] = "Hatari reset.c";
#include "vdi.h"
#include "nvram.h"
#include "video.h"
+#include "vme.h"
#include "falcon/videl.h"
#include "falcon/dsp.h"
#include "debugcpu.h"
@@ -84,7 +85,10 @@ static int Reset_ST(bool bCold)
{
Ncr5380_Reset();
}
-
+ if (Config_IsMachineTT() || Config_IsMachineMegaSTE())
+ {
+ VME_Reset();
+ }
if (Config_IsMachineFalcon())
{
DSP_Reset(); /* Reset the DSP */
diff --git a/src/vme.c b/src/vme.c
new file mode 100644
index 00000000..9cd328e0
--- /dev/null
+++ b/src/vme.c
@@ -0,0 +1,219 @@
+/*
+ Hatari - vme.c
+
+ This file is distributed under the GNU General Public License, version 2
+ or at your option any later version. Read the file gpl.txt for details.
+
+ VMEbus / SCU (System Control Unit) interrupt handling.
+
+ TODO: Non-cacheable TT VME card address mapping (word based data transfer):
+ - FE000000-FEFEFFFF VMEbus A24:D16
+ - FEFF0000-FEFFFFFF VMEbus A16:D16
+
+ TODO: more limited MegaSTE VME card address mapping:
+ - 00A00000-00DEFFFF VMEbus A24:D16
+ - 00DF0000-00DFFFFF VMEbus A16:D16
+
+ SCU IRQ info from TT HW reference:
+ - SCU generated IRQ1 is detected only by the MPU not the VMEbus
+ - SCU generated IRQ1 and IRQ3 are hardwired to the corresponding
+ priorities and are always auto vectored
+ - only interrupts 5 and 6 have external IACK pins and are capable
+ of generating vectored interrupts on the motherboard (and also
+ cause VME IRQ5 and IRQ6 respectively)
+ - VMEbus SYSFAIL generates a system (motherboard) IRQ7 to the MPU,
+ but does not not generate an IRQ7 to the VMEbus. The only other
+ source of an IRQ7 is a VMEbus card
+*/
+const char vme_fileid[] = "Hatari vme.c";
+
+#include "main.h"
+#include "configuration.h"
+#include "ioMem.h"
+#include "log.h"
+#include "vme.h"
+
+#define IOTAB_OFFSET 0xff8000
+
+/**
+ * SCU trace logging
+ */
+static void SCU_Trace(const char *access, const char *info)
+{
+ int addr = IoAccessCurrentAddress;
+ LOG_TRACE(TRACE_VME, "VME: SCU %s (0x%x): 0x%02x %s\n", access, addr, IoMem[addr], info);
+}
+
+/**
+ * Generic SCU reg read access function
+ */
+static void SCU_TraceRead(void)
+{
+ SCU_Trace("read ", "");
+}
+
+/**
+ * 0xff8e01 - masks interrupts generated on the system (board)
+ *
+ * Bits 1-7 -> IRQ 0-6, Bit 0 unused
+ *
+ * IRQ5 & IRQ6 can be serviced either by 68030 or VMEbus master,
+ * so they cannot be masked independently by VME & system masks.
+ */
+static void SCU_SysIntMask_WriteByte(void)
+{
+ SCU_Trace("write", "(system interrupt mask)");
+ /* TODO: implement interrupt masking */
+}
+/**
+ * 0xff8e03 - system interrupt status before they are masked with above
+ */
+static void SCU_SysIntState_ReadByte(void)
+{
+ SCU_Trace("read ", "(system interrupt state)");
+ /* TODO: provide non-masked interrupt status */
+}
+static void SCU_SysIntState_WriteByte(void)
+{
+ SCU_Trace("write", "(system interrupt state - READ ONLY)");
+}
+
+/**
+ * 0xff8e05 - SCU system interrupter
+ *
+ * Bit 0 controls VME IRQ1 setting/clearing
+ */
+static void SCU_SysInterrupter_WriteByte(void)
+{
+ if (IoMem[0xff8e05] & 0x1) {
+ SCU_Trace("write", "(system interrupter, IRQ1 set)");
+ /* TODO: generate auto vectored level 1 interrupt (IRQ1),
+ * interrupt CPU immediately unless masked off
+ */
+ } else {
+ SCU_Trace("write", "(system interrupter, IRQ1 clear)");
+ /* TODO: clear VMEbus IRQ1 */
+ }
+}
+/**
+ * 0xff8e07 - SCU VME interrupter
+ *
+ * Bit 0 controls VME IRQ3 setting/clearing
+ */
+static void SCU_VmeInterrupter_WriteByte(void)
+{
+ if (IoMem[0xff8e07] & 0x1) {
+ SCU_Trace("write", "(VME interrupter, IRQ3 set)");
+ /* TODO: generate VMEbus level 3 interrupt (IRQ3),
+ * interrupt CPU immediately unless masked off
+ *
+ * System responds to interrupt acknowledge cycle
+ * with the status ID of 0xFF
+ *
+ * Status word supplied by the card during acknowledge
+ * cycle is used as 030 interrupt vector.
+ */
+ } else {
+ SCU_Trace("write", "(VME interrupter, IRQ3 clear)");
+ /* TODO: clear VMEbus IRQ3 */
+ }
+}
+
+/**
+ * 0xff8e09 - SCU general purpose reg 1
+ */
+static void SCU_GenReg1_WriteByte(void)
+{
+ SCU_Trace("write", "(general reg 1)");
+}
+/**
+ * 0xff8e0b - SCU general purpose reg 2
+ */
+static void SCU_GenReg2_WriteByte(void)
+{
+ SCU_Trace("write", "(general reg 2)");
+}
+
+/**
+ * 0xff8e0d - masks interrupts generated by VMEbus sources
+ *
+ * Bits 1-7 -> IRQ 0-6, Bit 0 unused
+ */
+static void SCU_VmeIntMask_WriteByte(void)
+{
+ SCU_Trace("write", "(VME interrupt mask)");
+ /* TODO: implement interrupt masking */
+}
+/**
+ * 0xff8e0f - VME interrupt status before they are masked with above
+ */
+static void SCU_VmeIntState_ReadByte(void)
+{
+ SCU_Trace("read ", "(VME interrupt state)");
+ /* TODO: provide non-masked interrupt status */
+}
+static void SCU_VmeIntState_WriteByte(void)
+{
+ SCU_Trace("write", "(VME interrupt state - READ ONLY)");
+}
+
+/**
+ * Allow VME SCU register access and set up tracing
+ */
+static void SCUSetupTracing(void (**reads)(void), void (**writes)(void))
+{
+ reads[0xff8e01 - IOTAB_OFFSET] = SCU_TraceRead;
+ reads[0xff8e03 - IOTAB_OFFSET] = SCU_SysIntState_ReadByte;
+ reads[0xff8e05 - IOTAB_OFFSET] = SCU_TraceRead;
+ reads[0xff8e07 - IOTAB_OFFSET] = SCU_TraceRead;
+ reads[0xff8e09 - IOTAB_OFFSET] = SCU_TraceRead;
+ reads[0xff8e0b - IOTAB_OFFSET] = SCU_TraceRead;
+ reads[0xff8e0d - IOTAB_OFFSET] = SCU_TraceRead;
+ reads[0xff8e0f - IOTAB_OFFSET] = SCU_VmeIntState_ReadByte;
+
+ writes[0xff8e01 - IOTAB_OFFSET] = SCU_SysIntMask_WriteByte; /* SCU system interrupt mask */
+ writes[0xff8e03 - IOTAB_OFFSET] = SCU_SysIntState_WriteByte; /* SCU system interrupt state (RO) */
+ writes[0xff8e05 - IOTAB_OFFSET] = SCU_SysInterrupter_WriteByte; /* SCU system interrupter */
+ writes[0xff8e07 - IOTAB_OFFSET] = SCU_VmeInterrupter_WriteByte; /* SCU VME interrupter */
+ writes[0xff8e09 - IOTAB_OFFSET] = SCU_GenReg1_WriteByte; /* SCU general purpose 1 */
+ writes[0xff8e0b - IOTAB_OFFSET] = SCU_GenReg2_WriteByte; /* SCU general purpose 2 */
+ writes[0xff8e0d - IOTAB_OFFSET] = SCU_VmeIntMask_WriteByte; /* SCU VME interrupt mask */
+ writes[0xff8e0f - IOTAB_OFFSET] = SCU_VmeIntState_WriteByte; /* SCU VME interrupt state (RO) */
+}
+
+/**
+ * Set VME (SCU) register accessors based on Hatari configuration
+ * VME type setting
+ */
+void VME_SetAccess(void (**readtab)(void), void (**writetab)(void))
+{
+ /*
+ * Hatari does't emulate VME / SCU interrupts yet, but:
+ * - TOS2 crashes on MegaSTE unless it can access SCU regs
+ * - TOS3 crashes on TT unless it can access SCU regs
+ * - Linux freezes on boot if it can access SCU regs
+ * (as it tries then to use them, and they aren't
+ * fully emulated)
+ *
+ * => Use "dummy" mode for TOS 2 & 3, "none" for m68k Linux
+ */
+ if (ConfigureParams.System.nVMEType == VME_TYPE_DUMMY) {
+ SCUSetupTracing(readtab, writetab);
+ }
+}
+
+/**
+ * Reset VME / SCU registers and interrupts
+ */
+void VME_Reset(void)
+{
+ int addr;
+ /* docs say that all SCU regs are cleared on reset */
+ for (addr = 0xff8e01; addr <= 0xff8e0f; addr += 2) {
+ IoMem[addr] = 0;
+ }
+ /* TODO: TOS v2 & v3 crash unless gen reg 1 has this value, why? */
+ IoMem[0xff8e09] = 0x1;
+
+ /* TODO: clear all SCU interrupts */
+}
--
2.20.1
--------------B13909ECEF288043F33E2AFA--