#ifndef HW_SPAPR_H
#define HW_SPAPR_H
+#include "qemu/units.h"
#include "sysemu/dma.h"
#include "hw/boards.h"
#include "hw/ppc/xics.h"
struct sPAPRNVRAM;
typedef struct sPAPREventLogEntry sPAPREventLogEntry;
typedef struct sPAPREventSource sPAPREventSource;
+typedef struct sPAPRPendingHPT sPAPRPendingHPT;
#define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL
#define SPAPR_ENTRY_POINT 0x100
#define SPAPR_MACHINE_CLASS(klass) \
OBJECT_CLASS_CHECK(sPAPRMachineClass, klass, TYPE_SPAPR_MACHINE)
+typedef enum {
+ SPAPR_RESIZE_HPT_DEFAULT = 0,
+ SPAPR_RESIZE_HPT_DISABLED,
+ SPAPR_RESIZE_HPT_ENABLED,
+ SPAPR_RESIZE_HPT_REQUIRED,
+} sPAPRResizeHPT;
+
+/**
+ * Capabilities
+ */
+
+/* Hardware Transactional Memory */
+#define SPAPR_CAP_HTM 0x00
+/* Vector Scalar Extensions */
+#define SPAPR_CAP_VSX 0x01
+/* Decimal Floating Point */
+#define SPAPR_CAP_DFP 0x02
+/* Cache Flush on Privilege Change */
+#define SPAPR_CAP_CFPC 0x03
+/* Speculation Barrier Bounds Checking */
+#define SPAPR_CAP_SBBC 0x04
+/* Indirect Branch Serialisation */
+#define SPAPR_CAP_IBS 0x05
+/* HPT Maximum Page Size (encoded as a shift) */
+#define SPAPR_CAP_HPT_MAXPAGESIZE 0x06
+/* Num Caps */
+#define SPAPR_CAP_NUM (SPAPR_CAP_HPT_MAXPAGESIZE + 1)
+
+/*
+ * Capability Values
+ */
+/* Bool Caps */
+#define SPAPR_CAP_OFF 0x00
+#define SPAPR_CAP_ON 0x01
+/* Custom Caps */
+#define SPAPR_CAP_BROKEN 0x00
+#define SPAPR_CAP_WORKAROUND 0x01
+#define SPAPR_CAP_FIXED 0x02
+#define SPAPR_CAP_FIXED_IBS 0x02
+#define SPAPR_CAP_FIXED_CCD 0x03
+
+typedef struct sPAPRCapabilities sPAPRCapabilities;
+struct sPAPRCapabilities {
+ uint8_t caps[SPAPR_CAP_NUM];
+};
+
/**
* sPAPRMachineClass:
*/
/*< public >*/
bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */
bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */
- const char *tcg_default_cpu; /* which (TCG) CPU to simulate by default */
bool pre_2_10_has_unused_icps;
void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
unsigned n_dma, uint32_t *liobns, Error **errp);
+ sPAPRResizeHPT resize_hpt_default;
+ sPAPRCapabilities default_caps;
};
/**
ICSState *ics;
sPAPRRTCState rtc;
+ sPAPRResizeHPT resize_hpt;
void *htab;
uint32_t htab_shift;
uint64_t patb_entry; /* Process tbl registed in H_REGISTER_PROCESS_TABLE */
+ sPAPRPendingHPT *pending_hpt; /* in-progress resize */
+
hwaddr rma_size;
int vrma_adjust;
ssize_t rtas_size;
uint64_t rtc_offset; /* Now used only during incoming migration */
struct PPCTimebase tb;
bool has_graphics;
+ uint32_t vsmt; /* Virtual SMT mode (KVM's "core stride") */
Notifier epow_notifier;
QTAILQ_HEAD(, sPAPREventLogEntry) pending_events;
/*< public >*/
char *kvm_type;
- MemoryHotplugState hotplug_memory;
const char *icp_type;
+
+ bool cmd_line_caps[SPAPR_CAP_NUM];
+ sPAPRCapabilities def, eff, mig;
};
#define H_SUCCESS 0
#define H_DABRX_KERNEL (1ULL<<(63-62))
#define H_DABRX_USER (1ULL<<(63-63))
+/* Values for KVM_PPC_GET_CPU_CHAR & H_GET_CPU_CHARACTERISTICS */
+#define H_CPU_CHAR_SPEC_BAR_ORI31 PPC_BIT(0)
+#define H_CPU_CHAR_BCCTRL_SERIALISED PPC_BIT(1)
+#define H_CPU_CHAR_L1D_FLUSH_ORI30 PPC_BIT(2)
+#define H_CPU_CHAR_L1D_FLUSH_TRIG2 PPC_BIT(3)
+#define H_CPU_CHAR_L1D_THREAD_PRIV PPC_BIT(4)
+#define H_CPU_CHAR_HON_BRANCH_HINTS PPC_BIT(5)
+#define H_CPU_CHAR_THR_RECONF_TRIG PPC_BIT(6)
+#define H_CPU_CHAR_CACHE_COUNT_DIS PPC_BIT(7)
+#define H_CPU_BEHAV_FAVOUR_SECURITY PPC_BIT(0)
+#define H_CPU_BEHAV_L1D_FLUSH_PR PPC_BIT(1)
+#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR PPC_BIT(2)
+
/* Each control block has to be on a 4K boundary */
#define H_CB_ALIGNMENT 4096
#define H_GET_HCA_INFO 0x1B8
#define H_GET_PERF_COUNT 0x1BC
#define H_MANAGE_TRACE 0x1C0
+#define H_GET_CPU_CHARACTERISTICS 0x1C8
#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
#define H_QUERY_INT_STATE 0x1E4
#define H_POLL_PENDING 0x1D8
#define H_XIRR_X 0x2FC
#define H_RANDOM 0x300
#define H_SET_MODE 0x31C
+#define H_RESIZE_HPT_PREPARE 0x36C
+#define H_RESIZE_HPT_COMMIT 0x370
#define H_CLEAN_SLB 0x374
#define H_INVALIDATE_PID 0x378
#define H_REGISTER_PROC_TBL 0x37C
* as well.
*
* We also need some hcalls which are specific to qemu / KVM-on-POWER.
- * So far we just need one for H_RTAS, but in future we'll need more
- * for extensions like virtio. We put those into the 0xf000-0xfffc
- * range which is reserved by PAPR for "platform-specific" hcalls.
+ * We put those into the 0xf000-0xfffc range which is reserved by PAPR
+ * for "platform-specific" hcalls.
*/
#define KVMPPC_HCALL_BASE 0xf000
#define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0)
#define RTAS_EVENT_SCAN_RATE 1
+/* This helper should be used to encode interrupt specifiers when the related
+ * "interrupt-controller" node has its "#interrupt-cells" property set to 2 (ie,
+ * VIO devices, RTAS event sources and PHBs).
+ */
+static inline void spapr_dt_xics_irq(uint32_t *intspec, int irq, bool is_lsi)
+{
+ intspec[0] = cpu_to_be32(irq);
+ intspec[1] = is_lsi ? cpu_to_be32(1) : 0;
+}
+
typedef struct sPAPRTCETable sPAPRTCETable;
#define TYPE_SPAPR_TCE_TABLE "spapr-tce-table"
#define SPAPR_TCE_TABLE(obj) \
OBJECT_CHECK(sPAPRTCETable, (obj), TYPE_SPAPR_TCE_TABLE)
+#define TYPE_SPAPR_IOMMU_MEMORY_REGION "spapr-iommu-memory-region"
+#define SPAPR_IOMMU_MEMORY_REGION(obj) \
+ OBJECT_CHECK(IOMMUMemoryRegion, (obj), TYPE_SPAPR_IOMMU_MEMORY_REGION)
+
struct sPAPRTCETable {
DeviceState parent;
uint32_t liobn;
bool bypass;
bool need_vfio;
int fd;
- MemoryRegion root, iommu;
+ MemoryRegion root;
+ IOMMUMemoryRegion iommu;
struct VIOsPAPRDevice *vdev; /* for @bypass migration compatibility only */
QLIST_ENTRY(sPAPRTCETable) list;
};
sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn);
struct sPAPREventLogEntry {
- int log_type;
- void *data;
+ uint32_t summary;
+ uint32_t extended_length;
+ void *extended_log;
QTAILQ_ENTRY(sPAPREventLogEntry) next;
};
uint32_t count, uint32_t index);
void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
uint32_t count, uint32_t index);
-void spapr_cpu_parse_features(sPAPRMachineState *spapr);
-void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset,
- sPAPRMachineState *spapr);
+int spapr_hpt_shift_for_ramsize(uint64_t ramsize);
+void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
+ Error **errp);
+void spapr_clear_pending_events(sPAPRMachineState *spapr);
/* CPU and LMB DRC release callbacks. */
void spapr_core_release(DeviceState *dev);
#define SPAPR_MAX_RAM_SLOTS 32
/* 1GB alignment for hotplug memory region */
-#define SPAPR_HOTPLUG_MEM_ALIGN (1ULL << 30)
+#define SPAPR_DEVICE_MEM_ALIGN (1 * GiB)
/*
* Number of 32 bit words in each LMB list entry in ibm,dynamic-memory
void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
+#define HTAB_SIZE(spapr) (1ULL << ((spapr)->htab_shift))
+
+int spapr_get_vcpu_id(PowerPCCPU *cpu);
+void spapr_set_vcpu_id(PowerPCCPU *cpu, int cpu_index, Error **errp);
+PowerPCCPU *spapr_find_cpu(int vcpu_id);
+
+int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align,
+ Error **errp);
+#define spapr_irq_findone(spapr, errp) spapr_irq_find(spapr, 1, false, errp)
+int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp);
+void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num);
+qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq);
+
+
+int spapr_caps_pre_load(void *opaque);
+int spapr_caps_pre_save(void *opaque);
+
+/*
+ * Handling of optional capabilities
+ */
+extern const VMStateDescription vmstate_spapr_cap_htm;
+extern const VMStateDescription vmstate_spapr_cap_vsx;
+extern const VMStateDescription vmstate_spapr_cap_dfp;
+extern const VMStateDescription vmstate_spapr_cap_cfpc;
+extern const VMStateDescription vmstate_spapr_cap_sbbc;
+extern const VMStateDescription vmstate_spapr_cap_ibs;
+
+static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
+{
+ return spapr->eff.caps[cap];
+}
+
+void spapr_caps_init(sPAPRMachineState *spapr);
+void spapr_caps_apply(sPAPRMachineState *spapr);
+void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu);
+void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp);
+int spapr_caps_post_migration(sPAPRMachineState *spapr);
+
+void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize,
+ Error **errp);
+
#endif /* HW_SPAPR_H */