📄 sym_fw2.h
字号:
PADDR_B (msg_out),}/*-------------------------< MSG_OUT_DONE >---------------------*/,{ /* * Let the C code be aware of the * sent message and clear the message. */ SCR_INT, SIR_MSG_OUT_DONE, /* * ... and process the next phase */ SCR_JUMP, PADDR_A (dispatch),}/*-------------------------< DATA_OVRUN >-----------------------*/,{ /* * Use scratcha to count the extra bytes. */ SCR_LOAD_ABS (scratcha, 4), PADDR_B (zero),}/*-------------------------< DATA_OVRUN1 >----------------------*/,{ /* * The target may want to transfer too much data. * * If phase is DATA OUT write 1 byte and count it. */ SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)), 16, SCR_CHMOV_ABS (1) ^ SCR_DATA_OUT, HADDR_1 (scratch), SCR_JUMP, PADDR_B (data_ovrun2), /* * If WSR is set, clear this condition, and * count this byte. */ SCR_FROM_REG (scntl2), 0, SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)), 16, SCR_REG_REG (scntl2, SCR_OR, WSR), 0, SCR_JUMP, PADDR_B (data_ovrun2), /* * Finally check against DATA IN phase. * Signal data overrun to the C code * and jump to dispatcher if not so. * Read 1 byte otherwise and count it. */ SCR_JUMPR ^ IFTRUE (WHEN (SCR_DATA_IN)), 16, SCR_INT, SIR_DATA_OVERRUN, SCR_JUMP, PADDR_A (dispatch), SCR_CHMOV_ABS (1) ^ SCR_DATA_IN, HADDR_1 (scratch),}/*-------------------------< DATA_OVRUN2 >----------------------*/,{ /* * Count this byte. * This will allow to return a negative * residual to user. */ SCR_REG_REG (scratcha, SCR_ADD, 0x01), 0, SCR_REG_REG (scratcha1, SCR_ADDC, 0), 0, SCR_REG_REG (scratcha2, SCR_ADDC, 0), 0, /* * .. and repeat as required. */ SCR_JUMP, PADDR_B (data_ovrun1),}/*-------------------------< ABORT_RESEL >----------------------*/,{ SCR_SET (SCR_ATN), 0, SCR_CLR (SCR_ACK), 0, /* * send the abort/abortag/reset message * we expect an immediate disconnect */ SCR_REG_REG (scntl2, SCR_AND, 0x7f), 0, SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, HADDR_1 (msgout), SCR_CLR (SCR_ACK|SCR_ATN), 0, SCR_WAIT_DISC, 0, SCR_INT, SIR_RESEL_ABORTED, SCR_JUMP, PADDR_A (start),}/*-------------------------< RESEND_IDENT >---------------------*/,{ /* * The target stays in MSG OUT phase after having acked * Identify [+ Tag [+ Extended message ]]. Targets shall * behave this way on parity error. * We must send it again all the messages. */ SCR_SET (SCR_ATN), /* Shall be asserted 2 deskew delays before the */ 0, /* 1rst ACK = 90 ns. Hope the chip isn't too fast */ SCR_JUMP, PADDR_A (send_ident),}/*-------------------------< IDENT_BREAK >----------------------*/,{ SCR_CLR (SCR_ATN), 0, SCR_JUMP, PADDR_A (select2),}/*-------------------------< IDENT_BREAK_ATN >------------------*/,{ SCR_SET (SCR_ATN), 0, SCR_JUMP, PADDR_A (select2),}/*-------------------------< SDATA_IN >-------------------------*/,{ SCR_CHMOV_TBL ^ SCR_DATA_IN, offsetof (struct sym_dsb, sense), SCR_CALL, PADDR_A (datai_done), SCR_JUMP, PADDR_B (data_ovrun),}/*-------------------------< RESEL_BAD_LUN >--------------------*/,{ /* * Message is an IDENTIFY, but lun is unknown. * Signal problem to C code for logging the event. * Send a M_ABORT to clear all pending tasks. */ SCR_INT, SIR_RESEL_BAD_LUN, SCR_JUMP, PADDR_B (abort_resel),}/*-------------------------< BAD_I_T_L >------------------------*/,{ /* * We donnot have a task for that I_T_L. * Signal problem to C code for logging the event. * Send a M_ABORT message. */ SCR_INT, SIR_RESEL_BAD_I_T_L, SCR_JUMP, PADDR_B (abort_resel),}/*-------------------------< BAD_I_T_L_Q >----------------------*/,{ /* * We donnot have a task that matches the tag. * Signal problem to C code for logging the event. * Send a M_ABORTTAG message. */ SCR_INT, SIR_RESEL_BAD_I_T_L_Q, SCR_JUMP, PADDR_B (abort_resel),}/*-------------------------< BAD_STATUS >-----------------------*/,{ /* * Anything different from INTERMEDIATE * CONDITION MET should be a bad SCSI status, * given that GOOD status has already been tested. * Call the C code. */ SCR_LOAD_ABS (scratcha, 4), PADDR_B (startpos), SCR_INT ^ IFFALSE (DATA (S_COND_MET)), SIR_BAD_SCSI_STATUS, SCR_RETURN, 0,}/*-------------------------< PM_HANDLE >------------------------*/,{ /* * Phase mismatch handling. * * Since we have to deal with 2 SCSI data pointers * (current and saved), we need at least 2 contexts. * Each context (pm0 and pm1) has a saved area, a * SAVE mini-script and a DATA phase mini-script. */ /* * Get the PM handling flags. */ SCR_FROM_REG (HF_REG), 0, /* * If no flags (1rst PM for example), avoid * all the below heavy flags testing. * This makes the normal case a bit faster. */ SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED))), PADDR_B (pm_handle1), /* * If we received a SAVE DP, switch to the * other PM context since the savep may point * to the current PM context. */ SCR_JUMPR ^ IFFALSE (MASK (HF_DP_SAVED, HF_DP_SAVED)), 8, SCR_REG_REG (sfbr, SCR_XOR, HF_ACT_PM), 0, /* * If we have been interrupt in a PM DATA mini-script, * we take the return address from the corresponding * saved area. * This ensure the return address always points to the * main DATA script for this transfer. */ SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1))), PADDR_B (pm_handle1), SCR_JUMPR ^ IFFALSE (MASK (HF_IN_PM0, HF_IN_PM0)), 16, SCR_LOAD_REL (ia, 4), offsetof(struct sym_ccb, phys.pm0.ret), SCR_JUMP, PADDR_B (pm_save), SCR_LOAD_REL (ia, 4), offsetof(struct sym_ccb, phys.pm1.ret), SCR_JUMP, PADDR_B (pm_save),}/*-------------------------< PM_HANDLE1 >-----------------------*/,{ /* * Normal case. * Update the return address so that it * will point after the interrupted MOVE. */ SCR_REG_REG (ia, SCR_ADD, 8), 0, SCR_REG_REG (ia1, SCR_ADDC, 0), 0,}/*-------------------------< PM_SAVE >--------------------------*/,{ /* * Clear all the flags that told us if we were * interrupted in a PM DATA mini-script and/or * we received a SAVE DP. */ SCR_SFBR_REG (HF_REG, SCR_AND, (~(HF_IN_PM0|HF_IN_PM1|HF_DP_SAVED))), 0, /* * Choose the current PM context. */ SCR_JUMP ^ IFTRUE (MASK (HF_ACT_PM, HF_ACT_PM)), PADDR_B (pm1_save),}/*-------------------------< PM0_SAVE >-------------------------*/,{ SCR_STORE_REL (ia, 4), offsetof(struct sym_ccb, phys.pm0.ret), /* * If WSR bit is set, either UA and RBC may * have to be changed whether the device wants * to ignore this residue or not. */ SCR_FROM_REG (scntl2), 0, SCR_CALL ^ IFTRUE (MASK (WSR, WSR)), PADDR_B (pm_wsr_handle), /* * Save the remaining byte count, the updated * address and the return address. */ SCR_STORE_REL (rbc, 4), offsetof(struct sym_ccb, phys.pm0.sg.size), SCR_STORE_REL (ua, 4), offsetof(struct sym_ccb, phys.pm0.sg.addr), /* * Set the current pointer at the PM0 DATA mini-script. */ SCR_LOAD_ABS (ia, 4), PADDR_B (pm0_data_addr),}/*-------------------------< PM_SAVE_END >----------------------*/,{ SCR_STORE_REL (ia, 4), offsetof(struct sym_ccb, phys.head.lastp), SCR_JUMP, PADDR_A (dispatch),}/*-------------------------< PM1_SAVE >-------------------------*/,{ SCR_STORE_REL (ia, 4), offsetof(struct sym_ccb, phys.pm1.ret), /* * If WSR bit is set, either UA and RBC may * have to be changed whether the device wants * to ignore this residue or not. */ SCR_FROM_REG (scntl2), 0, SCR_CALL ^ IFTRUE (MASK (WSR, WSR)), PADDR_B (pm_wsr_handle), /* * Save the remaining byte count, the updated * address and the return address. */ SCR_STORE_REL (rbc, 4), offsetof(struct sym_ccb, phys.pm1.sg.size), SCR_STORE_REL (ua, 4), offsetof(struct sym_ccb, phys.pm1.sg.addr), /* * Set the current pointer at the PM1 DATA mini-script. */ SCR_LOAD_ABS (ia, 4), PADDR_B (pm1_data_addr), SCR_JUMP, PADDR_B (pm_save_end),}/*-------------------------< PM_WSR_HANDLE >--------------------*/,{ /* * Phase mismatch handling from SCRIPT with WSR set. * Such a condition can occur if the chip wants to * execute a CHMOV(size > 1) when the WSR bit is * set and the target changes PHASE. * * We must move the residual byte to memory. * * UA contains bit 0..31 of the address to * move the residual byte. * Move it to the table indirect. */ SCR_STORE_REL (ua, 4), offsetof (struct sym_ccb, phys.wresid.addr), /* * Increment UA (move address to next position). */ SCR_REG_REG (ua, SCR_ADD, 1), 0, SCR_REG_REG (ua1, SCR_ADDC, 0), 0, SCR_REG_REG (ua2, SCR_ADDC, 0), 0, SCR_REG_REG (ua3, SCR_ADDC, 0), 0, /* * Compute SCRATCHA as: * - size to transfer = 1 byte. * - bit 24..31 = high address bit [32...39]. */ SCR_LOAD_ABS (scratcha, 4), PADDR_B (zero), SCR_REG_REG (scratcha, SCR_OR, 1), 0, SCR_FROM_REG (rbc3), 0, SCR_TO_REG (scratcha3), 0, /* * Move this value to the table indirect. */ SCR_STORE_REL (scratcha, 4), offsetof (struct sym_ccb, phys.wresid.size), /* * Wait for a valid phase. * While testing with bogus QUANTUM drives, the C1010 * sometimes raised a spurious phase mismatch with * WSR and the CHMOV(1) triggered another PM. * Waiting explicitely for the PHASE seemed to avoid * the nested phase mismatch. Btw, this didn't happen * using my IBM drives. */ SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_IN)), 0, /* * Perform the move of the residual byte. */ SCR_CHMOV_TBL ^ SCR_DATA_IN, offsetof (struct sym_ccb, phys.wresid), /* * We can now handle the phase mismatch with UA fixed. * RBC[0..23]=0 is a special case that does not require * a PM context. The C code also checks against this. */ SCR_FROM_REG (rbc), 0, SCR_RETURN ^ IFFALSE (DATA (0)), 0, SCR_FROM_REG (rbc1), 0, SCR_RETURN ^ IFFALSE (DATA (0)), 0, SCR_FROM_REG (rbc2), 0, SCR_RETURN ^ IFFALSE (DATA (0)), 0, /* * RBC[0..23]=0. * Not only we donnot need a PM context, but this would * lead to a bogus CHMOV(0). This condition means that * the residual was the last byte to move from this CHMOV. * So, we just have to move the current data script pointer * (i.e. TEMP) to the SCRIPTS address following the * interrupted CHMOV and jump to dispatcher. * IA contains the data pointer to save. */ SCR_JUMP, PADDR_B (pm_save_end),}/*-------------------------< WSR_MA_HELPER >--------------------*/,{ /* * Helper for the C code when WSR bit is set. * Perform the move of the residual byte. */ SCR_CHMOV_TBL ^ SCR_DATA_IN, offsetof (struct sym_ccb, phys.wresid), SCR_JUMP, PADDR_A (dispatch),#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN}/*-------------------------< DATA_IO >--------------------------*/,{ /* * We jump here if the data direction was unknown at the * time we had to queue the command to the scripts processor. * Pointers had been set as follow in this situation: * savep --> DATA_IO * lastp --> start pointer when DATA_IN * wlastp --> start pointer when DATA_OUT * This script sets savep and lastp according to the * direction chosen by the target. */ SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)), PADDR_B (data_io_out),}/*-------------------------< DATA_IO_IN >-----------------------*/,{ /* * Direction is DATA IN. */ SCR_LOAD_REL (scratcha, 4), offsetof (struct sym_ccb, phys.head.lastp),}/*-------------------------< DATA_IO_COM >----------------------*/,{ SCR_STORE_REL (scratcha, 4), offsetof (struct sym_ccb, phys.head.savep), /* * Jump to the SCRIPTS according to actual direction. */ SCR_LOAD_REL (temp, 4), offsetof (struct sym_ccb, phys.head.savep), SCR_RETURN, 0,}/*-------------------------< DATA_IO_OUT >----------------------*/,{ /* * Direction is DATA OUT. */ SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)), 0, SCR_LOAD_REL (scratcha, 4), offsetof (struct sym_ccb, phys.head.wlastp), SCR_STORE_REL (scratcha, 4), offsetof (struct sym_ccb, phys.head.lastp), SCR_JUMP, PADDR_B(data_io_com),#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */}/*-------------------------< ZERO >-----------------------------*/,{ SCR_DATA_ZERO,}/*-------------------------< SCRATCH >--------------------------*/,{ SCR_DATA_ZERO,}/*-------------------------< PM0_DATA_ADDR >--------------------*/,{ SCR_DATA_ZERO,}/*-------------------------< PM1_DATA_ADDR >--------------------*/,{ SCR_DATA_ZERO,}/*-------------------------< DONE_POS >-------------------------*/,{ SCR_DATA_ZERO,}/*-------------------------< STARTPOS >-------------------------*/,{ SCR_DATA_ZERO,}/*-------------------------< TARGTBL >--------------------------*/,{ SCR_DATA_ZERO,}/*-------------------------<>-----------------------------------*/};static struct SYM_FWZ_SCR SYM_FWZ_SCR = { /*-------------------------< SNOOPTEST >------------------------*/{ /* * Read the variable from memory. */ SCR_LOAD_REL (scratcha, 4), offsetof(struct sym_hcb, scratch), /* * Write the variable to memory. */ SCR_STORE_REL (temp, 4), offsetof(struct sym_hcb, scratch), /* * Read back the variable from memory. */ SCR_LOAD_REL (temp, 4), offsetof(struct sym_hcb, scratch),}/*-------------------------< SNOOPEND >-------------------------*/,{ /* * And stop. */ SCR_INT, 99,}/*-------------------------<>-----------------------------------*/};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -