mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 18:08:20 -07:00
A couple of fixes
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
{
|
||||
|
||||
256
src/mem/mem.c
256
src/mem/mem.c
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user