Implement DRB locking for VIA Apollo chipsets
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/spd.h>
|
||||
|
||||
|
||||
typedef struct via_apollo_t
|
||||
@@ -226,6 +227,13 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[0][0x53] = (dev->pci_conf[0][0x53] & ~0xf0) | (val & 0xf0);
|
||||
break;
|
||||
|
||||
case 0x56: case 0x57: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: /* DRAM Row Ending Address */
|
||||
if (dev->id >= 0x0691)
|
||||
spd_write_drbs(dev->pci_conf[0], 0x5a, 0x56, 8);
|
||||
else if (addr >= 0x5a)
|
||||
spd_write_drbs(dev->pci_conf[0], 0x5a, 0x5f, 8);
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
if (dev->id == 0x0597)
|
||||
dev->pci_conf[0][0x58] = (dev->pci_conf[0][0x58] & ~0xee) | (val & 0xee);
|
||||
|
||||
@@ -407,10 +407,14 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
|
||||
void
|
||||
spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
|
||||
{
|
||||
uint8_t row, dimm;
|
||||
uint8_t row, dimm, drb, apollo = 0;
|
||||
uint16_t size, vslots[SPD_MAX_SLOTS];
|
||||
|
||||
spd_log("DRB write begin\n");
|
||||
/* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */
|
||||
if (reg_max < reg_min) {
|
||||
apollo = reg_max;
|
||||
reg_max = reg_min + 8;
|
||||
}
|
||||
|
||||
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
|
||||
if (!spd_present) {
|
||||
@@ -437,11 +441,16 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit
|
||||
size = (vslots[dimm] >> 1);
|
||||
}
|
||||
|
||||
/* Populate DRB register, adding the previous DRB's value.
|
||||
/* Determine the DRB register to write. */
|
||||
drb = reg_min + row;
|
||||
if ((apollo) && ((drb & 0xf) < 0x8))
|
||||
drb = apollo + (drb & 0xf);
|
||||
|
||||
/* Write DRB register, adding the previous DRB's value.
|
||||
This will intentionally overflow on 440GX with 2 GB. */
|
||||
regs[reg_min + row] = ((row > 0) ? regs[reg_min + row - 1] : 0);
|
||||
regs[drb] = ((row > 0) ? regs[drb - 1] : 0);
|
||||
if (size)
|
||||
regs[reg_min + row] += (size / drb_unit);
|
||||
spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[reg_min + row]);
|
||||
regs[drb] += (size / drb_unit);
|
||||
spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user