mirror of https://github.com/xemu-project/xemu.git
Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf
* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf: (22 commits) PPC: pseries: Remove hack for PIO window PPC: e500: Map PIO space into core memory region xen_platform: convert PIO to new memory api read/write vmport: convert PIO to new memory api read/write serial: convert PIO to new memory api read/write rtl8139: convert PIO to new memory api read/write pckbd: convert PIO to new memory api read/write pc port92: convert PIO to new memory api read/write mc146818rtc: convert PIO to new memory api read/write m48t59: convert PIO to new memory api read/write i8254: convert PIO to new memory api read/write es1370: convert PIO to new memory api read/write virtio-pci: convert PIO to new memory api read/write ac97: convert PIO to new memory api read/write pseries: Implement qemu initiated shutdowns using EPOW events target-ppc: Rework storage of VPA registration state pseries: Don't allow duplicate registration of hcalls or RTAS calls Add USB option in machine options e500: Fix serial initialization PPC: 440: Emulate DCBR0 ...
This commit is contained in:
commit
d262cb0286
109
hw/ac97.c
109
hw/ac97.c
|
@ -1226,32 +1226,101 @@ static const VMStateDescription vmstate_ac97 = {
|
|||
}
|
||||
};
|
||||
|
||||
static const MemoryRegionPortio nam_portio[] = {
|
||||
{ 0, 256 * 1, 1, .read = nam_readb, },
|
||||
{ 0, 256 * 2, 2, .read = nam_readw, },
|
||||
{ 0, 256 * 4, 4, .read = nam_readl, },
|
||||
{ 0, 256 * 1, 1, .write = nam_writeb, },
|
||||
{ 0, 256 * 2, 2, .write = nam_writew, },
|
||||
{ 0, 256 * 4, 4, .write = nam_writel, },
|
||||
PORTIO_END_OF_LIST (),
|
||||
};
|
||||
static uint64_t nam_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
if ((addr / size) > 256) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
return nam_readb(opaque, addr);
|
||||
case 2:
|
||||
return nam_readw(opaque, addr);
|
||||
case 4:
|
||||
return nam_readl(opaque, addr);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void nam_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
if ((addr / size) > 256) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
nam_writeb(opaque, addr, val);
|
||||
break;
|
||||
case 2:
|
||||
nam_writew(opaque, addr, val);
|
||||
break;
|
||||
case 4:
|
||||
nam_writel(opaque, addr, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps ac97_io_nam_ops = {
|
||||
.old_portio = nam_portio,
|
||||
.read = nam_read,
|
||||
.write = nam_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static const MemoryRegionPortio nabm_portio[] = {
|
||||
{ 0, 64 * 1, 1, .read = nabm_readb, },
|
||||
{ 0, 64 * 2, 2, .read = nabm_readw, },
|
||||
{ 0, 64 * 4, 4, .read = nabm_readl, },
|
||||
{ 0, 64 * 1, 1, .write = nabm_writeb, },
|
||||
{ 0, 64 * 2, 2, .write = nabm_writew, },
|
||||
{ 0, 64 * 4, 4, .write = nabm_writel, },
|
||||
PORTIO_END_OF_LIST ()
|
||||
};
|
||||
static uint64_t nabm_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
if ((addr / size) > 64) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
return nabm_readb(opaque, addr);
|
||||
case 2:
|
||||
return nabm_readw(opaque, addr);
|
||||
case 4:
|
||||
return nabm_readl(opaque, addr);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void nabm_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
if ((addr / size) > 64) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
nabm_writeb(opaque, addr, val);
|
||||
break;
|
||||
case 2:
|
||||
nabm_writew(opaque, addr, val);
|
||||
break;
|
||||
case 4:
|
||||
nabm_writel(opaque, addr, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const MemoryRegionOps ac97_io_nabm_ops = {
|
||||
.old_portio = nabm_portio,
|
||||
.read = nabm_read,
|
||||
.write = nabm_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void ac97_on_reset (void *opaque)
|
||||
|
|
46
hw/es1370.c
46
hw/es1370.c
|
@ -908,18 +908,44 @@ static void es1370_adc_callback (void *opaque, int avail)
|
|||
es1370_run_channel (s, ADC_CHANNEL, avail);
|
||||
}
|
||||
|
||||
static const MemoryRegionPortio es1370_portio[] = {
|
||||
{ 0, 0x40 * 4, 1, .write = es1370_writeb, },
|
||||
{ 0, 0x40 * 2, 2, .write = es1370_writew, },
|
||||
{ 0, 0x40, 4, .write = es1370_writel, },
|
||||
{ 0, 0x40 * 4, 1, .read = es1370_readb, },
|
||||
{ 0, 0x40 * 2, 2, .read = es1370_readw, },
|
||||
{ 0, 0x40, 4, .read = es1370_readl, },
|
||||
PORTIO_END_OF_LIST ()
|
||||
};
|
||||
static uint64_t es1370_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
return es1370_readb(opaque, addr);
|
||||
case 2:
|
||||
return es1370_readw(opaque, addr);
|
||||
case 4:
|
||||
return es1370_readl(opaque, addr);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void es1370_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
es1370_writeb(opaque, addr, val);
|
||||
break;
|
||||
case 2:
|
||||
es1370_writew(opaque, addr, val);
|
||||
break;
|
||||
case 4:
|
||||
es1370_writel(opaque, addr, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps es1370_io_ops = {
|
||||
.old_portio = es1370_portio,
|
||||
.read = es1370_read,
|
||||
.write = es1370_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
|
|
20
hw/i8254.c
20
hw/i8254.c
|
@ -111,7 +111,8 @@ static void pit_latch_count(PITChannelState *s)
|
|||
}
|
||||
}
|
||||
|
||||
static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void pit_ioport_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
PITCommonState *pit = opaque;
|
||||
int channel, access;
|
||||
|
@ -178,7 +179,8 @@ static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
|
||||
static uint64_t pit_ioport_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
PITCommonState *pit = opaque;
|
||||
int ret, count;
|
||||
|
@ -290,14 +292,14 @@ static void pit_irq_control(void *opaque, int n, int enable)
|
|||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionPortio pit_portio[] = {
|
||||
{ 0, 4, 1, .write = pit_ioport_write },
|
||||
{ 0, 3, 1, .read = pit_ioport_read },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
|
||||
static const MemoryRegionOps pit_ioport_ops = {
|
||||
.old_portio = pit_portio
|
||||
.read = pit_ioport_read,
|
||||
.write = pit_ioport_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void pit_post_load(PITCommonState *s)
|
||||
|
|
24
hw/m48t59.c
24
hw/m48t59.c
|
@ -27,6 +27,7 @@
|
|||
#include "sysemu.h"
|
||||
#include "sysbus.h"
|
||||
#include "isa.h"
|
||||
#include "exec-memory.h"
|
||||
|
||||
//#define DEBUG_NVRAM
|
||||
|
||||
|
@ -80,6 +81,7 @@ typedef struct M48t59ISAState {
|
|||
typedef struct M48t59SysBusState {
|
||||
SysBusDevice busdev;
|
||||
M48t59State state;
|
||||
MemoryRegion io;
|
||||
} M48t59SysBusState;
|
||||
|
||||
/* Fake timer functions */
|
||||
|
@ -481,7 +483,8 @@ void m48t59_toggle_lock (void *opaque, int lock)
|
|||
}
|
||||
|
||||
/* IO access to NVRAM */
|
||||
static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val)
|
||||
static void NVRAM_writeb(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
M48t59State *NVRAM = opaque;
|
||||
|
||||
|
@ -504,7 +507,7 @@ static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t NVRAM_readb (void *opaque, uint32_t addr)
|
||||
static uint64_t NVRAM_readb(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
M48t59State *NVRAM = opaque;
|
||||
uint32_t retval;
|
||||
|
@ -626,13 +629,14 @@ static void m48t59_reset_sysbus(DeviceState *d)
|
|||
m48t59_reset_common(NVRAM);
|
||||
}
|
||||
|
||||
static const MemoryRegionPortio m48t59_portio[] = {
|
||||
{0, 4, 1, .read = NVRAM_readb, .write = NVRAM_writeb },
|
||||
PORTIO_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static const MemoryRegionOps m48t59_io_ops = {
|
||||
.old_portio = m48t59_portio,
|
||||
.read = NVRAM_readb,
|
||||
.write = NVRAM_writeb,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
/* Initialisation routine */
|
||||
|
@ -653,9 +657,9 @@ M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
|
|||
d = FROM_SYSBUS(M48t59SysBusState, s);
|
||||
state = &d->state;
|
||||
sysbus_connect_irq(s, 0, IRQ);
|
||||
memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
|
||||
if (io_base != 0) {
|
||||
register_ioport_read(io_base, 0x04, 1, NVRAM_readb, state);
|
||||
register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, state);
|
||||
memory_region_add_subregion(get_system_io(), io_base, &d->io);
|
||||
}
|
||||
if (mem_base != 0) {
|
||||
sysbus_mmio_map(s, 0, mem_base);
|
||||
|
|
|
@ -383,7 +383,8 @@ static void rtc_update_timer(void *opaque)
|
|||
check_update_timer(s);
|
||||
}
|
||||
|
||||
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
|
||||
static void cmos_ioport_write(void *opaque, hwaddr addr,
|
||||
uint64_t data, unsigned size)
|
||||
{
|
||||
RTCState *s = opaque;
|
||||
|
||||
|
@ -595,7 +596,8 @@ static int update_in_progress(RTCState *s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
|
||||
static uint64_t cmos_ioport_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
RTCState *s = opaque;
|
||||
int ret;
|
||||
|
@ -769,13 +771,14 @@ static void rtc_reset(void *opaque)
|
|||
#endif
|
||||
}
|
||||
|
||||
static const MemoryRegionPortio cmos_portio[] = {
|
||||
{0, 2, 1, .read = cmos_ioport_read, .write = cmos_ioport_write },
|
||||
PORTIO_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static const MemoryRegionOps cmos_ops = {
|
||||
.old_portio = cmos_portio
|
||||
.read = cmos_ioport_read,
|
||||
.write = cmos_ioport_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
|
||||
|
|
|
@ -1334,8 +1334,9 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
|
|||
n8x0_dss_setup(s);
|
||||
n8x0_cbus_setup(s);
|
||||
n8x0_uart_setup(s);
|
||||
if (usb_enabled)
|
||||
if (usb_enabled(false)) {
|
||||
n8x0_usb_setup(s);
|
||||
}
|
||||
|
||||
if (kernel_filename) {
|
||||
/* Or at the linux loader. */
|
||||
|
|
19
hw/pc.c
19
hw/pc.c
|
@ -421,7 +421,8 @@ typedef struct Port92State {
|
|||
qemu_irq *a20_out;
|
||||
} Port92State;
|
||||
|
||||
static void port92_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void port92_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
Port92State *s = opaque;
|
||||
|
||||
|
@ -433,7 +434,8 @@ static void port92_write(void *opaque, uint32_t addr, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t port92_read(void *opaque, uint32_t addr)
|
||||
static uint64_t port92_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
Port92State *s = opaque;
|
||||
uint32_t ret;
|
||||
|
@ -468,13 +470,14 @@ static void port92_reset(DeviceState *d)
|
|||
s->outport &= ~1;
|
||||
}
|
||||
|
||||
static const MemoryRegionPortio port92_portio[] = {
|
||||
{ 0, 1, 1, .read = port92_read, .write = port92_write },
|
||||
PORTIO_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static const MemoryRegionOps port92_ops = {
|
||||
.old_portio = port92_portio
|
||||
.read = port92_read,
|
||||
.write = port92_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static int port92_initfn(ISADevice *dev)
|
||||
|
|
|
@ -267,7 +267,7 @@ static void pc_init1(MemoryRegion *system_memory,
|
|||
pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
|
||||
floppy, idebus[0], idebus[1], rtc_state);
|
||||
|
||||
if (pci_enabled && usb_enabled) {
|
||||
if (pci_enabled && usb_enabled(false)) {
|
||||
pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
|
||||
}
|
||||
|
||||
|
|
48
hw/pckbd.c
48
hw/pckbd.c
|
@ -194,7 +194,8 @@ static void kbd_update_aux_irq(void *opaque, int level)
|
|||
kbd_update_irq(s);
|
||||
}
|
||||
|
||||
static uint32_t kbd_read_status(void *opaque, uint32_t addr)
|
||||
static uint64_t kbd_read_status(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
KBDState *s = opaque;
|
||||
int val;
|
||||
|
@ -223,7 +224,8 @@ static void outport_write(KBDState *s, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void kbd_write_command(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
KBDState *s = opaque;
|
||||
|
||||
|
@ -303,12 +305,13 @@ static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
|
|||
/* ignore that */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", val);
|
||||
fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", (int)val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t kbd_read_data(void *opaque, uint32_t addr)
|
||||
static uint64_t kbd_read_data(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
KBDState *s = opaque;
|
||||
uint32_t val;
|
||||
|
@ -322,7 +325,8 @@ static uint32_t kbd_read_data(void *opaque, uint32_t addr)
|
|||
return val;
|
||||
}
|
||||
|
||||
static void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void kbd_write_data(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
KBDState *s = opaque;
|
||||
|
||||
|
@ -385,9 +389,9 @@ static uint32_t kbd_mm_readb (void *opaque, hwaddr addr)
|
|||
KBDState *s = opaque;
|
||||
|
||||
if (addr & s->mask)
|
||||
return kbd_read_status(s, 0) & 0xff;
|
||||
return kbd_read_status(s, 0, 1) & 0xff;
|
||||
else
|
||||
return kbd_read_data(s, 0) & 0xff;
|
||||
return kbd_read_data(s, 0, 1) & 0xff;
|
||||
}
|
||||
|
||||
static void kbd_mm_writeb (void *opaque, hwaddr addr, uint32_t value)
|
||||
|
@ -395,9 +399,9 @@ static void kbd_mm_writeb (void *opaque, hwaddr addr, uint32_t value)
|
|||
KBDState *s = opaque;
|
||||
|
||||
if (addr & s->mask)
|
||||
kbd_write_command(s, 0, value & 0xff);
|
||||
kbd_write_command(s, 0, value & 0xff, 1);
|
||||
else
|
||||
kbd_write_data(s, 0, value & 0xff);
|
||||
kbd_write_data(s, 0, value & 0xff, 1);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps i8042_mmio_ops = {
|
||||
|
@ -459,22 +463,24 @@ static const VMStateDescription vmstate_kbd_isa = {
|
|||
}
|
||||
};
|
||||
|
||||
static const MemoryRegionPortio i8042_data_portio[] = {
|
||||
{ 0, 1, 1, .read = kbd_read_data, .write = kbd_write_data },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
|
||||
static const MemoryRegionPortio i8042_cmd_portio[] = {
|
||||
{ 0, 1, 1, .read = kbd_read_status, .write = kbd_write_command },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
|
||||
static const MemoryRegionOps i8042_data_ops = {
|
||||
.old_portio = i8042_data_portio
|
||||
.read = kbd_read_data,
|
||||
.write = kbd_write_data,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static const MemoryRegionOps i8042_cmd_ops = {
|
||||
.old_portio = i8042_cmd_portio
|
||||
.read = kbd_read_status,
|
||||
.write = kbd_write_command,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static int i8042_initfn(ISADevice *dev)
|
||||
|
|
|
@ -11,6 +11,7 @@ obj-y += ppc_newworld.o
|
|||
obj-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
|
||||
obj-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o
|
||||
obj-$(CONFIG_PSERIES) += spapr_pci.o pci-hotplug.o spapr_iommu.o
|
||||
obj-$(CONFIG_PSERIES) += spapr_events.o
|
||||
# PowerPC 4xx boards
|
||||
obj-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
|
||||
obj-y += ppc440_bamboo.o
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#define MPC8544_PCI_REGS_BASE (MPC8544_CCSRBAR_BASE + 0x8000ULL)
|
||||
#define MPC8544_PCI_REGS_SIZE 0x1000ULL
|
||||
#define MPC8544_PCI_IO 0xE1000000ULL
|
||||
#define MPC8544_PCI_IOLEN 0x10000ULL
|
||||
#define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + 0xe0000ULL)
|
||||
#define MPC8544_SPIN_BASE 0xEF000000ULL
|
||||
|
||||
|
@ -496,7 +495,7 @@ void ppce500_init(PPCE500Params *params)
|
|||
if (serial_hds[1]) {
|
||||
serial_mm_init(address_space_mem, MPC8544_SERIAL1_REGS_BASE,
|
||||
0, mpic[12+26], 399193,
|
||||
serial_hds[0], DEVICE_BIG_ENDIAN);
|
||||
serial_hds[1], DEVICE_BIG_ENDIAN);
|
||||
}
|
||||
|
||||
/* General Utility device */
|
||||
|
@ -511,7 +510,7 @@ void ppce500_init(PPCE500Params *params)
|
|||
if (!pci_bus)
|
||||
printf("couldn't create PCI controller!\n");
|
||||
|
||||
isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN);
|
||||
sysbus_mmio_map(sysbus_from_qdev(dev), 1, MPC8544_PCI_IO);
|
||||
|
||||
if (pci_bus) {
|
||||
/* Register network interfaces. */
|
||||
|
|
|
@ -59,7 +59,7 @@ static int bamboo_load_device_tree(hwaddr addr,
|
|||
{
|
||||
int ret = -1;
|
||||
#ifdef CONFIG_FDT
|
||||
uint32_t mem_reg_property[] = { 0, 0, ramsize };
|
||||
uint32_t mem_reg_property[] = { 0, 0, cpu_to_be32(ramsize) };
|
||||
char *filename;
|
||||
int fdt_size;
|
||||
void *fdt;
|
||||
|
|
|
@ -348,10 +348,6 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
|||
ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
|
||||
ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
|
||||
|
||||
/* cuda also initialize ADB */
|
||||
if (machine_arch == ARCH_MAC99_U3) {
|
||||
usb_enabled = 1;
|
||||
}
|
||||
cuda_init(&cuda_mem, pic[0x19]);
|
||||
|
||||
adb_kbd_init(&adb_bus);
|
||||
|
@ -360,15 +356,14 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
|||
macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
|
||||
dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);
|
||||
|
||||
if (usb_enabled) {
|
||||
if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
|
||||
pci_create_simple(pci_bus, -1, "pci-ohci");
|
||||
}
|
||||
|
||||
/* U3 needs to use USB for input because Linux doesn't support via-cuda
|
||||
on PPC64 */
|
||||
if (machine_arch == ARCH_MAC99_U3) {
|
||||
usbdevice_create("keyboard");
|
||||
usbdevice_create("mouse");
|
||||
/* U3 needs to use USB for input because Linux doesn't support via-cuda
|
||||
on PPC64 */
|
||||
if (machine_arch == ARCH_MAC99_U3) {
|
||||
usbdevice_create("keyboard");
|
||||
usbdevice_create("mouse");
|
||||
}
|
||||
}
|
||||
|
||||
if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
|
||||
|
|
|
@ -286,7 +286,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
|
|||
macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
|
||||
dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar);
|
||||
|
||||
if (usb_enabled) {
|
||||
if (usb_enabled(false)) {
|
||||
pci_create_simple(pci_bus, -1, "pci-ohci");
|
||||
}
|
||||
|
||||
|
|
|
@ -661,7 +661,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
|
|||
memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr);
|
||||
#endif
|
||||
|
||||
if (usb_enabled) {
|
||||
if (usb_enabled(false)) {
|
||||
pci_create_simple(pci_bus, -1, "pci-ohci");
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#define PCIE500_ALL_SIZE 0x1000
|
||||
#define PCIE500_REG_SIZE (PCIE500_ALL_SIZE - PCIE500_REG_BASE)
|
||||
|
||||
#define PCIE500_PCI_IOLEN 0x10000ULL
|
||||
|
||||
#define PPCE500_PCI_CONFIG_ADDR 0x0
|
||||
#define PPCE500_PCI_CONFIG_DATA 0x4
|
||||
#define PPCE500_PCI_INTACK 0x8
|
||||
|
@ -87,6 +89,7 @@ struct PPCE500PCIState {
|
|||
/* mmio maps */
|
||||
MemoryRegion container;
|
||||
MemoryRegion iomem;
|
||||
MemoryRegion pio;
|
||||
};
|
||||
|
||||
typedef struct PPCE500PCIState PPCE500PCIState;
|
||||
|
@ -314,7 +317,6 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
|
|||
PCIBus *b;
|
||||
int i;
|
||||
MemoryRegion *address_space_mem = get_system_memory();
|
||||
MemoryRegion *address_space_io = get_system_io();
|
||||
|
||||
h = PCI_HOST_BRIDGE(dev);
|
||||
s = PPC_E500_PCI_HOST_BRIDGE(dev);
|
||||
|
@ -323,9 +325,11 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
|
|||
sysbus_init_irq(dev, &s->irq[i]);
|
||||
}
|
||||
|
||||
memory_region_init(&s->pio, "pci-pio", PCIE500_PCI_IOLEN);
|
||||
|
||||
b = pci_register_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
|
||||
mpc85xx_pci_map_irq, s->irq, address_space_mem,
|
||||
address_space_io, PCI_DEVFN(0x11, 0), 4);
|
||||
&s->pio, PCI_DEVFN(0x11, 0), 4);
|
||||
h->bus = b;
|
||||
|
||||
pci_create_simple(b, 0, "e500-host-bridge");
|
||||
|
@ -341,6 +345,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
|
|||
memory_region_add_subregion(&s->container, PCIE500_CFGDATA, &h->data_mem);
|
||||
memory_region_add_subregion(&s->container, PCIE500_REG_BASE, &s->iomem);
|
||||
sysbus_init_mmio(dev, &s->container);
|
||||
sysbus_init_mmio(dev, &s->pio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2108,7 +2108,7 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
|
|||
s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
|
||||
}
|
||||
|
||||
if (usb_enabled) {
|
||||
if (usb_enabled(false)) {
|
||||
sysbus_create_simple("sysbus-ohci", 0x4c000000,
|
||||
qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
|
||||
}
|
||||
|
@ -2239,7 +2239,7 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
|
|||
s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
|
||||
}
|
||||
|
||||
if (usb_enabled) {
|
||||
if (usb_enabled(false)) {
|
||||
sysbus_create_simple("sysbus-ohci", 0x4c000000,
|
||||
qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ static void realview_init(ram_addr_t ram_size,
|
|||
sysbus_connect_irq(busdev, 2, pic[50]);
|
||||
sysbus_connect_irq(busdev, 3, pic[51]);
|
||||
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
|
||||
if (usb_enabled) {
|
||||
if (usb_enabled(false)) {
|
||||
pci_create_simple(pci_bus, -1, "pci-ohci");
|
||||
}
|
||||
n = drive_get_max_bus(IF_SCSI);
|
||||
|
|
78
hw/rtl8139.c
78
hw/rtl8139.c
|
@ -3187,38 +3187,6 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
|
|||
|
||||
/* */
|
||||
|
||||
static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
|
||||
{
|
||||
rtl8139_io_writeb(opaque, addr & 0xFF, val);
|
||||
}
|
||||
|
||||
static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
|
||||
{
|
||||
rtl8139_io_writew(opaque, addr & 0xFF, val);
|
||||
}
|
||||
|
||||
static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
|
||||
{
|
||||
rtl8139_io_writel(opaque, addr & 0xFF, val);
|
||||
}
|
||||
|
||||
static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
|
||||
{
|
||||
return rtl8139_io_readb(opaque, addr & 0xFF);
|
||||
}
|
||||
|
||||
static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
|
||||
{
|
||||
return rtl8139_io_readw(opaque, addr & 0xFF);
|
||||
}
|
||||
|
||||
static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
|
||||
{
|
||||
return rtl8139_io_readl(opaque, addr & 0xFF);
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
static void rtl8139_mmio_writeb(void *opaque, hwaddr addr, uint32_t val)
|
||||
{
|
||||
rtl8139_io_writeb(opaque, addr & 0xFF, val);
|
||||
|
@ -3386,18 +3354,44 @@ static const VMStateDescription vmstate_rtl8139 = {
|
|||
/***********************************************************/
|
||||
/* PCI RTL8139 definitions */
|
||||
|
||||
static const MemoryRegionPortio rtl8139_portio[] = {
|
||||
{ 0, 0x100, 1, .read = rtl8139_ioport_readb, },
|
||||
{ 0, 0x100, 1, .write = rtl8139_ioport_writeb, },
|
||||
{ 0, 0x100, 2, .read = rtl8139_ioport_readw, },
|
||||
{ 0, 0x100, 2, .write = rtl8139_ioport_writew, },
|
||||
{ 0, 0x100, 4, .read = rtl8139_ioport_readl, },
|
||||
{ 0, 0x100, 4, .write = rtl8139_ioport_writel, },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
static void rtl8139_ioport_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
rtl8139_io_writeb(opaque, addr, val);
|
||||
break;
|
||||
case 2:
|
||||
rtl8139_io_writew(opaque, addr, val);
|
||||
break;
|
||||
case 4:
|
||||
rtl8139_io_writel(opaque, addr, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t rtl8139_ioport_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
return rtl8139_io_readb(opaque, addr);
|
||||
case 2:
|
||||
return rtl8139_io_readw(opaque, addr);
|
||||
case 4:
|
||||
return rtl8139_io_readl(opaque, addr);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps rtl8139_io_ops = {
|
||||
.old_portio = rtl8139_portio,
|
||||
.read = rtl8139_ioport_read,
|
||||
.write = rtl8139_ioport_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
|
|
30
hw/serial.c
30
hw/serial.c
|
@ -26,6 +26,7 @@
|
|||
#include "serial.h"
|
||||
#include "qemu-char.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "exec-memory.h"
|
||||
|
||||
//#define DEBUG_SERIAL
|
||||
|
||||
|
@ -305,7 +306,8 @@ static void serial_xmit(void *opaque)
|
|||
}
|
||||
|
||||
|
||||
static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
SerialState *s = opaque;
|
||||
|
||||
|
@ -451,7 +453,7 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
|
||||
static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
SerialState *s = opaque;
|
||||
uint32_t ret;
|
||||
|
@ -620,7 +622,7 @@ static int serial_post_load(void *opaque, int version_id)
|
|||
s->fcr_vmstate = 0;
|
||||
}
|
||||
/* Initialize fcr via setter to perform essential side-effects */
|
||||
serial_ioport_write(s, 0x02, s->fcr_vmstate);
|
||||
serial_ioport_write(s, 0x02, s->fcr_vmstate, 1);
|
||||
serial_update_parameters(s);
|
||||
return 0;
|
||||
}
|
||||
|
@ -705,13 +707,14 @@ void serial_set_frequency(SerialState *s, uint32_t frequency)
|
|||
serial_update_parameters(s);
|
||||
}
|
||||
|
||||
static const MemoryRegionPortio serial_portio[] = {
|
||||
{ 0, 8, 1, .read = serial_ioport_read, .write = serial_ioport_write },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
|
||||
const MemoryRegionOps serial_io_ops = {
|
||||
.old_portio = serial_portio
|
||||
.read = serial_ioport_read,
|
||||
.write = serial_ioport_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
|
||||
|
@ -728,8 +731,9 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
|
|||
|
||||
vmstate_register(NULL, base, &vmstate_serial, s);
|
||||
|
||||
register_ioport_write(base, 8, 1, serial_ioport_write, s);
|
||||
register_ioport_read(base, 8, 1, serial_ioport_read, s);
|
||||
memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
|
||||
memory_region_add_subregion(get_system_io(), base, &s->io);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -738,7 +742,7 @@ static uint64_t serial_mm_read(void *opaque, hwaddr addr,
|
|||
unsigned size)
|
||||
{
|
||||
SerialState *s = opaque;
|
||||
return serial_ioport_read(s, addr >> s->it_shift);
|
||||
return serial_ioport_read(s, addr >> s->it_shift, 1);
|
||||
}
|
||||
|
||||
static void serial_mm_write(void *opaque, hwaddr addr,
|
||||
|
@ -746,7 +750,7 @@ static void serial_mm_write(void *opaque, hwaddr addr,
|
|||
{
|
||||
SerialState *s = opaque;
|
||||
value &= ~0u >> (32 - (size * 8));
|
||||
serial_ioport_write(s, addr >> s->it_shift, value);
|
||||
serial_ioport_write(s, addr >> s->it_shift, value, 1);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps serial_mm_ops[3] = {
|
||||
|
|
16
hw/spapr.c
16
hw/spapr.c
|
@ -232,7 +232,8 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
|
|||
hwaddr initrd_size,
|
||||
hwaddr kernel_size,
|
||||
const char *boot_device,
|
||||
const char *kernel_cmdline)
|
||||
const char *kernel_cmdline,
|
||||
uint32_t epow_irq)
|
||||
{
|
||||
void *fdt;
|
||||
CPUPPCState *env;
|
||||
|
@ -403,6 +404,8 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
|
|||
_FDT((fdt_property(fdt, "ibm,associativity-reference-points",
|
||||
refpoints, sizeof(refpoints))));
|
||||
|
||||
_FDT((fdt_property_cell(fdt, "rtas-error-log-max", RTAS_ERROR_LOG_MAX)));
|
||||
|
||||
_FDT((fdt_end_node(fdt)));
|
||||
|
||||
/* interrupt controller */
|
||||
|
@ -433,6 +436,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
|
|||
|
||||
_FDT((fdt_end_node(fdt)));
|
||||
|
||||
/* event-sources */
|
||||
spapr_events_fdt_skel(fdt, epow_irq);
|
||||
|
||||
_FDT((fdt_end_node(fdt))); /* close root node */
|
||||
_FDT((fdt_finish(fdt)));
|
||||
|
||||
|
@ -795,6 +801,9 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
|
|||
spapr->icp = xics_system_init(XICS_IRQS);
|
||||
spapr->next_irq = 16;
|
||||
|
||||
/* Set up EPOW events infrastructure */
|
||||
spapr_events_init(spapr);
|
||||
|
||||
/* Set up IOMMU */
|
||||
spapr_iommu_init();
|
||||
|
||||
|
@ -840,7 +849,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
|
|||
spapr->has_graphics = true;
|
||||
}
|
||||
|
||||
if (usb_enabled) {
|
||||
if (usb_enabled(spapr->has_graphics)) {
|
||||
pci_create_simple(phb->bus, -1, "pci-ohci");
|
||||
if (spapr->has_graphics) {
|
||||
usbdevice_create("keyboard");
|
||||
|
@ -903,7 +912,8 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
|
|||
spapr->fdt_skel = spapr_create_fdt_skel(cpu_model,
|
||||
initrd_base, initrd_size,
|
||||
kernel_size,
|
||||
boot_device, kernel_cmdline);
|
||||
boot_device, kernel_cmdline,
|
||||
spapr->epow_irq);
|
||||
assert(spapr->fdt_skel != NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ typedef struct sPAPREnvironment {
|
|||
int rtc_offset;
|
||||
char *cpu_model;
|
||||
bool has_graphics;
|
||||
|
||||
uint32_t epow_irq;
|
||||
Notifier epow_notifier;
|
||||
} sPAPREnvironment;
|
||||
|
||||
#define H_SUCCESS 0
|
||||
|
@ -335,7 +338,12 @@ typedef struct sPAPRTCE {
|
|||
#define SPAPR_VIO_BASE_LIOBN 0x00000000
|
||||
#define SPAPR_PCI_BASE_LIOBN 0x80000000
|
||||
|
||||
#define RTAS_ERROR_LOG_MAX 2048
|
||||
|
||||
|
||||
void spapr_iommu_init(void);
|
||||
void spapr_events_init(sPAPREnvironment *spapr);
|
||||
void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
|
||||
DMAContext *spapr_tce_new_dma_context(uint32_t liobn, size_t window_size);
|
||||
void spapr_tce_free(DMAContext *dma);
|
||||
void spapr_tce_reset(DMAContext *dma);
|
||||
|
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
|
||||
*
|
||||
* RTAS events handling
|
||||
*
|
||||
* Copyright (c) 2012 David Gibson, IBM Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include "cpu.h"
|
||||
#include "sysemu.h"
|
||||
#include "qemu-char.h"
|
||||
#include "hw/qdev.h"
|
||||
#include "device_tree.h"
|
||||
|
||||
#include "hw/spapr.h"
|
||||
#include "hw/spapr_vio.h"
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
struct rtas_error_log {
|
||||
uint32_t summary;
|
||||
#define RTAS_LOG_VERSION_MASK 0xff000000
|
||||
#define RTAS_LOG_VERSION_6 0x06000000
|
||||
#define RTAS_LOG_SEVERITY_MASK 0x00e00000
|
||||
#define RTAS_LOG_SEVERITY_ALREADY_REPORTED 0x00c00000
|
||||
#define RTAS_LOG_SEVERITY_FATAL 0x00a00000
|
||||
#define RTAS_LOG_SEVERITY_ERROR 0x00800000
|
||||
#define RTAS_LOG_SEVERITY_ERROR_SYNC 0x00600000
|
||||
#define RTAS_LOG_SEVERITY_WARNING 0x00400000
|
||||
#define RTAS_LOG_SEVERITY_EVENT 0x00200000
|
||||
#define RTAS_LOG_SEVERITY_NO_ERROR 0x00000000
|
||||
#define RTAS_LOG_DISPOSITION_MASK 0x00180000
|
||||
#define RTAS_LOG_DISPOSITION_FULLY_RECOVERED 0x00000000
|
||||
#define RTAS_LOG_DISPOSITION_LIMITED_RECOVERY 0x00080000
|
||||
#define RTAS_LOG_DISPOSITION_NOT_RECOVERED 0x00100000
|
||||
#define RTAS_LOG_OPTIONAL_PART_PRESENT 0x00040000
|
||||
#define RTAS_LOG_INITIATOR_MASK 0x0000f000
|
||||
#define RTAS_LOG_INITIATOR_UNKNOWN 0x00000000
|
||||
#define RTAS_LOG_INITIATOR_CPU 0x00001000
|
||||
#define RTAS_LOG_INITIATOR_PCI 0x00002000
|
||||
#define RTAS_LOG_INITIATOR_MEMORY 0x00004000
|
||||
#define RTAS_LOG_INITIATOR_HOTPLUG 0x00006000
|
||||
#define RTAS_LOG_TARGET_MASK 0x00000f00
|
||||
#define RTAS_LOG_TARGET_UNKNOWN 0x00000000
|
||||
#define RTAS_LOG_TARGET_CPU 0x00000100
|
||||
#define RTAS_LOG_TARGET_PCI 0x00000200
|
||||
#define RTAS_LOG_TARGET_MEMORY 0x00000400
|
||||
#define RTAS_LOG_TARGET_HOTPLUG 0x00000600
|
||||
#define RTAS_LOG_TYPE_MASK 0x000000ff
|
||||
#define RTAS_LOG_TYPE_OTHER 0x00000000
|
||||
#define RTAS_LOG_TYPE_RETRY 0x00000001
|
||||
#define RTAS_LOG_TYPE_TCE_ERR 0x00000002
|
||||
#define RTAS_LOG_TYPE_INTERN_DEV_FAIL 0x00000003
|
||||
#define RTAS_LOG_TYPE_TIMEOUT 0x00000004
|
||||
#define RTAS_LOG_TYPE_DATA_PARITY 0x00000005
|
||||
#define RTAS_LOG_TYPE_ADDR_PARITY 0x00000006
|
||||
#define RTAS_LOG_TYPE_CACHE_PARITY 0x00000007
|
||||
#define RTAS_LOG_TYPE_ADDR_INVALID 0x00000008
|
||||
#define RTAS_LOG_TYPE_ECC_UNCORR 0x00000009
|
||||
#define RTAS_LOG_TYPE_ECC_CORR 0x0000000a
|
||||
#define RTAS_LOG_TYPE_EPOW 0x00000040
|
||||
uint32_t extended_length;
|
||||
} QEMU_PACKED;
|
||||
|
||||
struct rtas_event_log_v6 {
|
||||
uint8_t b0;
|
||||
#define RTAS_LOG_V6_B0_VALID 0x80
|
||||
#define RTAS_LOG_V6_B0_UNRECOVERABLE_ERROR 0x40
|
||||
#define RTAS_LOG_V6_B0_RECOVERABLE_ERROR 0x20
|
||||
#define RTAS_LOG_V6_B0_DEGRADED_OPERATION 0x10
|
||||
#define RTAS_LOG_V6_B0_PREDICTIVE_ERROR 0x08
|
||||
#define RTAS_LOG_V6_B0_NEW_LOG 0x04
|
||||
#define RTAS_LOG_V6_B0_BIGENDIAN 0x02
|
||||
uint8_t _resv1;
|
||||
uint8_t b2;
|
||||
#define RTAS_LOG_V6_B2_POWERPC_FORMAT 0x80
|
||||
#define RTAS_LOG_V6_B2_LOG_FORMAT_MASK 0x0f
|
||||
#define RTAS_LOG_V6_B2_LOG_FORMAT_PLATFORM_EVENT 0x0e
|
||||
uint8_t _resv2[9];
|
||||
uint32_t company;
|
||||
#define RTAS_LOG_V6_COMPANY_IBM 0x49424d00 /* IBM<null> */
|
||||
} QEMU_PACKED;
|
||||
|
||||
struct rtas_event_log_v6_section_header {
|
||||
uint16_t section_id;
|
||||
uint16_t section_length;
|
||||
uint8_t section_version;
|
||||
uint8_t section_subtype;
|
||||
uint16_t creator_component_id;
|
||||
} QEMU_PACKED;
|
||||
|
||||
struct rtas_event_log_v6_maina {
|
||||
#define RTAS_LOG_V6_SECTION_ID_MAINA 0x5048 /* PH */
|
||||
struct rtas_event_log_v6_section_header hdr;
|
||||
uint32_t creation_date; /* BCD: YYYYMMDD */
|
||||
uint32_t creation_time; /* BCD: HHMMSS00 */
|
||||
uint8_t _platform1[8];
|
||||
char creator_id;
|
||||
uint8_t _resv1[2];
|
||||
uint8_t section_count;
|
||||
uint8_t _resv2[4];
|
||||
uint8_t _platform2[8];
|
||||
uint32_t plid;
|
||||
uint8_t _platform3[4];
|
||||
} QEMU_PACKED;
|
||||
|
||||
struct rtas_event_log_v6_mainb {
|
||||
#define RTAS_LOG_V6_SECTION_ID_MAINB 0x5548 /* UH */
|
||||
struct rtas_event_log_v6_section_header hdr;
|
||||
uint8_t subsystem_id;
|
||||
uint8_t _platform1;
|
||||
uint8_t event_severity;
|
||||
uint8_t event_subtype;
|
||||
uint8_t _platform2[4];
|
||||
uint8_t _resv1[2];
|
||||
uint16_t action_flags;
|
||||
uint8_t _resv2[4];
|
||||
} QEMU_PACKED;
|
||||
|
||||
struct rtas_event_log_v6_epow {
|
||||
#define RTAS_LOG_V6_SECTION_ID_EPOW 0x4550 /* EP */
|
||||
struct rtas_event_log_v6_section_header hdr;
|
||||
uint8_t sensor_value;
|
||||
#define RTAS_LOG_V6_EPOW_ACTION_RESET 0
|
||||
#define RTAS_LOG_V6_EPOW_ACTION_WARN_COOLING 1
|
||||
#define RTAS_LOG_V6_EPOW_ACTION_WARN_POWER 2
|
||||
#define RTAS_LOG_V6_EPOW_ACTION_SYSTEM_SHUTDOWN 3
|
||||
#define RTAS_LOG_V6_EPOW_ACTION_SYSTEM_HALT 4
|
||||
#define RTAS_LOG_V6_EPOW_ACTION_MAIN_ENCLOSURE 5
|
||||
#define RTAS_LOG_V6_EPOW_ACTION_POWER_OFF 7
|
||||
uint8_t event_modifier;
|
||||
#define RTAS_LOG_V6_EPOW_MODIFIER_NORMAL 1
|
||||
#define RTAS_LOG_V6_EPOW_MODIFIER_ON_UPS 2
|
||||
#define RTAS_LOG_V6_EPOW_MODIFIER_CRITICAL 3
|
||||
#define RTAS_LOG_V6_EPOW_MODIFIER_TEMPERATURE 4
|
||||
uint8_t extended_modifier;
|
||||
#define RTAS_LOG_V6_EPOW_XMODIFIER_SYSTEM_WIDE 0
|
||||
#define RTAS_LOG_V6_EPOW_XMODIFIER_PARTITION_SPECIFIC 1
|
||||
uint8_t _resv;
|
||||
uint64_t reason_code;
|
||||
} QEMU_PACKED;
|
||||
|
||||
struct epow_log_full {
|
||||
struct rtas_error_log hdr;
|
||||
struct rtas_event_log_v6 v6hdr;
|
||||
struct rtas_event_log_v6_maina maina;
|
||||
struct rtas_event_log_v6_mainb mainb;
|
||||
struct rtas_event_log_v6_epow epow;
|
||||
} QEMU_PACKED;
|
||||
|
||||
#define EVENT_MASK_INTERNAL_ERRORS 0x80000000
|
||||
#define EVENT_MASK_EPOW 0x40000000
|
||||
#define EVENT_MASK_HOTPLUG 0x10000000
|
||||
#define EVENT_MASK_IO 0x08000000
|
||||
|
||||
#define _FDT(exp) \
|
||||
do { \
|
||||
int ret = (exp); \
|
||||
if (ret < 0) { \
|
||||
fprintf(stderr, "qemu: error creating device tree: %s: %s\n", \
|
||||
#exp, fdt_strerror(ret)); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq)
|
||||
{
|
||||
uint32_t epow_irq_ranges[] = {cpu_to_be32(epow_irq), cpu_to_be32(1)};
|
||||
uint32_t epow_interrupts[] = {cpu_to_be32(epow_irq), 0};
|
||||
|
||||
_FDT((fdt_begin_node(fdt, "event-sources")));
|
||||
|
||||
_FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
|
||||
_FDT((fdt_property_cell(fdt, "#interrupt-cells", 2)));
|
||||
_FDT((fdt_property(fdt, "interrupt-ranges",
|
||||
epow_irq_ranges, sizeof(epow_irq_ranges))));
|
||||
|
||||
_FDT((fdt_begin_node(fdt, "epow-events")));
|
||||
_FDT((fdt_property(fdt, "interrupts",
|
||||
epow_interrupts, sizeof(epow_interrupts))));
|
||||
_FDT((fdt_end_node(fdt)));
|
||||
|
||||
_FDT((fdt_end_node(fdt)));
|
||||
}
|
||||
|
||||
static struct epow_log_full *pending_epow;
|
||||
static uint32_t next_plid;
|
||||
|
||||
static void spapr_powerdown_req(Notifier *n, void *opaque)
|
||||
{
|
||||
sPAPREnvironment *spapr = container_of(n, sPAPREnvironment, epow_notifier);
|
||||
struct rtas_error_log *hdr;
|
||||
struct rtas_event_log_v6 *v6hdr;
|
||||
struct rtas_event_log_v6_maina *maina;
|
||||
struct rtas_event_log_v6_mainb *mainb;
|
||||
struct rtas_event_log_v6_epow *epow;
|
||||
struct tm tm;
|
||||
int year;
|
||||
|
||||
if (pending_epow) {
|
||||
/* For now, we just throw away earlier events if two come
|
||||
* along before any are consumed. This is sufficient for our
|
||||
* powerdown messages, but we'll need more if we do more
|
||||
* general error/event logging */
|
||||
g_free(pending_epow);
|
||||
}
|
||||
pending_epow = g_malloc0(sizeof(*pending_epow));
|
||||
hdr = &pending_epow->hdr;
|
||||
v6hdr = &pending_epow->v6hdr;
|
||||
maina = &pending_epow->maina;
|
||||
mainb = &pending_epow->mainb;
|
||||
epow = &pending_epow->epow;
|
||||
|
||||
hdr->summary = cpu_to_be32(RTAS_LOG_VERSION_6
|
||||
| RTAS_LOG_SEVERITY_EVENT
|
||||
| RTAS_LOG_DISPOSITION_NOT_RECOVERED
|
||||
| RTAS_LOG_OPTIONAL_PART_PRESENT
|
||||
| RTAS_LOG_TYPE_EPOW);
|
||||
hdr->extended_length = cpu_to_be32(sizeof(*pending_epow)
|
||||
- sizeof(pending_epow->hdr));
|
||||
|
||||
v6hdr->b0 = RTAS_LOG_V6_B0_VALID | RTAS_LOG_V6_B0_NEW_LOG
|
||||
| RTAS_LOG_V6_B0_BIGENDIAN;
|
||||
v6hdr->b2 = RTAS_LOG_V6_B2_POWERPC_FORMAT
|
||||
| RTAS_LOG_V6_B2_LOG_FORMAT_PLATFORM_EVENT;
|
||||
v6hdr->company = cpu_to_be32(RTAS_LOG_V6_COMPANY_IBM);
|
||||
|
||||
maina->hdr.section_id = cpu_to_be16(RTAS_LOG_V6_SECTION_ID_MAINA);
|
||||
maina->hdr.section_length = cpu_to_be16(sizeof(*maina));
|
||||
/* FIXME: section version, subtype and creator id? */
|
||||
qemu_get_timedate(&tm, spapr->rtc_offset);
|
||||
year = tm.tm_year + 1900;
|
||||
maina->creation_date = cpu_to_be32((to_bcd(year / 100) << 24)
|
||||
| (to_bcd(year % 100) << 16)
|
||||
| (to_bcd(tm.tm_mon + 1) << 8)
|
||||
| to_bcd(tm.tm_mday));
|
||||
maina->creation_time = cpu_to_be32((to_bcd(tm.tm_hour) << 24)
|
||||
| (to_bcd(tm.tm_min) << 16)
|
||||
| (to_bcd(tm.tm_sec) << 8));
|
||||
maina->creator_id = 'H'; /* Hypervisor */
|
||||
maina->section_count = 3; /* Main-A, Main-B and EPOW */
|
||||
maina->plid = next_plid++;
|
||||
|
||||
mainb->hdr.section_id = cpu_to_be16(RTAS_LOG_V6_SECTION_ID_MAINB);
|
||||
mainb->hdr.section_length = cpu_to_be16(sizeof(*mainb));
|
||||
/* FIXME: section version, subtype and creator id? */
|
||||
mainb->subsystem_id = 0xa0; /* External environment */
|
||||
mainb->event_severity = 0x00; /* Informational / non-error */
|
||||
mainb->event_subtype = 0xd0; /* Normal shutdown */
|
||||
|
||||
epow->hdr.section_id = cpu_to_be16(RTAS_LOG_V6_SECTION_ID_EPOW);
|
||||
epow->hdr.section_length = cpu_to_be16(sizeof(*epow));
|
||||
epow->hdr.section_version = 2; /* includes extended modifier */
|
||||
/* FIXME: section subtype and creator id? */
|
||||
epow->sensor_value = RTAS_LOG_V6_EPOW_ACTION_SYSTEM_SHUTDOWN;
|
||||
epow->event_modifier = RTAS_LOG_V6_EPOW_MODIFIER_NORMAL;
|
||||
epow->extended_modifier = RTAS_LOG_V6_EPOW_XMODIFIER_PARTITION_SPECIFIC;
|
||||
|
||||
qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->epow_irq));
|
||||
}
|
||||
|
||||
static void check_exception(sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
uint32_t mask, buf, len;
|
||||
uint64_t xinfo;
|
||||
|
||||
if ((nargs < 6) || (nargs > 7) || nret != 1) {
|
||||
rtas_st(rets, 0, -3);
|
||||
return;
|
||||
}
|
||||
|
||||
xinfo = rtas_ld(args, 1);
|
||||
mask = rtas_ld(args, 2);
|
||||
buf = rtas_ld(args, 4);
|
||||
len = rtas_ld(args, 5);
|
||||
if (nargs == 7) {
|
||||
xinfo |= (uint64_t)rtas_ld(args, 6) << 32;
|
||||
}
|
||||
|
||||
if ((mask & EVENT_MASK_EPOW) && pending_epow) {
|
||||
if (sizeof(*pending_epow) < len) {
|
||||
len = sizeof(*pending_epow);
|
||||
}
|
||||
|
||||
cpu_physical_memory_write(buf, pending_epow, len);
|
||||
g_free(pending_epow);
|
||||
pending_epow = NULL;
|
||||
rtas_st(rets, 0, 0);
|
||||
} else {
|
||||
rtas_st(rets, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_events_init(sPAPREnvironment *spapr)
|
||||
{
|
||||
spapr->epow_irq = spapr_allocate_msi(0);
|
||||
spapr->epow_notifier.notify = spapr_powerdown_req;
|
||||
qemu_register_powerdown_notifier(&spapr->epow_notifier);
|
||||
spapr_rtas_register("check-exception", check_exception);
|
||||
}
|
|
@ -366,26 +366,26 @@ static target_ulong register_vpa(CPUPPCState *env, target_ulong vpa)
|
|||
return H_PARAMETER;
|
||||
}
|
||||
|
||||
env->vpa = vpa;
|
||||
env->vpa_addr = vpa;
|
||||
|
||||
tmp = ldub_phys(env->vpa + VPA_SHARED_PROC_OFFSET);
|
||||
tmp = ldub_phys(env->vpa_addr + VPA_SHARED_PROC_OFFSET);
|
||||
tmp |= VPA_SHARED_PROC_VAL;
|
||||
stb_phys(env->vpa + VPA_SHARED_PROC_OFFSET, tmp);
|
||||
stb_phys(env->vpa_addr + VPA_SHARED_PROC_OFFSET, tmp);
|
||||
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong deregister_vpa(CPUPPCState *env, target_ulong vpa)
|
||||
{
|
||||
if (env->slb_shadow) {
|
||||
if (env->slb_shadow_addr) {
|
||||
return H_RESOURCE;
|
||||
}
|
||||
|
||||
if (env->dispatch_trace_log) {
|
||||
if (env->dtl_addr) {
|
||||
return H_RESOURCE;
|
||||
}
|
||||
|
||||
env->vpa = 0;
|
||||
env->vpa_addr = 0;
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -407,18 +407,20 @@ static target_ulong register_slb_shadow(CPUPPCState *env, target_ulong addr)
|
|||
return H_PARAMETER;
|
||||
}
|
||||
|
||||
if (!env->vpa) {
|
||||
if (!env->vpa_addr) {
|
||||
return H_RESOURCE;
|
||||
}
|
||||
|
||||
env->slb_shadow = addr;
|
||||
env->slb_shadow_addr = addr;
|
||||
env->slb_shadow_size = size;
|
||||
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong deregister_slb_shadow(CPUPPCState *env, target_ulong addr)
|
||||
{
|
||||
env->slb_shadow = 0;
|
||||
env->slb_shadow_addr = 0;
|
||||
env->slb_shadow_size = 0;
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -437,11 +439,11 @@ static target_ulong register_dtl(CPUPPCState *env, target_ulong addr)
|
|||
return H_PARAMETER;
|
||||
}
|
||||
|
||||
if (!env->vpa) {
|
||||
if (!env->vpa_addr) {
|
||||
return H_RESOURCE;
|
||||
}
|
||||
|
||||
env->dispatch_trace_log = addr;
|
||||
env->dtl_addr = addr;
|
||||
env->dtl_size = size;
|
||||
|
||||
return H_SUCCESS;
|
||||
|
@ -449,7 +451,7 @@ static target_ulong register_dtl(CPUPPCState *env, target_ulong addr)
|
|||
|
||||
static target_ulong deregister_dtl(CPUPPCState *env, target_ulong addr)
|
||||
{
|
||||
env->dispatch_trace_log = 0;
|
||||
env->dtl_addr = 0;
|
||||
env->dtl_size = 0;
|
||||
|
||||
return H_SUCCESS;
|
||||
|
@ -670,11 +672,10 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
|
|||
} else {
|
||||
assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX));
|
||||
|
||||
|
||||
slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];
|
||||
}
|
||||
|
||||
assert(!(*slot) || (fn == *slot));
|
||||
assert(!(*slot));
|
||||
*slot = fn;
|
||||
}
|
||||
|
||||
|
|
|
@ -439,43 +439,6 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
|
|||
qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
|
||||
}
|
||||
|
||||
static uint64_t spapr_io_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
return cpu_inb(addr);
|
||||
case 2:
|
||||
return cpu_inw(addr);
|
||||
case 4:
|
||||
return cpu_inl(addr);
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
static void spapr_io_write(void *opaque, hwaddr addr,
|
||||
uint64_t data, unsigned size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
cpu_outb(addr, data);
|
||||
return;
|
||||
case 2:
|
||||
cpu_outw(addr, data);
|
||||
return;
|
||||
case 4:
|
||||
cpu_outl(addr, data);
|
||||
return;
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps spapr_io_ops = {
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.read = spapr_io_read,
|
||||
.write = spapr_io_write
|
||||
};
|
||||
|
||||
/*
|
||||
* MSI/MSIX memory region implementation.
|
||||
* The handler handles both MSI and MSIX.
|
||||
|
@ -545,14 +508,9 @@ static int spapr_phb_init(SysBusDevice *s)
|
|||
* old_portion are updated */
|
||||
sprintf(namebuf, "%s.io", sphb->dtbusname);
|
||||
memory_region_init(&sphb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE);
|
||||
/* FIXME: fix to support multiple PHBs */
|
||||
memory_region_add_subregion(get_system_io(), 0, &sphb->iospace);
|
||||
|
||||
sprintf(namebuf, "%s.io-alias", sphb->dtbusname);
|
||||
memory_region_init_io(&sphb->iowindow, &spapr_io_ops, sphb,
|
||||
namebuf, SPAPR_PCI_IO_WIN_SIZE);
|
||||
memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
|
||||
&sphb->iowindow);
|
||||
&sphb->iospace);
|
||||
|
||||
/* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,
|
||||
* we need to allocate some memory to catch those writes coming
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef struct sPAPRPHBState {
|
|||
MemoryRegion memspace, iospace;
|
||||
hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size;
|
||||
hwaddr msi_win_addr;
|
||||
MemoryRegion memwindow, iowindow, msiwindow;
|
||||
MemoryRegion memwindow, msiwindow;
|
||||
|
||||
uint32_t dma_liobn;
|
||||
uint64_t dma_window_start;
|
||||
|
|
|
@ -241,6 +241,15 @@ target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
|
|||
|
||||
void spapr_rtas_register(const char *name, spapr_rtas_fn fn)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (rtas_next - rtas_table); i++) {
|
||||
if (strcmp(name, rtas_table[i].name) == 0) {
|
||||
fprintf(stderr, "RTAS call \"%s\" registered twice\n", name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
assert(rtas_next < (rtas_table + TOKEN_MAX));
|
||||
|
||||
rtas_next->name = name;
|
||||
|
|
|
@ -248,7 +248,7 @@ static void versatile_init(ram_addr_t ram_size,
|
|||
pci_nic_init_nofail(nd, "rtl8139", NULL);
|
||||
}
|
||||
}
|
||||
if (usb_enabled) {
|
||||
if (usb_enabled(false)) {
|
||||
pci_create_simple(pci_bus, -1, "pci-ohci");
|
||||
}
|
||||
n = drive_get_max_bus(IF_SCSI);
|
||||
|
|
128
hw/virtio-pci.c
128
hw/virtio-pci.c
|
@ -374,52 +374,39 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
|
||||
static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
|
||||
if (addr < config)
|
||||
uint64_t val = 0;
|
||||
if (addr < config) {
|
||||
return virtio_ioport_read(proxy, addr);
|
||||
}
|
||||
addr -= config;
|
||||
return virtio_config_readb(proxy->vdev, addr);
|
||||
}
|
||||
|
||||
static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
|
||||
uint16_t val;
|
||||
if (addr < config)
|
||||
return virtio_ioport_read(proxy, addr);
|
||||
addr -= config;
|
||||
val = virtio_config_readw(proxy->vdev, addr);
|
||||
if (virtio_is_big_endian()) {
|
||||
/*
|
||||
* virtio is odd, ioports are LE but config space is target native
|
||||
* endian. However, in qemu, all PIO is LE, so we need to re-swap
|
||||
* on BE targets
|
||||
*/
|
||||
val = bswap16(val);
|
||||
switch (size) {
|
||||
case 1:
|
||||
val = virtio_config_readb(proxy->vdev, addr);
|
||||
break;
|
||||
case 2:
|
||||
val = virtio_config_readw(proxy->vdev, addr);
|
||||
if (virtio_is_big_endian()) {
|
||||
val = bswap16(val);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
val = virtio_config_readl(proxy->vdev, addr);
|
||||
if (virtio_is_big_endian()) {
|
||||
val = bswap32(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
|
||||
uint32_t val;
|
||||
if (addr < config)
|
||||
return virtio_ioport_read(proxy, addr);
|
||||
addr -= config;
|
||||
val = virtio_config_readl(proxy->vdev, addr);
|
||||
if (virtio_is_big_endian()) {
|
||||
val = bswap32(val);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void virtio_pci_config_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
|
||||
|
@ -428,51 +415,36 @@ static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
|
|||
return;
|
||||
}
|
||||
addr -= config;
|
||||
virtio_config_writeb(proxy->vdev, addr, val);
|
||||
/*
|
||||
* Virtio-PCI is odd. Ioports are LE but config space is target native
|
||||
* endian.
|
||||
*/
|
||||
switch (size) {
|
||||
case 1:
|
||||
virtio_config_writeb(proxy->vdev, addr, val);
|
||||
break;
|
||||
case 2:
|
||||
if (virtio_is_big_endian()) {
|
||||
val = bswap16(val);
|
||||
}
|
||||
virtio_config_writew(proxy->vdev, addr, val);
|
||||
break;
|
||||
case 4:
|
||||
if (virtio_is_big_endian()) {
|
||||
val = bswap32(val);
|
||||
}
|
||||
virtio_config_writel(proxy->vdev, addr, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
|
||||
if (addr < config) {
|
||||
virtio_ioport_write(proxy, addr, val);
|
||||
return;
|
||||
}
|
||||
addr -= config;
|
||||
if (virtio_is_big_endian()) {
|
||||
val = bswap16(val);
|
||||
}
|
||||
virtio_config_writew(proxy->vdev, addr, val);
|
||||
}
|
||||
|
||||
static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
|
||||
if (addr < config) {
|
||||
virtio_ioport_write(proxy, addr, val);
|
||||
return;
|
||||
}
|
||||
addr -= config;
|
||||
if (virtio_is_big_endian()) {
|
||||
val = bswap32(val);
|
||||
}
|
||||
virtio_config_writel(proxy->vdev, addr, val);
|
||||
}
|
||||
|
||||
static const MemoryRegionPortio virtio_portio[] = {
|
||||
{ 0, 0x10000, 1, .write = virtio_pci_config_writeb, },
|
||||
{ 0, 0x10000, 2, .write = virtio_pci_config_writew, },
|
||||
{ 0, 0x10000, 4, .write = virtio_pci_config_writel, },
|
||||
{ 0, 0x10000, 1, .read = virtio_pci_config_readb, },
|
||||
{ 0, 0x10000, 2, .read = virtio_pci_config_readw, },
|
||||
{ 0, 0x10000, 4, .read = virtio_pci_config_readl, },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
|
||||
static const MemoryRegionOps virtio_pci_config_ops = {
|
||||
.old_portio = virtio_portio,
|
||||
.read = virtio_pci_config_read,
|
||||
.write = virtio_pci_config_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
|
|
21
hw/vmport.c
21
hw/vmport.c
|
@ -54,7 +54,8 @@ void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque)
|
|||
port_state->opaque[command] = opaque;
|
||||
}
|
||||
|
||||
static uint32_t vmport_ioport_read(void *opaque, uint32_t addr)
|
||||
static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
VMPortState *s = opaque;
|
||||
CPUX86State *env = cpu_single_env;
|
||||
|
@ -81,11 +82,12 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr)
|
|||
return s->func[command](s->opaque[command], addr);
|
||||
}
|
||||
|
||||
static void vmport_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void vmport_ioport_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
CPUX86State *env = cpu_single_env;
|
||||
|
||||
env->regs[R_EAX] = vmport_ioport_read(opaque, addr);
|
||||
env->regs[R_EAX] = vmport_ioport_read(opaque, addr, 4);
|
||||
}
|
||||
|
||||
static uint32_t vmport_cmd_get_version(void *opaque, uint32_t addr)
|
||||
|
@ -121,13 +123,14 @@ void vmmouse_set_data(const uint32_t *data)
|
|||
env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5];
|
||||
}
|
||||
|
||||
static const MemoryRegionPortio vmport_portio[] = {
|
||||
{0, 1, 4, .read = vmport_ioport_read, .write = vmport_ioport_write },
|
||||
PORTIO_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static const MemoryRegionOps vmport_ops = {
|
||||
.old_portio = vmport_portio
|
||||
.read = vmport_ioport_read,
|
||||
.write = vmport_ioport_write,
|
||||
.impl = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static int vmport_initfn(ISADevice *dev)
|
||||
|
|
|
@ -228,18 +228,46 @@ static void platform_fixed_ioport_reset(void *opaque)
|
|||
platform_fixed_ioport_writeb(s, 0, 0);
|
||||
}
|
||||
|
||||
const MemoryRegionPortio xen_platform_ioport[] = {
|
||||
{ 0, 16, 4, .write = platform_fixed_ioport_writel, },
|
||||
{ 0, 16, 2, .write = platform_fixed_ioport_writew, },
|
||||
{ 0, 16, 1, .write = platform_fixed_ioport_writeb, },
|
||||
{ 0, 16, 2, .read = platform_fixed_ioport_readw, },
|
||||
{ 0, 16, 1, .read = platform_fixed_ioport_readb, },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
static uint64_t platform_fixed_ioport_read(void *opaque,
|
||||
hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
return platform_fixed_ioport_readb(opaque, addr);
|
||||
case 2:
|
||||
return platform_fixed_ioport_readw(opaque, addr);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void platform_fixed_ioport_write(void *opaque, hwaddr addr,
|
||||
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
platform_fixed_ioport_writeb(opaque, addr, val);
|
||||
break;
|
||||
case 2:
|
||||
platform_fixed_ioport_writew(opaque, addr, val);
|
||||
break;
|
||||
case 4:
|
||||
platform_fixed_ioport_writel(opaque, addr, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const MemoryRegionOps platform_fixed_io_ops = {
|
||||
.old_portio = xen_platform_ioport,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.read = platform_fixed_ioport_read,
|
||||
.write = platform_fixed_ioport_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void platform_fixed_ioport_init(PCIXenPlatformState* s)
|
||||
|
|
|
@ -619,6 +619,10 @@ static QemuOptsList qemu_machine_opts = {
|
|||
.name = "mem-merge",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "enable/disable memory merge support",
|
||||
},{
|
||||
.name = "usb",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "Set on/off to enable/disable usb",
|
||||
},
|
||||
{ /* End of list */ }
|
||||
},
|
||||
|
|
4
sysemu.h
4
sysemu.h
|
@ -116,7 +116,6 @@ extern const char *keyboard_layout;
|
|||
extern int win2k_install_hack;
|
||||
extern int alt_grab;
|
||||
extern int ctrl_grab;
|
||||
extern int usb_enabled;
|
||||
extern int smp_cpus;
|
||||
extern int max_cpus;
|
||||
extern int cursor_hide;
|
||||
|
@ -186,4 +185,7 @@ void register_devices(void);
|
|||
void add_boot_device_path(int32_t bootindex, DeviceState *dev,
|
||||
const char *suffix);
|
||||
char *get_boot_devices_list(uint32_t *size);
|
||||
|
||||
bool usb_enabled(bool default_usb);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1045,10 +1045,9 @@ struct CPUPPCState {
|
|||
#endif
|
||||
|
||||
#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
|
||||
hwaddr vpa;
|
||||
hwaddr slb_shadow;
|
||||
hwaddr dispatch_trace_log;
|
||||
uint32_t dtl_size;
|
||||
hwaddr vpa_addr;
|
||||
hwaddr slb_shadow_addr, slb_shadow_size;
|
||||
hwaddr dtl_addr, dtl_size;
|
||||
#endif /* TARGET_PPC64 */
|
||||
|
||||
int error_code;
|
||||
|
|
|
@ -1509,10 +1509,8 @@ static void mmubooke_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
|
|||
mask = ~(entry->size - 1);
|
||||
ea = entry->EPN & mask;
|
||||
pa = entry->RPN & mask;
|
||||
#if (TARGET_PHYS_ADDR_SPACE_BITS >= 36)
|
||||
/* Extend the physical address to 36 bits */
|
||||
pa |= (hwaddr)(entry->RPN & 0xF) << 32;
|
||||
#endif
|
||||
size /= 1024;
|
||||
if (size >= 1024) {
|
||||
snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / 1024);
|
||||
|
|
|
@ -1498,7 +1498,7 @@ static void gen_spr_BookE (CPUPPCState *env, uint64_t ivor_mask)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_BOOKE_DBCR0, "DBCR0",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, &spr_write_40x_dbcr0,
|
||||
0x00000000);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_BOOKE_DBCR1, "DBCR1",
|
||||
|
@ -10425,9 +10425,10 @@ static void ppc_cpu_reset(CPUState *s)
|
|||
env->error_code = 0;
|
||||
|
||||
#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
|
||||
env->vpa = 0;
|
||||
env->slb_shadow = 0;
|
||||
env->dispatch_trace_log = 0;
|
||||
env->vpa_addr = 0;
|
||||
env->slb_shadow_addr = 0;
|
||||
env->slb_shadow_size = 0;
|
||||
env->dtl_addr = 0;
|
||||
env->dtl_size = 0;
|
||||
#endif /* TARGET_PPC64 */
|
||||
|
||||
|
|
30
vl.c
30
vl.c
|
@ -203,7 +203,6 @@ CharDriverState *serial_hds[MAX_SERIAL_PORTS];
|
|||
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
|
||||
CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
|
||||
int win2k_install_hack = 0;
|
||||
int usb_enabled = 0;
|
||||
int singlestep = 0;
|
||||
int smp_cpus = 1;
|
||||
int max_cpus = 0;
|
||||
|
@ -790,6 +789,17 @@ static int parse_sandbox(QemuOpts *opts, void *opaque)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*********QEMU USB setting******/
|
||||
bool usb_enabled(bool default_usb)
|
||||
{
|
||||
QemuOpts *mach_opts;
|
||||
mach_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
|
||||
if (mach_opts) {
|
||||
return qemu_opt_get_bool(mach_opts, "usb", default_usb);
|
||||
}
|
||||
return default_usb;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
/* QEMU Block devices */
|
||||
|
||||
|
@ -1077,8 +1087,9 @@ static int usb_device_add(const char *devname)
|
|||
const char *p;
|
||||
USBDevice *dev = NULL;
|
||||
|
||||
if (!usb_enabled)
|
||||
if (!usb_enabled(false)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* drivers with .usbdevice_name entry in USBDeviceInfo */
|
||||
dev = usbdevice_create(devname);
|
||||
|
@ -1114,8 +1125,9 @@ static int usb_device_del(const char *devname)
|
|||
if (strstart(devname, "host:", &p))
|
||||
return usb_host_device_close(p);
|
||||
|
||||
if (!usb_enabled)
|
||||
if (!usb_enabled(false)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = strchr(devname, '.');
|
||||
if (!p)
|
||||
|
@ -3083,10 +3095,16 @@ int main(int argc, char **argv, char **envp)
|
|||
}
|
||||
break;
|
||||
case QEMU_OPTION_usb:
|
||||
usb_enabled = 1;
|
||||
machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
|
||||
if (machine_opts) {
|
||||
qemu_opt_set_bool(machine_opts, "usb", true);
|
||||
}
|
||||
break;
|
||||
case QEMU_OPTION_usbdevice:
|
||||
usb_enabled = 1;
|
||||
machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
|
||||
if (machine_opts) {
|
||||
qemu_opt_set_bool(machine_opts, "usb", true);
|
||||
}
|
||||
add_device_config(DEV_USB, optarg);
|
||||
break;
|
||||
case QEMU_OPTION_device:
|
||||
|
@ -3653,7 +3671,7 @@ int main(int argc, char **argv, char **envp)
|
|||
current_machine = machine;
|
||||
|
||||
/* init USB devices */
|
||||
if (usb_enabled) {
|
||||
if (usb_enabled(false)) {
|
||||
if (foreach_device_config(DEV_USB, usb_parse) < 0)
|
||||
exit(1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue