📄 vxalib.s
字号:
mfspr p2, TBU_R /* load from TBHI */ mfspr p3, TBL_R /* load from TBLO */ mfspr p4, TBU_R /* load from TBHI */#else /* CPU == PPC4xx, PPC85XX */ mftbu p2 /* load from TBU */ mftb p3 /* load from TBL */ mftbu p4 /* load from TBU */#endif /* CPU == PPC4xx, PPC85XX */ cmpw p2, p4 /* if old = new */ bne vxTimeBaseGet stw p2, 0x0(p0) stw p3, 0x0(p1) blrFUNC_END(vxTimeBaseGet)#if ((CPU == PPC440) || (CPU == PPC85XX))/********************************************************************************* vxDecSet - set decrementer** RETURN: N/A.*/FUNC_BEGIN(vxDecSet) mtspr DEC, p0 mtspr DECAR, p0 /* Also set the auto-reload register */ blrFUNC_END(vxDecSet)/********************************************************************************* vxDecGet - get decrementer** RETURN: the value of decrementer.*/FUNC_BEGIN(vxDecGet) mfspr p0, DEC blrFUNC_END(vxDecGet)/********************************************************************************* vxDecIntEnable - enable decrementer timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxDecIntEnable) mfspr p1, TCR oris p1, p1, _PPC_TCR_DIE_U /* set decrementerinterrupt enable */ mtspr TCR, p1 mfmsr p0 /* read msr to p0 */ ori p0, p0, _PPC_MSR_EE /* set ee bit */ mtmsr p0 /* enable interrupt */ blrFUNC_END(vxDecIntEnable)/********************************************************************************* vxDecIntAck - acknowledge decrementer timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxDecIntAck) addis p0, r0, _PPC_TSR_DIS_U /* load status mask bit */ mtspr TSR, p0 /* clear decrementer pending bit */ blrFUNC_END(vxDecIntAck)#endif /* CPU == PPC440, PPC85XX */#if ((CPU == PPC509) || (CPU == PPC555) || (CPU == PPC601) || \ (CPU == PPC603) || (CPU == PPCEC603) || (CPU == PPC604) || \ (CPU == PPC860))/********************************************************************************* vxDecSet - set decrementer* For CPU==PPC860 the option of locking the key registers is there. * In this case it is also done in a interrupt handler so it needs to * interrupt safe. As the routine isn't called that often it's * not that wasteful. * RETURN: N/A.*/FUNC_BEGIN(vxDecSet)#if (CPU == PPC860) lis p5, HIADJ(vx860KeyedRegUsed) lwz p5, LO(vx860KeyedRegUsed)(p5) cmpwi p5, TRUE /* test == TRUE */ bne vxDecSetStandard /* branch to normal non keyed reg use */ mfspr p1, IMMR /* move IMMR register to P0 */ rlwinm p1, p1, 0, 0, 15 /* the address should be 64K aligned */ lis p3, HIADJ( 0x55CCAA33 ) /* KEYED_REG_UNLOCK_VALUE */ addi p3, p3, LO( 0x55CCAA33 ) /* KEYED_REG_UNLOCK_VALUE */ lis p5, HIADJ( ~0x55CCAA33 ) /* KEYED_REG_LOCK_VALUE */ addi p5, p5, LO( ~0x55CCAA33 ) /* KEYED_REG_LOCK_VALUE */ mfmsr p4 /* read msr to p0 */ INT_MASK(p4, p2) /* mask ee bit */ mtmsr p2 /* disable interrupt */ isync stw p3, 0x30C(p1) /* unlock TB registers. 0x30c is TBK */ isync mtdec p0 stw p5, 0x30C(p1) /* lock TB registers. 0x30c is TBK */ mtmsr p4 /* enable interrupt */ blrvxDecSetStandard:#endif mtdec p0 blrFUNC_END(vxDecSet)/********************************************************************************* vxDecGet - get decrementer** RETURN: the value of decrementer.*/FUNC_BEGIN(vxDecGet) mfdec p0 blrFUNC_END(vxDecGet)/********************************************************************************* vxDecReload - reload decrementer** Reload the decrementer with a multiple of input argument. This is* necessary to insure that a positive number is reloaded.** This code is supposedly for use of the decrementer as the system clock.* The decrementer counts down from a preset value and generates an interrupt* when the value counts below 0. When the interrupt is processed the* decrementer has to be reloaded with the initial count. However, there* is always a delay from the time the interrupt is generated until the CPU* enters the service routine. The decrementer is still counting, so the reload* has to take into account the actual current value of the decrementer.** Since we could have actually missed more than one system tick, we need to* be able to add more than a single multiple of the initial count value.* The algorithm insures that we load a positive number into the decrementer.* We keep track of how many initial count values we had to add to the* decrementer. This is the number of elapsed 'ticks' since the last time* the counter was reloaded. The normal value will be '1'. If it is greater* than one then multiple ticks have been skipped.** RETURN: Returns the number of multiples added (or system 'ticks').*/FUNC_BEGIN(vxDecReload) ori p1,p0,0x0 /* p1 = p0 */ li p0,0 /* p0 = 0 */ mfdec p2 /* p2 = decrementer */reloadLoop: /* do { */ addi p0,p0,1 /* p0 += 1 */ add. p2,p1,p2 /* p2 += p1 */ blt reloadLoop /* } while (p2 < 0) */ mtdec p2 /* decrementer = p2 */ blr /* return p0 */FUNC_END(vxDecReload)#endif /* ((CPU == PPC5xx) || (CPU==PPC60[134]) || (CPU == PPC860)) */#if (CPU==PPC860)/********************************************************************************* vxKeyedDecReload - reload decrementer** Reload the decrementer with a multiple of input argument. This is* necessary to insure that a positive number is reloaded.** This code is supposedly for use of the decrementer as the system clock.* The decrementer counts down from a preset value and generates an interrupt* when the value counts below 0. When the interrupt is processed the* decrementer has to be reloaded with the initial count. However, there* is always a delay from the time the interrupt is generated until the CPU* enters the service routine. The decrementer is still counting, so the reload* has to take into account the actual current value of the decrementer.** Since we could have actually missed more than one system tick, we need to* be able to add more than a single multiple of the initial count value.* The algorithm insures that we load a positive number into the decrementer.* We keep track of how many initial count values we had to add to the* decrementer. This is the number of elapsed 'ticks' since the last time* the counter was reloaded. The normal value will be '1'. If it is greater* than one then multiple ticks have been skipped.** This function also unlocks/locks the KEYED registers in addition to what * vxDecReload does. This is to cut down on the possibilty that the registers* get corrupted( h/w errata ).The bsp must define USE_KEY_REGS for the timer. ** RETURN: Returns the number of multiples added (or system 'ticks').*/FUNC_BEGIN(vxKeyedDecReload) ori p1,p0,0x0 /* p1 = p0 */ li p0,0 /* p0 = 0 */ mfdec p2 /* p2 = decrementer */keyedReloadLoop: /* do { */ addi p0,p0,1 /* p0 += 1 */ add. p2,p1,p2 /* p2 += p1 */ blt keyedReloadLoop /* } while (p2 < 0) */ mfspr p3, IMMR /* move IMMR register to P0 */ rlwinm p3, p3, 0, 0, 15 /* the address should be 64K aligned */ lis p4, HIADJ( 0x55CCAA33 ) /* KEYED_REG_UNLOCK_VALUE */ addi p4, p4, LO( 0x55CCAA33 ) /* KEYED_REG_UNLOCK_VALUE */ lis p1, HIADJ( ~0x55CCAA33 ) /* KEYED_REG_LOCK_VALUE */ addi p1, p1, LO( ~0x55CCAA33 ) /* KEYED_REG_LOCK_VALUE */ stw p4, 0x30C(p3) /* unlock TB registers */ isync mtdec p2 /* decrementer = p2 */ stw p1, 0x30C(p3) /* lock reg TB registers */ blr /* return p0 */FUNC_END(vxKeyedDecReload)/******************************************************************************* vxPlprcrSet - Set the PLPRCR memory mapped register for LPM and * reset control.** Use for Errata SIU9 MPC860* * vxPlpcrset (UINT32 *ImmrAddr,UINT32 value,UINT32 delay)* * The delay can be calculated as follows : * (delay * 16 clock cycles ) + 2** RETURN : N/A*/ .balign 16 /* For cache line alignment */ FUNC_BEGIN(vxPlprcrSet) stw p1,PLPRCR_OFFSET(p0) isyncdelayLoop:/* Note p0(IMMR address) should never be zero */ divw p1,p0,p0 /* 13 clocks */ addi p2,p2,-1 /* 1 clock */ cmpwi p2,0 /* 1 clock */ bgt delayLoop /* 1 clock */ blr FUNC_END(vxPlprcrSet)#endif /* (CPU==PPC860) */ #if ((CPU == PPC403) || (CPU == PPC405) || (CPU == PPC405F) || \ (CPU == PPC440) || (CPU == PPC85XX))# if ((CPU != PPC440) && (CPU != PPC85XX))/********************************************************************************* vxPitSet - set the programmable interval timer to specified value** RETURN: N/A.*/FUNC_BEGIN(vxPitSet) mtspr PIT, p0 blrFUNC_END(vxPitSet)/********************************************************************************* vxPitGet - get the value of the programmable interval timer** RETURN: the value of the programmable interval timer.*/FUNC_BEGIN(vxPitGet) mfspr p0, PIT blrFUNC_END(vxPitGet)# endif /* CPU != PPC440, PPC85XX */# if (CPU==PPC403)/********************************************************************************* vxPitIntEnable - enable programmable interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxPitIntEnable) mfspr p1, TCR oris p1, p1, _PPC403_TCR_PIEM_U /* set pit interrupt enable */ mtspr TCR, p1 mfmsr p0 /* read msr to p0 */ ori p0, p0, _PPC_MSR_EE /* set ee bit */ mtmsr p0 /* enable interrupt */ blrFUNC_END(vxPitIntEnable)/********************************************************************************* vxPitIntAck - acknowledge programmable interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxPitIntAck) oris p0, r0, _PPC403_TSR_PISM_U /* load status mask bit */ mtspr TSR, p0 /* clear pit pending bit */ blrFUNC_END(vxPitIntAck)/********************************************************************************* vxFitIntDisable - disable fixed interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxFitIntDisable) mfspr p0, TCR addis p1, r0, _PPC403_TCR_FIEM_U /* set fit interrupt enable */ andc p1, p0, p1 /* mask off fie bit */ mtspr TCR, p1 blrFUNC_END(vxFitIntDisable)/********************************************************************************* vxFitIntEnable - enable fixed interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxFitIntEnable) mfspr p1, TCR oris p1, p1, _PPC403_TCR_FIEM_U /* set fit interrupt enable */ mtspr TCR, p1 blrFUNC_END(vxFitIntEnable)/********************************************************************************* vxFitIntAck - acknowledge fixed interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxFitIntAck) oris p0, r0, _PPC403_TSR_FISM_U /* load status mask bit */ mtspr TSR, p0 /* clear fit pending bit */ blrFUNC_END(vxFitIntAck)/********************************************************************************* vxDbcrGet - this routine gets DBCR register value ** RETURN: debug control register value.*/FUNC_BEGIN(vxDbcrGet) mfspr p0, DBCR /* move dbcr to p0 */ blrFUNC_END(vxDbcrGet)/********************************************************************************* vxDbcrSet - this routine sets DBCR register to a specific value** RETURN: N/A.*/FUNC_BEGIN(vxDbcrSet) mtspr DBCR, p0 /* move p0 to dbcr */ blrFUNC_END(vxDbcrSet)# elif ((CPU==PPC405) || (CPU==PPC405F))/********************************************************************************* vxPitIntEnable - enable programmable interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxPitIntEnable) mfspr p1, TCR oris p1, p1, _PPC405_TCR_PIEM_U /* set pit interrupt enable */ mtspr TCR, p1 mfmsr p0 /* read msr to p0 */ ori p0, p0, _PPC_MSR_EE /* set ee bit */ mtmsr p0 /* enable interrupt */ blrFUNC_END(vxPitIntEnable)/********************************************************************************* vxPitIntAck - acknowledge programmable interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxPitIntAck) addis p0, r0, _PPC405_TSR_PISM_U /* load status mask bit */ mtspr TSR, p0 /* clear pit pending bit */ blrFUNC_END(vxPitIntAck)/********************************************************************************* vxFitIntAck - acknowledge fixed interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxFitIntAck) addis p0, r0, _PPC405_TSR_FISM_U /* load status mask bit */ mtspr TSR, p0 /* clear fit pending bit */ blrFUNC_END(vxFitIntAck)/********************************************************************************* vxFitIntDisable - disable fixed interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxFitIntDisable) mfspr p0, TCR addis p1, r0, _PPC405_TCR_FIEM_U /* set fit interrupt enable */ andc p1, p0, p1 /* mask off fie bit */ mtspr TCR, p1 blrFUNC_END(vxFitIntDisable)/********************************************************************************* vxFitIntEnable - enable fixed interval timer interrupt** RETURN: N/A.*/FUNC_BEGIN(vxFitIntEnable) mfspr p1, TCR oris p1, p1, _PPC405_TCR_FIEM_U /* set fit interrupt enable */ mtspr TCR, p1 blrFUNC_END(vxFitIntEnable)# endif /* (CPU == PPC403) : ((CPU == PPC405) || (CPU == PPC405F)) */# if ((CPU == PPC405) || (CPU == PPC405F) || (CPU == PPC440) || \ (CPU == PPC85XX))/********************************************************************************* vxDbcr0Get - this routine gets DBCR0 register value ** RETURN: debug control register value.*/FUNC_BEGIN(vxDbcr0Get) mfspr p0, DBCR0 /* move dbcr0 to p0 */ blrFUNC_END(vxDbcr0Get)/********************************************************************************* vxDbcr0Set - this routine sets DBCR0 register to a specific value** RETURN: N/A.*/FUNC_BEGIN(vxDbcr0Set) mtspr DBCR0, p0 /* move p0 to dbcr0 */ blrFUNC_END(vxDbcr0Set)/********************************************************************************* vxDbcr1Get - this routine gets DBCR1 register value ** RETURN: debug control register value.*/FUNC_BEGIN(vxDbcr1Get) mfspr p0, DBCR1 /* move dbcr1 to p0 */ blrFUNC_END(vxDbcr1Get)/********************************************************************************* vxDbcr1Set - this routine sets DBCR1 register to a specific value** RETURN: N/A.*/FUNC_BEGIN(vxDbcr1Set) mtspr DBCR1, p0 /* move p0 to dbcr1 */ blrFUNC_END(vxDbcr1Set)# if ((CPU == PPC440) || (CPU == PPC85XX))/********************************************************************************* vxDbcr2Get - this routine gets DBCR2 register value ** RETURN: debug control register value.*/FUNC_BEGIN(vxDbcr2Get) mfspr p0, DBCR2 /* move dbcr2 to p0 */ blrFUNC_END(vxDbcr2Get)/********************************************************************************* vxDbcr2Set - this routine sets DBCR2 register to a specific value** RETURN: N/A.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -