[Cbe-oss-dev] [patch v3] Cell: Wrap master run control bit
Geert Uytterhoeven
Geert.Uytterhoeven at sonycom.com
Thu Oct 25 01:53:32 EST 2007
On Sun, 23 Sep 2007, Geoff Levand wrote:
> Subject: Cell: Wrap master run control bit
>
> From: Masato Noguchi <Masato.Noguchi at jp.sony.com>
>
> Add platform specific SPU run control routines to the spufs. The current
> spufs implementation uses the SPU master run control bit (MFC_SR1[S]) to
> control SPE execution, but the PS3 hypervisor does not support the use of
> this feature.
>
> This change adds the run control wrapper routies spu_enable_spu() and
> spu_disable_spu(). The bare metal routines use the master run control
> bit, and the PS3 specific routines use the priv2 run control register.
>
> An outstanding enhancement for the PS3 would be to add a guard to check
> for incorrect access to the spu problem state when the spu context is
> disabled. This check could be implemented with a flag added to the spu
> context that would inhibit mapping problem state pages, and a routine
> to unmap spu problem state pages. When the spu is enabled with
> ps3_enable_spu() the flag would be set allowing pages to be mapped,
> and when the spu is disabled with ps3_disable_spu() the flag would be
> cleared and mapped problem state pages would be unmapped.
>
> Signed-off-by: Masato Noguchi <Masato.Noguchi at jp.sony.com>
> Signed-off-by: Geoff Levand <geoffrey.levand at am.sony.com>
> ---
>
> Jeremy,
>
> Here is an updated version for 2.6.24. Noguchi-san will
As 2.6.24-rc1 is out and Geoff is offline: what's the status of this patch?
> work on the LS unmapping feature for 2.6.25.
>
> -Geoff
>
> v2:
> o Added comments about unmapping PS pages when disabled.
> v3:
> o Changed routines to return void instead of int.
> o Rebased to apply to Jeremy's 2.6.23-rc work-around.
>
> arch/powerpc/platforms/cell/spu_manage.c | 13 +++++++++++
> arch/powerpc/platforms/cell/spufs/backing_ops.c | 6 +++++
> arch/powerpc/platforms/cell/spufs/hw_ops.c | 10 ++++++++
> arch/powerpc/platforms/cell/spufs/run.c | 4 +--
> arch/powerpc/platforms/cell/spufs/spufs.h | 1
> arch/powerpc/platforms/ps3/spu.c | 27 ++++++++++++++++++++++--
> include/asm-powerpc/spu_priv1.h | 15 +++++++++++++
> 7 files changed, 72 insertions(+), 4 deletions(-)
>
> --- a/arch/powerpc/platforms/cell/spu_manage.c
> +++ b/arch/powerpc/platforms/cell/spu_manage.c
> @@ -35,6 +35,7 @@
> #include <asm/firmware.h>
> #include <asm/prom.h>
>
> +#include "spufs/spufs.h"
> #include "interrupt.h"
>
> struct device_node *spu_devnode(struct spu *spu)
> @@ -369,6 +370,16 @@ static int of_destroy_spu(struct spu *sp
> return 0;
> }
>
> +static void enable_spu_by_master_run(struct spu_context *ctx)
> +{
> + ctx->ops->master_start(ctx);
> +}
> +
> +static void disable_spu_by_master_run(struct spu_context *ctx)
> +{
> + ctx->ops->master_stop(ctx);
> +}
> +
> /* Hardcoded affinity idxs for qs20 */
> #define QS20_SPES_PER_BE 8
> static int qs20_reg_idxs[QS20_SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 };
> @@ -535,5 +546,7 @@ const struct spu_management_ops spu_mana
> .enumerate_spus = of_enumerate_spus,
> .create_spu = of_create_spu,
> .destroy_spu = of_destroy_spu,
> + .enable_spu = enable_spu_by_master_run,
> + .disable_spu = disable_spu_by_master_run,
> .init_affinity = init_affinity,
> };
> --- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
> +++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
> @@ -285,6 +285,11 @@ static void spu_backing_runcntl_write(st
> spin_unlock(&ctx->csa.register_lock);
> }
>
> +static void spu_backing_runcntl_stop(struct spu_context *ctx)
> +{
> + spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP);
> +}
> +
> static void spu_backing_master_start(struct spu_context *ctx)
> {
> struct spu_state *csa = &ctx->csa;
> @@ -381,6 +386,7 @@ struct spu_context_ops spu_backing_ops =
> .get_ls = spu_backing_get_ls,
> .runcntl_read = spu_backing_runcntl_read,
> .runcntl_write = spu_backing_runcntl_write,
> + .runcntl_stop = spu_backing_runcntl_stop,
> .master_start = spu_backing_master_start,
> .master_stop = spu_backing_master_stop,
> .set_mfc_query = spu_backing_set_mfc_query,
> --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
> +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
> @@ -220,6 +220,15 @@ static void spu_hw_runcntl_write(struct
> spin_unlock_irq(&ctx->spu->register_lock);
> }
>
> +static void spu_hw_runcntl_stop(struct spu_context *ctx)
> +{
> + spin_lock_irq(&ctx->spu->register_lock);
> + out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP);
> + while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING)
> + cpu_relax();
> + spin_unlock_irq(&ctx->spu->register_lock);
> +}
> +
> static void spu_hw_master_start(struct spu_context *ctx)
> {
> struct spu *spu = ctx->spu;
> @@ -321,6 +330,7 @@ struct spu_context_ops spu_hw_ops = {
> .get_ls = spu_hw_get_ls,
> .runcntl_read = spu_hw_runcntl_read,
> .runcntl_write = spu_hw_runcntl_write,
> + .runcntl_stop = spu_hw_runcntl_stop,
> .master_start = spu_hw_master_start,
> .master_stop = spu_hw_master_stop,
> .set_mfc_query = spu_hw_set_mfc_query,
> --- a/arch/powerpc/platforms/cell/spufs/run.c
> +++ b/arch/powerpc/platforms/cell/spufs/run.c
> @@ -302,7 +302,7 @@ long spufs_run_spu(struct spu_context *c
> if (mutex_lock_interruptible(&ctx->run_mutex))
> return -ERESTARTSYS;
>
> - ctx->ops->master_start(ctx);
> + spu_enable_spu(ctx);
> ctx->event_return = 0;
>
> spu_acquire(ctx);
> @@ -376,7 +376,7 @@ long spufs_run_spu(struct spu_context *c
> ctx->stats.libassist++;
>
>
> - ctx->ops->master_stop(ctx);
> + spu_disable_spu(ctx);
> ret = spu_run_fini(ctx, npc, &status);
> spu_yield(ctx);
>
> --- a/arch/powerpc/platforms/cell/spufs/spufs.h
> +++ b/arch/powerpc/platforms/cell/spufs/spufs.h
> @@ -170,6 +170,7 @@ struct spu_context_ops {
> char*(*get_ls) (struct spu_context * ctx);
> u32 (*runcntl_read) (struct spu_context * ctx);
> void (*runcntl_write) (struct spu_context * ctx, u32 data);
> + void (*runcntl_stop) (struct spu_context * ctx);
> void (*master_start) (struct spu_context * ctx);
> void (*master_stop) (struct spu_context * ctx);
> int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
> --- a/arch/powerpc/platforms/ps3/spu.c
> +++ b/arch/powerpc/platforms/ps3/spu.c
> @@ -28,6 +28,7 @@
> #include <asm/spu_priv1.h>
> #include <asm/lv1call.h>
>
> +#include "../cell/spufs/spufs.h"
> #include "platform.h"
>
> /* spu_management_ops */
> @@ -419,10 +420,34 @@ static int ps3_init_affinity(void)
> return 0;
> }
>
> +/**
> + * ps3_enable_spu - Enable SPU run control.
> + *
> + * An outstanding enhancement for the PS3 would be to add a guard to check
> + * for incorrect access to the spu problem state when the spu context is
> + * disabled. This check could be implemented with a flag added to the spu
> + * context that would inhibit mapping problem state pages, and a routine
> + * to unmap spu problem state pages. When the spu is enabled with
> + * ps3_enable_spu() the flag would be set allowing pages to be mapped,
> + * and when the spu is disabled with ps3_disable_spu() the flag would be
> + * cleared and the mapped problem state pages would be unmapped.
> + */
> +
> +static void ps3_enable_spu(struct spu_context *ctx)
> +{
> +}
> +
> +static void ps3_disable_spu(struct spu_context *ctx)
> +{
> + ctx->ops->runcntl_stop(ctx);
> +}
> +
> const struct spu_management_ops spu_management_ps3_ops = {
> .enumerate_spus = ps3_enumerate_spus,
> .create_spu = ps3_create_spu,
> .destroy_spu = ps3_destroy_spu,
> + .enable_spu = ps3_enable_spu,
> + .disable_spu = ps3_disable_spu,
> .init_affinity = ps3_init_affinity,
> };
>
> @@ -505,8 +530,6 @@ static void mfc_sr1_set(struct spu *spu,
> static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK
> | MFC_STATE1_PROBLEM_STATE_MASK);
>
> - sr1 |= MFC_STATE1_MASTER_RUN_CONTROL_MASK;
> -
> BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed));
>
> spu_pdata(spu)->cache.sr1 = sr1;
> --- a/include/asm-powerpc/spu_priv1.h
> +++ b/include/asm-powerpc/spu_priv1.h
> @@ -24,6 +24,7 @@
> #include <linux/types.h>
>
> struct spu;
> +struct spu_context;
>
> /* access to priv1 registers */
>
> @@ -178,6 +179,8 @@ struct spu_management_ops {
> int (*enumerate_spus)(int (*fn)(void *data));
> int (*create_spu)(struct spu *spu, void *data);
> int (*destroy_spu)(struct spu *spu);
> + void (*enable_spu)(struct spu_context *ctx);
> + void (*disable_spu)(struct spu_context *ctx);
> int (*init_affinity)(void);
> };
>
> @@ -207,6 +210,18 @@ spu_init_affinity (void)
> return spu_management_ops->init_affinity();
> }
>
> +static inline void
> +spu_enable_spu (struct spu_context *ctx)
> +{
> + spu_management_ops->enable_spu(ctx);
> +}
> +
> +static inline void
> +spu_disable_spu (struct spu_context *ctx)
> +{
> + spu_management_ops->disable_spu(ctx);
> +}
> +
> /*
> * The declarations folowing are put here for convenience
> * and only intended to be used by the platform setup code.
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
With kind regards,
Geert Uytterhoeven
Software Architect
Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
Phone: +32 (0)2 700 8453
Fax: +32 (0)2 700 8622
E-mail: Geert.Uytterhoeven at sonycom.com
Internet: http://www.sony-europe.com/
Sony Network and Software Technology Center Europe
A division of Sony Service Centre (Europe) N.V.
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium
VAT BE 0413.825.160 · RPR Brussels
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619
More information about the cbe-oss-dev
mailing list