mirror of
https://github.com/qemu/qemu.git
synced 2024-11-26 04:13:39 +08:00
ppc patch queue 2016-07-18
Here's what ought to be the final ppc pull request before the 2.7 hard freeze. This set contains a rework of the DBDMA device for Mac platforms, and some assorted cleanups and bugfixes. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXjFyPAAoJEGw4ysog2bOSfcMQAL6M8Kq51GHugv1Kf7f+pj2t QKtwHc2MTASNJuwE0uKOyUdsgPgUiX+umEBHmUP4FDE13LIfHgF3k/T9gzwPNnrR W2/qVZZVPJW9Bn3ZsUzQ2RYoSE3NMgPA93s80PTwGD/7IQl5uAs9chon3yHapt65 lS/IRsLWHJ1Y+7GUTLHy8vPbo5yrMkwywO4jlCrlqi/3uYLYsDdWZA3lAYQ7ZUsB mf/Ldb/5q6CBxqhUpm7eX/Wzd3F0zXqiaoFEIbvHCzd1Cl/ZH/JeSUkOgY42kYTp Sdt17oY5vXivyLwANkeXntvVZNuDJrHWIH/e1Mn81OezA0QBTV0uRxc3hxdhetSH JdaqWI7H5uSi9hdLN6CSecRWR9DLW2678D+qwwHcGtpJhLQvNfwmQH5GQZuDkKYn ZLsuvhquDc29wq6T+G64MmzimvFWy6HMaqjoMyzg3h5VZO+DL+JdX2GiQWmsv7Sx 4AX82S+vjmODgc+rv/KezvpUEus8JJO1wUb8xu9Q00uYO7HzBOQfXSKnU9rFV8Q5 jS0rxU3CB2Ely9nkXU5i+4I20P0ARosOwdjbPfI0FxEJZAxPt4VFiOriE4nbOHpc vJqGc51hkR/2C2zypd02ApFqeLOPx/iSLKpUrO5+RVrjStvupj1sL1ZSsQS6p5zN tGpyEhnSGItPqsADvXch =K5vl -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.7-20160718' into staging ppc patch queue 2016-07-18 Here's what ought to be the final ppc pull request before the 2.7 hard freeze. This set contains a rework of the DBDMA device for Mac platforms, and some assorted cleanups and bugfixes. # gpg: Signature made Mon 18 Jul 2016 05:35:27 BST # gpg: using RSA key 0x6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-2.7-20160718: ppc: Yet another fix for the huge page support detection mechanism target-ppc: fix left shift overflow in hpte_page_shift ppc/mmu-hash64: Remove duplicated #include statement ppc: abort if compat property contains an unknown value spapr: Ensure CPU cores are added contiguously and removed in LIFO order vfio/spapr: Remove stale ioctl() call ppc: Fix support for odd MSR combinations dbdma: reset io->processing flag for unassigned DBDMA channel rw accesses dbdma: set FLUSH bit upon reception of flush command for unassigned DBDMA channels dbdma: fix load_word/store_word value endianness dbdma: fix endian of DBDMA_CMDPTR_LO during branch dbdma: add per-channel debugging enabled via DEBUG_DBDMA_CHANMASK dbdma: always define DBDMA_DPRINTF and enable debug with DEBUG_DBDMA spapr: fix core unplug crash Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3913d3707e
@ -45,14 +45,22 @@
|
||||
#include "sysemu/dma.h"
|
||||
|
||||
/* debug DBDMA */
|
||||
//#define DEBUG_DBDMA
|
||||
#define DEBUG_DBDMA 0
|
||||
#define DEBUG_DBDMA_CHANMASK ((1ull << DBDMA_CHANNELS) - 1)
|
||||
|
||||
#ifdef DEBUG_DBDMA
|
||||
#define DBDMA_DPRINTF(fmt, ...) \
|
||||
do { printf("DBDMA: " fmt , ## __VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define DBDMA_DPRINTF(fmt, ...)
|
||||
#endif
|
||||
#define DBDMA_DPRINTF(fmt, ...) do { \
|
||||
if (DEBUG_DBDMA) { \
|
||||
printf("DBDMA: " fmt , ## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define DBDMA_DPRINTFCH(ch, fmt, ...) do { \
|
||||
if (DEBUG_DBDMA) { \
|
||||
if ((1ul << (ch)->channel) & DEBUG_DBDMA_CHANMASK) { \
|
||||
printf("DBDMA[%02x]: " fmt , (ch)->channel, ## __VA_ARGS__); \
|
||||
} \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
/*
|
||||
*/
|
||||
@ -62,7 +70,7 @@ static DBDMAState *dbdma_from_ch(DBDMA_channel *ch)
|
||||
return container_of(ch, DBDMAState, channels[ch->channel]);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DBDMA
|
||||
#if DEBUG_DBDMA
|
||||
static void dump_dbdma_cmd(dbdma_cmd *cmd)
|
||||
{
|
||||
printf("dbdma_cmd %p\n", cmd);
|
||||
@ -80,26 +88,26 @@ static void dump_dbdma_cmd(dbdma_cmd *cmd)
|
||||
#endif
|
||||
static void dbdma_cmdptr_load(DBDMA_channel *ch)
|
||||
{
|
||||
DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n",
|
||||
ch->regs[DBDMA_CMDPTR_LO]);
|
||||
DBDMA_DPRINTFCH(ch, "dbdma_cmdptr_load 0x%08x\n",
|
||||
ch->regs[DBDMA_CMDPTR_LO]);
|
||||
dma_memory_read(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
|
||||
&ch->current, sizeof(dbdma_cmd));
|
||||
}
|
||||
|
||||
static void dbdma_cmdptr_save(DBDMA_channel *ch)
|
||||
{
|
||||
DBDMA_DPRINTF("dbdma_cmdptr_save 0x%08x\n",
|
||||
ch->regs[DBDMA_CMDPTR_LO]);
|
||||
DBDMA_DPRINTF("xfer_status 0x%08x res_count 0x%04x\n",
|
||||
le16_to_cpu(ch->current.xfer_status),
|
||||
le16_to_cpu(ch->current.res_count));
|
||||
DBDMA_DPRINTFCH(ch, "dbdma_cmdptr_save 0x%08x\n",
|
||||
ch->regs[DBDMA_CMDPTR_LO]);
|
||||
DBDMA_DPRINTFCH(ch, "xfer_status 0x%08x res_count 0x%04x\n",
|
||||
le16_to_cpu(ch->current.xfer_status),
|
||||
le16_to_cpu(ch->current.res_count));
|
||||
dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
|
||||
&ch->current, sizeof(dbdma_cmd));
|
||||
}
|
||||
|
||||
static void kill_channel(DBDMA_channel *ch)
|
||||
{
|
||||
DBDMA_DPRINTF("kill_channel\n");
|
||||
DBDMA_DPRINTFCH(ch, "kill_channel\n");
|
||||
|
||||
ch->regs[DBDMA_STATUS] |= DEAD;
|
||||
ch->regs[DBDMA_STATUS] &= ~ACTIVE;
|
||||
@ -115,7 +123,7 @@ static void conditional_interrupt(DBDMA_channel *ch)
|
||||
uint32_t status;
|
||||
int cond;
|
||||
|
||||
DBDMA_DPRINTF("%s\n", __func__);
|
||||
DBDMA_DPRINTFCH(ch, "%s\n", __func__);
|
||||
|
||||
intr = le16_to_cpu(current->command) & INTR_MASK;
|
||||
|
||||
@ -124,7 +132,7 @@ static void conditional_interrupt(DBDMA_channel *ch)
|
||||
return;
|
||||
case INTR_ALWAYS: /* always interrupt */
|
||||
qemu_irq_raise(ch->irq);
|
||||
DBDMA_DPRINTF("%s: raise\n", __func__);
|
||||
DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -139,13 +147,13 @@ static void conditional_interrupt(DBDMA_channel *ch)
|
||||
case INTR_IFSET: /* intr if condition bit is 1 */
|
||||
if (cond) {
|
||||
qemu_irq_raise(ch->irq);
|
||||
DBDMA_DPRINTF("%s: raise\n", __func__);
|
||||
DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
|
||||
}
|
||||
return;
|
||||
case INTR_IFCLR: /* intr if condition bit is 0 */
|
||||
if (!cond) {
|
||||
qemu_irq_raise(ch->irq);
|
||||
DBDMA_DPRINTF("%s: raise\n", __func__);
|
||||
DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -159,7 +167,7 @@ static int conditional_wait(DBDMA_channel *ch)
|
||||
uint32_t status;
|
||||
int cond;
|
||||
|
||||
DBDMA_DPRINTF("conditional_wait\n");
|
||||
DBDMA_DPRINTFCH(ch, "conditional_wait\n");
|
||||
|
||||
wait = le16_to_cpu(current->command) & WAIT_MASK;
|
||||
|
||||
@ -205,7 +213,7 @@ static void branch(DBDMA_channel *ch)
|
||||
{
|
||||
dbdma_cmd *current = &ch->current;
|
||||
|
||||
ch->regs[DBDMA_CMDPTR_LO] = current->cmd_dep;
|
||||
ch->regs[DBDMA_CMDPTR_LO] = le32_to_cpu(current->cmd_dep);
|
||||
ch->regs[DBDMA_STATUS] |= BT;
|
||||
dbdma_cmdptr_load(ch);
|
||||
}
|
||||
@ -218,7 +226,7 @@ static void conditional_branch(DBDMA_channel *ch)
|
||||
uint32_t status;
|
||||
int cond;
|
||||
|
||||
DBDMA_DPRINTF("conditional_branch\n");
|
||||
DBDMA_DPRINTFCH(ch, "conditional_branch\n");
|
||||
|
||||
/* check if we must branch */
|
||||
|
||||
@ -263,7 +271,7 @@ static void dbdma_end(DBDMA_io *io)
|
||||
DBDMA_channel *ch = io->channel;
|
||||
dbdma_cmd *current = &ch->current;
|
||||
|
||||
DBDMA_DPRINTF("%s\n", __func__);
|
||||
DBDMA_DPRINTFCH(ch, "%s\n", __func__);
|
||||
|
||||
if (conditional_wait(ch))
|
||||
goto wait;
|
||||
@ -289,13 +297,13 @@ wait:
|
||||
static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
|
||||
uint16_t req_count, int is_last)
|
||||
{
|
||||
DBDMA_DPRINTF("start_output\n");
|
||||
DBDMA_DPRINTFCH(ch, "start_output\n");
|
||||
|
||||
/* KEY_REGS, KEY_DEVICE and KEY_STREAM
|
||||
* are not implemented in the mac-io chip
|
||||
*/
|
||||
|
||||
DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
|
||||
DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key);
|
||||
if (!addr || key > KEY_STREAM3) {
|
||||
kill_channel(ch);
|
||||
return;
|
||||
@ -315,13 +323,13 @@ static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
|
||||
static void start_input(DBDMA_channel *ch, int key, uint32_t addr,
|
||||
uint16_t req_count, int is_last)
|
||||
{
|
||||
DBDMA_DPRINTF("start_input\n");
|
||||
DBDMA_DPRINTFCH(ch, "start_input\n");
|
||||
|
||||
/* KEY_REGS, KEY_DEVICE and KEY_STREAM
|
||||
* are not implemented in the mac-io chip
|
||||
*/
|
||||
|
||||
DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
|
||||
DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key);
|
||||
if (!addr || key > KEY_STREAM3) {
|
||||
kill_channel(ch);
|
||||
return;
|
||||
@ -342,9 +350,8 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
|
||||
uint16_t len)
|
||||
{
|
||||
dbdma_cmd *current = &ch->current;
|
||||
uint32_t val;
|
||||
|
||||
DBDMA_DPRINTF("load_word\n");
|
||||
DBDMA_DPRINTFCH(ch, "load_word %d bytes, addr=%08x\n", len, addr);
|
||||
|
||||
/* only implements KEY_SYSTEM */
|
||||
|
||||
@ -354,14 +361,7 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
|
||||
return;
|
||||
}
|
||||
|
||||
dma_memory_read(&address_space_memory, addr, &val, len);
|
||||
|
||||
if (len == 2)
|
||||
val = (val << 16) | (current->cmd_dep & 0x0000ffff);
|
||||
else if (len == 1)
|
||||
val = (val << 24) | (current->cmd_dep & 0x00ffffff);
|
||||
|
||||
current->cmd_dep = val;
|
||||
dma_memory_read(&address_space_memory, addr, ¤t->cmd_dep, len);
|
||||
|
||||
if (conditional_wait(ch))
|
||||
goto wait;
|
||||
@ -381,9 +381,9 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
|
||||
uint16_t len)
|
||||
{
|
||||
dbdma_cmd *current = &ch->current;
|
||||
uint32_t val;
|
||||
|
||||
DBDMA_DPRINTF("store_word\n");
|
||||
DBDMA_DPRINTFCH(ch, "store_word %d bytes, addr=%08x pa=%x\n",
|
||||
len, addr, le32_to_cpu(current->cmd_dep));
|
||||
|
||||
/* only implements KEY_SYSTEM */
|
||||
|
||||
@ -393,13 +393,7 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
|
||||
return;
|
||||
}
|
||||
|
||||
val = current->cmd_dep;
|
||||
if (len == 2)
|
||||
val >>= 16;
|
||||
else if (len == 1)
|
||||
val >>= 24;
|
||||
|
||||
dma_memory_write(&address_space_memory, addr, &val, len);
|
||||
dma_memory_write(&address_space_memory, addr, ¤t->cmd_dep, len);
|
||||
|
||||
if (conditional_wait(ch))
|
||||
goto wait;
|
||||
@ -446,7 +440,7 @@ static void channel_run(DBDMA_channel *ch)
|
||||
uint16_t req_count;
|
||||
uint32_t phy_addr;
|
||||
|
||||
DBDMA_DPRINTF("channel_run\n");
|
||||
DBDMA_DPRINTFCH(ch, "channel_run\n");
|
||||
dump_dbdma_cmd(current);
|
||||
|
||||
/* clear WAKE flag at command fetch */
|
||||
@ -540,9 +534,9 @@ static void DBDMA_run_bh(void *opaque)
|
||||
{
|
||||
DBDMAState *s = opaque;
|
||||
|
||||
DBDMA_DPRINTF("DBDMA_run_bh\n");
|
||||
|
||||
DBDMA_DPRINTF("-> DBDMA_run_bh\n");
|
||||
DBDMA_run(s);
|
||||
DBDMA_DPRINTF("<- DBDMA_run_bh\n");
|
||||
}
|
||||
|
||||
void DBDMA_kick(DBDMAState *dbdma)
|
||||
@ -557,7 +551,7 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
|
||||
DBDMAState *s = dbdma;
|
||||
DBDMA_channel *ch = &s->channels[nchan];
|
||||
|
||||
DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan);
|
||||
DBDMA_DPRINTFCH(ch, "DBDMA_register_channel 0x%x\n", nchan);
|
||||
|
||||
assert(rw);
|
||||
assert(flush);
|
||||
@ -601,7 +595,7 @@ dbdma_control_write(DBDMA_channel *ch)
|
||||
status &= ~FLUSH;
|
||||
}
|
||||
|
||||
DBDMA_DPRINTF(" status 0x%08x\n", status);
|
||||
DBDMA_DPRINTFCH(ch, " status 0x%08x\n", status);
|
||||
|
||||
ch->regs[DBDMA_STATUS] = status;
|
||||
|
||||
@ -618,10 +612,10 @@ static void dbdma_write(void *opaque, hwaddr addr,
|
||||
DBDMA_channel *ch = &s->channels[channel];
|
||||
int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
|
||||
|
||||
DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n",
|
||||
addr, value);
|
||||
DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
|
||||
(uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
|
||||
DBDMA_DPRINTFCH(ch, "writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n",
|
||||
addr, value);
|
||||
DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
|
||||
(uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
|
||||
|
||||
/* cmdptr cannot be modified if channel is ACTIVE */
|
||||
|
||||
@ -672,9 +666,9 @@ static uint64_t dbdma_read(void *opaque, hwaddr addr,
|
||||
|
||||
value = ch->regs[reg];
|
||||
|
||||
DBDMA_DPRINTF("readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
|
||||
DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
|
||||
(uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
|
||||
DBDMA_DPRINTFCH(ch, "readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
|
||||
DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
|
||||
(uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
|
||||
|
||||
switch(reg) {
|
||||
case DBDMA_CONTROL:
|
||||
@ -784,13 +778,24 @@ static void dbdma_unassigned_rw(DBDMA_io *io)
|
||||
DBDMA_channel *ch = io->channel;
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
|
||||
__func__, ch->channel);
|
||||
ch->io.processing = false;
|
||||
}
|
||||
|
||||
static void dbdma_unassigned_flush(DBDMA_io *io)
|
||||
{
|
||||
DBDMA_channel *ch = io->channel;
|
||||
dbdma_cmd *current = &ch->current;
|
||||
uint16_t cmd;
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
|
||||
__func__, ch->channel);
|
||||
|
||||
cmd = le16_to_cpu(current->command) & COMMAND_MASK;
|
||||
if (cmd == OUTPUT_MORE || cmd == OUTPUT_LAST ||
|
||||
cmd == INPUT_MORE || cmd == INPUT_LAST) {
|
||||
current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS] | FLUSH);
|
||||
current->res_count = cpu_to_le16(io->len);
|
||||
dbdma_cmdptr_save(ch);
|
||||
}
|
||||
}
|
||||
|
||||
void* DBDMA_init (MemoryRegion **dbdma_mem)
|
||||
|
@ -126,14 +126,23 @@ static void spapr_core_release(DeviceState *dev, void *opaque)
|
||||
void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
Error **errp)
|
||||
{
|
||||
sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));
|
||||
PowerPCCPU *cpu = POWERPC_CPU(core->threads);
|
||||
int id = ppc_get_vcpu_dt_id(cpu);
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
|
||||
CPUCore *cc = CPU_CORE(dev);
|
||||
sPAPRDRConnector *drc =
|
||||
spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, id);
|
||||
spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, cc->core_id);
|
||||
sPAPRDRConnectorClass *drck;
|
||||
Error *local_err = NULL;
|
||||
int smt = kvmppc_smt_threads();
|
||||
int index = cc->core_id / smt;
|
||||
int spapr_max_cores = max_cpus / smp_threads;
|
||||
int i;
|
||||
|
||||
for (i = spapr_max_cores - 1; i > index; i--) {
|
||||
if (spapr->cores[i]) {
|
||||
error_setg(errp, "core-id %d should be removed first", i * smt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
g_assert(drc);
|
||||
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
@ -216,7 +225,7 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(OBJECT(hotplug_dev));
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
|
||||
int spapr_max_cores = max_cpus / smp_threads;
|
||||
int index;
|
||||
int index, i;
|
||||
int smt = kvmppc_smt_threads();
|
||||
Error *local_err = NULL;
|
||||
CPUCore *cc = CPU_CORE(dev);
|
||||
@ -254,6 +263,14 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < index; i++) {
|
||||
if (!spapr->cores[i]) {
|
||||
error_setg(&local_err, "core-id %d should be added first",
|
||||
i * smt);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
g_free(base_core_type);
|
||||
error_propagate(errp, local_err);
|
||||
|
@ -177,7 +177,6 @@ int vfio_spapr_create_window(VFIOContainer *container,
|
||||
error_report("Host doesn't support DMA window at %"HWADDR_PRIx", must be %"PRIx64,
|
||||
section->offset_within_address_space,
|
||||
(uint64_t)create.start_addr);
|
||||
ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_REMOVE, &remove);
|
||||
return -EINVAL;
|
||||
}
|
||||
trace_vfio_spapr_create_window(create.page_shift,
|
||||
|
@ -41,17 +41,19 @@ static inline void hreg_swap_gpr_tgpr(CPUPPCState *env)
|
||||
|
||||
static inline void hreg_compute_mem_idx(CPUPPCState *env)
|
||||
{
|
||||
/* This is our encoding for server processors
|
||||
/* This is our encoding for server processors. The architecture
|
||||
* specifies that there is no such thing as userspace with
|
||||
* translation off, however it appears that MacOS does it and
|
||||
* some 32-bit CPUs support it. Weird...
|
||||
*
|
||||
* 0 = Guest User space virtual mode
|
||||
* 1 = Guest Kernel space virtual mode
|
||||
* 2 = Guest Kernel space real mode
|
||||
* 3 = HV User space virtual mode
|
||||
* 4 = HV Kernel space virtual mode
|
||||
* 5 = HV Kernel space real mode
|
||||
*
|
||||
* The combination PR=1 IR&DR=0 is invalid, we will treat
|
||||
* it as IR=DR=1
|
||||
* 2 = Guest User space real mode
|
||||
* 3 = Guest Kernel space real mode
|
||||
* 4 = HV User space virtual mode
|
||||
* 5 = HV Kernel space virtual mode
|
||||
* 6 = HV User space real mode
|
||||
* 7 = HV Kernel space real mode
|
||||
*
|
||||
* For BookE, we need 8 MMU modes as follow:
|
||||
*
|
||||
@ -71,20 +73,11 @@ static inline void hreg_compute_mem_idx(CPUPPCState *env)
|
||||
env->immu_idx += msr_gs ? 4 : 0;
|
||||
env->dmmu_idx += msr_gs ? 4 : 0;
|
||||
} else {
|
||||
/* First calucalte a base value independent of HV */
|
||||
if (msr_pr != 0) {
|
||||
/* User space, ignore IR and DR */
|
||||
env->immu_idx = env->dmmu_idx = 0;
|
||||
} else {
|
||||
/* Kernel, setup a base I/D value */
|
||||
env->immu_idx = msr_ir ? 1 : 2;
|
||||
env->dmmu_idx = msr_dr ? 1 : 2;
|
||||
}
|
||||
/* Then offset it for HV */
|
||||
if (msr_hv) {
|
||||
env->immu_idx += 3;
|
||||
env->dmmu_idx += 3;
|
||||
}
|
||||
env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1;
|
||||
env->immu_idx += msr_ir ? 0 : 2;
|
||||
env->dmmu_idx += msr_dr ? 0 : 2;
|
||||
env->immu_idx += msr_hv ? 4 : 0;
|
||||
env->dmmu_idx += msr_hv ? 4 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,8 +129,13 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
|
||||
/* Change the exception prefix on PowerPC 601 */
|
||||
env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000;
|
||||
}
|
||||
/* If PR=1 then EE, IR and DR must be 1 */
|
||||
if ((value >> MSR_PR) & 1) {
|
||||
/* If PR=1 then EE, IR and DR must be 1
|
||||
*
|
||||
* Note: We only enforce this on 64-bit processors. It appears that
|
||||
* 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
|
||||
* exploits it.
|
||||
*/
|
||||
if ((env->insns_flags & PPC_64B) && ((value >> MSR_PR) & 1)) {
|
||||
value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR);
|
||||
}
|
||||
#endif
|
||||
|
@ -389,12 +389,16 @@ static long getrampagesize(void)
|
||||
|
||||
object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize);
|
||||
|
||||
if (hpsize == LONG_MAX) {
|
||||
if (hpsize == LONG_MAX || hpsize == getpagesize()) {
|
||||
return getpagesize();
|
||||
}
|
||||
|
||||
if (nb_numa_nodes == 0 && hpsize > getpagesize()) {
|
||||
/* No NUMA nodes and normal RAM without -mem-path ==> no huge pages! */
|
||||
/* If NUMA is disabled or the NUMA nodes are not backed with a
|
||||
* memory-backend, then there is at least one node using "normal"
|
||||
* RAM. And since normal RAM has not been configured with "-mem-path"
|
||||
* (what we've checked earlier here already), we can not use huge pages!
|
||||
*/
|
||||
if (nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL) {
|
||||
static bool warned;
|
||||
if (!warned) {
|
||||
error_report("Huge page support disabled (n/a for main memory).");
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "exec/helper-proto.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "kvm_ppc.h"
|
||||
#include "mmu-hash64.h"
|
||||
#include "exec/log.h"
|
||||
@ -479,7 +478,7 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
|
||||
|
||||
mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
|
||||
|
||||
if ((pte1 & mask) == (ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
|
||||
if ((pte1 & mask) == ((uint64_t)ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
|
||||
return ps->page_shift;
|
||||
}
|
||||
}
|
||||
|
@ -8446,8 +8446,8 @@ static void powerpc_get_compat(Object *obj, Visitor *v, const char *name,
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
error_setg(errp, "Internal error: compat is set to %x",
|
||||
max_compat ? *max_compat : -1);
|
||||
error_report("Internal error: compat is set to %x", *max_compat);
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user