A couple of fixes

This commit is contained in:
Jasmine Iwanek
2022-07-27 13:57:03 -04:00
parent a7c4b8740d
commit eee8ce6c7d
5 changed files with 451 additions and 56 deletions

View File

@@ -150,6 +150,11 @@ void (*cpu_exec)(int cycs);
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
void cpu_INVD(uint8_t wb)
{
mem_invalidate_mtrr(wb);
}
static int cyrix_addr;
@@ -2174,24 +2179,14 @@ cpu_RDMSR(void)
case 0x204: case 0x205: case 0x206: case 0x207:
case 0x208: case 0x209: case 0x20a: case 0x20b:
case 0x20c: case 0x20d: case 0x20e: case 0x20f:
temp = EAX | ((uint64_t)EDX << 32);
temp2 = (ECX - 0x200) >> 1;
if (ECX & 1) {
cpu_log("MTRR physmask[%d] = %08llx\n", temp2, temp);
if ((mtrr_physmask_msr[temp2] >> 11) & 0x1)
mem_del_mtrr(mtrr_physbase_msr[temp2] & ~(0xFFF), mtrr_physmask_msr[temp2] & ~(0xFFF));
if ((temp >> 11) & 0x1)
mem_add_mtrr(mtrr_physbase_msr[temp2] & ~(0xFFF), temp & ~(0xFFF), mtrr_physbase_msr[temp2] & 0xFF);
mtrr_physmask_msr[temp2] = temp;
} else {
cpu_log("MTRR physbase[%d] = %08llx\n", temp2, temp);
mtrr_physbase_msr[temp2] = temp;
}
break;
if (ECX & 1) {
EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff;
EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32;
} else {
EAX = msr.mtrr_physbase[(ECX - 0x200) >> 1] & 0xffffffff;
EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32;
}
break;
case 0x250:
EAX = msr.mtrr_fix64k_8000 & 0xffffffff;
EDX = msr.mtrr_fix64k_8000 >> 32;
@@ -2625,23 +2620,24 @@ cpu_WRMSR(void)
case 0x204: case 0x205: case 0x206: case 0x207:
case 0x208: case 0x209: case 0x20a: case 0x20b:
case 0x20c: case 0x20d: case 0x20e: case 0x20f:
temp = EAX | ((uint64_t)EDX << 32);
temp2 = (ECX - 0x200) >> 1;
if (ECX & 1) {
cpu_log("MTRR physmask[%d] = %08llx\n", temp2, temp);
temp = EAX | ((uint64_t)EDX << 32);
temp2 = (ECX - 0x200) >> 1;
if (ECX & 1) {
cpu_log("MTRR physmask[%d] = %08llx\n", temp2, temp);
if ((mtrr_physmask_msr[temp2] >> 11) & 0x1)
mem_del_mtrr(mtrr_physbase_msr[temp2] & ~(0xfff), mtrr_physmask_msr[temp2] & ~(0xfff));
if ((msr.mtrr_physmask[temp2] >> 11) & 0x1)
mem_del_mtrr(msr.mtrr_physbase[temp2] & ~(0xFFF), msr.mtrr_physmask[temp2] & ~(0xFFF));
if ((temp >> 11) & 0x1)
mem_add_mtrr(mtrr_physbase_msr[temp2] & ~(0xfff), temp & ~(0xfff), mtrr_physbase_msr[temp2] & 0xff);
if ((temp >> 11) & 0x1)
mem_add_mtrr(msr.mtrr_physbase[temp2] & ~(0xFFF), temp & ~(0xFFF), msr.mtrr_physbase[temp2] & 0xFF);
mtrr_physmask_msr[temp2] = temp;
} else {
cpu_log("MTRR physbase[%d] = %08llx\n", temp2, temp);
msr.mtrr_physmask[temp2] = temp;
} else {
cpu_log("MTRR physbase[%d] = %08llx\n", temp2, temp);
mtrr_physbase_msr[temp2] = temp;
}
msr.mtrr_physbase[temp2] = temp;
}
break;
case 0x250:
msr.mtrr_fix64k_8000 = EAX | ((uint64_t)EDX << 32);
break;
@@ -2843,11 +2839,24 @@ amd_k_invalid_wrmsr:
case 0x204: case 0x205: case 0x206: case 0x207:
case 0x208: case 0x209: case 0x20a: case 0x20b:
case 0x20c: case 0x20d: case 0x20e: case 0x20f:
if (ECX & 1)
msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32);
else
msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32);
break;
temp = EAX | ((uint64_t)EDX << 32);
temp2 = (ECX - 0x200) >> 1;
if (ECX & 1) {
cpu_log("MTRR physmask[%d] = %08llx\n", temp2, temp);
if ((msr.mtrr_physmask[temp2] >> 11) & 0x1)
mem_del_mtrr(msr.mtrr_physbase[temp2] & ~(0xFFF), msr.mtrr_physmask[temp2] & ~(0xFFF));
if ((temp >> 11) & 0x1)
mem_add_mtrr(msr.mtrr_physbase[temp2] & ~(0xFFF), temp & ~(0xFFF), msr.mtrr_physbase[temp2] & 0xFF);
msr.mtrr_physmask[temp2] = temp;
} else {
cpu_log("MTRR physbase[%d] = %08llx\n", temp2, temp);
msr.mtrr_physbase[temp2] = temp;
}
break;
case 0x250:
msr.mtrr_fix64k_8000 = EAX | ((uint64_t)EDX << 32);
break;
@@ -2902,12 +2911,6 @@ i686_invalid_wrmsr:
}
}
void cpu_INVD(uint8_t wb)
{
mem_invalidate_mtrr(wb);
}
static int cyrix_addr;
static void
cpu_write(uint16_t addr, uint8_t val, void *priv)

View File

@@ -108,7 +108,6 @@
#define MACHINE_USB_PRI 0x04000000 /* sys has int pri USB */
#define MACHINE_USB_SEC 0x08000000 /* sys has int sec USB */
#define MACHINE_COREBOOT 0x10000000 /* sys has coreboot BIOS */
/* Combined flags. */
#define MACHINE_IDE (MACHINE_IDE_PRI) /* sys has int single IDE/ATAPI - mark as pri IDE/ATAPI */
#define MACHINE_IDE_DUAL (MACHINE_IDE_PRI | MACHINE_IDE_SEC) /* sys has int dual IDE/ATAPI - mark as both pri and sec IDE/ATAPI */
@@ -664,6 +663,8 @@ extern int machine_at_p6i440e2_init(const machine_t *);
extern int machine_at_p2bls_init(const machine_t *);
extern int machine_at_p3bf_init(const machine_t *);
extern int machine_at_p2bls_coreboot_init(const machine_t *);
extern int machine_at_p3bf_coreboot_init(const machine_t *);
extern int machine_at_bf6_init(const machine_t *);
extern int machine_at_ax6bc_init(const machine_t *);
extern int machine_at_atc6310bxii_init(const machine_t *);

View File

@@ -194,12 +194,46 @@ machine_at_p2bls_init(const machine_t *model)
{
int ret;
if (model->flags & MACHINE_COREBOOT)
ret = bios_load_linear("roms/machines/p2bls/coreboot.rom",
0x000c0000, 262144, 0);
else
ret = bios_load_linear("roms/machines/p2bls/1014ls.003",
0x000c0000, 262144, 0);
ret = bios_load_linear("roms/machines/p2bls/1014ls.003",
0x000c0000, 262144, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* SCSI */
pci_register_slot(0x07, PCI_CARD_NORMAL, 3, 4, 1, 2); /* LAN */
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&w83977ef_device);
//device_add(ics9xxx_get(ICS9150_08)); /* setting proper speeds requires some interaction with the AS97127F ASIC */
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */
hwm_values.temperatures[1] = 0; /* unused */
hwm_values.temperatures[2] -= 3; /* CPU offset */
return ret;
}
int
machine_at_p2bls_coreboot_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/p2bls/coreboot.rom",
0x000c0000, 262144, 0);
if (bios_only || !ret)
return ret;
@@ -236,13 +270,46 @@ machine_at_p3bf_init(const machine_t *model)
{
int ret;
if (model->flags & MACHINE_COREBOOT)
ret = bios_load_linear("roms/machines/p3bf/coreboot.rom",
0x000c0000, 262144, 0);
else
// ret = bios_load_linear("roms/machines/p3bf/bx3f1006.awd",
ret = bios_load_linear("roms/machines/p3bf/1008f.004",
0x000c0000, 262144, 0);
// ret = bios_load_linear("roms/machines/p3bf/bx3f1006.awd",
ret = bios_load_linear("roms/machines/p3bf/1008f.004",
0x000c0000, 262144, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&w83977ef_device);
device_add(ics9xxx_get(ICS9250_08));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */
hwm_values.voltages[4] = hwm_values.voltages[5]; /* +12V reading not in line with other boards; appears to be close to the -12V reading */
return ret;
}
int
machine_at_p3bf_coreboot_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/p3bf/coreboot.rom",
0x000c0000, 262144, 0);
if (bios_only || !ret)
return ret;

View File

@@ -9858,6 +9858,40 @@ const machine_t machines[] = {
.device = NULL,
.vid_device = NULL
},
{
.name = "[i440BX] ASUS P2B-LS (coreboot)",
.internal_name = "p2bls_coreboot",
.type = MACHINE_TYPE_SLOT1,
.chipset = MACHINE_CHIPSET_INTEL_440BX,
.init = machine_at_p2bls_coreboot_init,
.pad = 0,
.pad0 = 0,
.pad1 = MACHINE_AVAILABLE,
.pad2 = 0,
.cpu = {
.package = CPU_PKG_SLOT1,
.block = CPU_BLOCK_NONE,
.min_bus = 50000000,
.max_bus = 112121212,
.min_voltage = 1300,
.max_voltage = 3500,
.min_multi = 1.5,
.max_multi = 8.0
},
.bus_flags = MACHINE_PS2_AGP,
.flags = MACHINE_IDE_DUAL | MACHINE_COREBOOT,
.ram = {
.min = 8192,
.max = 1048576,
.step = 8192
},
.nvrmask = 255,
.kbc = KBC_UNKNOWN,
.kbc_p1 = 0,
.gpio = 0,
.device = NULL,
.vid_device = NULL
},
/* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC
firmware. */
{
@@ -9894,6 +9928,40 @@ const machine_t machines[] = {
.device = NULL,
.vid_device = NULL
},
{
.name = "[i440BX] ASUS P3B-F (coreboot)",
.internal_name = "p3bf_coreboot",
.type = MACHINE_TYPE_SLOT1,
.chipset = MACHINE_CHIPSET_INTEL_440BX,
.init = machine_at_p3bf_coreboot_init,
.pad = 0,
.pad0 = 0,
.pad1 = MACHINE_AVAILABLE,
.pad2 = 0,
.cpu = {
.package = CPU_PKG_SLOT1,
.block = CPU_BLOCK_NONE,
.min_bus = 66666667,
.max_bus = 150000000,
.min_voltage = 1300,
.max_voltage = 3500,
.min_multi = 1.5,
.max_multi = 8.0
},
.bus_flags = MACHINE_PS2_AGP,
.flags = MACHINE_IDE_DUAL | MACHINE_COREBOOT,
.ram = {
.min = 8192,
.max = 1048576,
.step = 8192
},
.nvrmask = 255,
.kbc = KBC_UNKNOWN,
.kbc_p1 = 0,
.gpio = 0,
.device = NULL,
.vid_device = NULL
},
/* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC
firmware. */
{

View File

@@ -23,6 +23,7 @@
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <errno.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/version.h>
@@ -129,6 +130,10 @@ static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO];
static uint8_t *_mem_exec[MEM_MAPPINGS_NO];
static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };
static mem_state_t _mem_state[MEM_MAPPINGS_NO];
static uint8_t *mtrr_areas[MEM_MAPPINGS_NO];
static uint8_t mtrr_area_refcounts[MEM_MAPPINGS_NO];
static uint32_t remap_start_addr;
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
static size_t ram_size = 0, ram2_size = 0;
@@ -783,6 +788,8 @@ readmembl(uint32_t addr)
{
mem_mapping_t *map;
uint64_t a;
uint32_t page;
uint8_t *mtrr;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
@@ -800,6 +807,11 @@ readmembl(uint32_t addr)
}
addr = (uint32_t) (addr64 & rammask);
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr)
return mtrr[addr & MEM_GRANULARITY_MASK];
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->read_b)
return map->read_b(addr, map->p);
@@ -811,6 +823,8 @@ readmembl(uint32_t addr)
void
writemembl(uint32_t addr, uint8_t val)
{
uint32_t page;
uint8_t *mtrr;
mem_mapping_t *map;
uint64_t a;
@@ -835,6 +849,13 @@ writemembl(uint32_t addr, uint8_t val)
}
addr = (uint32_t) (addr64 & rammask);
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr) {
mtrr[addr & MEM_GRANULARITY_MASK] = val;
return;
}
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->write_b)
map->write_b(addr, val, map->p);
@@ -846,6 +867,8 @@ uint8_t
readmembl_no_mmut(uint32_t addr, uint32_t a64)
{
mem_mapping_t *map;
uint32_t page;
uint8_t *mtrr;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
@@ -859,6 +882,11 @@ readmembl_no_mmut(uint32_t addr, uint32_t a64)
} else
addr &= rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr)
return mtrr[addr & MEM_GRANULARITY_MASK];
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->read_b)
return map->read_b(addr, map->p);
@@ -872,6 +900,8 @@ void
writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val)
{
mem_mapping_t *map;
uint32_t page;
uint8_t *mtrr;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
@@ -890,6 +920,13 @@ writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val)
} else
addr &= rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr) {
mtrr[addr & MEM_GRANULARITY_MASK] = val;
return;
}
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->write_b)
map->write_b(addr, val, map->p);
@@ -900,6 +937,8 @@ uint16_t
readmemwl(uint32_t addr)
{
mem_mapping_t *map;
uint32_t page;
uint8_t *mtrr;
int i;
uint64_t a;
@@ -944,6 +983,11 @@ readmemwl(uint32_t addr)
addr = addr64a[0] & rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr)
return mtrr[addr & MEM_GRANULARITY_MASK] | ((uint16_t) (mtrr[(addr + 1) & MEM_GRANULARITY_MASK]) << 8);
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->read_w)
@@ -961,6 +1005,8 @@ readmemwl(uint32_t addr)
void
writememwl(uint32_t addr, uint16_t val)
{
uint32_t page;
uint8_t *mtrr;
mem_mapping_t *map;
int i;
uint64_t a;
@@ -1019,6 +1065,14 @@ writememwl(uint32_t addr, uint16_t val)
addr = addr64a[0] & rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr) {
mtrr[addr & MEM_GRANULARITY_MASK] = val;
mtrr[(addr + 1) & MEM_GRANULARITY_MASK] = val >> 8;
return;
}
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->write_w) {
@@ -1038,6 +1092,8 @@ writememwl(uint32_t addr, uint16_t val)
uint16_t
readmemwl_no_mmut(uint32_t addr, uint32_t *a64)
{
uint32_t page;
uint8_t *mtrr;
mem_mapping_t *map;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2);
@@ -1069,6 +1125,11 @@ readmemwl_no_mmut(uint32_t addr, uint32_t *a64)
} else
addr &= rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr)
return mtrr[addr & MEM_GRANULARITY_MASK] | ((uint16_t) (mtrr[(addr + 1) & MEM_GRANULARITY_MASK]) << 8);
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->read_w)
@@ -1087,6 +1148,8 @@ readmemwl_no_mmut(uint32_t addr, uint32_t *a64)
void
writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val)
{
uint32_t page;
uint8_t *mtrr;
mem_mapping_t *map;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2);
@@ -1126,6 +1189,14 @@ writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val)
} else
addr &= rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr) {
mtrr[addr & MEM_GRANULARITY_MASK] = val;
mtrr[(addr + 1) & MEM_GRANULARITY_MASK] = val >> 8;
return;
}
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->write_w) {
@@ -1144,6 +1215,8 @@ writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val)
uint32_t
readmemll(uint32_t addr)
{
uint32_t page;
uint8_t *mtrr;
mem_mapping_t *map;
int i;
uint64_t a = 0x0000000000000000ULL;
@@ -1202,6 +1275,11 @@ readmemll(uint32_t addr)
addr = addr64a[0] & rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr)
return mtrr[addr & MEM_GRANULARITY_MASK] | ((uint32_t) (mtrr[(addr + 1) & MEM_GRANULARITY_MASK]) << 8) | ((uint32_t) (mtrr[(addr + 2) & MEM_GRANULARITY_MASK]) << 16) | ((uint32_t) (mtrr[(addr + 3) & MEM_GRANULARITY_MASK]) << 24);
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->read_l)
@@ -1224,6 +1302,8 @@ readmemll(uint32_t addr)
void
writememll(uint32_t addr, uint32_t val)
{
uint32_t page;
uint8_t *mtrr;
mem_mapping_t *map;
int i;
uint64_t a = 0x0000000000000000ULL;
@@ -1294,6 +1374,16 @@ writememll(uint32_t addr, uint32_t val)
addr = addr64a[0] & rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr) {
mtrr[addr & MEM_GRANULARITY_MASK] = val;
mtrr[(addr + 1) & MEM_GRANULARITY_MASK] = val >> 8;
mtrr[(addr + 2) & MEM_GRANULARITY_MASK] = val >> 16;
mtrr[(addr + 3) & MEM_GRANULARITY_MASK] = val >> 24;
return;
}
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->write_l) {
@@ -1320,6 +1410,8 @@ uint32_t
readmemll_no_mmut(uint32_t addr, uint32_t *a64)
{
mem_mapping_t *map;
uint32_t page;
uint8_t *mtrr;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4);
@@ -1349,6 +1441,11 @@ readmemll_no_mmut(uint32_t addr, uint32_t *a64)
addr = (uint32_t) (a64[0] & rammask);
} else
addr &= rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr)
return mtrr[addr & MEM_GRANULARITY_MASK] | ((uint32_t) (mtrr[(addr + 1) & MEM_GRANULARITY_MASK]) << 8) | ((uint32_t) (mtrr[(addr + 2) & MEM_GRANULARITY_MASK]) << 16) | ((uint32_t) (mtrr[(addr + 3) & MEM_GRANULARITY_MASK]) << 24);
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
@@ -1374,6 +1471,8 @@ void
writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val)
{
mem_mapping_t *map;
uint32_t page;
uint8_t *mtrr;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4);
@@ -1412,6 +1511,16 @@ writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val)
} else
addr &= rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr) {
mtrr[addr & MEM_GRANULARITY_MASK] = val;
mtrr[(addr + 1) & MEM_GRANULARITY_MASK] = val >> 8;
mtrr[(addr + 2) & MEM_GRANULARITY_MASK] = val >> 16;
mtrr[(addr + 3) & MEM_GRANULARITY_MASK] = val >> 24;
return;
}
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->write_l) {
@@ -1438,6 +1547,8 @@ readmemql(uint32_t addr)
{
mem_mapping_t *map;
int i;
uint32_t page;
uint8_t *mtrr;
uint64_t a = 0x0000000000000000ULL;
for (i = 0; i < 8; i++)
@@ -1493,6 +1604,11 @@ readmemql(uint32_t addr)
addr = addr64a[0] & rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr)
return readmemll(addr) | ((uint64_t)readmemll(addr+4)<<32);
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->read_l)
return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32);
@@ -1506,6 +1622,8 @@ writememql(uint32_t addr, uint64_t val)
{
mem_mapping_t *map;
int i;
uint32_t page;
uint8_t *mtrr;
uint64_t a = 0x0000000000000000ULL;
for (i = 0; i < 8; i++)
@@ -1572,6 +1690,20 @@ writememql(uint32_t addr, uint64_t val)
addr = addr64a[0] & rammask;
page = (addr >> MEM_GRANULARITY_BITS);
mtrr = mtrr_areas[page];
if (mtrr) {
mtrr[addr & MEM_GRANULARITY_MASK] = val;
mtrr[(addr + 1) & MEM_GRANULARITY_MASK] = val >> 8;
mtrr[(addr + 2) & MEM_GRANULARITY_MASK] = val >> 16;
mtrr[(addr + 3) & MEM_GRANULARITY_MASK] = val >> 24;
mtrr[(addr + 4) & MEM_GRANULARITY_MASK] = val >> 32;
mtrr[(addr + 5) & MEM_GRANULARITY_MASK] = val >> 40;
mtrr[(addr + 6) & MEM_GRANULARITY_MASK] = val >> 48;
mtrr[(addr + 7) & MEM_GRANULARITY_MASK] = val >> 56;
return;
}
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->write_l) {
@@ -2717,6 +2849,14 @@ mem_reset(void)
memset(pages, 0x00, pages_sz*sizeof(page_t));
for (c = 0; c < MEM_MAPPINGS_NO; c++) {
if (mtrr_areas[c]) {
free(mtrr_areas[c]);
mtrr_areas[c] = 0;
}
mtrr_area_refcounts[c] = 0;
}
#ifdef USE_NEW_DYNAREC
byte_dirty_mask = malloc((mem_size * 1024) / 8);
memset(byte_dirty_mask, 0, (mem_size * 1024) / 8);
@@ -2821,6 +2961,8 @@ mem_init(void)
readlookupp = malloc((1<<20)*sizeof(uint8_t));
writelookup2 = malloc((1<<20)*sizeof(uintptr_t));
writelookupp = malloc((1<<20)*sizeof(uint8_t));
memset(mtrr_areas, 0x00, MEM_MAPPINGS_NO*sizeof(uint8_t *));
}
@@ -2925,3 +3067,117 @@ mem_a20_recalc(void)
mem_a20_state = state;
}
void
mem_add_mtrr(uint64_t base, uint64_t mask, uint8_t type)
{
uint64_t size = ((~mask) & 0xffffffff) + 1;
uint64_t page_base, page, addr;
uint8_t *mtrr;
mem_log("Adding MTRR base=%08llx mask=%08llx size=%08llx type=%d\n", base, mask, size, type);
if (size > 0x8000) {
mem_log("Ignoring MTRR, size too big\n");
return;
}
if (mem_addr_is_ram(base)) {
mem_log("Ignoring MTRR, base is in RAM\n");
return;
}
for (page_base = base; page_base < base + size; page_base += MEM_GRANULARITY_SIZE) {
page = (page_base >> MEM_GRANULARITY_BITS);
if (mtrr_areas[page]) {
/* area already allocated, increase refcount and don't allocate it again */
mtrr_area_refcounts[page]++;
continue;
}
/* allocate area */
mtrr = malloc(MEM_GRANULARITY_SIZE);
if (!mtrr)
fatal("Failed to allocate page for MTRR page %08llx (errno=%d)\n", page_base, errno);
/* populate area with data from RAM */
for (addr = 0; addr < MEM_GRANULARITY_SIZE; addr++) {
mtrr[addr] = readmembl(page_base | addr);
}
/* enable area */
mtrr_areas[page] = mtrr;
}
}
void
mem_del_mtrr(uint64_t base, uint64_t mask)
{
uint64_t size = ((~mask) & 0xffffffff) + 1;
uint64_t page_base, page;
mem_log("Deleting MTRR base=%08llx mask=%08llx size=%08llx\n", base, mask, size);
if (size > 0x8000) {
mem_log("Ignoring MTRR, size too big\n");
return;
}
if (mem_addr_is_ram(base)) {
mem_log("Ignoring MTRR, base is in RAM\n");
return;
}
for (page_base = base; page_base < base + size; page_base += MEM_GRANULARITY_SIZE) {
page = (page_base >> MEM_GRANULARITY_BITS);
if (mtrr_areas[page]) {
/* decrease reference count */
if (mtrr_area_refcounts[page] > 0)
mtrr_area_refcounts[page]--;
/* if no references are left, de-allocate area */
if (mtrr_area_refcounts[page] == 0) {
free(mtrr_areas[page]);
mtrr_areas[page] = 0;
}
}
}
}
void
mem_invalidate_mtrr(uint8_t wb)
{
uint64_t page, page_base, addr;
uint8_t *mtrr;
mem_log("Invalidating cache (writeback=%d)\n", wb);
for (page = 0; page < MEM_MAPPINGS_NO; page++) {
mtrr = mtrr_areas[page];
if (mtrr) {
page_base = (page << MEM_GRANULARITY_BITS);
if (!mem_addr_is_ram(page_base))
continue; /* don't invalidate pages not backed by RAM (hack?) */
/* temporarily set area aside */
mtrr_areas[page] = 0;
/* write data back to memory if requested */
if (wb && write_mapping[page]) { /* don't write back to a page which can't be written to */
for (addr = 0; addr < MEM_GRANULARITY_SIZE; addr++) {
writemembl(page_base | addr, mtrr[addr]);
}
}
/* re-populate area with data from memory */
for (addr = 0; addr < MEM_GRANULARITY_SIZE; addr++) {
mtrr[addr] = readmembl(page_base | addr);
}
/* re-enable area */
mtrr_areas[page] = mtrr;
}
}
}