/* file: L2CacheTest2.s - defines L2 cache functions * Modification history * -------------------- * 15Sep98,My Added autosize for 256K backside, and detect MPC740. * 31Jul98,My&RGP Created * 5May2000, TPeters Pulled from VxWorks for stand alone demo for DINK32 */ /* includes */ #include "l2sizing.h" /* globals */ .globl sysL2BackGlobalInv .globl sysL2BackDisable .globl sysL2BackEnable .globl sysL2BackAutoSize .globl sysL1DcacheEnable .globl sysL1DcacheDisable .globl sysL2CRWrite .globl sysL2CRRead .globl sysPVRRead /********************************************************************* * sysL2BackGlobalInv - Globally invalidate L2 backside cache * This function reads the value of the l2cr register, disables * the cache, before setting the global invalidate bit. It waits * for the L2CR[L2IP] bit is clear before returning to the caller. * Input - None * Return - None */ sysL2BackGlobalInv: sync mfspr r3, L2CR_REG // read L2CR register lis r4,L2CR_DISABLE_MASK@h // setup mask 0x7fffffff ori r4,r4,L2CR_DISABLE_MASK@l and r3,r3,r4 // clear enable bit mtspr L2CR_REG, r3 // write L2CR value sync oris r3, r3, L2CR_GLOBAL_INV_U // Set global invalidate bit mtspr L2CR_REG, r3 sync /* Monitoring the L2CR[L2IP] bit to determine when the global * invalidation operation is completed. */ invalidate_in_progress: mfspr r3, L2CR_REG andi. r3, r3, 0x1 //still invalidating? bne invalidate_in_progress mfspr r3, L2CR_REG lis r4,0xffdf //clear L2I bit ori r4,r4,0xffff and r3,r3,r4 mtspr L2CR_REG,r3 sync blr /********************************************************************* * sysL2BackEnable - Enable L2 backside cache * Input - None * return - None */ sysL2BackEnable: mfspr r3,L2CR_REG oris r3, r3, L2CR_EN_U // Set the L2E bit mtspr L2CR_REG, r3 // Store to L2CR register blr /********************************************************************* * sysL2BackDisable - Disable the L2 backside cache * The value of the l2cr register is read, the enable bit is * disabled and written back to the l2cr register. * Input - None * Output - None */ sysL2BackDisable: sync mfspr r3, L2CR_REG // Read L2 control register lis r4,L2CR_DISABLE_MASK@h // setup mask 0x7fffffff ori r4,r4,L2CR_DISABLE_MASK@l and r3,r3,r4 // clear L2E bit mtspr L2CR_REG, r3 sync blr /********************************************************************* * sysL2BackAutoSize - Autosize L2 Backside cache * L2 backside cache is available in MPC750 only. The L2 cache size * could be 1M, 512K, or 256K. The size is programmed in the L2CR * register. To detect the correct size, this function assumes that * the L2 cache size is 1M, the cache is put in test mode so that a * cache flush operation (dcbf) will write from L1 cache to L2. 1M * of data is written to memory, then read back. If the cache size * is truely 1M, all data read back will be correct as expected. If * the cache size is 512 KB, half of the data will be correct, and * the other half is not, and so on. Once the size is determined, * the value that must be set in L2CR when the L2 backside cache is * enabled is stored in r3. * * There is no real way to distinguish MPC740 and MPC750; they both * have the same PRV number. After writing to L2 backside cache, if * the result is neither 1M, 512 KB, or 256 KB, it must be MPC740 * (no L2 backside cache, r3 is set to 0). * * Input - Cache size to test in r3 * Output - Value of L2CR is set in r3. */ sysL2BackAutoSize: xor r0, r0, r0 /* clear r0 */ andi. r5, r0, 0x0 /* clear r5 */ andi. r3, r0, 0x0 /* clear r3 */ addis r4, r0, 0x0 /* Count index reg. */ addis r6, r0, WRITE_ADDR_U /* Address to start writing */ addis r5, r0, L2_SIZE_1M_U /* Memory chunk size */ l2SzWriteLoop: dcbz r4, r6 /* zero out the cache line */ stwx r4, r4, r6 /* write index to a cache line */ dcbf r4, r6 /* flush cache to L2 */ addi r4, r4, L2_ADR_INCR /* Increase the address index */ cmp 0, 0, r4, r5 blt l2SzWriteLoop addis r4, r0, 0x0 /* Count index reg. - reset to 0 */ l2SzReadLoop: lwzx r7, r4, r6 /* Load a word from the cache line */ cmp 0, 0, r4, r7 /* Same as indexing value ? */ bne l2SkipCount addi r3, r3, 0x1 /* Count cache line read correctly */ l2SkipCount: dcbi r4, r6 /* Invalidate the cache line */ addi r4, r4, L2_ADR_INCR /* increase the address index */ cmp 0, 0, r4, r5 /* Any memory space to read ? */ blt l2SzReadLoop addi r7, r0, 0x3 cmpi 0, 0, r3, L2_SIZE_1M /* 1M L2 backside cache? */ beq l2AutoSizeDone addi r7, r0, 0x2 cmpi 0, 0, r3, L2_SIZE_HM /* 512K L2 backside cache? */ beq l2AutoSizeDone addi r7, r0, 0x1 cmpi 0, 0, r3, L2_SIZE_QM /* 256K L2 backside cache? */ beq l2AutoSizeDone addis r7, r0, 0x0 /* No L2 cache */ l2AutoSizeDone: addi r3, r7, 0x0 blr /********************************************************************** * sysPVRRead - Read the content of the PVR register * Once the PVR is read, the 16 least significant bits are shifted * off. * Input - None * Return - upper 16 bits of PVR stored in r3 */ sysPVRRead: mfspr r4, PVR_REG // read PVR li r3, 16 // shift 16 bits srw r3, r4, r3 // shift off the least 16 bits blr /********************************************************************** * sysL2CRWrite - Write a value to the L2CR register * Input - value in R3 * */ sysL2CRWrite: mtspr L2CR_REG, r3 blr /********************************************************************** * sysL2CRRead - Read the L2CR register * Input - None * Outupt - L2CR value * */ sysL2CRRead: mfspr r3,L2CR_REG blr /********************************************************************** * sysL1DcacheEnable - Enable the L1 Dcache * Input - None * Return - None */ sysL1DcacheEnable: mfspr r5,HID0_REG /* turn on the D cache. */ ori r5,r5,L1_DCACHE_ENABLE /* Data cache only! */ mtspr HID0_REG,r5 isync sync blr /********************************************************************** * sysL1DcacheDisable - Disable the L1 Dcache * Input - None * Return - None */ sysL1DcacheDisable: mfspr r5,HID0_REG lis r4,0xffff ori r4,r4,L1_DCACHE_DISABLE and r5,r5,r4 mtspr HID0_REG,r5 isync sync blr