diff --git a/src/acpi.c b/src/acpi.c index 2839aec3e..1617768a1 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -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); diff --git a/src/chipset/intel_815ep.c b/src/chipset/intel_815ep.c index d56045d08..e15b74ee8 100644 --- a/src/chipset/intel_815ep.c +++ b/src/chipset/intel_815ep.c @@ -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; diff --git a/src/chipset/intel_ich2.c b/src/chipset/intel_ich2.c index aeb890232..4b5868742 100644 --- a/src/chipset/intel_ich2.c +++ b/src/chipset/intel_ich2.c @@ -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); } diff --git a/src/device/hwm_nsc366.c b/src/device/hwm_nsc366.c index e0cae6e29..90bbe1666 100644 --- a/src/device/hwm_nsc366.c +++ b/src/device/hwm_nsc366.c @@ -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; diff --git a/src/device/intel_ich2_trap.c b/src/device/intel_ich2_trap.c index 0030f9639..fd05db205 100644 --- a/src/device/intel_ich2_trap.c +++ b/src/device/intel_ich2_trap.c @@ -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 = { diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index 4673b39a0..2bf5fc5b4 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -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; diff --git a/src/device/tco.c b/src/device/tco.c index dc54fe364..bd6e3163e 100644 --- a/src/device/tco.c +++ b/src/device/tco.c @@ -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 #include #include @@ -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", diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 8c70bea78..4d84f0089 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -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, diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 8d3a663fb..c97287702 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -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*/ diff --git a/src/include/86box/intel_ich2_trap.h b/src/include/86box/intel_ich2_trap.h index 0905bdb24..968f79a98 100644 --- a/src/include/86box/intel_ich2_trap.h +++ b/src/include/86box/intel_ich2_trap.h @@ -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; diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index f40210ac1..95541014b 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -94,8 +94,7 @@ extern uint64_t PITCONST, ISACONST, HERCCONST, VGACONST1, VGACONST2, - RTCCONST, - TCOCONST; + RTCCONST; extern int refresh_at_enable; diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 53c675fb5..e872ace6c 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -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; diff --git a/src/include/86box/smbus.h b/src/include/86box/smbus.h index e365f38b9..f93bb8367 100644 --- a/src/include/86box/smbus.h +++ b/src/include/86box/smbus.h @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Definitions for the SMBus host controllers. + * Definitions for the SMBus host controllers. * * * diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index 71a250009..3605e9243 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -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*/ diff --git a/src/include/86box/tco.h b/src/include/86box/tco.h index bd5c0a16f..fa3a3f437 100644 --- a/src/include/86box/tco.h +++ b/src/include/86box/tco.h @@ -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; diff --git a/src/machine/m_at_ich2.c b/src/machine/m_at_ich2.c index 2a0617276..df9aadcca 100644 --- a/src/machine/m_at_ich2.c +++ b/src/machine/m_at_ich2.c @@ -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 */ diff --git a/src/mem/815ep_spd_hack.c b/src/mem/815ep_spd_hack.c new file mode 100644 index 000000000..e3f1efd9e --- /dev/null +++ b/src/mem/815ep_spd_hack.c @@ -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 +#include +#include +#include +#include +#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; + } +} diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index 9eae342fd..ac8d53fcc 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -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) diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index d132b8105..61ca9c46c 100644 --- a/src/mem/sst_flash.c +++ b/src/mem/sst_flash.c @@ -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, diff --git a/src/sio/sio_nsc366.c b/src/sio/sio_nsc366.c index 91e40b72b..fcba16954 100644 --- a/src/sio/sio_nsc366.c +++ b/src/sio/sio_nsc366.c @@ -12,6 +12,7 @@ * Author: Tiseno100, * Copyright 2022 Tiseno100. */ + #include #include #include @@ -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 */