diff mbox series

[RFC,v3,1/5] ppc64: Add semihosting support

Message ID 20220418191100.270334-2-leandro.lupori@eldorado.org.br
State New
Headers show
Series Port PPC64/PowerNV MMU tests to QEMU | expand

Commit Message

Leandro Lupori April 18, 2022, 7:10 p.m. UTC
Add semihosting support for PPC64. This implementation is
based on the standard for ARM semihosting version 2.0, as
implemented by QEMU and documented in

    https://github.com/ARM-software/abi-aa/releases

The PPC64 specific differences are the following:

Semihosting Trap Instruction: sc 7
Operation Number Register: r3
Parameter Register: r4
Return Register: r3
Data block field size: 64 bits

Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br>
---
 configs/devices/ppc64-softmmu/default.mak |  3 +++
 qemu-options.hx                           | 18 ++++++++-----
 semihosting/arm-compat-semi.c             | 33 +++++++++++++++++++++++
 target/ppc/cpu.h                          |  3 ++-
 target/ppc/excp_helper.c                  |  9 +++++++
 target/ppc/translate.c                    | 14 ++++++++++
 6 files changed, 72 insertions(+), 8 deletions(-)

Comments

Cédric Le Goater April 18, 2022, 8:22 p.m. UTC | #1
On 4/18/22 21:10, Leandro Lupori wrote:
> Add semihosting support for PPC64. This implementation is
> based on the standard for ARM semihosting version 2.0, as
> implemented by QEMU and documented in
> 
>      https://github.com/ARM-software/abi-aa/releases
> 
> The PPC64 specific differences are the following:
> 
> Semihosting Trap Instruction: sc 7
> Operation Number Register: r3
> Parameter Register: r4
> Return Register: r3
> Data block field size: 64 bits

'sc' is a good way to implement semi hosting but we should make sure
that it is not colliding with future extensions, at least with the
next POWERPC processor. Is that the case ? if not, then the lev could
be reserved.

I think the part adding POWERPC_EXCP_SEMIHOST should be proposed in a
separate patch.

> Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br>
> ---
>   configs/devices/ppc64-softmmu/default.mak |  3 +++
>   qemu-options.hx                           | 18 ++++++++-----
>   semihosting/arm-compat-semi.c             | 33 +++++++++++++++++++++++
>   target/ppc/cpu.h                          |  3 ++-
>   target/ppc/excp_helper.c                  |  9 +++++++
>   target/ppc/translate.c                    | 14 ++++++++++
>   6 files changed, 72 insertions(+), 8 deletions(-)
> 
> diff --git a/configs/devices/ppc64-softmmu/default.mak b/configs/devices/ppc64-softmmu/default.mak
> index b90e5bf455..43b618fa32 100644
> --- a/configs/devices/ppc64-softmmu/default.mak
> +++ b/configs/devices/ppc64-softmmu/default.mak
> @@ -8,3 +8,6 @@ CONFIG_POWERNV=y
>   
>   # For pSeries
>   CONFIG_PSERIES=y
> +
> +CONFIG_SEMIHOSTING=y
> +CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 34e9b32a5c..6e76f7de96 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -4527,11 +4527,12 @@ SRST
>   ERST
>   DEF("semihosting", 0, QEMU_OPTION_semihosting,
>       "-semihosting    semihosting mode\n",
> -    QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA |
> -    QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
> +    QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_MIPS |
> +    QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV | QEMU_ARCH_PPC)
>   SRST
>   ``-semihosting``
> -    Enable semihosting mode (ARM, M68K, Xtensa, MIPS, Nios II, RISC-V only).
> +    Enable semihosting mode (ARM, M68K, Xtensa, MIPS, Nios II, RISC-V and
> +    PPC only).
>   
>       Note that this allows guest direct access to the host filesystem, so
>       should only be used with a trusted guest OS.
> @@ -4542,12 +4543,12 @@ ERST
>   DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config,
>       "-semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]\n" \
>       "                semihosting configuration\n",
> -QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA |
> -QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
> +QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_MIPS |
> +QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV | QEMU_ARCH_PPC)
>   SRST
>   ``-semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]``
> -    Enable and configure semihosting (ARM, M68K, Xtensa, MIPS, Nios II, RISC-V
> -    only).
> +    Enable and configure semihosting (ARM, M68K, Xtensa, MIPS, Nios II,
> +    RISC-V, PPC only).
>   
>       Note that this allows guest direct access to the host filesystem, so
>       should only be used with a trusted guest OS.
> @@ -4563,6 +4564,9 @@ SRST
>   
>       On RISC-V this implements the standard semihosting API, version 0.2.
>   
> +    On PPC this implements the standard Arm semihosting API, version 2.0,
> +    with only the trap instruction and register definitions changed.
> +
>       ``target=native|gdb|auto``
>           Defines where the semihosting calls will be addressed, to QEMU
>           (``native``) or to GDB (``gdb``). The default is ``auto``, which
> diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
> index 7a51fd0737..e1279c316c 100644
> --- a/semihosting/arm-compat-semi.c
> +++ b/semihosting/arm-compat-semi.c
> @@ -268,6 +268,31 @@ common_semi_sys_exit_extended(CPUState *cs, int nr)
>   
>   #endif
>   
> +#ifdef TARGET_PPC64

This PPC ifdef in an ARM file seems wrong.

The rest looks OK.

Thanks,

C.


> +static inline target_ulong
> +common_semi_arg(CPUState *cs, int argno)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +    return env->gpr[3 + argno];
> +}
> +
> +static inline void
> +common_semi_set_ret(CPUState *cs, target_ulong ret)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +    env->gpr[3] = ret;
> +}
> +
> +static inline bool
> +common_semi_sys_exit_extended(CPUState *cs, int nr)
> +{
> +    return (nr == TARGET_SYS_EXIT_EXTENDED || sizeof(target_ulong) == 8);
> +}
> +
> +#endif
> +
>   /*
>    * Allocate a new guest file descriptor and return it; if we
>    * couldn't allocate a new fd then return -1.
> @@ -450,6 +475,12 @@ static target_ulong common_semi_flen_buf(CPUState *cs)
>   
>       sp = env->gpr[xSP];
>   #endif
> +#ifdef TARGET_PPC64
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +
> +    sp = env->gpr[1];
> +#endif
>   
>       return sp - 64;
>   }
> @@ -780,6 +811,8 @@ static inline bool is_64bit_semihosting(CPUArchState *env)
>       return is_a64(env);
>   #elif defined(TARGET_RISCV)
>       return riscv_cpu_mxl(env) != MXL_RV32;
> +#elif defined(TARGET_PPC64)
> +    return true;
>   #else
>   #error un-handled architecture
>   #endif
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 047b24ba50..349104ad79 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -129,8 +129,9 @@ enum {
>       POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception                     */
>       POWERPC_EXCP_PERFM_EBB = 103,    /* Performance Monitor EBB Exception    */
>       POWERPC_EXCP_EXTERNAL_EBB = 104, /* External EBB Exception               */
> +    POWERPC_EXCP_SEMIHOST = 105,     /* Semihosting Exception                */
>       /* EOL                                                                   */
> -    POWERPC_EXCP_NB       = 105,
> +    POWERPC_EXCP_NB       = 106,
>       /* QEMU exceptions: special cases we want to stop translation            */
>       POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only      */
>   };
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index d3e2cfcd71..af34a57082 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -25,6 +25,7 @@
>   #include "helper_regs.h"
>   
>   #include "trace.h"
> +#include "semihosting/common-semi.h"
>   
>   #ifdef CONFIG_TCG
>   #include "exec/helper-proto.h"
> @@ -100,6 +101,7 @@ static const char *powerpc_excp_name(int excp)
>       case POWERPC_EXCP_SDOOR_HV: return "SDOOR_HV";
>       case POWERPC_EXCP_HVIRT:    return "HVIRT";
>       case POWERPC_EXCP_SYSCALL_VECTORED: return "SYSCALL_VECTORED";
> +    case POWERPC_EXCP_SEMIHOST: return "SEMIHOST";
>       default:
>           g_assert_not_reached();
>       }
> @@ -1327,6 +1329,13 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
>       target_ulong msr, new_msr, vector;
>       int srr0, srr1, lev = -1;
>   
> +    /* Handle semihost exceptions first */
> +    if (excp == POWERPC_EXCP_SEMIHOST) {
> +        env->gpr[3] = do_common_semihosting(cs);
> +        env->nip += 4;
> +        return;
> +    }
> +
>       /* new srr1 value excluding must-be-zero bits */
>       msr = env->msr & ~0x783f0000ULL;
>   
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 408ae26173..c013889a84 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -4520,6 +4520,20 @@ static void gen_sc(DisasContext *ctx)
>       uint32_t lev;
>   
>       lev = (ctx->opcode >> 5) & 0x7F;
> +
> +#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
> +    /*
> +     * PowerPC semihosting uses the following
> +     * instruction to flag a semihosting call:
> +     *
> +     *      sc 7            0x440000e2
> +     */
> +    if (lev == 7) {
> +        gen_exception(ctx, POWERPC_EXCP_SEMIHOST);
> +        return;
> +    }
> +#endif
> +
>       gen_exception_err(ctx, POWERPC_SYSCALL, lev);
>   }
>
Richard Henderson April 18, 2022, 11:33 p.m. UTC | #2
On 4/18/22 12:10, Leandro Lupori wrote:
> Add semihosting support for PPC64. This implementation is
> based on the standard for ARM semihosting version 2.0, as
> implemented by QEMU and documented in
> 
>      https://github.com/ARM-software/abi-aa/releases
> 
> The PPC64 specific differences are the following:
> 
> Semihosting Trap Instruction: sc 7
> Operation Number Register: r3
> Parameter Register: r4
> Return Register: r3
> Data block field size: 64 bits
> 
> Signed-off-by: Leandro Lupori<leandro.lupori@eldorado.org.br>
> ---
>   configs/devices/ppc64-softmmu/default.mak |  3 +++
>   qemu-options.hx                           | 18 ++++++++-----
>   semihosting/arm-compat-semi.c             | 33 +++++++++++++++++++++++
>   target/ppc/cpu.h                          |  3 ++-
>   target/ppc/excp_helper.c                  |  9 +++++++
>   target/ppc/translate.c                    | 14 ++++++++++
>   6 files changed, 72 insertions(+), 8 deletions(-)

Modulo whatever sc number yall settle on,

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
Peter Maydell April 19, 2022, 9:26 a.m. UTC | #3
On Mon, 18 Apr 2022 at 20:15, Leandro Lupori
<leandro.lupori@eldorado.org.br> wrote:
>
> Add semihosting support for PPC64. This implementation is
> based on the standard for ARM semihosting version 2.0, as
> implemented by QEMU and documented in
>
>     https://github.com/ARM-software/abi-aa/releases
>
> The PPC64 specific differences are the following:
>
> Semihosting Trap Instruction: sc 7
> Operation Number Register: r3
> Parameter Register: r4
> Return Register: r3
> Data block field size: 64 bits

Where is the independent specification which defines that
this is the ABI for PPC semihosting? You should provide the
URL for that in a comment somewhere.

thanks
-- PMM
Leandro Lupori April 20, 2022, 5:54 p.m. UTC | #4
On 4/18/22 17:22, Cédric Le Goater wrote:

>> diff --git a/semihosting/arm-compat-semi.c 
>> b/semihosting/arm-compat-semi.c
>> index 7a51fd0737..e1279c316c 100644
>> --- a/semihosting/arm-compat-semi.c
>> +++ b/semihosting/arm-compat-semi.c
>> @@ -268,6 +268,31 @@ common_semi_sys_exit_extended(CPUState *cs, int nr)
>>
>>   #endif
>>
>> +#ifdef TARGET_PPC64
> 
> This PPC ifdef in an ARM file seems wrong.
> 
> The rest looks OK.

IIUC, arm-compat-semi.c is not an ARM specific file, but it's used by 
targets that implement ARM-compatible semihosting. It's currently used 
by ARM and RISC-V and both use target ifdefs in small parts of this file.

Thanks,
Leandro

> 
> Thanks,
> 
> C.
> 
> 
>> +static inline target_ulong
>> +common_semi_arg(CPUState *cs, int argno)
>> +{
>> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
>> +    CPUPPCState *env = &cpu->env;
>> +    return env->gpr[3 + argno];
>> +}
>> +
>> +static inline void
>> +common_semi_set_ret(CPUState *cs, target_ulong ret)
>> +{
>> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
>> +    CPUPPCState *env = &cpu->env;
>> +    env->gpr[3] = ret;
>> +}
>> +
>> +static inline bool
>> +common_semi_sys_exit_extended(CPUState *cs, int nr)
>> +{
>> +    return (nr == TARGET_SYS_EXIT_EXTENDED || sizeof(target_ulong) == 
>> 8);
>> +}
>> +
>> +#endif
>> +
Peter Maydell April 20, 2022, 6:05 p.m. UTC | #5
On Mon, 18 Apr 2022 at 20:15, Leandro Lupori
<leandro.lupori@eldorado.org.br> wrote:
>
> Add semihosting support for PPC64. This implementation is
> based on the standard for ARM semihosting version 2.0, as
> implemented by QEMU and documented in
>
>     https://github.com/ARM-software/abi-aa/releases
>
> The PPC64 specific differences are the following:
>
> Semihosting Trap Instruction: sc 7
> Operation Number Register: r3
> Parameter Register: r4
> Return Register: r3
> Data block field size: 64 bits
>
> +static inline bool
> +common_semi_sys_exit_extended(CPUState *cs, int nr)
> +{
> +    return (nr == TARGET_SYS_EXIT_EXTENDED || sizeof(target_ulong) == 8);
> +}

Does the PPC specification for semihosting really follow the
legacy Arm requirement that the 32-bit version of the EXIT
call doesn't let the caller specify the exit status? It's
not a very sensible choice IMHO if you don't have the legacy
baggage to deal with.

-- PMM
Leandro Lupori April 20, 2022, 6:09 p.m. UTC | #6
On 4/18/22 17:22, Cédric Le Goater wrote:
> On 4/18/22 21:10, Leandro Lupori wrote:
>> Add semihosting support for PPC64. This implementation is
>> based on the standard for ARM semihosting version 2.0, as
>> implemented by QEMU and documented in
>>
>>      https://github.com/ARM-software/abi-aa/releases
>>
>> The PPC64 specific differences are the following:
>>
>> Semihosting Trap Instruction: sc 7
>> Operation Number Register: r3
>> Parameter Register: r4
>> Return Register: r3
>> Data block field size: 64 bits
> 
> 'sc' is a good way to implement semi hosting but we should make sure
> that it is not colliding with future extensions, at least with the
> next POWERPC processor. Is that the case ? if not, then the lev could
> be reserved.
> 

Power ISA 3.1B says that LEV values greater that 2 are reserved.
Level 2 is the ultravisor, so I assumed that level 7 was far enough from 
current max level. I don't know if POWER11 will introduce new privilege 
levels. Is this info publicly available somewhere? Or do you have a 
better level in mind to use instead?

> I think the part adding POWERPC_EXCP_SEMIHOST should be proposed in a
> separate patch.
> 

Ok, I can move it to a separate patch. That would be all changes in 
target/ppc/cpu.h and target/ppc/excp_helper.c, right?
Richard Henderson April 20, 2022, 6:18 p.m. UTC | #7
On 4/20/22 10:54, Leandro Lupori wrote:
> On 4/18/22 17:22, Cédric Le Goater wrote:
> 
>>> diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
>>> index 7a51fd0737..e1279c316c 100644
>>> --- a/semihosting/arm-compat-semi.c
>>> +++ b/semihosting/arm-compat-semi.c
>>> @@ -268,6 +268,31 @@ common_semi_sys_exit_extended(CPUState *cs, int nr)
>>>
>>>   #endif
>>>
>>> +#ifdef TARGET_PPC64
>>
>> This PPC ifdef in an ARM file seems wrong.
>>
>> The rest looks OK.
> 
> IIUC, arm-compat-semi.c is not an ARM specific file, but it's used by targets that 
> implement ARM-compatible semihosting. It's currently used by ARM and RISC-V and both use 
> target ifdefs in small parts of this file.

It would be nice to split these out to target/arch/arm-compat-semi.h or something akin.


r~
Leandro Lupori April 20, 2022, 6:20 p.m. UTC | #8
On 4/19/22 06:26, Peter Maydell wrote:
> On Mon, 18 Apr 2022 at 20:15, Leandro Lupori
> <leandro.lupori@eldorado.org.br> wrote:
>>
>> Add semihosting support for PPC64. This implementation is
>> based on the standard for ARM semihosting version 2.0, as
>> implemented by QEMU and documented in
>>
>>      https://github.com/ARM-software/abi-aa/releases
>>
>> The PPC64 specific differences are the following:
>>
>> Semihosting Trap Instruction: sc 7
>> Operation Number Register: r3
>> Parameter Register: r4
>> Return Register: r3
>> Data block field size: 64 bits
> 
> Where is the independent specification which defines that
> this is the ABI for PPC semihosting? You should provide the
> URL for that in a comment somewhere.
> 

AFAIK, there is no official PPC semihosting specification. Would it be 
ok to just document it somewhere else, e.g. GitHub, as an unofficial 
specification?

Thanks,
Leandro

> thanks
> -- PMM
Leandro Lupori April 20, 2022, 6:30 p.m. UTC | #9
On 4/20/22 15:05, Peter Maydell wrote:
> [E-MAIL EXTERNO] Não clique em links ou abra anexos, a menos que você possa confirmar o remetente e saber que o conteúdo é seguro. Em caso de e-mail suspeito entre imediatamente em contato com o DTI.
> 
> On Mon, 18 Apr 2022 at 20:15, Leandro Lupori
> <leandro.lupori@eldorado.org.br> wrote:
>>
>> Add semihosting support for PPC64. This implementation is
>> based on the standard for ARM semihosting version 2.0, as
>> implemented by QEMU and documented in
>>
>>      https://github.com/ARM-software/abi-aa/releases
>>
>> The PPC64 specific differences are the following:
>>
>> Semihosting Trap Instruction: sc 7
>> Operation Number Register: r3
>> Parameter Register: r4
>> Return Register: r3
>> Data block field size: 64 bits
>>
>> +static inline bool
>> +common_semi_sys_exit_extended(CPUState *cs, int nr)
>> +{
>> +    return (nr == TARGET_SYS_EXIT_EXTENDED || sizeof(target_ulong) == 8);
>> +}
> 
> Does the PPC specification for semihosting really follow the
> legacy Arm requirement that the 32-bit version of the EXIT
> call doesn't let the caller specify the exit status? It's
> not a very sensible choice IMHO if you don't have the legacy
> baggage to deal with.
> 

As we are actually writing an unofficial PPC specification for 
semihosting now, I guess it makes sense to leave the legacy 32-bit 
version of EXIT out of it. I'll change this part to always return true.
By the way, this initial implementation supports only 64-bit PPC.

Thanks,
Leandro

> -- PMM
Leandro Lupori April 20, 2022, 6:38 p.m. UTC | #10
On 4/20/22 15:18, Richard Henderson wrote:
> [E-MAIL EXTERNO] Não clique em links ou abra anexos, a menos que você 
> possa confirmar o remetente e saber que o conteúdo é seguro. Em caso de 
> e-mail suspeito entre imediatamente em contato com o DTI.
> 
> On 4/20/22 10:54, Leandro Lupori wrote:
>> On 4/18/22 17:22, Cédric Le Goater wrote:
>>
>>>> diff --git a/semihosting/arm-compat-semi.c 
>>>> b/semihosting/arm-compat-semi.c
>>>> index 7a51fd0737..e1279c316c 100644
>>>> --- a/semihosting/arm-compat-semi.c
>>>> +++ b/semihosting/arm-compat-semi.c
>>>> @@ -268,6 +268,31 @@ common_semi_sys_exit_extended(CPUState *cs, int 
>>>> nr)
>>>>
>>>>   #endif
>>>>
>>>> +#ifdef TARGET_PPC64
>>>
>>> This PPC ifdef in an ARM file seems wrong.
>>>
>>> The rest looks OK.
>>
>> IIUC, arm-compat-semi.c is not an ARM specific file, but it's used by 
>> targets that
>> implement ARM-compatible semihosting. It's currently used by ARM and 
>> RISC-V and both use
>> target ifdefs in small parts of this file.
> 
> It would be nice to split these out to target/arch/arm-compat-semi.h or 
> something akin.
> 

Ah, ok, I'll try to move the target specific parts to their own header 
files then.

Thanks,
Leandro

> 
> r~
Peter Maydell April 20, 2022, 7:24 p.m. UTC | #11
On Wed, 20 Apr 2022 at 19:20, Leandro Lupori
<leandro.lupori@eldorado.org.br> wrote:
>
> On 4/19/22 06:26, Peter Maydell wrote:
> > On Mon, 18 Apr 2022 at 20:15, Leandro Lupori
> > <leandro.lupori@eldorado.org.br> wrote:
> >>
> >> Add semihosting support for PPC64. This implementation is
> >> based on the standard for ARM semihosting version 2.0, as
> >> implemented by QEMU and documented in
> >>
> >>      https://github.com/ARM-software/abi-aa/releases
> >>
> >> The PPC64 specific differences are the following:
> >>
> >> Semihosting Trap Instruction: sc 7
> >> Operation Number Register: r3
> >> Parameter Register: r4
> >> Return Register: r3
> >> Data block field size: 64 bits
> >
> > Where is the independent specification which defines that
> > this is the ABI for PPC semihosting? You should provide the
> > URL for that in a comment somewhere.
> >
>
> AFAIK, there is no official PPC semihosting specification. Would it be
> ok to just document it somewhere else, e.g. GitHub, as an unofficial
> specification?

I'm going to push back on this in the same way I did for
the RISC-V folks. If this is an official PPC semihosting
specification, intended to be supported by multiple
different pieces of software, it needs to have an
independent spec document somewhere (even if that
spec document just cross-refers to the Arm spec for
most of the detail). If this is an ad-hoc "add this
thing for PPC in a purely QEMU-specific way" patchset,
then no, we shouldn't implement it.

Semihosting is an ABI, and when QEMU implements an ABI
it should be because it's an external pre-existing one.

thanks
-- PMM
Nicholas Piggin April 21, 2022, 2:04 a.m. UTC | #12
Excerpts from Leandro Lupori's message of April 21, 2022 4:09 am:
> On 4/18/22 17:22, Cédric Le Goater wrote:
>> On 4/18/22 21:10, Leandro Lupori wrote:
>>> Add semihosting support for PPC64. This implementation is
>>> based on the standard for ARM semihosting version 2.0, as
>>> implemented by QEMU and documented in
>>>
>>>      https://github.com/ARM-software/abi-aa/releases
>>>
>>> The PPC64 specific differences are the following:
>>>
>>> Semihosting Trap Instruction: sc 7
>>> Operation Number Register: r3
>>> Parameter Register: r4
>>> Return Register: r3
>>> Data block field size: 64 bits
>> 
>> 'sc' is a good way to implement semi hosting but we should make sure
>> that it is not colliding with future extensions, at least with the
>> next POWERPC processor. Is that the case ? if not, then the lev could
>> be reserved.
>> 
> 
> Power ISA 3.1B says that LEV values greater that 2 are reserved.
> Level 2 is the ultravisor, so I assumed that level 7 was far enough from 
> current max level. I don't know if POWER11 will introduce new privilege 
> levels. Is this info publicly available somewhere? Or do you have a 
> better level in mind to use instead?

It's not available but there are no plans to use LEV=7.

It would be fine in practice I think, but it's kind of ugly and not 
great precedent -- how would we find out all the projects which use 
reserved instructions or values for something? Nominally the onus is on 
the software to accept breakage, but in reality important software that
breaks causes a headache for the ISA.

IBM's systemsim emulator actually has an instruction to call out to the 
emulator to do various things like IO. It uses the opcode

  .long 0x000eaeb0

That is the primary op 0 reserved space, and there is actually another 
op 'attn' or 'sp_attn' there which IBM CPUs implement, it is similar in 
spirit (it calls out to the service processor and/or chip error handling 
system to deal with a condition out-of-band). You don't want to use attn 
here because the core under emulation might implement it, I'm just 
noting the precedent with similar functionality under this primary 
opcode.

So I think the systemsim emulator instruction should be a good choice. 
But it should really be documented. I will bring this up at the Open 
Power ISA working group meeting next week and see what the options are 
with getting it formally allocated for semihosting emulators (or what 
the alternatives are).

Thanks,
Nick
Cédric Le Goater April 21, 2022, 6:12 a.m. UTC | #13
>> I think the part adding POWERPC_EXCP_SEMIHOST should be proposed in
>> a separate patch.
> 
> Ok, I can move it to a separate patch. That would be all changes in 
> target/ppc/cpu.h and target/ppc/excp_helper.c, right?

yes.

Thanks,

C.
Cédric Le Goater April 21, 2022, 6:21 a.m. UTC | #14
On 4/21/22 04:04, Nicholas Piggin wrote:
> Excerpts from Leandro Lupori's message of April 21, 2022 4:09 am:
>> On 4/18/22 17:22, Cédric Le Goater wrote:
>>> On 4/18/22 21:10, Leandro Lupori wrote:
>>>> Add semihosting support for PPC64. This implementation is
>>>> based on the standard for ARM semihosting version 2.0, as
>>>> implemented by QEMU and documented in
>>>>
>>>>       https://github.com/ARM-software/abi-aa/releases
>>>>
>>>> The PPC64 specific differences are the following:
>>>>
>>>> Semihosting Trap Instruction: sc 7
>>>> Operation Number Register: r3
>>>> Parameter Register: r4
>>>> Return Register: r3
>>>> Data block field size: 64 bits
>>>
>>> 'sc' is a good way to implement semi hosting but we should make sure
>>> that it is not colliding with future extensions, at least with the
>>> next POWERPC processor. Is that the case ? if not, then the lev could
>>> be reserved.
>>>
>>
>> Power ISA 3.1B says that LEV values greater that 2 are reserved.
>> Level 2 is the ultravisor, so I assumed that level 7 was far enough from
>> current max level. I don't know if POWER11 will introduce new privilege
>> levels. Is this info publicly available somewhere? Or do you have a
>> better level in mind to use instead?
> 
> It's not available but there are no plans to use LEV=7.
> 
> It would be fine in practice I think, but it's kind of ugly and not
> great precedent -- how would we find out all the projects which use
> reserved instructions or values for something? Nominally the onus is on
> the software to accept breakage, but in reality important software that
> breaks causes a headache for the ISA.
> 
> IBM's systemsim emulator actually has an instruction to call out to the
> emulator to do various things like IO. It uses the opcode
> 
>    .long 0x000eaeb0
> 
> That is the primary op 0 reserved space, and there is actually another
> op 'attn' or 'sp_attn' there which IBM CPUs implement, it is similar in
> spirit (it calls out to the service processor and/or chip error handling
> system to deal with a condition out-of-band). You don't want to use attn
> here because the core under emulation might implement it, I'm just
> noting the precedent with similar functionality under this primary
> opcode.
> 
> So I think the systemsim emulator instruction should be a good choice.

yeah. It's not a major change.

> But it should really be documented. I will bring this up at the Open
> Power ISA working group meeting next week and see what the options are
> with getting it formally allocated for semihosting emulators (or what
> the alternatives are).

It would be nice to invite Leandro to this meeting since he started
implementing.

Thanks,

C.
Nicholas Piggin April 21, 2022, 9:56 a.m. UTC | #15
Excerpts from Cédric Le Goater's message of April 21, 2022 4:21 pm:
> On 4/21/22 04:04, Nicholas Piggin wrote:
>> Excerpts from Leandro Lupori's message of April 21, 2022 4:09 am:
>>> On 4/18/22 17:22, Cédric Le Goater wrote:
>>>> On 4/18/22 21:10, Leandro Lupori wrote:
>>>>> Add semihosting support for PPC64. This implementation is
>>>>> based on the standard for ARM semihosting version 2.0, as
>>>>> implemented by QEMU and documented in
>>>>>
>>>>>       https://github.com/ARM-software/abi-aa/releases
>>>>>
>>>>> The PPC64 specific differences are the following:
>>>>>
>>>>> Semihosting Trap Instruction: sc 7
>>>>> Operation Number Register: r3
>>>>> Parameter Register: r4
>>>>> Return Register: r3
>>>>> Data block field size: 64 bits
>>>>
>>>> 'sc' is a good way to implement semi hosting but we should make sure
>>>> that it is not colliding with future extensions, at least with the
>>>> next POWERPC processor. Is that the case ? if not, then the lev could
>>>> be reserved.
>>>>
>>>
>>> Power ISA 3.1B says that LEV values greater that 2 are reserved.
>>> Level 2 is the ultravisor, so I assumed that level 7 was far enough from
>>> current max level. I don't know if POWER11 will introduce new privilege
>>> levels. Is this info publicly available somewhere? Or do you have a
>>> better level in mind to use instead?
>> 
>> It's not available but there are no plans to use LEV=7.
>> 
>> It would be fine in practice I think, but it's kind of ugly and not
>> great precedent -- how would we find out all the projects which use
>> reserved instructions or values for something? Nominally the onus is on
>> the software to accept breakage, but in reality important software that
>> breaks causes a headache for the ISA.
>> 
>> IBM's systemsim emulator actually has an instruction to call out to the
>> emulator to do various things like IO. It uses the opcode
>> 
>>    .long 0x000eaeb0
>> 
>> That is the primary op 0 reserved space, and there is actually another
>> op 'attn' or 'sp_attn' there which IBM CPUs implement, it is similar in
>> spirit (it calls out to the service processor and/or chip error handling
>> system to deal with a condition out-of-band). You don't want to use attn
>> here because the core under emulation might implement it, I'm just
>> noting the precedent with similar functionality under this primary
>> opcode.
>> 
>> So I think the systemsim emulator instruction should be a good choice.
> 
> yeah. It's not a major change.
> 
>> But it should really be documented. I will bring this up at the Open
>> Power ISA working group meeting next week and see what the options are
>> with getting it formally allocated for semihosting emulators (or what
>> the alternatives are).
> 
> It would be nice to invite Leandro to this meeting since he started
> implementing.

Good point. I'll organize with him offline.

Thanks,
Nick
Nicholas Piggin April 28, 2022, 3:56 a.m. UTC | #16
Excerpts from Nicholas Piggin's message of April 21, 2022 12:04 pm:
> Excerpts from Leandro Lupori's message of April 21, 2022 4:09 am:
>> On 4/18/22 17:22, Cédric Le Goater wrote:
>>> On 4/18/22 21:10, Leandro Lupori wrote:
>>>> Add semihosting support for PPC64. This implementation is
>>>> based on the standard for ARM semihosting version 2.0, as
>>>> implemented by QEMU and documented in
>>>>
>>>>      https://github.com/ARM-software/abi-aa/releases
>>>>
>>>> The PPC64 specific differences are the following:
>>>>
>>>> Semihosting Trap Instruction: sc 7
>>>> Operation Number Register: r3
>>>> Parameter Register: r4
>>>> Return Register: r3
>>>> Data block field size: 64 bits
>>> 
>>> 'sc' is a good way to implement semi hosting but we should make sure
>>> that it is not colliding with future extensions, at least with the
>>> next POWERPC processor. Is that the case ? if not, then the lev could
>>> be reserved.
>>> 
>> 
>> Power ISA 3.1B says that LEV values greater that 2 are reserved.
>> Level 2 is the ultravisor, so I assumed that level 7 was far enough from 
>> current max level. I don't know if POWER11 will introduce new privilege 
>> levels. Is this info publicly available somewhere? Or do you have a 
>> better level in mind to use instead?
> 
> It's not available but there are no plans to use LEV=7.
> 
> It would be fine in practice I think, but it's kind of ugly and not 
> great precedent -- how would we find out all the projects which use 
> reserved instructions or values for something? Nominally the onus is on 
> the software to accept breakage, but in reality important software that
> breaks causes a headache for the ISA.
> 
> IBM's systemsim emulator actually has an instruction to call out to the 
> emulator to do various things like IO. It uses the opcode
> 
>   .long 0x000eaeb0
> 
> That is the primary op 0 reserved space, and there is actually another 
> op 'attn' or 'sp_attn' there which IBM CPUs implement, it is similar in 
> spirit (it calls out to the service processor and/or chip error handling 
> system to deal with a condition out-of-band). You don't want to use attn 
> here because the core under emulation might implement it, I'm just 
> noting the precedent with similar functionality under this primary 
> opcode.
> 
> So I think the systemsim emulator instruction should be a good choice. 
> But it should really be documented. I will bring this up at the Open 
> Power ISA working group meeting next week and see what the options are 
> with getting it formally allocated for semihosting emulators (or what 
> the alternatives are).

Update on the ISA TWG meeting

Semihosting was well received, the idea is not so new so I think it was
easily understood by attendees.

There were no objections to allocating a new opcode for this purpose.
The preference was a new opcode rather than using a reserved sc LEV
value.

The primary opcode 0 space is possibly unsuitable because it is said
to be "allocated to specific purposes that are outside the scope of the
Power ISA." whereas I think we want a first class instruction for this,
it may have implementation-dependent behaviour but on processors that
do not implement it, we would like it to have well-defined behaviour.

So we can probably just pick an opcode and submit a patch RFC to the
ISA (I can try help with that). First, there are a few questions to
resolve:

- What behaviour do we want for CPUs which do not implement it or
  disable it? E.g., no-op or illegal instruction interrupt. Ideally
  we would choose an opcode such that the architecture is compatible
  with existing CPUs.

- Would it be useful for KVM to implement semihosting support for
  guests on hard processors?

- Is there value in an endian-agnostic instruction? (Assuming we can
  find one). This question only comes to me because our BMC gdbserver
  for debugging the host CPUs implements breakpoints by inserting an
  'attn' instruction in the host code, and that does not work if the
  host switches endian. Any possibility the semihosting instruction
  would ever be injected out-of-band? Seems not so likely.

There were also some thoughts about bringing the semihosting spec
under the Open Power group but that's outside the scope of the ISA
group. This may be a possibility we could consider but I think for
now it should be enough to document it like riscv and put it
somewhere (even in the QEMU tree should be okay for now IMO).

Thanks,
Nick
Fabiano Rosas May 3, 2022, 3:50 p.m. UTC | #17
Nicholas Piggin <npiggin@gmail.com> writes:

> Excerpts from Nicholas Piggin's message of April 21, 2022 12:04 pm:
>> Excerpts from Leandro Lupori's message of April 21, 2022 4:09 am:
>>> On 4/18/22 17:22, Cédric Le Goater wrote:
>>>> On 4/18/22 21:10, Leandro Lupori wrote:
>>>>> Add semihosting support for PPC64. This implementation is
>>>>> based on the standard for ARM semihosting version 2.0, as
>>>>> implemented by QEMU and documented in
>>>>>
>>>>>      https://github.com/ARM-software/abi-aa/releases
>>>>>
>>>>> The PPC64 specific differences are the following:
>>>>>
>>>>> Semihosting Trap Instruction: sc 7
>>>>> Operation Number Register: r3
>>>>> Parameter Register: r4
>>>>> Return Register: r3
>>>>> Data block field size: 64 bits
>>>> 
>>>> 'sc' is a good way to implement semi hosting but we should make sure
>>>> that it is not colliding with future extensions, at least with the
>>>> next POWERPC processor. Is that the case ? if not, then the lev could
>>>> be reserved.
>>>> 
>>> 
>>> Power ISA 3.1B says that LEV values greater that 2 are reserved.
>>> Level 2 is the ultravisor, so I assumed that level 7 was far enough from 
>>> current max level. I don't know if POWER11 will introduce new privilege 
>>> levels. Is this info publicly available somewhere? Or do you have a 
>>> better level in mind to use instead?
>> 
>> It's not available but there are no plans to use LEV=7.
>> 
>> It would be fine in practice I think, but it's kind of ugly and not 
>> great precedent -- how would we find out all the projects which use 
>> reserved instructions or values for something? Nominally the onus is on 
>> the software to accept breakage, but in reality important software that
>> breaks causes a headache for the ISA.
>> 
>> IBM's systemsim emulator actually has an instruction to call out to the 
>> emulator to do various things like IO. It uses the opcode
>> 
>>   .long 0x000eaeb0
>> 
>> That is the primary op 0 reserved space, and there is actually another 
>> op 'attn' or 'sp_attn' there which IBM CPUs implement, it is similar in 
>> spirit (it calls out to the service processor and/or chip error handling 
>> system to deal with a condition out-of-band). You don't want to use attn 
>> here because the core under emulation might implement it, I'm just 
>> noting the precedent with similar functionality under this primary 
>> opcode.
>> 
>> So I think the systemsim emulator instruction should be a good choice. 
>> But it should really be documented. I will bring this up at the Open 
>> Power ISA working group meeting next week and see what the options are 
>> with getting it formally allocated for semihosting emulators (or what 
>> the alternatives are).
>
> Update on the ISA TWG meeting
>
> Semihosting was well received, the idea is not so new so I think it was
> easily understood by attendees.
>
> There were no objections to allocating a new opcode for this purpose.
> The preference was a new opcode rather than using a reserved sc LEV
> value.
>
> The primary opcode 0 space is possibly unsuitable because it is said
> to be "allocated to specific purposes that are outside the scope of the
> Power ISA." whereas I think we want a first class instruction for this,
> it may have implementation-dependent behaviour but on processors that
> do not implement it, we would like it to have well-defined behaviour.
>
> So we can probably just pick an opcode and submit a patch RFC to the
> ISA (I can try help with that). First, there are a few questions to
> resolve:
>
> - What behaviour do we want for CPUs which do not implement it or
>   disable it? E.g., no-op or illegal instruction interrupt. Ideally
>   we would choose an opcode such that the architecture is compatible
>   with existing CPUs.

I think that since semihosting is not a one-shot thing it would be
better to have it trap so that the "host" could remediate in some
way. Or even carry on with servicing the semihosting anyway.

> - Would it be useful for KVM to implement semihosting support for
>   guests on hard processors?

Are there any undesirable implications to using an instruction that
traps to the HV? I'd say let's get it if we can but otherwise it's not a
big deal.

I had two use-cases in mind:

1) Improving our interactions with gdbstub and having the guest use
   sys_exit to report some debugging events like watchpoints or
   singlestep;

2) Bootstrapping with KVM. We had instances in the past of needing to
   write guest code from scratch and having to rely solely in GDB for a
   while before setting up the console.

But I realise that these use-cases conflate semihosting with general
debugging and regular PAPR features, respectively. So it might be a
stretch.

> - Is there value in an endian-agnostic instruction? (Assuming we can
>   find one). This question only comes to me because our BMC gdbserver
>   for debugging the host CPUs implements breakpoints by inserting an
>   'attn' instruction in the host code, and that does not work if the
>   host switches endian. Any possibility the semihosting instruction
>   would ever be injected out-of-band? Seems not so likely.

Semihosting requires some sort of register setup, I don't think having
it done out-of-band would be practical. So we possibly don't need an
endian-agnostic instruction.

> There were also some thoughts about bringing the semihosting spec
> under the Open Power group but that's outside the scope of the ISA
> group. This may be a possibility we could consider but I think for
> now it should be enough to document it like riscv and put it
> somewhere (even in the QEMU tree should be okay for now IMO).
>
> Thanks,
> Nick
Nicholas Piggin May 10, 2022, 9:41 a.m. UTC | #18
Excerpts from Fabiano Rosas's message of May 4, 2022 1:50 am:
> Nicholas Piggin <npiggin@gmail.com> writes:
> 
>> Excerpts from Nicholas Piggin's message of April 21, 2022 12:04 pm:
>>> Excerpts from Leandro Lupori's message of April 21, 2022 4:09 am:
>>>> On 4/18/22 17:22, Cédric Le Goater wrote:
>>>>> On 4/18/22 21:10, Leandro Lupori wrote:
>>>>>> Add semihosting support for PPC64. This implementation is
>>>>>> based on the standard for ARM semihosting version 2.0, as
>>>>>> implemented by QEMU and documented in
>>>>>>
>>>>>>      https://github.com/ARM-software/abi-aa/releases
>>>>>>
>>>>>> The PPC64 specific differences are the following:
>>>>>>
>>>>>> Semihosting Trap Instruction: sc 7
>>>>>> Operation Number Register: r3
>>>>>> Parameter Register: r4
>>>>>> Return Register: r3
>>>>>> Data block field size: 64 bits
>>>>> 
>>>>> 'sc' is a good way to implement semi hosting but we should make sure
>>>>> that it is not colliding with future extensions, at least with the
>>>>> next POWERPC processor. Is that the case ? if not, then the lev could
>>>>> be reserved.
>>>>> 
>>>> 
>>>> Power ISA 3.1B says that LEV values greater that 2 are reserved.
>>>> Level 2 is the ultravisor, so I assumed that level 7 was far enough from 
>>>> current max level. I don't know if POWER11 will introduce new privilege 
>>>> levels. Is this info publicly available somewhere? Or do you have a 
>>>> better level in mind to use instead?
>>> 
>>> It's not available but there are no plans to use LEV=7.
>>> 
>>> It would be fine in practice I think, but it's kind of ugly and not 
>>> great precedent -- how would we find out all the projects which use 
>>> reserved instructions or values for something? Nominally the onus is on 
>>> the software to accept breakage, but in reality important software that
>>> breaks causes a headache for the ISA.
>>> 
>>> IBM's systemsim emulator actually has an instruction to call out to the 
>>> emulator to do various things like IO. It uses the opcode
>>> 
>>>   .long 0x000eaeb0
>>> 
>>> That is the primary op 0 reserved space, and there is actually another 
>>> op 'attn' or 'sp_attn' there which IBM CPUs implement, it is similar in 
>>> spirit (it calls out to the service processor and/or chip error handling 
>>> system to deal with a condition out-of-band). You don't want to use attn 
>>> here because the core under emulation might implement it, I'm just 
>>> noting the precedent with similar functionality under this primary 
>>> opcode.
>>> 
>>> So I think the systemsim emulator instruction should be a good choice. 
>>> But it should really be documented. I will bring this up at the Open 
>>> Power ISA working group meeting next week and see what the options are 
>>> with getting it formally allocated for semihosting emulators (or what 
>>> the alternatives are).
>>
>> Update on the ISA TWG meeting
>>
>> Semihosting was well received, the idea is not so new so I think it was
>> easily understood by attendees.
>>
>> There were no objections to allocating a new opcode for this purpose.
>> The preference was a new opcode rather than using a reserved sc LEV
>> value.
>>
>> The primary opcode 0 space is possibly unsuitable because it is said
>> to be "allocated to specific purposes that are outside the scope of the
>> Power ISA." whereas I think we want a first class instruction for this,
>> it may have implementation-dependent behaviour but on processors that
>> do not implement it, we would like it to have well-defined behaviour.
>>
>> So we can probably just pick an opcode and submit a patch RFC to the
>> ISA (I can try help with that). First, there are a few questions to
>> resolve:
>>
>> - What behaviour do we want for CPUs which do not implement it or
>>   disable it? E.g., no-op or illegal instruction interrupt. Ideally
>>   we would choose an opcode such that the architecture is compatible
>>   with existing CPUs.
> 
> I think that since semihosting is not a one-shot thing it would be
> better to have it trap so that the "host" could remediate in some
> way. Or even carry on with servicing the semihosting anyway.

Yeah I think I agree, and semihosting code that is intended to compile
away or be dynamically disableable can implement that itself if
needed.

> 
>> - Would it be useful for KVM to implement semihosting support for
>>   guests on hard processors?
> 
> Are there any undesirable implications to using an instruction that
> traps to the HV? I'd say let's get it if we can but otherwise it's not a
> big deal.
> 
> I had two use-cases in mind:
> 
> 1) Improving our interactions with gdbstub and having the guest use
>    sys_exit to report some debugging events like watchpoints or
>    singlestep;
> 
> 2) Bootstrapping with KVM. We had instances in the past of needing to
>    write guest code from scratch and having to rely solely in GDB for a
>    while before setting up the console.
> 
> But I realise that these use-cases conflate semihosting with general
> debugging and regular PAPR features, respectively. So it might be a
> stretch.

I don't see downsides actually. A userspace can already induce some HV
interrupts.

So we can use any unallocated opcode, and in the specification we can 
say processors which do not support the semihosting facility
should treat it as an illegal instruction. That means the spec is 
backward compatible. It also gives you the trap to HV with HEAI 
interrupt on existing processors so KVM can implement it for guests.

Maybe it's as simple as that?

> 
>> - Is there value in an endian-agnostic instruction? (Assuming we can
>>   find one). This question only comes to me because our BMC gdbserver
>>   for debugging the host CPUs implements breakpoints by inserting an
>>   'attn' instruction in the host code, and that does not work if the
>>   host switches endian. Any possibility the semihosting instruction
>>   would ever be injected out-of-band? Seems not so likely.
> 
> Semihosting requires some sort of register setup, I don't think having
> it done out-of-band would be practical. So we possibly don't need an
> endian-agnostic instruction.

Okay.

Thanks,
Nick
diff mbox series

Patch

diff --git a/configs/devices/ppc64-softmmu/default.mak b/configs/devices/ppc64-softmmu/default.mak
index b90e5bf455..43b618fa32 100644
--- a/configs/devices/ppc64-softmmu/default.mak
+++ b/configs/devices/ppc64-softmmu/default.mak
@@ -8,3 +8,6 @@  CONFIG_POWERNV=y
 
 # For pSeries
 CONFIG_PSERIES=y
+
+CONFIG_SEMIHOSTING=y
+CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
diff --git a/qemu-options.hx b/qemu-options.hx
index 34e9b32a5c..6e76f7de96 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4527,11 +4527,12 @@  SRST
 ERST
 DEF("semihosting", 0, QEMU_OPTION_semihosting,
     "-semihosting    semihosting mode\n",
-    QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA |
-    QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
+    QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_MIPS |
+    QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV | QEMU_ARCH_PPC)
 SRST
 ``-semihosting``
-    Enable semihosting mode (ARM, M68K, Xtensa, MIPS, Nios II, RISC-V only).
+    Enable semihosting mode (ARM, M68K, Xtensa, MIPS, Nios II, RISC-V and
+    PPC only).
 
     Note that this allows guest direct access to the host filesystem, so
     should only be used with a trusted guest OS.
@@ -4542,12 +4543,12 @@  ERST
 DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config,
     "-semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]\n" \
     "                semihosting configuration\n",
-QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA |
-QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
+QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_MIPS |
+QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV | QEMU_ARCH_PPC)
 SRST
 ``-semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]``
-    Enable and configure semihosting (ARM, M68K, Xtensa, MIPS, Nios II, RISC-V
-    only).
+    Enable and configure semihosting (ARM, M68K, Xtensa, MIPS, Nios II,
+    RISC-V, PPC only).
 
     Note that this allows guest direct access to the host filesystem, so
     should only be used with a trusted guest OS.
@@ -4563,6 +4564,9 @@  SRST
 
     On RISC-V this implements the standard semihosting API, version 0.2.
 
+    On PPC this implements the standard Arm semihosting API, version 2.0,
+    with only the trap instruction and register definitions changed.
+
     ``target=native|gdb|auto``
         Defines where the semihosting calls will be addressed, to QEMU
         (``native``) or to GDB (``gdb``). The default is ``auto``, which
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 7a51fd0737..e1279c316c 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -268,6 +268,31 @@  common_semi_sys_exit_extended(CPUState *cs, int nr)
 
 #endif
 
+#ifdef TARGET_PPC64
+static inline target_ulong
+common_semi_arg(CPUState *cs, int argno)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+    return env->gpr[3 + argno];
+}
+
+static inline void
+common_semi_set_ret(CPUState *cs, target_ulong ret)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+    env->gpr[3] = ret;
+}
+
+static inline bool
+common_semi_sys_exit_extended(CPUState *cs, int nr)
+{
+    return (nr == TARGET_SYS_EXIT_EXTENDED || sizeof(target_ulong) == 8);
+}
+
+#endif
+
 /*
  * Allocate a new guest file descriptor and return it; if we
  * couldn't allocate a new fd then return -1.
@@ -450,6 +475,12 @@  static target_ulong common_semi_flen_buf(CPUState *cs)
 
     sp = env->gpr[xSP];
 #endif
+#ifdef TARGET_PPC64
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    sp = env->gpr[1];
+#endif
 
     return sp - 64;
 }
@@ -780,6 +811,8 @@  static inline bool is_64bit_semihosting(CPUArchState *env)
     return is_a64(env);
 #elif defined(TARGET_RISCV)
     return riscv_cpu_mxl(env) != MXL_RV32;
+#elif defined(TARGET_PPC64)
+    return true;
 #else
 #error un-handled architecture
 #endif
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 047b24ba50..349104ad79 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -129,8 +129,9 @@  enum {
     POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception                     */
     POWERPC_EXCP_PERFM_EBB = 103,    /* Performance Monitor EBB Exception    */
     POWERPC_EXCP_EXTERNAL_EBB = 104, /* External EBB Exception               */
+    POWERPC_EXCP_SEMIHOST = 105,     /* Semihosting Exception                */
     /* EOL                                                                   */
-    POWERPC_EXCP_NB       = 105,
+    POWERPC_EXCP_NB       = 106,
     /* QEMU exceptions: special cases we want to stop translation            */
     POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only      */
 };
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index d3e2cfcd71..af34a57082 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -25,6 +25,7 @@ 
 #include "helper_regs.h"
 
 #include "trace.h"
+#include "semihosting/common-semi.h"
 
 #ifdef CONFIG_TCG
 #include "exec/helper-proto.h"
@@ -100,6 +101,7 @@  static const char *powerpc_excp_name(int excp)
     case POWERPC_EXCP_SDOOR_HV: return "SDOOR_HV";
     case POWERPC_EXCP_HVIRT:    return "HVIRT";
     case POWERPC_EXCP_SYSCALL_VECTORED: return "SYSCALL_VECTORED";
+    case POWERPC_EXCP_SEMIHOST: return "SEMIHOST";
     default:
         g_assert_not_reached();
     }
@@ -1327,6 +1329,13 @@  static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
     target_ulong msr, new_msr, vector;
     int srr0, srr1, lev = -1;
 
+    /* Handle semihost exceptions first */
+    if (excp == POWERPC_EXCP_SEMIHOST) {
+        env->gpr[3] = do_common_semihosting(cs);
+        env->nip += 4;
+        return;
+    }
+
     /* new srr1 value excluding must-be-zero bits */
     msr = env->msr & ~0x783f0000ULL;
 
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 408ae26173..c013889a84 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -4520,6 +4520,20 @@  static void gen_sc(DisasContext *ctx)
     uint32_t lev;
 
     lev = (ctx->opcode >> 5) & 0x7F;
+
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+    /*
+     * PowerPC semihosting uses the following
+     * instruction to flag a semihosting call:
+     *
+     *      sc 7            0x440000e2
+     */
+    if (lev == 7) {
+        gen_exception(ctx, POWERPC_EXCP_SEMIHOST);
+        return;
+    }
+#endif
+
     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
 }