Better ACPI implementation (currently only on PIIX4/PIIX4E/SMSC southbridges), finished the SMSC southbridge (but the Atrend BIOS still hangs, need to figure out why), and fixed Tandy EEPROM saving.
This commit is contained in:
@@ -1101,8 +1101,6 @@ i4x0_reset(void *priv)
|
||||
for (i = 0; i <= dev->max_func; i++)
|
||||
memset(dev->regs_locked[i], 0x00, 256 * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
// smbase = 0xa0000;
|
||||
}
|
||||
|
||||
|
||||
@@ -1315,8 +1313,6 @@ static void
|
||||
i4x0_write(regs[0x5f], 0x5f, 0x00, dev);
|
||||
i4x0_write(regs[0x72], 0x72, 0x00, dev);
|
||||
|
||||
// smbase = 0xa0000;
|
||||
|
||||
if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) {
|
||||
regs = (uint8_t *) dev->regs[1];
|
||||
|
||||
|
||||
@@ -1077,6 +1077,9 @@ enter_smm(int in_hlt)
|
||||
smm_in_hlt = in_hlt;
|
||||
|
||||
CPU_BLOCK_END();
|
||||
|
||||
// if (smbase == 0x000a0000)
|
||||
// leave_smm();
|
||||
}
|
||||
|
||||
|
||||
@@ -1132,6 +1135,10 @@ leave_smm(void)
|
||||
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
|
||||
smram_restore_state_p6(saved_state);
|
||||
|
||||
/* Maybe we need this? */
|
||||
if (smbase == 0x00030000)
|
||||
smbase = 0x000a0000;
|
||||
|
||||
in_smm = 0;
|
||||
mem_mapping_recalc(0x00030000, 0x00020000);
|
||||
mem_mapping_recalc(0x000a0000, 0x00060000);
|
||||
|
||||
@@ -2202,9 +2202,15 @@ cpu_CPUID(void)
|
||||
EAX = CPUID;
|
||||
EBX = ECX = 0;
|
||||
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MTRR/* | CPUID_SEP*/ | CPUID_CMOV;
|
||||
#ifdef USE_SEP
|
||||
EDX |= CPUID_SEP;
|
||||
#endif
|
||||
}
|
||||
else if (EAX == 2)
|
||||
{
|
||||
EAX = 0x00000001;
|
||||
EBX = ECX = 0;
|
||||
EDX = 0x00000000;
|
||||
}
|
||||
else
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
@@ -2223,12 +2229,15 @@ cpu_CPUID(void)
|
||||
EAX = CPUID;
|
||||
EBX = ECX = 0;
|
||||
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR/* | CPUID_SEP*/ | CPUID_CMOV;
|
||||
#ifdef USE_SEP
|
||||
EDX |= CPUID_SEP;
|
||||
#endif
|
||||
}
|
||||
else if (EAX == 2)
|
||||
{
|
||||
EAX = 0x03020101;
|
||||
EAX = 0x00000001;
|
||||
EBX = ECX = 0;
|
||||
EDX = 0x0C040843;
|
||||
EDX = 0x00000000;
|
||||
}
|
||||
else
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
@@ -2247,12 +2256,15 @@ cpu_CPUID(void)
|
||||
EAX = CPUID;
|
||||
EBX = ECX = 0;
|
||||
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR/* | CPUID_SEP*/ | CPUID_FXSR | CPUID_CMOV;
|
||||
#ifdef USE_SEP
|
||||
EDX |= CPUID_SEP;
|
||||
#endif
|
||||
}
|
||||
else if (EAX == 2)
|
||||
{
|
||||
EAX = 0x03020101;
|
||||
EAX = 0x00000001;
|
||||
EBX = ECX = 0;
|
||||
EDX = 0x0C040844;
|
||||
EDX = 0x00000000;
|
||||
}
|
||||
else
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
|
||||
@@ -374,17 +374,21 @@ sff_bus_master_set_irq(int channel, void *priv)
|
||||
channel &= 0x01;
|
||||
if (dev->status & 0x04) {
|
||||
sff_log("SFF8038i: Channel %i IRQ raise\n", channel);
|
||||
if ((dev->irq_mode == 2) && channel && pci_use_mirq(0))
|
||||
if (dev->irq_mode[channel] == 3)
|
||||
picintlevel(1 << dev->irq_line);
|
||||
else if ((dev->irq_mode[channel] == 2) && channel && pci_use_mirq(0))
|
||||
pci_set_mirq(0, 0);
|
||||
else if (dev->irq_mode == 1)
|
||||
else if (dev->irq_mode[channel] == 1)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
else
|
||||
picint(1 << (14 + channel));
|
||||
} else {
|
||||
sff_log("SFF8038i: Channel %i IRQ lower\n", channel);
|
||||
if ((dev->irq_mode == 2) && channel && pci_use_mirq(0))
|
||||
if (dev->irq_mode[channel] == 3)
|
||||
picintc(1 << dev->irq_line);
|
||||
else if ((dev->irq_mode[channel] == 2) && channel && pci_use_mirq(0))
|
||||
pci_clear_mirq(0, 0);
|
||||
else if (dev->irq_mode == 1)
|
||||
else if (dev->irq_mode[channel] == 1)
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
else
|
||||
picintc(1 << (14 + channel));
|
||||
@@ -449,9 +453,16 @@ sff_set_slot(sff8038i_t *dev, int slot)
|
||||
|
||||
|
||||
void
|
||||
sff_set_irq_mode(sff8038i_t *dev, int irq_mode)
|
||||
sff_set_irq_line(sff8038i_t *dev, int irq_line)
|
||||
{
|
||||
dev->irq_mode = irq_mode;
|
||||
dev->irq_line = irq_line;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode)
|
||||
{
|
||||
dev->irq_mode[channel] = irq_mode;
|
||||
}
|
||||
|
||||
|
||||
@@ -488,8 +499,9 @@ static void
|
||||
ide_set_bus_master(next_id, sff_bus_master_dma, sff_bus_master_set_irq, dev);
|
||||
|
||||
dev->slot = 7;
|
||||
dev->irq_mode = 2;
|
||||
dev->irq_mode[0] = dev->irq_mode[1] = 2;
|
||||
dev->irq_pin = PCI_INTA;
|
||||
dev->irq_line = 14;
|
||||
|
||||
next_id++;
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ typedef struct
|
||||
addr;
|
||||
int count, eot,
|
||||
slot,
|
||||
irq_mode, irq_pin;
|
||||
irq_mode[2], irq_pin,
|
||||
irq_line;
|
||||
} sff8038i_t;
|
||||
|
||||
|
||||
@@ -42,5 +43,7 @@ extern void sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base);
|
||||
|
||||
extern void sff_set_slot(sff8038i_t *dev, int slot);
|
||||
|
||||
extern void sff_set_irq_mode(sff8038i_t *dev, int irq_mode);
|
||||
extern void sff_set_irq_line(sff8038i_t *dev, int irq_line);
|
||||
|
||||
extern void sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode);
|
||||
extern void sff_set_irq_pin(sff8038i_t *dev, int irq_pin);
|
||||
|
||||
@@ -112,6 +112,7 @@ extern int nvr_get_days(int month, int year);
|
||||
extern void nvr_time_get(struct tm *);
|
||||
extern void nvr_time_set(struct tm *);
|
||||
|
||||
extern void nvr_reg_write(uint16_t reg, uint8_t val, void *priv);
|
||||
extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr);
|
||||
extern void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr);
|
||||
extern void nvr_wp_set(int set, int h, nvr_t *nvr);
|
||||
|
||||
@@ -57,7 +57,7 @@ extern uint64_t PITCONST, ISACONST,
|
||||
HERCCONST,
|
||||
VGACONST1,
|
||||
VGACONST2,
|
||||
RTCCONST;
|
||||
RTCCONST, ACPICONST;
|
||||
|
||||
|
||||
/* Gets a counter's count. */
|
||||
|
||||
483
src/intel_piix.c
483
src/intel_piix.c
@@ -39,6 +39,7 @@
|
||||
#include <86box/mem.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/port_92.h>
|
||||
@@ -51,24 +52,6 @@
|
||||
#include <86box/piix.h>
|
||||
|
||||
|
||||
#define ACPI_TIMER_FREQ 3579545
|
||||
#define PM_FREQ ACPI_TIMER_FREQ
|
||||
|
||||
#define RSM_STS (1 << 15)
|
||||
#define PWRBTN_STS (1 << 8)
|
||||
|
||||
#define RTC_EN (1 << 10)
|
||||
#define PWRBTN_EN (1 << 8)
|
||||
#define GBL_EN (1 << 5)
|
||||
#define TMROF_EN (1 << 0)
|
||||
|
||||
#define SCI_EN (1 << 0)
|
||||
#define SUS_EN (1 << 13)
|
||||
|
||||
#define ACPI_ENABLE 0xf1
|
||||
#define ACPI_DISABLE 0xf0
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t io_base;
|
||||
@@ -76,17 +59,6 @@ typedef struct
|
||||
} ddma_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t gpireg[3], gporeg[4];
|
||||
uint16_t pmsts, pmen,
|
||||
pmcntrl;
|
||||
uint32_t glbctl;
|
||||
uint64_t tmr_overflow_time;
|
||||
int timer_index;
|
||||
} power_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cur_readout_reg, rev,
|
||||
@@ -96,15 +68,16 @@ typedef struct
|
||||
readout_regs[256], board_config[2];
|
||||
uint16_t func0_id,
|
||||
nvr_io_base,
|
||||
usb_io_base, power_io_base;
|
||||
usb_io_base, acpi_io_base;
|
||||
uint8_t *usb_smsc_mmio;
|
||||
mem_mapping_t *usb_smsc_mmio_mapping;
|
||||
mem_mapping_t usb_smsc_mmio_mapping;
|
||||
sff8038i_t *bm[2];
|
||||
ddma_t ddma[2];
|
||||
power_t power;
|
||||
smbus_piix4_t * smbus;
|
||||
apm_t * apm;
|
||||
nvr_t * nvr;
|
||||
acpi_t * acpi;
|
||||
port_92_t * port_92;
|
||||
} piix_t;
|
||||
|
||||
|
||||
@@ -128,28 +101,88 @@ piix_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static
|
||||
void do_irq(piix_t *dev, int func, int level)
|
||||
static void
|
||||
smsc_ide_handlers(piix_t *dev)
|
||||
{
|
||||
if ((dev == NULL) || (func > dev->max_func) /*||
|
||||
(dev->regs[func][0x3d] < PCI_INTA) || (dev->regs[func][0x3d] < PCI_INTD)*/)
|
||||
return;
|
||||
uint16_t main, side;
|
||||
|
||||
if (level) {
|
||||
#ifdef WRONG_SPEC
|
||||
pci_set_irq(dev->pci_slot, dev->regs[func][0x3d]);
|
||||
#else
|
||||
picintlevel(1 << 9);
|
||||
#endif
|
||||
piix_log("Raising IRQ...\n");
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
|
||||
if (dev->regs[1][0x09] & 0x01) {
|
||||
main = (dev->regs[1][0x11] << 8) | (dev->regs[1][0x10] & 0xf8);
|
||||
side = ((dev->regs[1][0x15] << 8) | (dev->regs[1][0x14] & 0xfc)) + 2;
|
||||
} else {
|
||||
#ifdef WRONG_SPEC
|
||||
pci_clear_irq(dev->pci_slot, dev->regs[func][0x3d]);
|
||||
#else
|
||||
picintc(1 << 9);
|
||||
#endif
|
||||
piix_log("Lowering IRQ...\n");
|
||||
main = 0x1f0;
|
||||
side = 0x3f6;
|
||||
}
|
||||
ide_set_base(0, main);
|
||||
ide_set_side(0, side);
|
||||
|
||||
if (dev->regs[1][0x09] & 0x04) {
|
||||
main = (dev->regs[1][0x19] << 8) | (dev->regs[1][0x18] & 0xf8);
|
||||
side = ((dev->regs[1][0x1d] << 8) | (dev->regs[1][0x1c] & 0xfc)) + 2;
|
||||
} else {
|
||||
main = 0x170;
|
||||
side = 0x376;
|
||||
}
|
||||
ide_set_base(1, main);
|
||||
ide_set_side(1, side);
|
||||
|
||||
if (dev->regs[1][0x04] & PCI_COMMAND_IO) {
|
||||
if (dev->regs[1][0x41] & 0x80)
|
||||
ide_pri_enable();
|
||||
if (dev->regs[1][0x43] & 0x80)
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smsc_ide_irqs(piix_t *dev)
|
||||
{
|
||||
int irq_line = 3, irq_mode[2] = { 0, 0 };
|
||||
|
||||
if (dev->regs[1][0x09] & 0x01)
|
||||
irq_mode[0] = (dev->regs[0][0xe0] & 0x01) ? 3 : 1;
|
||||
|
||||
if (dev->regs[1][0x09] & 0x04)
|
||||
irq_mode[1] = (dev->regs[0][0xe0] & 0x01) ? 3 : 1;
|
||||
|
||||
switch ((dev->regs[0][0xe0] >> 1) & 0x07) {
|
||||
case 0x00:
|
||||
irq_line = 3;
|
||||
break;
|
||||
case 0x01:
|
||||
irq_line = 5;
|
||||
break;
|
||||
case 0x02:
|
||||
irq_line = 7;
|
||||
break;
|
||||
case 0x03:
|
||||
irq_line = 8;
|
||||
break;
|
||||
case 0x04:
|
||||
irq_line = 11;
|
||||
break;
|
||||
case 0x05:
|
||||
irq_line = 12;
|
||||
break;
|
||||
case 0x06:
|
||||
irq_line = 14;
|
||||
break;
|
||||
case 0x07:
|
||||
irq_line = 15;
|
||||
break;
|
||||
}
|
||||
|
||||
sff_set_irq_line(dev->bm[0], irq_line);
|
||||
sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]);
|
||||
sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]);
|
||||
|
||||
sff_set_irq_line(dev->bm[1], irq_line);
|
||||
sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]);
|
||||
sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]);
|
||||
}
|
||||
|
||||
|
||||
@@ -356,23 +389,14 @@ usb_update_io_mapping(piix_t *dev)
|
||||
static void
|
||||
usb_smsc_update_mem_mapping(piix_t *dev)
|
||||
{
|
||||
uint8_t *fregs;
|
||||
uint32_t usb_bar;
|
||||
|
||||
if (!dev->usb_smsc_mmio_mapping)
|
||||
return;
|
||||
mem_mapping_disable(&dev->usb_smsc_mmio_mapping);
|
||||
|
||||
mem_mapping_disable(dev->usb_smsc_mmio_mapping);
|
||||
usb_bar = ((dev->regs[2][0x11] << 8) | (dev->regs[2][0x12] << 16) | (dev->regs[2][0x13] << 24)) & 0xfffff000;
|
||||
|
||||
if (!dev->usb_smsc_mmio)
|
||||
return;
|
||||
|
||||
fregs = (uint8_t *) dev->regs[2];
|
||||
usb_bar = fregs[0x10] | (fregs[0x11] << 8) | (fregs[0x12] << 16) | (fregs[0x13] << 24);
|
||||
piix_log("smsc usb bar %08x\n", usb_bar);
|
||||
|
||||
if ((usb_bar != 0x00000000) && (usb_bar < 0xFF000000))
|
||||
mem_mapping_set_addr(dev->usb_smsc_mmio_mapping, usb_bar, 0x1000);
|
||||
if ((dev->regs[2][0x04] & 0x02) && (usb_bar != 0x00000000))
|
||||
mem_mapping_set_addr(&dev->usb_smsc_mmio_mapping, usb_bar, 0x1000);
|
||||
}
|
||||
|
||||
|
||||
@@ -380,10 +404,12 @@ static uint8_t
|
||||
usb_smsc_mmio_read(uint32_t addr, void *p)
|
||||
{
|
||||
piix_t *dev = (piix_t *) p;
|
||||
uint8_t ret;
|
||||
ret = dev->usb_smsc_mmio[addr & 0xFFF];
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
/* addr &= 0x00000fff;
|
||||
|
||||
ret = dev->usb_smsc_mmio[addr]; */
|
||||
|
||||
piix_log("usb_smsc_mmio_read(%08x) = %02x\n", addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -393,127 +419,22 @@ usb_smsc_mmio_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
piix_t *dev = (piix_t *) p;
|
||||
|
||||
switch (addr & 0xFFF) {
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x08: /* HCCOMMANDSTATUS */
|
||||
/* bit HostControllerReset must be cleared for the controller to be seen as initialized */
|
||||
val = val & ~(0x01);
|
||||
val &= ~0x01;
|
||||
|
||||
/* bit OwnershipChangeRequest triggers an ownership change (SMM <-> OS) */
|
||||
if (val & 0x0F) {
|
||||
dev->usb_smsc_mmio[0x0F] = 0x40;
|
||||
if (val & 0x0f) {
|
||||
dev->usb_smsc_mmio[0x0f] = 0x40;
|
||||
dev->usb_smsc_mmio[0x05] &= ~(dev->usb_smsc_mmio[0x05] & 0x01);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
dev->usb_smsc_mmio[addr & 0xFFF] = val;
|
||||
|
||||
piix_log("usb_smsc_mmio_write(%08x, %02x)\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
power_reg_readl(uint16_t addr, void *p)
|
||||
{
|
||||
piix_t *dev = (piix_t *) p;
|
||||
uint32_t timer;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
switch (addr & 0x3c) {
|
||||
case 0x08:
|
||||
/* ACPI timer */
|
||||
timer = (tsc * ACPI_TIMER_FREQ) / machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed;
|
||||
timer &= 0x00ffffff;
|
||||
ret = timer;
|
||||
break;
|
||||
}
|
||||
|
||||
piix_log("ACPI: Read L %08X from %04X\n", ret, addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
power_reg_readw(uint16_t addr, void *p)
|
||||
{
|
||||
piix_t *dev = (piix_t *) p;
|
||||
uint16_t ret = 0xffff;
|
||||
uint32_t ret32;
|
||||
|
||||
switch (addr & 0x3c) {
|
||||
case 0x00:
|
||||
break;
|
||||
default:
|
||||
ret32 = power_reg_readl(addr, p);
|
||||
if (addr & 0x02)
|
||||
ret = (ret32 >> 16) & 0xffff;
|
||||
else
|
||||
ret = ret32 & 0xffff;
|
||||
break;
|
||||
}
|
||||
|
||||
piix_log("ACPI: Read W %08X from %04X\n", ret, addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
power_reg_read(uint16_t addr, void *p)
|
||||
{
|
||||
piix_t *dev = (piix_t *) p;
|
||||
uint32_t timer;
|
||||
uint8_t ret = 0xff;
|
||||
uint16_t ret16;
|
||||
|
||||
switch (addr & 0x3f) {
|
||||
case 0x30: case 0x31: case 0x32:
|
||||
ret = dev->power.gporeg[addr & 0x03];
|
||||
piix_log("ACPI: Read B %02X from GPIREG %01X\n", ret, addr & 0x03);
|
||||
break;
|
||||
case 0x34: case 0x35: case 0x36: case 0x37:
|
||||
ret = dev->power.gporeg[addr & 0x03];
|
||||
piix_log("ACPI: Read B %02X from GPOREG %01X\n", ret, addr & 0x03);
|
||||
break;
|
||||
default:
|
||||
ret16 = power_reg_readw(addr, p);
|
||||
if (addr & 0x01)
|
||||
ret = (ret16 >> 8) & 0xff;
|
||||
else
|
||||
ret = ret16 & 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
power_reg_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
piix_t *dev = (piix_t *) p;
|
||||
|
||||
piix_log("ACPI: Write %02X to %04X\n", val, addr);
|
||||
|
||||
switch (addr & 0x3f) {
|
||||
case 0x34: case 0x35: case 0x36: case 0x37:
|
||||
dev->power.gporeg[addr & 0x03] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
power_update_io_mapping(piix_t *dev)
|
||||
{
|
||||
if (dev->power_io_base != 0x0000)
|
||||
io_removehandler(dev->power_io_base, 0x40, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, dev);
|
||||
|
||||
dev->power_io_base = (dev->regs[3][0x41] << 8) | (dev->regs[3][0x40] & 0xc0);
|
||||
|
||||
if ((dev->regs[3][0x80] & 0x01) && (dev->power_io_base != 0x0000))
|
||||
io_sethandler(dev->power_io_base, 0x40, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, dev);
|
||||
dev->usb_smsc_mmio[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -527,24 +448,29 @@ smbus_update_io_mapping(piix_t *dev)
|
||||
static void
|
||||
nvr_update_io_mapping(piix_t *dev)
|
||||
{
|
||||
int enabled2 = 1;
|
||||
|
||||
if (dev->nvr_io_base != 0x0000) {
|
||||
nvr_at_handler(0, dev->nvr_io_base, dev->nvr);
|
||||
nvr_at_handler(0, dev->nvr_io_base + 0x0002, dev->nvr);
|
||||
nvr_at_handler(0, dev->nvr_io_base + 0x0004, dev->nvr);
|
||||
nvr_at_handler(0, dev->nvr_io_base + 0x0006, dev->nvr);
|
||||
}
|
||||
|
||||
if (dev->type == 5)
|
||||
dev->power_io_base = (dev->regs[0][0xd5] << 8) | (dev->regs[3][0xd4] & 0xf0);
|
||||
dev->nvr_io_base = (dev->regs[0][0xd5] << 8) | (dev->regs[0][0xd4] & 0xf0);
|
||||
else
|
||||
dev->power_io_base = 0x70;
|
||||
dev->nvr_io_base = 0x70;
|
||||
pclog("New NVR I/O base: %04X\n", dev->nvr_io_base);
|
||||
|
||||
if ((dev->regs[0][0xcb] & 0x01) && (dev->regs[2][0xff] & 0x10))
|
||||
/* if (dev->type == 4)
|
||||
enabled2 = (dev->regs[2][0xff] & 0x10); */
|
||||
|
||||
if ((dev->regs[0][0xcb] & 0x01) && enabled2) {
|
||||
nvr_at_handler(1, dev->nvr_io_base, dev->nvr);
|
||||
nvr_at_handler(1, dev->nvr_io_base + 0x0004, dev->nvr);
|
||||
}
|
||||
if (dev->regs[0][0xcb] & 0x04)
|
||||
nvr_at_handler(1, dev->nvr_io_base + 0x0002, dev->nvr);
|
||||
nvr_at_handler(1, dev->nvr_io_base + 0x0004, dev->nvr);
|
||||
nvr_at_handler(1, dev->nvr_io_base + 0x0006, dev->nvr);
|
||||
}
|
||||
|
||||
|
||||
@@ -563,6 +489,10 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ignore the new IDE BAR's on the Intel chips. */
|
||||
if ((dev->type < 5) && (func == 1) && (addr >= 0x10) && (addr <= 0x1f))
|
||||
return;
|
||||
|
||||
piix_log("PIIX function %i write: %02X to %02X\n", func, val, addr);
|
||||
fregs = (uint8_t *) dev->regs[func];
|
||||
|
||||
@@ -628,9 +558,9 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (dev->type > 4)
|
||||
fregs[0x65] = val;
|
||||
break;
|
||||
case 0x68:
|
||||
case 0x66:
|
||||
if (dev->type > 4)
|
||||
fregs[0x68] = val & 0x81;
|
||||
fregs[0x66] = val & 0x81;
|
||||
break;
|
||||
case 0x69:
|
||||
if (dev->type > 1)
|
||||
@@ -791,14 +721,22 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0xe1: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
||||
if (dev->type > 4)
|
||||
if (dev->type > 4) {
|
||||
fregs[addr] = val;
|
||||
if ((dev->type == 5) && (addr == 0xe1)) {
|
||||
smsc_ide_irqs(dev);
|
||||
port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x40));
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else if (func == 1) switch(addr) { /* IDE */
|
||||
case 0x04:
|
||||
fregs[0x04] = (val & 5);
|
||||
if (dev->type < 3)
|
||||
fregs[0x04] |= 0x02;
|
||||
if (dev->type == 5)
|
||||
smsc_ide_handlers(dev);
|
||||
else
|
||||
piix_ide_legacy_handlers(dev, 0x03);
|
||||
piix_ide_bm_handlers(dev);
|
||||
break;
|
||||
@@ -810,9 +748,48 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (val & 0x08)
|
||||
fregs[0x07] &= 0xf7;
|
||||
break;
|
||||
case 0x09:
|
||||
if (dev->type == 5) {
|
||||
fregs[0x09] = (fregs[0x09] & 0xfa) | (val & 0x05);
|
||||
smsc_ide_handlers(dev);
|
||||
smsc_ide_irqs(dev);
|
||||
}
|
||||
break;
|
||||
case 0x0d:
|
||||
fregs[0x0d] = val & 0xf0;
|
||||
break;
|
||||
case 0x10:
|
||||
fregs[0x10] = (val & 0xf8) | 1;
|
||||
smsc_ide_handlers(dev);
|
||||
break;
|
||||
case 0x11:
|
||||
fregs[0x11] = val;
|
||||
smsc_ide_handlers(dev);
|
||||
break;
|
||||
case 0x14:
|
||||
fregs[0x14] = (val & 0xfc) | 1;
|
||||
smsc_ide_handlers(dev);
|
||||
break;
|
||||
case 0x15:
|
||||
fregs[0x15] = val;
|
||||
smsc_ide_handlers(dev);
|
||||
break;
|
||||
case 0x18:
|
||||
fregs[0x18] = (val & 0xf8) | 1;
|
||||
smsc_ide_handlers(dev);
|
||||
break;
|
||||
case 0x19:
|
||||
fregs[0x19] = val;
|
||||
smsc_ide_handlers(dev);
|
||||
break;
|
||||
case 0x1c:
|
||||
fregs[0x1c] = (val & 0xfc) | 1;
|
||||
smsc_ide_handlers(dev);
|
||||
break;
|
||||
case 0x1d:
|
||||
fregs[0x1d] = val;
|
||||
smsc_ide_handlers(dev);
|
||||
break;
|
||||
case 0x20:
|
||||
fregs[0x20] = (val & 0xf0) | 1;
|
||||
piix_ide_bm_handlers(dev);
|
||||
@@ -822,7 +799,6 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
piix_ide_bm_handlers(dev);
|
||||
break;
|
||||
case 0x3c:
|
||||
piix_log("IDE IRQ write: %02X\n", val);
|
||||
fregs[0x3c] = val;
|
||||
break;
|
||||
case 0x40: case 0x42:
|
||||
@@ -830,26 +806,52 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x41: case 0x43:
|
||||
fregs[addr] = val & ((dev->type > 1) ? 0xf3 : 0xb3);
|
||||
if (dev->type == 5)
|
||||
smsc_ide_handlers(dev);
|
||||
else
|
||||
piix_ide_legacy_handlers(dev, 1 << !!(addr & 0x02));
|
||||
break;
|
||||
case 0x44:
|
||||
if (dev->type > 1)
|
||||
fregs[0x44] = val;
|
||||
break;
|
||||
case 0x45:
|
||||
if (dev->type > 4)
|
||||
fregs[0x45] = val;
|
||||
break;
|
||||
case 0x46:
|
||||
if (dev->type > 4)
|
||||
fregs[0x46] = val & 0x03;
|
||||
break;
|
||||
case 0x48:
|
||||
if (dev->type > 3)
|
||||
fregs[0x48] = val & 0x0f;
|
||||
break;
|
||||
case 0x4a: case 0x4b:
|
||||
if (dev->type > 4)
|
||||
if (dev->type > 3)
|
||||
fregs[addr] = val & 0x33;
|
||||
break;
|
||||
case 0x5c: case 0x5d:
|
||||
if (dev->type > 4)
|
||||
fregs[addr] = val;
|
||||
break;
|
||||
} else if (func == 2) switch(addr) { /* USB */
|
||||
case 0x04:
|
||||
if (dev->type > 4) {
|
||||
fregs[0x04] = (val & 7);
|
||||
usb_smsc_update_mem_mapping(dev);
|
||||
} else {
|
||||
fregs[0x04] = (val & 5);
|
||||
usb_update_io_mapping(dev);
|
||||
}
|
||||
break;
|
||||
case 0x07:
|
||||
if (dev->type > 4) {
|
||||
if (val & 0x80)
|
||||
fregs[0x07] &= 0x7f;
|
||||
if (val & 0x40)
|
||||
fregs[0x07] &= 0xbf;
|
||||
}
|
||||
if (val & 0x20)
|
||||
fregs[0x07] &= 0xdf;
|
||||
if (val & 0x10)
|
||||
@@ -857,40 +859,68 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (val & 0x08)
|
||||
fregs[0x07] &= 0xf7;
|
||||
break;
|
||||
case 0x0c:
|
||||
if (dev->type > 4)
|
||||
fregs[0x0c] = val;
|
||||
break;
|
||||
case 0x0d:
|
||||
if (dev->type <= 4)
|
||||
fregs[0x0d] = val & 0xf0;
|
||||
break;
|
||||
case 0x11:
|
||||
fregs[addr] = val & ~(0x10);
|
||||
if (dev->type > 4) {
|
||||
fregs[addr] = val & 0xf0;
|
||||
usb_smsc_update_mem_mapping(dev);
|
||||
}
|
||||
break;
|
||||
case 0x12: case 0x13:
|
||||
if (dev->type > 4) {
|
||||
fregs[addr] = val;
|
||||
usb_smsc_update_mem_mapping(dev);
|
||||
}
|
||||
break;
|
||||
case 0x20:
|
||||
if (dev->type < 5) {
|
||||
fregs[0x20] = (val & 0xe0) | 1;
|
||||
usb_update_io_mapping(dev);
|
||||
}
|
||||
break;
|
||||
case 0x21:
|
||||
if (dev->type < 5) {
|
||||
fregs[0x21] = val;
|
||||
usb_update_io_mapping(dev);
|
||||
}
|
||||
break;
|
||||
case 0x3c:
|
||||
fregs[0x3c] = val;
|
||||
break;
|
||||
case 0x3e: case 0x3f:
|
||||
case 0x40: case 0x41: case 0x43:
|
||||
if (dev->type > 4)
|
||||
fregs[addr] = val;
|
||||
break;
|
||||
case 0x42:
|
||||
if (dev->type > 4)
|
||||
fregs[addr] = val & 0x8f;
|
||||
break;
|
||||
case 0x44: case 0x45:
|
||||
if (dev->type > 4)
|
||||
fregs[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x6a:
|
||||
if (dev->type < 4)
|
||||
if (dev->type == 4)
|
||||
fregs[0x6a] = val & 0x01;
|
||||
break;
|
||||
case 0xc0:
|
||||
if (dev->type == 4)
|
||||
fregs[0xc0] = val;
|
||||
break;
|
||||
case 0xc1:
|
||||
if (dev->type == 4)
|
||||
fregs[0xc1] = val & 0xbf;
|
||||
break;
|
||||
case 0xff:
|
||||
if (dev->type >= 4) {
|
||||
if (dev->type == 4) {
|
||||
fregs[addr] = val & 0x10;
|
||||
nvr_at_handler(0, 0x0070, dev->nvr);
|
||||
if ((dev->regs[0][0xcb] & 0x01) && (dev->regs[2][0xff] & 0x10))
|
||||
@@ -900,7 +930,6 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
} else if (func == 3) switch(addr) { /* Power Management */
|
||||
case 0x04:
|
||||
fregs[0x04] = (val & 0x01);
|
||||
power_update_io_mapping(dev);
|
||||
smbus_update_io_mapping(dev);
|
||||
apm_set_do_smi(dev->apm, !!(fregs[0x5b] & 0x02) && !!(val & 0x01));
|
||||
break;
|
||||
@@ -915,11 +944,13 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
#endif
|
||||
case 0x40:
|
||||
fregs[0x40] = (val & 0xc0) | 1;
|
||||
power_update_io_mapping(dev);
|
||||
dev->acpi_io_base = (dev->regs[3][0x41] << 8) | (dev->regs[3][0x40] & 0xc0);
|
||||
acpi_update_io_mapping(dev->acpi, dev->acpi_io_base, (dev->regs[3][0x80] & 0x01));
|
||||
break;
|
||||
case 0x41:
|
||||
fregs[0x41] = val;
|
||||
power_update_io_mapping(dev);
|
||||
dev->acpi_io_base = (dev->regs[3][0x41] << 8) | (dev->regs[3][0x40] & 0xc0);
|
||||
acpi_update_io_mapping(dev->acpi, dev->acpi_io_base, (dev->regs[3][0x80] & 0x01));
|
||||
break;
|
||||
case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
case 0x48: case 0x49:
|
||||
@@ -947,7 +978,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x4f: case 0x80: case 0xd2:
|
||||
fregs[addr] = val & 0x0f;
|
||||
if (addr == 0x80)
|
||||
power_update_io_mapping(dev);
|
||||
acpi_update_io_mapping(dev->acpi, dev->acpi_io_base, (dev->regs[3][0x80] & 0x01));
|
||||
else if (addr == 0xd2)
|
||||
smbus_update_io_mapping(dev);
|
||||
break;
|
||||
@@ -1056,8 +1087,17 @@ piix_reset_hard(piix_t *dev)
|
||||
sff_bus_master_reset(dev->bm[1], old_base + 8);
|
||||
|
||||
if (dev->type >= 4) {
|
||||
sff_set_irq_mode(dev->bm[0], 0);
|
||||
sff_set_irq_mode(dev->bm[1], 0);
|
||||
sff_set_slot(dev->bm[0], dev->pci_slot);
|
||||
sff_set_irq_pin(dev->bm[0], PCI_INTA);
|
||||
sff_set_irq_line(dev->bm[0], 14);
|
||||
sff_set_irq_mode(dev->bm[0], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[0], 1, 0);
|
||||
|
||||
sff_set_slot(dev->bm[1], dev->pci_slot);
|
||||
sff_set_irq_pin(dev->bm[1], PCI_INTA);
|
||||
sff_set_irq_line(dev->bm[1], 14);
|
||||
sff_set_irq_mode(dev->bm[1], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[1], 1, 0);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_PIIX_LOG
|
||||
@@ -1071,7 +1111,6 @@ piix_reset_hard(piix_t *dev)
|
||||
nvr_wp_set(0, 0, dev->nvr);
|
||||
nvr_wp_set(0, 1, dev->nvr);
|
||||
nvr_at_handler(1, 0x0074, dev->nvr);
|
||||
nvr_at_handler(1, 0x0076, dev->nvr);
|
||||
dev->nvr_io_base = 0x0070;
|
||||
}
|
||||
|
||||
@@ -1140,9 +1179,16 @@ piix_reset_hard(piix_t *dev)
|
||||
fregs[0x08] = dev->rev & 0x07;
|
||||
else
|
||||
fregs[0x08] = dev->rev;
|
||||
if (dev->type == 5)
|
||||
fregs[0x09] = 0x8a;
|
||||
else
|
||||
fregs[0x09] = 0x80;
|
||||
fregs[0x0a] = 0x01; fregs[0x0b] = 0x01;
|
||||
fregs[0x20] = 0x01;
|
||||
if (dev->type == 5) {
|
||||
fregs[0x3c] = 0x0e;
|
||||
fregs[0x3d] = 0x01;
|
||||
}
|
||||
dev->max_func = 0; /* It starts with IDE disabled, then enables it. */
|
||||
|
||||
/* Function 2: USB */
|
||||
@@ -1153,8 +1199,10 @@ piix_reset_hard(piix_t *dev)
|
||||
fregs[0x06] = 0x80; fregs[0x07] = 0x02;
|
||||
if (dev->type == 4)
|
||||
fregs[0x08] = dev->rev & 0x07;
|
||||
else
|
||||
else if (dev->type < 4)
|
||||
fregs[0x08] = dev->rev;
|
||||
else
|
||||
fregs[0x08] = 0x02;
|
||||
if (dev->type == 5)
|
||||
fregs[0x09] = 0x10; /* SMSC has OHCI rather than UHCI */
|
||||
fregs[0x0a] = 0x03; fregs[0x0b] = 0x0c;
|
||||
@@ -1180,10 +1228,14 @@ piix_reset_hard(piix_t *dev)
|
||||
fregs = (uint8_t *) dev->regs[3];
|
||||
piix_log("PIIX Function 3: %02X%02X:%02X%02X\n", fregs[0x01], fregs[0x00], fregs[0x03], fregs[0x02]);
|
||||
fregs[0x06] = 0x80; fregs[0x07] = 0x02;
|
||||
if (dev->type > 4)
|
||||
fregs[0x08] = 0x02;
|
||||
else
|
||||
fregs[0x08] = (dev->rev & 0x08) ? 0x02 : (dev->rev & 0x07);
|
||||
fregs[0x0a] = 0x80; fregs[0x0b] = 0x06;
|
||||
/* NOTE: The Specification Update says this should default to 0x00 and be read-only. */
|
||||
#ifdef WRONG_SPEC
|
||||
if (dev->type == 4)
|
||||
fregs[0x3d] = 0x01;
|
||||
#endif
|
||||
fregs[0x40] = 0x01;
|
||||
@@ -1201,12 +1253,8 @@ piix_reset_hard(piix_t *dev)
|
||||
if (dev->type < 3)
|
||||
pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED);
|
||||
|
||||
if (dev->type == 4) {
|
||||
dev->power.gporeg[0] = 0xff;
|
||||
dev->power.gporeg[1] = 0xbf;
|
||||
dev->power.gporeg[2] = 0xff;
|
||||
dev->power.gporeg[3] = 0x7f;
|
||||
}
|
||||
if (dev->type >= 4)
|
||||
acpi_init_gporeg(dev->acpi, 0xff, 0xbf, 0xff, 0x7f);
|
||||
}
|
||||
|
||||
|
||||
@@ -1222,7 +1270,6 @@ piix_close(void *p)
|
||||
static void
|
||||
*piix_init(const device_t *info)
|
||||
{
|
||||
int i;
|
||||
CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu];
|
||||
|
||||
piix_t *dev = (piix_t *) malloc(sizeof(piix_t));
|
||||
@@ -1240,26 +1287,30 @@ static void
|
||||
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
if (dev->type > 3)
|
||||
if (dev->type > 3) {
|
||||
dev->nvr = device_add(&piix4_nvr_device);
|
||||
dev->smbus = device_add(&piix4_smbus_device);
|
||||
|
||||
dev->acpi = device_add(&acpi_device);
|
||||
acpi_set_slot(dev->acpi, dev->pci_slot);
|
||||
acpi_set_nvr(dev->acpi, dev->nvr);
|
||||
}
|
||||
|
||||
if (dev->type == 5) {
|
||||
dev->usb_smsc_mmio = malloc(4096);
|
||||
dev->usb_smsc_mmio = (uint8_t *) malloc(4096);
|
||||
memset(dev->usb_smsc_mmio, 0x00, 4096);
|
||||
|
||||
dev->usb_smsc_mmio_mapping = malloc(sizeof(mem_mapping_t));
|
||||
mem_mapping_add(dev->usb_smsc_mmio_mapping, 0, 0,
|
||||
mem_mapping_add(&dev->usb_smsc_mmio_mapping, 0, 0,
|
||||
usb_smsc_mmio_read, NULL, NULL,
|
||||
usb_smsc_mmio_write, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, dev);
|
||||
mem_mapping_disable(dev->usb_smsc_mmio_mapping);
|
||||
mem_mapping_disable(&dev->usb_smsc_mmio_mapping);
|
||||
}
|
||||
|
||||
piix_reset_hard(dev);
|
||||
|
||||
dev->smbus = device_add(&piix4_smbus_device);
|
||||
|
||||
dev->apm = device_add(&apm_device);
|
||||
device_add(&port_92_pci_device);
|
||||
dev->port_92 = device_add(&port_92_pci_device);
|
||||
|
||||
dma_alias_set();
|
||||
|
||||
@@ -1299,7 +1350,7 @@ static void
|
||||
dev->readout_regs[1] |= 0x80;
|
||||
|
||||
io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
|
||||
// io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
|
||||
io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
|
||||
|
||||
dev->board_config[0] = 0xff;
|
||||
dev->board_config[0] = 0x00;
|
||||
|
||||
@@ -97,7 +97,7 @@ machine_at_p2bls_init(const machine_t *model)
|
||||
device_add(&i440bx_device);
|
||||
device_add(&piix4e_device);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&w83977ef_device);
|
||||
// device_add(&w83977ef_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
|
||||
|
||||
|
||||
@@ -1309,7 +1309,7 @@ eep_close(void *priv)
|
||||
t1keep_t *eep = (t1keep_t *)priv;
|
||||
FILE *f = NULL;
|
||||
|
||||
f = nvr_fopen(eep->path, L"rb");
|
||||
f = nvr_fopen(eep->path, L"wb");
|
||||
if (f != NULL) {
|
||||
(void)fwrite(eep->store, 128, 1, f);
|
||||
(void)fclose(f);
|
||||
|
||||
47
src/nvr_at.c
47
src/nvr_at.c
@@ -553,24 +553,18 @@ timer_tick(nvr_t *nvr)
|
||||
}
|
||||
|
||||
|
||||
/* Write to one of the NVR registers. */
|
||||
static void
|
||||
nvr_write(uint16_t addr, uint8_t val, void *priv)
|
||||
/* This must be exposed because ACPI uses it. */
|
||||
void
|
||||
nvr_reg_write(uint16_t reg, uint8_t val, void *priv)
|
||||
{
|
||||
nvr_t *nvr = (nvr_t *)priv;
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
struct tm tm;
|
||||
uint8_t old, i;
|
||||
uint8_t addr_id = (addr & 0x0e) >> 1;
|
||||
uint16_t checksum = 0x0000;
|
||||
|
||||
sub_cycles(ISA_CYCLES(8));
|
||||
|
||||
if (addr & 1) {
|
||||
if (local->bank[addr_id] == 0xff)
|
||||
return;
|
||||
old = nvr->regs[local->addr[addr_id]];
|
||||
switch(local->addr[addr_id]) {
|
||||
old = nvr->regs[reg];
|
||||
switch(reg) {
|
||||
case RTC_REGA:
|
||||
nvr->regs[RTC_REGA] = val;
|
||||
timer_load_count(nvr);
|
||||
@@ -602,21 +596,21 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
|
||||
/*FALLTHROUGH*/
|
||||
|
||||
default: /* non-RTC registers are just NVRAM */
|
||||
if ((local->addr[addr_id] >= 0x38) && (local->addr[addr_id] <= 0x3f) && local->wp[0])
|
||||
if ((reg >= 0x38) && (reg <= 0x3f) && local->wp[0])
|
||||
break;
|
||||
if ((local->addr[addr_id] >= 0xb8) && (local->addr[addr_id] <= 0xbf) && local->wp[1])
|
||||
if ((reg >= 0xb8) && (reg <= 0xbf) && local->wp[1])
|
||||
break;
|
||||
if (local->lock[local->addr[addr_id]])
|
||||
if (local->lock[reg])
|
||||
break;
|
||||
if (nvr->regs[local->addr[addr_id]] != val) {
|
||||
nvr->regs[local->addr[addr_id]] = val;
|
||||
if (nvr->regs[reg] != val) {
|
||||
nvr->regs[reg] = val;
|
||||
nvr_dosave = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ((local->addr[addr_id] < RTC_REGA) || ((local->cent != 0xff) && (local->addr[addr_id] == local->cent))) {
|
||||
if ((local->addr[addr_id] != 1) && (local->addr[addr_id] != 3) && (local->addr[addr_id] != 5)) {
|
||||
if ((reg < RTC_REGA) || ((local->cent != 0xff) && (reg == local->cent))) {
|
||||
if ((reg != 1) && (reg != 3) && (reg != 5)) {
|
||||
if ((old != val) && !(time_sync & TIME_SYNC_ENABLED)) {
|
||||
/* Update internal clock. */
|
||||
time_get(nvr, &tm);
|
||||
@@ -625,6 +619,23 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Write to one of the NVR registers. */
|
||||
static void
|
||||
nvr_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
nvr_t *nvr = (nvr_t *)priv;
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
uint8_t addr_id = (addr & 0x0e) >> 1;
|
||||
|
||||
sub_cycles(ISA_CYCLES(8));
|
||||
|
||||
if (addr & 1) {
|
||||
if (local->bank[addr_id] == 0xff)
|
||||
return;
|
||||
nvr_reg_write(local->addr[addr_id], val, priv);
|
||||
} else {
|
||||
local->addr[addr_id] = (val & (nvr->size - 1));
|
||||
/* Some chipsets use a 256 byte NVRAM but ports 70h and 71h always access only 128 bytes. */
|
||||
|
||||
@@ -50,7 +50,7 @@ uint64_t PITCONST, ISACONST,
|
||||
CGACONST,
|
||||
MDACONST, HERCCONST,
|
||||
VGACONST1, VGACONST2,
|
||||
RTCCONST;
|
||||
RTCCONST, ACPICONST;
|
||||
|
||||
int io_delay = 5;
|
||||
|
||||
@@ -1021,6 +1021,7 @@ pit_set_clock(int clock)
|
||||
VGACONST1 = (uint64_t) (cpuclock / 25175000.0 * (double)(1ull << 32));
|
||||
VGACONST2 = (uint64_t) (cpuclock / 28322000.0 * (double)(1ull << 32));
|
||||
RTCCONST = (uint64_t) (cpuclock / 32768.0 * (double)(1ull << 32));
|
||||
ACPICONST = (uint64_t) (cpuclock / 3579545.0 * (double)(1ull << 32));
|
||||
|
||||
TIMER_USEC = (uint64_t)((cpuclock / 1000000.0) * (double)(1ull << 32));
|
||||
|
||||
|
||||
@@ -810,6 +810,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
break;
|
||||
|
||||
case 0x09: /*AZTECH mode set*/
|
||||
if (IS_AZTECH(dsp)) {
|
||||
if (dsp->sb_data[0] == 0x00) {
|
||||
sb_dsp_log("AZT2316A: WSS MODE!\n");
|
||||
azt2316a_enable_wss(1, dsp->parent);
|
||||
@@ -818,6 +819,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
azt2316a_enable_wss(0, dsp->parent);
|
||||
} else
|
||||
sb_dsp_log("AZT2316A: UNKNOWN MODE! = %02x\n", dsp->sb_data[0]); // sequences 0x02->0xFF, 0x04->0xFF seen
|
||||
}
|
||||
break;
|
||||
|
||||
/* TODO: Some more data about the DSP registeres
|
||||
|
||||
@@ -220,6 +220,25 @@ via_vt82c586b_ide_handlers(via_vt82c586b_t *dev)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
via_vt82c586b_ide_irqs(via_vt82c586b_t *dev)
|
||||
{
|
||||
int irq_mode[2] = { 0, 0 };
|
||||
|
||||
if (dev->ide_regs[0x09] & 0x01)
|
||||
irq_mode[0] = (dev->ide_regs[0x3d] & 0x01);
|
||||
|
||||
if (dev->ide_regs[0x09] & 0x04)
|
||||
irq_mode[1] = (dev->ide_regs[0x3d] & 0x01);
|
||||
|
||||
sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]);
|
||||
sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]);
|
||||
|
||||
sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]);
|
||||
sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
via_vt82c586b_bus_master_handlers(via_vt82c586b_t *dev)
|
||||
{
|
||||
@@ -466,6 +485,7 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x09:
|
||||
dev->ide_regs[0x09] = (val & 0x05) | 0x8a;
|
||||
via_vt82c586b_ide_handlers(dev);
|
||||
via_vt82c586b_ide_irqs(dev);
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
@@ -514,8 +534,8 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x3d:
|
||||
sff_set_irq_mode(dev->bm[0], val);
|
||||
sff_set_irq_mode(dev->bm[1], val);
|
||||
dev->ide_regs[0x3d] = val & 0x01;
|
||||
via_vt82c586b_ide_irqs(dev);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
@@ -591,12 +611,14 @@ static void
|
||||
|
||||
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
sff_set_slot(dev->bm[0], dev->slot);
|
||||
sff_set_irq_mode(dev->bm[0], 0);
|
||||
sff_set_irq_mode(dev->bm[0], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[0], 1, 0);
|
||||
sff_set_irq_pin(dev->bm[0], PCI_INTA);
|
||||
|
||||
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
|
||||
sff_set_slot(dev->bm[1], dev->slot);
|
||||
sff_set_irq_mode(dev->bm[1], 0);
|
||||
sff_set_irq_mode(dev->bm[1], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[1], 1, 0);
|
||||
sff_set_irq_pin(dev->bm[1], PCI_INTA);
|
||||
|
||||
dev->nvr = device_add(&via_nvr_device);
|
||||
|
||||
@@ -263,6 +263,7 @@ via_vt82c596b_reset(void *priv)
|
||||
ide_sec_disable();
|
||||
}
|
||||
|
||||
|
||||
// IDE CONTROLLER
|
||||
static void
|
||||
ide_handlers(via_vt82c596b_t *dev)
|
||||
@@ -307,6 +308,25 @@ ide_handlers(via_vt82c596b_t *dev)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ide_irqs(via_vt82c596b_t *dev)
|
||||
{
|
||||
int irq_mode[2] = { 0, 0 };
|
||||
|
||||
if (dev->ide_regs[0x09] & 0x01)
|
||||
irq_mode[0] = (dev->ide_regs[0x3d] & 0x01);
|
||||
|
||||
if (dev->ide_regs[0x09] & 0x04)
|
||||
irq_mode[1] = (dev->ide_regs[0x3d] & 0x01);
|
||||
|
||||
sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]);
|
||||
sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]);
|
||||
|
||||
sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]);
|
||||
sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bus_master_handlers(via_vt82c596b_t *dev)
|
||||
{
|
||||
@@ -581,6 +601,7 @@ via_vt82c596b_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x09:
|
||||
dev->ide_regs[0x09] = (val & 0x05) | 0x8a;
|
||||
ide_handlers(dev);
|
||||
ide_irqs(dev);
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
@@ -629,8 +650,8 @@ via_vt82c596b_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x3d:
|
||||
sff_set_irq_mode(dev->bm[0], val);
|
||||
sff_set_irq_mode(dev->bm[1], val);
|
||||
dev->ide_regs[0x3d] = val & 0x01;
|
||||
ide_irqs(dev);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
@@ -717,12 +738,14 @@ via_vt82c596b_init(const device_t *info)
|
||||
|
||||
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
sff_set_slot(dev->bm[0], dev->slot);
|
||||
sff_set_irq_mode(dev->bm[0], 0);
|
||||
sff_set_irq_mode(dev->bm[0], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[0], 1, 0);
|
||||
sff_set_irq_pin(dev->bm[0], PCI_INTA);
|
||||
|
||||
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
|
||||
sff_set_slot(dev->bm[1], dev->slot);
|
||||
sff_set_irq_mode(dev->bm[1], 0);
|
||||
sff_set_irq_mode(dev->bm[1], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[1], 1, 0);
|
||||
sff_set_irq_pin(dev->bm[1], PCI_INTA);
|
||||
|
||||
dev->nvr = device_add(&via_nvr_device);
|
||||
|
||||
@@ -549,7 +549,7 @@ CXXFLAGS := $(CFLAGS)
|
||||
#########################################################################
|
||||
# Create the (final) list of objects to build. #
|
||||
#########################################################################
|
||||
MAINOBJ := pc.o config.o random.o timer.o io.o apm.o dma.o nmi.o \
|
||||
MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o nmi.o \
|
||||
pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \
|
||||
rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \
|
||||
via_vt82c596b.o $(VNCOBJ) $(RDPOBJ)
|
||||
|
||||
@@ -553,7 +553,7 @@ CXXFLAGS := $(CFLAGS)
|
||||
#########################################################################
|
||||
# Create the (final) list of objects to build. #
|
||||
#########################################################################
|
||||
MAINOBJ := pc.o config.o random.o timer.o io.o apm.o dma.o nmi.o \
|
||||
MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o nmi.o \
|
||||
pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \
|
||||
rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \
|
||||
via_vt82c596b.o $(VNCOBJ) $(RDPOBJ)
|
||||
|
||||
Reference in New Issue
Block a user