* [Qemu-devel] [PATCH 1/6] pseries: Bugfixes for interrupt numbering in XICS code
2011-08-04 7:02 [Qemu-devel] pseries machine updates David Gibson
@ 2011-08-04 7:02 ` David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 2/6] Implement POWER7's CFAR in TCG David Gibson
` (5 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: David Gibson @ 2011-08-04 7:02 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
The implementation of the XICS interrupt controller contains several
(difficult to trigger) bugs due to the fact that we were not 100%
consistent with which irq numbering we used. In most places, global
numbers were used as handled by the presentation layer, however a few
functions took "local" numberings, that is the source number within
the interrupt source controller which is offset from the global
number. In most cases the function and its caller agreed on this, but
in a few cases it didn't.
This patch cleans this up by always using global numbering.
Translation to the local number is now always and only done when we
look up the individual interrupt source state structure. This should
remove the existing bugs and with luck reduce the chances of
re-introducing such bugs.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
hw/xics.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/hw/xics.c b/hw/xics.c
index 13a1d25..93da4f6 100644
--- a/hw/xics.c
+++ b/hw/xics.c
@@ -187,17 +187,17 @@ static int ics_valid_irq(struct ics_state *ics, uint32_t nr)
&& (nr < (ics->offset + ics->nr_irqs));
}
-static void ics_set_irq_msi(void *opaque, int nr, int val)
+static void ics_set_irq_msi(void *opaque, int srcno, int val)
{
struct ics_state *ics = (struct ics_state *)opaque;
- struct ics_irq_state *irq = ics->irqs + nr;
+ struct ics_irq_state *irq = ics->irqs + srcno;
if (val) {
if (irq->priority == 0xff) {
irq->masked_pending = 1;
/* masked pending */ ;
} else {
- icp_irq(ics->icp, irq->server, nr + ics->offset, irq->priority);
+ icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
}
}
}
@@ -229,7 +229,7 @@ static void ics_resend_msi(struct ics_state *ics)
static void ics_write_xive_msi(struct ics_state *ics, int nr, int server,
uint8_t priority)
{
- struct ics_irq_state *irq = ics->irqs + nr;
+ struct ics_irq_state *irq = ics->irqs + nr - ics->offset;
irq->server = server;
irq->priority = priority;
@@ -239,7 +239,7 @@ static void ics_write_xive_msi(struct ics_state *ics, int nr, int server,
}
irq->masked_pending = 0;
- icp_irq(ics->icp, server, nr + ics->offset, priority);
+ icp_irq(ics->icp, server, nr, priority);
}
static void ics_reject(struct ics_state *ics, int nr)
@@ -334,7 +334,7 @@ static void rtas_set_xive(sPAPREnvironment *spapr, uint32_t token,
return;
}
- ics_write_xive_msi(ics, nr - ics->offset, server, priority);
+ ics_write_xive_msi(ics, nr, server, priority);
rtas_st(rets, 0, 0); /* Success */
}
@@ -388,7 +388,7 @@ static void rtas_int_off(sPAPREnvironment *spapr, uint32_t token,
struct ics_irq_state *irq = xics->irqs + (nr - xics->offset);
irq->saved_priority = irq->priority;
- ics_write_xive_msi(xics, nr - xics->offset, irq->server, 0xff);
+ ics_write_xive_msi(xics, nr, irq->server, 0xff);
#endif
rtas_st(rets, 0, 0); /* Success */
@@ -418,8 +418,7 @@ static void rtas_int_on(sPAPREnvironment *spapr, uint32_t token,
#if 0
struct ics_irq_state *irq = xics->irqs + (nr - xics->offset);
- ics_write_xive_msi(xics, nr - xics->offset,
- irq->server, irq->saved_priority);
+ ics_write_xive_msi(xics, nr, irq->server, irq->saved_priority);
#endif
rtas_st(rets, 0, 0); /* Success */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 2/6] Implement POWER7's CFAR in TCG
2011-08-04 7:02 [Qemu-devel] pseries machine updates David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 1/6] pseries: Bugfixes for interrupt numbering in XICS code David Gibson
@ 2011-08-04 7:02 ` David Gibson
2011-08-10 15:10 ` Alexander Graf
2011-08-04 7:02 ` [Qemu-devel] [PATCH 3/6] pseries: Add real mode debugging hcalls David Gibson
` (4 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: David Gibson @ 2011-08-04 7:02 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
This patch implements support for the CFAR SPR on POWER7 (Come From
Address Register), which snapshots the PC value at the time of a branch or
an rfid. The latest powerpc-next kernel also catches it and can show it in
xmon or in the signal frames.
This works well enough to let recent kernels boot (which otherwise oops
on the CFAR access). It hasn't been tested enough to be confident that the
CFAR values are actually accurate, but one thing at a time.
Signed-off-by: Ben Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
target-ppc/cpu.h | 8 ++++++++
target-ppc/translate.c | 33 +++++++++++++++++++++++++++++++--
target-ppc/translate_init.c | 21 ++++++++++++++++++++-
3 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index d903366..8cf029f 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -540,6 +540,8 @@ enum {
/* Decrementer clock: RTC clock (POWER, 601) or bus clock */
POWERPC_FLAG_RTC_CLK = 0x00010000,
POWERPC_FLAG_BUS_CLK = 0x00020000,
+ /* Has CFAR */
+ POWERPC_FLAG_CFAR = 0x00040000,
};
/*****************************************************************************/
@@ -857,6 +859,10 @@ struct CPUPPCState {
target_ulong ctr;
/* condition register */
uint32_t crf[8];
+#if defined(TARGET_PPC64)
+ /* CFAR */
+ target_ulong cfar;
+#endif
/* XER */
target_ulong xer;
/* Reservation address */
@@ -1187,6 +1193,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
#define SPR_601_UDECR (0x006)
#define SPR_LR (0x008)
#define SPR_CTR (0x009)
+#define SPR_DSCR (0x011)
#define SPR_DSISR (0x012)
#define SPR_DAR (0x013) /* DAE for PowerPC 601 */
#define SPR_601_RTCU (0x014)
@@ -1195,6 +1202,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
#define SPR_SDR1 (0x019)
#define SPR_SRR0 (0x01A)
#define SPR_SRR1 (0x01B)
+#define SPR_CFAR (0x01C)
#define SPR_AMR (0x01D)
#define SPR_BOOKE_PID (0x030)
#define SPR_BOOKE_DECAR (0x036)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fd7c208..cb49c7d 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -69,6 +69,9 @@ static TCGv cpu_nip;
static TCGv cpu_msr;
static TCGv cpu_ctr;
static TCGv cpu_lr;
+#if defined(TARGET_PPC64)
+static TCGv cpu_cfar;
+#endif
static TCGv cpu_xer;
static TCGv cpu_reserve;
static TCGv_i32 cpu_fpscr;
@@ -154,6 +157,11 @@ void ppc_translate_init(void)
cpu_lr = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, lr), "lr");
+#if defined(TARGET_PPC64)
+ cpu_cfar = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUState, cfar), "cfar");
+#endif
+
cpu_xer = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, xer), "xer");
@@ -187,12 +195,13 @@ typedef struct DisasContext {
int le_mode;
#if defined(TARGET_PPC64)
int sf_mode;
+ int has_cfar;
#endif
int fpu_enabled;
int altivec_enabled;
int spe_enabled;
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
- int singlestep_enabled;
+ int singlestep_enabled;
} DisasContext;
struct opc_handler_t {
@@ -3345,6 +3354,14 @@ static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
/* stfiwx */
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
+static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
+{
+#if defined(TARGET_PPC64)
+ if (ctx->has_cfar)
+ tcg_gen_movi_tl(cpu_cfar, nip);
+#endif
+}
+
/*** Branch ***/
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
{
@@ -3352,7 +3369,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
tb = ctx->tb;
#if defined(TARGET_PPC64)
if (!ctx->sf_mode)
- dest = (uint32_t) dest;
+ dest = (uint32_t) dest;
#endif
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
likely(!ctx->singlestep_enabled)) {
@@ -3407,6 +3424,7 @@ static void gen_b(DisasContext *ctx)
target = li;
if (LK(ctx->opcode))
gen_setlr(ctx, ctx->nip);
+ gen_update_cfar(ctx, ctx->nip);
gen_goto_tb(ctx, 0, target);
}
@@ -3469,6 +3487,7 @@ static inline void gen_bcond(DisasContext *ctx, int type)
}
tcg_temp_free_i32(temp);
}
+ gen_update_cfar(ctx, ctx->nip);
if (type == BCOND_IM) {
target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
if (likely(AA(ctx->opcode) == 0)) {
@@ -3569,6 +3588,7 @@ static void gen_mcrf(DisasContext *ctx)
/*** System linkage ***/
+
/* rfi (mem_idx only) */
static void gen_rfi(DisasContext *ctx)
{
@@ -3580,6 +3600,7 @@ static void gen_rfi(DisasContext *ctx)
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
+ gen_update_cfar(ctx, ctx->nip);
gen_helper_rfi();
gen_sync_exception(ctx);
#endif
@@ -3596,6 +3617,7 @@ static void gen_rfid(DisasContext *ctx)
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
+ gen_update_cfar(ctx, ctx->nip);
gen_helper_rfid();
gen_sync_exception(ctx);
#endif
@@ -9263,6 +9285,12 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
*/
}
+#if defined(TARGET_PPC64)
+ if (env->flags & POWERPC_FLAG_CFAR) {
+ cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
+ }
+#endif
+
switch (env->mmu_model) {
case POWERPC_MMU_32B:
case POWERPC_MMU_601:
@@ -9371,6 +9399,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
#if defined(TARGET_PPC64)
ctx.sf_mode = msr_sf;
+ ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
#endif
ctx.fpu_enabled = msr_fp;
if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index f542b8e..510d9dd 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -129,6 +129,17 @@ static void spr_write_lr (void *opaque, int sprn, int gprn)
tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
}
+/* CFAR */
+static void spr_read_cfar (void *opaque, int gprn, int sprn)
+{
+ tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
+}
+
+static void spr_write_cfar (void *opaque, int sprn, int gprn)
+{
+ tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
+}
+
/* CTR */
static void spr_read_ctr (void *opaque, int gprn, int sprn)
{
@@ -6489,7 +6500,7 @@ static void init_proc_970MP (CPUPPCState *env)
#define POWERPC_BFDM_POWER7 (bfd_mach_ppc64)
#define POWERPC_FLAG_POWER7 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
+ POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR)
#define check_pow_POWER7 check_pow_nocheck
static void init_proc_POWER7 (CPUPPCState *env)
@@ -6508,6 +6519,14 @@ static void init_proc_POWER7 (CPUPPCState *env)
&spr_read_purr, SPR_NOACCESS,
&spr_read_purr, SPR_NOACCESS,
0x00000000);
+ spr_register(env, SPR_CFAR, "SPR_CFAR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_cfar, &spr_write_cfar,
+ 0x00000000);
+ spr_register(env, SPR_DSCR, "SPR_DSCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
#endif /* !CONFIG_USER_ONLY */
/* Memory management */
/* XXX : not implemented */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 2/6] Implement POWER7's CFAR in TCG
2011-08-04 7:02 ` [Qemu-devel] [PATCH 2/6] Implement POWER7's CFAR in TCG David Gibson
@ 2011-08-10 15:10 ` Alexander Graf
2011-08-11 0:35 ` David Gibson
0 siblings, 1 reply; 18+ messages in thread
From: Alexander Graf @ 2011-08-10 15:10 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel
On 08/04/2011 09:02 AM, David Gibson wrote:
> This patch implements support for the CFAR SPR on POWER7 (Come From
> Address Register), which snapshots the PC value at the time of a branch or
> an rfid. The latest powerpc-next kernel also catches it and can show it in
> xmon or in the signal frames.
>
> This works well enough to let recent kernels boot (which otherwise oops
> on the CFAR access). It hasn't been tested enough to be confident that the
> CFAR values are actually accurate, but one thing at a time.
>
> Signed-off-by: Ben Herrenschmidt<benh@kernel.crashing.org>
> Signed-off-by: David Gibson<david@gibson.dropbear.id.au>
> ---
> target-ppc/cpu.h | 8 ++++++++
> target-ppc/translate.c | 33 +++++++++++++++++++++++++++++++--
> target-ppc/translate_init.c | 21 ++++++++++++++++++++-
> 3 files changed, 59 insertions(+), 3 deletions(-)
>
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index d903366..8cf029f 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -540,6 +540,8 @@ enum {
> /* Decrementer clock: RTC clock (POWER, 601) or bus clock */
> POWERPC_FLAG_RTC_CLK = 0x00010000,
> POWERPC_FLAG_BUS_CLK = 0x00020000,
> + /* Has CFAR */
> + POWERPC_FLAG_CFAR = 0x00040000,
> };
>
> /*****************************************************************************/
> @@ -857,6 +859,10 @@ struct CPUPPCState {
> target_ulong ctr;
> /* condition register */
> uint32_t crf[8];
> +#if defined(TARGET_PPC64)
> + /* CFAR */
> + target_ulong cfar;
> +#endif
> /* XER */
> target_ulong xer;
> /* Reservation address */
> @@ -1187,6 +1193,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
> #define SPR_601_UDECR (0x006)
> #define SPR_LR (0x008)
> #define SPR_CTR (0x009)
> +#define SPR_DSCR (0x011)
> #define SPR_DSISR (0x012)
> #define SPR_DAR (0x013) /* DAE for PowerPC 601 */
> #define SPR_601_RTCU (0x014)
> @@ -1195,6 +1202,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
> #define SPR_SDR1 (0x019)
> #define SPR_SRR0 (0x01A)
> #define SPR_SRR1 (0x01B)
> +#define SPR_CFAR (0x01C)
> #define SPR_AMR (0x01D)
> #define SPR_BOOKE_PID (0x030)
> #define SPR_BOOKE_DECAR (0x036)
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index fd7c208..cb49c7d 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -69,6 +69,9 @@ static TCGv cpu_nip;
> static TCGv cpu_msr;
> static TCGv cpu_ctr;
> static TCGv cpu_lr;
> +#if defined(TARGET_PPC64)
> +static TCGv cpu_cfar;
> +#endif
> static TCGv cpu_xer;
> static TCGv cpu_reserve;
> static TCGv_i32 cpu_fpscr;
> @@ -154,6 +157,11 @@ void ppc_translate_init(void)
> cpu_lr = tcg_global_mem_new(TCG_AREG0,
> offsetof(CPUState, lr), "lr");
>
> +#if defined(TARGET_PPC64)
> + cpu_cfar = tcg_global_mem_new(TCG_AREG0,
> + offsetof(CPUState, cfar), "cfar");
> +#endif
> +
> cpu_xer = tcg_global_mem_new(TCG_AREG0,
> offsetof(CPUState, xer), "xer");
>
> @@ -187,12 +195,13 @@ typedef struct DisasContext {
> int le_mode;
> #if defined(TARGET_PPC64)
> int sf_mode;
> + int has_cfar;
> #endif
> int fpu_enabled;
> int altivec_enabled;
> int spe_enabled;
> ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
> - int singlestep_enabled;
> + int singlestep_enabled;
Fairly sure this isn't intended :)
> } DisasContext;
>
> struct opc_handler_t {
> @@ -3345,6 +3354,14 @@ static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
> /* stfiwx */
> GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
>
> +static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
> +{
> +#if defined(TARGET_PPC64)
> + if (ctx->has_cfar)
> + tcg_gen_movi_tl(cpu_cfar, nip);
> +#endif
> +}
> +
> /*** Branch ***/
> static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
> {
> @@ -3352,7 +3369,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
> tb = ctx->tb;
> #if defined(TARGET_PPC64)
> if (!ctx->sf_mode)
> - dest = (uint32_t) dest;
> + dest = (uint32_t) dest;
Same here
> #endif
> if ((tb->pc& TARGET_PAGE_MASK) == (dest& TARGET_PAGE_MASK)&&
> likely(!ctx->singlestep_enabled)) {
> @@ -3407,6 +3424,7 @@ static void gen_b(DisasContext *ctx)
> target = li;
> if (LK(ctx->opcode))
> gen_setlr(ctx, ctx->nip);
> + gen_update_cfar(ctx, ctx->nip);
> gen_goto_tb(ctx, 0, target);
> }
>
> @@ -3469,6 +3487,7 @@ static inline void gen_bcond(DisasContext *ctx, int type)
> }
> tcg_temp_free_i32(temp);
> }
> + gen_update_cfar(ctx, ctx->nip);
> if (type == BCOND_IM) {
> target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
> if (likely(AA(ctx->opcode) == 0)) {
> @@ -3569,6 +3588,7 @@ static void gen_mcrf(DisasContext *ctx)
>
> /*** System linkage ***/
>
> +
Or here
> /* rfi (mem_idx only) */
> static void gen_rfi(DisasContext *ctx)
> {
> @@ -3580,6 +3600,7 @@ static void gen_rfi(DisasContext *ctx)
> gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> return;
> }
> + gen_update_cfar(ctx, ctx->nip);
> gen_helper_rfi();
> gen_sync_exception(ctx);
> #endif
> @@ -3596,6 +3617,7 @@ static void gen_rfid(DisasContext *ctx)
> gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> return;
> }
> + gen_update_cfar(ctx, ctx->nip);
> gen_helper_rfid();
> gen_sync_exception(ctx);
> #endif
> @@ -9263,6 +9285,12 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
> */
> }
>
> +#if defined(TARGET_PPC64)
> + if (env->flags& POWERPC_FLAG_CFAR) {
> + cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
> + }
> +#endif
> +
> switch (env->mmu_model) {
> case POWERPC_MMU_32B:
> case POWERPC_MMU_601:
> @@ -9371,6 +9399,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
> ctx.le_mode = env->hflags& (1<< MSR_LE) ? 1 : 0;
> #if defined(TARGET_PPC64)
> ctx.sf_mode = msr_sf;
> + ctx.has_cfar = !!(env->flags& POWERPC_FLAG_CFAR);
> #endif
> ctx.fpu_enabled = msr_fp;
> if ((env->flags& POWERPC_FLAG_SPE)&& msr_spe)
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index f542b8e..510d9dd 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -129,6 +129,17 @@ static void spr_write_lr (void *opaque, int sprn, int gprn)
> tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
> }
>
> +/* CFAR */
> +static void spr_read_cfar (void *opaque, int gprn, int sprn)
> +{
> + tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
> +}
> +
> +static void spr_write_cfar (void *opaque, int sprn, int gprn)
> +{
> + tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
> +}
> +
> /* CTR */
> static void spr_read_ctr (void *opaque, int gprn, int sprn)
> {
> @@ -6489,7 +6500,7 @@ static void init_proc_970MP (CPUPPCState *env)
> #define POWERPC_BFDM_POWER7 (bfd_mach_ppc64)
> #define POWERPC_FLAG_POWER7 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
> POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
> - POWERPC_FLAG_BUS_CLK)
> + POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR)
> #define check_pow_POWER7 check_pow_nocheck
>
> static void init_proc_POWER7 (CPUPPCState *env)
> @@ -6508,6 +6519,14 @@ static void init_proc_POWER7 (CPUPPCState *env)
> &spr_read_purr, SPR_NOACCESS,
> &spr_read_purr, SPR_NOACCESS,
> 0x00000000);
> + spr_register(env, SPR_CFAR, "SPR_CFAR",
> + SPR_NOACCESS, SPR_NOACCESS,
> +&spr_read_cfar,&spr_write_cfar,
> + 0x00000000);
> + spr_register(env, SPR_DSCR, "SPR_DSCR",
> + SPR_NOACCESS, SPR_NOACCESS,
> +&spr_read_generic,&spr_write_generic,
> + 0x00000000);
Are you sure this is only present on POWER7 and no machines before that?
Does 970 have CFAR?
Alex
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 2/6] Implement POWER7's CFAR in TCG
2011-08-10 15:10 ` Alexander Graf
@ 2011-08-11 0:35 ` David Gibson
0 siblings, 0 replies; 18+ messages in thread
From: David Gibson @ 2011-08-11 0:35 UTC (permalink / raw)
To: Alexander Graf; +Cc: qemu-devel
On Wed, Aug 10, 2011 at 05:10:11PM +0200, Alexander Graf wrote:
> On 08/04/2011 09:02 AM, David Gibson wrote:
[snip]
> >@@ -187,12 +195,13 @@ typedef struct DisasContext {
> > int le_mode;
> > #if defined(TARGET_PPC64)
> > int sf_mode;
> >+ int has_cfar;
> > #endif
> > int fpu_enabled;
> > int altivec_enabled;
> > int spe_enabled;
> > ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
> >- int singlestep_enabled;
> >+ int singlestep_enabled;
>
> Fairly sure this isn't intended :)
Oops, fixed. I think I'll blame Ben for that one :). And the others.
[snip]
> >@@ -6508,6 +6519,14 @@ static void init_proc_POWER7 (CPUPPCState *env)
> > &spr_read_purr, SPR_NOACCESS,
> > &spr_read_purr, SPR_NOACCESS,
> > 0x00000000);
> >+ spr_register(env, SPR_CFAR, "SPR_CFAR",
> >+ SPR_NOACCESS, SPR_NOACCESS,
> >+&spr_read_cfar,&spr_write_cfar,
> >+ 0x00000000);
> >+ spr_register(env, SPR_DSCR, "SPR_DSCR",
> >+ SPR_NOACCESS, SPR_NOACCESS,
> >+&spr_read_generic,&spr_write_generic,
> >+ 0x00000000);
>
> Are you sure this is only present on POWER7 and no machines before
> that? Does 970 have CFAR?
Looking at the feature bits in the kernel, it appears that it's in
POWER6 and POWER7, but not in 970, POWER4 or POWER5. Since we don't
have a model for POWER5 or POWER6, I believe the qemu logic here is
correct.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 3/6] pseries: Add real mode debugging hcalls
2011-08-04 7:02 [Qemu-devel] pseries machine updates David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 1/6] pseries: Bugfixes for interrupt numbering in XICS code David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 2/6] Implement POWER7's CFAR in TCG David Gibson
@ 2011-08-04 7:02 ` David Gibson
2011-08-10 15:19 ` Alexander Graf
2011-08-04 7:02 ` [Qemu-devel] [PATCH 4/6] pseries: Add a phandle to the xicp interrupt controller device tree node David Gibson
` (3 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: David Gibson @ 2011-08-04 7:02 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
From: Ben Herrenschmidt <benh@kernel.crashing.org>
PAPR systems support several hypercalls intended for use in real mode
debugging tools. These implement reads and writes to arbitrary guest
physical addresses. This is useful for real mode software because it
allows access to IO addresses and memory outside the RMA without going
through the somewhat involved process of setting up the hash page table
and enabling translation.
We want these so that when we add real IO devices, the SLOF firmware can
boot from them without having to enter virtual mode.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
---
hw/spapr_hcall.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 74 insertions(+), 0 deletions(-)
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index f7ead04..89d80d3 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -449,6 +449,67 @@ static target_ulong h_rtas(CPUState *env, sPAPREnvironment *spapr,
nret, rtas_r3 + 12 + 4*nargs);
}
+static target_ulong h_logical_load(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_ulong size = args[0];
+ target_ulong addr = args[1];
+
+ switch(size) {
+ case 1:
+ args[0] = ldub_phys(addr);
+ return H_SUCCESS;
+ case 2:
+ args[0] = lduw_phys(addr);
+ return H_SUCCESS;
+ case 4:
+ args[0] = ldl_phys(addr);
+ return H_SUCCESS;
+ case 8:
+ args[0] = ldq_phys(addr);
+ return H_SUCCESS;
+ }
+ return H_PARAMETER;
+}
+
+static target_ulong h_logical_store(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_ulong size = args[0];
+ target_ulong addr = args[1];
+ target_ulong val = args[2];
+
+ switch(size) {
+ case 1:
+ stb_phys(addr, val);
+ return H_SUCCESS;
+ case 2:
+ stw_phys(addr, val);
+ return H_SUCCESS;
+ case 4:
+ stl_phys(addr, val);
+ return H_SUCCESS;
+ case 8:
+ stq_phys(addr, val);
+ return H_SUCCESS;
+ }
+ return H_PARAMETER;
+}
+
+static target_ulong h_logical_icbi(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ /* Nothing to do on emulation, KVM will trap this in the kernel */
+ return H_SUCCESS;
+}
+
+static target_ulong h_logical_dcbf(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ /* Nothing to do on emulation, KVM will trap this in the kernel */
+ return H_SUCCESS;
+}
+
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];
@@ -513,6 +574,19 @@ static void hypercall_init(void)
spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa);
spapr_register_hypercall(H_CEDE, h_cede);
+ /* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate
+ * here between the "CI" and the "CACHE" variants, they will use whatever
+ * mapping attributes qemu is using. When using KVM, the kernel will
+ * enforce the attributes more strongly
+ */
+ spapr_register_hypercall(H_LOGICAL_CI_LOAD, h_logical_load);
+ spapr_register_hypercall(H_LOGICAL_CI_STORE, h_logical_store);
+ spapr_register_hypercall(H_LOGICAL_CACHE_LOAD, h_logical_load);
+ spapr_register_hypercall(H_LOGICAL_CACHE_STORE, h_logical_store);
+ spapr_register_hypercall(H_LOGICAL_ICBI, h_logical_icbi);
+ spapr_register_hypercall(H_LOGICAL_DCBF, h_logical_dcbf);
+
+
/* qemu/KVM-PPC specific hcalls */
spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 3/6] pseries: Add real mode debugging hcalls
2011-08-04 7:02 ` [Qemu-devel] [PATCH 3/6] pseries: Add real mode debugging hcalls David Gibson
@ 2011-08-10 15:19 ` Alexander Graf
0 siblings, 0 replies; 18+ messages in thread
From: Alexander Graf @ 2011-08-10 15:19 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel
On 08/04/2011 09:02 AM, David Gibson wrote:
> From: Ben Herrenschmidt<benh@kernel.crashing.org>
>
> PAPR systems support several hypercalls intended for use in real mode
> debugging tools. These implement reads and writes to arbitrary guest
> physical addresses. This is useful for real mode software because it
> allows access to IO addresses and memory outside the RMA without going
> through the somewhat involved process of setting up the hash page table
> and enabling translation.
>
> We want these so that when we add real IO devices, the SLOF firmware can
> boot from them without having to enter virtual mode.
>
> Signed-off-by: Benjamin Herrenschmidt<benh@kernel.crashing.org>
> Signed-off-by: David Gibson<dwg@au1.ibm.com>
agraf@lychee:/home/agraf/release/qemu> git pw am 108355
ERROR: code indent should never use tabs
#40: FILE: hw/spapr_hcall.c:453:
+^I^I^I^I target_ulong opcode, target_ulong *args)$
ERROR: code indent should never use tabs
#42: FILE: hw/spapr_hcall.c:455:
+^Itarget_ulong size = args[0];$
ERROR: code indent should never use tabs
#43: FILE: hw/spapr_hcall.c:456:
+^Itarget_ulong addr = args[1];$
ERROR: code indent should never use tabs
#45: FILE: hw/spapr_hcall.c:458:
+^Iswitch(size) {$
ERROR: space required before the open parenthesis '('
#45: FILE: hw/spapr_hcall.c:458:
+ switch(size) {
ERROR: code indent should never use tabs
#46: FILE: hw/spapr_hcall.c:459:
+^Icase 1:$
ERROR: code indent should never use tabs
#47: FILE: hw/spapr_hcall.c:460:
+^I^Iargs[0] = ldub_phys(addr);$
ERROR: code indent should never use tabs
#48: FILE: hw/spapr_hcall.c:461:
+^I^Ireturn H_SUCCESS;$
ERROR: code indent should never use tabs
#49: FILE: hw/spapr_hcall.c:462:
+^Icase 2:$
ERROR: code indent should never use tabs
#50: FILE: hw/spapr_hcall.c:463:
+^I^Iargs[0] = lduw_phys(addr);$
ERROR: code indent should never use tabs
#51: FILE: hw/spapr_hcall.c:464:
+^I^Ireturn H_SUCCESS;$
ERROR: code indent should never use tabs
#52: FILE: hw/spapr_hcall.c:465:
+^Icase 4:$
ERROR: code indent should never use tabs
#53: FILE: hw/spapr_hcall.c:466:
+^I^Iargs[0] = ldl_phys(addr);$
ERROR: code indent should never use tabs
#54: FILE: hw/spapr_hcall.c:467:
+^I^Ireturn H_SUCCESS;$
ERROR: code indent should never use tabs
#55: FILE: hw/spapr_hcall.c:468:
+^Icase 8:$
ERROR: code indent should never use tabs
#56: FILE: hw/spapr_hcall.c:469:
+^I^Iargs[0] = ldq_phys(addr);$
ERROR: code indent should never use tabs
#57: FILE: hw/spapr_hcall.c:470:
+^I^Ireturn H_SUCCESS;$
ERROR: code indent should never use tabs
#58: FILE: hw/spapr_hcall.c:471:
+^I}$
ERROR: code indent should never use tabs
#59: FILE: hw/spapr_hcall.c:472:
+^Ireturn H_PARAMETER;$
ERROR: code indent should never use tabs
#63: FILE: hw/spapr_hcall.c:476:
+^I^I^I^I target_ulong opcode, target_ulong *args)$
ERROR: code indent should never use tabs
#65: FILE: hw/spapr_hcall.c:478:
+^Itarget_ulong size = args[0];$
ERROR: code indent should never use tabs
#66: FILE: hw/spapr_hcall.c:479:
+^Itarget_ulong addr = args[1];$
ERROR: code indent should never use tabs
#67: FILE: hw/spapr_hcall.c:480:
+^Itarget_ulong val = args[2];$
ERROR: code indent should never use tabs
#69: FILE: hw/spapr_hcall.c:482:
+^Iswitch(size) {$
ERROR: space required before the open parenthesis '('
#69: FILE: hw/spapr_hcall.c:482:
+ switch(size) {
ERROR: code indent should never use tabs
#70: FILE: hw/spapr_hcall.c:483:
+^Icase 1:$
ERROR: code indent should never use tabs
#71: FILE: hw/spapr_hcall.c:484:
+^I^Istb_phys(addr, val);$
ERROR: code indent should never use tabs
#72: FILE: hw/spapr_hcall.c:485:
+^I^Ireturn H_SUCCESS;$
ERROR: code indent should never use tabs
#73: FILE: hw/spapr_hcall.c:486:
+^Icase 2:$
ERROR: code indent should never use tabs
#74: FILE: hw/spapr_hcall.c:487:
+^I^Istw_phys(addr, val);$
ERROR: code indent should never use tabs
#75: FILE: hw/spapr_hcall.c:488:
+^I^Ireturn H_SUCCESS;$
ERROR: code indent should never use tabs
#76: FILE: hw/spapr_hcall.c:489:
+^Icase 4:$
ERROR: code indent should never use tabs
#77: FILE: hw/spapr_hcall.c:490:
+^I^Istl_phys(addr, val);$
ERROR: code indent should never use tabs
#78: FILE: hw/spapr_hcall.c:491:
+^I^Ireturn H_SUCCESS;$
ERROR: code indent should never use tabs
#79: FILE: hw/spapr_hcall.c:492:
+^Icase 8:$
ERROR: trailing whitespace
#80: FILE: hw/spapr_hcall.c:493:
+^I^Istq_phys(addr, val);^I$
ERROR: code indent should never use tabs
#80: FILE: hw/spapr_hcall.c:493:
+^I^Istq_phys(addr, val);^I$
ERROR: code indent should never use tabs
#81: FILE: hw/spapr_hcall.c:494:
+^I^Ireturn H_SUCCESS;$
ERROR: code indent should never use tabs
#82: FILE: hw/spapr_hcall.c:495:
+^I}$
ERROR: code indent should never use tabs
#83: FILE: hw/spapr_hcall.c:496:
+^Ireturn H_PARAMETER;$
ERROR: code indent should never use tabs
#87: FILE: hw/spapr_hcall.c:500:
+^I^I^I^I target_ulong opcode, target_ulong *args)$
ERROR: code indent should never use tabs
#89: FILE: hw/spapr_hcall.c:502:
+^I/* Nothing to do on emulation, KVM will trap this in the kernel */$
ERROR: code indent should never use tabs
#90: FILE: hw/spapr_hcall.c:503:
+^Ireturn H_SUCCESS;$
ERROR: code indent should never use tabs
#94: FILE: hw/spapr_hcall.c:507:
+^I^I^I^I target_ulong opcode, target_ulong *args)$
ERROR: code indent should never use tabs
#96: FILE: hw/spapr_hcall.c:509:
+^I/* Nothing to do on emulation, KVM will trap this in the kernel */$
ERROR: code indent should never use tabs
#97: FILE: hw/spapr_hcall.c:510:
+^Ireturn H_SUCCESS;$
ERROR: trailing whitespace
#118: FILE: hw/spapr_hcall.c:588:
+ $
total: 47 errors, 0 warnings, 86 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 4/6] pseries: Add a phandle to the xicp interrupt controller device tree node
2011-08-04 7:02 [Qemu-devel] pseries machine updates David Gibson
` (2 preceding siblings ...)
2011-08-04 7:02 ` [Qemu-devel] [PATCH 3/6] pseries: Add real mode debugging hcalls David Gibson
@ 2011-08-04 7:02 ` David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 5/6] pseries: interrupt controller should not have a 'reg' property David Gibson
` (2 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: David Gibson @ 2011-08-04 7:02 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
Future devices we will be adding to the pseries machine (e.g. PCI) will
need nodes in the device tree which explicitly reference the top-level
interrupt controller via interrupt-parent or interrupt-map properties.
In order to do this, the interrupt controller node needs an assigned
phandle. This patch adds the appropriate property, in preparation.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
hw/spapr.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/hw/spapr.c b/hw/spapr.c
index 109b774..bc15b5c 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -54,6 +54,8 @@
#define MAX_CPUS 256
#define XICS_IRQS 1024
+#define PHANDLE_XICP 0x00001111
+
sPAPREnvironment *spapr;
static void *spapr_create_fdt_skel(const char *cpu_model,
@@ -199,6 +201,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
_FDT((fdt_property(fdt, "ibm,interrupt-server-ranges",
interrupt_server_ranges_prop,
sizeof(interrupt_server_ranges_prop))));
+ _FDT((fdt_property_cell(fdt, "#interrupt-cells", 2)));
+ _FDT((fdt_property_cell(fdt, "linux,phandle", PHANDLE_XICP)));
+ _FDT((fdt_property_cell(fdt, "phandle", PHANDLE_XICP)));
_FDT((fdt_end_node(fdt)));
--
1.7.5.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 5/6] pseries: interrupt controller should not have a 'reg' property
2011-08-04 7:02 [Qemu-devel] pseries machine updates David Gibson
` (3 preceding siblings ...)
2011-08-04 7:02 ` [Qemu-devel] [PATCH 4/6] pseries: Add a phandle to the xicp interrupt controller device tree node David Gibson
@ 2011-08-04 7:02 ` David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 6/6] pseries: More complete WIMG validation in H_ENTER code David Gibson
2011-08-10 15:16 ` [Qemu-devel] pseries machine updates Alexander Graf
6 siblings, 0 replies; 18+ messages in thread
From: David Gibson @ 2011-08-04 7:02 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
The interrupt controller presented in the device tree for the pseries
machine is manipulated by the guest only through hypervisor calls. It
has no real or emulated registers for the guest to access.
However, it currently has a bogus 'reg' property advertising a register
window. Moreover, this property has an invalid format, being a 32-bit
zero, when the #address-cells property on the root bus indicates that it
needs a 64-bit address. Since the guest never attempts to manipulate
the node directly, it works, but it is ugly and can cause warnings when
manipulating the device tree in other tools (such as future firmware
versions).
This patch, therefore, corrects the problem by entirely removing the
interrupt-controller node's 'reg' property.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
hw/spapr.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/hw/spapr.c b/hw/spapr.c
index bc15b5c..cf9f758 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -191,12 +191,11 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
_FDT((fdt_end_node(fdt)));
/* interrupt controller */
- _FDT((fdt_begin_node(fdt, "interrupt-controller@0")));
+ _FDT((fdt_begin_node(fdt, "interrupt-controller")));
_FDT((fdt_property_string(fdt, "device_type",
"PowerPC-External-Interrupt-Presentation")));
_FDT((fdt_property_string(fdt, "compatible", "IBM,ppc-xicp")));
- _FDT((fdt_property_cell(fdt, "reg", 0)));
_FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
_FDT((fdt_property(fdt, "ibm,interrupt-server-ranges",
interrupt_server_ranges_prop,
--
1.7.5.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 6/6] pseries: More complete WIMG validation in H_ENTER code
2011-08-04 7:02 [Qemu-devel] pseries machine updates David Gibson
` (4 preceding siblings ...)
2011-08-04 7:02 ` [Qemu-devel] [PATCH 5/6] pseries: interrupt controller should not have a 'reg' property David Gibson
@ 2011-08-04 7:02 ` David Gibson
2011-08-10 15:16 ` [Qemu-devel] pseries machine updates Alexander Graf
6 siblings, 0 replies; 18+ messages in thread
From: David Gibson @ 2011-08-04 7:02 UTC (permalink / raw)
To: agraf; +Cc: qemu-devel
Currently our implementation of the H_ENTER hypercall, which inserts a
mapping in the hash page table assumes that only ordinary memory is ever
mapped, and only permits mapping attribute bits accordingly (WIMG==0010).
However, we intend to start adding emulated IO to the pseries platform
(and real IO with PCI passthrough on kvm) which means this simple test
will no longer suffice.
This patch extends the h_enter validation code to check if the given
address is a RAM address. If it is it enforces WIMG==0010, otherwise
it assumes that it is an IO mapping and instead enforces WIMG=010x.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
hw/spapr.c | 3 ++-
hw/spapr.h | 1 +
hw/spapr_hcall.c | 22 ++++++++++++++++++----
3 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/hw/spapr.c b/hw/spapr.c
index cf9f758..7030c17 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -334,7 +334,8 @@ static void ppc_spapr_init(ram_addr_t ram_size,
}
/* allocate RAM */
- ram_offset = qemu_ram_alloc(NULL, "ppc_spapr.ram", ram_size);
+ spapr->ram_limit = ram_size;
+ ram_offset = qemu_ram_alloc(NULL, "ppc_spapr.ram", spapr->ram_limit);
cpu_register_physical_memory(0, ram_size, ram_offset);
/* allocate hash page table. For now we always make this 16mb,
diff --git a/hw/spapr.h b/hw/spapr.h
index 263691b..400001e 100644
--- a/hw/spapr.h
+++ b/hw/spapr.h
@@ -8,6 +8,7 @@ typedef struct sPAPREnvironment {
struct VIOsPAPRBus *vio_bus;
struct icp_state *icp;
+ target_phys_addr_t ram_limit;
void *htab;
long htab_size;
target_phys_addr_t fdt_addr, rtas_addr;
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index 89d80d3..822d715 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -99,6 +99,8 @@ static target_ulong h_enter(CPUState *env, sPAPREnvironment *spapr,
target_ulong pte_index = args[1];
target_ulong pteh = args[2];
target_ulong ptel = args[3];
+ target_ulong page_shift = 12;
+ target_ulong raddr;
target_ulong i;
uint8_t *hpte;
@@ -111,6 +113,7 @@ static target_ulong h_enter(CPUState *env, sPAPREnvironment *spapr,
#endif
if ((ptel & 0xff000) == 0) {
/* 16M page */
+ page_shift = 24;
/* lowest AVA bit must be 0 for 16M pages */
if (pteh & 0x80) {
return H_PARAMETER;
@@ -120,12 +123,23 @@ static target_ulong h_enter(CPUState *env, sPAPREnvironment *spapr,
}
}
- /* FIXME: bounds check the pa? */
+ raddr = (ptel & HPTE_R_RPN) & ~((1ULL << page_shift) - 1);
- /* Check WIMG */
- if ((ptel & HPTE_R_WIMG) != HPTE_R_M) {
- return H_PARAMETER;
+ if (raddr < spapr->ram_limit) {
+ /* Regular RAM - should have WIMG=0010 */
+ if ((ptel & HPTE_R_WIMG) != HPTE_R_M) {
+ return H_PARAMETER;
+ }
+ } else {
+ /* Looks like an IO address */
+ /* FIXME: What WIMG combinations could be sensible for IO?
+ * For now we allow WIMG=010x, but are there others? */
+ /* FIXME: Should we check against registered IO addresses? */
+ if ((ptel & (HPTE_R_W | HPTE_R_I | HPTE_R_M)) != HPTE_R_I) {
+ return H_PARAMETER;
+ }
}
+
pteh &= ~0x60ULL;
if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
--
1.7.5.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] pseries machine updates
2011-08-04 7:02 [Qemu-devel] pseries machine updates David Gibson
` (5 preceding siblings ...)
2011-08-04 7:02 ` [Qemu-devel] [PATCH 6/6] pseries: More complete WIMG validation in H_ENTER code David Gibson
@ 2011-08-10 15:16 ` Alexander Graf
2011-08-10 15:24 ` Alexander Graf
2011-08-11 0:39 ` David Gibson
6 siblings, 2 replies; 18+ messages in thread
From: Alexander Graf @ 2011-08-10 15:16 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel
On 08/04/2011 09:02 AM, David Gibson wrote:
> Hi Alex,
>
> Here's another batch of assorted updates for the pseries machine.
Looks pretty nice. Please update patch 2/6 with the bug you found and
the whitespace problems. I'll put the others into my tree already.
Alex
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] pseries machine updates
2011-08-10 15:16 ` [Qemu-devel] pseries machine updates Alexander Graf
@ 2011-08-10 15:24 ` Alexander Graf
2011-08-11 0:44 ` David Gibson
2011-08-11 0:39 ` David Gibson
1 sibling, 1 reply; 18+ messages in thread
From: Alexander Graf @ 2011-08-10 15:24 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel
On 08/10/2011 05:16 PM, Alexander Graf wrote:
> On 08/04/2011 09:02 AM, David Gibson wrote:
>> Hi Alex,
>>
>> Here's another batch of assorted updates for the pseries machine.
>
> Looks pretty nice. Please update patch 2/6 with the bug you found and
> the whitespace problems. I'll put the others into my tree already.
Sorry, patch 3 failed checkpatch. Please respin that one too.
Alex
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] pseries machine updates
2011-08-10 15:24 ` Alexander Graf
@ 2011-08-11 0:44 ` David Gibson
2011-08-31 9:18 ` Alexander Graf
0 siblings, 1 reply; 18+ messages in thread
From: David Gibson @ 2011-08-11 0:44 UTC (permalink / raw)
To: Alexander Graf; +Cc: qemu-devel
On Wed, Aug 10, 2011 at 05:24:59PM +0200, Alexander Graf wrote:
> On 08/10/2011 05:16 PM, Alexander Graf wrote:
> >On 08/04/2011 09:02 AM, David Gibson wrote:
> >>Hi Alex,
> >>
> >>Here's another batch of assorted updates for the pseries machine.
> >
> >Looks pretty nice. Please update patch 2/6 with the bug you found
> >and the whitespace problems. I'll put the others into my tree
> >already.
>
> Sorry, patch 3 failed checkpatch. Please respin that one too.
Done. Here you go. I'll blame Ben again :)
>From 6d5418b479852edfe93c40b8ddb707dde5128e32 Mon Sep 17 00:00:00 2001
From: Ben Herrenschmidt <benh@kernel.crashing.org>
Date: Fri, 29 Jul 2011 12:06:33 +1000
Subject: [PATCH] pseries: Add real mode debugging hcalls
PAPR systems support several hypercalls intended for use in real mode
debugging tools. These implement reads and writes to arbitrary guest
physical addresses. This is useful for real mode software because it
allows access to IO addresses and memory outside the RMA without going
through the somewhat involved process of setting up the hash page table
and enabling translation.
We want these so that when we add real IO devices, the SLOF firmware can
boot from them without having to enter virtual mode.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
---
hw/spapr_hcall.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index f7ead04..05d6c54 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -449,6 +449,67 @@ static target_ulong h_rtas(CPUState *env, sPAPREnvironment *spapr,
nret, rtas_r3 + 12 + 4*nargs);
}
+static target_ulong h_logical_load(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_ulong size = args[0];
+ target_ulong addr = args[1];
+
+ switch (size) {
+ case 1:
+ args[0] = ldub_phys(addr);
+ return H_SUCCESS;
+ case 2:
+ args[0] = lduw_phys(addr);
+ return H_SUCCESS;
+ case 4:
+ args[0] = ldl_phys(addr);
+ return H_SUCCESS;
+ case 8:
+ args[0] = ldq_phys(addr);
+ return H_SUCCESS;
+ }
+ return H_PARAMETER;
+}
+
+static target_ulong h_logical_store(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_ulong size = args[0];
+ target_ulong addr = args[1];
+ target_ulong val = args[2];
+
+ switch (size) {
+ case 1:
+ stb_phys(addr, val);
+ return H_SUCCESS;
+ case 2:
+ stw_phys(addr, val);
+ return H_SUCCESS;
+ case 4:
+ stl_phys(addr, val);
+ return H_SUCCESS;
+ case 8:
+ stq_phys(addr, val);
+ return H_SUCCESS;
+ }
+ return H_PARAMETER;
+}
+
+static target_ulong h_logical_icbi(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ /* Nothing to do on emulation, KVM will trap this in the kernel */
+ return H_SUCCESS;
+}
+
+static target_ulong h_logical_dcbf(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ /* Nothing to do on emulation, KVM will trap this in the kernel */
+ return H_SUCCESS;
+}
+
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];
@@ -513,6 +574,18 @@ static void hypercall_init(void)
spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa);
spapr_register_hypercall(H_CEDE, h_cede);
+ /* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate
+ * here between the "CI" and the "CACHE" variants, they will use whatever
+ * mapping attributes qemu is using. When using KVM, the kernel will
+ * enforce the attributes more strongly
+ */
+ spapr_register_hypercall(H_LOGICAL_CI_LOAD, h_logical_load);
+ spapr_register_hypercall(H_LOGICAL_CI_STORE, h_logical_store);
+ spapr_register_hypercall(H_LOGICAL_CACHE_LOAD, h_logical_load);
+ spapr_register_hypercall(H_LOGICAL_CACHE_STORE, h_logical_store);
+ spapr_register_hypercall(H_LOGICAL_ICBI, h_logical_icbi);
+ spapr_register_hypercall(H_LOGICAL_DCBF, h_logical_dcbf);
+
/* qemu/KVM-PPC specific hcalls */
spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
}
--
1.7.5.4
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] pseries machine updates
2011-08-11 0:44 ` David Gibson
@ 2011-08-31 9:18 ` Alexander Graf
0 siblings, 0 replies; 18+ messages in thread
From: Alexander Graf @ 2011-08-31 9:18 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel
On 11.08.2011, at 02:44, David Gibson wrote:
> On Wed, Aug 10, 2011 at 05:24:59PM +0200, Alexander Graf wrote:
>> On 08/10/2011 05:16 PM, Alexander Graf wrote:
>>> On 08/04/2011 09:02 AM, David Gibson wrote:
>>>> Hi Alex,
>>>>
>>>> Here's another batch of assorted updates for the pseries machine.
>>>
>>> Looks pretty nice. Please update patch 2/6 with the bug you found
>>> and the whitespace problems. I'll put the others into my tree
>>> already.
>>
>> Sorry, patch 3 failed checkpatch. Please respin that one too.
>
> Done. Here you go. I'll blame Ben again :)
>
> From 6d5418b479852edfe93c40b8ddb707dde5128e32 Mon Sep 17 00:00:00 2001
> From: Ben Herrenschmidt <benh@kernel.crashing.org>
> Date: Fri, 29 Jul 2011 12:06:33 +1000
> Subject: [PATCH] pseries: Add real mode debugging hcalls
>
> PAPR systems support several hypercalls intended for use in real mode
> debugging tools. These implement reads and writes to arbitrary guest
> physical addresses. This is useful for real mode software because it
> allows access to IO addresses and memory outside the RMA without going
> through the somewhat involved process of setting up the hash page table
> and enabling translation.
>
> We want these so that when we add real IO devices, the SLOF firmware can
> boot from them without having to enter virtual mode.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: David Gibson <dwg@au1.ibm.com>
Thanks, applied.
Alex
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] pseries machine updates
2011-08-10 15:16 ` [Qemu-devel] pseries machine updates Alexander Graf
2011-08-10 15:24 ` Alexander Graf
@ 2011-08-11 0:39 ` David Gibson
2011-08-31 9:17 ` Alexander Graf
1 sibling, 1 reply; 18+ messages in thread
From: David Gibson @ 2011-08-11 0:39 UTC (permalink / raw)
To: Alexander Graf; +Cc: qemu-devel
On Wed, Aug 10, 2011 at 05:16:35PM +0200, Alexander Graf wrote:
> On 08/04/2011 09:02 AM, David Gibson wrote:
> >Hi Alex,
> >
> >Here's another batch of assorted updates for the pseries machine.
>
> Looks pretty nice. Please update patch 2/6 with the bug you found
> and the whitespace problems. I'll put the others into my tree
> already.
Here's the updated 2/6
>From e5b9ba608d4814a46f256337bbf60b94fdc2c5d9 Mon Sep 17 00:00:00 2001
From: Ben Herrenschmidt <benh@kernel.crashing.org>
Date: Thu, 4 Aug 2011 16:56:41 +1000
Subject: [PATCH] Implement POWER7's CFAR in TCG
This patch implements support for the CFAR SPR on POWER7 (Come From
Address Register), which snapshots the PC value at the time of a branch or
an rfid. The latest powerpc-next kernel also catches it and can show it in
xmon or in the signal frames.
This works well enough to let recent kernels boot (which otherwise oops
on the CFAR access). It hasn't been tested enough to be confident that the
CFAR values are actually accurate, but one thing at a time.
Signed-off-by: Ben Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
target-ppc/cpu.h | 8 ++++++++
target-ppc/translate.c | 28 ++++++++++++++++++++++++++++
target-ppc/translate_init.c | 23 ++++++++++++++++++++++-
3 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 024eb6f..d6b64a2 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -540,6 +540,8 @@ enum {
/* Decrementer clock: RTC clock (POWER, 601) or bus clock */
POWERPC_FLAG_RTC_CLK = 0x00010000,
POWERPC_FLAG_BUS_CLK = 0x00020000,
+ /* Has CFAR */
+ POWERPC_FLAG_CFAR = 0x00040000,
};
/*****************************************************************************/
@@ -857,6 +859,10 @@ struct CPUPPCState {
target_ulong ctr;
/* condition register */
uint32_t crf[8];
+#if defined(TARGET_PPC64)
+ /* CFAR */
+ target_ulong cfar;
+#endif
/* XER */
target_ulong xer;
/* Reservation address */
@@ -1187,6 +1193,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
#define SPR_601_UDECR (0x006)
#define SPR_LR (0x008)
#define SPR_CTR (0x009)
+#define SPR_DSCR (0x011)
#define SPR_DSISR (0x012)
#define SPR_DAR (0x013) /* DAE for PowerPC 601 */
#define SPR_601_RTCU (0x014)
@@ -1195,6 +1202,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
#define SPR_SDR1 (0x019)
#define SPR_SRR0 (0x01A)
#define SPR_SRR1 (0x01B)
+#define SPR_CFAR (0x01C)
#define SPR_AMR (0x01D)
#define SPR_BOOKE_PID (0x030)
#define SPR_BOOKE_DECAR (0x036)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fd7c208..e38dd0e 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -69,6 +69,9 @@ static TCGv cpu_nip;
static TCGv cpu_msr;
static TCGv cpu_ctr;
static TCGv cpu_lr;
+#if defined(TARGET_PPC64)
+static TCGv cpu_cfar;
+#endif
static TCGv cpu_xer;
static TCGv cpu_reserve;
static TCGv_i32 cpu_fpscr;
@@ -154,6 +157,11 @@ void ppc_translate_init(void)
cpu_lr = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, lr), "lr");
+#if defined(TARGET_PPC64)
+ cpu_cfar = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUState, cfar), "cfar");
+#endif
+
cpu_xer = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, xer), "xer");
@@ -187,6 +195,7 @@ typedef struct DisasContext {
int le_mode;
#if defined(TARGET_PPC64)
int sf_mode;
+ int has_cfar;
#endif
int fpu_enabled;
int altivec_enabled;
@@ -3345,6 +3354,14 @@ static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
/* stfiwx */
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
+static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
+{
+#if defined(TARGET_PPC64)
+ if (ctx->has_cfar)
+ tcg_gen_movi_tl(cpu_cfar, nip);
+#endif
+}
+
/*** Branch ***/
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
{
@@ -3407,6 +3424,7 @@ static void gen_b(DisasContext *ctx)
target = li;
if (LK(ctx->opcode))
gen_setlr(ctx, ctx->nip);
+ gen_update_cfar(ctx, ctx->nip);
gen_goto_tb(ctx, 0, target);
}
@@ -3469,6 +3487,7 @@ static inline void gen_bcond(DisasContext *ctx, int type)
}
tcg_temp_free_i32(temp);
}
+ gen_update_cfar(ctx, ctx->nip);
if (type == BCOND_IM) {
target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
if (likely(AA(ctx->opcode) == 0)) {
@@ -3580,6 +3599,7 @@ static void gen_rfi(DisasContext *ctx)
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
+ gen_update_cfar(ctx, ctx->nip);
gen_helper_rfi();
gen_sync_exception(ctx);
#endif
@@ -3596,6 +3616,7 @@ static void gen_rfid(DisasContext *ctx)
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
+ gen_update_cfar(ctx, ctx->nip);
gen_helper_rfid();
gen_sync_exception(ctx);
#endif
@@ -9263,6 +9284,12 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
*/
}
+#if defined(TARGET_PPC64)
+ if (env->flags & POWERPC_FLAG_CFAR) {
+ cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
+ }
+#endif
+
switch (env->mmu_model) {
case POWERPC_MMU_32B:
case POWERPC_MMU_601:
@@ -9371,6 +9398,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
#if defined(TARGET_PPC64)
ctx.sf_mode = msr_sf;
+ ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
#endif
ctx.fpu_enabled = msr_fp;
if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index f542b8e..35ce8bf 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -129,6 +129,19 @@ static void spr_write_lr (void *opaque, int sprn, int gprn)
tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
}
+/* CFAR */
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+static void spr_read_cfar (void *opaque, int gprn, int sprn)
+{
+ tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
+}
+
+static void spr_write_cfar (void *opaque, int sprn, int gprn)
+{
+ tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
+}
+#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
+
/* CTR */
static void spr_read_ctr (void *opaque, int gprn, int sprn)
{
@@ -6489,7 +6502,7 @@ static void init_proc_970MP (CPUPPCState *env)
#define POWERPC_BFDM_POWER7 (bfd_mach_ppc64)
#define POWERPC_FLAG_POWER7 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
+ POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR)
#define check_pow_POWER7 check_pow_nocheck
static void init_proc_POWER7 (CPUPPCState *env)
@@ -6508,6 +6521,14 @@ static void init_proc_POWER7 (CPUPPCState *env)
&spr_read_purr, SPR_NOACCESS,
&spr_read_purr, SPR_NOACCESS,
0x00000000);
+ spr_register(env, SPR_CFAR, "SPR_CFAR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_cfar, &spr_write_cfar,
+ 0x00000000);
+ spr_register(env, SPR_DSCR, "SPR_DSCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
#endif /* !CONFIG_USER_ONLY */
/* Memory management */
/* XXX : not implemented */
--
1.7.5.4
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] pseries machine updates
2011-08-11 0:39 ` David Gibson
@ 2011-08-31 9:17 ` Alexander Graf
2011-09-01 1:45 ` David Gibson
0 siblings, 1 reply; 18+ messages in thread
From: Alexander Graf @ 2011-08-31 9:17 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel
On 11.08.2011, at 02:39, David Gibson wrote:
> On Wed, Aug 10, 2011 at 05:16:35PM +0200, Alexander Graf wrote:
>> On 08/04/2011 09:02 AM, David Gibson wrote:
>>> Hi Alex,
>>>
>>> Here's another batch of assorted updates for the pseries machine.
>>
>> Looks pretty nice. Please update patch 2/6 with the bug you found
>> and the whitespace problems. I'll put the others into my tree
>> already.
>
> Here's the updated 2/6
>
> From e5b9ba608d4814a46f256337bbf60b94fdc2c5d9 Mon Sep 17 00:00:00 2001
> From: Ben Herrenschmidt <benh@kernel.crashing.org>
> Date: Thu, 4 Aug 2011 16:56:41 +1000
> Subject: [PATCH] Implement POWER7's CFAR in TCG
>
> This patch implements support for the CFAR SPR on POWER7 (Come From
> Address Register), which snapshots the PC value at the time of a branch or
> an rfid. The latest powerpc-next kernel also catches it and can show it in
> xmon or in the signal frames.
>
> This works well enough to let recent kernels boot (which otherwise oops
> on the CFAR access). It hasn't been tested enough to be confident that the
> CFAR values are actually accurate, but one thing at a time.
>
> Signed-off-by: Ben Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
agraf@lychee:/home/agraf/release/qemu> git pw am 109480
ERROR: code indent should never use tabs
#107: FILE: target-ppc/translate.c:162:
+^I^I^I^I offsetof(CPUState, cfar), "cfar");$
ERROR: code indent should never use tabs
#174: FILE: target-ppc/translate.c:9289:
+^Icpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);$
WARNING: space prohibited between function name and open parenthesis '('
#199: FILE: target-ppc/translate_init.c:134:
+static void spr_read_cfar (void *opaque, int gprn, int sprn)
WARNING: space prohibited between function name and open parenthesis '('
#204: FILE: target-ppc/translate_init.c:139:
+static void spr_write_cfar (void *opaque, int sprn, int gprn)
total: 2 errors, 2 warnings, 161 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
checkpatch failed, still apply? [y|N]
Alex
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] pseries machine updates
2011-08-31 9:17 ` Alexander Graf
@ 2011-09-01 1:45 ` David Gibson
2011-09-02 13:20 ` Alexander Graf
0 siblings, 1 reply; 18+ messages in thread
From: David Gibson @ 2011-09-01 1:45 UTC (permalink / raw)
To: Alexander Graf; +Cc: qemu-devel
On Wed, Aug 31, 2011 at 11:17:13AM +0200, Alexander Graf wrote:
>
> On 11.08.2011, at 02:39, David Gibson wrote:
>
> > On Wed, Aug 10, 2011 at 05:16:35PM +0200, Alexander Graf wrote:
> >> On 08/04/2011 09:02 AM, David Gibson wrote:
> >>> Hi Alex,
> >>>
> >>> Here's another batch of assorted updates for the pseries machine.
> >>
> >> Looks pretty nice. Please update patch 2/6 with the bug you found
> >> and the whitespace problems. I'll put the others into my tree
> >> already.
> >
> > Here's the updated 2/6
> >
> > From e5b9ba608d4814a46f256337bbf60b94fdc2c5d9 Mon Sep 17 00:00:00 2001
> > From: Ben Herrenschmidt <benh@kernel.crashing.org>
> > Date: Thu, 4 Aug 2011 16:56:41 +1000
> > Subject: [PATCH] Implement POWER7's CFAR in TCG
> >
> > This patch implements support for the CFAR SPR on POWER7 (Come From
> > Address Register), which snapshots the PC value at the time of a branch or
> > an rfid. The latest powerpc-next kernel also catches it and can show it in
> > xmon or in the signal frames.
> >
> > This works well enough to let recent kernels boot (which otherwise oops
> > on the CFAR access). It hasn't been tested enough to be confident that the
> > CFAR values are actually accurate, but one thing at a time.
> >
> > Signed-off-by: Ben Herrenschmidt <benh@kernel.crashing.org>
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>
> agraf@lychee:/home/agraf/release/qemu> git pw am 109480
> ERROR: code indent should never use tabs
> #107: FILE: target-ppc/translate.c:162:
> +^I^I^I^I offsetof(CPUState, cfar), "cfar");$
>
> ERROR: code indent should never use tabs
> #174: FILE: target-ppc/translate.c:9289:
> +^Icpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);$
Blah. Fixed now, I'll try to get BenH to use the emacs magic to stop
it putting tabs in.
> WARNING: space prohibited between function name and open parenthesis '('
> #199: FILE: target-ppc/translate_init.c:134:
> +static void spr_read_cfar (void *opaque, int gprn, int sprn)
>
> WARNING: space prohibited between function name and open parenthesis '('
> #204: FILE: target-ppc/translate_init.c:139:
> +static void spr_write_cfar (void *opaque, int sprn, int gprn)
Well, these are deliberate, on the grounds that matching the
surrounding functions seemed more important than matching the global
style guidelines.
Revised patch below
>From b35b94ea867550faf99fc553b661739551c9bb8b Mon Sep 17 00:00:00 2001
From: Ben Herrenschmidt <benh@kernel.crashing.org>
Date: Thu, 4 Aug 2011 16:56:41 +1000
Subject: [PATCH] Implement POWER7's CFAR in TCG
This patch implements support for the CFAR SPR on POWER7 (Come From
Address Register), which snapshots the PC value at the time of a branch or
an rfid. The latest powerpc-next kernel also catches it and can show it in
xmon or in the signal frames.
This works well enough to let recent kernels boot (which otherwise oops
on the CFAR access). It hasn't been tested enough to be confident that the
CFAR values are actually accurate, but one thing at a time.
Signed-off-by: Ben Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
target-ppc/cpu.h | 8 ++++++++
target-ppc/translate.c | 28 ++++++++++++++++++++++++++++
target-ppc/translate_init.c | 23 ++++++++++++++++++++++-
3 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index b8d42e0..145103a 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -555,6 +555,8 @@ enum {
/* Decrementer clock: RTC clock (POWER, 601) or bus clock */
POWERPC_FLAG_RTC_CLK = 0x00010000,
POWERPC_FLAG_BUS_CLK = 0x00020000,
+ /* Has CFAR */
+ POWERPC_FLAG_CFAR = 0x00040000,
};
/*****************************************************************************/
@@ -872,6 +874,10 @@ struct CPUPPCState {
target_ulong ctr;
/* condition register */
uint32_t crf[8];
+#if defined(TARGET_PPC64)
+ /* CFAR */
+ target_ulong cfar;
+#endif
/* XER */
target_ulong xer;
/* Reservation address */
@@ -1202,6 +1208,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
#define SPR_601_UDECR (0x006)
#define SPR_LR (0x008)
#define SPR_CTR (0x009)
+#define SPR_DSCR (0x011)
#define SPR_DSISR (0x012)
#define SPR_DAR (0x013) /* DAE for PowerPC 601 */
#define SPR_601_RTCU (0x014)
@@ -1210,6 +1217,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
#define SPR_SDR1 (0x019)
#define SPR_SRR0 (0x01A)
#define SPR_SRR1 (0x01B)
+#define SPR_CFAR (0x01C)
#define SPR_AMR (0x01D)
#define SPR_BOOKE_PID (0x030)
#define SPR_BOOKE_DECAR (0x036)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 4277460..1e362fc 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -69,6 +69,9 @@ static TCGv cpu_nip;
static TCGv cpu_msr;
static TCGv cpu_ctr;
static TCGv cpu_lr;
+#if defined(TARGET_PPC64)
+static TCGv cpu_cfar;
+#endif
static TCGv cpu_xer;
static TCGv cpu_reserve;
static TCGv_i32 cpu_fpscr;
@@ -154,6 +157,11 @@ void ppc_translate_init(void)
cpu_lr = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, lr), "lr");
+#if defined(TARGET_PPC64)
+ cpu_cfar = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUState, cfar), "cfar");
+#endif
+
cpu_xer = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, xer), "xer");
@@ -187,6 +195,7 @@ typedef struct DisasContext {
int le_mode;
#if defined(TARGET_PPC64)
int sf_mode;
+ int has_cfar;
#endif
int fpu_enabled;
int altivec_enabled;
@@ -3345,6 +3354,14 @@ static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
/* stfiwx */
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
+static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
+{
+#if defined(TARGET_PPC64)
+ if (ctx->has_cfar)
+ tcg_gen_movi_tl(cpu_cfar, nip);
+#endif
+}
+
/*** Branch ***/
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
{
@@ -3407,6 +3424,7 @@ static void gen_b(DisasContext *ctx)
target = li;
if (LK(ctx->opcode))
gen_setlr(ctx, ctx->nip);
+ gen_update_cfar(ctx, ctx->nip);
gen_goto_tb(ctx, 0, target);
}
@@ -3469,6 +3487,7 @@ static inline void gen_bcond(DisasContext *ctx, int type)
}
tcg_temp_free_i32(temp);
}
+ gen_update_cfar(ctx, ctx->nip);
if (type == BCOND_IM) {
target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
if (likely(AA(ctx->opcode) == 0)) {
@@ -3580,6 +3599,7 @@ static void gen_rfi(DisasContext *ctx)
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
+ gen_update_cfar(ctx, ctx->nip);
gen_helper_rfi();
gen_sync_exception(ctx);
#endif
@@ -3596,6 +3616,7 @@ static void gen_rfid(DisasContext *ctx)
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
+ gen_update_cfar(ctx, ctx->nip);
gen_helper_rfid();
gen_sync_exception(ctx);
#endif
@@ -9263,6 +9284,12 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
*/
}
+#if defined(TARGET_PPC64)
+ if (env->flags & POWERPC_FLAG_CFAR) {
+ cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
+ }
+#endif
+
switch (env->mmu_model) {
case POWERPC_MMU_32B:
case POWERPC_MMU_601:
@@ -9371,6 +9398,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
#if defined(TARGET_PPC64)
ctx.sf_mode = msr_sf;
+ ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
#endif
ctx.fpu_enabled = msr_fp;
if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 9ea193d..211f3bd 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -129,6 +129,19 @@ static void spr_write_lr (void *opaque, int sprn, int gprn)
tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
}
+/* CFAR */
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+static void spr_read_cfar (void *opaque, int gprn, int sprn)
+{
+ tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
+}
+
+static void spr_write_cfar (void *opaque, int sprn, int gprn)
+{
+ tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
+}
+#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
+
/* CTR */
static void spr_read_ctr (void *opaque, int gprn, int sprn)
{
@@ -6489,7 +6502,7 @@ static void init_proc_970MP (CPUPPCState *env)
#define POWERPC_BFDM_POWER7 (bfd_mach_ppc64)
#define POWERPC_FLAG_POWER7 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
+ POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR)
#define check_pow_POWER7 check_pow_nocheck
static void init_proc_POWER7 (CPUPPCState *env)
@@ -6508,6 +6521,14 @@ static void init_proc_POWER7 (CPUPPCState *env)
&spr_read_purr, SPR_NOACCESS,
&spr_read_purr, SPR_NOACCESS,
0x00000000);
+ spr_register(env, SPR_CFAR, "SPR_CFAR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_cfar, &spr_write_cfar,
+ 0x00000000);
+ spr_register(env, SPR_DSCR, "SPR_DSCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
#endif /* !CONFIG_USER_ONLY */
/* Memory management */
/* XXX : not implemented */
--
1.7.5.4
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] pseries machine updates
2011-09-01 1:45 ` David Gibson
@ 2011-09-02 13:20 ` Alexander Graf
0 siblings, 0 replies; 18+ messages in thread
From: Alexander Graf @ 2011-09-02 13:20 UTC (permalink / raw)
To: qemu-devel
On 09/01/2011 03:45 AM, David Gibson wrote:
> On Wed, Aug 31, 2011 at 11:17:13AM +0200, Alexander Graf wrote:
>> On 11.08.2011, at 02:39, David Gibson wrote:
>>
>>> On Wed, Aug 10, 2011 at 05:16:35PM +0200, Alexander Graf wrote:
>>>> On 08/04/2011 09:02 AM, David Gibson wrote:
>>>>> Hi Alex,
>>>>>
>>>>> Here's another batch of assorted updates for the pseries machine.
>>>> Looks pretty nice. Please update patch 2/6 with the bug you found
>>>> and the whitespace problems. I'll put the others into my tree
>>>> already.
>>> Here's the updated 2/6
>>>
>>> From e5b9ba608d4814a46f256337bbf60b94fdc2c5d9 Mon Sep 17 00:00:00 2001
>>> From: Ben Herrenschmidt<benh@kernel.crashing.org>
>>> Date: Thu, 4 Aug 2011 16:56:41 +1000
>>> Subject: [PATCH] Implement POWER7's CFAR in TCG
>>>
>>> This patch implements support for the CFAR SPR on POWER7 (Come From
>>> Address Register), which snapshots the PC value at the time of a branch or
>>> an rfid. The latest powerpc-next kernel also catches it and can show it in
>>> xmon or in the signal frames.
>>>
>>> This works well enough to let recent kernels boot (which otherwise oops
>>> on the CFAR access). It hasn't been tested enough to be confident that the
>>> CFAR values are actually accurate, but one thing at a time.
>>>
>>> Signed-off-by: Ben Herrenschmidt<benh@kernel.crashing.org>
>>> Signed-off-by: David Gibson<david@gibson.dropbear.id.au>
>> agraf@lychee:/home/agraf/release/qemu> git pw am 109480
>> ERROR: code indent should never use tabs
>> #107: FILE: target-ppc/translate.c:162:
>> +^I^I^I^I offsetof(CPUState, cfar), "cfar");$
>>
>> ERROR: code indent should never use tabs
>> #174: FILE: target-ppc/translate.c:9289:
>> +^Icpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);$
> Blah. Fixed now, I'll try to get BenH to use the emacs magic to stop
> it putting tabs in.
>
>> WARNING: space prohibited between function name and open parenthesis '('
>> #199: FILE: target-ppc/translate_init.c:134:
>> +static void spr_read_cfar (void *opaque, int gprn, int sprn)
>>
>> WARNING: space prohibited between function name and open parenthesis '('
>> #204: FILE: target-ppc/translate_init.c:139:
>> +static void spr_write_cfar (void *opaque, int sprn, int gprn)
> Well, these are deliberate, on the grounds that matching the
> surrounding functions seemed more important than matching the global
> style guidelines.
>
> Revised patch below
>
> From b35b94ea867550faf99fc553b661739551c9bb8b Mon Sep 17 00:00:00 2001
> From: Ben Herrenschmidt<benh@kernel.crashing.org>
> Date: Thu, 4 Aug 2011 16:56:41 +1000
> Subject: [PATCH] Implement POWER7's CFAR in TCG
>
> This patch implements support for the CFAR SPR on POWER7 (Come From
> Address Register), which snapshots the PC value at the time of a branch or
> an rfid. The latest powerpc-next kernel also catches it and can show it in
> xmon or in the signal frames.
>
> This works well enough to let recent kernels boot (which otherwise oops
> on the CFAR access). It hasn't been tested enough to be confident that the
> CFAR values are actually accurate, but one thing at a time.
>
> Signed-off-by: Ben Herrenschmidt<benh@kernel.crashing.org>
> Signed-off-by: David Gibson<david@gibson.dropbear.id.au>
> ---
> target-ppc/cpu.h | 8 ++++++++
> target-ppc/translate.c | 28 ++++++++++++++++++++++++++++
> target-ppc/translate_init.c | 23 ++++++++++++++++++++++-
> 3 files changed, 58 insertions(+), 1 deletions(-)
Thanks, applied. Please resend patches as full patches though. Patchwork
doesn't deal too well with updated inline patches.
Alex
^ permalink raw reply [flat|nested] 18+ messages in thread