qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alexey Kardashevskiy <aik@ozlabs.ru>
To: qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org, David Gibson <david@gibson.dropbear.id.au>
Subject: Re: [Qemu-devel] [PATCH qemu v3] target-ppc: Define get_monitor_def
Date: Mon, 7 Sep 2015 11:26:52 +1000	[thread overview]
Message-ID: <55ECE7DC.1000104@ozlabs.ru> (raw)
In-Reply-To: <1439523270-32718-1-git-send-email-aik@ozlabs.ru>

On 08/14/2015 01:34 PM, Alexey Kardashevskiy wrote:
> At the moment get_monitor_def() prints only registers from monitor_defs.
> However there is a lot of BOOK3S SPRs which are not in the list and
> cannot be printed.
>
> This makes use of the new get_monitor_def() callback and prints all
> registered SPRs and fails on unregistered ones proving the user

ping?

and also s/proving the user/providing the user with/ (not sure what I 
thought about when I wrote it)? :)




> information on what is actually supported in the running CPU.
>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> Changes:
> v3:
> * removed the check for endptr as strtoul() always initializes it
> * check if there is any number after r/f/sr and fail if none
> * added tolower()/strncasecmp() to support both r/f/sr and R/F/SR
>
> v2:
> * handles r**, f**, sr** if their numbers  were parsed completely and correctly
> * added "cr" as synonym of "ccr"
> ---
>   monitor.c                   | 215 +-------------------------------------------
>   target-ppc/cpu-qom.h        |   2 +
>   target-ppc/translate.c      |  80 +++++++++++++++++
>   target-ppc/translate_init.c |   1 +
>   4 files changed, 84 insertions(+), 214 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index bdfcacc..07ca678 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2916,51 +2916,6 @@ static target_long monitor_get_pc (const struct MonitorDef *md, int val)
>   }
>   #endif
>
> -#if defined(TARGET_PPC)
> -static target_long monitor_get_ccr (const struct MonitorDef *md, int val)
> -{
> -    CPUArchState *env = mon_get_cpu_env();
> -    unsigned int u;
> -    int i;
> -
> -    u = 0;
> -    for (i = 0; i < 8; i++)
> -        u |= env->crf[i] << (32 - (4 * (i + 1)));
> -
> -    return u;
> -}
> -
> -static target_long monitor_get_msr (const struct MonitorDef *md, int val)
> -{
> -    CPUArchState *env = mon_get_cpu_env();
> -    return env->msr;
> -}
> -
> -static target_long monitor_get_xer (const struct MonitorDef *md, int val)
> -{
> -    CPUArchState *env = mon_get_cpu_env();
> -    return env->xer;
> -}
> -
> -static target_long monitor_get_decr (const struct MonitorDef *md, int val)
> -{
> -    CPUArchState *env = mon_get_cpu_env();
> -    return cpu_ppc_load_decr(env);
> -}
> -
> -static target_long monitor_get_tbu (const struct MonitorDef *md, int val)
> -{
> -    CPUArchState *env = mon_get_cpu_env();
> -    return cpu_ppc_load_tbu(env);
> -}
> -
> -static target_long monitor_get_tbl (const struct MonitorDef *md, int val)
> -{
> -    CPUArchState *env = mon_get_cpu_env();
> -    return cpu_ppc_load_tbl(env);
> -}
> -#endif
> -
>   #if defined(TARGET_SPARC)
>   #ifndef TARGET_SPARC64
>   static target_long monitor_get_psr (const struct MonitorDef *md, int val)
> @@ -3014,175 +2969,7 @@ static const MonitorDef monitor_defs[] = {
>       SEG("gs", R_GS)
>       { "pc", 0, monitor_get_pc, },
>   #elif defined(TARGET_PPC)
> -    /* General purpose registers */
> -    { "r0", offsetof(CPUPPCState, gpr[0]) },
> -    { "r1", offsetof(CPUPPCState, gpr[1]) },
> -    { "r2", offsetof(CPUPPCState, gpr[2]) },
> -    { "r3", offsetof(CPUPPCState, gpr[3]) },
> -    { "r4", offsetof(CPUPPCState, gpr[4]) },
> -    { "r5", offsetof(CPUPPCState, gpr[5]) },
> -    { "r6", offsetof(CPUPPCState, gpr[6]) },
> -    { "r7", offsetof(CPUPPCState, gpr[7]) },
> -    { "r8", offsetof(CPUPPCState, gpr[8]) },
> -    { "r9", offsetof(CPUPPCState, gpr[9]) },
> -    { "r10", offsetof(CPUPPCState, gpr[10]) },
> -    { "r11", offsetof(CPUPPCState, gpr[11]) },
> -    { "r12", offsetof(CPUPPCState, gpr[12]) },
> -    { "r13", offsetof(CPUPPCState, gpr[13]) },
> -    { "r14", offsetof(CPUPPCState, gpr[14]) },
> -    { "r15", offsetof(CPUPPCState, gpr[15]) },
> -    { "r16", offsetof(CPUPPCState, gpr[16]) },
> -    { "r17", offsetof(CPUPPCState, gpr[17]) },
> -    { "r18", offsetof(CPUPPCState, gpr[18]) },
> -    { "r19", offsetof(CPUPPCState, gpr[19]) },
> -    { "r20", offsetof(CPUPPCState, gpr[20]) },
> -    { "r21", offsetof(CPUPPCState, gpr[21]) },
> -    { "r22", offsetof(CPUPPCState, gpr[22]) },
> -    { "r23", offsetof(CPUPPCState, gpr[23]) },
> -    { "r24", offsetof(CPUPPCState, gpr[24]) },
> -    { "r25", offsetof(CPUPPCState, gpr[25]) },
> -    { "r26", offsetof(CPUPPCState, gpr[26]) },
> -    { "r27", offsetof(CPUPPCState, gpr[27]) },
> -    { "r28", offsetof(CPUPPCState, gpr[28]) },
> -    { "r29", offsetof(CPUPPCState, gpr[29]) },
> -    { "r30", offsetof(CPUPPCState, gpr[30]) },
> -    { "r31", offsetof(CPUPPCState, gpr[31]) },
> -    /* Floating point registers */
> -    { "f0", offsetof(CPUPPCState, fpr[0]) },
> -    { "f1", offsetof(CPUPPCState, fpr[1]) },
> -    { "f2", offsetof(CPUPPCState, fpr[2]) },
> -    { "f3", offsetof(CPUPPCState, fpr[3]) },
> -    { "f4", offsetof(CPUPPCState, fpr[4]) },
> -    { "f5", offsetof(CPUPPCState, fpr[5]) },
> -    { "f6", offsetof(CPUPPCState, fpr[6]) },
> -    { "f7", offsetof(CPUPPCState, fpr[7]) },
> -    { "f8", offsetof(CPUPPCState, fpr[8]) },
> -    { "f9", offsetof(CPUPPCState, fpr[9]) },
> -    { "f10", offsetof(CPUPPCState, fpr[10]) },
> -    { "f11", offsetof(CPUPPCState, fpr[11]) },
> -    { "f12", offsetof(CPUPPCState, fpr[12]) },
> -    { "f13", offsetof(CPUPPCState, fpr[13]) },
> -    { "f14", offsetof(CPUPPCState, fpr[14]) },
> -    { "f15", offsetof(CPUPPCState, fpr[15]) },
> -    { "f16", offsetof(CPUPPCState, fpr[16]) },
> -    { "f17", offsetof(CPUPPCState, fpr[17]) },
> -    { "f18", offsetof(CPUPPCState, fpr[18]) },
> -    { "f19", offsetof(CPUPPCState, fpr[19]) },
> -    { "f20", offsetof(CPUPPCState, fpr[20]) },
> -    { "f21", offsetof(CPUPPCState, fpr[21]) },
> -    { "f22", offsetof(CPUPPCState, fpr[22]) },
> -    { "f23", offsetof(CPUPPCState, fpr[23]) },
> -    { "f24", offsetof(CPUPPCState, fpr[24]) },
> -    { "f25", offsetof(CPUPPCState, fpr[25]) },
> -    { "f26", offsetof(CPUPPCState, fpr[26]) },
> -    { "f27", offsetof(CPUPPCState, fpr[27]) },
> -    { "f28", offsetof(CPUPPCState, fpr[28]) },
> -    { "f29", offsetof(CPUPPCState, fpr[29]) },
> -    { "f30", offsetof(CPUPPCState, fpr[30]) },
> -    { "f31", offsetof(CPUPPCState, fpr[31]) },
> -    { "fpscr", offsetof(CPUPPCState, fpscr) },
> -    /* Next instruction pointer */
> -    { "nip|pc", offsetof(CPUPPCState, nip) },
> -    { "lr", offsetof(CPUPPCState, lr) },
> -    { "ctr", offsetof(CPUPPCState, ctr) },
> -    { "decr", 0, &monitor_get_decr, },
> -    { "ccr", 0, &monitor_get_ccr, },
> -    /* Machine state register */
> -    { "msr", 0, &monitor_get_msr, },
> -    { "xer", 0, &monitor_get_xer, },
> -    { "tbu", 0, &monitor_get_tbu, },
> -    { "tbl", 0, &monitor_get_tbl, },
> -    /* Segment registers */
> -    { "sdr1", offsetof(CPUPPCState, spr[SPR_SDR1]) },
> -    { "sr0", offsetof(CPUPPCState, sr[0]) },
> -    { "sr1", offsetof(CPUPPCState, sr[1]) },
> -    { "sr2", offsetof(CPUPPCState, sr[2]) },
> -    { "sr3", offsetof(CPUPPCState, sr[3]) },
> -    { "sr4", offsetof(CPUPPCState, sr[4]) },
> -    { "sr5", offsetof(CPUPPCState, sr[5]) },
> -    { "sr6", offsetof(CPUPPCState, sr[6]) },
> -    { "sr7", offsetof(CPUPPCState, sr[7]) },
> -    { "sr8", offsetof(CPUPPCState, sr[8]) },
> -    { "sr9", offsetof(CPUPPCState, sr[9]) },
> -    { "sr10", offsetof(CPUPPCState, sr[10]) },
> -    { "sr11", offsetof(CPUPPCState, sr[11]) },
> -    { "sr12", offsetof(CPUPPCState, sr[12]) },
> -    { "sr13", offsetof(CPUPPCState, sr[13]) },
> -    { "sr14", offsetof(CPUPPCState, sr[14]) },
> -    { "sr15", offsetof(CPUPPCState, sr[15]) },
> -    /* Too lazy to put BATs... */
> -    { "pvr", offsetof(CPUPPCState, spr[SPR_PVR]) },
> -
> -    { "srr0", offsetof(CPUPPCState, spr[SPR_SRR0]) },
> -    { "srr1", offsetof(CPUPPCState, spr[SPR_SRR1]) },
> -    { "dar", offsetof(CPUPPCState, spr[SPR_DAR]) },
> -    { "dsisr", offsetof(CPUPPCState, spr[SPR_DSISR]) },
> -    { "cfar", offsetof(CPUPPCState, spr[SPR_CFAR]) },
> -    { "sprg0", offsetof(CPUPPCState, spr[SPR_SPRG0]) },
> -    { "sprg1", offsetof(CPUPPCState, spr[SPR_SPRG1]) },
> -    { "sprg2", offsetof(CPUPPCState, spr[SPR_SPRG2]) },
> -    { "sprg3", offsetof(CPUPPCState, spr[SPR_SPRG3]) },
> -    { "sprg4", offsetof(CPUPPCState, spr[SPR_SPRG4]) },
> -    { "sprg5", offsetof(CPUPPCState, spr[SPR_SPRG5]) },
> -    { "sprg6", offsetof(CPUPPCState, spr[SPR_SPRG6]) },
> -    { "sprg7", offsetof(CPUPPCState, spr[SPR_SPRG7]) },
> -    { "pid", offsetof(CPUPPCState, spr[SPR_BOOKE_PID]) },
> -    { "csrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR0]) },
> -    { "csrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR1]) },
> -    { "esr", offsetof(CPUPPCState, spr[SPR_BOOKE_ESR]) },
> -    { "dear", offsetof(CPUPPCState, spr[SPR_BOOKE_DEAR]) },
> -    { "mcsr", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSR]) },
> -    { "tsr", offsetof(CPUPPCState, spr[SPR_BOOKE_TSR]) },
> -    { "tcr", offsetof(CPUPPCState, spr[SPR_BOOKE_TCR]) },
> -    { "vrsave", offsetof(CPUPPCState, spr[SPR_VRSAVE]) },
> -    { "pir", offsetof(CPUPPCState, spr[SPR_BOOKE_PIR]) },
> -    { "mcsrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR0]) },
> -    { "mcsrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR1]) },
> -    { "decar", offsetof(CPUPPCState, spr[SPR_BOOKE_DECAR]) },
> -    { "ivpr", offsetof(CPUPPCState, spr[SPR_BOOKE_IVPR]) },
> -    { "epcr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPCR]) },
> -    { "sprg8", offsetof(CPUPPCState, spr[SPR_BOOKE_SPRG8]) },
> -    { "ivor0", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR0]) },
> -    { "ivor1", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR1]) },
> -    { "ivor2", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR2]) },
> -    { "ivor3", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR3]) },
> -    { "ivor4", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR4]) },
> -    { "ivor5", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR5]) },
> -    { "ivor6", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR6]) },
> -    { "ivor7", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR7]) },
> -    { "ivor8", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR8]) },
> -    { "ivor9", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR9]) },
> -    { "ivor10", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR10]) },
> -    { "ivor11", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR11]) },
> -    { "ivor12", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR12]) },
> -    { "ivor13", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR13]) },
> -    { "ivor14", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR14]) },
> -    { "ivor15", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR15]) },
> -    { "ivor32", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR32]) },
> -    { "ivor33", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR33]) },
> -    { "ivor34", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR34]) },
> -    { "ivor35", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR35]) },
> -    { "ivor36", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR36]) },
> -    { "ivor37", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR37]) },
> -    { "mas0", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS0]) },
> -    { "mas1", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS1]) },
> -    { "mas2", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS2]) },
> -    { "mas3", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS3]) },
> -    { "mas4", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS4]) },
> -    { "mas6", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS6]) },
> -    { "mas7", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS7]) },
> -    { "mmucfg", offsetof(CPUPPCState, spr[SPR_MMUCFG]) },
> -    { "tlb0cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB0CFG]) },
> -    { "tlb1cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB1CFG]) },
> -    { "epr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPR]) },
> -    { "eplc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPLC]) },
> -    { "epsc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPSC]) },
> -    { "svr", offsetof(CPUPPCState, spr[SPR_E500_SVR]) },
> -    { "mcar", offsetof(CPUPPCState, spr[SPR_Exxx_MCAR]) },
> -    { "pid1", offsetof(CPUPPCState, spr[SPR_BOOKE_PID1]) },
> -    { "pid2", offsetof(CPUPPCState, spr[SPR_BOOKE_PID2]) },
> -    { "hid0", offsetof(CPUPPCState, spr[SPR_HID0]) },
> -
> +    /* Uses get_monitor_def() */
>   #elif defined(TARGET_SPARC)
>       { "g0", offsetof(CPUSPARCState, gregs[0]) },
>       { "g1", offsetof(CPUSPARCState, gregs[1]) },
> diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
> index 6967a80..bc20504 100644
> --- a/target-ppc/cpu-qom.h
> +++ b/target-ppc/cpu-qom.h
> @@ -118,6 +118,8 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
>                           int flags);
>   void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
>                                fprintf_function cpu_fprintf, int flags);
> +int ppc_cpu_get_monitor_def(CPUState *cs, const char *name,
> +                            uint64_t *pval);
>   hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>   int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
>   int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg);
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 84c5cea..2c6f772 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -11401,6 +11401,86 @@ void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
>   #endif
>   }
>
> +static bool ppc_cpu_get_reg(target_ulong *regs, const char *numstr, int maxnum,
> +                            uint64_t *pval)
> +{
> +    char *endptr = NULL;
> +    int regnum;
> +
> +    if (!*numstr) {
> +        return false;
> +    }
> +
> +    regnum = strtoul(numstr, &endptr, 10);
> +    if (*endptr || (regnum >= maxnum)) {
> +        return false;
> +    }
> +    *pval = regs[regnum];
> +
> +    return true;
> +}
> +
> +int ppc_cpu_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
> +{
> +    int i;
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +
> +#define MONREG(s, f) \
> +    if ((strcasecmp((s), name) == 0)) { \
> +        *pval = (f); \
> +        return 0; \
> +    }
> +    MONREG("pc", env->nip)
> +    MONREG("nip", env->nip)
> +    MONREG("lr", env->lr)
> +    MONREG("ctr", env->ctr)
> +    MONREG("xer", env->xer)
> +    MONREG("decr", cpu_ppc_load_decr(env))
> +    MONREG("msr",  env->msr)
> +    MONREG("tbu",  cpu_ppc_load_tbu(env))
> +    MONREG("tbl", cpu_ppc_load_tbl(env))
> +
> +    if ((strcasecmp("ccr", name) == 0) || (strcasecmp("cr", name) == 0)) {
> +        unsigned int u = 0;
> +
> +        for (i = 0; i < 8; i++)
> +            u |= env->crf[i] << (32 - (4 * (i + 1)));
> +
> +        return u;
> +    }
> +
> +    /* General purpose registers */
> +    if ((tolower(name[0]) == 'r') &&
> +        ppc_cpu_get_reg(env->gpr, name + 1, ARRAY_SIZE(env->gpr), pval)) {
> +        return 0;
> +    }
> +
> +    /* Floating point registers */
> +    if ((tolower(name[0]) == 'f') &&
> +        ppc_cpu_get_reg(env->fpr, name + 1, ARRAY_SIZE(env->fpr), pval)) {
> +        return 0;
> +    }
> +
> +    /* Segment registers */
> +    if ((strncasecmp(name, "sr", 2) == 0) &&
> +        ppc_cpu_get_reg(env->sr, name + 2, ARRAY_SIZE(env->sr), pval)) {
> +        return 0;
> +    }
> +
> +    /* Special purpose registers */
> +    for (i = 0; i < ARRAY_SIZE(env->spr_cb); ++i) {
> +        ppc_spr_t *spr = &env->spr_cb[i];
> +
> +        if (spr->name && (strcasecmp(name, spr->name) == 0)) {
> +            *pval = env->spr[i];
> +            return 0;
> +        }
> +    }
> +
> +    return -EINVAL;
> +}
> +
>   /*****************************************************************************/
>   static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
>                                                     TranslationBlock *tb,
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 16d7b16..038674a 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -9706,6 +9706,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
>       cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
>       cc->dump_state = ppc_cpu_dump_state;
>       cc->dump_statistics = ppc_cpu_dump_statistics;
> +    cc->get_monitor_def = ppc_cpu_get_monitor_def;
>       cc->set_pc = ppc_cpu_set_pc;
>       cc->gdb_read_register = ppc_cpu_gdb_read_register;
>       cc->gdb_write_register = ppc_cpu_gdb_write_register;
>


-- 
Alexey

  reply	other threads:[~2015-09-07  1:27 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-06  5:25 [Qemu-devel] [PATCH qemu 0/2] monitor/ppc: Print correct SPRs Alexey Kardashevskiy
2015-08-06  5:25 ` [Qemu-devel] [PATCH qemu 1/2] monitor: Add CPU class callback to read registers for monitor Alexey Kardashevskiy
2015-08-12  1:12   ` David Gibson
2015-08-06  5:25 ` [Qemu-devel] [PATCH qemu 2/2] target-ppc: Define get_monitor_def Alexey Kardashevskiy
2015-08-06  6:33   ` Thomas Huth
2015-08-06  7:00     ` Alexey Kardashevskiy
2015-08-06  7:07       ` Thomas Huth
2015-08-12  1:21   ` David Gibson
2015-08-13 15:52     ` [Qemu-devel] [PATCH qemu v2] " Alexey Kardashevskiy
2015-08-13 22:39       ` David Gibson
2015-08-14  3:34         ` [Qemu-devel] [PATCH qemu v3] " Alexey Kardashevskiy
2015-09-07  1:26           ` Alexey Kardashevskiy [this message]
2015-09-23  3:40           ` David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55ECE7DC.1000104@ozlabs.ru \
    --to=aik@ozlabs.ru \
    --cc=david@gibson.dropbear.id.au \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).