3.4.1. Locking down the caches

The procedures for locking down a segment in the ICache and DCache are slightly different. In both cases you must:

  1. Put the cache into lockdown mode by programming register 9.

  2. Force a linefill.

  3. Lock the corresponding data in the cache.

DCache lockdown

For the DCache, the procedure is as follows:

  1. Write to CP15 register 9, setting DL=1 (DL is bit 31, the load bit) and Dindex=0 (Dindex are bits 1:0, the cache segment bits).

  2. Initialize the pointer to the first of the words to be locked into the cache.

  3. Execute an LDR from that location. This forces a linefill from that location and the resulting eight words are captured in the cache.

  4. Increment the pointer by 32 (number of bytes in a cache line).

  5. Execute an LDR from that location. The resulting linefill is captured in the cache.

  6. Repeat steps 4 and 5 until all words are loaded in the cache, or one quarter of the cache has been loaded.

  7. Write to CP15 register 9, setting DL=0 and Dindex=1.

If there is more data to lockdown, at the final step, the DL bit must be left HIGH and the process repeated. The DL bit must only be set LOW when all the lockdown data has been loaded. The Dindex bits must be set to the next available segment.

Note

The write to CP15 register 9 must not be executed until the linefill has completed. This is achieved by aligning the LDR to the last address of the line.

ICache lockdown

For the ICache, the procedure is as follows:

  1. Write to CP15 register 9, setting IL=1 (the load bit) and Iindex=0 (the cache segment bits).

  2. Initialize the pointer to the first of the words to be locked into the cache.

  3. Force a linefill from that location by writing to CP15 register 7 (ICache preload).

  4. Increment the pointer by 32 (number of bytes in a cache line).

  5. Force a linefill from that location by writing to CP15 register 7. The resulting linefill is captured in the ICache.

  6. Repeat steps 4 and 5 until all words are loaded in the cache, or one quarter of the cache has been loaded.

  7. Write to CP15 register 9, setting IL=0 and Iindex=1.

If there are more instructions to lockdown, at the final step, the IL bit must be left HIGH and the process repeated. The IL bit must only be set LOW when all the lockdown instructions have been loaded. The Iindex bits must be set to the next available segment.

The only significant difference between the sequence of operations for the DCache and ICache is that an MCR instruction must be used to force the linefill in the ICache, instead of an LDR. The rest of the sequence is the same as for DCache lockdown.

The MCR to perform the ICache fetch is a CP15 register 7 operation:

	MCR 	p15, 0, Rd, c7, c13, 1

Example ICache lockdown subroutine

A subroutine that you can use to lock down code in the ICache is:

; Subroutine lock_i_cache
; r1 contains the start address
; r2 contains the end address
; Assumes that r2 - r1 fits within one cache set
; The subroutine performs a lockdown of instructions in the
; instruction cache
; It first reads the current lock_down index and then locks
; down the number of sets required
; Note - This subroutine must be located in a noncachable
;        region of memory
;      - Interrupts must be disabled
;      - Subroutine must be called using the BL instruction
;      - r1-r3 can be corrupted in line with ARM/Thumb
;        Procedure Call Standards (ATPCS)
;      - Returns final ICache lockdown index in r0 if successful
;      - Returns 0xFFFFFFFF in r0 if an error occurred

lock_I_cache
	BIC	r1, r1, #0x7f						;Align address to cache line
	MRC	p15, 0, r3, c9, c0, 1						;Get current ICache index
	AND	r3, r3, #0x3						;Mask unwanted bits
	CMP	r3, #0x3						;Check for available set
	BEQ	error						;If no sets available,
								;generate an error
	ORR     r3, r3, #0x8000000							;Set the lockdown bit
	MCR     p15, 0, r3, c9, c0, 1							;Write lockdown register

lock_loop
	MCR	p15, 0, r1, c7, c13, 1						;Force an instruction fetch
								;from address r1
	ADD	r1, r1, #0x20						;Increment address by a
								;cache line length
	CMP	r2, r1						;Reached our end address yet?
	BLT	lock_loop						;If not, repeat loop
	ADD	r3, r3, #0x1						;Increment ICache index
	BIC	r0, r3, #0x8000000						;Clear lockdown bit and
								;Write index into r0
	MCR	p15, 0, r3, c9, c0, 1						;Write lockdown register
	MOV	pc, lr						;Return from subroutine

error
	MVN	r0, #0						;Move 0xFFFFFFFF into r0
	MOV	pc, lr						;Return from subroutine


Copyright © 2000 ARM Limited. All rights reserved.ARM DDI 0155A
Non-Confidential