コード例 #1
0
static inline void restore_decr(void)
{
	unsigned int offset;
	unsigned int decr_running;
	unsigned int decr;

	/* Restore, Step 6(moved):
	 *    If the LSCSA "decrementer running" flag is set
	 *    then write the SPU_WrDec channel with the
	 *    decrementer value from LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(decr_status);
	decr_running = regs_spill[offset].slot[0] & SPU_DECR_STATUS_RUNNING;
	if (decr_running) {
		offset = LSCSA_QW_OFFSET(decr);
		decr = regs_spill[offset].slot[0];
		spu_writech(SPU_WrDec, decr);
	}
}
コード例 #2
0
ファイル: spu_save.c プロジェクト: CSCLOG/beaglebone
static inline void save_tag_mask(void)
{
	unsigned int offset;

	/* Save, Step 3:
	 *    Read the SPU_RdTagMsk channel and save to the LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(tag_mask);
	regs_spill[offset].slot[0] = spu_readch(MFC_RdTagMask);
}
コード例 #3
0
ファイル: spu_save.c プロジェクト: CSCLOG/beaglebone
static inline void save_event_mask(void)
{
	unsigned int offset;

	/* Save, Step 2:
	 *    Read the SPU_RdEventMsk channel and save to the LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(event_mask);
	regs_spill[offset].slot[0] = spu_readch(SPU_RdEventMask);
}
コード例 #4
0
ファイル: spu_save.c プロジェクト: CSCLOG/beaglebone
static inline void save_decr(void)
{
	unsigned int offset;

	/* Save, Step 10:
	 *    Read and save the SPU_RdDec channel data to
	 *    the LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(decr);
	regs_spill[offset].slot[0] = spu_readch(SPU_RdDec);
}
コード例 #5
0
ファイル: spu_save.c プロジェクト: CSCLOG/beaglebone
static inline void save_srr0(void)
{
	unsigned int offset;

	/* Save, Step 11:
	 *    Read and save the SPU_WSRR0 channel data to
	 *    the LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(srr0);
	regs_spill[offset].slot[0] = spu_readch(SPU_RdSRR0);
}
コード例 #6
0
static inline void restore_tag_mask(void)
{
	unsigned int offset;
	unsigned int tag_mask;

	/* Restore, Step 16:
	 *    Restore the SPU_RdTagMsk data from the LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(tag_mask);
	tag_mask = regs_spill[offset].slot[0];
	spu_writech(MFC_WrTagMask, tag_mask);
}
コード例 #7
0
static inline void restore_event_mask(void)
{
	unsigned int offset;
	unsigned int event_mask;

	/* Restore, Step 15:
	 *    Restore the SPU_RdEventMsk data from the LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(event_mask);
	event_mask = regs_spill[offset].slot[0];
	spu_writech(SPU_WrEventMask, event_mask);
}
コード例 #8
0
static inline void restore_srr0(void)
{
	unsigned int offset;
	unsigned int srr0;

	/* Restore, Step 14:
	 *    Restore the SPU SRR0 data from the LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(srr0);
	srr0 = regs_spill[offset].slot[0];
	spu_writech(SPU_WrSRR0, srr0);
}
コード例 #9
0
ファイル: spu_save.c プロジェクト: CSCLOG/beaglebone
static inline void save_fpcr(void)
{
	// vector unsigned int fpcr;
	unsigned int offset;

	/* Save, Step 9:
	 *    Issue the floating-point status and control register
	 *    read instruction, and save to the LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(fpcr);
	regs_spill[offset].v = spu_mffpscr();
}
コード例 #10
0
static inline void restore_fpcr(void)
{
	unsigned int offset;
	vector unsigned int fpcr;

	/* Restore, Step 13:
	 *    Restore the floating-point status and control
	 *    register from the LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(fpcr);
	fpcr = regs_spill[offset].v;
	spu_mtfpscr(fpcr);
}
コード例 #11
0
static inline void write_ppuint_mb(void)
{
	unsigned int offset;
	unsigned int data;

	/* Restore, Step 12:
	 *    Write the MFC_WrInt_MB channel with the PPUINT_MB
	 *    data from LSCSA.
	 */
	offset = LSCSA_QW_OFFSET(ppuint_mb);
	data = regs_spill[offset].slot[0];
	spu_writech(SPU_WrOutIntrMbox, data);
}
コード例 #12
0
static inline void restore_complete(void)
{
	extern void exit_fini(void);
	unsigned int *exit_instrs = (unsigned int *)exit_fini;
	unsigned int offset;
	unsigned int stopped_status;
	unsigned int stopped_code;

	/* Restore, Step 18:
	 *    Issue a stop-and-signal instruction with
	 *    "good context restore" signal value.
	 *
	 * Restore, Step 19:
	 *    There may be additional instructions placed
	 *    here by the PPE Sequence for SPU Context
	 *    Restore in order to restore the correct
	 *    "stopped state".
	 *
	 *    This step is handled here by analyzing the
	 *    LSCSA.stopped_status and then modifying the
	 *    exit() function to behave appropriately.
	 */

	offset = LSCSA_QW_OFFSET(stopped_status);
	stopped_status = regs_spill[offset].slot[0];
	stopped_code = regs_spill[offset].slot[1];

	switch (stopped_status) {
	case SPU_STOPPED_STATUS_P_I:
		/* SPU_Status[P,I]=1.  Add illegal instruction
		 * followed by stop-and-signal instruction after
		 * end of restore code.
		 */
		exit_instrs[0] = RESTORE_COMPLETE;
		exit_instrs[1] = ILLEGAL_INSTR;
		exit_instrs[2] = STOP_INSTR | stopped_code;
		break;
	case SPU_STOPPED_STATUS_P_H:
		/* SPU_Status[P,H]=1.  Add 'heq $0, $0' followed
		 * by stop-and-signal instruction after end of
		 * restore code.
		 */
		exit_instrs[0] = RESTORE_COMPLETE;
		exit_instrs[1] = HEQ_INSTR;
		exit_instrs[2] = STOP_INSTR | stopped_code;
		break;
	case SPU_STOPPED_STATUS_S_P:
		/* SPU_Status[S,P]=1.  Add nop instruction
		 * followed by 'br -4' after end of restore
		 * code.
		 */
		exit_instrs[0] = RESTORE_COMPLETE;
		exit_instrs[1] = STOP_INSTR | stopped_code;
		exit_instrs[2] = NOP_INSTR;
		exit_instrs[3] = BR_INSTR;
		break;
	case SPU_STOPPED_STATUS_S_I:
		/* SPU_Status[S,I]=1.  Add  illegal instruction
		 * followed by 'br -4' after end of restore code.
		 */
		exit_instrs[0] = RESTORE_COMPLETE;
		exit_instrs[1] = ILLEGAL_INSTR;
		exit_instrs[2] = NOP_INSTR;
		exit_instrs[3] = BR_INSTR;
		break;
	case SPU_STOPPED_STATUS_I:
		/* SPU_Status[I]=1. Add illegal instruction followed
		 * by infinite loop after end of restore sequence.
		 */
		exit_instrs[0] = RESTORE_COMPLETE;
		exit_instrs[1] = ILLEGAL_INSTR;
		exit_instrs[2] = NOP_INSTR;
		exit_instrs[3] = BR_INSTR;
		break;
	case SPU_STOPPED_STATUS_S:
		/* SPU_Status[S]=1. Add two 'nop' instructions. */
		exit_instrs[0] = RESTORE_COMPLETE;
		exit_instrs[1] = NOP_INSTR;
		exit_instrs[2] = NOP_INSTR;
		exit_instrs[3] = BR_INSTR;
		break;
	case SPU_STOPPED_STATUS_H:
		/* SPU_Status[H]=1. Add 'heq $0, $0' instruction
		 * after end of restore code.
		 */
		exit_instrs[0] = RESTORE_COMPLETE;
		exit_instrs[1] = HEQ_INSTR;
		exit_instrs[2] = NOP_INSTR;
		exit_instrs[3] = BR_INSTR;
		break;
	case SPU_STOPPED_STATUS_P:
		/* SPU_Status[P]=1. Add stop-and-signal instruction
		 * after end of restore code.
		 */
		exit_instrs[0] = RESTORE_COMPLETE;
		exit_instrs[1] = STOP_INSTR | stopped_code;
		break;
	case SPU_STOPPED_STATUS_R:
		/* SPU_Status[I,S,H,P,R]=0. Add infinite loop. */
		exit_instrs[0] = RESTORE_COMPLETE;
		exit_instrs[1] = NOP_INSTR;
		exit_instrs[2] = NOP_INSTR;
		exit_instrs[3] = BR_INSTR;
		break;
	default:
		/* SPU_Status[R]=1. No additonal instructions. */
		break;
	}
	spu_sync();
}