pseries: Add H_SET_MODE hcall to change guest exception endianness
H_SET_MODE is used for controlling various partition settings. One of these settings is the endianness a guest takes its exceptions in. Signed-off-by: Anton Blanchard <anton@samba.org> [agraf: fix whitespace] Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
33a0e5d8c5
commit
42561bf2e4
@ -282,7 +282,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
|
|||||||
uint32_t start_prop = cpu_to_be32(initrd_base);
|
uint32_t start_prop = cpu_to_be32(initrd_base);
|
||||||
uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
|
uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
|
||||||
char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
|
char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
|
||||||
"\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk";
|
"\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk\0hcall-set-mode";
|
||||||
char qemu_hypertas_prop[] = "hcall-memop1";
|
char qemu_hypertas_prop[] = "hcall-memop1";
|
||||||
uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
|
uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
|
||||||
uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
|
uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
|
||||||
|
@ -657,6 +657,54 @@ static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
|||||||
return H_SUCCESS;
|
return H_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||||
|
target_ulong opcode, target_ulong *args)
|
||||||
|
{
|
||||||
|
CPUState *cs;
|
||||||
|
target_ulong mflags = args[0];
|
||||||
|
target_ulong resource = args[1];
|
||||||
|
target_ulong value1 = args[2];
|
||||||
|
target_ulong value2 = args[3];
|
||||||
|
target_ulong ret = H_P2;
|
||||||
|
|
||||||
|
if (resource == H_SET_MODE_ENDIAN) {
|
||||||
|
if (value1) {
|
||||||
|
ret = H_P3;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (value2) {
|
||||||
|
ret = H_P4;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mflags) {
|
||||||
|
case H_SET_MODE_ENDIAN_BIG:
|
||||||
|
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
|
||||||
|
PowerPCCPU *cp = POWERPC_CPU(cs);
|
||||||
|
CPUPPCState *env = &cp->env;
|
||||||
|
env->spr[SPR_LPCR] &= ~LPCR_ILE;
|
||||||
|
}
|
||||||
|
ret = H_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_SET_MODE_ENDIAN_LITTLE:
|
||||||
|
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
|
||||||
|
PowerPCCPU *cp = POWERPC_CPU(cs);
|
||||||
|
CPUPPCState *env = &cp->env;
|
||||||
|
env->spr[SPR_LPCR] |= LPCR_ILE;
|
||||||
|
}
|
||||||
|
ret = H_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = H_UNSUPPORTED_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
|
static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
|
||||||
static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
|
static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
|
||||||
|
|
||||||
@ -734,6 +782,8 @@ static void hypercall_register_types(void)
|
|||||||
|
|
||||||
/* qemu/KVM-PPC specific hcalls */
|
/* qemu/KVM-PPC specific hcalls */
|
||||||
spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
|
spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
|
||||||
|
|
||||||
|
spapr_register_hypercall(H_SET_MODE, h_set_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
type_init(hypercall_register_types)
|
type_init(hypercall_register_types)
|
||||||
|
@ -111,6 +111,15 @@ typedef struct sPAPREnvironment {
|
|||||||
#define H_NOT_ENOUGH_RESOURCES -44
|
#define H_NOT_ENOUGH_RESOURCES -44
|
||||||
#define H_R_STATE -45
|
#define H_R_STATE -45
|
||||||
#define H_RESCINDEND -46
|
#define H_RESCINDEND -46
|
||||||
|
#define H_P2 -55
|
||||||
|
#define H_P3 -56
|
||||||
|
#define H_P4 -57
|
||||||
|
#define H_P5 -58
|
||||||
|
#define H_P6 -59
|
||||||
|
#define H_P7 -60
|
||||||
|
#define H_P8 -61
|
||||||
|
#define H_P9 -62
|
||||||
|
#define H_UNSUPPORTED_FLAG -256
|
||||||
#define H_MULTI_THREADS_ACTIVE -9005
|
#define H_MULTI_THREADS_ACTIVE -9005
|
||||||
|
|
||||||
|
|
||||||
@ -145,6 +154,11 @@ typedef struct sPAPREnvironment {
|
|||||||
#define H_PP1 (1ULL<<(63-62))
|
#define H_PP1 (1ULL<<(63-62))
|
||||||
#define H_PP2 (1ULL<<(63-63))
|
#define H_PP2 (1ULL<<(63-63))
|
||||||
|
|
||||||
|
/* H_SET_MODE flags */
|
||||||
|
#define H_SET_MODE_ENDIAN 4
|
||||||
|
#define H_SET_MODE_ENDIAN_BIG 0
|
||||||
|
#define H_SET_MODE_ENDIAN_LITTLE 1
|
||||||
|
|
||||||
/* VASI States */
|
/* VASI States */
|
||||||
#define H_VASI_INVALID 0
|
#define H_VASI_INVALID 0
|
||||||
#define H_VASI_ENABLED 1
|
#define H_VASI_ENABLED 1
|
||||||
@ -269,7 +283,8 @@ typedef struct sPAPREnvironment {
|
|||||||
#define H_GET_EM_PARMS 0x2B8
|
#define H_GET_EM_PARMS 0x2B8
|
||||||
#define H_SET_MPP 0x2D0
|
#define H_SET_MPP 0x2D0
|
||||||
#define H_GET_MPP 0x2D4
|
#define H_GET_MPP 0x2D4
|
||||||
#define MAX_HCALL_OPCODE H_GET_MPP
|
#define H_SET_MODE 0x31C
|
||||||
|
#define MAX_HCALL_OPCODE H_SET_MODE
|
||||||
|
|
||||||
/* The hcalls above are standardized in PAPR and implemented by pHyp
|
/* The hcalls above are standardized in PAPR and implemented by pHyp
|
||||||
* as well.
|
* as well.
|
||||||
|
Loading…
Reference in New Issue
Block a user