mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-5.0-20200317' into staging
ppc patch queue 2020-03-17 Here's my final pull request for the qemu-5.0 soft freeze. Sorry this is just under the wire - I hit some last minute problems that took a while to fix up and retest. Highlights are: * Numerous fixes for the FWNMI feature * A handful of cleanups to the device tree construction code * Numerous fixes for the spapr-vscsi device * A number of fixes and cleanups for real mode (MMU off) softmmu handling * Fixes for handling of the PAPR RMA * Better handling of hotplug/unplug events during boot * Assorted other fixes # gpg: Signature made Tue 17 Mar 2020 09:55:07 GMT # gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full] # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full] # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full] # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown] # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-5.0-20200317: (45 commits) pseries: Update SLOF firmware image ppc/spapr: Ignore common "ibm,nmi-interlock" Linux bug ppc/spapr: Implement FWNMI System Reset delivery target/ppc: allow ppc_cpu_do_system_reset to take an alternate vector ppc/spapr: Allow FWNMI on TCG ppc/spapr: Fix FWNMI machine check interrupt delivery ppc/spapr: Add FWNMI System Reset state ppc/spapr: Change FWNMI names ppc/spapr: Fix FWNMI machine check failure handling spapr: Rename DT functions to newer naming convention spapr: Move creation of ibm,architecture-vec-5 property spapr: Move creation of ibm,dynamic-reconfiguration-memory dt node spapr/rtas: Reserve space for RTAS blob and log pseries: Update SLOF firmware image ppc/spapr: Move GPRs setup to one place target/ppc: Fix rlwinm on ppc64 spapr/xive: use SPAPR_IRQ_IPI to define IPI ranges exposed to the guest hw/scsi/spapr_vscsi: Convert debug fprintf() to trace event hw/scsi/spapr_vscsi: Prevent buffer overflow hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -289,6 +289,13 @@ The RISC-V no MMU cpus have been depcreated. The two CPUs: ``rv32imacu-nommu`` a
|
||||
``rv64imacu-nommu`` should no longer be used. Instead the MMU status can be specified
|
||||
via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
|
||||
|
||||
``compat`` property of server class POWER CPUs (since 5.0)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The ``compat`` property used to set backwards compatibility modes for
|
||||
the processor has been deprecated. The ``max-cpu-compat`` property of
|
||||
the ``pseries`` machine type should be used instead.
|
||||
|
||||
System emulator devices
|
||||
-----------------------
|
||||
|
||||
|
||||
@@ -677,8 +677,8 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
|
||||
uint64_t timas[2 * 2];
|
||||
/* Interrupt number ranges for the IPIs */
|
||||
uint32_t lisn_ranges[] = {
|
||||
cpu_to_be32(0),
|
||||
cpu_to_be32(nr_servers),
|
||||
cpu_to_be32(SPAPR_IRQ_IPI),
|
||||
cpu_to_be32(SPAPR_IRQ_IPI + nr_servers),
|
||||
};
|
||||
/*
|
||||
* EQ size - the sizes of pages supported by the system 4K, 64K,
|
||||
|
||||
+1
-1
@@ -829,7 +829,7 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
|
||||
bool hostboot_mode = !!pnv->fw_load_addr;
|
||||
|
||||
/* let isa_bus_new() create its own bridge on SysBus otherwise
|
||||
* devices speficied on the command line won't find the bus and
|
||||
* devices specified on the command line won't find the bus and
|
||||
* will fail to create.
|
||||
*/
|
||||
isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io, &local_err);
|
||||
|
||||
+495
-457
File diff suppressed because it is too large
Load Diff
+8
-11
@@ -509,17 +509,14 @@ static void cap_ccf_assist_apply(SpaprMachineState *spapr, uint8_t val,
|
||||
}
|
||||
}
|
||||
|
||||
static void cap_fwnmi_mce_apply(SpaprMachineState *spapr, uint8_t val,
|
||||
static void cap_fwnmi_apply(SpaprMachineState *spapr, uint8_t val,
|
||||
Error **errp)
|
||||
{
|
||||
if (!val) {
|
||||
return; /* Disabled by default */
|
||||
}
|
||||
|
||||
if (tcg_enabled()) {
|
||||
warn_report("Firmware Assisted Non-Maskable Interrupts(FWNMI) not "
|
||||
"supported in TCG");
|
||||
} else if (kvm_enabled()) {
|
||||
if (kvm_enabled()) {
|
||||
if (kvmppc_set_fwnmi() < 0) {
|
||||
error_setg(errp, "Firmware Assisted Non-Maskable Interrupts(FWNMI) "
|
||||
"not supported by KVM");
|
||||
@@ -626,14 +623,14 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
|
||||
.type = "bool",
|
||||
.apply = cap_ccf_assist_apply,
|
||||
},
|
||||
[SPAPR_CAP_FWNMI_MCE] = {
|
||||
.name = "fwnmi-mce",
|
||||
.description = "Handle fwnmi machine check exceptions",
|
||||
.index = SPAPR_CAP_FWNMI_MCE,
|
||||
[SPAPR_CAP_FWNMI] = {
|
||||
.name = "fwnmi",
|
||||
.description = "Implements PAPR FWNMI option",
|
||||
.index = SPAPR_CAP_FWNMI,
|
||||
.get = spapr_cap_get_bool,
|
||||
.set = spapr_cap_set_bool,
|
||||
.type = "bool",
|
||||
.apply = cap_fwnmi_mce_apply,
|
||||
.apply = cap_fwnmi_apply,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -774,7 +771,7 @@ SPAPR_CAP_MIG_STATE(hpt_maxpagesize, SPAPR_CAP_HPT_MAXPAGESIZE);
|
||||
SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
|
||||
SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
|
||||
SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
|
||||
SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI_MCE);
|
||||
SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI);
|
||||
|
||||
void spapr_caps_init(SpaprMachineState *spapr)
|
||||
{
|
||||
|
||||
+6
-10
@@ -50,22 +50,14 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
|
||||
* the settings below ensure proper operations with TCG in absence of
|
||||
* a real hypervisor.
|
||||
*
|
||||
* Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
|
||||
* real mode accesses, which thankfully defaults to 0 and isn't
|
||||
* accessible in guest mode.
|
||||
*
|
||||
* Disable Power-saving mode Exit Cause exceptions for the CPU, so
|
||||
* we don't get spurious wakups before an RTAS start-cpu call.
|
||||
* For the same reason, set PSSCR_EC.
|
||||
*/
|
||||
lpcr &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV | pcc->lpcr_pm);
|
||||
lpcr &= ~(LPCR_VPM1 | LPCR_ISL | LPCR_KBV | pcc->lpcr_pm);
|
||||
lpcr |= LPCR_LPES0 | LPCR_LPES1;
|
||||
env->spr[SPR_PSSCR] |= PSSCR_EC;
|
||||
|
||||
/* Set RMLS to the max (ie, 16G) */
|
||||
lpcr &= ~LPCR_RMLS;
|
||||
lpcr |= 1ull << LPCR_RMLS_SHIFT;
|
||||
|
||||
ppc_store_lpcr(cpu, lpcr);
|
||||
|
||||
/* Set a full AMOR so guest can use the AMR as it sees fit */
|
||||
@@ -84,13 +76,17 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
|
||||
spapr_irq_cpu_intc_reset(spapr, cpu);
|
||||
}
|
||||
|
||||
void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r3)
|
||||
void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip,
|
||||
target_ulong r1, target_ulong r3,
|
||||
target_ulong r4)
|
||||
{
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
env->nip = nip;
|
||||
env->gpr[1] = r1;
|
||||
env->gpr[3] = r3;
|
||||
env->gpr[4] = r4;
|
||||
kvmppc_set_reg_ppc_online(cpu, 1);
|
||||
CPU(cpu)->halted = 0;
|
||||
/* Enable Power-saving mode Exit Cause exceptions */
|
||||
|
||||
+23
-28
@@ -786,28 +786,12 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, bool recovered)
|
||||
{
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
CPUState *cs = CPU(cpu);
|
||||
uint64_t rtas_addr;
|
||||
CPUPPCState *env = &cpu->env;
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
target_ulong msr = 0;
|
||||
uint64_t rtas_addr;
|
||||
struct rtas_error_log log;
|
||||
struct mc_extended_log *ext_elog;
|
||||
uint32_t summary;
|
||||
|
||||
/*
|
||||
* Properly set bits in MSR before we invoke the handler.
|
||||
* SRR0/1, DAR and DSISR are properly set by KVM
|
||||
*/
|
||||
if (!(*pcc->interrupts_big_endian)(cpu)) {
|
||||
msr |= (1ULL << MSR_LE);
|
||||
}
|
||||
|
||||
if (env->msr & (1ULL << MSR_SF)) {
|
||||
msr |= (1ULL << MSR_SF);
|
||||
}
|
||||
|
||||
msr |= (1ULL << MSR_ME);
|
||||
|
||||
ext_elog = g_malloc0(sizeof(*ext_elog));
|
||||
summary = spapr_mce_get_elog_type(cpu, recovered, ext_elog);
|
||||
|
||||
@@ -823,8 +807,7 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, bool recovered)
|
||||
/* get rtas addr from fdt */
|
||||
rtas_addr = spapr_get_rtas_addr();
|
||||
if (!rtas_addr) {
|
||||
/* Unable to fetch rtas_addr. Hence reset the guest */
|
||||
ppc_cpu_do_system_reset(cs);
|
||||
qemu_system_guest_panicked(NULL);
|
||||
g_free(ext_elog);
|
||||
return;
|
||||
}
|
||||
@@ -836,12 +819,11 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, bool recovered)
|
||||
cpu_physical_memory_write(rtas_addr + RTAS_ERROR_LOG_OFFSET +
|
||||
sizeof(env->gpr[3]) + sizeof(log), ext_elog,
|
||||
sizeof(*ext_elog));
|
||||
g_free(ext_elog);
|
||||
|
||||
env->gpr[3] = rtas_addr + RTAS_ERROR_LOG_OFFSET;
|
||||
env->msr = msr;
|
||||
env->nip = spapr->guest_machine_check_addr;
|
||||
|
||||
g_free(ext_elog);
|
||||
ppc_cpu_do_fwnmi_machine_check(cs, spapr->fwnmi_machine_check_addr);
|
||||
}
|
||||
|
||||
void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
|
||||
@@ -851,7 +833,7 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
|
||||
int ret;
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (spapr->guest_machine_check_addr == -1) {
|
||||
if (spapr->fwnmi_machine_check_addr == -1) {
|
||||
/*
|
||||
* This implies that we have hit a machine check either when the
|
||||
* guest has not registered FWNMI (i.e., "ibm,nmi-register" not
|
||||
@@ -863,19 +845,19 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
|
||||
return;
|
||||
}
|
||||
|
||||
while (spapr->mc_status != -1) {
|
||||
while (spapr->fwnmi_machine_check_interlock != -1) {
|
||||
/*
|
||||
* Check whether the same CPU got machine check error
|
||||
* while still handling the mc error (i.e., before
|
||||
* that CPU called "ibm,nmi-interlock")
|
||||
*/
|
||||
if (spapr->mc_status == cpu->vcpu_id) {
|
||||
if (spapr->fwnmi_machine_check_interlock == cpu->vcpu_id) {
|
||||
qemu_system_guest_panicked(NULL);
|
||||
return;
|
||||
}
|
||||
qemu_cond_wait_iothread(&spapr->mc_delivery_cond);
|
||||
qemu_cond_wait_iothread(&spapr->fwnmi_machine_check_interlock_cond);
|
||||
/* Meanwhile if the system is reset, then just return */
|
||||
if (spapr->guest_machine_check_addr == -1) {
|
||||
if (spapr->fwnmi_machine_check_addr == -1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -891,7 +873,7 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
|
||||
warn_report("Received a fwnmi while migration was in progress");
|
||||
}
|
||||
|
||||
spapr->mc_status = cpu->vcpu_id;
|
||||
spapr->fwnmi_machine_check_interlock = cpu->vcpu_id;
|
||||
spapr_mce_dispatch_elog(cpu, recovered);
|
||||
}
|
||||
|
||||
@@ -983,6 +965,19 @@ void spapr_clear_pending_events(SpaprMachineState *spapr)
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_clear_pending_hotplug_events(SpaprMachineState *spapr)
|
||||
{
|
||||
SpaprEventLogEntry *entry = NULL, *next_entry;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(entry, &spapr->pending_events, next, next_entry) {
|
||||
if (spapr_event_log_entry_type(entry) == RTAS_LOG_TYPE_HOTPLUG) {
|
||||
QTAILQ_REMOVE(&spapr->pending_events, entry, next);
|
||||
g_free(entry->extended_log);
|
||||
g_free(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_events_init(SpaprMachineState *spapr)
|
||||
{
|
||||
int epow_irq = SPAPR_IRQ_EPOW;
|
||||
|
||||
@@ -1458,7 +1458,7 @@ static void spapr_check_setup_free_hpt(SpaprMachineState *spapr,
|
||||
spapr_free_hpt(spapr);
|
||||
} else if (!(patbe_new & PATE1_GR)) {
|
||||
/* RADIX->HASH || NOTHING->HASH : Allocate HPT */
|
||||
spapr_setup_hpt_and_vrma(spapr);
|
||||
spapr_setup_hpt(spapr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1640,7 +1640,7 @@ static uint32_t cas_check_pvr(SpaprMachineState *spapr, PowerPCCPU *cpu,
|
||||
return best_compat;
|
||||
}
|
||||
|
||||
static bool spapr_transient_dev_before_cas(void)
|
||||
static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr)
|
||||
{
|
||||
Object *drc_container;
|
||||
ObjectProperty *prop;
|
||||
@@ -1658,10 +1658,11 @@ static bool spapr_transient_dev_before_cas(void)
|
||||
prop->name, NULL));
|
||||
|
||||
if (spapr_drc_transient(drc)) {
|
||||
return true;
|
||||
spapr_drc_reset(drc);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
spapr_clear_pending_hotplug_events(spapr);
|
||||
}
|
||||
|
||||
static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
|
||||
@@ -1834,9 +1835,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
|
||||
|
||||
spapr_irq_update_active_intc(spapr);
|
||||
|
||||
if (spapr_transient_dev_before_cas()) {
|
||||
spapr->cas_reboot = true;
|
||||
}
|
||||
spapr_handle_transient_dev_before_cas(spapr);
|
||||
|
||||
if (!spapr->cas_reboot) {
|
||||
void *fdt;
|
||||
@@ -1846,7 +1845,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
|
||||
* (because the guest isn't going to use radix) then set it up here. */
|
||||
if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
|
||||
/* legacy hash or new hash: */
|
||||
spapr_setup_hpt_and_vrma(spapr);
|
||||
spapr_setup_hpt(spapr);
|
||||
}
|
||||
|
||||
if (fdt_bufsize < sizeof(hdr)) {
|
||||
|
||||
@@ -35,6 +35,7 @@ void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
|
||||
{
|
||||
char *uuidstr = NULL;
|
||||
QemuUUID uuid;
|
||||
int ret;
|
||||
|
||||
if (size % SPAPR_MINIMUM_SCM_BLOCK_SIZE) {
|
||||
error_setg(errp, "NVDIMM memory size excluding the label area"
|
||||
@@ -43,8 +44,10 @@ void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
|
||||
return;
|
||||
}
|
||||
|
||||
uuidstr = object_property_get_str(OBJECT(nvdimm), NVDIMM_UUID_PROP, NULL);
|
||||
qemu_uuid_parse(uuidstr, &uuid);
|
||||
uuidstr = object_property_get_str(OBJECT(nvdimm), NVDIMM_UUID_PROP,
|
||||
&error_abort);
|
||||
ret = qemu_uuid_parse(uuidstr, &uuid);
|
||||
g_assert(!ret);
|
||||
g_free(uuidstr);
|
||||
|
||||
if (qemu_uuid_is_null(&uuid)) {
|
||||
|
||||
+2
-2
@@ -200,8 +200,8 @@ SpaprOptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector)
|
||||
return ov;
|
||||
}
|
||||
|
||||
int spapr_ovec_populate_dt(void *fdt, int fdt_offset,
|
||||
SpaprOptionVector *ov, const char *name)
|
||||
int spapr_dt_ovec(void *fdt, int fdt_offset,
|
||||
SpaprOptionVector *ov, const char *name)
|
||||
{
|
||||
uint8_t vec[OV_MAXBYTES + 1];
|
||||
uint16_t vec_len;
|
||||
|
||||
+34
-11
@@ -190,7 +190,7 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr,
|
||||
*/
|
||||
newcpu->env.tb_env->tb_offset = callcpu->env.tb_env->tb_offset;
|
||||
|
||||
spapr_cpu_set_entry_state(newcpu, start, r3);
|
||||
spapr_cpu_set_entry_state(newcpu, start, 0, r3, 0);
|
||||
|
||||
qemu_cpu_kick(CPU(newcpu));
|
||||
|
||||
@@ -414,8 +414,9 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
hwaddr rtas_addr;
|
||||
target_ulong sreset_addr, mce_addr;
|
||||
|
||||
if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI_MCE) == SPAPR_CAP_OFF) {
|
||||
if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI) == SPAPR_CAP_OFF) {
|
||||
rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
@@ -426,7 +427,19 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
|
||||
return;
|
||||
}
|
||||
|
||||
spapr->guest_machine_check_addr = rtas_ld(args, 1);
|
||||
sreset_addr = rtas_ld(args, 0);
|
||||
mce_addr = rtas_ld(args, 1);
|
||||
|
||||
/* PAPR requires these are in the first 32M of memory and within RMA */
|
||||
if (sreset_addr >= 32 * MiB || sreset_addr >= spapr->rma_size ||
|
||||
mce_addr >= 32 * MiB || mce_addr >= spapr->rma_size) {
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
spapr->fwnmi_system_reset_addr = sreset_addr;
|
||||
spapr->fwnmi_machine_check_addr = mce_addr;
|
||||
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -436,29 +449,39 @@ static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI_MCE) == SPAPR_CAP_OFF) {
|
||||
if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI) == SPAPR_CAP_OFF) {
|
||||
rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (spapr->guest_machine_check_addr == -1) {
|
||||
if (spapr->fwnmi_machine_check_addr == -1) {
|
||||
/* NMI register not called */
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (spapr->mc_status != cpu->vcpu_id) {
|
||||
/* The vCPU that hit the NMI should invoke "ibm,nmi-interlock" */
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
if (spapr->fwnmi_machine_check_interlock != cpu->vcpu_id) {
|
||||
/*
|
||||
* The vCPU that hit the NMI should invoke "ibm,nmi-interlock"
|
||||
* This should be PARAM_ERROR, but Linux calls "ibm,nmi-interlock"
|
||||
* for system reset interrupts, despite them not being interlocked.
|
||||
* PowerVM silently ignores this and returns success here. Returning
|
||||
* failure causes Linux to print the error "FWNMI: nmi-interlock
|
||||
* failed: -3", although no other apparent ill effects, this is a
|
||||
* regression for the user when enabling FWNMI. So for now, match
|
||||
* PowerVM. When most Linux clients are fixed, this could be
|
||||
* changed.
|
||||
*/
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* vCPU issuing "ibm,nmi-interlock" is done with NMI handling,
|
||||
* hence unset mc_status.
|
||||
* hence unset fwnmi_machine_check_interlock.
|
||||
*/
|
||||
spapr->mc_status = -1;
|
||||
qemu_cond_signal(&spapr->mc_delivery_cond);
|
||||
spapr->fwnmi_machine_check_interlock = -1;
|
||||
qemu_cond_signal(&spapr->fwnmi_machine_check_interlock_cond);
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
migrate_del_blocker(spapr->fwnmi_migration_blocker);
|
||||
}
|
||||
|
||||
+42
-30
@@ -55,6 +55,8 @@
|
||||
#define VSCSI_MAX_SECTORS 4096
|
||||
#define VSCSI_REQ_LIMIT 24
|
||||
|
||||
/* Maximum size of a IU payload */
|
||||
#define SRP_MAX_IU_DATA_LEN (SRP_MAX_IU_LEN - sizeof(union srp_iu))
|
||||
#define SRP_RSP_SENSE_DATA_LEN 18
|
||||
|
||||
#define SRP_REPORT_LUNS_WLUN 0xc10100000000000ULL
|
||||
@@ -66,7 +68,7 @@ typedef union vscsi_crq {
|
||||
|
||||
typedef struct vscsi_req {
|
||||
vscsi_crq crq;
|
||||
union viosrp_iu iu;
|
||||
uint8_t viosrp_iu_buf[SRP_MAX_IU_LEN];
|
||||
|
||||
/* SCSI request tracking */
|
||||
SCSIRequest *sreq;
|
||||
@@ -97,6 +99,11 @@ typedef struct {
|
||||
vscsi_req reqs[VSCSI_REQ_LIMIT];
|
||||
} VSCSIState;
|
||||
|
||||
static union viosrp_iu *req_iu(vscsi_req *req)
|
||||
{
|
||||
return (union viosrp_iu *)req->viosrp_iu_buf;
|
||||
}
|
||||
|
||||
static struct vscsi_req *vscsi_get_req(VSCSIState *s)
|
||||
{
|
||||
vscsi_req *req;
|
||||
@@ -121,7 +128,7 @@ static struct vscsi_req *vscsi_find_req(VSCSIState *s, uint64_t srp_tag)
|
||||
|
||||
for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
|
||||
req = &s->reqs[i];
|
||||
if (req->iu.srp.cmd.tag == srp_tag) {
|
||||
if (req_iu(req)->srp.cmd.tag == srp_tag) {
|
||||
return req;
|
||||
}
|
||||
}
|
||||
@@ -176,9 +183,11 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
|
||||
{
|
||||
long rc, rc1;
|
||||
|
||||
assert(length <= SRP_MAX_IU_LEN);
|
||||
|
||||
/* First copy the SRP */
|
||||
rc = spapr_vio_dma_write(&s->vdev, req->crq.s.IU_data_ptr,
|
||||
&req->iu, length);
|
||||
&req->viosrp_iu_buf, length);
|
||||
if (rc) {
|
||||
fprintf(stderr, "vscsi_send_iu: DMA write failure !\n");
|
||||
}
|
||||
@@ -188,7 +197,7 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
|
||||
req->crq.s.reserved = 0x00;
|
||||
req->crq.s.timeout = cpu_to_be16(0x0000);
|
||||
req->crq.s.IU_length = cpu_to_be16(length);
|
||||
req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */
|
||||
req->crq.s.IU_data_ptr = req_iu(req)->srp.rsp.tag; /* right byte order */
|
||||
|
||||
if (rc == 0) {
|
||||
req->crq.s.status = VIOSRP_OK;
|
||||
@@ -224,7 +233,7 @@ static void vscsi_makeup_sense(VSCSIState *s, vscsi_req *req,
|
||||
static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req,
|
||||
uint8_t status, int32_t res_in, int32_t res_out)
|
||||
{
|
||||
union viosrp_iu *iu = &req->iu;
|
||||
union viosrp_iu *iu = req_iu(req);
|
||||
uint64_t tag = iu->srp.rsp.tag;
|
||||
int total_len = sizeof(iu->srp.rsp);
|
||||
uint8_t sol_not = iu->srp.cmd.sol_not;
|
||||
@@ -261,10 +270,12 @@ static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req,
|
||||
if (status) {
|
||||
iu->srp.rsp.sol_not = (sol_not & 0x04) >> 2;
|
||||
if (req->senselen) {
|
||||
req->iu.srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
|
||||
req->iu.srp.rsp.sense_data_len = cpu_to_be32(req->senselen);
|
||||
memcpy(req->iu.srp.rsp.data, req->sense, req->senselen);
|
||||
total_len += req->senselen;
|
||||
int sense_data_len = MIN(req->senselen, SRP_MAX_IU_DATA_LEN);
|
||||
|
||||
iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
|
||||
iu->srp.rsp.sense_data_len = cpu_to_be32(sense_data_len);
|
||||
memcpy(iu->srp.rsp.data, req->sense, sense_data_len);
|
||||
total_len += sense_data_len;
|
||||
}
|
||||
} else {
|
||||
iu->srp.rsp.sol_not = (sol_not & 0x02) >> 1;
|
||||
@@ -285,7 +296,7 @@ static int vscsi_fetch_desc(VSCSIState *s, struct vscsi_req *req,
|
||||
unsigned n, unsigned buf_offset,
|
||||
struct srp_direct_buf *ret)
|
||||
{
|
||||
struct srp_cmd *cmd = &req->iu.srp.cmd;
|
||||
struct srp_cmd *cmd = &req_iu(req)->srp.cmd;
|
||||
|
||||
switch (req->dma_fmt) {
|
||||
case SRP_NO_DATA_DESC: {
|
||||
@@ -473,7 +484,7 @@ static int data_out_desc_size(struct srp_cmd *cmd)
|
||||
|
||||
static int vscsi_preprocess_desc(vscsi_req *req)
|
||||
{
|
||||
struct srp_cmd *cmd = &req->iu.srp.cmd;
|
||||
struct srp_cmd *cmd = &req_iu(req)->srp.cmd;
|
||||
|
||||
req->cdb_offset = cmd->add_cdb_len & ~3;
|
||||
|
||||
@@ -597,7 +608,7 @@ static const VMStateDescription vmstate_spapr_vscsi_req = {
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_BUFFER(crq.raw, vscsi_req),
|
||||
VMSTATE_BUFFER(iu.srp.reserved, vscsi_req),
|
||||
VMSTATE_BUFFER(viosrp_iu_buf, vscsi_req),
|
||||
VMSTATE_UINT32(qtag, vscsi_req),
|
||||
VMSTATE_BOOL(active, vscsi_req),
|
||||
VMSTATE_UINT32(data_len, vscsi_req),
|
||||
@@ -655,7 +666,7 @@ static void *vscsi_load_request(QEMUFile *f, SCSIRequest *sreq)
|
||||
|
||||
static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
|
||||
{
|
||||
union viosrp_iu *iu = &req->iu;
|
||||
union viosrp_iu *iu = req_iu(req);
|
||||
struct srp_login_rsp *rsp = &iu->srp.login_rsp;
|
||||
uint64_t tag = iu->srp.rsp.tag;
|
||||
|
||||
@@ -671,8 +682,8 @@ static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
|
||||
*/
|
||||
rsp->req_lim_delta = cpu_to_be32(VSCSI_REQ_LIMIT-2);
|
||||
rsp->tag = tag;
|
||||
rsp->max_it_iu_len = cpu_to_be32(sizeof(union srp_iu));
|
||||
rsp->max_ti_iu_len = cpu_to_be32(sizeof(union srp_iu));
|
||||
rsp->max_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);
|
||||
rsp->max_ti_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);
|
||||
/* direct and indirect */
|
||||
rsp->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT);
|
||||
|
||||
@@ -681,7 +692,7 @@ static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
|
||||
|
||||
static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req)
|
||||
{
|
||||
uint8_t *cdb = req->iu.srp.cmd.cdb;
|
||||
uint8_t *cdb = req_iu(req)->srp.cmd.cdb;
|
||||
uint8_t resp_data[36];
|
||||
int rc, len, alen;
|
||||
|
||||
@@ -770,7 +781,7 @@ static void vscsi_report_luns(VSCSIState *s, vscsi_req *req)
|
||||
|
||||
static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
|
||||
{
|
||||
union srp_iu *srp = &req->iu.srp;
|
||||
union srp_iu *srp = &req_iu(req)->srp;
|
||||
SCSIDevice *sdev;
|
||||
int n, lun;
|
||||
|
||||
@@ -821,17 +832,16 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
|
||||
|
||||
static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
|
||||
{
|
||||
union viosrp_iu *iu = &req->iu;
|
||||
union viosrp_iu *iu = req_iu(req);
|
||||
vscsi_req *tmpreq;
|
||||
int i, lun = 0, resp = SRP_TSK_MGMT_COMPLETE;
|
||||
SCSIDevice *d;
|
||||
uint64_t tag = iu->srp.rsp.tag;
|
||||
uint8_t sol_not = iu->srp.cmd.sol_not;
|
||||
|
||||
fprintf(stderr, "vscsi_process_tsk_mgmt %02x\n",
|
||||
iu->srp.tsk_mgmt.tsk_mgmt_func);
|
||||
|
||||
d = vscsi_device_find(&s->bus, be64_to_cpu(req->iu.srp.tsk_mgmt.lun), &lun);
|
||||
trace_spapr_vscsi_process_tsk_mgmt(iu->srp.tsk_mgmt.tsk_mgmt_func);
|
||||
d = vscsi_device_find(&s->bus,
|
||||
be64_to_cpu(req_iu(req)->srp.tsk_mgmt.lun), &lun);
|
||||
if (!d) {
|
||||
resp = SRP_TSK_MGMT_FIELDS_INVALID;
|
||||
} else {
|
||||
@@ -842,7 +852,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
|
||||
break;
|
||||
}
|
||||
|
||||
tmpreq = vscsi_find_req(s, req->iu.srp.tsk_mgmt.task_tag);
|
||||
tmpreq = vscsi_find_req(s, req_iu(req)->srp.tsk_mgmt.task_tag);
|
||||
if (tmpreq && tmpreq->sreq) {
|
||||
assert(tmpreq->sreq->hba_private);
|
||||
scsi_req_cancel(tmpreq->sreq);
|
||||
@@ -867,7 +877,8 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
|
||||
|
||||
for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
|
||||
tmpreq = &s->reqs[i];
|
||||
if (tmpreq->iu.srp.cmd.lun != req->iu.srp.tsk_mgmt.lun) {
|
||||
if (req_iu(tmpreq)->srp.cmd.lun
|
||||
!= req_iu(req)->srp.tsk_mgmt.lun) {
|
||||
continue;
|
||||
}
|
||||
if (!tmpreq->active || !tmpreq->sreq) {
|
||||
@@ -889,6 +900,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
|
||||
}
|
||||
|
||||
/* Compose the response here as */
|
||||
QEMU_BUILD_BUG_ON(SRP_MAX_IU_DATA_LEN < 4);
|
||||
memset(iu, 0, sizeof(struct srp_rsp) + 4);
|
||||
iu->srp.rsp.opcode = SRP_RSP;
|
||||
iu->srp.rsp.req_lim_delta = cpu_to_be32(1);
|
||||
@@ -911,7 +923,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
|
||||
|
||||
static int vscsi_handle_srp_req(VSCSIState *s, vscsi_req *req)
|
||||
{
|
||||
union srp_iu *srp = &req->iu.srp;
|
||||
union srp_iu *srp = &req_iu(req)->srp;
|
||||
int done = 1;
|
||||
uint8_t opcode = srp->rsp.opcode;
|
||||
|
||||
@@ -948,7 +960,7 @@ static int vscsi_send_adapter_info(VSCSIState *s, vscsi_req *req)
|
||||
struct mad_adapter_info_data info;
|
||||
int rc;
|
||||
|
||||
sinfo = &req->iu.mad.adapter_info;
|
||||
sinfo = &req_iu(req)->mad.adapter_info;
|
||||
|
||||
#if 0 /* What for ? */
|
||||
rc = spapr_vio_dma_read(&s->vdev, be64_to_cpu(sinfo->buffer),
|
||||
@@ -984,7 +996,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req)
|
||||
uint64_t buffer;
|
||||
int rc;
|
||||
|
||||
vcap = &req->iu.mad.capabilities;
|
||||
vcap = &req_iu(req)->mad.capabilities;
|
||||
req_len = len = be16_to_cpu(vcap->common.length);
|
||||
buffer = be64_to_cpu(vcap->buffer);
|
||||
if (len > sizeof(cap)) {
|
||||
@@ -1029,7 +1041,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req)
|
||||
|
||||
static int vscsi_handle_mad_req(VSCSIState *s, vscsi_req *req)
|
||||
{
|
||||
union mad_iu *mad = &req->iu.mad;
|
||||
union mad_iu *mad = &req_iu(req)->mad;
|
||||
bool request_handled = false;
|
||||
uint64_t retlen = 0;
|
||||
|
||||
@@ -1088,7 +1100,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
|
||||
* in our 256 bytes IUs. If not we'll have to increase the size
|
||||
* of the structure.
|
||||
*/
|
||||
if (crq->s.IU_length > sizeof(union viosrp_iu)) {
|
||||
if (crq->s.IU_length > SRP_MAX_IU_LEN) {
|
||||
fprintf(stderr, "VSCSI: SRP IU too long (%d bytes) !\n",
|
||||
crq->s.IU_length);
|
||||
vscsi_put_req(req);
|
||||
@@ -1096,7 +1108,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
|
||||
}
|
||||
|
||||
/* XXX Handle failure differently ? */
|
||||
if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu,
|
||||
if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->viosrp_iu_buf,
|
||||
crq->s.IU_length)) {
|
||||
fprintf(stderr, "vscsi_got_payload: DMA read failure !\n");
|
||||
vscsi_put_req(req);
|
||||
|
||||
@@ -227,6 +227,7 @@ spapr_vscsi_command_complete_status(uint32_t status) "Command complete err=%"PRI
|
||||
spapr_vscsi_save_request(uint32_t qtag, unsigned desc, unsigned offset) "saving tag=%"PRIu32", current desc#%u, offset=0x%x"
|
||||
spapr_vscsi_load_request(uint32_t qtag, unsigned desc, unsigned offset) "restoring tag=%"PRIu32", current desc#%u, offset=0x%x"
|
||||
spapr_vscsi_process_login(void) "Got login, sending response !"
|
||||
spapr_vscsi_process_tsk_mgmt(uint8_t func) "tsk_mgmt_func 0x%02x"
|
||||
spapr_vscsi_queue_cmd_no_drive(uint64_t lun) "Command for lun 0x%08" PRIx64 " with no drive"
|
||||
spapr_vscsi_queue_cmd(uint32_t qtag, unsigned cdb, const char *cmd, int lun, int ret) "Queued command tag 0x%"PRIx32" CMD 0x%x=%s LUN %d ret: %d"
|
||||
spapr_vscsi_do_crq(unsigned c0, unsigned c1) "crq: %02x %02x ..."
|
||||
|
||||
+2
-1
@@ -34,6 +34,8 @@
|
||||
#ifndef PPC_VIOSRP_H
|
||||
#define PPC_VIOSRP_H
|
||||
|
||||
#include "hw/scsi/srp.h"
|
||||
|
||||
#define SRP_VERSION "16.a"
|
||||
#define SRP_MAX_IU_LEN 256
|
||||
#define SRP_MAX_LOC_LEN 32
|
||||
@@ -47,7 +49,6 @@ union srp_iu {
|
||||
struct srp_tsk_mgmt tsk_mgmt;
|
||||
struct srp_cmd cmd;
|
||||
struct srp_rsp rsp;
|
||||
uint8_t reserved[SRP_MAX_IU_LEN];
|
||||
};
|
||||
|
||||
enum viosrp_crq_formats {
|
||||
|
||||
+22
-12
@@ -79,10 +79,10 @@ typedef enum {
|
||||
#define SPAPR_CAP_LARGE_DECREMENTER 0x08
|
||||
/* Count Cache Flush Assist HW Instruction */
|
||||
#define SPAPR_CAP_CCF_ASSIST 0x09
|
||||
/* FWNMI machine check handling */
|
||||
#define SPAPR_CAP_FWNMI_MCE 0x0A
|
||||
/* Implements PAPR FWNMI option */
|
||||
#define SPAPR_CAP_FWNMI 0x0A
|
||||
/* Num Caps */
|
||||
#define SPAPR_CAP_NUM (SPAPR_CAP_FWNMI_MCE + 1)
|
||||
#define SPAPR_CAP_NUM (SPAPR_CAP_FWNMI + 1)
|
||||
|
||||
/*
|
||||
* Capability Values
|
||||
@@ -126,6 +126,7 @@ struct SpaprMachineClass {
|
||||
bool pre_4_1_migration; /* don't migrate hpt-max-page-size */
|
||||
bool linux_pci_probe;
|
||||
bool smp_threads_vsmt; /* set VSMT to smp_threads by default */
|
||||
hwaddr rma_limit; /* clamp the RMA to this size */
|
||||
|
||||
void (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
|
||||
uint64_t *buid, hwaddr *pio,
|
||||
@@ -156,7 +157,6 @@ struct SpaprMachineState {
|
||||
SpaprPendingHpt *pending_hpt; /* in-progress resize */
|
||||
|
||||
hwaddr rma_size;
|
||||
int vrma_adjust;
|
||||
uint32_t fdt_size;
|
||||
uint32_t fdt_initial_size;
|
||||
void *fdt_blob;
|
||||
@@ -192,14 +192,22 @@ struct SpaprMachineState {
|
||||
* occurs during the unplug process. */
|
||||
QTAILQ_HEAD(, SpaprDimmState) pending_dimm_unplugs;
|
||||
|
||||
/* State related to "ibm,nmi-register" and "ibm,nmi-interlock" calls */
|
||||
target_ulong guest_machine_check_addr;
|
||||
/*
|
||||
* mc_status is set to -1 if mc is not in progress, else is set to the CPU
|
||||
* handling the mc.
|
||||
/* State related to FWNMI option */
|
||||
|
||||
/* System Reset and Machine Check Notification Routine addresses
|
||||
* registered by "ibm,nmi-register" RTAS call.
|
||||
*/
|
||||
int mc_status;
|
||||
QemuCond mc_delivery_cond;
|
||||
target_ulong fwnmi_system_reset_addr;
|
||||
target_ulong fwnmi_machine_check_addr;
|
||||
|
||||
/* Machine Check FWNMI synchronization, fwnmi_machine_check_interlock is
|
||||
* set to -1 if a FWNMI machine check is not in progress, else is set to
|
||||
* the CPU that was delivered the machine check, and is set back to -1
|
||||
* when that CPU makes an "ibm,nmi-interlock" RTAS call. The cond is used
|
||||
* to synchronize other CPUs.
|
||||
*/
|
||||
int fwnmi_machine_check_interlock;
|
||||
QemuCond fwnmi_machine_check_interlock_cond;
|
||||
|
||||
/*< public >*/
|
||||
char *kvm_type;
|
||||
@@ -736,6 +744,7 @@ void spapr_load_rtas(SpaprMachineState *spapr, void *fdt, hwaddr addr);
|
||||
#define SPAPR_IS_PCI_LIOBN(liobn) (!!((liobn) & 0x80000000))
|
||||
#define SPAPR_PCI_DMA_WINDOW_NUM(liobn) ((liobn) & 0xff)
|
||||
|
||||
#define RTAS_SIZE 2048
|
||||
#define RTAS_ERROR_LOG_MAX 2048
|
||||
|
||||
/* Offset from rtas-base where error log is placed */
|
||||
@@ -795,7 +804,7 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space);
|
||||
void spapr_events_init(SpaprMachineState *sm);
|
||||
void spapr_dt_events(SpaprMachineState *sm, void *fdt);
|
||||
void close_htab_fd(SpaprMachineState *spapr);
|
||||
void spapr_setup_hpt_and_vrma(SpaprMachineState *spapr);
|
||||
void spapr_setup_hpt(SpaprMachineState *spapr);
|
||||
void spapr_free_hpt(SpaprMachineState *spapr);
|
||||
SpaprTceTable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn);
|
||||
void spapr_tce_table_enable(SpaprTceTable *tcet,
|
||||
@@ -824,6 +833,7 @@ 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);
|
||||
void spapr_clear_pending_hotplug_events(SpaprMachineState *spapr);
|
||||
int spapr_max_server_number(SpaprMachineState *spapr);
|
||||
void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
|
||||
uint64_t pte0, uint64_t pte1);
|
||||
|
||||
@@ -40,7 +40,9 @@ typedef struct SpaprCpuCoreClass {
|
||||
} SpaprCpuCoreClass;
|
||||
|
||||
const char *spapr_get_cpu_core_type(const char *cpu_type);
|
||||
void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r3);
|
||||
void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip,
|
||||
target_ulong r1, target_ulong r3,
|
||||
target_ulong r4);
|
||||
|
||||
typedef struct SpaprCpuState {
|
||||
uint64_t vpa_addr;
|
||||
|
||||
@@ -72,8 +72,8 @@ void spapr_ovec_set(SpaprOptionVector *ov, long bitnr);
|
||||
void spapr_ovec_clear(SpaprOptionVector *ov, long bitnr);
|
||||
bool spapr_ovec_test(SpaprOptionVector *ov, long bitnr);
|
||||
SpaprOptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector);
|
||||
int spapr_ovec_populate_dt(void *fdt, int fdt_offset,
|
||||
SpaprOptionVector *ov, const char *name);
|
||||
int spapr_dt_ovec(void *fdt, int fdt_offset,
|
||||
SpaprOptionVector *ov, const char *name);
|
||||
|
||||
/* migration */
|
||||
extern const VMStateDescription vmstate_spapr_ovec;
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
|
||||
implementation for certain IBM POWER hardware. The sources are at
|
||||
https://github.com/aik/SLOF, and the image currently in qemu is
|
||||
built from git tag qemu-slof-20191217.
|
||||
built from git tag qemu-slof-20200317.
|
||||
|
||||
- sgabios (the Serial Graphics Adapter option ROM) provides a means for
|
||||
legacy x86 software to communicate with an attached serial console as
|
||||
|
||||
Binary file not shown.
+1
-1
Submodule roms/SLOF updated: 9546892a80...ab6984f5a6
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user