From 10b66df24a2e38369667e6eb605714437df98681 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 7 Jan 2023 14:41:38 +0200 Subject: [PATCH] PCI board config validation support (FM801 interrupt disable bit is reserved) --- gfxboard.cpp | 4 ++-- include/pci_hw.h | 2 ++ pci.cpp | 18 ++++++++++++++++-- qemuvga/es1370.cpp | 2 +- qemuvga/ne2000.cpp | 6 +++--- sndboard.cpp | 19 ++++++++++++++----- 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/gfxboard.cpp b/gfxboard.cpp index 24dd0467..bc996d2f 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -3856,7 +3856,7 @@ static const struct pci_config voodoo3_pci_config = static const struct pci_board voodoo3_pci_board = { _T("VOODOO3"), - &voodoo3_pci_config, NULL, NULL, NULL, NULL, + &voodoo3_pci_config, NULL, NULL, NULL, NULL, NULL, { { voodoo3_mb0_lget, voodoo3_mb0_wget, voodoo3_mb0_bget, voodoo3_mb0_lput, voodoo3_mb0_wput, voodoo3_mb0_bput }, { voodoo3_mb1_lget, voodoo3_mb1_wget, voodoo3_mb1_bget, voodoo3_mb1_lput, voodoo3_mb1_wput, voodoo3_mb1_bput }, @@ -4058,7 +4058,7 @@ static const struct pci_config s3virge_pci_config = static const struct pci_board s3virge_pci_board = { _T("S3VIRGE"), - &s3virge_pci_config, NULL, NULL, NULL, NULL, + &s3virge_pci_config, NULL, NULL, NULL, NULL, NULL, { { s3virge_mb0_lget, s3virge_mb0_wget, s3virge_mb0_bget, s3virge_mb0_lput, s3virge_mb0_wput, s3virge_mb0_bput }, { NULL }, diff --git a/include/pci_hw.h b/include/pci_hw.h index 0523199f..4afbc767 100644 --- a/include/pci_hw.h +++ b/include/pci_hw.h @@ -12,6 +12,7 @@ typedef void (*pci_dev_irq)(struct pci_board_state*,bool); typedef bool(*pci_dev_init)(struct pci_board_state*,struct autoconfig_info*); typedef void(*pci_dev_reset)(struct pci_board_state*); typedef void(*pci_dev_hsync)(struct pci_board_state*); +typedef void(*pci_dev_chkcfg)(struct pci_board_state*, uae_u8*); typedef void(*pci_dev_free)(struct pci_board_state*); typedef uae_u8(*pci_get_config_func)(uaecptr); typedef void(*pci_put_config_func)(uaecptr, uae_u8); @@ -50,6 +51,7 @@ struct pci_board pci_dev_free free; pci_dev_reset reset; pci_dev_hsync hsync; + pci_dev_chkcfg chkcfg; pci_addrbank bars[MAX_PCI_BARS + 1]; bool dont_mask_io; pci_get_config_func pci_get_config; diff --git a/pci.cpp b/pci.cpp index c9491a35..3d845512 100644 --- a/pci.cpp +++ b/pci.cpp @@ -225,6 +225,7 @@ static void create_config_data(struct pci_board_state *s) { uae_u8 *d = s->config_data; const struct pci_config *c = &s->dynamic_config; + uae_u8 irq = d[5] & (1 << 3); // big endian, get/put functions will swap if needed. d[0] = c->device >> 8; @@ -232,6 +233,12 @@ static void create_config_data(struct pci_board_state *s) d[2] = c->vendor >> 8; d[3] = (uae_u8)c->vendor; + // Status register + // Clear Abort/Error flags, allow DEVSEL timing. + d[4] &= ~3; + // Allow only Fast back-to-back capable + d[5] &= ~(1 << 7); + d[8] = c->deviceclass >> 16; d[9] = c->deviceclass >> 8; d[10] = c->deviceclass; @@ -255,6 +262,14 @@ static void create_config_data(struct pci_board_state *s) d[0x3c] = c->max_latency; d[0x3d] = c->min_grant; d[0x3e] = c->interruptpin; + + // validate config + if (s->board->chkcfg) { + s->board->chkcfg(s, d); + } + + d[5] &= ~(1 << 3); + d[5] |= irq; } static struct pci_bridge *get_pci_bridge(uaecptr addr) @@ -1277,7 +1292,6 @@ static void REGPARAM2 pci_bridge_bput_2(uaecptr addr, uae_u32 b) } else { map_banks_z2(&dummy_bank, (pcib->baseaddress_2 + 0x10000) >> 16, 0x10000 >> 16); } - memory_map_dump(); } else if (offset == 11) { pcib->intena = b >> 4; } else if (offset == 0x40) { @@ -1688,7 +1702,7 @@ static const struct pci_config ncr_53c815_pci_config = static const struct pci_board ncr_53c815_pci_board = { _T("NCR53C815"), - &ncr_53c815_pci_config, NULL, NULL, NULL, NULL, + &ncr_53c815_pci_config, NULL, NULL, NULL, NULL, NULL, { { wildfire_lget, wildfire_wget, wildfire_bget, wildfire_lput, wildfire_wput, wildfire_bput }, { wildfire_lget, wildfire_wget, wildfire_bget, wildfire_lput, wildfire_wput, wildfire_bput }, diff --git a/qemuvga/es1370.cpp b/qemuvga/es1370.cpp index b0922a8e..e3e482a7 100644 --- a/qemuvga/es1370.cpp +++ b/qemuvga/es1370.cpp @@ -1201,7 +1201,7 @@ static const struct pci_config es1370_pci_config = const struct pci_board es1370_pci_board = { _T("ES1370"), - &es1370_pci_config, es1370_init, es1370_free, es1370_reset, NULL, + &es1370_pci_config, es1370_init, es1370_free, es1370_reset, NULL, NULL, { { es1370_lget, es1370_wget, es1370_bget, es1370_lput, es1370_wput, es1370_bput }, { NULL }, diff --git a/qemuvga/ne2000.cpp b/qemuvga/ne2000.cpp index 3316162b..a2a60ac0 100644 --- a/qemuvga/ne2000.cpp +++ b/qemuvga/ne2000.cpp @@ -1355,7 +1355,7 @@ static const struct pci_config ne2000_pci_config = const struct pci_board ne2000_pci_board = { _T("RTL8029"), - &ne2000_pci_config, ne2000_init, ne2000_free, ne2000_reset, ne2000_hsync_handler, + &ne2000_pci_config, ne2000_init, ne2000_free, ne2000_reset, ne2000_hsync_handler, NULL, { { ne2000_lget, ne2000_wget, ne2000_bget, ne2000_lput, ne2000_wput, ne2000_bput }, { NULL }, @@ -1370,7 +1370,7 @@ const struct pci_board ne2000_pci_board = const struct pci_board ne2000_pci_board_pcmcia = { _T("RTL8029"), - &ne2000_pci_config, ne2000_init_pcmcia, ne2000_free, ne2000_reset, ne2000_hsync_handler, + &ne2000_pci_config, ne2000_init_pcmcia, ne2000_free, ne2000_reset, ne2000_hsync_handler, NULL, { { ne2000_lget, ne2000_wget, ne2000_bget, ne2000_lput, ne2000_wput, ne2000_bput }, { NULL }, @@ -1386,7 +1386,7 @@ const struct pci_board ne2000_pci_board_pcmcia = const struct pci_board ne2000_pci_board_x86 = { _T("RTL8029"), - &ne2000_pci_config, ne2000_init_x86, ne2000_free, ne2000_reset, ne2000_hsync_handler, + &ne2000_pci_config, ne2000_init_x86, ne2000_free, ne2000_reset, ne2000_hsync_handler, NULL, { { ne2000_lget, ne2000_wget, ne2000_bget, ne2000_lput, ne2000_wput, ne2000_bput }, { NULL }, diff --git a/sndboard.cpp b/sndboard.cpp index 9d19c3dd..2fdb8a46 100644 --- a/sndboard.cpp +++ b/sndboard.cpp @@ -2683,19 +2683,28 @@ static bool fm801_init(struct pci_board_state *pcibs, struct autoconfig_info *ac return false; } +static void fm801_config(struct pci_board_state *pcibs, uae_u8 *cfg) +{ + // Status register is read-only + cfg[4] = 0x02; + cfg[5] = 0x80; + // Clear command register reserved + cfg[6] &= 3; +} + static const struct pci_config fm801_pci_config = { - 0x1319, 0x0801, 0, 0, 0xb2, 0x040100, 0x80, 0x1319, 0x1319, 1, 0x04, 0x28, { 128 | 1, 0, 0, 0, 0, 0, 0 } + 0x1319, 0x0801, 0, 0x280, 0xb2, 0x040100, 0x80, 0x1319, 0x1319, 1, 0x04, 0x28, { 128 | 1, 0, 0, 0, 0, 0, 0 } }; static const struct pci_config fm801_pci_config_func1 = { - 0x1319, 0x0802, 0, 0, 0xb2, 0x098000, 0x80, 0x1319, 0x1319, 0, 0x04, 0x28, { 16 | 1, 0, 0, 0, 0, 0, 0 } + 0x1319, 0x0802, 0, 0x280, 0xb2, 0x098000, 0x80, 0x1319, 0x1319, 0, 0x04, 0x28, { 16 | 1, 0, 0, 0, 0, 0, 0 } }; const struct pci_board fm801_pci_board = { _T("FM801"), - &fm801_pci_config, fm801_init, fm801_free, fm801_reset, fm801_hsync_handler, + &fm801_pci_config, fm801_init, fm801_free, fm801_reset, fm801_hsync_handler, fm801_config, { { fm801_lget, fm801_wget, fm801_bget, fm801_lput, fm801_wput, fm801_bput }, { NULL }, @@ -2711,7 +2720,7 @@ const struct pci_board fm801_pci_board = const struct pci_board fm801_pci_board_func1 = { _T("FM801-2"), - &fm801_pci_config_func1, NULL, NULL, NULL, NULL, + &fm801_pci_config_func1, NULL, NULL, NULL, NULL, fm801_config, { { fm801_lget, fm801_wget, fm801_bget, fm801_lput, fm801_wput, fm801_bput }, { NULL }, @@ -2805,7 +2814,7 @@ static const struct pci_config solo1_pci_config = const struct pci_board solo1_pci_board = { _T("SOLO1"), - &solo1_pci_config, solo1_init, solo1_free, solo1_reset, NULL, + &solo1_pci_config, solo1_init, solo1_free, solo1_reset, NULL, NULL, { { solo1_lget, solo1_wget, solo1_bget, solo1_lput, solo1_wput, solo1_bput }, { solo1_lget, solo1_wget, solo1_bget, solo1_lput, solo1_wput, solo1_bput }, -- 2.47.3