mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-12-17 21:26:13 -07:00
* KVM error improvement from Laurent
* CONFIG_PARALLEL fix from Mirek * Atomic/optimized dirty bitmap access from myself and Stefan * BUILD_DIR convenience/bugfix from Peter C * Memory leak fix from Shannon * SMM improvements (though still TCG only) from myself and Gerd, acked by mst -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAABCAAGBQJVceAwAAoJEL/70l94x66Dyz4H/RHS/OUGo6HOwG1FZ4l8RxRl FY+pwJqinxFyGySmMLVHEeQCsIfxgi8bOmuWblG7sdt245nhMIj2jglyEOCUA3RN Q9qxQr6QyXBWiwK4bfB7xI1z3/mc8cVvuxjtkLaBMa16A4MXMunWCDcyhsX9/0Vw VySgTgBbn5AyY5x58TbkB7Tl6hMZgxF0yNwU6IGQvP079dgREAL2tzR1Wk8kPC80 ltLWlrwTAzF2km5m6rmstpMeZ/XIaq3DD2LU03SyUhefMsYowGKK+7Boo4lHpVm9 XAlxflahN7VGtQuno5RpYNNSzGqSJgqu5X5JxCMnbWdPi4sX3bijQdcUhW3/0oo= =KPIz -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging * KVM error improvement from Laurent * CONFIG_PARALLEL fix from Mirek * Atomic/optimized dirty bitmap access from myself and Stefan * BUILD_DIR convenience/bugfix from Peter C * Memory leak fix from Shannon * SMM improvements (though still TCG only) from myself and Gerd, acked by mst # gpg: Signature made Fri Jun 5 18:45:20 2015 BST using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (62 commits) update Linux headers from kvm/next atomics: add explicit compiler fence in __atomic memory barriers ich9: implement SMI_LOCK q35: implement TSEG q35: add test for SMRAM.D_LCK q35: implement SMRAM.D_LCK q35: add config space wmask for SMRAM and ESMRAMC q35: fix ESMRAMC default q35: implement high SMRAM hw/i386: remove smram_update target-i386: use memory API to implement SMRAM hw/i386: add a separate region that tracks the SMRAME bit target-i386: create a separate AddressSpace for each CPU vl: run "late" notifiers immediately qom: add object_property_add_const_link vl: allow full-blown QemuOpts syntax for -global pflash_cfi01: add secure property pflash_cfi01: change to new-style MMIO accessors pflash_cfi01: change big-endian property to BIT type target-i386: wake up processors that receive an SMI ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
ee09f84e6b
75 changed files with 1548 additions and 1043 deletions
|
|
@ -94,7 +94,8 @@ static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val,
|
|||
ICH9LPCPMRegs *pm = opaque;
|
||||
switch (addr) {
|
||||
case 0:
|
||||
pm->smi_en = val;
|
||||
pm->smi_en &= ~pm->smi_en_wmask;
|
||||
pm->smi_en |= (val & pm->smi_en_wmask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -198,6 +199,7 @@ static void pm_reset(void *opaque)
|
|||
* support SMM mode. */
|
||||
pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
|
||||
}
|
||||
pm->smi_en_wmask = ~0;
|
||||
|
||||
acpi_update_sci(&pm->acpi_regs, pm->irq);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -525,7 +525,7 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
|
|||
qdev_prop_set_uint64(dev, "sector-length", VEXPRESS_FLASH_SECT_SIZE);
|
||||
qdev_prop_set_uint8(dev, "width", 4);
|
||||
qdev_prop_set_uint8(dev, "device-width", 2);
|
||||
qdev_prop_set_uint8(dev, "big-endian", 0);
|
||||
qdev_prop_set_bit(dev, "big-endian", false);
|
||||
qdev_prop_set_uint16(dev, "id0", 0x89);
|
||||
qdev_prop_set_uint16(dev, "id1", 0x18);
|
||||
qdev_prop_set_uint16(dev, "id2", 0x00);
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ static void create_one_flash(const char *name, hwaddr flashbase,
|
|||
qdev_prop_set_uint64(dev, "sector-length", sectorlength);
|
||||
qdev_prop_set_uint8(dev, "width", 4);
|
||||
qdev_prop_set_uint8(dev, "device-width", 2);
|
||||
qdev_prop_set_uint8(dev, "big-endian", 0);
|
||||
qdev_prop_set_bit(dev, "big-endian", false);
|
||||
qdev_prop_set_uint16(dev, "id0", 0x89);
|
||||
qdev_prop_set_uint16(dev, "id1", 0x18);
|
||||
qdev_prop_set_uint16(dev, "id2", 0x00);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ do { \
|
|||
#define TYPE_CFI_PFLASH01 "cfi.pflash01"
|
||||
#define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01)
|
||||
|
||||
#define PFLASH_BE 0
|
||||
#define PFLASH_SECURE 1
|
||||
|
||||
struct pflash_t {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
|
|
@ -75,7 +78,7 @@ struct pflash_t {
|
|||
uint8_t bank_width;
|
||||
uint8_t device_width; /* If 0, device width not specified. */
|
||||
uint8_t max_device_width; /* max device width in bytes */
|
||||
uint8_t be;
|
||||
uint32_t features;
|
||||
uint8_t wcycle; /* if 0, the flash is read normally */
|
||||
int ro;
|
||||
uint8_t cmd;
|
||||
|
|
@ -235,12 +238,57 @@ static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
|
|||
return resp;
|
||||
}
|
||||
|
||||
static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset,
|
||||
int width, int be)
|
||||
{
|
||||
uint8_t *p;
|
||||
uint32_t ret;
|
||||
|
||||
p = pfl->storage;
|
||||
switch (width) {
|
||||
case 1:
|
||||
ret = p[offset];
|
||||
DPRINTF("%s: data offset " TARGET_FMT_plx " %02x\n",
|
||||
__func__, offset, ret);
|
||||
break;
|
||||
case 2:
|
||||
if (be) {
|
||||
ret = p[offset] << 8;
|
||||
ret |= p[offset + 1];
|
||||
} else {
|
||||
ret = p[offset];
|
||||
ret |= p[offset + 1] << 8;
|
||||
}
|
||||
DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n",
|
||||
__func__, offset, ret);
|
||||
break;
|
||||
case 4:
|
||||
if (be) {
|
||||
ret = p[offset] << 24;
|
||||
ret |= p[offset + 1] << 16;
|
||||
ret |= p[offset + 2] << 8;
|
||||
ret |= p[offset + 3];
|
||||
} else {
|
||||
ret = p[offset];
|
||||
ret |= p[offset + 1] << 8;
|
||||
ret |= p[offset + 2] << 16;
|
||||
ret |= p[offset + 3] << 24;
|
||||
}
|
||||
DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n",
|
||||
__func__, offset, ret);
|
||||
break;
|
||||
default:
|
||||
DPRINTF("BUG in %s\n", __func__);
|
||||
abort();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
|
||||
int width, int be)
|
||||
{
|
||||
hwaddr boff;
|
||||
uint32_t ret;
|
||||
uint8_t *p;
|
||||
|
||||
ret = -1;
|
||||
|
||||
|
|
@ -257,43 +305,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
|
|||
/* fall through to read code */
|
||||
case 0x00:
|
||||
/* Flash area read */
|
||||
p = pfl->storage;
|
||||
switch (width) {
|
||||
case 1:
|
||||
ret = p[offset];
|
||||
DPRINTF("%s: data offset " TARGET_FMT_plx " %02x\n",
|
||||
__func__, offset, ret);
|
||||
break;
|
||||
case 2:
|
||||
if (be) {
|
||||
ret = p[offset] << 8;
|
||||
ret |= p[offset + 1];
|
||||
} else {
|
||||
ret = p[offset];
|
||||
ret |= p[offset + 1] << 8;
|
||||
}
|
||||
DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n",
|
||||
__func__, offset, ret);
|
||||
break;
|
||||
case 4:
|
||||
if (be) {
|
||||
ret = p[offset] << 24;
|
||||
ret |= p[offset + 1] << 16;
|
||||
ret |= p[offset + 2] << 8;
|
||||
ret |= p[offset + 3];
|
||||
} else {
|
||||
ret = p[offset];
|
||||
ret |= p[offset + 1] << 8;
|
||||
ret |= p[offset + 2] << 16;
|
||||
ret |= p[offset + 3] << 24;
|
||||
}
|
||||
DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n",
|
||||
__func__, offset, ret);
|
||||
break;
|
||||
default:
|
||||
DPRINTF("BUG in %s\n", __func__);
|
||||
}
|
||||
|
||||
ret = pflash_data_read(pfl, offset, width, be);
|
||||
break;
|
||||
case 0x10: /* Single byte program */
|
||||
case 0x20: /* Block erase */
|
||||
|
|
@ -648,101 +660,37 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
|
|||
}
|
||||
|
||||
|
||||
static uint32_t pflash_readb_be(void *opaque, hwaddr addr)
|
||||
{
|
||||
return pflash_read(opaque, addr, 1, 1);
|
||||
}
|
||||
|
||||
static uint32_t pflash_readb_le(void *opaque, hwaddr addr)
|
||||
{
|
||||
return pflash_read(opaque, addr, 1, 0);
|
||||
}
|
||||
|
||||
static uint32_t pflash_readw_be(void *opaque, hwaddr addr)
|
||||
static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_t *value,
|
||||
unsigned len, MemTxAttrs attrs)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
bool be = !!(pfl->features & (1 << PFLASH_BE));
|
||||
|
||||
return pflash_read(pfl, addr, 2, 1);
|
||||
if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
|
||||
*value = pflash_data_read(opaque, addr, len, be);
|
||||
} else {
|
||||
*value = pflash_read(opaque, addr, len, be);
|
||||
}
|
||||
return MEMTX_OK;
|
||||
}
|
||||
|
||||
static uint32_t pflash_readw_le(void *opaque, hwaddr addr)
|
||||
static MemTxResult pflash_mem_write_with_attrs(void *opaque, hwaddr addr, uint64_t value,
|
||||
unsigned len, MemTxAttrs attrs)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
bool be = !!(pfl->features & (1 << PFLASH_BE));
|
||||
|
||||
return pflash_read(pfl, addr, 2, 0);
|
||||
if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
|
||||
return MEMTX_ERROR;
|
||||
} else {
|
||||
pflash_write(opaque, addr, value, len, be);
|
||||
return MEMTX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t pflash_readl_be(void *opaque, hwaddr addr)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
|
||||
return pflash_read(pfl, addr, 4, 1);
|
||||
}
|
||||
|
||||
static uint32_t pflash_readl_le(void *opaque, hwaddr addr)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
|
||||
return pflash_read(pfl, addr, 4, 0);
|
||||
}
|
||||
|
||||
static void pflash_writeb_be(void *opaque, hwaddr addr,
|
||||
uint32_t value)
|
||||
{
|
||||
pflash_write(opaque, addr, value, 1, 1);
|
||||
}
|
||||
|
||||
static void pflash_writeb_le(void *opaque, hwaddr addr,
|
||||
uint32_t value)
|
||||
{
|
||||
pflash_write(opaque, addr, value, 1, 0);
|
||||
}
|
||||
|
||||
static void pflash_writew_be(void *opaque, hwaddr addr,
|
||||
uint32_t value)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
|
||||
pflash_write(pfl, addr, value, 2, 1);
|
||||
}
|
||||
|
||||
static void pflash_writew_le(void *opaque, hwaddr addr,
|
||||
uint32_t value)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
|
||||
pflash_write(pfl, addr, value, 2, 0);
|
||||
}
|
||||
|
||||
static void pflash_writel_be(void *opaque, hwaddr addr,
|
||||
uint32_t value)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
|
||||
pflash_write(pfl, addr, value, 4, 1);
|
||||
}
|
||||
|
||||
static void pflash_writel_le(void *opaque, hwaddr addr,
|
||||
uint32_t value)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
|
||||
pflash_write(pfl, addr, value, 4, 0);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pflash_cfi01_ops_be = {
|
||||
.old_mmio = {
|
||||
.read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
|
||||
.write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
|
||||
},
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static const MemoryRegionOps pflash_cfi01_ops_le = {
|
||||
.old_mmio = {
|
||||
.read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
|
||||
.write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
|
||||
},
|
||||
static const MemoryRegionOps pflash_cfi01_ops = {
|
||||
.read_with_attrs = pflash_mem_read_with_attrs,
|
||||
.write_with_attrs = pflash_mem_write_with_attrs,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
|
|
@ -773,7 +721,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
|
|||
|
||||
memory_region_init_rom_device(
|
||||
&pfl->mem, OBJECT(dev),
|
||||
pfl->be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl,
|
||||
&pflash_cfi01_ops,
|
||||
pfl,
|
||||
pfl->name, total_len, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
|
|
@ -925,7 +874,8 @@ static Property pflash_cfi01_properties[] = {
|
|||
DEFINE_PROP_UINT8("width", struct pflash_t, bank_width, 0),
|
||||
DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0),
|
||||
DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0),
|
||||
DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0),
|
||||
DEFINE_PROP_BIT("big-endian", struct pflash_t, features, PFLASH_BE, 0),
|
||||
DEFINE_PROP_BIT("secure", struct pflash_t, features, PFLASH_SECURE, 0),
|
||||
DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0),
|
||||
DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0),
|
||||
DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0),
|
||||
|
|
@ -975,7 +925,7 @@ pflash_t *pflash_cfi01_register(hwaddr base,
|
|||
qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
|
||||
qdev_prop_set_uint64(dev, "sector-length", sector_len);
|
||||
qdev_prop_set_uint8(dev, "width", bank_width);
|
||||
qdev_prop_set_uint8(dev, "big-endian", !!be);
|
||||
qdev_prop_set_bit(dev, "big-endian", !!be);
|
||||
qdev_prop_set_uint16(dev, "id0", id0);
|
||||
qdev_prop_set_uint16(dev, "id1", id1);
|
||||
qdev_prop_set_uint16(dev, "id2", id2);
|
||||
|
|
|
|||
|
|
@ -641,28 +641,3 @@ static void parallel_register_types(void)
|
|||
}
|
||||
|
||||
type_init(parallel_register_types)
|
||||
|
||||
static void parallel_init(ISABus *bus, int index, CharDriverState *chr)
|
||||
{
|
||||
DeviceState *dev;
|
||||
ISADevice *isadev;
|
||||
|
||||
isadev = isa_create(bus, "isa-parallel");
|
||||
dev = DEVICE(isadev);
|
||||
qdev_prop_set_uint32(dev, "index", index);
|
||||
qdev_prop_set_chr(dev, "chardev", chr);
|
||||
qdev_init_nofail(dev);
|
||||
}
|
||||
|
||||
void parallel_hds_isa_init(ISABus *bus, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(n <= MAX_PARALLEL_PORTS);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (parallel_hds[i]) {
|
||||
parallel_init(bus, i, parallel_hds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ static void cg3_update_display(void *opaque)
|
|||
pix = memory_region_get_ram_ptr(&s->vram_mem);
|
||||
data = (uint32_t *)surface_data(surface);
|
||||
|
||||
memory_region_sync_dirty_bitmap(&s->vram_mem);
|
||||
for (y = 0; y < height; y++) {
|
||||
int update = s->full_update;
|
||||
|
||||
|
|
@ -309,6 +310,7 @@ static void cg3_realizefn(DeviceState *dev, Error **errp)
|
|||
|
||||
memory_region_init_ram(&s->vram_mem, NULL, "cg3.vram", s->vram_size,
|
||||
&error_abort);
|
||||
memory_region_set_log(&s->vram_mem, true, DIRTY_MEMORY_VGA);
|
||||
vmstate_register_ram_global(&s->vram_mem);
|
||||
sysbus_init_mmio(sbd, &s->vram_mem);
|
||||
|
||||
|
|
|
|||
|
|
@ -1109,6 +1109,12 @@ static inline int fimd_get_buffer_id(Exynos4210fimdWindow *w)
|
|||
}
|
||||
}
|
||||
|
||||
static void exynos4210_fimd_invalidate(void *opaque)
|
||||
{
|
||||
Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;
|
||||
s->invalidate = true;
|
||||
}
|
||||
|
||||
/* Updates specified window's MemorySection based on values of WINCON,
|
||||
* VIDOSDA, VIDOSDB, VIDWADDx and SHADOWCON registers */
|
||||
static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win)
|
||||
|
|
@ -1136,7 +1142,11 @@ static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win)
|
|||
/* TODO: add .exit and unref the region there. Not needed yet since sysbus
|
||||
* does not support hot-unplug.
|
||||
*/
|
||||
memory_region_unref(w->mem_section.mr);
|
||||
if (w->mem_section.mr) {
|
||||
memory_region_set_log(w->mem_section.mr, false, DIRTY_MEMORY_VGA);
|
||||
memory_region_unref(w->mem_section.mr);
|
||||
}
|
||||
|
||||
w->mem_section = memory_region_find(sysbus_address_space(sbd),
|
||||
fb_start_addr, w->fb_len);
|
||||
assert(w->mem_section.mr);
|
||||
|
|
@ -1162,6 +1172,8 @@ static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win)
|
|||
cpu_physical_memory_unmap(w->host_fb_addr, fb_mapped_len, 0, 0);
|
||||
goto error_return;
|
||||
}
|
||||
memory_region_set_log(w->mem_section.mr, true, DIRTY_MEMORY_VGA);
|
||||
exynos4210_fimd_invalidate(s);
|
||||
return;
|
||||
|
||||
error_return:
|
||||
|
|
@ -1224,12 +1236,6 @@ static void exynos4210_fimd_update_irq(Exynos4210fimdState *s)
|
|||
}
|
||||
}
|
||||
|
||||
static void exynos4210_fimd_invalidate(void *opaque)
|
||||
{
|
||||
Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;
|
||||
s->invalidate = true;
|
||||
}
|
||||
|
||||
static void exynos4210_update_resolution(Exynos4210fimdState *s)
|
||||
{
|
||||
DisplaySurface *surface = qemu_console_surface(s->console);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ void framebuffer_update_display(
|
|||
assert(mem_section.offset_within_address_space == base);
|
||||
|
||||
memory_region_sync_dirty_bitmap(mem);
|
||||
if (!memory_region_is_logging(mem, DIRTY_MEMORY_VGA)) {
|
||||
invalidate = true;
|
||||
}
|
||||
|
||||
src_base = cpu_physical_memory_map(base, &src_len, 0);
|
||||
/* If we can't map the framebuffer then bail. We could try harder,
|
||||
but it's not really worth it as dirty flag tracking will probably
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ static void g364fb_update_display(void *opaque)
|
|||
qemu_console_resize(s->con, s->width, s->height);
|
||||
}
|
||||
|
||||
memory_region_sync_dirty_bitmap(&s->mem_vram);
|
||||
if (s->ctla & CTLA_FORCE_BLANK) {
|
||||
g364fb_draw_blank(s);
|
||||
} else if (s->depth == 8) {
|
||||
|
|
@ -489,7 +490,7 @@ static void g364fb_init(DeviceState *dev, G364State *s)
|
|||
memory_region_init_ram_ptr(&s->mem_vram, NULL, "vram",
|
||||
s->vram_size, s->vram);
|
||||
vmstate_register_ram(&s->mem_vram, dev);
|
||||
memory_region_set_coalescing(&s->mem_vram);
|
||||
memory_region_set_log(&s->mem_vram, true, DIRTY_MEMORY_VGA);
|
||||
}
|
||||
|
||||
#define TYPE_G364 "sysbus-g364"
|
||||
|
|
|
|||
|
|
@ -1322,6 +1322,7 @@ static void sm501_draw_crt(SM501State * s)
|
|||
}
|
||||
|
||||
/* draw each line according to conditions */
|
||||
memory_region_sync_dirty_bitmap(&s->local_mem_region);
|
||||
for (y = 0; y < height; y++) {
|
||||
int update_hwc = draw_hwc_line ? within_hwc_y_range(s, y, 1) : 0;
|
||||
int update = full_update || update_hwc;
|
||||
|
|
@ -1412,6 +1413,7 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
|
|||
memory_region_init_ram(&s->local_mem_region, NULL, "sm501.local",
|
||||
local_mem_bytes, &error_abort);
|
||||
vmstate_register_ram_global(&s->local_mem_region);
|
||||
memory_region_set_log(&s->local_mem_region, true, DIRTY_MEMORY_VGA);
|
||||
s->local_mem = memory_region_get_ram_ptr(&s->local_mem_region);
|
||||
memory_region_add_subregion(address_space_mem, base, &s->local_mem_region);
|
||||
|
||||
|
|
|
|||
|
|
@ -353,6 +353,7 @@ static void tcx_update_display(void *opaque)
|
|||
return;
|
||||
}
|
||||
|
||||
memory_region_sync_dirty_bitmap(&ts->vram_mem);
|
||||
for (y = 0; y < ts->height; page += TARGET_PAGE_SIZE) {
|
||||
if (memory_region_get_dirty(&ts->vram_mem, page, TARGET_PAGE_SIZE,
|
||||
DIRTY_MEMORY_VGA)) {
|
||||
|
|
@ -446,6 +447,7 @@ static void tcx24_update_display(void *opaque)
|
|||
dd = surface_stride(surface);
|
||||
ds = 1024;
|
||||
|
||||
memory_region_sync_dirty_bitmap(&ts->vram_mem);
|
||||
for (y = 0; y < ts->height; page += TARGET_PAGE_SIZE,
|
||||
page24 += TARGET_PAGE_SIZE, cpage += TARGET_PAGE_SIZE) {
|
||||
if (tcx24_check_dirty(ts, page, page24, cpage)) {
|
||||
|
|
@ -1006,6 +1008,7 @@ static void tcx_realizefn(DeviceState *dev, Error **errp)
|
|||
memory_region_init_ram(&s->vram_mem, OBJECT(s), "tcx.vram",
|
||||
s->vram_size * (1 + 4 + 4), &error_abort);
|
||||
vmstate_register_ram_global(&s->vram_mem);
|
||||
memory_region_set_log(&s->vram_mem, true, DIRTY_MEMORY_VGA);
|
||||
vram_base = memory_region_get_ram_ptr(&s->vram_mem);
|
||||
|
||||
/* 10/ROM : FCode ROM */
|
||||
|
|
|
|||
|
|
@ -1124,7 +1124,7 @@ static void vmsvga_update_display(void *opaque)
|
|||
* Is it more efficient to look at vram VGA-dirty bits or wait
|
||||
* for the driver to issue SVGA_CMD_UPDATE?
|
||||
*/
|
||||
if (memory_region_is_logging(&s->vga.vram)) {
|
||||
if (memory_region_is_logging(&s->vga.vram, DIRTY_MEMORY_VGA)) {
|
||||
vga_sync_dirty_bitmap(&s->vga);
|
||||
dirty = memory_region_get_dirty(&s->vga.vram, 0,
|
||||
surface_stride(surface) * surface_height(surface),
|
||||
|
|
|
|||
21
hw/i386/pc.c
21
hw/i386/pc.c
|
|
@ -164,27 +164,6 @@ uint64_t cpu_get_tsc(CPUX86State *env)
|
|||
return cpu_get_ticks();
|
||||
}
|
||||
|
||||
/* SMM support */
|
||||
|
||||
static cpu_set_smm_t smm_set;
|
||||
static void *smm_arg;
|
||||
|
||||
void cpu_smm_register(cpu_set_smm_t callback, void *arg)
|
||||
{
|
||||
assert(smm_set == NULL);
|
||||
assert(smm_arg == NULL);
|
||||
smm_set = callback;
|
||||
smm_arg = arg;
|
||||
}
|
||||
|
||||
void cpu_smm_update(CPUX86State *env)
|
||||
{
|
||||
if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
|
||||
smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* IRQ handling */
|
||||
int cpu_get_pic_interrupt(CPUX86State *env)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "hw/sysbus.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/isa/isa.h"
|
||||
#include "hw/i386/pc.h"
|
||||
|
||||
static ISABus *isabus;
|
||||
|
||||
|
|
@ -267,3 +268,28 @@ MemoryRegion *isa_address_space_io(ISADevice *dev)
|
|||
}
|
||||
|
||||
type_init(isabus_register_types)
|
||||
|
||||
static void parallel_init(ISABus *bus, int index, CharDriverState *chr)
|
||||
{
|
||||
DeviceState *dev;
|
||||
ISADevice *isadev;
|
||||
|
||||
isadev = isa_create(bus, "isa-parallel");
|
||||
dev = DEVICE(isadev);
|
||||
qdev_prop_set_uint32(dev, "index", index);
|
||||
qdev_prop_set_chr(dev, "chardev", chr);
|
||||
qdev_init_nofail(dev);
|
||||
}
|
||||
|
||||
void parallel_hds_isa_init(ISABus *bus, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(n <= MAX_PARALLEL_PORTS);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (parallel_hds[i]) {
|
||||
parallel_init(bus, i, parallel_hds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,12 +407,28 @@ static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old)
|
|||
}
|
||||
}
|
||||
|
||||
/* config:GEN_PMCON* */
|
||||
static void
|
||||
ich9_lpc_pmcon_update(ICH9LPCState *lpc)
|
||||
{
|
||||
uint16_t gen_pmcon_1 = pci_get_word(lpc->d.config + ICH9_LPC_GEN_PMCON_1);
|
||||
uint16_t wmask;
|
||||
|
||||
if (gen_pmcon_1 & ICH9_LPC_GEN_PMCON_1_SMI_LOCK) {
|
||||
wmask = pci_get_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1);
|
||||
wmask &= ~ICH9_LPC_GEN_PMCON_1_SMI_LOCK;
|
||||
pci_set_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1, wmask);
|
||||
lpc->pm.smi_en_wmask &= ~1;
|
||||
}
|
||||
}
|
||||
|
||||
static int ich9_lpc_post_load(void *opaque, int version_id)
|
||||
{
|
||||
ICH9LPCState *lpc = opaque;
|
||||
|
||||
ich9_lpc_pmbase_update(lpc);
|
||||
ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RBCA_EN */);
|
||||
ich9_lpc_pmcon_update(lpc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -435,6 +451,9 @@ static void ich9_lpc_config_write(PCIDevice *d,
|
|||
if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
|
||||
pci_bus_fire_intx_routing_notifier(lpc->d.bus);
|
||||
}
|
||||
if (ranges_overlap(addr, len, ICH9_LPC_GEN_PMCON_1, 8)) {
|
||||
ich9_lpc_pmcon_update(lpc);
|
||||
}
|
||||
}
|
||||
|
||||
static void ich9_lpc_reset(DeviceState *qdev)
|
||||
|
|
|
|||
|
|
@ -31,26 +31,6 @@
|
|||
#include "sysemu/sysemu.h"
|
||||
#include "hw/pci-host/pam.h"
|
||||
|
||||
void smram_update(MemoryRegion *smram_region, uint8_t smram,
|
||||
uint8_t smm_enabled)
|
||||
{
|
||||
bool smram_enabled;
|
||||
|
||||
smram_enabled = ((smm_enabled && (smram & SMRAM_G_SMRAME)) ||
|
||||
(smram & SMRAM_D_OPEN));
|
||||
memory_region_set_enabled(smram_region, !smram_enabled);
|
||||
}
|
||||
|
||||
void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
|
||||
MemoryRegion *smram_region)
|
||||
{
|
||||
uint8_t smm_enabled = (smm != 0);
|
||||
if (*host_smm_enabled != smm_enabled) {
|
||||
*host_smm_enabled = smm_enabled;
|
||||
smram_update(smram_region, smram, *host_smm_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void init_pam(DeviceState *dev, MemoryRegion *ram_memory,
|
||||
MemoryRegion *system_memory, MemoryRegion *pci_address_space,
|
||||
PAMMemoryRegion *mem, uint32_t start, uint32_t size)
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ struct PCII440FXState {
|
|||
MemoryRegion *ram_memory;
|
||||
PAMMemoryRegion pam_regions[13];
|
||||
MemoryRegion smram_region;
|
||||
uint8_t smm_enabled;
|
||||
MemoryRegion smram, low_smram;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -138,18 +138,10 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
|
|||
pam_update(&d->pam_regions[i], i,
|
||||
pd->config[I440FX_PAM + ((i + 1) / 2)]);
|
||||
}
|
||||
smram_update(&d->smram_region, pd->config[I440FX_SMRAM], d->smm_enabled);
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
|
||||
static void i440fx_set_smm(int val, void *arg)
|
||||
{
|
||||
PCII440FXState *d = arg;
|
||||
PCIDevice *pd = PCI_DEVICE(d);
|
||||
|
||||
memory_region_transaction_begin();
|
||||
smram_set_smm(&d->smm_enabled, val, pd->config[I440FX_SMRAM],
|
||||
&d->smram_region);
|
||||
memory_region_set_enabled(&d->smram_region,
|
||||
!(pd->config[I440FX_SMRAM] & SMRAM_D_OPEN));
|
||||
memory_region_set_enabled(&d->smram,
|
||||
pd->config[I440FX_SMRAM] & SMRAM_G_SMRAME);
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
|
||||
|
|
@ -172,12 +164,13 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
|
|||
PCII440FXState *d = opaque;
|
||||
PCIDevice *pd = PCI_DEVICE(d);
|
||||
int ret, i;
|
||||
uint8_t smm_enabled;
|
||||
|
||||
ret = pci_device_load(pd, f);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
i440fx_update_memory_mappings(d);
|
||||
qemu_get_8s(f, &d->smm_enabled);
|
||||
qemu_get_8s(f, &smm_enabled);
|
||||
|
||||
if (version_id == 2) {
|
||||
for (i = 0; i < PIIX_NUM_PIRQS; i++) {
|
||||
|
|
@ -205,7 +198,10 @@ static const VMStateDescription vmstate_i440fx = {
|
|||
.post_load = i440fx_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(parent_obj, PCII440FXState),
|
||||
VMSTATE_UINT8(smm_enabled, PCII440FXState),
|
||||
/* Used to be smm_enabled, which was basically always zero because
|
||||
* SeaBIOS hardly uses SMM. SMRAM is now handled by CPU code.
|
||||
*/
|
||||
VMSTATE_UNUSED(1),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
|
@ -297,11 +293,7 @@ static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
|
|||
|
||||
static void i440fx_realize(PCIDevice *dev, Error **errp)
|
||||
{
|
||||
PCII440FXState *d = I440FX_PCI_DEVICE(dev);
|
||||
|
||||
dev->config[I440FX_SMRAM] = 0x02;
|
||||
|
||||
cpu_smm_register(&i440fx_set_smm, d);
|
||||
}
|
||||
|
||||
PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
|
||||
|
|
@ -346,11 +338,23 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
|
|||
pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
|
||||
f->pci_address_space);
|
||||
|
||||
/* if *disabled* show SMRAM to all CPUs */
|
||||
memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",
|
||||
f->pci_address_space, 0xa0000, 0x20000);
|
||||
memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
|
||||
&f->smram_region, 1);
|
||||
memory_region_set_enabled(&f->smram_region, false);
|
||||
memory_region_set_enabled(&f->smram_region, true);
|
||||
|
||||
/* smram, as seen by SMM CPUs */
|
||||
memory_region_init(&f->smram, OBJECT(d), "smram", 1ull << 32);
|
||||
memory_region_set_enabled(&f->smram, true);
|
||||
memory_region_init_alias(&f->low_smram, OBJECT(d), "smram-low",
|
||||
f->ram_memory, 0xa0000, 0x20000);
|
||||
memory_region_set_enabled(&f->low_smram, true);
|
||||
memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram);
|
||||
object_property_add_const_link(qdev_get_machine(), "smram",
|
||||
OBJECT(&f->smram), &error_abort);
|
||||
|
||||
init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space,
|
||||
&f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
|
||||
for (i = 0; i < 12; ++i) {
|
||||
|
|
|
|||
|
|
@ -198,6 +198,28 @@ static const TypeInfo q35_host_info = {
|
|||
* MCH D0:F0
|
||||
*/
|
||||
|
||||
static uint64_t tseg_blackhole_read(void *ptr, hwaddr reg, unsigned size)
|
||||
{
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
static void tseg_blackhole_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned width)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static const MemoryRegionOps tseg_blackhole_ops = {
|
||||
.read = tseg_blackhole_read,
|
||||
.write = tseg_blackhole_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.valid.min_access_size = 1,
|
||||
.valid.max_access_size = 4,
|
||||
.impl.min_access_size = 4,
|
||||
.impl.max_access_size = 4,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
/* PCIe MMCFG */
|
||||
static void mch_update_pciexbar(MCHPCIState *mch)
|
||||
{
|
||||
|
|
@ -266,21 +288,70 @@ static void mch_update_pam(MCHPCIState *mch)
|
|||
static void mch_update_smram(MCHPCIState *mch)
|
||||
{
|
||||
PCIDevice *pd = PCI_DEVICE(mch);
|
||||
bool h_smrame = (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME);
|
||||
uint32_t tseg_size;
|
||||
|
||||
/* implement SMRAM.D_LCK */
|
||||
if (pd->config[MCH_HOST_BRIDGE_SMRAM] & MCH_HOST_BRIDGE_SMRAM_D_LCK) {
|
||||
pd->config[MCH_HOST_BRIDGE_SMRAM] &= ~MCH_HOST_BRIDGE_SMRAM_D_OPEN;
|
||||
pd->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK_LCK;
|
||||
pd->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK_LCK;
|
||||
}
|
||||
|
||||
memory_region_transaction_begin();
|
||||
smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM],
|
||||
mch->smm_enabled);
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
|
||||
static void mch_set_smm(int smm, void *arg)
|
||||
{
|
||||
MCHPCIState *mch = arg;
|
||||
PCIDevice *pd = PCI_DEVICE(mch);
|
||||
if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_D_OPEN) {
|
||||
/* Hide (!) low SMRAM if H_SMRAME = 1 */
|
||||
memory_region_set_enabled(&mch->smram_region, h_smrame);
|
||||
/* Show high SMRAM if H_SMRAME = 1 */
|
||||
memory_region_set_enabled(&mch->open_high_smram, h_smrame);
|
||||
} else {
|
||||
/* Hide high SMRAM and low SMRAM */
|
||||
memory_region_set_enabled(&mch->smram_region, true);
|
||||
memory_region_set_enabled(&mch->open_high_smram, false);
|
||||
}
|
||||
|
||||
if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME) {
|
||||
memory_region_set_enabled(&mch->low_smram, !h_smrame);
|
||||
memory_region_set_enabled(&mch->high_smram, h_smrame);
|
||||
} else {
|
||||
memory_region_set_enabled(&mch->low_smram, false);
|
||||
memory_region_set_enabled(&mch->high_smram, false);
|
||||
}
|
||||
|
||||
if (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_T_EN) {
|
||||
switch (pd->config[MCH_HOST_BRIDGE_ESMRAMC] &
|
||||
MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK) {
|
||||
case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB:
|
||||
tseg_size = 1024 * 1024;
|
||||
break;
|
||||
case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB:
|
||||
tseg_size = 1024 * 1024 * 2;
|
||||
break;
|
||||
case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB:
|
||||
tseg_size = 1024 * 1024 * 8;
|
||||
break;
|
||||
default:
|
||||
tseg_size = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
tseg_size = 0;
|
||||
}
|
||||
memory_region_del_subregion(mch->system_memory, &mch->tseg_blackhole);
|
||||
memory_region_set_enabled(&mch->tseg_blackhole, tseg_size);
|
||||
memory_region_set_size(&mch->tseg_blackhole, tseg_size);
|
||||
memory_region_add_subregion_overlap(mch->system_memory,
|
||||
mch->below_4g_mem_size - tseg_size,
|
||||
&mch->tseg_blackhole, 1);
|
||||
|
||||
memory_region_set_enabled(&mch->tseg_window, tseg_size);
|
||||
memory_region_set_size(&mch->tseg_window, tseg_size);
|
||||
memory_region_set_address(&mch->tseg_window,
|
||||
mch->below_4g_mem_size - tseg_size);
|
||||
memory_region_set_alias_offset(&mch->tseg_window,
|
||||
mch->below_4g_mem_size - tseg_size);
|
||||
|
||||
memory_region_transaction_begin();
|
||||
smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRIDGE_SMRAM],
|
||||
&mch->smram_region);
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
|
||||
|
|
@ -289,7 +360,6 @@ static void mch_write_config(PCIDevice *d,
|
|||
{
|
||||
MCHPCIState *mch = MCH_PCI_DEVICE(d);
|
||||
|
||||
/* XXX: implement SMRAM.D_LOCK */
|
||||
pci_default_write_config(d, address, val, len);
|
||||
|
||||
if (ranges_overlap(address, len, MCH_HOST_BRIDGE_PAM0,
|
||||
|
|
@ -329,7 +399,10 @@ static const VMStateDescription vmstate_mch = {
|
|||
.post_load = mch_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(parent_obj, MCHPCIState),
|
||||
VMSTATE_UINT8(smm_enabled, MCHPCIState),
|
||||
/* Used to be smm_enabled, which was basically always zero because
|
||||
* SeaBIOS hardly uses SMM. SMRAM is now handled by CPU code.
|
||||
*/
|
||||
VMSTATE_UNUSED(1),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
|
@ -343,6 +416,9 @@ static void mch_reset(DeviceState *qdev)
|
|||
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
|
||||
|
||||
d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
|
||||
d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT;
|
||||
d->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK;
|
||||
d->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK;
|
||||
|
||||
mch_update(mch);
|
||||
}
|
||||
|
|
@ -399,13 +475,47 @@ static void mch_realize(PCIDevice *d, Error **errp)
|
|||
pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
|
||||
mch->pci_address_space);
|
||||
|
||||
/* smram */
|
||||
cpu_smm_register(&mch_set_smm, mch);
|
||||
/* if *disabled* show SMRAM to all CPUs */
|
||||
memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
|
||||
mch->pci_address_space, 0xa0000, 0x20000);
|
||||
memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
|
||||
&mch->smram_region, 1);
|
||||
memory_region_set_enabled(&mch->smram_region, false);
|
||||
memory_region_set_enabled(&mch->smram_region, true);
|
||||
|
||||
memory_region_init_alias(&mch->open_high_smram, OBJECT(mch), "smram-open-high",
|
||||
mch->ram_memory, 0xa0000, 0x20000);
|
||||
memory_region_add_subregion_overlap(mch->system_memory, 0xfeda0000,
|
||||
&mch->open_high_smram, 1);
|
||||
memory_region_set_enabled(&mch->open_high_smram, false);
|
||||
|
||||
/* smram, as seen by SMM CPUs */
|
||||
memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
|
||||
memory_region_set_enabled(&mch->smram, true);
|
||||
memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
|
||||
mch->ram_memory, 0xa0000, 0x20000);
|
||||
memory_region_set_enabled(&mch->low_smram, true);
|
||||
memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
|
||||
memory_region_init_alias(&mch->high_smram, OBJECT(mch), "smram-high",
|
||||
mch->ram_memory, 0xa0000, 0x20000);
|
||||
memory_region_set_enabled(&mch->high_smram, true);
|
||||
memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram);
|
||||
|
||||
memory_region_init_io(&mch->tseg_blackhole, OBJECT(mch),
|
||||
&tseg_blackhole_ops, NULL,
|
||||
"tseg-blackhole", 0);
|
||||
memory_region_set_enabled(&mch->tseg_blackhole, false);
|
||||
memory_region_add_subregion_overlap(mch->system_memory,
|
||||
mch->below_4g_mem_size,
|
||||
&mch->tseg_blackhole, 1);
|
||||
|
||||
memory_region_init_alias(&mch->tseg_window, OBJECT(mch), "tseg-window",
|
||||
mch->ram_memory, mch->below_4g_mem_size, 0);
|
||||
memory_region_set_enabled(&mch->tseg_window, false);
|
||||
memory_region_add_subregion(&mch->smram, mch->below_4g_mem_size,
|
||||
&mch->tseg_window);
|
||||
object_property_add_const_link(qdev_get_machine(), "smram",
|
||||
OBJECT(&mch->smram), &error_abort);
|
||||
|
||||
init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
|
||||
mch->pci_address_space, &mch->pam_regions[0],
|
||||
PAM_BIOS_BASE, PAM_BIOS_SIZE);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ static void *vring_map(MemoryRegion **mr, hwaddr phys, hwaddr len,
|
|||
}
|
||||
|
||||
/* Ignore regions with dirty logging, we cannot mark them dirty */
|
||||
if (memory_region_is_logging(section.mr)) {
|
||||
if (memory_region_get_dirty_log_mask(section.mr)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -416,7 +416,8 @@ static void vhost_set_memory(MemoryListener *listener,
|
|||
memory_listener);
|
||||
hwaddr start_addr = section->offset_within_address_space;
|
||||
ram_addr_t size = int128_get64(section->size);
|
||||
bool log_dirty = memory_region_is_logging(section->mr);
|
||||
bool log_dirty =
|
||||
memory_region_get_dirty_log_mask(section->mr) & ~(1 << DIRTY_MEMORY_MIGRATION);
|
||||
int s = offsetof(struct vhost_memory, regions) +
|
||||
(dev->mem->nregions + 1) * sizeof dev->mem->regions[0];
|
||||
void *ram;
|
||||
|
|
@ -675,13 +676,15 @@ static void vhost_log_global_stop(MemoryListener *listener)
|
|||
}
|
||||
|
||||
static void vhost_log_start(MemoryListener *listener,
|
||||
MemoryRegionSection *section)
|
||||
MemoryRegionSection *section,
|
||||
int old, int new)
|
||||
{
|
||||
/* FIXME: implement */
|
||||
}
|
||||
|
||||
static void vhost_log_stop(MemoryListener *listener,
|
||||
MemoryRegionSection *section)
|
||||
MemoryRegionSection *section,
|
||||
int old, int new)
|
||||
{
|
||||
/* FIXME: implement */
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue