root/arch/powerpc/platforms/cell/spufs/spu_save.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. save_event_mask
  2. save_tag_mask
  3. save_upper_240kb
  4. save_fpcr
  5. save_decr
  6. save_srr0
  7. spill_regs_to_mem
  8. enqueue_sync
  9. save_complete
  10. main

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * spu_save.c
   4  *
   5  * (C) Copyright IBM Corp. 2005
   6  *
   7  * SPU-side context save sequence outlined in
   8  * Synergistic Processor Element Book IV
   9  *
  10  * Author: Mark Nutter <mnutter@us.ibm.com>
  11  */
  12 
  13 
  14 #ifndef LS_SIZE
  15 #define LS_SIZE                 0x40000 /* 256K (in bytes) */
  16 #endif
  17 
  18 typedef unsigned int u32;
  19 typedef unsigned long long u64;
  20 
  21 #include <spu_intrinsics.h>
  22 #include <asm/spu_csa.h>
  23 #include "spu_utils.h"
  24 
  25 static inline void save_event_mask(void)
  26 {
  27         unsigned int offset;
  28 
  29         /* Save, Step 2:
  30          *    Read the SPU_RdEventMsk channel and save to the LSCSA.
  31          */
  32         offset = LSCSA_QW_OFFSET(event_mask);
  33         regs_spill[offset].slot[0] = spu_readch(SPU_RdEventMask);
  34 }
  35 
  36 static inline void save_tag_mask(void)
  37 {
  38         unsigned int offset;
  39 
  40         /* Save, Step 3:
  41          *    Read the SPU_RdTagMsk channel and save to the LSCSA.
  42          */
  43         offset = LSCSA_QW_OFFSET(tag_mask);
  44         regs_spill[offset].slot[0] = spu_readch(MFC_RdTagMask);
  45 }
  46 
  47 static inline void save_upper_240kb(addr64 lscsa_ea)
  48 {
  49         unsigned int ls = 16384;
  50         unsigned int list = (unsigned int)&dma_list[0];
  51         unsigned int size = sizeof(dma_list);
  52         unsigned int tag_id = 0;
  53         unsigned int cmd = 0x24;        /* PUTL */
  54 
  55         /* Save, Step 7:
  56          *    Enqueue the PUTL command (tag 0) to the MFC SPU command
  57          *    queue to transfer the remaining 240 kb of LS to CSA.
  58          */
  59         spu_writech(MFC_LSA, ls);
  60         spu_writech(MFC_EAH, lscsa_ea.ui[0]);
  61         spu_writech(MFC_EAL, list);
  62         spu_writech(MFC_Size, size);
  63         spu_writech(MFC_TagID, tag_id);
  64         spu_writech(MFC_Cmd, cmd);
  65 }
  66 
  67 static inline void save_fpcr(void)
  68 {
  69         // vector unsigned int fpcr;
  70         unsigned int offset;
  71 
  72         /* Save, Step 9:
  73          *    Issue the floating-point status and control register
  74          *    read instruction, and save to the LSCSA.
  75          */
  76         offset = LSCSA_QW_OFFSET(fpcr);
  77         regs_spill[offset].v = spu_mffpscr();
  78 }
  79 
  80 static inline void save_decr(void)
  81 {
  82         unsigned int offset;
  83 
  84         /* Save, Step 10:
  85          *    Read and save the SPU_RdDec channel data to
  86          *    the LSCSA.
  87          */
  88         offset = LSCSA_QW_OFFSET(decr);
  89         regs_spill[offset].slot[0] = spu_readch(SPU_RdDec);
  90 }
  91 
  92 static inline void save_srr0(void)
  93 {
  94         unsigned int offset;
  95 
  96         /* Save, Step 11:
  97          *    Read and save the SPU_WSRR0 channel data to
  98          *    the LSCSA.
  99          */
 100         offset = LSCSA_QW_OFFSET(srr0);
 101         regs_spill[offset].slot[0] = spu_readch(SPU_RdSRR0);
 102 }
 103 
 104 static inline void spill_regs_to_mem(addr64 lscsa_ea)
 105 {
 106         unsigned int ls = (unsigned int)&regs_spill[0];
 107         unsigned int size = sizeof(regs_spill);
 108         unsigned int tag_id = 0;
 109         unsigned int cmd = 0x20;        /* PUT */
 110 
 111         /* Save, Step 13:
 112          *    Enqueue a PUT command (tag 0) to send the LSCSA
 113          *    to the CSA.
 114          */
 115         spu_writech(MFC_LSA, ls);
 116         spu_writech(MFC_EAH, lscsa_ea.ui[0]);
 117         spu_writech(MFC_EAL, lscsa_ea.ui[1]);
 118         spu_writech(MFC_Size, size);
 119         spu_writech(MFC_TagID, tag_id);
 120         spu_writech(MFC_Cmd, cmd);
 121 }
 122 
 123 static inline void enqueue_sync(addr64 lscsa_ea)
 124 {
 125         unsigned int tag_id = 0;
 126         unsigned int cmd = 0xCC;
 127 
 128         /* Save, Step 14:
 129          *    Enqueue an MFC_SYNC command (tag 0).
 130          */
 131         spu_writech(MFC_TagID, tag_id);
 132         spu_writech(MFC_Cmd, cmd);
 133 }
 134 
 135 static inline void save_complete(void)
 136 {
 137         /* Save, Step 18:
 138          *    Issue a stop-and-signal instruction indicating
 139          *    "save complete".  Note: This function will not
 140          *    return!!
 141          */
 142         spu_stop(SPU_SAVE_COMPLETE);
 143 }
 144 
 145 /**
 146  * main - entry point for SPU-side context save.
 147  *
 148  * This code deviates from the documented sequence as follows:
 149  *
 150  *      1. The EA for LSCSA is passed from PPE in the
 151  *         signal notification channels.
 152  *      2. All 128 registers are saved by crt0.o.
 153  */
 154 int main()
 155 {
 156         addr64 lscsa_ea;
 157 
 158         lscsa_ea.ui[0] = spu_readch(SPU_RdSigNotify1);
 159         lscsa_ea.ui[1] = spu_readch(SPU_RdSigNotify2);
 160 
 161         /* Step 1: done by exit(). */
 162         save_event_mask();      /* Step 2.  */
 163         save_tag_mask();        /* Step 3.  */
 164         set_event_mask();       /* Step 4.  */
 165         set_tag_mask();         /* Step 5.  */
 166         build_dma_list(lscsa_ea);       /* Step 6.  */
 167         save_upper_240kb(lscsa_ea);     /* Step 7.  */
 168         /* Step 8: done by exit(). */
 169         save_fpcr();            /* Step 9.  */
 170         save_decr();            /* Step 10. */
 171         save_srr0();            /* Step 11. */
 172         enqueue_putllc(lscsa_ea);       /* Step 12. */
 173         spill_regs_to_mem(lscsa_ea);    /* Step 13. */
 174         enqueue_sync(lscsa_ea); /* Step 14. */
 175         set_tag_update();       /* Step 15. */
 176         read_tag_status();      /* Step 16. */
 177         read_llar_status();     /* Step 17. */
 178         save_complete();        /* Step 18. */
 179 
 180         return 0;
 181 }

/* [<][>][^][v][top][bottom][index][help] */