csl_dspmmuaux.h

来自「dsp在音频处理中的运用」· C头文件 代码 · 共 853 行 · 第 1/2 页

H
853
字号
 *
 *   <b> Post Condition </b>
 *   @n   TLB victim is configured
 *
 *   @b Modifies
 *   @n   Hardware register
 *
 *   @b Example
 *   @verbatim
            CSL_DspmmuHandle    hDspmmu;
            ...
            CSL_dspmmuConfigLockVictim (hDspMmu, 16);
     @endverbatim
 * ============================================================================
 */

static inline
void CSL_dspmmuConfigLockVictim (
    CSL_DspmmuHandle    hDspmmu,
    Uint8               tlbVictim
)
{
    CSL_FINS (hDspmmu->regs->LOCK_REG, DSPMMU_LOCK_REG_CURRENT_VICTIM, tlbVictim);
}

/** ===========================================================================
 *   @n@b CSL_dspmmuGlobalFlush
 *
 *   @b Description
 *   @n This function flushes the nonprotected TLB entries.
 *
 *   @b Arguments
 *   @verbatim
            hDspmmu         Handle to the DSP MMU instance
     @endverbatim
 *
 *   <b> Return Value </b>  void
 *
 *   <b> Pre Condition </b>
 *   @n   None
 *
 *   <b> Post Condition </b>
 *   @n   Nonprotected TLB entries are flushed
 *
 *   @b Modifies
 *   @n   Translation lookaside buffer (TLB)
 *
 *   @b Example
 *   @verbatim
            CSL_DspmmuHandle    hDspmmu;
            ...
            CSL_dspmmuGlobalFlush (hDspMmu);
     @endverbatim
 * ============================================================================
 */

static inline
void CSL_dspmmuGlobalFlush (
    CSL_DspmmuHandle        hDspmmu
)
{
    CSL_FINS(hDspmmu->regs->GFLUSH_REG, DSPMMU_GFLUSH_REG_GLOBAL_FLUSH, 1);
}

/** ===========================================================================
 *   @n@b CSL_dspmmuFlushTlbEntry
 *
 *   @b Description
 *   @n This function flushes a particular TLB entry.
 *
 *   @b Arguments
 *   @verbatim
            hDspmmu         Handle to the DSP MMU instance
            camRamEntry     Pointer to CAM-RAM structure
     @endverbatim
 *
 *   <b> Return Value </b>  void
 *
 *   <b> Pre Condition </b>
 *   @n   None
 *
 *   <b> Post Condition </b>
 *   @n   Particular TLB entry is flushed
 *
 *   @b Modifies
 *   @n   Translation lookaside buffer (TLB)
 *
 *   @b Example
 *   @verbatim
            CSL_DspmmuHandle    hDspmmu;
            Uint32				virtualAddress = 0x00600000;
            ...
            CSL_dspmmuFlushTlbEntry (hDspMmu, &virtualAddress);
     @endverbatim
 * ============================================================================
 */

static inline
void CSL_dspmmuFlushTlbEntry (
    CSL_DspmmuHandle        hDspmmu,
    Uint32				   	virtualAddress
)
{
    Uint16 wtlState;
    Uint8	victim;
    Uint32 camHValue;
    Uint32 camLValue;
    Uint32 camLValueRead;
    Uint32 camLValueMask;

    /* Stores the upper 12 bits of the virtual address */
    Uint32 vaTagL1 = (virtualAddress >> CSL_DSPMMU_VADDR_L1_SHIFT);

    /* Stores the 10th to 19th (10) bits of the virtual address */
    Uint32 vaTagL2 = CSL_FEXTR(virtualAddress, \
                       CSL_DSPMMU_VADDR_L1_SHIFT, CSL_DSPMMU_VADDR_L2_SHIFT);

	/* Get the contents of the TLB for the virtual address */
    camHValue = ((virtualAddress >> CSL_DSPMMU_VADDR_L1_SHIFT) >>
    					CSL_DSPMMU_VADDR_L1_H_SHIFT);
    camLValue = CSL_FMK(DSPMMU_CAM_L_REG_VA_TAG_L1_L, \
                                 (vaTagL1 & CSL_DSPMMU_VADDR_L1_L_MASK)) | \
                     CSL_FMK(DSPMMU_CAM_L_REG_VA_TAG_L2, vaTagL2);


    /* disable the WTL, if enabled */
    wtlState = CSL_FEXT(hDspmmu->regs->CNTL_REG, DSPMMU_CNTL_REG_WTL_EN);
    CSL_FINS(hDspmmu->regs->CNTL_REG, DSPMMU_CNTL_REG_WTL_EN, 0);

	/* Find the matching TLB entry */
	for (victim = 0; victim <= 31; victim++) {

		/* set the victim pointer */
		CSL_FINS(hDspmmu->regs->LOCK_REG, DSPMMU_LOCK_REG_CURRENT_VICTIM,
												victim);
		/* set the read bit */
		CSL_FINS(hDspmmu->regs->LD_TLB_REG, DSPMMU_LD_TLB_REG_READ_TLB_ITEM, 1);

		/* check for valid tlb entry */
 		if (!CSL_FEXT (hDspmmu->regs->READ_CAM_L_REG, DSPMMU_READ_CAM_L_REG_V)) {
 			continue;
 		}

		/* check if level 1 index in CAM_H reg matches */
		if (camHValue == CSL_FEXT (hDspmmu->regs->READ_CAM_H_REG,
									DSPMMU_READ_CAM_H_REG_VA_TAG_L1_H)) {
			/* check if, the entry in CAM_L reg matches */
			camLValueRead = (hDspmmu->regs->READ_CAM_L_REG &
						CSL_DSPMMU_READ_CAM_L_REG_VA_TAG_L1_L_MASK);
			camLValueRead |= (hDspmmu->regs->READ_CAM_L_REG &
						CSL_DSPMMU_READ_CAM_L_REG_VA_TAG_L2_MASK);

			/* based on the get the L2 index for comparison */
			switch (CSL_FEXT (hDspmmu->regs->READ_CAM_L_REG, DSPMMU_READ_CAM_L_REG_SLST)) {
				case CSL_DSPMMU_CAM_L_REG_SLST_SECTION:
					camLValueMask = CAM_L_REG_MASK_SECTION;
					break;
				case CSL_DSPMMU_CAM_L_REG_SLST_LARGE:
					camLValueMask = CAM_L_REG_MASK_LARGE_PAGE;
					break;
				case CSL_DSPMMU_CAM_L_REG_SLST_SMALL:
					camLValueMask = CAM_L_REG_MASK_SMALL_PAGE;
					break;
				case CSL_DSPMMU_CAM_L_REG_SLST_TINY:
					camLValueMask = CAM_L_REG_MASK_TINY_PAGE;
					break;
				default:
		                  camLValueMask = CAM_L_REG_MASK_SECTION;
					break;
			}

			if ((camLValue & camLValueMask) == (camLValueRead & camLValueMask)) {
				/* If match, flush the TLB entry */
				CSL_FINS(hDspmmu->regs->FLUSH_ENTRY_REG, \
						 DSPMMU_FLUSH_ENTRY_REG_FLUSH_ENTRY, 1);
				break;
			}
		}
		else
			continue;
	}
	/* restore the WTL state */
    CSL_FINS(hDspmmu->regs->CNTL_REG, DSPMMU_CNTL_REG_WTL_EN, wtlState);
}

/**
 *	Status Query Functions of DSP MMU
 */

/** ===========================================================================
 *   @n@b CSL_dspmmuIsWtlWorking
 *
 *   @b Description
 *   @n This function gets the status of the walking table logic.
 *
 *   @b Arguments
 *   @verbatim
            hDspmmu         Handle to the DSP MMU instance
     @endverbatim
 *
 *   <b> Return Value </b>  CSL_DspmmuWlktblLogic
 *
 *   <b> Pre Condition </b>
 *   @n   None
 *
 *   <b> Post Condition </b>
 *   @n   None
 *
 *   @b Modifies
 *   @n   None
 *
 *   @b Example
 *   @verbatim
            CSL_DspmmuHandle        hDspmmu;
            CSL_DspmmuWlktblLogic   wlktblLogic;
            ...
            wlktblLogic = CSL_dspmmuIsWtlWorking (hDspMmu);
     @endverbatim
 * ============================================================================
 */

static inline
CSL_DspmmuWlktblLogic CSL_dspmmuIsWtlWorking (
    CSL_DspmmuHandle        hDspmmu
)
{
    return ((CSL_DspmmuWlktblLogic)
            CSL_FEXT(hDspmmu->regs->WALKING_ST_REG, \
                     DSPMMU_WALKING_ST_REG_WALK_WORKING));
}

/** ===========================================================================
 *   @n@b CSL_dspmmuIsPrefetchOn
 *
 *   @b Description
 *   @n This function gets the status of the prefetch operation.
 *
 *   @b Arguments
 *   @verbatim
            hDspmmu         Handle to the DSP MMU instance
     @endverbatim
 *
 *   <b> Return Value </b>  CSL_DspmmuPrefetchStatus
 *
 *   <b> Pre Condition </b>
 *   @n   None
 *
 *   <b> Post Condition </b>
 *   @n   None
 *
 *   @b Modifies
 *   @n   None
 *
 *   @b Example
 *   @verbatim
            CSL_DspmmuHandle            hDspmmu;
            CSL_DspmmuPrefetchStatus    prefetchStatus;
            ...
            prefetchStatus = CSL_dspmmuIsPrefetchOn (hDspMmu);
     @endverbatim
 * ============================================================================
 */

static inline
CSL_DspmmuPrefetchStatus CSL_dspmmuIsPrefetchOn (
    CSL_DspmmuHandle        hDspmmu
)
{
    return ((CSL_DspmmuPrefetchStatus)
            CSL_FEXT(hDspmmu->regs->WALKING_ST_REG, \
                     DSPMMU_WALKING_ST_REG_PREFETCH_ON));
}

/** ===========================================================================
 *   @n@b CSL_dspmmuGetFaultInfo
 *
 *   @b Description
 *   @n This function gets the information regarding the cause of the fault
 *
 *   @b Arguments
 *   @verbatim
            hDspmmu         Handle to the DSP MMU instance
            fltinfo         Pointer to fault info structure
     @endverbatim
 *
 *   <b> Return Value </b>  void
 *
 *   <b> Pre Condition </b>
 *   @n   None
 *
 *   <b> Post Condition </b>
 *   @n   None
 *
 *   @b Modifies
 *   @n   None
 *
 *   @b Example
 *   @verbatim
            CSL_DspmmuHandle            hDspmmu;
            CSL_DspmmuFltInfo           faultinfo;
            ...
            CSL_dspmmuGetFaultInfo (hDspMmu, &faultInfo);
     @endverbatim
 * ============================================================================
 */

static inline
void CSL_dspmmuGetFaultInfo (
    CSL_DspmmuHandle        hDspmmu,
    CSL_DspmmuFltInfo *     fltinfo
)
{
    Uint32  address = 0;
    fltinfo->faultEventType = (Uint16)(hDspmmu->regs->FAULT_ST_REG & 0x000F);

    if (CSL_PERMISSION_FAULT & fltinfo->faultEventType)
    {
        address = hDspmmu->regs->FAULT_AD_H_REG;
        address = (address << 16) | hDspmmu->regs->FAULT_AD_L_REG;
        fltinfo->faultAddr = address;
    }
}

/** ===========================================================================
 *   @n@b CSL_dspmmuGetCamramEntry
 *
 *   @b Description
 *   @n This function gets the cama ram info of a TLB
 *
 *   @b Arguments
 *   @verbatim
            hDspmmu         Handle to the DSP MMU instance
            camRamEntry     Pointer to cam ram entry structure
     @endverbatim
 *
 *   <b> Return Value </b>  void
 *
 *   <b> Pre Condition </b>
 *   @n   None
 *
 *   <b> Post Condition </b>
 *   @n   None
 *
 *   @b Modifies
 *   @n   None
 *
 *   @b Example
 *   @verbatim
            CSL_DspmmuHandle            hDspmmu;
            CSL_DspmmuCamramEntry       tlbCamramEntry;
            ...
            CSL_dspmmuGetCamramEntry (hDspMmu, &tlbCamramEntry);
     @endverbatim
 * ============================================================================
 */

static inline
void CSL_dspmmuGetCamramEntry (
    CSL_DspmmuHandle            hDspmmu,
    CSL_DspmmuQueryCamramEntry *     camRamEntry
)
{
    Uint16 wtlState;
    Uint32 phyAddress;
    Uint32 virtAddress;
	CSL_DspmmuTlbEntry *tlbEntry = &camRamEntry->tlbEntry;

    /* disable the WTL, if enabled */
    wtlState = CSL_FEXT(hDspmmu->regs->CNTL_REG, DSPMMU_CNTL_REG_WTL_EN);
    CSL_FINS(hDspmmu->regs->CNTL_REG, DSPMMU_CNTL_REG_WTL_EN, 0);

	/* set the victim pointer */
    CSL_FINS(hDspmmu->regs->LOCK_REG, DSPMMU_LOCK_REG_CURRENT_VICTIM,
    										camRamEntry->index);

	/* set the read bit */
    CSL_FINS(hDspmmu->regs->LD_TLB_REG, DSPMMU_LD_TLB_REG_READ_TLB_ITEM, 1);

	/* read the RAM registers to get the physical address */
	phyAddress = (CSL_FEXT (hDspmmu->regs->READ_RAM_H_REG,
			DSPMMU_READ_RAM_H_REG_RAM_MSB)) << CSL_DSPMMU_PHY_ADDR_MSB_SHIFT;

	phyAddress |= (hDspmmu->regs->READ_RAM_L_REG &
			CSL_DSPMMU_READ_RAM_L_REG_RAM_LSB_MASK);

	tlbEntry->phyAddr = (void*) phyAddress;

	tlbEntry->apBit = (CSL_DspmmuAccessType) CSL_FEXT (
				hDspmmu->regs->READ_RAM_L_REG, DSPMMU_RAM_L_REG_AP);

	/* read the CAM registers */
	/* Extract the virtual address level 1 index */
	virtAddress = (CSL_FEXT (hDspmmu->regs->READ_CAM_H_REG,
			DSPMMU_READ_CAM_H_REG_VA_TAG_L1_H)) << CSL_DSPMMU_VADDR_L1_H_SHIFT;

	virtAddress |= CSL_FEXT (hDspmmu->regs->READ_CAM_L_REG,
			DSPMMU_READ_CAM_L_REG_VA_TAG_L1_L);

	virtAddress = virtAddress << CSL_DSPMMU_VADDR_L1_SHIFT;

	/* Extract the level 2 index */
	virtAddress |= (CSL_FEXT (hDspmmu->regs->READ_CAM_L_REG,
			DSPMMU_READ_CAM_L_REG_VA_TAG_L2)) << CSL_DSPMMU_VADDR_L2_SHIFT;

	tlbEntry->virtualAddr = virtAddress;

	/* Extract the other bits */
	tlbEntry->pBit = (CSL_DspmmuPreservedBit) CSL_FEXT (
				hDspmmu->regs->READ_CAM_L_REG, DSPMMU_READ_CAM_L_REG_P);
	tlbEntry->slstBit = (CSL_DspmmuPageType) CSL_FEXT (
				hDspmmu->regs->READ_CAM_L_REG, DSPMMU_READ_CAM_L_REG_SLST);
	tlbEntry->valid = (CSL_DspmmuValidBit) CSL_FEXT (
				hDspmmu->regs->READ_CAM_L_REG, DSPMMU_READ_CAM_L_REG_V);

	/* restore the WTL state */
    CSL_FINS(hDspmmu->regs->CNTL_REG, DSPMMU_CNTL_REG_WTL_EN, wtlState);
}

#ifdef __cplusplus
}
#endif


#endif  /* _CSL_DSPMMUAUX_H_ */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?