Improved the VIA VPX code

Moved host bridge write code via_vpx_write.
Default registers are now on via_vpx_init.
Read only registers are hardcoded.
This commit is contained in:
tiseno100
2020-04-29 10:50:53 +03:00
committed by GitHub
parent 19eed0a404
commit 570034cb09

View File

@@ -12,6 +12,9 @@ VIA Apollo VPX North Bridge emulation
VT82C585VPX used in the Zida Tomato TX100 board
based on the model of VIA MVP3 by mooch & Sarah
There's also a SOYO board using the ETEQ chipset which is a rebranded
VPX + 586B but fails to save on CMOS properly.
Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
Copyright(C) 2020 Tiseno100
Copyright(C) 2020 Melissa Goad
@@ -35,7 +38,7 @@ Copyright(C) 2020 Miran Grca
typedef struct via_vpx_t
{
uint8_t pci_conf[2][256];
uint8_t pci_conf[256];
} via_vpx_t;
static void
@@ -60,109 +63,63 @@ vpx_map(uint32_t addr, uint32_t size, int state)
}
static void
via_vpx_pci_regs(via_vpx_t *dev)
{
memset(dev, 0, sizeof(via_vpx_t));
// Host Bridge registers
dev->pci_conf[0][0x00] = 0x06; // VIA
dev->pci_conf[0][0x01] = 0x11;
dev->pci_conf[0][0x02] = 0x85; // VT82C585VPX
dev->pci_conf[0][0x03] = 0x05;
dev->pci_conf[0][0x04] = 7; // Command
dev->pci_conf[0][0x05] = 0;
dev->pci_conf[0][0x06] = 0xa0; // Status
dev->pci_conf[0][0x07] = 2;
dev->pci_conf[0][0x09] = 0; // Program Interface
dev->pci_conf[0][0x0a] = 0; // Sub Class Code
dev->pci_conf[0][0x0b] = 6; // Base Class Code
dev->pci_conf[0][0x0c] = 0; // reserved
dev->pci_conf[0][0x0d] = 0; // Latency Timer
dev->pci_conf[0][0x0e] = 0; // Header Type
dev->pci_conf[0][0x0f] = 0; // Built-in Self test
dev->pci_conf[0][0x58] = 0x40; // DRAM Configuration 1
dev->pci_conf[0][0x59] = 5; // DRAM Configuration 2
dev->pci_conf[0][0x5a] = 1; // Bank 0 Ending
dev->pci_conf[0][0x5b] = 1; // Bank 1 Ending
dev->pci_conf[0][0x5c] = 1; // Bank 2 Ending
dev->pci_conf[0][0x5d] = 1; // Bank 3 Ending
dev->pci_conf[0][0x5e] = 1; // Bank 4 Ending
dev->pci_conf[0][0x5f] = 1; // Bank 5 Ending
dev->pci_conf[0][0x64] = 0xab; // DRAM reference timing
}
static void
host_bridge_write(int func, int addr, uint8_t val, void *priv)
via_vpx_write(int func, int addr, uint8_t val, void *priv)
{
via_vpx_t *dev = (via_vpx_t *) priv;
// Read-Only registers. Exact same as MVP3
if ((addr < 4) || ((addr >= 5) && (addr < 7)) || ((addr >= 8) && (addr < 0xd)) || ((addr >= 0xe) && (addr < 0x12)) ||
((addr >= 0x14) && (addr < 0x50)) || ((addr >= 0x79) && (addr < 0x7e)) || ((addr >= 0x85) && (addr < 0x88)) ||
((addr >= 0x8c) && (addr < 0xa8)) || ((addr >= 0xad) && (addr < 0xfd)))
return;
// Read-Only registers
switch(addr){
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0e: case 0x0f:
return;
}
switch(addr){
case 0x04: // Command
dev->pci_conf[0][0x04] = (dev->pci_conf[0][0x04] & ~0x40) | (val & 0x40);
case 0x04: // Command. On Bitfield 6 RW
dev->pci_conf[0x04] = (dev->pci_conf[0x04] & ~0x40) | (val & 0x40);
case 0x07: // Status
dev->pci_conf[0][0x07] &= ~(val & 0xb0);
dev->pci_conf[0x07] &= ~(val & 0xb0);
break;
case 0x61: // Shadow RAM control 1
if ((dev->pci_conf[0][0x61] ^ val) & 0x03)
if ((dev->pci_conf[0x61] ^ val) & 0x03)
vpx_map(0xc0000, 0x04000, val & 0x03);
if ((dev->pci_conf[0][0x61] ^ val) & 0x0c)
if ((dev->pci_conf[0x61] ^ val) & 0x0c)
vpx_map(0xc4000, 0x04000, (val & 0x0c) >> 2);
if ((dev->pci_conf[0][0x61] ^ val) & 0x30)
if ((dev->pci_conf[0x61] ^ val) & 0x30)
vpx_map(0xc8000, 0x04000, (val & 0x30) >> 4);
if ((dev->pci_conf[0][0x61] ^ val) & 0xc0)
if ((dev->pci_conf[0x61] ^ val) & 0xc0)
vpx_map(0xcc000, 0x04000, (val & 0xc0) >> 6);
dev->pci_conf[0][0x61] = val;
dev->pci_conf[0x61] = val;
return;
case 0x62: // Shadow RAM Control 2
if ((dev->pci_conf[0][0x62] ^ val) & 0x03)
if ((dev->pci_conf[0x62] ^ val) & 0x03)
vpx_map(0xd0000, 0x04000, val & 0x03);
if ((dev->pci_conf[0][0x62] ^ val) & 0x0c)
if ((dev->pci_conf[0x62] ^ val) & 0x0c)
vpx_map(0xd4000, 0x04000, (val & 0x0c) >> 2);
if ((dev->pci_conf[0][0x62] ^ val) & 0x30)
if ((dev->pci_conf[0x62] ^ val) & 0x30)
vpx_map(0xd8000, 0x04000, (val & 0x30) >> 4);
if ((dev->pci_conf[0][0x62] ^ val) & 0xc0)
if ((dev->pci_conf[0x62] ^ val) & 0xc0)
vpx_map(0xdc000, 0x04000, (val & 0xc0) >> 6);
dev->pci_conf[0][0x62] = val;
dev->pci_conf[0x62] = val;
return;
case 0x63: // Shadow RAM Control 3
if ((dev->pci_conf[0][0x63] ^ val) & 0x30) {
if ((dev->pci_conf[0x63] ^ val) & 0x30) {
vpx_map(0xf0000, 0x10000, (val & 0x30) >> 4);
shadowbios = (((val & 0x30) >> 4) & 0x02);
}
if ((dev->pci_conf[0][0x63] ^ val) & 0xc0)
if ((dev->pci_conf[0x63] ^ val) & 0xc0)
vpx_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
dev->pci_conf[0][0x63] = val;
dev->pci_conf[0x63] = val;
return;
//In case we throw somewhere
default:
dev->pci_conf[0][addr] = val;
dev->pci_conf[addr] = val;
break;
}
}
@@ -175,19 +132,13 @@ via_vpx_read(int func, int addr, void *priv)
switch(func) {
case 0:
ret = dev->pci_conf[0][addr];
ret = dev->pci_conf[addr];
break;
}
return ret;
}
static void
via_vpx_write(int func, int addr, uint8_t val, void *priv)
{
host_bridge_write(func, addr, val, priv);
}
static void
via_vpx_reset(void *priv)
{
@@ -198,10 +149,47 @@ static void *
via_vpx_init(const device_t *info)
{
via_vpx_t *dev = (via_vpx_t *) malloc(sizeof(via_vpx_t));
memset(dev, 0, sizeof(via_vpx_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, via_vpx_read, via_vpx_write, dev);
via_vpx_pci_regs(dev);
dev->pci_conf[0x00] = 0x06; // VIA
dev->pci_conf[0x01] = 0x11;
dev->pci_conf[0x02] = 0x85; // VT82C585VPX
dev->pci_conf[0x03] = 0x05;
dev->pci_conf[0x04] = 7; // Command
dev->pci_conf[0x05] = 0;
dev->pci_conf[0x06] = 0xa0; // Status
dev->pci_conf[0x07] = 2;
dev->pci_conf[0x09] = 0; // Program Interface
dev->pci_conf[0x0a] = 0; // Sub Class Code
dev->pci_conf[0x0b] = 6; // Base Class Code
dev->pci_conf[0x0c] = 0; // reserved
dev->pci_conf[0x0d] = 0; // Latency Timer
dev->pci_conf[0x0e] = 0; // Header Type
dev->pci_conf[0x0f] = 0; // Built-in Self test
dev->pci_conf[0x58] = 0x40; // DRAM Configuration 1
dev->pci_conf[0x59] = 0x05; // DRAM Configuration 2
dev->pci_conf[0x5a] = 1; // Bank 0 Ending
dev->pci_conf[0x5b] = 1; // Bank 1 Ending
dev->pci_conf[0x5c] = 1; // Bank 2 Ending
dev->pci_conf[0x5d] = 1; // Bank 3 Ending
dev->pci_conf[0x5e] = 1; // Bank 4 Ending
dev->pci_conf[0x5f] = 1; // Bank 5 Ending
dev->pci_conf[0x64] = 0xab; // DRAM reference timing
return dev;
}