linux/arch/powerpc/platforms/cell/spufs/spu_utils.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * utils.h: Utilities for SPU-side of the context switch operation.
   4 *
   5 * (C) Copyright IBM 2005
   6 */
   7
   8#ifndef _SPU_CONTEXT_UTILS_H_
   9#define _SPU_CONTEXT_UTILS_H_
  10
  11/*
  12 * 64-bit safe EA.
  13 */
  14typedef union {
  15        unsigned long long ull;
  16        unsigned int ui[2];
  17} addr64;
  18
  19/*
  20 * 128-bit register template.
  21 */
  22typedef union {
  23        unsigned int slot[4];
  24        vector unsigned int v;
  25} spu_reg128v;
  26
  27/*
  28 * DMA list structure.
  29 */
  30struct dma_list_elem {
  31        unsigned int size;
  32        unsigned int ea_low;
  33};
  34
  35/*
  36 * Declare storage for 8-byte aligned DMA list.
  37 */
  38struct dma_list_elem dma_list[15] __attribute__ ((aligned(8)));
  39
  40/*
  41 * External definition for storage
  42 * declared in crt0.
  43 */
  44extern spu_reg128v regs_spill[NR_SPU_SPILL_REGS];
  45
  46/*
  47 * Compute LSCSA byte offset for a given field.
  48 */
  49static struct spu_lscsa *dummy = (struct spu_lscsa *)0;
  50#define LSCSA_BYTE_OFFSET(_field)  \
  51        ((char *)(&(dummy->_field)) - (char *)(&(dummy->gprs[0].slot[0])))
  52#define LSCSA_QW_OFFSET(_field)  (LSCSA_BYTE_OFFSET(_field) >> 4)
  53
  54static inline void set_event_mask(void)
  55{
  56        unsigned int event_mask = 0;
  57
  58        /* Save, Step 4:
  59         * Restore, Step 1:
  60         *    Set the SPU_RdEventMsk channel to zero to mask
  61         *    all events.
  62         */
  63        spu_writech(SPU_WrEventMask, event_mask);
  64}
  65
  66static inline void set_tag_mask(void)
  67{
  68        unsigned int tag_mask = 1;
  69
  70        /* Save, Step 5:
  71         * Restore, Step 2:
  72         *    Set the SPU_WrTagMsk channel to '01' to unmask
  73         *    only tag group 0.
  74         */
  75        spu_writech(MFC_WrTagMask, tag_mask);
  76}
  77
  78static inline void build_dma_list(addr64 lscsa_ea)
  79{
  80        unsigned int ea_low;
  81        int i;
  82
  83        /* Save, Step 6:
  84         * Restore, Step 3:
  85         *    Update the effective address for the CSA in the
  86         *    pre-canned DMA-list in local storage.
  87         */
  88        ea_low = lscsa_ea.ui[1];
  89        ea_low += LSCSA_BYTE_OFFSET(ls[16384]);
  90
  91        for (i = 0; i < 15; i++, ea_low += 16384) {
  92                dma_list[i].size = 16384;
  93                dma_list[i].ea_low = ea_low;
  94        }
  95}
  96
  97static inline void enqueue_putllc(addr64 lscsa_ea)
  98{
  99        unsigned int ls = 0;
 100        unsigned int size = 128;
 101        unsigned int tag_id = 0;
 102        unsigned int cmd = 0xB4;        /* PUTLLC */
 103
 104        /* Save, Step 12:
 105         * Restore, Step 7:
 106         *    Send a PUTLLC (tag 0) command to the MFC using
 107         *    an effective address in the CSA in order to
 108         *    remove any possible lock-line reservation.
 109         */
 110        spu_writech(MFC_LSA, ls);
 111        spu_writech(MFC_EAH, lscsa_ea.ui[0]);
 112        spu_writech(MFC_EAL, lscsa_ea.ui[1]);
 113        spu_writech(MFC_Size, size);
 114        spu_writech(MFC_TagID, tag_id);
 115        spu_writech(MFC_Cmd, cmd);
 116}
 117
 118static inline void set_tag_update(void)
 119{
 120        unsigned int update_any = 1;
 121
 122        /* Save, Step 15:
 123         * Restore, Step 8:
 124         *    Write the MFC_TagUpdate channel with '01'.
 125         */
 126        spu_writech(MFC_WrTagUpdate, update_any);
 127}
 128
 129static inline void read_tag_status(void)
 130{
 131        /* Save, Step 16:
 132         * Restore, Step 9:
 133         *    Read the MFC_TagStat channel data.
 134         */
 135        spu_readch(MFC_RdTagStat);
 136}
 137
 138static inline void read_llar_status(void)
 139{
 140        /* Save, Step 17:
 141         * Restore, Step 10:
 142         *    Read the MFC_AtomicStat channel data.
 143         */
 144        spu_readch(MFC_RdAtomicStat);
 145}
 146
 147#endif                          /* _SPU_CONTEXT_UTILS_H_ */
 148