mirror of https://github.com/xqemu/xqemu.git
Merge remote-tracking branch 'agraf/ppc-for-upstream' into staging
# By Alexander Graf (12) and others # Via Alexander Graf * agraf/ppc-for-upstream: (32 commits) PPC: Ignore writes to L2CR mac-io: Add escc-legacy memory alias region PPC: Newworld: Add second uninorth control register set PPC: Newworld: Add uninorth token register PPC: Add clock-frequency export for Mac machines PPC: Introduce an alias cache for faster lookups PPC: Fix GDB read on code area for PPC6xx PPC: Add dump_mmu() for 6xx target-ppc: Introduce unrealizefn for PowerPCCPU booke_ppc: limit booke timer to max when timeout overflow Graphics: Switch to 800x600x32 as default mode pseries: Update MAINTAINERS information target-ppc kvm: save cr register pseries: Fix compiler warning (conversion of pointer to integral value) spapr-rtas: add CPU argument to RTAS calls target-ppc: Change default machine for 64-bit ppc: do not register IABR SPR twice for 603e target-ppc: Drop redundant flags assignments from CPU families mpc8544_guts: Turn qdev initfn into instance_init mpc8544_guts: QOM'ify ... Message-id: 1372556709-23868-1-git-send-email-agraf@suse.de Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
1acd5a3739
|
@ -428,11 +428,14 @@ F: hw/pci/devices/host-prep.[hc]
|
|||
F: hw/isa/pc87312.[hc]
|
||||
|
||||
sPAPR
|
||||
M: David Gibson <david@gibson.dropbear.id.au>
|
||||
M: Alexander Graf <agraf@suse.de>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Supported
|
||||
F: hw/*/spapr*
|
||||
F: include/hw/*/spapr*
|
||||
F: hw/*/xics*
|
||||
F: include/hw/*/xics*
|
||||
F: pc-bios/spapr-rtas/*
|
||||
|
||||
virtex_ml507
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
|
|
|
@ -65,7 +65,7 @@ int graphic_depth = 8;
|
|||
#else
|
||||
int graphic_width = 800;
|
||||
int graphic_height = 600;
|
||||
int graphic_depth = 15;
|
||||
int graphic_depth = 32;
|
||||
#endif
|
||||
|
||||
|
||||
|
|
2
cpus.c
2
cpus.c
|
@ -71,7 +71,7 @@ static bool cpu_thread_is_idle(CPUState *cpu)
|
|||
return true;
|
||||
}
|
||||
if (!cpu->halted || qemu_cpu_has_work(cpu) ||
|
||||
kvm_async_interrupts_enabled()) {
|
||||
kvm_halt_in_kernel()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -43,5 +43,6 @@ CONFIG_XILINX=y
|
|||
CONFIG_XILINX_ETHLITE=y
|
||||
CONFIG_OPENPIC=y
|
||||
CONFIG_E500=y
|
||||
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
|
||||
# For PReP
|
||||
CONFIG_MC146818RTC=y
|
||||
|
|
|
@ -44,6 +44,7 @@ CONFIG_XILINX_ETHLITE=y
|
|||
CONFIG_OPENPIC=y
|
||||
CONFIG_PSERIES=y
|
||||
CONFIG_E500=y
|
||||
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
|
||||
# For pSeries
|
||||
CONFIG_PCI_HOTPLUG=y
|
||||
# For PReP
|
||||
|
|
|
@ -38,5 +38,6 @@ CONFIG_XILINX=y
|
|||
CONFIG_XILINX_ETHLITE=y
|
||||
CONFIG_OPENPIC=y
|
||||
CONFIG_E500=y
|
||||
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
|
||||
# For PReP
|
||||
CONFIG_MC146818RTC=y
|
||||
|
|
|
@ -40,6 +40,7 @@ void kvm_pc_setup_irq_routing(bool pci_enabled)
|
|||
}
|
||||
}
|
||||
}
|
||||
kvm_irqchip_commit_routes(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,4 +20,5 @@ obj-$(CONFIG_GRLIB) += grlib_irqmp.o
|
|||
obj-$(CONFIG_IOAPIC) += ioapic.o
|
||||
obj-$(CONFIG_OMAP) += omap_intc.o
|
||||
obj-$(CONFIG_OPENPIC) += openpic.o
|
||||
obj-$(CONFIG_OPENPIC_KVM) += openpic_kvm.o
|
||||
obj-$(CONFIG_SH4) += sh_intc.o
|
||||
|
|
|
@ -57,11 +57,7 @@ static const int debug_openpic = 0;
|
|||
} while (0)
|
||||
|
||||
#define MAX_CPU 32
|
||||
#define MAX_SRC 256
|
||||
#define MAX_TMR 4
|
||||
#define MAX_IPI 4
|
||||
#define MAX_MSI 8
|
||||
#define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR)
|
||||
#define VID 0x03 /* MPIC version ID */
|
||||
|
||||
/* OpenPIC capability flags */
|
||||
|
@ -78,7 +74,7 @@ static const int debug_openpic = 0;
|
|||
#define OPENPIC_SUMMARY_REG_START 0x3800
|
||||
#define OPENPIC_SUMMARY_REG_SIZE 0x800
|
||||
#define OPENPIC_SRC_REG_START 0x10000
|
||||
#define OPENPIC_SRC_REG_SIZE (MAX_SRC * 0x20)
|
||||
#define OPENPIC_SRC_REG_SIZE (OPENPIC_MAX_SRC * 0x20)
|
||||
#define OPENPIC_CPU_REG_START 0x20000
|
||||
#define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000)
|
||||
|
||||
|
@ -86,8 +82,8 @@ static const int debug_openpic = 0;
|
|||
#define RAVEN_MAX_CPU 2
|
||||
#define RAVEN_MAX_EXT 48
|
||||
#define RAVEN_MAX_IRQ 64
|
||||
#define RAVEN_MAX_TMR MAX_TMR
|
||||
#define RAVEN_MAX_IPI MAX_IPI
|
||||
#define RAVEN_MAX_TMR OPENPIC_MAX_TMR
|
||||
#define RAVEN_MAX_IPI OPENPIC_MAX_IPI
|
||||
|
||||
/* Interrupt definitions */
|
||||
#define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */
|
||||
|
@ -209,7 +205,7 @@ typedef struct IRQQueue {
|
|||
/* Round up to the nearest 64 IRQs so that the queue length
|
||||
* won't change when moving between 32 and 64 bit hosts.
|
||||
*/
|
||||
unsigned long queue[BITS_TO_LONGS((MAX_IRQ + 63) & ~63)];
|
||||
unsigned long queue[BITS_TO_LONGS((OPENPIC_MAX_IRQ + 63) & ~63)];
|
||||
int next;
|
||||
int priority;
|
||||
} IRQQueue;
|
||||
|
@ -255,8 +251,13 @@ typedef struct IRQDest {
|
|||
uint32_t outputs_active[OPENPIC_OUTPUT_NB];
|
||||
} IRQDest;
|
||||
|
||||
#define OPENPIC(obj) OBJECT_CHECK(OpenPICState, (obj), TYPE_OPENPIC)
|
||||
|
||||
typedef struct OpenPICState {
|
||||
SysBusDevice busdev;
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
MemoryRegion mem;
|
||||
|
||||
/* Behavior control */
|
||||
|
@ -283,7 +284,7 @@ typedef struct OpenPICState {
|
|||
uint32_t spve; /* Spurious vector register */
|
||||
uint32_t tfrr; /* Timer frequency reporting register */
|
||||
/* Source registers */
|
||||
IRQSource src[MAX_IRQ];
|
||||
IRQSource src[OPENPIC_MAX_IRQ];
|
||||
/* Local registers per output pin */
|
||||
IRQDest dst[MAX_CPU];
|
||||
uint32_t nb_cpus;
|
||||
|
@ -291,7 +292,7 @@ typedef struct OpenPICState {
|
|||
struct {
|
||||
uint32_t tccr; /* Global timer current count register */
|
||||
uint32_t tbcr; /* Global timer base count register */
|
||||
} timers[MAX_TMR];
|
||||
} timers[OPENPIC_MAX_TMR];
|
||||
/* Shared MSI registers */
|
||||
struct {
|
||||
uint32_t msir; /* Shared Message Signaled Interrupt Register */
|
||||
|
@ -503,7 +504,7 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level)
|
|||
OpenPICState *opp = opaque;
|
||||
IRQSource *src;
|
||||
|
||||
if (n_IRQ >= MAX_IRQ) {
|
||||
if (n_IRQ >= OPENPIC_MAX_IRQ) {
|
||||
fprintf(stderr, "%s: IRQ %d out of range\n", __func__, n_IRQ);
|
||||
abort();
|
||||
}
|
||||
|
@ -537,7 +538,7 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level)
|
|||
|
||||
static void openpic_reset(DeviceState *d)
|
||||
{
|
||||
OpenPICState *opp = FROM_SYSBUS(typeof(*opp), SYS_BUS_DEVICE(d));
|
||||
OpenPICState *opp = OPENPIC(d);
|
||||
int i;
|
||||
|
||||
opp->gcr = GCR_RESET;
|
||||
|
@ -576,7 +577,7 @@ static void openpic_reset(DeviceState *d)
|
|||
opp->dst[i].servicing.next = -1;
|
||||
}
|
||||
/* Initialise timers */
|
||||
for (i = 0; i < MAX_TMR; i++) {
|
||||
for (i = 0; i < OPENPIC_MAX_TMR; i++) {
|
||||
opp->timers[i].tccr = 0;
|
||||
opp->timers[i].tbcr = TBCR_CI;
|
||||
}
|
||||
|
@ -703,7 +704,7 @@ static void openpic_gcr_write(OpenPICState *opp, uint64_t val)
|
|||
bool mpic_proxy = false;
|
||||
|
||||
if (val & GCR_RESET) {
|
||||
openpic_reset(&opp->busdev.qdev);
|
||||
openpic_reset(DEVICE(opp));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1182,7 +1183,7 @@ static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu)
|
|||
IRQ_resetbit(&dst->raised, irq);
|
||||
}
|
||||
|
||||
if ((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + MAX_IPI))) {
|
||||
if ((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + OPENPIC_MAX_IPI))) {
|
||||
src->destmask &= ~(1 << cpu);
|
||||
if (src->destmask && !src->level) {
|
||||
/* trigger on CPUs that didn't know about it yet */
|
||||
|
@ -1381,7 +1382,7 @@ static void openpic_save(QEMUFile* f, void *opaque)
|
|||
sizeof(opp->dst[i].outputs_active));
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_TMR; i++) {
|
||||
for (i = 0; i < OPENPIC_MAX_TMR; i++) {
|
||||
qemu_put_be32s(f, &opp->timers[i].tccr);
|
||||
qemu_put_be32s(f, &opp->timers[i].tbcr);
|
||||
}
|
||||
|
@ -1440,7 +1441,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
|
|||
sizeof(opp->dst[i].outputs_active));
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_TMR; i++) {
|
||||
for (i = 0; i < OPENPIC_MAX_TMR; i++) {
|
||||
qemu_get_be32s(f, &opp->timers[i].tccr);
|
||||
qemu_get_be32s(f, &opp->timers[i].tbcr);
|
||||
}
|
||||
|
@ -1473,7 +1474,7 @@ typedef struct MemReg {
|
|||
static void fsl_common_init(OpenPICState *opp)
|
||||
{
|
||||
int i;
|
||||
int virq = MAX_SRC;
|
||||
int virq = OPENPIC_MAX_SRC;
|
||||
|
||||
opp->vid = VID_REVISION_1_2;
|
||||
opp->vir = VIR_GENERIC;
|
||||
|
@ -1481,14 +1482,14 @@ static void fsl_common_init(OpenPICState *opp)
|
|||
opp->tfrr_reset = 0;
|
||||
opp->ivpr_reset = IVPR_MASK_MASK;
|
||||
opp->idr_reset = 1 << 0;
|
||||
opp->max_irq = MAX_IRQ;
|
||||
opp->max_irq = OPENPIC_MAX_IRQ;
|
||||
|
||||
opp->irq_ipi0 = virq;
|
||||
virq += MAX_IPI;
|
||||
virq += OPENPIC_MAX_IPI;
|
||||
opp->irq_tim0 = virq;
|
||||
virq += MAX_TMR;
|
||||
virq += OPENPIC_MAX_TMR;
|
||||
|
||||
assert(virq <= MAX_IRQ);
|
||||
assert(virq <= OPENPIC_MAX_IRQ);
|
||||
|
||||
opp->irq_msi = 224;
|
||||
|
||||
|
@ -1498,13 +1499,13 @@ static void fsl_common_init(OpenPICState *opp)
|
|||
}
|
||||
|
||||
/* Internal interrupts, including message and MSI */
|
||||
for (i = 16; i < MAX_SRC; i++) {
|
||||
for (i = 16; i < OPENPIC_MAX_SRC; i++) {
|
||||
opp->src[i].type = IRQ_TYPE_FSLINT;
|
||||
opp->src[i].level = true;
|
||||
}
|
||||
|
||||
/* timers and IPIs */
|
||||
for (i = MAX_SRC; i < virq; i++) {
|
||||
for (i = OPENPIC_MAX_SRC; i < virq; i++) {
|
||||
opp->src[i].type = IRQ_TYPE_FSLSPECIAL;
|
||||
opp->src[i].level = false;
|
||||
}
|
||||
|
@ -1526,9 +1527,17 @@ static void map_list(OpenPICState *opp, const MemReg *list, int *count)
|
|||
}
|
||||
}
|
||||
|
||||
static int openpic_init(SysBusDevice *dev)
|
||||
static void openpic_init(Object *obj)
|
||||
{
|
||||
OpenPICState *opp = FROM_SYSBUS(typeof (*opp), dev);
|
||||
OpenPICState *opp = OPENPIC(obj);
|
||||
|
||||
memory_region_init(&opp->mem, "openpic", 0x40000);
|
||||
}
|
||||
|
||||
static void openpic_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
SysBusDevice *d = SYS_BUS_DEVICE(dev);
|
||||
OpenPICState *opp = OPENPIC(dev);
|
||||
int i, j;
|
||||
int list_count = 0;
|
||||
static const MemReg list_le[] = {
|
||||
|
@ -1561,8 +1570,6 @@ static int openpic_init(SysBusDevice *dev)
|
|||
{NULL}
|
||||
};
|
||||
|
||||
memory_region_init(&opp->mem, "openpic", 0x40000);
|
||||
|
||||
switch (opp->model) {
|
||||
case OPENPIC_MODEL_FSL_MPIC_20:
|
||||
default:
|
||||
|
@ -1605,9 +1612,9 @@ static int openpic_init(SysBusDevice *dev)
|
|||
opp->brr1 = -1;
|
||||
opp->mpic_mode_mask = GCR_MODE_MIXED;
|
||||
|
||||
/* Only UP supported today */
|
||||
if (opp->nb_cpus != 1) {
|
||||
return -EINVAL;
|
||||
error_setg(errp, "Only UP supported today");
|
||||
return;
|
||||
}
|
||||
|
||||
map_list(opp, list_le, &list_count);
|
||||
|
@ -1617,17 +1624,15 @@ static int openpic_init(SysBusDevice *dev)
|
|||
for (i = 0; i < opp->nb_cpus; i++) {
|
||||
opp->dst[i].irqs = g_new(qemu_irq, OPENPIC_OUTPUT_NB);
|
||||
for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
|
||||
sysbus_init_irq(dev, &opp->dst[i].irqs[j]);
|
||||
sysbus_init_irq(d, &opp->dst[i].irqs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
register_savevm(&opp->busdev.qdev, "openpic", 0, 2,
|
||||
register_savevm(dev, "openpic", 0, 2,
|
||||
openpic_save, openpic_load, opp);
|
||||
|
||||
sysbus_init_mmio(dev, &opp->mem);
|
||||
qdev_init_gpio_in(&dev->qdev, openpic_set_irq, opp->max_irq);
|
||||
|
||||
return 0;
|
||||
sysbus_init_mmio(d, &opp->mem);
|
||||
qdev_init_gpio_in(dev, openpic_set_irq, opp->max_irq);
|
||||
}
|
||||
|
||||
static Property openpic_properties[] = {
|
||||
|
@ -1636,20 +1641,20 @@ static Property openpic_properties[] = {
|
|||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void openpic_class_init(ObjectClass *klass, void *data)
|
||||
static void openpic_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
k->init = openpic_init;
|
||||
dc->realize = openpic_realize;
|
||||
dc->props = openpic_properties;
|
||||
dc->reset = openpic_reset;
|
||||
}
|
||||
|
||||
static const TypeInfo openpic_info = {
|
||||
.name = "openpic",
|
||||
.name = TYPE_OPENPIC,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(OpenPICState),
|
||||
.instance_init = openpic_init,
|
||||
.class_init = openpic_class_init,
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
* KVM in-kernel OpenPIC
|
||||
*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <sys/ioctl.h>
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/ppc/openpic.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
#define KVM_OPENPIC(obj) \
|
||||
OBJECT_CHECK(KVMOpenPICState, (obj), TYPE_KVM_OPENPIC)
|
||||
|
||||
typedef struct KVMOpenPICState {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
MemoryRegion mem;
|
||||
MemoryListener mem_listener;
|
||||
uint32_t fd;
|
||||
uint32_t model;
|
||||
} KVMOpenPICState;
|
||||
|
||||
static void kvm_openpic_set_irq(void *opaque, int n_IRQ, int level)
|
||||
{
|
||||
kvm_set_irq(kvm_state, n_IRQ, level);
|
||||
}
|
||||
|
||||
static void kvm_openpic_reset(DeviceState *d)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
|
||||
}
|
||||
|
||||
static void kvm_openpic_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
KVMOpenPICState *opp = opaque;
|
||||
struct kvm_device_attr attr;
|
||||
uint32_t val32 = val;
|
||||
int ret;
|
||||
|
||||
attr.group = KVM_DEV_MPIC_GRP_REGISTER;
|
||||
attr.attr = addr;
|
||||
attr.addr = (uint64_t)(unsigned long)&val32;
|
||||
|
||||
ret = ioctl(opp->fd, KVM_SET_DEVICE_ATTR, &attr);
|
||||
if (ret < 0) {
|
||||
qemu_log_mask(LOG_UNIMP, "%s: %s %" PRIx64 "\n", __func__,
|
||||
strerror(errno), attr.attr);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t kvm_openpic_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
KVMOpenPICState *opp = opaque;
|
||||
struct kvm_device_attr attr;
|
||||
uint32_t val = 0xdeadbeef;
|
||||
int ret;
|
||||
|
||||
attr.group = KVM_DEV_MPIC_GRP_REGISTER;
|
||||
attr.attr = addr;
|
||||
attr.addr = (uint64_t)(unsigned long)&val;
|
||||
|
||||
ret = ioctl(opp->fd, KVM_GET_DEVICE_ATTR, &attr);
|
||||
if (ret < 0) {
|
||||
qemu_log_mask(LOG_UNIMP, "%s: %s %" PRIx64 "\n", __func__,
|
||||
strerror(errno), attr.attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps kvm_openpic_mem_ops = {
|
||||
.write = kvm_openpic_write,
|
||||
.read = kvm_openpic_read,
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
.impl = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
};
|
||||
|
||||
static void kvm_openpic_region_add(MemoryListener *listener,
|
||||
MemoryRegionSection *section)
|
||||
{
|
||||
KVMOpenPICState *opp = container_of(listener, KVMOpenPICState,
|
||||
mem_listener);
|
||||
struct kvm_device_attr attr;
|
||||
uint64_t reg_base;
|
||||
int ret;
|
||||
|
||||
if (section->address_space != &address_space_memory) {
|
||||
abort();
|
||||
}
|
||||
|
||||
reg_base = section->offset_within_address_space;
|
||||
|
||||
attr.group = KVM_DEV_MPIC_GRP_MISC;
|
||||
attr.attr = KVM_DEV_MPIC_BASE_ADDR;
|
||||
attr.addr = (uint64_t)(unsigned long)®_base;
|
||||
|
||||
ret = ioctl(opp->fd, KVM_SET_DEVICE_ATTR, &attr);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "%s: %s %" PRIx64 "\n", __func__,
|
||||
strerror(errno), reg_base);
|
||||
}
|
||||
}
|
||||
|
||||
static void kvm_openpic_region_del(MemoryListener *listener,
|
||||
MemoryRegionSection *section)
|
||||
{
|
||||
KVMOpenPICState *opp = container_of(listener, KVMOpenPICState,
|
||||
mem_listener);
|
||||
struct kvm_device_attr attr;
|
||||
uint64_t reg_base = 0;
|
||||
int ret;
|
||||
|
||||
attr.group = KVM_DEV_MPIC_GRP_MISC;
|
||||
attr.attr = KVM_DEV_MPIC_BASE_ADDR;
|
||||
attr.addr = (uint64_t)(unsigned long)®_base;
|
||||
|
||||
ret = ioctl(opp->fd, KVM_SET_DEVICE_ATTR, &attr);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "%s: %s %" PRIx64 "\n", __func__,
|
||||
strerror(errno), reg_base);
|
||||
}
|
||||
}
|
||||
|
||||
static void kvm_openpic_init(Object *obj)
|
||||
{
|
||||
KVMOpenPICState *opp = KVM_OPENPIC(obj);
|
||||
|
||||
memory_region_init_io(&opp->mem, &kvm_openpic_mem_ops, opp,
|
||||
"kvm-openpic", 0x40000);
|
||||
}
|
||||
|
||||
static void kvm_openpic_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
SysBusDevice *d = SYS_BUS_DEVICE(dev);
|
||||
KVMOpenPICState *opp = KVM_OPENPIC(dev);
|
||||
KVMState *s = kvm_state;
|
||||
int kvm_openpic_model;
|
||||
struct kvm_create_device cd = {0};
|
||||
int ret, i;
|
||||
|
||||
if (!kvm_check_extension(s, KVM_CAP_DEVICE_CTRL)) {
|
||||
error_setg(errp, "Kernel is lacking Device Control API");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (opp->model) {
|
||||
case OPENPIC_MODEL_FSL_MPIC_20:
|
||||
kvm_openpic_model = KVM_DEV_TYPE_FSL_MPIC_20;
|
||||
break;
|
||||
|
||||
case OPENPIC_MODEL_FSL_MPIC_42:
|
||||
kvm_openpic_model = KVM_DEV_TYPE_FSL_MPIC_42;
|
||||
break;
|
||||
|
||||
default:
|
||||
error_setg(errp, "Unsupported OpenPIC model %" PRIu32, opp->model);
|
||||
return;
|
||||
}
|
||||
|
||||
cd.type = kvm_openpic_model;
|
||||
ret = kvm_vm_ioctl(s, KVM_CREATE_DEVICE, &cd);
|
||||
if (ret < 0) {
|
||||
error_setg(errp, "Can't create device %d: %s",
|
||||
cd.type, strerror(errno));
|
||||
return;
|
||||
}
|
||||
opp->fd = cd.fd;
|
||||
|
||||
sysbus_init_mmio(d, &opp->mem);
|
||||
qdev_init_gpio_in(dev, kvm_openpic_set_irq, OPENPIC_MAX_IRQ);
|
||||
|
||||
opp->mem_listener.region_add = kvm_openpic_region_add;
|
||||
opp->mem_listener.region_add = kvm_openpic_region_del;
|
||||
memory_listener_register(&opp->mem_listener, &address_space_memory);
|
||||
|
||||
/* indicate pic capabilities */
|
||||
msi_supported = true;
|
||||
kvm_kernel_irqchip = true;
|
||||
kvm_async_interrupts_allowed = true;
|
||||
|
||||
/* set up irq routing */
|
||||
kvm_init_irq_routing(kvm_state);
|
||||
for (i = 0; i < 256; ++i) {
|
||||
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
|
||||
}
|
||||
|
||||
kvm_irqfds_allowed = true;
|
||||
kvm_msi_via_irqfd_allowed = true;
|
||||
kvm_gsi_routing_allowed = true;
|
||||
|
||||
kvm_irqchip_commit_routes(s);
|
||||
}
|
||||
|
||||
int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs)
|
||||
{
|
||||
KVMOpenPICState *opp = KVM_OPENPIC(d);
|
||||
struct kvm_enable_cap encap = {};
|
||||
|
||||
encap.cap = KVM_CAP_IRQ_MPIC;
|
||||
encap.args[0] = opp->fd;
|
||||
encap.args[1] = cs->cpu_index;
|
||||
|
||||
return kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &encap);
|
||||
}
|
||||
|
||||
static Property kvm_openpic_properties[] = {
|
||||
DEFINE_PROP_UINT32("model", KVMOpenPICState, model,
|
||||
OPENPIC_MODEL_FSL_MPIC_20),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void kvm_openpic_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
dc->realize = kvm_openpic_realize;
|
||||
dc->props = kvm_openpic_properties;
|
||||
dc->reset = kvm_openpic_reset;
|
||||
}
|
||||
|
||||
static const TypeInfo kvm_openpic_info = {
|
||||
.name = TYPE_KVM_OPENPIC,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(KVMOpenPICState),
|
||||
.instance_init = kvm_openpic_init,
|
||||
.class_init = kvm_openpic_class_init,
|
||||
};
|
||||
|
||||
static void kvm_openpic_register_types(void)
|
||||
{
|
||||
type_register_static(&kvm_openpic_info);
|
||||
}
|
||||
|
||||
type_init(kvm_openpic_register_types)
|
|
@ -69,12 +69,59 @@ typedef struct NewWorldMacIOState {
|
|||
MACIOIDEState ide[2];
|
||||
} NewWorldMacIOState;
|
||||
|
||||
/*
|
||||
* The mac-io has two interfaces to the ESCC. One is called "escc-legacy",
|
||||
* while the other one is the normal, current ESCC interface.
|
||||
*
|
||||
* The magic below creates memory aliases to spawn the escc-legacy device
|
||||
* purely by rerouting the respective registers to our escc region. This
|
||||
* works because the only difference between the two memory regions is the
|
||||
* register layout, not their semantics.
|
||||
*
|
||||
* Reference: ftp://ftp.software.ibm.com/rs6000/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf
|
||||
*/
|
||||
static void macio_escc_legacy_setup(MacIOState *macio_state)
|
||||
{
|
||||
MemoryRegion *escc_legacy = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *bar = &macio_state->bar;
|
||||
int i;
|
||||
static const int maps[] = {
|
||||
0x00, 0x00,
|
||||
0x02, 0x20,
|
||||
0x04, 0x10,
|
||||
0x06, 0x30,
|
||||
0x08, 0x40,
|
||||
0x0A, 0x50,
|
||||
0x60, 0x60,
|
||||
0x70, 0x70,
|
||||
0x80, 0x70,
|
||||
0x90, 0x80,
|
||||
0xA0, 0x90,
|
||||
0xB0, 0xA0,
|
||||
0xC0, 0xB0,
|
||||
0xD0, 0xC0,
|
||||
0xE0, 0xD0,
|
||||
0xF0, 0xE0,
|
||||
};
|
||||
|
||||
memory_region_init(escc_legacy, "escc-legacy", 256);
|
||||
for (i = 0; i < ARRAY_SIZE(maps); i += 2) {
|
||||
MemoryRegion *port = g_new(MemoryRegion, 1);
|
||||
memory_region_init_alias(port, "escc-legacy-port", macio_state->escc_mem,
|
||||
maps[i+1], 0x2);
|
||||
memory_region_add_subregion(escc_legacy, maps[i], port);
|
||||
}
|
||||
|
||||
memory_region_add_subregion(bar, 0x12000, escc_legacy);
|
||||
}
|
||||
|
||||
static void macio_bar_setup(MacIOState *macio_state)
|
||||
{
|
||||
MemoryRegion *bar = &macio_state->bar;
|
||||
|
||||
if (macio_state->escc_mem) {
|
||||
memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
|
||||
macio_escc_legacy_setup(macio_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef struct sPAPRNVRAM {
|
|||
#define DEFAULT_NVRAM_SIZE 65536
|
||||
#define MAX_NVRAM_SIZE (UINT16_MAX * 16)
|
||||
|
||||
static void rtas_nvram_fetch(sPAPREnvironment *spapr,
|
||||
static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -91,7 +91,7 @@ static void rtas_nvram_fetch(sPAPREnvironment *spapr,
|
|||
rtas_st(rets, 1, (alen < 0) ? 0 : alen);
|
||||
}
|
||||
|
||||
static void rtas_nvram_store(sPAPREnvironment *spapr,
|
||||
static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
|
125
hw/ppc/e500.c
125
hw/ppc/e500.c
|
@ -472,6 +472,107 @@ static void ppce500_cpu_reset(void *opaque)
|
|||
mmubooke_create_initial_mapping(env);
|
||||
}
|
||||
|
||||
static DeviceState *ppce500_init_mpic_qemu(PPCE500Params *params,
|
||||
qemu_irq **irqs)
|
||||
{
|
||||
DeviceState *dev;
|
||||
SysBusDevice *s;
|
||||
int i, j, k;
|
||||
|
||||
dev = qdev_create(NULL, TYPE_OPENPIC);
|
||||
qdev_prop_set_uint32(dev, "model", params->mpic_version);
|
||||
qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);
|
||||
|
||||
qdev_init_nofail(dev);
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
|
||||
sysbus_connect_irq(s, k++, irqs[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
|
||||
qemu_irq **irqs)
|
||||
{
|
||||
DeviceState *dev;
|
||||
CPUPPCState *env;
|
||||
CPUState *cs;
|
||||
int r;
|
||||
|
||||
dev = qdev_create(NULL, TYPE_KVM_OPENPIC);
|
||||
qdev_prop_set_uint32(dev, "model", params->mpic_version);
|
||||
|
||||
r = qdev_init(dev);
|
||||
if (r) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (env = first_cpu; env != NULL; env = env->next_cpu) {
|
||||
cs = ENV_GET_CPU(env);
|
||||
|
||||
if (kvm_openpic_connect_vcpu(dev, cs)) {
|
||||
fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
|
||||
__func__);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr,
|
||||
qemu_irq **irqs)
|
||||
{
|
||||
QemuOptsList *list;
|
||||
qemu_irq *mpic;
|
||||
DeviceState *dev = NULL;
|
||||
SysBusDevice *s;
|
||||
int i;
|
||||
|
||||
mpic = g_new(qemu_irq, 256);
|
||||
|
||||
if (kvm_enabled()) {
|
||||
bool irqchip_allowed = true, irqchip_required = false;
|
||||
|
||||
list = qemu_find_opts("machine");
|
||||
if (!QTAILQ_EMPTY(&list->head)) {
|
||||
irqchip_allowed = qemu_opt_get_bool(QTAILQ_FIRST(&list->head),
|
||||
"kernel_irqchip", true);
|
||||
irqchip_required = qemu_opt_get_bool(QTAILQ_FIRST(&list->head),
|
||||
"kernel_irqchip", false);
|
||||
}
|
||||
|
||||
if (irqchip_allowed) {
|
||||
dev = ppce500_init_mpic_kvm(params, irqs);
|
||||
}
|
||||
|
||||
if (irqchip_required && !dev) {
|
||||
fprintf(stderr, "%s: irqchip requested but unavailable\n",
|
||||
__func__);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev) {
|
||||
dev = ppce500_init_mpic_qemu(params, irqs);
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
mpic[i] = qdev_get_gpio_in(dev, i);
|
||||
}
|
||||
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
memory_region_add_subregion(ccsr, MPC8544_MPIC_REGS_OFFSET,
|
||||
s->mmio[0].memory);
|
||||
|
||||
return mpic;
|
||||
}
|
||||
|
||||
void ppce500_init(PPCE500Params *params)
|
||||
{
|
||||
MemoryRegion *address_space_mem = get_system_memory();
|
||||
|
@ -487,7 +588,7 @@ void ppce500_init(PPCE500Params *params)
|
|||
target_ulong initrd_base = 0;
|
||||
target_long initrd_size = 0;
|
||||
target_ulong cur_base = 0;
|
||||
int i = 0, j, k;
|
||||
int i;
|
||||
unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
|
||||
qemu_irq **irqs, *mpic;
|
||||
DeviceState *dev;
|
||||
|
@ -563,27 +664,7 @@ void ppce500_init(PPCE500Params *params)
|
|||
memory_region_add_subregion(address_space_mem, MPC8544_CCSRBAR_BASE,
|
||||
ccsr_addr_space);
|
||||
|
||||
/* MPIC */
|
||||
mpic = g_new(qemu_irq, 256);
|
||||
dev = qdev_create(NULL, "openpic");
|
||||
qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);
|
||||
qdev_prop_set_uint32(dev, "model", params->mpic_version);
|
||||
qdev_init_nofail(dev);
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
|
||||
sysbus_connect_irq(s, k++, irqs[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
mpic[i] = qdev_get_gpio_in(dev, i);
|
||||
}
|
||||
|
||||
memory_region_add_subregion(ccsr_addr_space, MPC8544_MPIC_REGS_OFFSET,
|
||||
s->mmio[0].memory);
|
||||
mpic = ppce500_init_mpic(params, ccsr_addr_space, irqs);
|
||||
|
||||
/* Serial */
|
||||
if (serial_hds[0]) {
|
||||
|
|
|
@ -87,6 +87,9 @@ static void unin_write(void *opaque, hwaddr addr, uint64_t value,
|
|||
unsigned size)
|
||||
{
|
||||
UNIN_DPRINTF("write addr " TARGET_FMT_plx " val %"PRIx64"\n", addr, value);
|
||||
if (addr == 0x0) {
|
||||
*(int*)opaque = value;
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size)
|
||||
|
@ -94,6 +97,11 @@ static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size)
|
|||
uint32_t value;
|
||||
|
||||
value = 0;
|
||||
switch (addr) {
|
||||
case 0:
|
||||
value = *(int*)opaque;
|
||||
}
|
||||
|
||||
UNIN_DPRINTF("readl addr " TARGET_FMT_plx " val %x\n", addr, value);
|
||||
|
||||
return value;
|
||||
|
@ -144,6 +152,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
|||
char *filename;
|
||||
qemu_irq *pic, **openpic_irqs;
|
||||
MemoryRegion *unin_memory = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *unin2_memory = g_new(MemoryRegion, 1);
|
||||
int linux_boot, i, j, k;
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1);
|
||||
hwaddr kernel_base, initrd_base, cmdline_base = 0;
|
||||
|
@ -162,6 +171,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
|||
int machine_arch;
|
||||
SysBusDevice *s;
|
||||
DeviceState *dev;
|
||||
int *token = g_new(int, 1);
|
||||
|
||||
linux_boot = (kernel_filename != NULL);
|
||||
|
||||
|
@ -279,10 +289,13 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
|||
/* Register 8 MB of ISA IO space */
|
||||
isa_mmio_init(0xf2000000, 0x00800000);
|
||||
|
||||
/* UniN init */
|
||||
memory_region_init_io(unin_memory, &unin_ops, NULL, "unin", 0x1000);
|
||||
/* UniN init: XXX should be a real device */
|
||||
memory_region_init_io(unin_memory, &unin_ops, token, "unin", 0x1000);
|
||||
memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);
|
||||
|
||||
memory_region_init_io(unin2_memory, &unin_ops, token, "unin", 0x1000);
|
||||
memory_region_add_subregion(get_system_memory(), 0xf3000000, unin2_memory);
|
||||
|
||||
openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
|
||||
openpic_irqs[0] =
|
||||
g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
|
||||
|
@ -329,7 +342,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
|||
|
||||
pic = g_new(qemu_irq, 64);
|
||||
|
||||
dev = qdev_create(NULL, "openpic");
|
||||
dev = qdev_create(NULL, TYPE_OPENPIC);
|
||||
qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_RAVEN);
|
||||
qdev_init_nofail(dev);
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
|
@ -449,6 +462,8 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
|||
} else {
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
|
||||
}
|
||||
/* Mac OS X requires a "known good" clock-frequency value; pass it one. */
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, 266000000);
|
||||
|
||||
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
|
||||
}
|
||||
|
@ -458,9 +473,6 @@ static QEMUMachine core99_machine = {
|
|||
.desc = "Mac99 based PowerMAC",
|
||||
.init = ppc_core99_init,
|
||||
.max_cpus = MAX_CPUS,
|
||||
#ifdef TARGET_PPC64
|
||||
.is_default = 1,
|
||||
#endif
|
||||
DEFAULT_MACHINE_OPTIONS,
|
||||
};
|
||||
|
||||
|
|
|
@ -333,6 +333,8 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
|
|||
} else {
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
|
||||
}
|
||||
/* Mac OS X requires a "known good" clock-frequency value; pass it one. */
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, 266000000);
|
||||
|
||||
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
|
||||
}
|
||||
|
|
|
@ -51,8 +51,14 @@
|
|||
#define MPC8544_GUTS_ADDR_SRDS2CR1 0xF10
|
||||
#define MPC8544_GUTS_ADDR_SRDS2CR3 0xF18
|
||||
|
||||
#define TYPE_MPC8544_GUTS "mpc8544-guts"
|
||||
#define MPC8544_GUTS(obj) OBJECT_CHECK(GutsState, (obj), TYPE_MPC8544_GUTS)
|
||||
|
||||
struct GutsState {
|
||||
SysBusDevice busdev;
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
MemoryRegion iomem;
|
||||
};
|
||||
|
||||
|
@ -108,31 +114,21 @@ static const MemoryRegionOps mpc8544_guts_ops = {
|
|||
},
|
||||
};
|
||||
|
||||
static int mpc8544_guts_initfn(SysBusDevice *dev)
|
||||
static void mpc8544_guts_initfn(Object *obj)
|
||||
{
|
||||
GutsState *s;
|
||||
|
||||
s = FROM_SYSBUS(GutsState, SYS_BUS_DEVICE(dev));
|
||||
SysBusDevice *d = SYS_BUS_DEVICE(obj);
|
||||
GutsState *s = MPC8544_GUTS(obj);
|
||||
|
||||
memory_region_init_io(&s->iomem, &mpc8544_guts_ops, s,
|
||||
"mpc6544.guts", MPC8544_GUTS_MMIO_SIZE);
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mpc8544_guts_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = mpc8544_guts_initfn;
|
||||
"mpc8544.guts", MPC8544_GUTS_MMIO_SIZE);
|
||||
sysbus_init_mmio(d, &s->iomem);
|
||||
}
|
||||
|
||||
static const TypeInfo mpc8544_guts_info = {
|
||||
.name = "mpc8544-guts",
|
||||
.name = TYPE_MPC8544_GUTS,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(GutsState),
|
||||
.class_init = mpc8544_guts_class_init,
|
||||
.instance_init = mpc8544_guts_initfn,
|
||||
};
|
||||
|
||||
static void mpc8544_guts_register_types(void)
|
||||
|
|
|
@ -131,17 +131,33 @@ static void booke_update_fixed_timer(CPUPPCState *env,
|
|||
struct QEMUTimer *timer)
|
||||
{
|
||||
ppc_tb_t *tb_env = env->tb_env;
|
||||
uint64_t lapse;
|
||||
uint64_t delta_tick, ticks = 0;
|
||||
uint64_t tb;
|
||||
uint64_t period = 1 << (target_bit + 1);
|
||||
uint64_t period;
|
||||
uint64_t now;
|
||||
|
||||
now = qemu_get_clock_ns(vm_clock);
|
||||
tb = cpu_ppc_get_tb(tb_env, now, tb_env->tb_offset);
|
||||
period = 1ULL << target_bit;
|
||||
delta_tick = period - (tb & (period - 1));
|
||||
|
||||
lapse = period - ((tb - (1 << target_bit)) & (period - 1));
|
||||
/* the timer triggers only when the selected bit toggles from 0 to 1 */
|
||||
if (tb & period) {
|
||||
ticks = period;
|
||||
}
|
||||
|
||||
*next = now + muldiv64(lapse, get_ticks_per_sec(), tb_env->tb_freq);
|
||||
if (ticks + delta_tick < ticks) {
|
||||
/* Overflow, so assume the biggest number we can express. */
|
||||
ticks = UINT64_MAX;
|
||||
} else {
|
||||
ticks += delta_tick;
|
||||
}
|
||||
|
||||
*next = now + muldiv64(ticks, get_ticks_per_sec(), tb_env->tb_freq);
|
||||
if ((*next < now) || (*next > INT64_MAX)) {
|
||||
/* Overflow, so assume the biggest number the qemu timer supports. */
|
||||
*next = INT64_MAX;
|
||||
}
|
||||
|
||||
/* XXX: If expire time is now. We can't run the callback because we don't
|
||||
* have access to it. So we just set the timer one nanosecond later.
|
||||
|
|
|
@ -670,7 +670,7 @@ static void spapr_cpu_reset(void *opaque)
|
|||
env->external_htab = spapr->htab;
|
||||
env->htab_base = -1;
|
||||
env->htab_mask = HTAB_SIZE(spapr) - 1;
|
||||
env->spr[SPR_SDR1] = (unsigned long)spapr->htab |
|
||||
env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab |
|
||||
(spapr->htab_shift - 18);
|
||||
}
|
||||
|
||||
|
@ -971,6 +971,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
|
|||
static QEMUMachine spapr_machine = {
|
||||
.name = "pseries",
|
||||
.desc = "pSeries Logical Partition (PAPR compliant)",
|
||||
.is_default = 1,
|
||||
.init = ppc_spapr_init,
|
||||
.reset = ppc_spapr_reset,
|
||||
.block_default_type = IF_SCSI,
|
||||
|
|
|
@ -277,7 +277,7 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
|
|||
qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->epow_irq));
|
||||
}
|
||||
|
||||
static void check_exception(sPAPREnvironment *spapr,
|
||||
static void check_exception(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
|
|
@ -525,7 +525,7 @@ static target_ulong h_rtas(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
|||
uint32_t nargs = ldl_be_phys(rtas_r3 + 4);
|
||||
uint32_t nret = ldl_be_phys(rtas_r3 + 8);
|
||||
|
||||
return spapr_rtas_call(spapr, token, nargs, rtas_r3 + 12,
|
||||
return spapr_rtas_call(cpu, spapr, token, nargs, rtas_r3 + 12,
|
||||
nret, rtas_r3 + 12 + 4*nargs);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ static void finish_read_pci_config(sPAPREnvironment *spapr, uint64_t buid,
|
|||
rtas_st(rets, 1, val);
|
||||
}
|
||||
|
||||
static void rtas_ibm_read_pci_config(sPAPREnvironment *spapr,
|
||||
static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -139,7 +139,7 @@ static void rtas_ibm_read_pci_config(sPAPREnvironment *spapr,
|
|||
finish_read_pci_config(spapr, buid, addr, size, rets);
|
||||
}
|
||||
|
||||
static void rtas_read_pci_config(sPAPREnvironment *spapr,
|
||||
static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -185,7 +185,7 @@ static void finish_write_pci_config(sPAPREnvironment *spapr, uint64_t buid,
|
|||
rtas_st(rets, 0, 0);
|
||||
}
|
||||
|
||||
static void rtas_ibm_write_pci_config(sPAPREnvironment *spapr,
|
||||
static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -206,7 +206,7 @@ static void rtas_ibm_write_pci_config(sPAPREnvironment *spapr,
|
|||
finish_write_pci_config(spapr, buid, addr, size, val, rets);
|
||||
}
|
||||
|
||||
static void rtas_write_pci_config(sPAPREnvironment *spapr,
|
||||
static void rtas_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -277,7 +277,7 @@ static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr,
|
|||
}
|
||||
}
|
||||
|
||||
static void rtas_ibm_change_msi(sPAPREnvironment *spapr,
|
||||
static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
|
@ -374,7 +374,8 @@ static void rtas_ibm_change_msi(sPAPREnvironment *spapr,
|
|||
trace_spapr_pci_rtas_ibm_change_msi(func, req_num);
|
||||
}
|
||||
|
||||
static void rtas_ibm_query_interrupt_source_number(sPAPREnvironment *spapr,
|
||||
static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
|
||||
sPAPREnvironment *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs,
|
||||
target_ulong args,
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define TOKEN_BASE 0x2000
|
||||
#define TOKEN_MAX 0x100
|
||||
|
||||
static void rtas_display_character(sPAPREnvironment *spapr,
|
||||
static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -54,7 +54,7 @@ static void rtas_display_character(sPAPREnvironment *spapr,
|
|||
}
|
||||
}
|
||||
|
||||
static void rtas_get_time_of_day(sPAPREnvironment *spapr,
|
||||
static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -78,7 +78,7 @@ static void rtas_get_time_of_day(sPAPREnvironment *spapr,
|
|||
rtas_st(rets, 7, 0); /* we don't do nanoseconds */
|
||||
}
|
||||
|
||||
static void rtas_set_time_of_day(sPAPREnvironment *spapr,
|
||||
static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -99,7 +99,7 @@ static void rtas_set_time_of_day(sPAPREnvironment *spapr,
|
|||
rtas_st(rets, 0, 0); /* Success */
|
||||
}
|
||||
|
||||
static void rtas_power_off(sPAPREnvironment *spapr,
|
||||
static void rtas_power_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
|
@ -111,7 +111,7 @@ static void rtas_power_off(sPAPREnvironment *spapr,
|
|||
rtas_st(rets, 0, 0);
|
||||
}
|
||||
|
||||
static void rtas_system_reboot(sPAPREnvironment *spapr,
|
||||
static void rtas_system_reboot(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -124,7 +124,8 @@ static void rtas_system_reboot(sPAPREnvironment *spapr,
|
|||
rtas_st(rets, 0, 0);
|
||||
}
|
||||
|
||||
static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
|
||||
static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
|
||||
sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -154,7 +155,7 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
|
|||
rtas_st(rets, 0, -3);
|
||||
}
|
||||
|
||||
static void rtas_start_cpu(sPAPREnvironment *spapr,
|
||||
static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
|
@ -208,7 +209,7 @@ static struct rtas_call {
|
|||
|
||||
struct rtas_call *rtas_next = rtas_table;
|
||||
|
||||
target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
|
||||
target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
|
@ -217,7 +218,7 @@ target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
|
|||
struct rtas_call *call = rtas_table + (token - TOKEN_BASE);
|
||||
|
||||
if (call->fn) {
|
||||
call->fn(spapr, token, nargs, args, nret, rets);
|
||||
call->fn(cpu, spapr, token, nargs, args, nret, rets);
|
||||
return H_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -227,7 +228,7 @@ target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
|
|||
* machines) without looking it up in the device tree. This
|
||||
* special case makes this work */
|
||||
if (token == 0xa) {
|
||||
rtas_display_character(spapr, 0xa, nargs, args, nret, rets);
|
||||
rtas_display_character(cpu, spapr, 0xa, nargs, args, nret, rets);
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -321,7 +321,8 @@ static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev)
|
|||
free_crq(dev);
|
||||
}
|
||||
|
||||
static void rtas_set_tce_bypass(sPAPREnvironment *spapr, uint32_t token,
|
||||
static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
|
@ -351,7 +352,8 @@ static void rtas_set_tce_bypass(sPAPREnvironment *spapr, uint32_t token,
|
|||
rtas_st(rets, 0, 0);
|
||||
}
|
||||
|
||||
static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
|
||||
static void rtas_quiesce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
|
|
|
@ -400,7 +400,8 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
|||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static void rtas_set_xive(sPAPREnvironment *spapr, uint32_t token,
|
||||
static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
|
@ -427,7 +428,8 @@ static void rtas_set_xive(sPAPREnvironment *spapr, uint32_t token,
|
|||
rtas_st(rets, 0, 0); /* Success */
|
||||
}
|
||||
|
||||
static void rtas_get_xive(sPAPREnvironment *spapr, uint32_t token,
|
||||
static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
|
@ -451,7 +453,8 @@ static void rtas_get_xive(sPAPREnvironment *spapr, uint32_t token,
|
|||
rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
|
||||
}
|
||||
|
||||
static void rtas_int_off(sPAPREnvironment *spapr, uint32_t token,
|
||||
static void rtas_int_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
|
@ -476,7 +479,8 @@ static void rtas_int_off(sPAPREnvironment *spapr, uint32_t token,
|
|||
rtas_st(rets, 0, 0); /* Success */
|
||||
}
|
||||
|
||||
static void rtas_int_on(sPAPREnvironment *spapr, uint32_t token,
|
||||
static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#if !defined(__OPENPIC_H__)
|
||||
#define __OPENPIC_H__
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "hw/qdev.h"
|
||||
|
||||
#define TYPE_OPENPIC "openpic"
|
||||
|
||||
/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
|
||||
enum {
|
||||
OPENPIC_OUTPUT_INT = 0, /* IRQ */
|
||||
|
@ -15,4 +20,13 @@ enum {
|
|||
#define OPENPIC_MODEL_FSL_MPIC_20 1
|
||||
#define OPENPIC_MODEL_FSL_MPIC_42 2
|
||||
|
||||
#define OPENPIC_MAX_SRC 256
|
||||
#define OPENPIC_MAX_TMR 4
|
||||
#define OPENPIC_MAX_IPI 4
|
||||
#define OPENPIC_MAX_IRQ (OPENPIC_MAX_SRC + OPENPIC_MAX_IPI + \
|
||||
OPENPIC_MAX_TMR)
|
||||
|
||||
#define TYPE_KVM_OPENPIC "kvm-openpic"
|
||||
int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs);
|
||||
|
||||
#endif /* __OPENPIC_H__ */
|
||||
|
|
|
@ -87,6 +87,7 @@ enum {
|
|||
#define FW_CFG_PPC_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
|
||||
#define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02)
|
||||
#define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03)
|
||||
#define FW_CFG_PPC_CLOCKFREQ (FW_CFG_ARCH_LOCAL + 0x04)
|
||||
#define FW_CFG_PPC_IS_KVM (FW_CFG_ARCH_LOCAL + 0x05)
|
||||
#define FW_CFG_PPC_KVM_HC (FW_CFG_ARCH_LOCAL + 0x06)
|
||||
#define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07)
|
||||
|
|
|
@ -319,11 +319,12 @@ static inline void rtas_st(target_ulong phys, int n, uint32_t val)
|
|||
stl_be_phys(phys + 4*n, val);
|
||||
}
|
||||
|
||||
typedef void (*spapr_rtas_fn)(sPAPREnvironment *spapr, uint32_t token,
|
||||
typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets);
|
||||
int spapr_rtas_register(const char *name, spapr_rtas_fn fn);
|
||||
target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
|
||||
target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets);
|
||||
int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
extern bool kvm_allowed;
|
||||
extern bool kvm_kernel_irqchip;
|
||||
extern bool kvm_async_interrupts_allowed;
|
||||
extern bool kvm_halt_in_kernel_allowed;
|
||||
extern bool kvm_irqfds_allowed;
|
||||
extern bool kvm_msi_via_irqfd_allowed;
|
||||
extern bool kvm_gsi_routing_allowed;
|
||||
|
@ -72,6 +73,14 @@ extern bool kvm_readonly_mem_allowed;
|
|||
*/
|
||||
#define kvm_async_interrupts_enabled() (kvm_async_interrupts_allowed)
|
||||
|
||||
/**
|
||||
* kvm_halt_in_kernel
|
||||
*
|
||||
* Returns: true if halted cpus should still get a KVM_RUN ioctl to run
|
||||
* inside of kernel space. This only works if MP state is implemented.
|
||||
*/
|
||||
#define kvm_halt_in_kernel() (kvm_halt_in_kernel_allowed)
|
||||
|
||||
/**
|
||||
* kvm_irqfds_enabled:
|
||||
*
|
||||
|
@ -110,6 +119,7 @@ extern bool kvm_readonly_mem_allowed;
|
|||
#define kvm_enabled() (0)
|
||||
#define kvm_irqchip_in_kernel() (false)
|
||||
#define kvm_async_interrupts_enabled() (false)
|
||||
#define kvm_halt_in_kernel() (false)
|
||||
#define kvm_irqfds_enabled() (false)
|
||||
#define kvm_msi_via_irqfd_enabled() (false)
|
||||
#define kvm_gsi_routing_allowed() (false)
|
||||
|
@ -220,6 +230,7 @@ int kvm_set_irq(KVMState *s, int irq, int level);
|
|||
int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
|
||||
|
||||
void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
|
||||
void kvm_irqchip_commit_routes(KVMState *s);
|
||||
|
||||
void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
|
||||
void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
|
||||
|
@ -302,4 +313,5 @@ int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);
|
|||
int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);
|
||||
void kvm_pc_gsi_handler(void *opaque, int n, int level);
|
||||
void kvm_pc_setup_irq_routing(bool pci_enabled);
|
||||
void kvm_init_irq_routing(KVMState *s);
|
||||
#endif
|
||||
|
|
22
kvm-all.c
22
kvm-all.c
|
@ -107,6 +107,7 @@ struct KVMState
|
|||
KVMState *kvm_state;
|
||||
bool kvm_kernel_irqchip;
|
||||
bool kvm_async_interrupts_allowed;
|
||||
bool kvm_halt_in_kernel_allowed;
|
||||
bool kvm_irqfds_allowed;
|
||||
bool kvm_msi_via_irqfd_allowed;
|
||||
bool kvm_gsi_routing_allowed;
|
||||
|
@ -953,7 +954,7 @@ static void clear_gsi(KVMState *s, unsigned int gsi)
|
|||
s->used_gsi_bitmap[gsi / 32] &= ~(1U << (gsi % 32));
|
||||
}
|
||||
|
||||
static void kvm_init_irq_routing(KVMState *s)
|
||||
void kvm_init_irq_routing(KVMState *s)
|
||||
{
|
||||
int gsi_count, i;
|
||||
|
||||
|
@ -984,7 +985,7 @@ static void kvm_init_irq_routing(KVMState *s)
|
|||
kvm_arch_init_irq_routing(s);
|
||||
}
|
||||
|
||||
static void kvm_irqchip_commit_routes(KVMState *s)
|
||||
void kvm_irqchip_commit_routes(KVMState *s)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -1018,8 +1019,6 @@ static void kvm_add_routing_entry(KVMState *s,
|
|||
new->u = entry->u;
|
||||
|
||||
set_gsi(s, entry->gsi);
|
||||
|
||||
kvm_irqchip_commit_routes(s);
|
||||
}
|
||||
|
||||
static int kvm_update_routing_entry(KVMState *s,
|
||||
|
@ -1130,7 +1129,7 @@ static KVMMSIRoute *kvm_lookup_msi_route(KVMState *s, MSIMessage msg)
|
|||
QTAILQ_FOREACH(route, &s->msi_hashtab[hash], entry) {
|
||||
if (route->kroute.u.msi.address_lo == (uint32_t)msg.address &&
|
||||
route->kroute.u.msi.address_hi == (msg.address >> 32) &&
|
||||
route->kroute.u.msi.data == msg.data) {
|
||||
route->kroute.u.msi.data == le32_to_cpu(msg.data)) {
|
||||
return route;
|
||||
}
|
||||
}
|
||||
|
@ -1145,7 +1144,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
|
|||
if (s->direct_msi) {
|
||||
msi.address_lo = (uint32_t)msg.address;
|
||||
msi.address_hi = msg.address >> 32;
|
||||
msi.data = msg.data;
|
||||
msi.data = le32_to_cpu(msg.data);
|
||||
msi.flags = 0;
|
||||
memset(msi.pad, 0, sizeof(msi.pad));
|
||||
|
||||
|
@ -1167,9 +1166,10 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
|
|||
route->kroute.flags = 0;
|
||||
route->kroute.u.msi.address_lo = (uint32_t)msg.address;
|
||||
route->kroute.u.msi.address_hi = msg.address >> 32;
|
||||
route->kroute.u.msi.data = msg.data;
|
||||
route->kroute.u.msi.data = le32_to_cpu(msg.data);
|
||||
|
||||
kvm_add_routing_entry(s, &route->kroute);
|
||||
kvm_irqchip_commit_routes(s);
|
||||
|
||||
QTAILQ_INSERT_TAIL(&s->msi_hashtab[kvm_hash_msi(msg.data)], route,
|
||||
entry);
|
||||
|
@ -1199,9 +1199,10 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
|
|||
kroute.flags = 0;
|
||||
kroute.u.msi.address_lo = (uint32_t)msg.address;
|
||||
kroute.u.msi.address_hi = msg.address >> 32;
|
||||
kroute.u.msi.data = msg.data;
|
||||
kroute.u.msi.data = le32_to_cpu(msg.data);
|
||||
|
||||
kvm_add_routing_entry(s, &kroute);
|
||||
kvm_irqchip_commit_routes(s);
|
||||
|
||||
return virq;
|
||||
}
|
||||
|
@ -1219,7 +1220,7 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
|
|||
kroute.flags = 0;
|
||||
kroute.u.msi.address_lo = (uint32_t)msg.address;
|
||||
kroute.u.msi.address_hi = msg.address >> 32;
|
||||
kroute.u.msi.data = msg.data;
|
||||
kroute.u.msi.data = le32_to_cpu(msg.data);
|
||||
|
||||
return kvm_update_routing_entry(s, &kroute);
|
||||
}
|
||||
|
@ -1241,7 +1242,7 @@ static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
|
|||
|
||||
#else /* !KVM_CAP_IRQ_ROUTING */
|
||||
|
||||
static void kvm_init_irq_routing(KVMState *s)
|
||||
void kvm_init_irq_routing(KVMState *s)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1303,6 +1304,7 @@ static int kvm_irqchip_create(KVMState *s)
|
|||
* interrupt delivery (though the reverse is not necessarily true)
|
||||
*/
|
||||
kvm_async_interrupts_allowed = true;
|
||||
kvm_halt_in_kernel_allowed = true;
|
||||
|
||||
kvm_init_irq_routing(s);
|
||||
|
||||
|
|
|
@ -122,6 +122,10 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
|
|||
return -ENOSYS;
|
||||
}
|
||||
|
||||
void kvm_init_irq_routing(KVMState *s)
|
||||
{
|
||||
}
|
||||
|
||||
void kvm_irqchip_release_virq(KVMState *s, int virq)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ obj-y += machine.o mmu_helper.o mmu-hash32.o
|
|||
obj-$(TARGET_PPC64) += mmu-hash64.o
|
||||
endif
|
||||
obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
|
||||
obj-$(CONFIG_NO_KVM) += kvm-stub.o
|
||||
obj-y += excp_helper.o
|
||||
obj-y += fpu_helper.o
|
||||
obj-y += int_helper.o
|
||||
|
|
|
@ -1227,7 +1227,7 @@
|
|||
/***************************************************************************/
|
||||
/* PowerPC CPU aliases */
|
||||
|
||||
const PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
{ "403", "403GC" },
|
||||
{ "405", "405D4" },
|
||||
{ "405CR", "405CRc" },
|
||||
|
|
|
@ -31,9 +31,10 @@
|
|||
typedef struct PowerPCCPUAlias {
|
||||
const char *alias;
|
||||
const char *model;
|
||||
ObjectClass *oc;
|
||||
} PowerPCCPUAlias;
|
||||
|
||||
extern const PowerPCCPUAlias ppc_cpu_aliases[];
|
||||
extern PowerPCCPUAlias ppc_cpu_aliases[];
|
||||
|
||||
/*****************************************************************************/
|
||||
/* PVR definitions for most known PowerPC */
|
||||
|
|
|
@ -886,6 +886,8 @@ struct ppc_segment_page_sizes {
|
|||
/* The whole PowerPC CPU context */
|
||||
#define NB_MMU_MODES 3
|
||||
|
||||
#define PPC_CPU_OPCODES_LEN 0x40
|
||||
|
||||
struct CPUPPCState {
|
||||
/* First are the most commonly used resources
|
||||
* during translated code execution
|
||||
|
@ -1039,7 +1041,7 @@ struct CPUPPCState {
|
|||
|
||||
/* Those resources are used only during code translation */
|
||||
/* opcode handlers */
|
||||
opc_handler_t *opcodes[0x40];
|
||||
opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN];
|
||||
|
||||
/* Those resources are used only in QEMU core */
|
||||
target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* QEMU KVM PPC specific function stubs
|
||||
*
|
||||
* Copyright Freescale Inc. 2013
|
||||
*
|
||||
* Author: Alexander Graf <agraf@suse.de>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "hw/ppc/openpic.h"
|
||||
|
||||
int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
|
@ -791,6 +791,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
|||
for (i = 0;i < 32; i++)
|
||||
regs.gpr[i] = env->gpr[i];
|
||||
|
||||
regs.cr = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
regs.cr |= (env->crf[i] & 15) << (4 * (7 - i));
|
||||
}
|
||||
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
|
@ -1176,6 +1176,94 @@ static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
|
|||
}
|
||||
}
|
||||
|
||||
static void mmu6xx_dump_BATs(FILE *f, fprintf_function cpu_fprintf,
|
||||
CPUPPCState *env, int type)
|
||||
{
|
||||
target_ulong *BATlt, *BATut, *BATu, *BATl;
|
||||
target_ulong BEPIl, BEPIu, bl;
|
||||
int i;
|
||||
|
||||
switch (type) {
|
||||
case ACCESS_CODE:
|
||||
BATlt = env->IBAT[1];
|
||||
BATut = env->IBAT[0];
|
||||
break;
|
||||
default:
|
||||
BATlt = env->DBAT[1];
|
||||
BATut = env->DBAT[0];
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < env->nb_BATs; i++) {
|
||||
BATu = &BATut[i];
|
||||
BATl = &BATlt[i];
|
||||
BEPIu = *BATu & 0xF0000000;
|
||||
BEPIl = *BATu & 0x0FFE0000;
|
||||
bl = (*BATu & 0x00001FFC) << 15;
|
||||
cpu_fprintf(f, "%s BAT%d BATu " TARGET_FMT_lx
|
||||
" BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
|
||||
TARGET_FMT_lx " " TARGET_FMT_lx "\n",
|
||||
type == ACCESS_CODE ? "code" : "data", i,
|
||||
*BATu, *BATl, BEPIu, BEPIl, bl);
|
||||
}
|
||||
}
|
||||
|
||||
static void mmu6xx_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
|
||||
CPUPPCState *env)
|
||||
{
|
||||
ppc6xx_tlb_t *tlb;
|
||||
target_ulong sr;
|
||||
int type, way, entry, i;
|
||||
|
||||
cpu_fprintf(f, "HTAB base = 0x%"HWADDR_PRIx"\n", env->htab_base);
|
||||
cpu_fprintf(f, "HTAB mask = 0x%"HWADDR_PRIx"\n", env->htab_mask);
|
||||
|
||||
cpu_fprintf(f, "\nSegment registers:\n");
|
||||
for (i = 0; i < 32; i++) {
|
||||
sr = env->sr[i];
|
||||
if (sr & 0x80000000) {
|
||||
cpu_fprintf(f, "%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
|
||||
"CNTLR_SPEC=0x%05x\n", i,
|
||||
sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
|
||||
sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF),
|
||||
(uint32_t)(sr & 0xFFFFF));
|
||||
} else {
|
||||
cpu_fprintf(f, "%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i,
|
||||
sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
|
||||
sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0,
|
||||
(uint32_t)(sr & 0x00FFFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
cpu_fprintf(f, "\nBATs:\n");
|
||||
mmu6xx_dump_BATs(f, cpu_fprintf, env, ACCESS_INT);
|
||||
mmu6xx_dump_BATs(f, cpu_fprintf, env, ACCESS_CODE);
|
||||
|
||||
if (env->id_tlbs != 1) {
|
||||
cpu_fprintf(f, "ERROR: 6xx MMU should have separated TLB"
|
||||
" for code and data\n");
|
||||
}
|
||||
|
||||
cpu_fprintf(f, "\nTLBs [EPN EPN + SIZE]\n");
|
||||
|
||||
for (type = 0; type < 2; type++) {
|
||||
for (way = 0; way < env->nb_ways; way++) {
|
||||
for (entry = env->nb_tlb * type + env->tlb_per_way * way;
|
||||
entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1));
|
||||
entry++) {
|
||||
|
||||
tlb = &env->tlb.tlb6[entry];
|
||||
cpu_fprintf(f, "%s TLB %02d/%02d way:%d %s ["
|
||||
TARGET_FMT_lx " " TARGET_FMT_lx "]\n",
|
||||
type ? "code" : "data", entry % env->nb_tlb,
|
||||
env->nb_tlb, way,
|
||||
pte_is_valid(tlb->pte0) ? "valid" : "inval",
|
||||
tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
|
||||
{
|
||||
switch (env->mmu_model) {
|
||||
|
@ -1185,6 +1273,10 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
|
|||
case POWERPC_MMU_BOOKE206:
|
||||
mmubooke206_dump_mmu(f, cpu_fprintf, env);
|
||||
break;
|
||||
case POWERPC_MMU_SOFT_6xx:
|
||||
case POWERPC_MMU_SOFT_74xx:
|
||||
mmu6xx_dump_mmu(f, cpu_fprintf, env);
|
||||
break;
|
||||
#if defined(TARGET_PPC64)
|
||||
case POWERPC_MMU_64B:
|
||||
case POWERPC_MMU_2_06:
|
||||
|
@ -1339,7 +1431,15 @@ hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
|
|||
}
|
||||
|
||||
if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) {
|
||||
return -1;
|
||||
|
||||
/* Some MMUs have separate TLBs for code and data. If we only try an
|
||||
* ACCESS_INT, we may not be able to read instructions mapped by code
|
||||
* TLBs, so we also try a ACCESS_CODE.
|
||||
*/
|
||||
if (unlikely(get_physical_address(env, &ctx, addr, 0,
|
||||
ACCESS_CODE) != 0)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.raddr & TARGET_PAGE_MASK;
|
||||
|
|
|
@ -1381,7 +1381,7 @@ static void gen_spr_74xx (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Not strictly an SPR */
|
||||
vscr_init(env, 0x00010000);
|
||||
|
@ -3147,7 +3147,6 @@ POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
|
|||
PPC_CACHE_DCBZ |
|
||||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_4xx_COMMON | PPC_40x_EXCP;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x00000000000FD201ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_REAL;
|
||||
pcc->excp_model = POWERPC_EXCP_40x;
|
||||
|
@ -3195,7 +3194,6 @@ POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
|
||||
PPC_4xx_COMMON | PPC_40x_EXCP;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x00000000001FD231ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
|
||||
pcc->excp_model = POWERPC_EXCP_40x;
|
||||
|
@ -3237,7 +3235,6 @@ POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
|
||||
PPC_4xx_COMMON | PPC_40x_EXCP;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x00000000001FD631ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
|
||||
pcc->excp_model = POWERPC_EXCP_40x;
|
||||
|
@ -3285,7 +3282,6 @@ POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
|
||||
PPC_4xx_COMMON | PPC_40x_EXCP;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x00000000001FD231ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
|
||||
pcc->excp_model = POWERPC_EXCP_40x;
|
||||
|
@ -3325,7 +3321,6 @@ POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
|
|||
PPC_CACHE_DCBZ |
|
||||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_4xx_COMMON | PPC_40x_EXCP;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000007D00DULL;
|
||||
pcc->mmu_model = POWERPC_MMU_REAL;
|
||||
pcc->excp_model = POWERPC_EXCP_40x;
|
||||
|
@ -3385,7 +3380,6 @@ POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
|
||||
PPC_4xx_COMMON | PPC_40x_EXCP;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000007D00DULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
|
||||
pcc->excp_model = POWERPC_EXCP_40x;
|
||||
|
@ -3444,7 +3438,6 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
|
||||
PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000006E630ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
|
||||
pcc->excp_model = POWERPC_EXCP_40x;
|
||||
|
@ -3538,7 +3531,6 @@ POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBSYNC | PPC_MFTB |
|
||||
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
|
||||
PPC_440_SPEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000006FF30ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_BOOKE;
|
||||
pcc->excp_model = POWERPC_EXCP_BOOKE;
|
||||
|
@ -3611,7 +3603,6 @@ POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
|
||||
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
|
||||
PPC_440_SPEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000006FF30ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_BOOKE;
|
||||
pcc->excp_model = POWERPC_EXCP_BOOKE;
|
||||
|
@ -3684,7 +3675,6 @@ POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBSYNC | PPC_MFTB |
|
||||
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
|
||||
PPC_440_SPEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000006FF30ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_BOOKE;
|
||||
pcc->excp_model = POWERPC_EXCP_BOOKE;
|
||||
|
@ -3775,7 +3765,6 @@ POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBSYNC | PPC_MFTB |
|
||||
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
|
||||
PPC_440_SPEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000006FF30ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_BOOKE;
|
||||
pcc->excp_model = POWERPC_EXCP_BOOKE;
|
||||
|
@ -3872,7 +3861,6 @@ POWERPC_FAMILY(460)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBSYNC | PPC_TLBIVA |
|
||||
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
|
||||
PPC_440_SPEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000006FF30ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_BOOKE;
|
||||
pcc->excp_model = POWERPC_EXCP_BOOKE;
|
||||
|
@ -3972,7 +3960,6 @@ POWERPC_FAMILY(460F)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBSYNC | PPC_TLBIVA |
|
||||
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
|
||||
PPC_440_SPEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000006FF30ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_BOOKE;
|
||||
pcc->excp_model = POWERPC_EXCP_BOOKE;
|
||||
|
@ -4006,7 +3993,6 @@ POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_EIEIO | PPC_MEM_SYNC |
|
||||
PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
|
||||
PPC_MFTB;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000001FF43ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_REAL;
|
||||
pcc->excp_model = POWERPC_EXCP_603;
|
||||
|
@ -4039,7 +4025,6 @@ POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
|
|||
pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
|
||||
PPC_MEM_EIEIO | PPC_MEM_SYNC |
|
||||
PPC_CACHE_ICBI | PPC_MFTB;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000001F673ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_MPC8xx;
|
||||
pcc->excp_model = POWERPC_EXCP_603;
|
||||
|
@ -4106,7 +4091,6 @@ POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000006FFF2ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_G2;
|
||||
|
@ -4198,7 +4182,6 @@ POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000007FFF3ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_G2;
|
||||
|
@ -4339,7 +4322,6 @@ POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
|
|||
PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
|
||||
PPC_MEM_TLBSYNC | PPC_TLBIVAX |
|
||||
PPC_BOOKE;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000606FF30ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_BOOKE206;
|
||||
pcc->excp_model = POWERPC_EXCP_BOOKE;
|
||||
|
@ -4398,7 +4380,6 @@ POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000007FFF3ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_603;
|
||||
|
@ -4810,7 +4791,6 @@ POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
|
|||
PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
|
||||
PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000000FD70ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_601;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -4847,7 +4827,6 @@ POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
|
|||
PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
|
||||
PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000000FD70ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_601;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -4900,7 +4879,6 @@ POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
|
||||
PPC_SEGMENT | PPC_602_SPEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x0000000000C7FF73ULL;
|
||||
/* XXX: 602 MMU is quite specific. Should add a special case */
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
|
@ -4953,7 +4931,6 @@ POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000007FF73ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_603;
|
||||
|
@ -4980,11 +4957,6 @@ static void init_proc_603E (CPUPPCState *env)
|
|||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_IABR, "IABR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* Memory management */
|
||||
gen_low_BATs(env);
|
||||
gen_6xx_7xx_soft_tlb(env, 64, 2);
|
||||
|
@ -5010,7 +4982,6 @@ POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000007FF73ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_603E;
|
||||
|
@ -5056,7 +5027,6 @@ POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -5125,7 +5095,6 @@ POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -5181,7 +5150,6 @@ POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -5201,7 +5169,7 @@ static void init_proc_750 (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Time base */
|
||||
gen_tbl(env);
|
||||
|
@ -5245,7 +5213,6 @@ POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -5265,7 +5232,7 @@ static void init_proc_750cl (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Time base */
|
||||
gen_tbl(env);
|
||||
|
@ -5432,7 +5399,6 @@ POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -5452,7 +5418,7 @@ static void init_proc_750cx (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Time base */
|
||||
gen_tbl(env);
|
||||
|
@ -5500,7 +5466,6 @@ POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -5520,7 +5485,7 @@ static void init_proc_750fx (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Time base */
|
||||
gen_tbl(env);
|
||||
|
@ -5573,7 +5538,6 @@ POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -5593,7 +5557,7 @@ static void init_proc_750gx (CPUPPCState *env)
|
|||
/* XXX : not implemented (XXX: different from 750fx) */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Time base */
|
||||
gen_tbl(env);
|
||||
|
@ -5646,7 +5610,6 @@ POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -5710,7 +5673,6 @@ POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_7x5;
|
||||
|
@ -5731,7 +5693,7 @@ static void init_proc_755 (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2PMCR, "L2PMCR",
|
||||
|
@ -5782,7 +5744,6 @@ POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000005FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_7x5;
|
||||
|
@ -5841,7 +5802,6 @@ POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIA |
|
||||
PPC_SEGMENT | PPC_EXTERN |
|
||||
PPC_ALTIVEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000205FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -5910,7 +5870,6 @@ POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIA |
|
||||
PPC_SEGMENT | PPC_EXTERN |
|
||||
PPC_ALTIVEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000205FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -6005,7 +5964,6 @@ POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIA | PPC_74xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN |
|
||||
PPC_ALTIVEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000205FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
|
||||
pcc->excp_model = POWERPC_EXCP_74xx;
|
||||
|
@ -6123,7 +6081,6 @@ POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIA | PPC_74xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN |
|
||||
PPC_ALTIVEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000205FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
|
||||
pcc->excp_model = POWERPC_EXCP_74xx;
|
||||
|
@ -6244,7 +6201,6 @@ POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIA | PPC_74xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN |
|
||||
PPC_ALTIVEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000205FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
|
||||
pcc->excp_model = POWERPC_EXCP_74xx;
|
||||
|
@ -6367,7 +6323,6 @@ POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIA | PPC_74xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN |
|
||||
PPC_ALTIVEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000205FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
|
||||
pcc->excp_model = POWERPC_EXCP_74xx;
|
||||
|
@ -6514,7 +6469,6 @@ POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIA | PPC_74xx_TLB |
|
||||
PPC_SEGMENT | PPC_EXTERN |
|
||||
PPC_ALTIVEC;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x000000000205FF77ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
|
||||
pcc->excp_model = POWERPC_EXCP_74xx;
|
||||
|
@ -6570,7 +6524,7 @@ static void init_proc_970 (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Memory management */
|
||||
/* XXX: not correct */
|
||||
|
@ -6619,7 +6573,6 @@ POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_64B | PPC_ALTIVEC |
|
||||
PPC_SEGMENT_64B | PPC_SLBI;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x900000000204FF36ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_64B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -6671,7 +6624,7 @@ static void init_proc_970FX (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Memory management */
|
||||
/* XXX: not correct */
|
||||
|
@ -6732,7 +6685,6 @@ POWERPC_FAMILY(970FX)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_64B | PPC_ALTIVEC |
|
||||
PPC_SEGMENT_64B | PPC_SLBI;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x800000000204FF36ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_64B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -6784,7 +6736,7 @@ static void init_proc_970GX (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Memory management */
|
||||
/* XXX: not correct */
|
||||
|
@ -6833,7 +6785,6 @@ POWERPC_FAMILY(970GX)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_64B | PPC_ALTIVEC |
|
||||
PPC_SEGMENT_64B | PPC_SLBI;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x800000000204FF36ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_64B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -6885,7 +6836,7 @@ static void init_proc_970MP (CPUPPCState *env)
|
|||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_L2CR, "L2CR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, NULL,
|
||||
0x00000000);
|
||||
/* Memory management */
|
||||
/* XXX: not correct */
|
||||
|
@ -6934,7 +6885,6 @@ POWERPC_FAMILY(970MP)(ObjectClass *oc, void *data)
|
|||
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
|
||||
PPC_64B | PPC_ALTIVEC |
|
||||
PPC_SEGMENT_64B | PPC_SLBI;
|
||||
pcc->insns_flags2 = PPC_NONE;
|
||||
pcc->msr_mask = 0x900000000204FF36ULL;
|
||||
pcc->mmu_model = POWERPC_MMU_64B;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -7306,7 +7256,7 @@ static int create_new_table (opc_handler_t **table, unsigned char idx)
|
|||
{
|
||||
opc_handler_t **tmp;
|
||||
|
||||
tmp = malloc(0x20 * sizeof(opc_handler_t));
|
||||
tmp = g_malloc(0x20 * sizeof(opc_handler_t));
|
||||
fill_new_table(tmp, 0x20);
|
||||
table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
|
||||
|
||||
|
@ -7914,6 +7864,19 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(dev);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
|
||||
if (env->opcodes[i] != &invalid_handler) {
|
||||
g_free(env->opcodes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
ObjectClass *oc = (ObjectClass *)a;
|
||||
|
@ -7971,6 +7934,28 @@ static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
|
|||
|
||||
#include <ctype.h>
|
||||
|
||||
static ObjectClass *ppc_cpu_class_by_name(const char *name);
|
||||
|
||||
static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias)
|
||||
{
|
||||
ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias;
|
||||
|
||||
/* Cache target class lookups in the alias table */
|
||||
if (!alias->oc) {
|
||||
alias->oc = ppc_cpu_class_by_name(alias->model);
|
||||
if (!alias->oc) {
|
||||
/* Fast check for non-existing aliases */
|
||||
alias->oc = invalid_class;
|
||||
}
|
||||
}
|
||||
|
||||
if (alias->oc == invalid_class) {
|
||||
return NULL;
|
||||
} else {
|
||||
return alias->oc;
|
||||
}
|
||||
}
|
||||
|
||||
static ObjectClass *ppc_cpu_class_by_name(const char *name)
|
||||
{
|
||||
GSList *list, *item;
|
||||
|
@ -7998,7 +7983,7 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name)
|
|||
|
||||
for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
|
||||
if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) {
|
||||
return ppc_cpu_class_by_name(ppc_cpu_aliases[i].model);
|
||||
return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8088,8 +8073,8 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
|
|||
(*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
|
||||
name, pcc->pvr);
|
||||
for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
|
||||
const PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
|
||||
ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
|
||||
PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
|
||||
ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias);
|
||||
|
||||
if (alias_oc != oc) {
|
||||
continue;
|
||||
|
@ -8156,12 +8141,12 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
|
|||
g_slist_free(list);
|
||||
|
||||
for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
|
||||
const PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
|
||||
PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
|
||||
ObjectClass *oc;
|
||||
CpuDefinitionInfoList *entry;
|
||||
CpuDefinitionInfo *info;
|
||||
|
||||
oc = ppc_cpu_class_by_name(alias->model);
|
||||
oc = ppc_cpu_class_by_alias(alias);
|
||||
if (oc == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
@ -8301,6 +8286,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
pcc->parent_realize = dc->realize;
|
||||
dc->realize = ppc_cpu_realizefn;
|
||||
dc->unrealize = ppc_cpu_unrealizefn;
|
||||
|
||||
pcc->parent_reset = cc->reset;
|
||||
cc->reset = ppc_cpu_reset;
|
||||
|
|
Loading…
Reference in New Issue