455 changes: 449 additions & 6 deletions hw/audio/via-ac97.c

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions hw/block/block.c
Expand Up @@ -39,8 +39,7 @@ static int blk_pread_nonzeroes(BlockBackend *blk, hwaddr size, void *buf)
return ret;
}
if (!(ret & BDRV_BLOCK_ZERO)) {
ret = bdrv_pread(bs->file, offset, bytes,
(uint8_t *) buf + offset, 0);
ret = blk_pread(blk, offset, bytes, (uint8_t *) buf + offset, 0);
if (ret < 0) {
return ret;
}
Expand Down
4 changes: 2 additions & 2 deletions hw/block/m25p80.c
Expand Up @@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "sysemu/block-backend.h"
#include "hw/block/block.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/ssi/ssi.h"
Expand Down Expand Up @@ -1615,8 +1616,7 @@ static void m25p80_realize(SSIPeripheral *ss, Error **errp)
trace_m25p80_binding(s);
s->storage = blk_blockalign(s->blk, s->size);

if (blk_pread(s->blk, 0, s->size, s->storage, 0) < 0) {
error_setg(errp, "failed to read the initial flash content");
if (!blk_check_size_and_read_all(s->blk, s->storage, s->size, errp)) {
return;
}
} else {
Expand Down
18 changes: 15 additions & 3 deletions hw/display/sm501.c
Expand Up @@ -465,6 +465,7 @@ typedef struct SM501State {
uint32_t last_width;
uint32_t last_height;
bool do_full_update; /* perform a full update next time */
uint8_t use_pixman;
I2CBus *i2c_bus;

/* mmio registers */
Expand Down Expand Up @@ -827,7 +828,7 @@ static void sm501_2d_operation(SM501State *s)
de = db + (width + (height - 1) * dst_pitch) * bypp;
overlap = (db < se && sb < de);
}
if (overlap) {
if (overlap && (s->use_pixman & BIT(2))) {
/* pixman can't do reverse blit: copy via temporary */
int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t));
uint32_t *tmp = tmp_buf;
Expand All @@ -852,13 +853,15 @@ static void sm501_2d_operation(SM501State *s)
if (tmp != tmp_buf) {
g_free(tmp);
}
} else {
} else if (!overlap && (s->use_pixman & BIT(1))) {
fallback = !pixman_blt((uint32_t *)&s->local_mem[src_base],
(uint32_t *)&s->local_mem[dst_base],
src_pitch * bypp / sizeof(uint32_t),
dst_pitch * bypp / sizeof(uint32_t),
8 * bypp, 8 * bypp, src_x, src_y,
dst_x, dst_y, width, height);
} else {
fallback = true;
}
if (fallback) {
uint8_t *sp = s->local_mem + src_base;
Expand Down Expand Up @@ -891,7 +894,7 @@ static void sm501_2d_operation(SM501State *s)
color = cpu_to_le16(color);
}

if ((width == 1 && height == 1) ||
if (!(s->use_pixman & BIT(0)) || (width == 1 && height == 1) ||
!pixman_fill((uint32_t *)&s->local_mem[dst_base],
dst_pitch * bypp / sizeof(uint32_t), 8 * bypp,
dst_x, dst_y, width, height, color)) {
Expand Down Expand Up @@ -2035,6 +2038,7 @@ static void sm501_realize_sysbus(DeviceState *dev, Error **errp)

static Property sm501_sysbus_properties[] = {
DEFINE_PROP_UINT32("vram-size", SM501SysBusState, vram_size, 0),
DEFINE_PROP_UINT8("x-pixman", SM501SysBusState, state.use_pixman, 7),
DEFINE_PROP_END_OF_LIST(),
};

Expand Down Expand Up @@ -2122,6 +2126,7 @@ static void sm501_realize_pci(PCIDevice *dev, Error **errp)

static Property sm501_pci_properties[] = {
DEFINE_PROP_UINT32("vram-size", SM501PCIState, vram_size, 64 * MiB),
DEFINE_PROP_UINT8("x-pixman", SM501PCIState, state.use_pixman, 7),
DEFINE_PROP_END_OF_LIST(),
};

Expand Down Expand Up @@ -2162,11 +2167,18 @@ static void sm501_pci_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_sm501_pci;
}

static void sm501_pci_init(Object *o)
{
object_property_set_description(o, "x-pixman", "Use pixman for: "
"1: fill, 2: blit, 4: overlap blit");
}

static const TypeInfo sm501_pci_info = {
.name = TYPE_PCI_SM501,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(SM501PCIState),
.class_init = sm501_pci_class_init,
.instance_init = sm501_pci_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
Expand Down
10 changes: 4 additions & 6 deletions hw/intc/i8259.c
Expand Up @@ -133,7 +133,7 @@ static void pic_set_irq(void *opaque, int irq, int level)
}
#endif

if (s->elcr & mask) {
if (s->ltim || (s->elcr & mask)) {
/* level triggered */
if (level) {
s->irr |= mask;
Expand Down Expand Up @@ -167,7 +167,7 @@ static void pic_intack(PICCommonState *s, int irq)
s->isr |= (1 << irq);
}
/* We don't clear a level sensitive interrupt here */
if (!(s->elcr & (1 << irq))) {
if (!s->ltim && !(s->elcr & (1 << irq))) {
s->irr &= ~(1 << irq);
}
pic_update_irq(s);
Expand Down Expand Up @@ -224,6 +224,7 @@ static void pic_reset(DeviceState *dev)
PICCommonState *s = PIC_COMMON(dev);

s->elcr = 0;
s->ltim = 0;
pic_init_reset(s);
}

Expand All @@ -243,10 +244,7 @@ static void pic_ioport_write(void *opaque, hwaddr addr64,
s->init_state = 1;
s->init4 = val & 1;
s->single_mode = val & 2;
if (val & 0x08) {
qemu_log_mask(LOG_UNIMP,
"i8259: level sensitive irq not supported\n");
}
s->ltim = val & 8;
} else if (val & 0x08) {
if (val & 0x04) {
s->poll = 1;
Expand Down
24 changes: 23 additions & 1 deletion hw/intc/i8259_common.c
Expand Up @@ -51,7 +51,7 @@ void pic_reset_common(PICCommonState *s)
s->special_fully_nested_mode = 0;
s->init4 = 0;
s->single_mode = 0;
/* Note: ELCR is not reset */
/* Note: ELCR and LTIM are not reset */
}

static int pic_dispatch_pre_save(void *opaque)
Expand Down Expand Up @@ -144,6 +144,24 @@ static void pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
s->special_fully_nested_mode);
}

static bool ltim_state_needed(void *opaque)
{
PICCommonState *s = PIC_COMMON(opaque);

return !!s->ltim;
}

static const VMStateDescription vmstate_pic_ltim = {
.name = "i8259/ltim",
.version_id = 1,
.minimum_version_id = 1,
.needed = ltim_state_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT8(ltim, PICCommonState),
VMSTATE_END_OF_LIST()
}
};

static const VMStateDescription vmstate_pic_common = {
.name = "i8259",
.version_id = 1,
Expand All @@ -168,6 +186,10 @@ static const VMStateDescription vmstate_pic_common = {
VMSTATE_UINT8(single_mode, PICCommonState),
VMSTATE_UINT8(elcr, PICCommonState),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {
&vmstate_pic_ltim,
NULL
}
};

Expand Down
4 changes: 2 additions & 2 deletions hw/intc/mips_gic.c
Expand Up @@ -439,8 +439,8 @@ static void mips_gic_realize(DeviceState *dev, Error **errp)
}

static Property mips_gic_properties[] = {
DEFINE_PROP_INT32("num-vp", MIPSGICState, num_vps, 1),
DEFINE_PROP_INT32("num-irq", MIPSGICState, num_irq, 256),
DEFINE_PROP_UINT32("num-vp", MIPSGICState, num_vps, 1),
DEFINE_PROP_UINT32("num-irq", MIPSGICState, num_irq, 256),
DEFINE_PROP_END_OF_LIST(),
};

Expand Down
10 changes: 9 additions & 1 deletion hw/isa/i82378.c
Expand Up @@ -47,6 +47,12 @@ static const VMStateDescription vmstate_i82378 = {
},
};

static void i82378_request_out0_irq(void *opaque, int irq, int level)
{
I82378State *s = opaque;
qemu_set_irq(s->cpu_intr, level);
}

static void i82378_request_pic_irq(void *opaque, int irq, int level)
{
DeviceState *dev = opaque;
Expand Down Expand Up @@ -88,7 +94,9 @@ static void i82378_realize(PCIDevice *pci, Error **errp)
*/

/* 2 82C59 (irq) */
s->isa_irqs_in = i8259_init(isabus, s->cpu_intr);
s->isa_irqs_in = i8259_init(isabus,
qemu_allocate_irq(i82378_request_out0_irq,
s, 0));
isa_bus_register_input_irqs(isabus, s->isa_irqs_in);

/* 1 82C54 (pit) */
Expand Down
1 change: 1 addition & 0 deletions hw/isa/trace-events
Expand Up @@ -16,6 +16,7 @@ apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x"

# vt82c686.c
via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
via_pm_read(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
via_pm_io_read(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
via_pm_io_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
Expand Down
54 changes: 52 additions & 2 deletions hw/isa/vt82c686.c
Expand Up @@ -554,7 +554,7 @@ struct ViaISAState {
PCIIDEState ide;
UHCIState uhci[2];
ViaPMState pm;
PCIDevice ac97;
ViaAC97State ac97;
PCIDevice mc97;
};

Expand Down Expand Up @@ -598,27 +598,77 @@ void via_isa_set_irq(PCIDevice *d, int n, int level)
qemu_set_irq(s->isa_irqs_in[n], level);
}

static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
{
ViaISAState *s = opaque;
qemu_set_irq(s->cpu_intr, level);
}

static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
{
switch (irq_num) {
case 0:
return s->dev.config[0x55] >> 4;
case 1:
return s->dev.config[0x56] & 0xf;
case 2:
return s->dev.config[0x56] >> 4;
case 3:
return s->dev.config[0x57] >> 4;
}
return 0;
}

static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
{
ViaISAState *s = opaque;
PCIBus *bus = pci_get_bus(&s->dev);
int i, pic_level, pic_irq = via_isa_get_pci_irq(s, irq_num);

/* IRQ 0: disabled, IRQ 2,8,13: reserved */
if (!pic_irq) {
return;
}
if (unlikely(pic_irq == 2 || pic_irq == 8 || pic_irq == 13)) {
qemu_log_mask(LOG_GUEST_ERROR, "Invalid ISA IRQ routing");
}

/* The pic level is the logical OR of all the PCI irqs mapped to it. */
pic_level = 0;
for (i = 0; i < PCI_NUM_PINS; i++) {
if (pic_irq == via_isa_get_pci_irq(s, i)) {
pic_level |= pci_bus_get_irq_level(bus, i);
}
}
/* Now we change the pic irq level according to the via irq mappings. */
qemu_set_irq(s->isa_irqs_in[pic_irq], pic_level);
}

static void via_isa_realize(PCIDevice *d, Error **errp)
{
ViaISAState *s = VIA_ISA(d);
DeviceState *dev = DEVICE(d);
PCIBus *pci_bus = pci_get_bus(d);
qemu_irq *isa_irq;
ISABus *isa_bus;
int i;

qdev_init_gpio_out(dev, &s->cpu_intr, 1);
isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
errp);

if (!isa_bus) {
return;
}

s->isa_irqs_in = i8259_init(isa_bus, s->cpu_intr);
s->isa_irqs_in = i8259_init(isa_bus, *isa_irq);
isa_bus_register_input_irqs(isa_bus, s->isa_irqs_in);
i8254_pit_init(isa_bus, 0x40, 0, NULL);
i8257_dma_init(isa_bus, 0);

qdev_init_gpio_in_named(dev, via_isa_set_pci_irq, "pirq", PCI_NUM_PINS);

/* RTC */
qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000);
if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) {
Expand Down
2 changes: 1 addition & 1 deletion hw/mips/boston.c
Expand Up @@ -702,7 +702,7 @@ static void boston_mach_init(MachineState *machine)
object_initialize_child(OBJECT(machine), "cps", &s->cps, TYPE_MIPS_CPS);
object_property_set_str(OBJECT(&s->cps), "cpu-type", machine->cpu_type,
&error_fatal);
object_property_set_int(OBJECT(&s->cps), "num-vp", machine->smp.cpus,
object_property_set_uint(OBJECT(&s->cps), "num-vp", machine->smp.cpus,
&error_fatal);
qdev_connect_clock_in(DEVICE(&s->cps), "clk-in",
qdev_get_clock_out(dev, "cpu-refclk"));
Expand Down
35 changes: 12 additions & 23 deletions hw/mips/cps.c
Expand Up @@ -66,20 +66,17 @@ static bool cpu_mips_itu_supported(CPUMIPSState *env)
static void mips_cps_realize(DeviceState *dev, Error **errp)
{
MIPSCPSState *s = MIPS_CPS(dev);
CPUMIPSState *env;
MIPSCPU *cpu;
int i;
target_ulong gcr_base;
bool itu_present = false;
bool saar_present = false;

if (!clock_get(s->clock)) {
error_setg(errp, "CPS input clock is not connected to an output clock");
return;
}

for (i = 0; i < s->num_vp; i++) {
cpu = MIPS_CPU(object_new(s->cpu_type));
for (int i = 0; i < s->num_vp; i++) {
MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
CPUMIPSState *env = &cpu->env;

/* All VPs are halted on reset. Leave powering up to CPC. */
if (!object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
Expand All @@ -97,7 +94,6 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
cpu_mips_irq_init_cpu(cpu);
cpu_mips_clock_init(cpu);

env = &cpu->env;
if (cpu_mips_itu_supported(env)) {
itu_present = true;
/* Attach ITC Tag to the VP */
Expand All @@ -107,22 +103,15 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
qemu_register_reset(main_cpu_reset, cpu);
}

cpu = MIPS_CPU(first_cpu);
env = &cpu->env;
saar_present = (bool)env->saarp;

/* Inter-Thread Communication Unit */
if (itu_present) {
object_initialize_child(OBJECT(dev), "itu", &s->itu, TYPE_MIPS_ITU);
object_property_set_int(OBJECT(&s->itu), "num-fifo", 16,
object_property_set_link(OBJECT(&s->itu), "cpu[0]",
OBJECT(first_cpu), &error_abort);
object_property_set_uint(OBJECT(&s->itu), "num-fifo", 16,
&error_abort);
object_property_set_int(OBJECT(&s->itu), "num-semaphores", 16,
object_property_set_uint(OBJECT(&s->itu), "num-semaphores", 16,
&error_abort);
object_property_set_bool(OBJECT(&s->itu), "saar-present", saar_present,
&error_abort);
if (saar_present) {
s->itu.saar = &env->CP0_SAAR;
}
if (!sysbus_realize(SYS_BUS_DEVICE(&s->itu), errp)) {
return;
}
Expand All @@ -133,7 +122,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)

/* Cluster Power Controller */
object_initialize_child(OBJECT(dev), "cpc", &s->cpc, TYPE_MIPS_CPC);
object_property_set_int(OBJECT(&s->cpc), "num-vp", s->num_vp,
object_property_set_uint(OBJECT(&s->cpc), "num-vp", s->num_vp,
&error_abort);
object_property_set_int(OBJECT(&s->cpc), "vp-start-running", 1,
&error_abort);
Expand All @@ -146,9 +135,9 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)

/* Global Interrupt Controller */
object_initialize_child(OBJECT(dev), "gic", &s->gic, TYPE_MIPS_GIC);
object_property_set_int(OBJECT(&s->gic), "num-vp", s->num_vp,
object_property_set_uint(OBJECT(&s->gic), "num-vp", s->num_vp,
&error_abort);
object_property_set_int(OBJECT(&s->gic), "num-irq", 128,
object_property_set_uint(OBJECT(&s->gic), "num-irq", 128,
&error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gic), errp)) {
return;
Expand All @@ -158,10 +147,10 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0));

/* Global Configuration Registers */
gcr_base = env->CP0_CMGCRBase << 4;
gcr_base = MIPS_CPU(first_cpu)->env.CP0_CMGCRBase << 4;

object_initialize_child(OBJECT(dev), "gcr", &s->gcr, TYPE_MIPS_GCR);
object_property_set_int(OBJECT(&s->gcr), "num-vp", s->num_vp,
object_property_set_uint(OBJECT(&s->gcr), "num-vp", s->num_vp,
&error_abort);
object_property_set_int(OBJECT(&s->gcr), "gcr-rev", 0x800,
&error_abort);
Expand Down
2 changes: 1 addition & 1 deletion hw/mips/malta.c
Expand Up @@ -1066,7 +1066,7 @@ static void create_cps(MachineState *ms, MaltaState *s,
object_initialize_child(OBJECT(s), "cps", &s->cps, TYPE_MIPS_CPS);
object_property_set_str(OBJECT(&s->cps), "cpu-type", ms->cpu_type,
&error_fatal);
object_property_set_int(OBJECT(&s->cps), "num-vp", ms->smp.cpus,
object_property_set_uint(OBJECT(&s->cps), "num-vp", ms->smp.cpus,
&error_fatal);
qdev_connect_clock_in(DEVICE(&s->cps), "clk-in", s->cpuclk);
sysbus_realize(SYS_BUS_DEVICE(&s->cps), &error_fatal);
Expand Down
2 changes: 1 addition & 1 deletion hw/misc/mips_cmgcr.c
Expand Up @@ -212,7 +212,7 @@ static const VMStateDescription vmstate_mips_gcr = {
};

static Property mips_gcr_properties[] = {
DEFINE_PROP_INT32("num-vp", MIPSGCRState, num_vps, 1),
DEFINE_PROP_UINT32("num-vp", MIPSGCRState, num_vps, 1),
DEFINE_PROP_INT32("gcr-rev", MIPSGCRState, gcr_rev, 0x800),
DEFINE_PROP_UINT64("gcr-base", MIPSGCRState, gcr_base, GCR_BASE_ADDR),
DEFINE_PROP_LINK("gic", MIPSGCRState, gic_mr, TYPE_MEMORY_REGION,
Expand Down
30 changes: 20 additions & 10 deletions hw/misc/mips_itu.c
Expand Up @@ -93,10 +93,10 @@ void itc_reconfigure(MIPSITUState *tag)
uint64_t size = (1 * KiB) + (am[1] & ITC_AM1_ADDR_MASK_MASK);
bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0;

if (tag->saar_present) {
address = ((*(uint64_t *) tag->saar) & 0xFFFFFFFFE000ULL) << 4;
size = 1ULL << ((*(uint64_t *) tag->saar >> 1) & 0x1f);
is_enabled = *(uint64_t *) tag->saar & 1;
if (tag->saar) {
address = (tag->saar[0] & 0xFFFFFFFFE000ULL) << 4;
size = 1ULL << ((tag->saar[0] >> 1) & 0x1f);
is_enabled = tag->saar[0] & 1;
}

memory_region_transaction_begin();
Expand Down Expand Up @@ -157,7 +157,7 @@ static inline ITCView get_itc_view(hwaddr addr)
static inline int get_cell_stride_shift(const MIPSITUState *s)
{
/* Minimum interval (for EntryGain = 0) is 128 B */
if (s->saar_present) {
if (s->saar) {
return 7 + ((s->icr0 >> ITC_ICR0_BLK_GRAIN) &
ITC_ICR0_BLK_GRAIN_MASK);
} else {
Expand Down Expand Up @@ -515,6 +515,7 @@ static void mips_itu_init(Object *obj)
static void mips_itu_realize(DeviceState *dev, Error **errp)
{
MIPSITUState *s = MIPS_ITU(dev);
CPUMIPSState *env;

if (s->num_fifo > ITC_FIFO_NUM_MAX) {
error_setg(errp, "Exceed maximum number of FIFO cells: %d",
Expand All @@ -526,6 +527,15 @@ static void mips_itu_realize(DeviceState *dev, Error **errp)
s->num_semaphores);
return;
}
if (!s->cpu0) {
error_setg(errp, "Missing 'cpu[0]' property");
return;
}

env = &s->cpu0->env;
if (env->saarp) {
s->saar = env->CP0_SAAR;
}

s->cell = g_new(ITCStorageCell, get_num_cells(s));
}
Expand All @@ -534,8 +544,8 @@ static void mips_itu_reset(DeviceState *dev)
{
MIPSITUState *s = MIPS_ITU(dev);

if (s->saar_present) {
*(uint64_t *) s->saar = 0x11 << 1;
if (s->saar) {
s->saar[0] = 0x11 << 1;
s->icr0 = get_num_cells(s) << ITC_ICR0_CELL_NUM;
} else {
s->ITCAddressMap[0] = 0;
Expand All @@ -549,11 +559,11 @@ static void mips_itu_reset(DeviceState *dev)
}

static Property mips_itu_properties[] = {
DEFINE_PROP_INT32("num-fifo", MIPSITUState, num_fifo,
DEFINE_PROP_UINT32("num-fifo", MIPSITUState, num_fifo,
ITC_FIFO_NUM_MAX),
DEFINE_PROP_INT32("num-semaphores", MIPSITUState, num_semaphores,
DEFINE_PROP_UINT32("num-semaphores", MIPSITUState, num_semaphores,
ITC_SEMAPH_NUM_MAX),
DEFINE_PROP_BOOL("saar-present", MIPSITUState, saar_present, false),
DEFINE_PROP_LINK("cpu[0]", MIPSITUState, cpu0, TYPE_MIPS_CPU, MIPSCPU *),
DEFINE_PROP_END_OF_LIST(),
};

Expand Down
4 changes: 0 additions & 4 deletions hw/pci-host/mv64361.c
Expand Up @@ -873,10 +873,6 @@ static void mv64361_realize(DeviceState *dev, Error **errp)
}
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
/* FIXME: PCI IRQ connections may be board specific */
for (i = 0; i < PCI_NUM_PINS; i++) {
s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
}
}

static void mv64361_reset(DeviceState *dev)
Expand Down
26 changes: 25 additions & 1 deletion hw/ppc/pegasos2.c
Expand Up @@ -73,6 +73,8 @@ struct Pegasos2MachineState {
MachineState parent_obj;
PowerPCCPU *cpu;
DeviceState *mv;
qemu_irq mv_pirq[PCI_NUM_PINS];
qemu_irq via_pirq[PCI_NUM_PINS];
Vof *vof;
void *fdt_blob;
uint64_t kernel_addr;
Expand All @@ -95,6 +97,15 @@ static void pegasos2_cpu_reset(void *opaque)
}
}

static void pegasos2_pci_irq(void *opaque, int n, int level)
{
Pegasos2MachineState *pm = opaque;

/* PCI interrupt lines are connected to both MV64361 and VT8231 */
qemu_set_irq(pm->mv_pirq[n], level);
qemu_set_irq(pm->via_pirq[n], level);
}

static void pegasos2_init(MachineState *machine)
{
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
Expand All @@ -106,7 +117,7 @@ static void pegasos2_init(MachineState *machine)
I2CBus *i2c_bus;
const char *fwname = machine->firmware ?: PROM_FILENAME;
char *filename;
int sz;
int i, sz;
uint8_t *spd_data;

/* init CPU */
Expand Down Expand Up @@ -156,11 +167,18 @@ static void pegasos2_init(MachineState *machine)
/* Marvell Discovery II system controller */
pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
for (i = 0; i < PCI_NUM_PINS; i++) {
pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
}
pci_bus = mv64361_get_pci_bus(pm->mv, 1);
pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);

/* VIA VT8231 South Bridge (multifunction PCI device) */
via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
true, TYPE_VT8231_ISA));
for (i = 0; i < PCI_NUM_PINS; i++) {
pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
}
object_property_add_alias(OBJECT(machine), "rtc-time",
object_resolve_path_component(via, "rtc"),
"date");
Expand Down Expand Up @@ -267,6 +285,12 @@ static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
PCI_INTERRUPT_LINE, 2, 0x9);
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
0x50, 1, 0x2);
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
0x55, 1, 0x90);
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
0x56, 1, 0x99);
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
0x57, 1, 0x90);

pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |
PCI_INTERRUPT_LINE, 2, 0x109);
Expand Down
23 changes: 17 additions & 6 deletions hw/usb/hcd-ohci.c
Expand Up @@ -1410,6 +1410,18 @@ static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
}
}

/* This is the one state transition the controller can do by itself */
static bool ohci_resume(OHCIState *s)
{
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
trace_usb_ohci_remote_wakeup(s->name);
s->ctl &= ~OHCI_CTL_HCFS;
s->ctl |= OHCI_USB_RESUME;
return true;
}
return false;
}

/*
* Sets a flag in a port status reg but only set it if the port is connected.
* If not set ConnectStatusChange flag. If flag is enabled return 1.
Expand All @@ -1426,7 +1438,10 @@ static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val)
if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
if (ohci->rhstatus & OHCI_RHS_DRWE) {
/* TODO: CSC is a wakeup event */
/* CSC is a wakeup event */
if (ohci_resume(ohci)) {
ohci_set_interrupt(ohci, OHCI_INTR_RD);
}
}
return 0;
}
Expand Down Expand Up @@ -1828,11 +1843,7 @@ static void ohci_wakeup(USBPort *port1)
intr = OHCI_INTR_RHSC;
}
/* Note that the controller can be suspended even if this port is not */
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
trace_usb_ohci_remote_wakeup(s->name);
/* This is the one state transition the controller can do by itself */
s->ctl &= ~OHCI_CTL_HCFS;
s->ctl |= OHCI_USB_RESUME;
if (ohci_resume(s)) {
/*
* In suspend mode only ResumeDetected is possible, not RHSC:
* see the OHCI spec 5.1.2.3.
Expand Down
12 changes: 0 additions & 12 deletions hw/usb/vt82c686-uhci-pci.c
@@ -1,17 +1,7 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/isa/vt82c686.h"
#include "hcd-uhci.h"

static void uhci_isa_set_irq(void *opaque, int irq_num, int level)
{
UHCIState *s = opaque;
uint8_t irq = pci_get_byte(s->dev.config + PCI_INTERRUPT_LINE);
if (irq > 0 && irq < 15) {
via_isa_set_irq(pci_get_function_0(&s->dev), irq, level);
}
}

static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
{
UHCIState *s = UHCI(dev);
Expand All @@ -25,8 +15,6 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
pci_set_long(pci_conf + 0xc0, 0x00002000);

usb_uhci_common_realize(dev, errp);
object_unref(s->irq);
s->irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
}

static UHCIInfo uhci_info[] = {
Expand Down
4 changes: 2 additions & 2 deletions include/hw/intc/mips_gic.h
Expand Up @@ -211,8 +211,8 @@ struct MIPSGICState {
/* GIC VP Timer */
MIPSGICTimerState *gic_timer;

int32_t num_vps;
int32_t num_irq;
uint32_t num_vps;
uint32_t num_irq;
};

#endif /* MIPS_GIC_H */
1 change: 1 addition & 0 deletions include/hw/isa/i8259_internal.h
Expand Up @@ -61,6 +61,7 @@ struct PICCommonState {
uint8_t single_mode; /* true if slave pic is not initialized */
uint8_t elcr; /* PIIX edge/trigger selection*/
uint8_t elcr_mask;
uint8_t ltim; /* Edge/Level Bank Select (pre-PIIX, chip-wide) */
qemu_irq int_out[1];
uint32_t master; /* reflects /SP input pin */
uint32_t iobase;
Expand Down
25 changes: 25 additions & 0 deletions include/hw/isa/vt82c686.h
@@ -1,6 +1,8 @@
#ifndef HW_VT82C686_H
#define HW_VT82C686_H

#include "hw/pci/pci_device.h"
#include "audio/audio.h"

#define TYPE_VT82C686B_ISA "vt82c686b-isa"
#define TYPE_VT82C686B_USB_UHCI "vt82c686b-usb-uhci"
Expand All @@ -9,6 +11,29 @@
#define TYPE_VIA_IDE "via-ide"
#define TYPE_VIA_MC97 "via-mc97"

typedef struct {
uint8_t stat;
uint8_t type;
uint32_t base;
uint32_t curr;
uint32_t addr;
uint32_t clen;
} ViaAC97SGDChannel;

OBJECT_DECLARE_SIMPLE_TYPE(ViaAC97State, VIA_AC97);

struct ViaAC97State {
PCIDevice dev;
QEMUSoundCard card;
MemoryRegion sgd;
MemoryRegion fm;
MemoryRegion midi;
SWVoiceOut *vo;
ViaAC97SGDChannel aur;
uint16_t codec_regs[128];
uint32_t ac97_cmd;
};

void via_isa_set_irq(PCIDevice *d, int n, int level);

#endif
2 changes: 1 addition & 1 deletion include/hw/misc/mips_cmgcr.h
Expand Up @@ -75,7 +75,7 @@ struct MIPSGCRState {
SysBusDevice parent_obj;

int32_t gcr_rev;
int32_t num_vps;
uint32_t num_vps;
hwaddr gcr_base;
MemoryRegion iomem;
MemoryRegion *cpc_mr;
Expand Down
9 changes: 4 additions & 5 deletions include/hw/misc/mips_itu.h
Expand Up @@ -57,8 +57,8 @@ struct MIPSITUState {
SysBusDevice parent_obj;
/*< public >*/

int32_t num_fifo;
int32_t num_semaphores;
uint32_t num_fifo;
uint32_t num_semaphores;

/* ITC Storage */
ITCStorageCell *cell;
Expand All @@ -72,9 +72,8 @@ struct MIPSITUState {
uint64_t icr0;

/* SAAR */
bool saar_present;
void *saar;

uint64_t *saar;
MIPSCPU *cpu0;
};

/* Get ITC Configuration Tag memory region. */
Expand Down
14 changes: 10 additions & 4 deletions softmmu/physmem.c
Expand Up @@ -1126,15 +1126,21 @@ GString *ram_block_format(void)
GString *buf = g_string_new("");

RCU_READ_LOCK_GUARD();
g_string_append_printf(buf, "%24s %8s %18s %18s %18s\n",
"Block Name", "PSize", "Offset", "Used", "Total");
g_string_append_printf(buf, "%24s %8s %18s %18s %18s %18s %3s\n",
"Block Name", "PSize", "Offset", "Used", "Total",
"HVA", "RO");

RAMBLOCK_FOREACH(block) {
psize = size_to_str(block->page_size);
g_string_append_printf(buf, "%24s %8s 0x%016" PRIx64 " 0x%016" PRIx64
" 0x%016" PRIx64 "\n", block->idstr, psize,
" 0x%016" PRIx64 " 0x%016" PRIx64 " %3s\n",
block->idstr, psize,
(uint64_t)block->offset,
(uint64_t)block->used_length,
(uint64_t)block->max_length);
(uint64_t)block->max_length,
(uint64_t)(uintptr_t)block->host,
block->mr->readonly ? "ro" : "rw");

g_free(psize);
}

Expand Down
13 changes: 11 additions & 2 deletions target/mips/cpu-defs.c.inc
Expand Up @@ -332,7 +332,11 @@ const mips_def_t mips_defs[] =
(0x1 << CP0C0_AR) | (MMU_TYPE_FMT << CP0C0_MT),
.CP0_Config1 = MIPS_CONFIG1,
.CP0_Config2 = MIPS_CONFIG2,
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (1 << CP0C3_VInt),
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (1 << CP0C3_VInt) |
(1 << CP0C3_M),
.CP0_Config4 = MIPS_CONFIG4 | (1 << CP0C4_M),
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_NFExists),
.CP0_Config7 = 1 << CP0C7_WII,
.CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 4,
.SYNCI_Step = 32,
Expand All @@ -353,7 +357,11 @@ const mips_def_t mips_defs[] =
(0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
(0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
.CP0_Config2 = MIPS_CONFIG2,
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (0 << CP0C3_VInt),
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (0 << CP0C3_VInt) |
(1 << CP0C3_M),
.CP0_Config4 = MIPS_CONFIG4 | (1 << CP0C4_M),
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_NFExists),
.CP0_Config7 = 1 << CP0C7_WII,
.CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 4,
.SYNCI_Step = 32,
Expand Down Expand Up @@ -392,6 +400,7 @@ const mips_def_t mips_defs[] =
.CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) |
(1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) |
(1 << CP0C5_FRE) | (1 << CP0C5_UFR),
.CP0_Config7 = 1 << CP0C7_WII,
.CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 0,
.SYNCI_Step = 32,
Expand Down
4 changes: 3 additions & 1 deletion target/mips/cpu.c
Expand Up @@ -143,11 +143,13 @@ static bool mips_cpu_has_work(CPUState *cs)
/*
* Prior to MIPS Release 6 it is implementation dependent if non-enabled
* interrupts wake-up the CPU, however most of the implementations only
* check for interrupts that can be taken.
* check for interrupts that can be taken. For pre-release 6 CPUs,
* check for CP0 Config7 'Wait IE ignore' bit.
*/
if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
cpu_mips_hw_interrupts_pending(env)) {
if (cpu_mips_hw_interrupts_enabled(env) ||
(env->CP0_Config7 & (1 << CP0C7_WII)) ||
(env->insn_flags & ISA_MIPS_R6)) {
has_work = true;
}
Expand Down
1 change: 1 addition & 0 deletions target/mips/cpu.h
Expand Up @@ -980,6 +980,7 @@ typedef struct CPUArchState {
#define CP0C6_DATAPREF 0
int32_t CP0_Config7;
int64_t CP0_Config7_rw_bitmask;
#define CP0C7_WII 31
#define CP0C7_NAPCGEN 2
#define CP0C7_UNIMUEN 1
#define CP0C7_VFPUCGEN 0
Expand Down
3 changes: 1 addition & 2 deletions target/mips/sysemu/physaddr.c
Expand Up @@ -70,8 +70,7 @@ static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx)
/* is this AM mapped in current execution mode */
return ((adetlb_mask << am) < 0);
default:
assert(0);
return TLBRET_BADADDR;
g_assert_not_reached();
};
}

Expand Down
4 changes: 2 additions & 2 deletions target/mips/tcg/ldst_helper.c
Expand Up @@ -248,14 +248,14 @@ void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
target_ulong i;

for (i = 0; i < base_reglist; i++) {
cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]],
cpu_stl_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]],
mem_idx, GETPC());
addr += 4;
}
}

if (do_r31) {
cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
cpu_stl_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
}
}

Expand Down
104 changes: 52 additions & 52 deletions target/mips/tcg/msa_helper.c

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions target/mips/tcg/translate.c
Expand Up @@ -4887,6 +4887,14 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
break;
case OPC_J:
case OPC_JAL:
{
/* Jump to immediate */
int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000
: 0xF0000000;
btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask)
| (uint32_t)offset;
break;
}
case OPC_JALX:
/* Jump to immediate */
btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
Expand Down
11 changes: 8 additions & 3 deletions ui/cocoa.m
Expand Up @@ -1330,10 +1330,15 @@ - (BOOL)windowShouldClose:(id)sender
return NO;
}

/* Called when QEMU goes into the background */
- (void) applicationWillResignActive: (NSNotification *)aNotification
/*
* Called when QEMU goes into the background. Note that
* [-NSWindowDelegate windowDidResignKey:] is used here instead of
* [-NSApplicationDelegate applicationWillResignActive:] because it cannot
* detect that the window loses focus when the deck is clicked on macOS 13.2.1.
*/
- (void) windowDidResignKey: (NSNotification *)aNotification
{
COCOA_DEBUG("QemuCocoaAppController: applicationWillResignActive\n");
COCOA_DEBUG("%s\n", __func__);
[cocoaView ungrabMouse];
[cocoaView raiseAllKeys];
}
Expand Down
2 changes: 1 addition & 1 deletion util/log.c
Expand Up @@ -489,7 +489,7 @@ const QEMULogItem qemu_log_items[] = {
"do not chain compiled TBs so that \"exec\" and \"cpu\" show\n"
"complete traces" },
#ifdef CONFIG_PLUGIN
{ CPU_LOG_PLUGIN, "plugin", "output from TCG plugins\n"},
{ CPU_LOG_PLUGIN, "plugin", "output from TCG plugins"},
#endif
{ LOG_STRACE, "strace",
"log every user-mode syscall, its input, and its result" },
Expand Down