This commit is contained in:
Jasmine Iwanek
2022-07-26 16:32:27 -04:00
parent 8c5c8e51e1
commit d1dd3997dc
20 changed files with 712 additions and 470 deletions

View File

@@ -162,7 +162,7 @@ acpi_raise_smi(void *priv, int do_smi)
}
}
else if ((dev->vendor == VEN_INTEL_ICH2) && do_smi && (dev->regs.smi_en & 1))
smi_line = 1;
smi_raise();
}
@@ -1459,7 +1459,7 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en)
break;
case VEN_INTEL_ICH2:
case VEN_VIA_596B:
size = 0x080;
size = 0x0080;
break;
}
@@ -1648,11 +1648,11 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p)
if (dev->vendor == VEN_INTEL)
dev->regs.glbsts |= 0x20;
else if (dev->vendor == VEN_INTEL_ICH2)
dev->regs.smi_sts |= 0x00000020;
if(dev->apm->do_smi)
dev->regs.smi_sts |= 0x00000020;
acpi_raise_smi(dev, dev->apm->do_smi);
} else
dev->apm->stat = val;
}
}
@@ -1670,10 +1670,10 @@ acpi_apm_in(uint16_t port, void *p)
else if (port == 0x0003)
ret = dev->apm->stat;
} else {
if (port == 0x0000)
ret = dev->apm->cmd;
else
ret = dev->apm->stat;
if (port == 0x0000)
ret = dev->apm->cmd;
else
ret = dev->apm->stat;
}
acpi_log("[%04X:%08X] APM read: %04X = %02X\n", CS, cpu_state.pc, port, ret);
@@ -1781,7 +1781,7 @@ acpi_init(const device_t *info)
acpi_log("Setting I/O handler at port B1\n");
io_sethandler(0x00b1, 0x0003, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
} else
io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
} else if (dev->vendor == VEN_VIA) {
dev->i2c = i2c_gpio_init("smbus_vt82c586b");
i2c_smbus = i2c_gpio_get_bus(dev->i2c);

View File

@@ -24,6 +24,7 @@
#include <86box/pci.h>
#include <86box/smram.h>
#include <86box/spd.h>
#include <86box/video.h>
#include <86box/chipset.h>
#ifdef ENABLE_INTEL_815EP_LOG
@@ -47,8 +48,33 @@ typedef struct intel_815ep_t
{
uint8_t pci_conf[256];
smram_t *lsmm_segment, *h_segment, *usmm_segment;
void *agpgart;
} intel_815ep_t;
static void
intel_815ep_agp_aperature(intel_815ep_t *dev)
{
uint32_t aperature_base, aperature_size_calc;
int aperature_size, aperature_enable;
aperature_base = dev->pci_conf[0x13] << 24;
aperature_size = !!(dev->pci_conf[0xb4] & 8);
aperature_size_calc = 1 << (aperature_size ? 25 : 24); /* 815EP has the choice of 64 & 32MB only */
aperature_enable = aperature_base != 0;
if(aperature_size)
dev->pci_conf[0x13] &= 0xfe;
if(aperature_enable)
intel_815ep_log("Intel 815EP AGP Aperature: Enabled at size 0x%x and size of %dMB\n", aperature_base, aperature_size ? 64 : 32);
else
intel_815ep_log("Intel 815EP AGP Aperature: AGP Aperature disabled\n");
agpgart_set_aperture(dev->agpgart, aperature_base, aperature_size_calc, aperature_enable);
}
static void
intel_usmm_segment_recalc(intel_815ep_t *dev, uint8_t val)
{
@@ -90,6 +116,8 @@ intel_lsmm_segment_recalc(intel_815ep_t *dev, uint8_t val)
smram_enable(dev->lsmm_segment, 0x000a0000, 0x000a0000, 0x20000, 0, 1);
break;
}
flushmmucache();
}
static void
@@ -104,6 +132,18 @@ intel_pam_recalc(int addr, uint8_t val)
mem_set_mem_state_both(region, 0x4000, ((val & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
mem_set_mem_state_both(region + 0x4000, 0x4000, ((val & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
}
flushmmucache_nopc();
}
static void
intel_815ep_gart_table(intel_815ep_t *dev)
{
uint32_t agp_gart_base = (dev->pci_conf[0xbb] << 24) | (dev->pci_conf[0xba] << 16) | (dev->pci_conf[0xb9] << 8);
intel_815ep_log("Intel 815EP AGP GART: GART address updated at 0x%x\n", agp_gart_base);
agpgart_set_gart(dev->agpgart, agp_gart_base);
}
static void
@@ -113,6 +153,9 @@ intel_815ep_write(int func, int addr, uint8_t val, void *priv)
intel_815ep_log("Intel 815EP MCH: dev->regs[%02x] = %02x\n", addr, val);
if(func)
return;
switch(addr)
{
case 0x05:
@@ -127,9 +170,10 @@ intel_815ep_write(int func, int addr, uint8_t val, void *priv)
if(dev->pci_conf[addr] != 0)
dev->pci_conf[addr] = val;
break;
case 0x13:
dev->pci_conf[addr] = val & 0xfe;
dev->pci_conf[addr] = val;
intel_815ep_agp_aperature(dev);
break;
case 0x50:
@@ -224,18 +268,22 @@ intel_815ep_write(int func, int addr, uint8_t val, void *priv)
case 0xb4:
dev->pci_conf[addr] = val & 8;
intel_815ep_agp_aperature(dev);
break;
case 0xb9:
dev->pci_conf[addr] = val & 0xf0;
intel_815ep_gart_table(dev);
break;
case 0xba:
dev->pci_conf[addr] = val;
intel_815ep_gart_table(dev);
break;
case 0xbb:
dev->pci_conf[addr] = val & 0x1f;
intel_815ep_gart_table(dev);
break;
case 0xbc ... 0xbd:
@@ -260,8 +308,13 @@ intel_815ep_read(int func, int addr, void *priv)
intel_815ep_log("Intel 815EP MCH: dev->regs[%02x] (%02x)\n", addr, dev->pci_conf[addr]);
if(func)
return 0xff;
if(addr == 0x51) // Bit 2 is Write Only. It cannot be read.
return dev->pci_conf[addr] & 3;
else if(addr == 0x52)
return intel_815ep_get_banking();
else
return dev->pci_conf[addr];
}
@@ -307,12 +360,16 @@ intel_815ep_reset(void *priv)
dev->pci_conf[0xa9] = 0x01; /* Hack: Brute Force AGP Enabled */
for(int i = 0x58; i <= 0x5f; i++) /* Reset PAM to defaults */
intel_815ep_agp_aperature(dev); /* Configure AGP Aperature */
for(int i = 0x59; i <= 0x5f; i++) /* Reset PAM to defaults */
intel_pam_recalc(i, 0);
intel_lsmm_segment_recalc(dev, 0); /* Reset LSMM SMRAM to defaults */
intel_usmm_segment_recalc(dev, 0); /* Reset USMM SMRAM to defaults */
intel_815ep_gart_table(dev); /* Reset AGP GART to defaults */
}
@@ -334,12 +391,21 @@ intel_815ep_init(const device_t *info)
intel_815ep_t *dev = (intel_815ep_t *)malloc(sizeof(intel_815ep_t));
memset(dev, 0, sizeof(intel_815ep_t));
/* Bus Speed(815EP runs at 133Mhz) */
if(cpu_busspeed >= 133333333)
cpu_set_pci_speed(133333333);
else
cpu_set_pci_speed(cpu_busspeed);
/* Device */
pci_add_card(PCI_ADD_NORTHBRIDGE, intel_815ep_read, intel_815ep_write, dev); /* Device 0: Intel 815EP MCH */
/* AGP Bridge */
device_add(&intel_815ep_agp_device);
/* AGP GART*/
dev->agpgart = device_add(&agpgart_device);
/* L1 & L2 Cache */
cpu_cache_int_enabled = 1;
cpu_cache_ext_enabled = 1;

View File

@@ -33,8 +33,8 @@
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/port_92.h>
#include <86box/smbus.h>
#include <86box/sound.h>
#include <86box/tco.h>
#include <86box/usb.h>
@@ -59,7 +59,7 @@ intel_ich2_log(const char *fmt, ...)
typedef struct intel_ich2_t
{
uint8_t pci_conf[5][256];
uint8_t pci_conf[7][256];
acpi_t *acpi;
intel_ich2_gpio_t *gpio;
@@ -85,143 +85,16 @@ intel_ich2_acpi_setup(intel_ich2_t *dev)
}
static void
intel_ich2_trap_update(void *priv)
intel_ich2_bioswe(intel_ich2_t *dev)
{
intel_ich2_t *dev = (intel_ich2_t *) priv;
uint16_t temp_addr = 0;
int bios_lock_enable = dev->pci_conf[0][0x4e] & 2;
int bios_write = dev->pci_conf[0][0x4e] & 1;
/* Hard Drives */
intel_ich2_device_trap_setup(1, 0x48, 0x01, 0x1f0, 8, 1, dev->trap_device[0]); // HDD's don't have a decode bit
intel_ich2_device_trap_setup(1, 0x48, 0x01, 0x3f6, 1, 1, dev->trap_device[0]);
intel_ich2_device_trap_setup(1, 0x48, 0x02, 0x170, 8, 1, dev->trap_device[1]);
intel_ich2_device_trap_setup(1, 0x48, 0x02, 0x376, 1, 1, dev->trap_device[1]);
/* COM A */
switch(dev->pci_conf[0][0xe0] & 7)
{
case 0:
temp_addr = 0x3f8;
break;
case 1:
temp_addr = 0x2f8;
break;
case 2:
temp_addr = 0x220;
break;
case 3:
temp_addr = 0x228;
break;
case 4:
temp_addr = 0x238;
break;
case 5:
temp_addr = 0x2e8;
break;
case 6:
temp_addr = 0x338;
break;
case 7:
temp_addr = 0x3e8;
break;
}
intel_ich2_device_trap_setup(!!(dev->pci_conf[0][0xe6] & 1), 0x48, 0x10, temp_addr, 8, 0, dev->trap_device[2]);
/* COM B */
switch((dev->pci_conf[0][0xe0] >> 4) & 7)
{
case 0:
temp_addr = 0x3f8;
break;
case 1:
temp_addr = 0x2f8;
break;
case 2:
temp_addr = 0x220;
break;
case 3:
temp_addr = 0x228;
break;
case 4:
temp_addr = 0x238;
break;
case 5:
temp_addr = 0x2e8;
break;
case 6:
temp_addr = 0x338;
break;
case 7:
temp_addr = 0x3e8;
break;
}
intel_ich2_device_trap_setup(!!(dev->pci_conf[0][0xe6] & 2), 0x48, 0x10, temp_addr, 8, 0, dev->trap_device[3]);
/* LPT */
switch(dev->pci_conf[0][0xe1] & 3)
{
case 0:
temp_addr = 0x378;
break;
case 1:
temp_addr = 0x278;
break;
case 2:
temp_addr = 0x3bc;
break;
}
intel_ich2_device_trap_setup(!!(dev->pci_conf[0][0xe6] & 4), 0x48, 0x10, temp_addr, 8, 0, dev->trap_device[4]);
/* FDC */
temp_addr = (dev->pci_conf[0][0xe1] & 0x10) ? 0x3f0 : 0x370;
intel_ich2_device_trap_setup(!!(dev->pci_conf[0][0xe6] & 8), 0x48, 0x10, temp_addr, 8, 0, dev->trap_device[5]);
/* MSS */
switch((dev->pci_conf[0][0xe2] >> 4) & 3)
{
case 0:
temp_addr = 0x530;
break;
case 1:
temp_addr = 0x604;
break;
case 2:
temp_addr = 0xe80;
break;
case 3:
temp_addr = 0xf40;
break;
}
intel_ich2_device_trap_setup(!!(dev->pci_conf[0][0xe6] & 0x40), 0x49, 0x04, 0x170, 8, 0, dev->trap_device[6]);
/* MIDI */
temp_addr = (dev->pci_conf[0][0xe2] & 8) ? 0x300 : 0x330;
intel_ich2_device_trap_setup(!!(dev->pci_conf[0][0xe6] & 0x20), 0x49, 0x08, temp_addr, 2, 0, dev->trap_device[7]);
/* KBC */
intel_ich2_device_trap_setup(1, 0x49, 0x10, 0x60, 4, 0, dev->trap_device[8]); // KBC doesn't have a decode bit
/* Adlib */
intel_ich2_device_trap_setup(!!(dev->pci_conf[0][0xe6] & 0x80), 0x49, 0x20, 0x388, 4, 0, dev->trap_device[9]);
if(bios_lock_enable)
if(bios_write) {
intel_ich2_log("Intel ICH2 BIOSWE: BIOSWE SMI was raised\n");
smi_raise();
}
}
static void
@@ -279,6 +152,146 @@ intel_ich2_nvr_handler(intel_ich2_t *dev)
nvr_at_handler(!!(dev->pci_conf[0][0xd8] & 4), 0x76, dev->nvr);
}
static void
intel_ich2_trap_update(void *priv)
{
intel_ich2_t *dev = (intel_ich2_t *) priv;
uint16_t temp_addr = 0;
/* Hard Drives */
intel_ich2_device_trap_setup(0x48, 0x01, 0x1f0, 8, dev->trap_device[0]); // HDD's don't have a decode bit
intel_ich2_device_trap_setup(0x48, 0x01, 0x3f6, 1, dev->trap_device[0]);
intel_ich2_device_trap_setup(0x48, 0x02, 0x170, 8, dev->trap_device[1]);
intel_ich2_device_trap_setup(0x48, 0x02, 0x376, 1, dev->trap_device[1]);
/* COM A */
switch(dev->pci_conf[0][0xe0] & 7)
{
case 0:
temp_addr = 0x3f8;
break;
case 1:
temp_addr = 0x2f8;
break;
case 2:
temp_addr = 0x220;
break;
case 3:
temp_addr = 0x228;
break;
case 4:
temp_addr = 0x238;
break;
case 5:
temp_addr = 0x2e8;
break;
case 6:
temp_addr = 0x338;
break;
case 7:
temp_addr = 0x3e8;
break;
}
intel_ich2_device_trap_setup(0x48, 0x10, temp_addr, 8, dev->trap_device[2]);
/* COM B */
switch((dev->pci_conf[0][0xe0] >> 4) & 7)
{
case 0:
temp_addr = 0x3f8;
break;
case 1:
temp_addr = 0x2f8;
break;
case 2:
temp_addr = 0x220;
break;
case 3:
temp_addr = 0x228;
break;
case 4:
temp_addr = 0x238;
break;
case 5:
temp_addr = 0x2e8;
break;
case 6:
temp_addr = 0x338;
break;
case 7:
temp_addr = 0x3e8;
break;
}
intel_ich2_device_trap_setup(0x48, 0x10, temp_addr, 8, dev->trap_device[3]);
/* LPT */
switch(dev->pci_conf[0][0xe1] & 3)
{
case 0:
temp_addr = 0x378;
break;
case 1:
temp_addr = 0x278;
break;
case 2:
temp_addr = 0x3bc;
break;
}
intel_ich2_device_trap_setup(0x48, 0x10, temp_addr, 8, dev->trap_device[4]);
/* FDC */
temp_addr = (dev->pci_conf[0][0xe1] & 0x10) ? 0x3f0 : 0x370;
intel_ich2_device_trap_setup(0x48, 0x10, temp_addr, 8, dev->trap_device[5]);
/* MSS (Note: There's no clear explaination about the SB Trap so only the MSS Trap is implementated) */
switch((dev->pci_conf[0][0xe2] >> 4) & 3)
{
case 0:
temp_addr = 0x530;
break;
case 1:
temp_addr = 0x604;
break;
case 2:
temp_addr = 0xe80;
break;
case 3:
temp_addr = 0xf40;
break;
}
intel_ich2_device_trap_setup(0x49, 0x04, temp_addr, 8, dev->trap_device[6]);
/* MIDI */
temp_addr = (dev->pci_conf[0][0xe2] & 8) ? 0x300 : 0x330;
intel_ich2_device_trap_setup(0x49, 0x08, temp_addr, 2, dev->trap_device[7]);
/* KBC */
intel_ich2_device_trap_setup(0x49, 0x10, 0x60, 4, dev->trap_device[8]); // KBC doesn't have a decode bit
/* Adlib */
intel_ich2_device_trap_setup(0x49, 0x20, 0x388, 4, dev->trap_device[9]);
}
static void
intel_ich2_function_disable(intel_ich2_t *dev)
{
@@ -288,6 +301,8 @@ uint16_t smbus_addr = (dev->pci_conf[3][0x21] << 8) | (dev->pci_conf[3][0x20] &
if(dev->pci_conf[0][0xf2] & 2) {
ide_pri_disable();
ide_sec_disable();
sff_bus_master_handler(dev->ide_drive[0], 0, 0);
sff_bus_master_handler(dev->ide_drive[1], 0, 0);
}
/* Disable USB Hub 1 */
@@ -296,7 +311,7 @@ if(dev->pci_conf[0][0xf2] & 4) {
}
/* Disable SMBus */
if(dev->pci_conf[0][0xf2] & 8) { //ICH2 Supports the ability of the SMBus Controller to be active even if it's PCI device is disabled
if(dev->pci_conf[0][0xf2] & 8) { // ICH2 Supports the ability of the SMBus Controller to be active even if it's PCI device is disabled
smbus_piix4_remap(dev->smbus, smbus_addr, dev->pci_conf[0][0xf3] & 1);
}
@@ -310,28 +325,26 @@ if(dev->pci_conf[0][0xf2] & 0x10) {
static void
intel_ich2_ide_setup(intel_ich2_t *dev)
{
uint16_t bm_base = (dev->pci_conf[1][0x21] << 8) | (dev->pci_conf[1][0x20] & 0xf0); /* Get the Bus Master Address */
ide_pri_disable();
ide_sec_disable();
sff_bus_master_handler(dev->ide_drive[0], 0, bm_base);
sff_bus_master_handler(dev->ide_drive[1], 0, bm_base + 8);
intel_ich2_log("Intel ICH2 IDE: Primary Channel is %s.\n", !!(dev->pci_conf[1][0x41] & 0x80) ? "Enabled" : "Disabled");
if(dev->pci_conf[1][0x41] & 0x80) {
intel_ich2_log("Intel ICH2 IDE: Primary Channel is enabled with Bus Master Address 0x%x.\n", bm_base);
ide_pri_enable();
sff_bus_master_handler(dev->ide_drive[0], 1, bm_base);
}
intel_ich2_log("Intel ICH2 IDE: Secondary Channel is %s.\n", !!(dev->pci_conf[1][0x43] & 0x80) ? "Enabled" : "Disabled");
if(dev->pci_conf[1][0x43] & 0x80) {
intel_ich2_log("Intel ICH2 IDE: Secondary Channel is enabled with Bus Master Address 0x%x.\n", bm_base + 8);
ide_sec_enable();
sff_bus_master_handler(dev->ide_drive[1], 1, bm_base + 8);
}
}
static void
intel_ich2_bus_master_setup(intel_ich2_t *dev)
{
uint16_t bm_base = ((dev->pci_conf[1][0x21] & 0xf0) << 8) | (dev->pci_conf[1][0x20] & 0xf0);
intel_ich2_log("Intel ICH2 IDE: IDE Bus Master address is 0x%04x.\n", bm_base);
sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf[1][0x04] & 1, bm_base);
sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf[1][0x04] & 1, bm_base + 8);
}
/* USB Controller functions */
static void
intel_ich2_usb_setup(int func, intel_ich2_t* dev)
@@ -386,9 +399,12 @@ intel_ich2_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x4e:
dev->pci_conf[func][addr] = val & 0x03;
if((val & 0x01) && ((val & 0x02) == 0x02))
smi_line = 1;
if(!(val & 2))
dev->pci_conf[func][addr] = val & 3;
else
dev->pci_conf[func][addr] = (val & 1) | 2;
intel_ich2_bioswe(dev);
break;
case 0x54:
@@ -432,6 +448,39 @@ intel_ich2_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[func][addr] = val & 0xfc;
break;
case 0xa0:
dev->pci_conf[func][addr] = val & 0x6c;
break;
case 0xa1:
dev->pci_conf[func][addr] = val & 6;
break;
case 0xa2:
dev->pci_conf[func][addr] &= val & 3;
break;
case 0xa4:
dev->pci_conf[func][addr] = val & 1;
dev->pci_conf[func][addr] &= val & 6;
break;
case 0xb8 ... 0xbb:
dev->pci_conf[func][addr] = val; /* GPIO Routing */
break;
case 0xc0:
dev->pci_conf[func][addr] = val & 0xf0;
break;
case 0xc4 ... 0xcb:
dev->pci_conf[func][addr] = val;
break;
case 0xcc ... 0xcd:
dev->pci_conf[func][addr] &= val;
break;
case 0xd0:
dev->pci_conf[func][addr] = val & 0x4f; /* Brute force APIC support as disabled */
break;
@@ -459,6 +508,7 @@ intel_ich2_write(int func, int addr, uint8_t val, void *priv)
case 0xe0:
dev->pci_conf[func][addr] = val & 0x77;
intel_ich2_trap_update(dev);
break;
case 0xe1:
@@ -481,9 +531,6 @@ intel_ich2_write(int func, int addr, uint8_t val, void *priv)
case 0xe5 ... 0xe6:
dev->pci_conf[func][addr] = val;
if(addr == 0xe6)
intel_ich2_trap_update(dev);
break;
case 0xe7:
@@ -523,7 +570,6 @@ intel_ich2_write(int func, int addr, uint8_t val, void *priv)
case 0x04:
dev->pci_conf[func][addr] = val & 5;
intel_ich2_ide_setup(dev);
intel_ich2_bus_master_setup(dev);
break;
case 0x07:
@@ -532,7 +578,7 @@ intel_ich2_write(int func, int addr, uint8_t val, void *priv)
case 0x20 ... 0x21:
dev->pci_conf[func][addr] = val & ((addr & 1) ? 0xff : (0xf0 | 1));
intel_ich2_bus_master_setup(dev);
intel_ich2_ide_setup(dev);
break;
case 0x2c ... 0x2f:
@@ -542,7 +588,9 @@ intel_ich2_write(int func, int addr, uint8_t val, void *priv)
case 0x40 ... 0x43:
dev->pci_conf[func][addr] = val & ((addr & 1) ? 0xf3 : 0xff);
intel_ich2_ide_setup(dev);
if((addr == 0x41) || (addr == 0x43))
intel_ich2_ide_setup(dev);
break;
case 0x44:
@@ -608,8 +656,9 @@ intel_ich2_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x3c:
dev->pci_conf[func][addr] = val;
smbus_piix4_get_irq(val, dev->smbus);
dev->pci_conf[func][addr] = val; /* 86Box doesn't give any capabilities to take the PCI IRQ pin, also */
smbus_piix4_get_irq(pci_get_int(0x1f, 2), dev->smbus); /* can't use pointers as whatever recieved from there is temporary. */
intel_ich2_log("Intel ICH2 SMBus: Got IRQ %d\n", pci_get_int(0x1f, 2));
break;
case 0x40:
@@ -821,7 +870,6 @@ static void
intel_ich2_close(void *priv)
{
intel_ich2_t *dev = (intel_ich2_t *)priv;
free(dev);
}

View File

@@ -24,15 +24,18 @@
#include <86box/hwm.h>
#include <86box/nsc366.h>
/* Fan Algorithms */
#define FAN_TO_REG(val, div) ((val) <= 100 ? 0 : 480000 / ((val) * (div)))
#define FAN_DIV_FROM_REG(val) (1 << (((val) >> 5) & 0x03))
#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 480000 / ((val) * (div)))
/* Voltage Algorithms */
#define IN_TO_REG(val, ref) ((val) < 0 ? 0 : (val) * 256 >= (ref) * 255 ? 255 : ((val) * 256 + (ref) / 2) / (ref))
#define IN_FROM_REG(val, ref) (((val) * (ref) + 128) / 256)
#define VREF (dev->vlm_config_global[0x08] & 2) ? 3025 : 2966 //VREF taken from pc87360.c
#define VLM_BANK dev->vlm_config_global[0x09]
/* Temperature Algorithms */
#define TEMP_TO_REG(val) ((val) < -55000 ? -55 : (val) > 127000 ? 127 : (val) < 0 ? ((val) - 500) / 1000 : ((val) + 500) / 1000)
#define TEMP_FROM_REG(val) ((val) * 1000)
#define TMS_BANK dev->tms_config_global[0x09]
@@ -60,7 +63,7 @@ nsc366_fscm_write(uint16_t addr, uint8_t val, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
nsc366_hwm_log("NSC366 Fan Control: Write 0x%02x to register 0x%02x\n", val, addr);
@@ -97,7 +100,7 @@ nsc366_fscm_read(uint16_t addr, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
switch(addr)
{
@@ -109,8 +112,11 @@ nsc366_fscm_read(uint16_t addr, void *priv)
case 0x07:
case 0x0a:
case 0x0d:
nsc366_hwm_log("NSC366 Fan Control: Reading %d RPM's from Bank %d\n", FAN_FROM_REG(dev->fscm_config[addr], FAN_DIV_FROM_REG(dev->fscm_config[0x06])), (addr - 7) / 3);
return dev->fscm_config[addr];
if(((addr == 0x07) && !!(dev->fscm_enable & 1)) || ((addr == 0x0a) && !!(dev->fscm_enable & 2)) || ((addr == 0x0d) && !!(dev->fscm_enable & 4))) {
nsc366_hwm_log("NSC366 Fan Control: Reading %d RPM's from Bank %d\n", FAN_FROM_REG(dev->fscm_config[addr], FAN_DIV_FROM_REG(dev->fscm_config[0x06])), (addr - 7) / 3);
return dev->fscm_config[addr];
}
else return 0;
default:
return 0;
@@ -135,7 +141,7 @@ nsc366_vlm_write(uint16_t addr, uint8_t val, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
if(addr <= 9)
nsc366_hwm_log("NSC366 Voltage Monitor: Write 0x%02x to register 0x%02x\n", val, addr);
@@ -186,7 +192,7 @@ nsc366_vlm_read(uint16_t addr, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
switch(addr)
{
@@ -202,8 +208,12 @@ nsc366_vlm_read(uint16_t addr, void *priv)
case 0x0b:
if (VLM_BANK < 13) {
nsc366_hwm_log("NSC366 Voltage Monitor: Reading %d Volts from Bank %d\n", IN_FROM_REG(dev->vlm_config_bank[VLM_BANK][1], VREF), VLM_BANK);
return dev->vlm_config_bank[VLM_BANK][1];
if (dev->vlm_config_bank[VLM_BANK][0] & 1) {
nsc366_hwm_log("NSC366 Voltage Monitor: Reading %d Volts from Bank %d\n", IN_FROM_REG(dev->vlm_config_bank[VLM_BANK][1], VREF), VLM_BANK);
return dev->vlm_config_bank[VLM_BANK][1];
}
else
return 0;
}
else
return 0;
@@ -231,7 +241,7 @@ nsc366_tms_write(uint16_t addr, uint8_t val, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
if(addr <= 9)
nsc366_hwm_log("NSC366 Temperature Monitor: Write 0x%02x to register 0x%02x\n", val, addr);
@@ -262,7 +272,7 @@ nsc366_tms_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0x0c ... 0x0e:
if(TMS_BANK < 13)
if(TMS_BANK < 3)
dev->tms_config_bank[TMS_BANK][addr - 0x0a] = val;
break;
}
@@ -274,9 +284,7 @@ nsc366_tms_read(uint16_t addr, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr++;
pclog("Reading %02x\n", addr);
addr &= 0x000f;
switch(addr)
{
@@ -285,12 +293,18 @@ nsc366_tms_read(uint16_t addr, void *priv)
case 0x0a:
case 0x0c ... 0x0e:
//return dev->tms_config_bank[TMS_BANK][addr - 0x0a];
return 1;
if(TMS_BANK < 4)
return dev->tms_config_bank[TMS_BANK][addr - 0x0a];
else return 0;
case 0x0b:
nsc366_hwm_log("NSC366 Temperature Monitor: Reading %d Degrees Celsius from Bank %d\n", TEMP_FROM_REG(dev->tms_config_bank[TMS_BANK][1]), TMS_BANK);
return dev->tms_config_bank[TMS_BANK][1];
if(TMS_BANK < 4) {
if (dev->vlm_config_bank[VLM_BANK][0] & 1) {
nsc366_hwm_log("NSC366 Temperature Monitor: Reading %d Degrees Celsius from Bank %d\n", TEMP_FROM_REG(dev->tms_config_bank[TMS_BANK][1]), TMS_BANK);
return dev->tms_config_bank[TMS_BANK][1];
}
else return 0;
}
default:
return 0;
@@ -316,6 +330,7 @@ nsc366_hwm_reset(void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
memset(dev->fscm_config, 0, sizeof(dev->fscm_config));
dev->fscm_enable = 0;
dev->fscm_addr = 0;
/* Get fan reports from defaults */
@@ -359,7 +374,7 @@ nsc366_hwm_init(const device_t *info)
nsc366_hwm_t *dev = (nsc366_hwm_t *)malloc(sizeof(nsc366_hwm_t));
memset(dev, 0, sizeof(nsc366_hwm_t));
/* Initialize the default values */
/* Initialize the default values (HWM is incomplete still) */
hwm_values_t defaults = {
{
3000, /* FAN 0 */
@@ -367,15 +382,24 @@ nsc366_hwm_init(const device_t *info)
3000 /* FAN 2 */
},
{
255, /* Temperature 0 */
255,
255,
155
30, /* Temperatures which are broken */
30,
30,
30
},
{
65535,
65535,
65535,
0, /* Voltages which are broken */
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
}
};
hwm_values = defaults;

View File

@@ -43,53 +43,51 @@ intel_ich2_trap_log(const char *fmt, ...)
#endif
void
intel_ich2_trap_set_acpi(intel_ich2_trap_t *trap, acpi_t *acpi)
intel_ich2_trap_set_acpi(intel_ich2_trap_t *dev, acpi_t *acpi)
{
trap->acpi = acpi;
dev->acpi = acpi;
}
static void
intel_ich2_trap_kick(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
{
intel_ich2_trap_t *trap = (intel_ich2_trap_t *) priv;
intel_ich2_trap_t *dev = (intel_ich2_trap_t *) priv;
intel_ich2_trap_log("Intel ICH2 Trap: Entered an I/O Trap. Provoking an SMI.\n");
acpi_raise_smi(trap->acpi, 1);
acpi_raise_smi(dev->acpi, 1);
}
void
intel_ich2_device_trap_setup(int enable, uint8_t acpi_reg, uint8_t acpi_reg_val, uint16_t addr, uint16_t size, int is_hdd, intel_ich2_trap_t *trap)
intel_ich2_device_trap_setup(uint8_t acpi_reg, uint8_t acpi_reg_val, uint16_t addr, uint16_t size, intel_ich2_trap_t *dev)
{
uint8_t acpi_trap_recieve = ((acpi_reg == 0x49) ? (trap->acpi->regs.devtrap_en >> 8) : (trap->acpi->regs.devtrap_en)) & 0xff; // Check if the decoded range is enabled on ACPIS
int acpi_enable = !!(acpi_trap_recieve & acpi_reg_val);
int trap_enabled = acpi_enable && enable;
uint8_t acpi_reg_recieve = dev->acpi->regs.devtrap_en >> ((acpi_reg & 1) * 8); /* Trap register is 16-bit on ranged ACPIBASE + 48h-49h */
int enable = !!(acpi_reg_recieve & acpi_reg_val); /* If enabled. Settle in the I/O trap */
if(trap_enabled)
{
intel_ich2_trap_log("Intel ICH2 Trap: An I/O has been enabled on range 0x%x\n", addr);
io_trap_add(intel_ich2_trap_kick, trap->trap);
}
if(enable)
intel_ich2_trap_log("Intel ICH2 Trap: A new trap was setted up on address 0x%x with the size of %d\n", addr, size);
io_trap_remap(trap->trap, trap_enabled, addr, size);
io_trap_remap(dev->trap, enable, addr, size);
}
static void
intel_ich2_trap_close(void *priv)
{
intel_ich2_trap_t *trap = (intel_ich2_trap_t *) priv;
io_trap_remove(trap->trap); // Remove the I/O Trap
free(trap);
intel_ich2_trap_t *dev = (intel_ich2_trap_t *) priv;
io_trap_remove(dev->trap); // Remove the I/O Trap
free(dev);
}
static void *
intel_ich2_trap_init(const device_t *info)
{
intel_ich2_trap_t *trap = (intel_ich2_trap_t *) malloc(sizeof(intel_ich2_trap_t));
memset(trap, 0, sizeof(intel_ich2_trap_t));
intel_ich2_trap_t *dev = (intel_ich2_trap_t *) malloc(sizeof(intel_ich2_trap_t));
memset(dev, 0, sizeof(intel_ich2_trap_t));
intel_ich2_trap_log("Intel ICH2 Trap: Starting a new Trap handler.");
return trap;
io_trap_add(intel_ich2_trap_kick, dev);
return dev;
}
const device_t intel_ich2_trap_device = {

View File

@@ -344,12 +344,11 @@ unknown_protocol:
}
/* Finish transfer. */
if (dev->local == SMBUS_INTEL_ICH2) {
/* ICH2 SMBus specific. Transfer on Byte command doesn't stop till their specific points. */
if (!dev->byte_rw)
i2c_stop(i2c_smbus, smbus_addr);
} else
i2c_stop(i2c_smbus, smbus_addr);
if (dev->local == SMBUS_INTEL_ICH2) // ICH2 SMBus specific. Transfer on Byte command doesn't stop till their specific points.
if (!dev->byte_rw)
i2c_stop(i2c_smbus, smbus_addr);
else
i2c_stop(i2c_smbus, smbus_addr);
}
break;

View File

@@ -15,6 +15,9 @@
*
* Copyright 2022 Tiseno100.
*/
/* Note: There's a TCO Timer too but for now it's of no use thus not implemented */
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -32,11 +35,9 @@
#include <86box/pit.h>
#include <86box/tco.h>
#ifdef ENABLE_TCO_LOG
int tco_do_log = ENABLE_TCO_LOG;
static void
tco_log(const char *fmt, ...)
{
@@ -68,7 +69,6 @@ tco_irq_update(tco_t *dev, uint16_t new_irq)
dev->tco_irq = new_irq;
}
void
tco_write(uint16_t addr, uint8_t val, tco_t *dev)
{
@@ -76,60 +76,60 @@ tco_write(uint16_t addr, uint8_t val, tco_t *dev)
tco_log("TCO: Write 0x%02x to Register 0x%02x\n", val, addr);
switch(addr) {
case 0x00:
dev->regs[addr] = val;
break;
case 0x00:
dev->regs[addr] = val;
break;
case 0x01:
dev->regs[addr] = val & 0x3f;
break;
case 0x01:
dev->regs[addr] = val & 0x3f;
break;
case 0x02: /* TCO Data in */
dev->regs[addr] = val;
dev->regs[0x04] |= 2;
smi_line = 1;
break;
case 0x02: /* TCO Data in */
dev->regs[addr] = val;
dev->regs[0x04] |= 2;
smi_line = 1;
break;
case 0x03: /* TCO Data out */
dev->regs[addr] = val;
dev->regs[0x04] |= 4;
picint(dev->tco_irq);
break;
case 0x03: /* TCO Data out */
dev->regs[addr] = val;
dev->regs[0x04] |= 4;
picint(1 << dev->tco_irq);
break;
case 0x04:
dev->regs[addr] &= 0x8f;
break;
dev->regs[addr] &= 0x8f;
break;
case 0x05:
dev->regs[addr] &= 0x1f;
break;
case 0x05:
dev->regs[addr] &= 0x1f;
break;
case 0x06:
dev->regs[addr] &= 0x07;
break;
case 0x06:
dev->regs[addr] &= 0x07;
break;
case 0x09:
if (val & 1) {
if (!nmi) /* If we're already on NMI */
nmi = 1;
case 0x09:
if (val & 1) {
if (!nmi) /* If we're already on NMI */
nmi_raise();
dev->regs[addr] = (dev->regs[addr] & 1) | val;
dev->regs[addr] &= val;
} else
dev->regs[addr] = 0x0f;
break;
dev->regs[addr] = (dev->regs[addr] & 1) | val;
dev->regs[addr] &= val;
} else
dev->regs[addr] = 0x0f;
break;
case 0x0a:
dev->regs[addr] = val & 0x06; // Intrusion Interrupt or SMI. We never get intruded so we never control it.
break;
case 0x0a:
dev->regs[addr] = val & 0x06; // Intrusion Interrupt or SMI. We never get intruded so we never control it.
break;
case 0x0c ... 0x0d:
dev->regs[addr] = val;
break;
case 0x0c ... 0x0d:
dev->regs[addr] = val;
break;
case 0x10:
dev->regs[addr] = val & 0x03;
break;
case 0x10:
dev->regs[addr] = val & 0x03;
break;
}
}
@@ -138,14 +138,12 @@ uint8_t
tco_read(uint16_t addr, tco_t *dev)
{
addr -= 0x60;
uint8_t ret = 0x00;
if (addr <= 0x10) {
tco_log("TCO: Read 0x%02x from Register 0x%02x\n", dev->regs[addr], addr);
ret = dev->regs[addr];
tco_log("TCO: Read 0x%02x from Register 0x%02x\n", dev->regs[addr], addr);
return dev->regs[addr];
}
return ret;
else return 0;
}
@@ -182,7 +180,6 @@ tco_init(const device_t *info)
return dev;
}
const device_t tco_device = {
.name = "Intel TCO",
.internal_name = "tco",

View File

@@ -22,7 +22,7 @@
extern "C" {
#endif
#include <86box/tco.h> /* TCO Header. Needed for Intel ICH chipsets. */
#include <86box/tco.h> /* TCO Header. Needed for the Intel ICH chipsets. */
#define ACPI_TIMER_FREQ 3579545
#define PM_FREQ ACPI_TIMER_FREQ
@@ -66,11 +66,11 @@ typedef struct
smicmd, gpio_dir,
gpio_val, muxcntrl, ali_soft_smi,
timer32, smireg,
gpireg[3], gporeg[4], tco[17],
gpireg[3], gporeg[4],
extiotrapsts, extiotrapen;
uint16_t pmsts, pmen,
pmcntrl, bus_addr_track, devact_sts,
devtrap_en, gpsts, gpsts1,
devtrap_en, gpsts, gpsts1,
gpen, gpen1, gpscien,
gpcntrl, gplvl, gpmux,
gpsel, gpsmien, pscntrl,

View File

@@ -14,6 +14,7 @@
*
* Copyright 2019,2020 Miran Grca.
*/
#ifndef EMU_CHIPSET_H
# define EMU_CHIPSET_H
@@ -99,31 +100,10 @@ extern const device_t slc90e66_device;
extern const device_t ioapic_device;
/* Intel ICH2 */
extern const device_t intel_815ep_device;
extern const device_t intel_ich2_device;
/* OPTi */
extern const device_t opti283_device;
extern const device_t opti291_device;
extern const device_t opti493_device;
extern const device_t opti495_device;
extern const device_t opti802g_device;
extern const device_t opti822_device;
extern const device_t opti895_device;
extern const device_t opti5x7_device;
/* SiS */
extern const device_t rabbit_device;
extern const device_t sis_85c401_device;
extern const device_t sis_85c460_device;
extern const device_t sis_85c461_device;
extern const device_t sis_85c471_device;
extern const device_t sis_85c496_device;
extern const device_t sis_85c496_ls486e_device;
extern const device_t sis_85c50x_device;
extern const device_t sis_5511_device;
extern const device_t sis_5571_device;
/* ST */
extern const device_t stpc_client_device;
@@ -172,4 +152,5 @@ extern const device_t phoenix_486_jumper_pci_device;
#if defined(DEV_BRANCH) && defined(USE_OLIVETTI)
extern const device_t olivetti_eva_device;
#endif
#endif /*EMU_CHIPSET_H*/

View File

@@ -20,7 +20,7 @@ typedef struct intel_ich2_trap_t
} intel_ich2_trap_t;
extern void intel_ich2_trap_set_acpi(intel_ich2_trap_t *trap, acpi_t *acpi);
extern void intel_ich2_device_trap_setup(int enable, uint8_t acpi_reg, uint8_t acpi_reg_val, uint16_t addr, uint16_t size, int is_hdd, intel_ich2_trap_t *trap);
extern void intel_ich2_device_trap_setup(uint8_t acpi_reg, uint8_t acpi_reg_val, uint16_t addr, uint16_t size, intel_ich2_trap_t *dev);
extern const device_t intel_ich2_trap_device;

View File

@@ -94,8 +94,7 @@ extern uint64_t PITCONST, ISACONST,
HERCCONST,
VGACONST1,
VGACONST2,
RTCCONST,
TCOCONST;
RTCCONST;
extern int refresh_at_enable;

View File

@@ -45,8 +45,11 @@ extern const device_t i82091aa_device;
extern const device_t i82091aa_398_device;
extern const device_t i82091aa_ide_pri_device;
extern const device_t i82091aa_ide_device;
/* National Semiconductor NSC366 (PC87366) */
extern const device_t nsc366_device;
extern const device_t nsc366_4f_device;
extern const device_t pc87306_device;
extern const device_t pc87307_device;
extern const device_t pc87307_15c_device;

View File

@@ -6,7 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* Definitions for the SMBus host controllers.
* Definitions for the SMBus host controllers.
*
*
*

View File

@@ -135,6 +135,9 @@ extern void spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint
extern void spd_write_drbs_with_ext(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit);
extern void spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit);
extern void spd_write_drbs_ali1621(uint8_t *regs, uint8_t reg_min, uint8_t reg_max);
extern void spd_write_drbs_intel_815ep(uint8_t *regs);
/* 815EP Memory Hack Specific */
extern void intel_815ep_spd_init(); /* Initialize the SPD (For the Machines) */
extern uint8_t intel_815ep_get_banking(); /* Get the Banking Configuration (For the Chipset) */
#endif /*EMU_SPD_H*/

View File

@@ -17,7 +17,6 @@ typedef struct
{
uint8_t regs[17];
uint16_t tco_irq;
pc_timer_t *tco_timer;
} tco_t;
extern const device_t tco_device;

View File

@@ -19,6 +19,7 @@
#include <86box/device.h>
#include <86box/chipset.h>
#include <86box/flash.h>
#include <86box/hwm.h>
#include <86box/sio.h>
#include <86box/spd.h>
#include <86box/clock.h>
@@ -30,7 +31,7 @@
*
* North Bridge: Intel 815E
* Super I/O: National Semiconductor NSC366 (PC87366)
* BIOS: AwardBIOS 6.00PG
* BIOS: Award BIOS 6.00PG
* Notes: No integrated ESS Solo & GPU
*/
int
@@ -48,27 +49,33 @@ machine_at_m6tsl_init(const machine_t *model)
pci_init(PCI_CONFIG_TYPE_1);
pci_register_bus_slot(0, 0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_bus_slot(0, 0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
pci_register_bus_slot(0, 0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0);
pci_register_bus_slot(0, 0x1e, PCI_CARD_BRIDGE, 0, 0, 0, 0);
pci_register_bus_slot(0, 0x1f, PCI_CARD_SOUTHBRIDGE, 1, 2, 8, 4);
pci_register_bus_slot(1, 0x01, PCI_CARD_AGP, 1, 2, 3, 4);
pci_register_bus_slot(2, 0x03, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_bus_slot(2, 0x04, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_bus_slot(2, 0x05, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_bus_slot(2, 0x06, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_bus_slot(2, 0x07, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_bus_slot(2, 0x08, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_bus_slot(2, 0x04, PCI_CARD_NORMAL, 3, 4, 5, 6);
pci_register_bus_slot(2, 0x05, PCI_CARD_NORMAL, 4, 5, 6, 7);
pci_register_bus_slot(2, 0x06, PCI_CARD_NORMAL, 5, 6, 7, 8);
pci_register_bus_slot(2, 0x07, PCI_CARD_NORMAL, 6, 7, 8, 1);
device_add(&intel_815ep_device); /* Intel 815EP MCH (This board has normally an i815E but this doesn't matter on our implementation) */
device_add(&intel_815ep_device); /* Intel 815EP MCH */
device_add(&intel_ich2_device); /* Intel ICH2 */
device_add(&nsc366_device); /* National Semiconductor NSC366 */
device_add(&sst_flash_49lf004_device); /* SST 4Mbit Firmware Hub */
device_add(ics9xxx_get(ICS9250_08)); /* ICS Clock Chip */
// device_add(ics9xxx_get(ICS9250_08)); /* ICS Clock Chip */
spd_register(SPD_TYPE_SDRAM, 0x7, 512);
return ret;
}
/*
* Biostar M6TSS
*
* North Bridge: Intel 815EP
* Super I/O: National Semiconductor NSC366 (PC87366)
* BIOS: AwardBIOS 6.00PG
* Notes:
*/
int
machine_at_m6tss_init(const machine_t *model)
{
@@ -135,8 +142,6 @@ machine_at_s2080_init(const machine_t *model)
pci_register_bus_slot(2, 0x05, PCI_CARD_NORMAL, 3, 4, 5, 6);
pci_register_bus_slot(2, 0x06, PCI_CARD_NORMAL, 4, 5, 6, 7);
pci_register_bus_slot(2, 0x07, PCI_CARD_NORMAL, 5, 6, 7, 8);
pci_register_bus_slot(2, 0x08, PCI_CARD_NORMAL, 6, 7, 8, 2); // 0x0a
pci_register_bus_slot(2, 0x09, PCI_CARD_NORMAL, 7, 8, 2, 3);
device_add(&intel_815ep_device); /* Intel 815EP MCH */
device_add(&intel_ich2_device); /* Intel ICH2 */

113
src/mem/815ep_spd_hack.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* 815EP SPD Memory Hack
*
* Authors: Tiseno100,
*
* Copyright 2022 Tiseno100.
*/
/* This is a hack because the 86Box SPD calculation algorithm is not made for the 815EP banking.
This SHOULD ONLY be used with the 815EP chipset. */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/spd.h>
#define MEM_SIZE_MB (mem_size >> 10)
uint8_t
intel_815ep_get_banking()
{
switch(MEM_SIZE_MB)
{
case 32:
return 0x02;
case 64:
return 0x01;
case 96:
return 0x21;
case 128:
return 0x04;
case 160:
return 0x24;
case 192:
return 0x06;
case 256:
return 0x07;
case 320:
return 0x57;
case 384:
return 0x97;
case 512:
return 0xed;
default:
return 0;
}
}
void
intel_815ep_spd_init()
{
switch(MEM_SIZE_MB)
{
case 32:
spd_register(SPD_TYPE_SDRAM, 1, 32);
break;
case 64:
spd_register(SPD_TYPE_SDRAM, 3, 32);
break;
case 96:
spd_register(SPD_TYPE_SDRAM, 7, 32);
break;
case 128:
spd_register(SPD_TYPE_SDRAM, 3, 64);
break;
case 160:
spd_register(SPD_TYPE_SDRAM, 7, 64);
break;
case 192:
spd_register(SPD_TYPE_SDRAM, 3, 96);
break;
case 256:
spd_register(SPD_TYPE_SDRAM, 3, 128);
break;
case 320:
spd_register(SPD_TYPE_SDRAM, 7, 128);
break;
case 384:
spd_register(SPD_TYPE_SDRAM, 7, 128);
break;
case 512:
spd_register(SPD_TYPE_SDRAM, 3, 256);
break;
default:
pclog("Intel 815EP SPD Hack: Illegal Size %dMB\n", MEM_SIZE_MB);
break;
}
}

View File

@@ -13,5 +13,5 @@
# Copyright 2020,2021 David Hrdlička.
#
add_library(mem OBJECT catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c rom.c
add_library(mem OBJECT 815ep_spd_hack.c catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c rom.c
smram.c spd.c sst_flash.c)

View File

@@ -594,7 +594,6 @@ const device_t sst_flash_49lf004_device = {
.internal_name = "sst_flash_49lf004",
.flags = 0,
.local = SST | SST49LF004 | SIZE_4M,
.init = sst_init,
.close = sst_close,
.reset = NULL,

View File

@@ -12,6 +12,7 @@
* Author: Tiseno100,
* Copyright 2022 Tiseno100.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -83,13 +84,13 @@ nsc366_fdc(nsc366_t *dev)
int dma_ch = dev->dma_select0[0] & 7;
if (dev->ld_activate[0]) {
nsc366_log("NSC 366 FDC: Reconfigured with Base: 0x%04x IRQ: %d DMA Channel: %d\n", base, irq, dma_ch);
fdc_set_base(dev->fdc, base);
fdc_set_irq(dev->fdc, irq);
fdc_set_dma_ch(dev->fdc, dma_ch);
fdc_update_densel_polarity(dev->fdc, !!(dev->dev_specific_config[0][0] & 0x20));
if (dev->dev_specific_config[0][0] & 8)
fdc_writeprotect(dev->fdc);
nsc366_log("NSC 366 FDC: Reconfigured with Base: 0x%04x IRQ: %d DMA Channel: %d\n", base, irq, dma_ch);
fdc_set_base(dev->fdc, base);
fdc_set_irq(dev->fdc, irq);
fdc_set_dma_ch(dev->fdc, dma_ch);
fdc_update_densel_polarity(dev->fdc, !!(dev->dev_specific_config[0][0] & 0x20));
if (dev->dev_specific_config[0][0] & 8)
fdc_writeprotect(dev->fdc);
}
}
@@ -102,9 +103,9 @@ nsc366_lpt(nsc366_t *dev)
int irq = (dev->int_num_irq[1] & 0x0f);
if (dev->ld_activate[1]) {
nsc366_log("NSC 366 LPT: Reconfigured with Base 0x%04x IRQ: %d\n", base ,irq);
lpt1_init(base);
lpt1_irq(irq);
nsc366_log("NSC 366 LPT: Reconfigured with Base 0x%04x IRQ: %d\n", base ,irq);
lpt1_init(base);
lpt1_irq(irq);
}
}
@@ -117,11 +118,23 @@ nsc366_uart(int uart, nsc366_t *dev)
int irq = (dev->int_num_irq[2 + uart] & 0x0f);
if (dev->ld_activate[2 + uart]) {
nsc366_log("NSC 366 UART Serial %d: Reconfigured with Base 0x%04x IRQ: %d\n", uart, base ,irq);
serial_setup(dev->uart[uart], base, irq);
nsc366_log("NSC 366 UART Serial %d: Reconfigured with Base 0x%04x IRQ: %d\n", uart, base ,irq);
serial_setup(dev->uart[uart], base, irq);
}
}
static void
nsc366_fscm_enable(nsc366_t *dev)
{
dev->hwm->fscm_enable = (!!(dev->dev_specific_config[1][9] & 1) << 2) | (!!(dev->dev_specific_config[0][9] & 0x20) << 1) | !!(dev->dev_specific_config[0][9] & 4);
/*
* Register F1h Bit 0: Fan Monitor 2 Enable
* Register F0h Bit 5: Fan Monitor 1 Enable
* Register F0h Bit 2: Fan Monitor 0 Enable
* Configuration Enables are not really needed
*/
}
static void
nsc366_fscm(nsc366_t *dev)
@@ -129,7 +142,7 @@ nsc366_fscm(nsc366_t *dev)
uint16_t base = (dev->io_base0[0][9] << 8) | (dev->io_base0[1][9] & 0xf0);
if (dev->ld_activate[9])
nsc366_log("NSC 366 Fan Control: Reconfigured with Base 0x%04x\n", base);
nsc366_log("NSC 366 Fan Control: Reconfigured with Base 0x%04x\n", base);
nsc366_update_fscm_io(dev->ld_activate[9], base, dev->hwm);
}
@@ -141,7 +154,7 @@ nsc366_vlm(nsc366_t *dev)
uint16_t base = (dev->io_base0[0][13] << 8) | (dev->io_base0[1][13] & 0xf0);
if (dev->ld_activate[13])
nsc366_log("NSC 366 Voltage Monitor: Reconfigured with Base 0x%04x\n", base);
nsc366_log("NSC 366 Voltage Monitor: Reconfigured with Base 0x%04x\n", base);
nsc366_update_vlm_io(dev->ld_activate[13], base, dev->hwm);
}
@@ -153,7 +166,7 @@ nsc366_tms(nsc366_t *dev)
uint16_t base = (dev->io_base0[0][14] << 8) | (dev->io_base0[1][14] & 0xf0);
if (dev->ld_activate[14])
nsc366_log("NSC 366 Temperature Monitor: Reconfigured with Base 0x%04x\n", base);
nsc366_log("NSC 366 Temperature Monitor: Reconfigured with Base 0x%04x\n", base);
nsc366_update_tms_io(dev->ld_activate[14], base, dev->hwm);
}
@@ -163,29 +176,30 @@ static void
nsc366_ldn_redirect(nsc366_t *dev)
{
switch(dev->ldn) {
case 0:
nsc366_fdc(dev);
break;
case 0:
nsc366_fdc(dev);
break;
case 1:
nsc366_lpt(dev);
break;
case 1:
nsc366_lpt(dev);
break;
case 2 ... 3:
nsc366_uart(dev->ldn == 3, dev);
break;
case 2 ... 3:
nsc366_uart(dev->ldn == 3, dev);
break;
case 9:
nsc366_fscm(dev);
break;
case 9:
nsc366_fscm_enable(dev);
nsc366_fscm(dev);
break;
case 13:
nsc366_vlm(dev);
break;
case 13:
nsc366_vlm(dev);
break;
case 14:
nsc366_tms(dev);
break;
case 14:
nsc366_tms(dev);
break;
}
}
@@ -195,105 +209,108 @@ nsc366_write(uint16_t addr, uint8_t val, void *priv)
{
nsc366_t *dev = (nsc366_t *)priv;
if (addr & 1) switch(dev->index) {
/* LDN */
case 0x07:
if (val <= 0x0e)
dev->ldn = val;
break;
if (addr & 1)
switch(dev->index) {
/* LDN */
case 0x07:
if (val <= 0x0e)
dev->ldn = val;
break;
/* Super I/O Configuration */
case 0x21:
if (!dev->siofc_lock) {
if (val & 0x80) {
dev->sio_config[dev->index - 0x20] = val | 0x80;
dev->siofc_lock = 1;
} else
dev->sio_config[dev->index - 0x20] = val;
}
break;
/* Super I/O Configuration */
case 0x20 ... 0x2d:
switch (dev->index - 0x20) {
case 0x01:
if (!dev->siofc_lock)
if (val & 0x80) {
dev->sio_config[dev->index - 0x20] = val | 0x80;
dev->siofc_lock = 1;
} else
dev->sio_config[dev->index - 0x20] = val;
break;
case 0x22:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val;
break;
case 0x02:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val;
break;
case 0x23:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val & 0xf7;
break;
case 0x03:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val & 0xf7;
break;
case 0x24:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val;
break;
case 0x04:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val;
break;
case 0x25:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val & 0xf3;
break;
case 0x05:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val & 0xf3;
break;
case 0x28:
dev->sio_config[dev->index - 0x20] = val & 0xf3;
break;
case 0x08:
dev->sio_config[dev->index - 0x20] = val & 0xf3;
break;
case 0x2a:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val;
break;
case 0x0a:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val;
break;
case 0x2b:
if (!dev->siofc_lock)
/* Force Case Intrusion to always off */
dev->sio_config[dev->index - 0x20] = val & 0x4f;
break;
case 0x0b:
if (!dev->siofc_lock)
dev->sio_config[dev->index - 0x20] = val & 0x4f; // Force Case Intrusion to always off
break;
case 0x2c ... 0x2d:
dev->sio_config[dev->index - 0x20] = val & 0xf3;
break;
case 0x0c ... 0x0d:
dev->sio_config[dev->index - 0x20] = val & 0xf3;
break;
}
break;
/* Logical Devices */
case 0x30:
dev->ld_activate[dev->ldn] = (val & 1) && (dev->sio_config[0] & 1);
nsc366_ldn_redirect(dev);
break;
/* Logical Devices */
case 0x30:
dev->ld_activate[dev->ldn] = (val & 1) && (dev->sio_config[0] & 1);
nsc366_ldn_redirect(dev);
break;
case 0x60 ... 0x61:
dev->io_base0[dev->index & 1][dev->ldn] = val;
nsc366_ldn_redirect(dev);
break;
case 0x60 ... 0x61:
dev->io_base0[dev->index & 1][dev->ldn] = val;
nsc366_ldn_redirect(dev);
break;
case 0x62 ... 0x63:
dev->io_base1[dev->index & 1][dev->ldn] = val;
nsc366_ldn_redirect(dev);
break;
case 0x62 ... 0x63:
dev->io_base1[dev->index & 1][dev->ldn] = val;
nsc366_ldn_redirect(dev);
break;
case 0x70:
dev->int_num_irq[dev->ldn] = val & 0x1f;
nsc366_ldn_redirect(dev);
break;
case 0x70:
dev->int_num_irq[dev->ldn] = val & 0x1f;
nsc366_ldn_redirect(dev);
break;
case 0x71:
dev->irq[dev->ldn] = val;
nsc366_ldn_redirect(dev);
break;
case 0x71:
dev->irq[dev->ldn] = val;
nsc366_ldn_redirect(dev);
break;
case 0x74:
dev->dma_select0[dev->ldn] = val & 0x1f;
nsc366_ldn_redirect(dev);
break;
case 0x74:
dev->dma_select0[dev->ldn] = val & 0x1f;
nsc366_ldn_redirect(dev);
break;
case 0x75:
dev->dma_select1[dev->ldn] = val & 0x1f;
nsc366_ldn_redirect(dev);
break;
case 0x75:
dev->dma_select1[dev->ldn] = val & 0x1f;
nsc366_ldn_redirect(dev);
break;
case 0xf0 ... 0xf2:
dev->dev_specific_config[dev->index - 0xf0][dev->ldn] = val;
nsc366_ldn_redirect(dev);
break;
case 0xf0 ... 0xf2:
dev->dev_specific_config[dev->index - 0xf0][dev->ldn] = val;
nsc366_ldn_redirect(dev);
break;
} else
dev->index = val;
dev->index = val;
}
@@ -301,54 +318,44 @@ static uint8_t
nsc366_read(uint16_t addr, void *priv)
{
nsc366_t *dev = (nsc366_t *)priv;
uint8_t ret = 0x00;
if (addr & 1) {
switch (dev->index) {
case 0x07:
ret = dev->ldn;
break;
switch (dev->index) {
case 0x07:
return dev->ldn;
case 0x20 ... 0x2d:
ret = dev->sio_config[dev->index - 0x20];
break;
case 0x20 ... 0x2d:
return dev->sio_config[dev->index - 0x20];
case 0x30:
ret = dev->ld_activate[dev->ldn];
break;
case 0x30:
return dev->ld_activate[dev->ldn];
case 0x60 ... 0x61:
ret = dev->io_base0[dev->index & 1][dev->ldn];
break;
case 0x60 ... 0x61:
return dev->io_base0[dev->index & 1][dev->ldn];
case 0x62 ... 0x63:
ret = dev->io_base1[dev->index & 1][dev->ldn];
break;
case 0x62 ... 0x63:
return dev->io_base1[dev->index & 1][dev->ldn];
case 0x70:
ret = dev->int_num_irq[dev->ldn];
break;
case 0x70:
return dev->int_num_irq[dev->ldn];
case 0x71:
ret = dev->irq[dev->ldn];
break;
case 0x71:
return dev->irq[dev->ldn];
case 0x74:
ret = dev->dma_select0[dev->ldn];
break;
case 0x74:
return dev->dma_select0[dev->ldn];
case 0x75:
ret = dev->dma_select1[dev->ldn];
break;
case 0x75:
return dev->dma_select1[dev->ldn];
case 0xf0 ... 0xf2:
ret = dev->dev_specific_config[dev->index - 0xf0][dev->ldn];
break;
}
} else
ret = dev->index;
case 0xf0 ... 0xf2:
return dev->dev_specific_config[dev->index - 0xf0][dev->ldn];
return ret;
default:
return 0;
}
}
else return dev->index;
}
@@ -446,6 +453,7 @@ nsc366_reset(void *priv)
dev->irq[9] = 0x03;
dev->dma_select0[9] = 0x04;
dev->dma_select1[9] = 0x04;
nsc366_fscm_enable(dev);
nsc366_fscm(dev);
/* Voltage Level Monitor */