aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-01-04 07:23:27 -0800
committerRichard Henderson <richard.henderson@linaro.org>2022-01-04 07:23:27 -0800
commit67e41fe0cfb62e6cdfa659f0155417d17e5274ea (patch)
tree239a4e8288cb91ee1ddabb02bd1dd5efbc6b8c04 /hw
parentb5a3d8bc9146ba22a25116cb748c97341bf99737 (diff)
parent0625c7760d5451d7436ef0738f763c6bb5141919 (diff)
Merge tag 'pull-ppc-20220104' of https://github.com/legoater/qemu into staging
ppc 7.0 queue: * Cleanup of PowerNV PHBs (Daniel and Cedric) * Cleanup and fixes for PPC405 machine (Cedric) * Fix for xscvspdpn (Matheus) * Rework of powerpc exception handling 1/n (Fabiano) * Optimisation for PMU (Richard and Daniel) # gpg: Signature made Mon 03 Jan 2022 11:04:06 PM PST # gpg: using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1 # gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: A0F6 6548 F048 95EB FE6B 0B60 51A3 43C7 CFFB ECA1 * tag 'pull-ppc-20220104' of https://github.com/legoater/qemu: (26 commits) target/ppc: do not call hreg_compute_hflags() in helper_store_mmcr0() target/ppc: Use env->pnc_cyc_cnt target/ppc: Rewrite pmu_increment_insns target/ppc: Cache per-pmc insn and cycle count settings target/ppc: powerpc_excp: Stop passing excp_model around target/ppc: powerpc_excp: Move system call vectored code together target/ppc: powerpc_excp: Set vector earlier target/ppc: powerpc_excp: Add excp_vectors bounds check target/ppc: powerpc_excp: Set alternate SRRs directly target/ppc: do not silence snan in xscvspdpn ppc/ppc405: Dump specific registers ppc/ppc405: Introduce a store helper for SPR_40x_PID ppc/ppc405: Fix timer initialization ppc/ppc405: Rework ppc_40x_timers_init() to use a PowerPCCPU ppc/ppc405: Restore TCR and STR write handlers ppc/ppc405: Activate MMU logs ppc/ppc4xx: Convert printfs() target/ppc: Print out literal exception names in logs target/ppc: Remove static inline target/ppc: Check effective address validity ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/pci-host/pnv_phb3.c3
-rw-r--r--hw/pci-host/pnv_phb4.c16
-rw-r--r--hw/pci-host/pnv_phb4_pec.c3
-rw-r--r--hw/ppc/mpc8544_guts.c9
-rw-r--r--hw/ppc/pnv.c2
-rw-r--r--hw/ppc/ppc.c67
-rw-r--r--hw/ppc/ppc405_uc.c2
-rw-r--r--hw/ppc/ppc4xx_devs.c39
-rw-r--r--hw/ppc/ppc4xx_pci.c11
-rw-r--r--hw/ppc/trace-events7
10 files changed, 79 insertions, 80 deletions
diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index c6e7871ecb..c78084cce7 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -1045,7 +1045,8 @@ static void pnv_phb3_realize(DeviceState *dev, Error **errp)
memory_region_init(&phb->pci_mmio, OBJECT(phb), "pci-mmio",
PCI_MMIO_TOTAL_SIZE);
- pci->bus = pci_register_root_bus(dev, "root-bus",
+ pci->bus = pci_register_root_bus(dev,
+ dev->id ? dev->id : NULL,
pnv_phb3_set_irq, pnv_phb3_map_irq, phb,
&phb->pci_mmio, &phb->pci_io,
0, 4, TYPE_PNV_PHB3_ROOT_BUS);
diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 1fbf7328f5..5ba26e250a 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1201,7 +1201,7 @@ static void pnv_phb4_realize(DeviceState *dev, Error **errp)
memory_region_init(&phb->pci_mmio, OBJECT(phb), name,
PCI_MMIO_TOTAL_SIZE);
- pci->bus = pci_register_root_bus(dev, "root-bus",
+ pci->bus = pci_register_root_bus(dev, dev->id,
pnv_phb4_set_irq, pnv_phb4_map_irq, phb,
&phb->pci_mmio, &phb->pci_io,
0, 4, TYPE_PNV_PHB4_ROOT_BUS);
@@ -1230,18 +1230,6 @@ static void pnv_phb4_realize(DeviceState *dev, Error **errp)
phb->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);
}
-static void pnv_phb4_reset(DeviceState *dev)
-{
- PnvPHB4 *phb = PNV_PHB4(dev);
- PCIDevice *root_dev = PCI_DEVICE(&phb->root);
-
- /*
- * Configure PCI device id at reset using a property.
- */
- pci_config_set_vendor_id(root_dev->config, PCI_VENDOR_ID_IBM);
- pci_config_set_device_id(root_dev->config, phb->device_id);
-}
-
static const char *pnv_phb4_root_bus_path(PCIHostState *host_bridge,
PCIBus *rootbus)
{
@@ -1274,7 +1262,6 @@ static Property pnv_phb4_properties[] = {
DEFINE_PROP_UINT32("index", PnvPHB4, phb_id, 0),
DEFINE_PROP_UINT32("chip-id", PnvPHB4, chip_id, 0),
DEFINE_PROP_UINT64("version", PnvPHB4, version, 0),
- DEFINE_PROP_UINT16("device-id", PnvPHB4, device_id, 0),
DEFINE_PROP_LINK("stack", PnvPHB4, stack, TYPE_PNV_PHB4_PEC_STACK,
PnvPhb4PecStack *),
DEFINE_PROP_END_OF_LIST(),
@@ -1291,7 +1278,6 @@ static void pnv_phb4_class_init(ObjectClass *klass, void *data)
device_class_set_props(dc, pnv_phb4_properties);
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->user_creatable = false;
- dc->reset = pnv_phb4_reset;
xfc->notify = pnv_phb4_xive_notify;
}
diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c
index 24a3adcae3..f3e4fa0c82 100644
--- a/hw/pci-host/pnv_phb4_pec.c
+++ b/hw/pci-host/pnv_phb4_pec.c
@@ -527,7 +527,6 @@ static void pnv_pec_class_init(ObjectClass *klass, void *data)
pecc->stk_compat = stk_compat;
pecc->stk_compat_size = sizeof(stk_compat);
pecc->version = PNV_PHB4_VERSION;
- pecc->device_id = PNV_PHB4_DEVICE_ID;
pecc->num_stacks = pnv_pec_num_stacks;
}
@@ -587,8 +586,6 @@ static void pnv_pec_stk_realize(DeviceState *dev, Error **errp)
&error_fatal);
object_property_set_int(OBJECT(&stack->phb), "version", pecc->version,
&error_fatal);
- object_property_set_int(OBJECT(&stack->phb), "device-id", pecc->device_id,
- &error_fatal);
object_property_set_link(OBJECT(&stack->phb), "stack", OBJECT(stack),
&error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&stack->phb), errp)) {
diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
index e8d2d51c20..a26e83d048 100644
--- a/hw/ppc/mpc8544_guts.c
+++ b/hw/ppc/mpc8544_guts.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu/module.h"
+#include "qemu/log.h"
#include "sysemu/runstate.h"
#include "cpu.h"
#include "hw/sysbus.h"
@@ -82,7 +83,9 @@ static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr,
value = env->spr[SPR_E500_SVR];
break;
default:
- fprintf(stderr, "guts: Unknown register read: %x\n", (int)addr);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Unknown register 0x%" HWADDR_PRIx "\n",
+ __func__, addr);
break;
}
@@ -101,8 +104,8 @@ static void mpc8544_guts_write(void *opaque, hwaddr addr,
}
break;
default:
- fprintf(stderr, "guts: Unknown register write: %x = %x\n",
- (int)addr, (unsigned)value);
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unknown register 0x%" HWADDR_PRIx
+ " = 0x%" PRIx64 "\n", __func__, addr, value);
break;
}
}
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 29ee0d0f08..9de8b83530 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1314,7 +1314,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
k->chip_cfam_id = 0x120d304980000000ull; /* P8 Naples DD1.0 */
k->cores_mask = POWER8_CORE_MASK;
- k->num_phbs = 3;
+ k->num_phbs = 4;
k->core_pir = pnv_chip_core_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->intc_reset = pnv_chip_power8_intc_reset;
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 818d757985..bb5bee9a33 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1124,14 +1124,12 @@ struct ppc40x_timer_t {
/* Fixed interval timer */
static void cpu_4xx_fit_cb (void *opaque)
{
- PowerPCCPU *cpu;
- CPUPPCState *env;
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
ppc_tb_t *tb_env;
ppc40x_timer_t *ppc40x_timer;
uint64_t now, next;
- env = opaque;
- cpu = env_archcpu(env);
tb_env = env->tb_env;
ppc40x_timer = tb_env->opaque;
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -1193,13 +1191,11 @@ static void start_stop_pit (CPUPPCState *env, ppc_tb_t *tb_env, int is_excp)
static void cpu_4xx_pit_cb (void *opaque)
{
- PowerPCCPU *cpu;
- CPUPPCState *env;
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
ppc_tb_t *tb_env;
ppc40x_timer_t *ppc40x_timer;
- env = opaque;
- cpu = env_archcpu(env);
tb_env = env->tb_env;
ppc40x_timer = tb_env->opaque;
env->spr[SPR_40x_TSR] |= 1 << 27;
@@ -1216,14 +1212,12 @@ static void cpu_4xx_pit_cb (void *opaque)
/* Watchdog timer */
static void cpu_4xx_wdt_cb (void *opaque)
{
- PowerPCCPU *cpu;
- CPUPPCState *env;
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
ppc_tb_t *tb_env;
ppc40x_timer_t *ppc40x_timer;
uint64_t now, next;
- env = opaque;
- cpu = env_archcpu(env);
tb_env = env->tb_env;
ppc40x_timer = tb_env->opaque;
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -1300,6 +1294,31 @@ target_ulong load_40x_pit (CPUPPCState *env)
return cpu_ppc_load_decr(env);
}
+void store_40x_tsr(CPUPPCState *env, target_ulong val)
+{
+ PowerPCCPU *cpu = env_archcpu(env);
+
+ trace_ppc40x_store_tcr(val);
+
+ env->spr[SPR_40x_TSR] &= ~(val & 0xFC000000);
+ if (val & 0x80000000) {
+ ppc_set_irq(cpu, PPC_INTERRUPT_PIT, 0);
+ }
+}
+
+void store_40x_tcr(CPUPPCState *env, target_ulong val)
+{
+ PowerPCCPU *cpu = env_archcpu(env);
+ ppc_tb_t *tb_env;
+
+ trace_ppc40x_store_tsr(val);
+
+ tb_env = env->tb_env;
+ env->spr[SPR_40x_TCR] = val & 0xFFC00000;
+ start_stop_pit(env, tb_env, 1);
+ cpu_4xx_wdt_cb(cpu);
+}
+
static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq)
{
CPUPPCState *env = opaque;
@@ -1316,24 +1335,26 @@ clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq,
{
ppc_tb_t *tb_env;
ppc40x_timer_t *ppc40x_timer;
+ PowerPCCPU *cpu = env_archcpu(env);
+
+ trace_ppc40x_timers_init(freq);
tb_env = g_malloc0(sizeof(ppc_tb_t));
+ ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
+
env->tb_env = tb_env;
tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
- ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
tb_env->tb_freq = freq;
tb_env->decr_freq = freq;
tb_env->opaque = ppc40x_timer;
- trace_ppc40x_timers_init(freq);
- if (ppc40x_timer != NULL) {
- /* We use decr timer for PIT */
- tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_pit_cb, env);
- ppc40x_timer->fit_timer =
- timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_fit_cb, env);
- ppc40x_timer->wdt_timer =
- timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_wdt_cb, env);
- ppc40x_timer->decr_excp = decr_excp;
- }
+
+ /* We use decr timer for PIT */
+ tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_pit_cb, cpu);
+ ppc40x_timer->fit_timer =
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_fit_cb, cpu);
+ ppc40x_timer->wdt_timer =
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_wdt_cb, cpu);
+ ppc40x_timer->decr_excp = decr_excp;
return &ppc_40x_set_tb_clk;
}
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index ec97b22bd0..8aacd275a6 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1461,8 +1461,6 @@ PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
ppc4xx_pob_init(env);
/* OBP arbitrer */
ppc4xx_opba_init(0xef600600);
- /* Initialize timers */
- ppc_booke_timers_init(cpu, sysclk, 0);
/* Universal interrupt controller */
uicdev = qdev_new(TYPE_PPC_UIC);
uicsbd = SYS_BUS_DEVICE(uicdev);
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 980c48944f..e7d82ae501 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -35,14 +35,7 @@
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
-
-/*#define DEBUG_UIC*/
-
-#ifdef DEBUG_UIC
-# define LOG_UIC(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
-#else
-# define LOG_UIC(...) do { } while (0)
-#endif
+#include "trace.h"
static void ppc4xx_reset(void *opaque)
{
@@ -137,8 +130,9 @@ static uint32_t sdram_bcr (hwaddr ram_base,
bcr = 0x000C0000;
break;
default:
- printf("%s: invalid RAM size " TARGET_FMT_plx "\n", __func__,
- ram_size);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
+ ram_size);
return 0x00000000;
}
bcr |= ram_base & 0xFF800000;
@@ -171,10 +165,8 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
{
if (sdram->bcr[i] & 0x00000001) {
/* Unmap RAM */
-#ifdef DEBUG_SDRAM
- printf("%s: unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
- __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
-#endif
+ trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]),
+ sdram_size(sdram->bcr[i]));
memory_region_del_subregion(get_system_memory(),
&sdram->containers[i]);
memory_region_del_subregion(&sdram->containers[i],
@@ -183,10 +175,7 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
}
sdram->bcr[i] = bcr & 0xFFDEE001;
if (enabled && (bcr & 0x00000001)) {
-#ifdef DEBUG_SDRAM
- printf("%s: Map RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
- __func__, sdram_base(bcr), sdram_size(bcr));
-#endif
+ trace_ppc4xx_sdram_unmap(sdram_base(bcr), sdram_size(bcr));
memory_region_init(&sdram->containers[i], NULL, "sdram-containers",
sdram_size(bcr));
memory_region_add_subregion(&sdram->containers[i], 0,
@@ -216,10 +205,8 @@ static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
int i;
for (i = 0; i < sdram->nbanks; i++) {
-#ifdef DEBUG_SDRAM
- printf("%s: Unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
- __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
-#endif
+ trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]),
+ sdram_size(sdram->bcr[i]));
memory_region_del_subregion(get_system_memory(),
&sdram->ram_memories[i]);
}
@@ -316,16 +303,12 @@ static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val)
case 0x20: /* SDRAM_CFG */
val &= 0xFFE00000;
if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
-#ifdef DEBUG_SDRAM
- printf("%s: enable SDRAM controller\n", __func__);
-#endif
+ trace_ppc4xx_sdram_enable("enable");
/* validate all RAM mappings */
sdram_map_bcr(sdram);
sdram->status &= ~0x80000000;
} else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
-#ifdef DEBUG_SDRAM
- printf("%s: disable SDRAM controller\n", __func__);
-#endif
+ trace_ppc4xx_sdram_enable("disable");
/* invalidate all RAM mappings */
sdram_unmap_bcr(sdram);
sdram->status |= 0x80000000;
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 304a29349c..5df97e6d15 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -20,6 +20,7 @@
* 4xx SoCs, such as the 440EP. */
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "hw/irq.h"
#include "hw/ppc/ppc.h"
#include "hw/ppc/ppc4xx.h"
@@ -152,8 +153,9 @@ static void ppc4xx_pci_reg_write4(void *opaque, hwaddr offset,
break;
default:
- printf("%s: unhandled PCI internal register 0x%lx\n", __func__,
- (unsigned long)offset);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: unhandled PCI internal register 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
break;
}
}
@@ -218,8 +220,9 @@ static uint64_t ppc4xx_pci_reg_read4(void *opaque, hwaddr offset,
break;
default:
- printf("%s: invalid PCI internal register 0x%lx\n", __func__,
- (unsigned long)offset);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid PCI internal register 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
value = 0;
}
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index ada644652d..5c0a215cad 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -110,6 +110,8 @@ ppc4xx_pit_start(uint64_t reload) "PIT 0x%016" PRIx64
ppc4xx_pit(uint32_t ar, uint32_t ir, uint64_t tcr, uint64_t tsr, uint64_t reload) "ar %d ir %d TCR 0x%" PRIx64 " TSR 0x%" PRIx64 " PIT 0x%016" PRIx64
ppc4xx_wdt(uint64_t tcr, uint64_t tsr) "TCR 0x%" PRIx64 " TSR 0x%" PRIx64
ppc40x_store_pit(uint64_t value) "val 0x%" PRIx64
+ppc40x_store_tcr(uint64_t value) "val 0x%" PRIx64
+ppc40x_store_tsr(uint64_t value) "val 0x%" PRIx64
ppc40x_set_tb_clk(uint32_t value) "new frequency %" PRIu32
ppc40x_timers_init(uint32_t value) "frequency %" PRIu32
@@ -164,3 +166,8 @@ ppc4xx_gpt_init(uint64_t addr) "offet 0x%" PRIx64
ppc405ep_clocks_compute(const char *param, uint32_t param2, uint32_t val) "%s 0x%1" PRIx32 " %d"
ppc405ep_clocks_setup(const char *trace) "%s"
+
+# ppc4xx_devs.c
+ppc4xx_sdram_enable(const char *trace) "%s SDRAM controller"
+ppc4xx_sdram_unmap(uint64_t addr, uint64_t size) "Unmap RAM area 0x%" PRIx64 " size 0x%" PRIx64
+ppc4xx_sdram_map(uint64_t addr, uint64_t size) "Map RAM area 0x%" PRIx64 " size 0x%" PRIx64