Some fixes/cleanup to the XScale cache clean code:

* Define a CPWAIT macro as described in the i80200 manual and use it,
  rather than replicating the code in a few places.
* The i80200 manual notes that the line-allocate operation used to
  do global D$ clean does not actually perform a load/fill request
  from external memory, and thus does not actually place valid data
  in the cache lines allocated.  Require that machine-dependent code
  allocate an appropriately-sized chunk of unmapped VA space for the
  global clean operation in order to avoid unpredictable results.
* The i80200 manual notes that the VA range for the Mini-Data global
  clean (which *must* be mapped to physical memory) must be reserved
  exclusively for cleaning the Mini-Data cache.  Require that machine-
  dependent code allocate an appropriately-sized chunk of memory for
  this purpose.
This commit is contained in:
thorpej 2001-11-11 17:18:27 +00:00
parent 4ffa983428
commit b75edaf367
1 changed files with 39 additions and 12 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpufunc_asm_xscale.S,v 1.2 2001/11/11 01:05:11 thorpej Exp $ */
/* $NetBSD: cpufunc_asm_xscale.S,v 1.3 2001/11/11 17:18:27 thorpej Exp $ */
/*
* Copyright (c) 2001 Matt Thomas
@ -42,6 +42,17 @@
Lblock_userspace_access:
.word _C_LABEL(block_userspace_access)
/*
* CPWAIT -- Canonical method to wait for CP15 update.
* From: Intel 80200 manual, section 2.3.3.
*
* NOTE: Clobbers r0.
*/
#define CPWAIT \
mrc p15, 0, r0, c2, c0, 0 /* arbitrary read of CP15 */ ;\
mov r0, r0 /* wait for it to complete */ ;\
sub pc, pc, #4 /* branch to next insn */
/*
* Functions to set the MMU Translation Table Base register
*
@ -74,10 +85,7 @@ ENTRY(xscale_setttb)
/* The cleanID above means we only need to flush the I cache here */
mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ and BTB */
/* Make sure that pipeline is emptied */
mrc p15, 0, r0, c2, c0, 0 /* read some register in CP15 */
mov r0, r0 /* force read to complete */
sub pc, pc, #4 /* branch to next instruction */
CPWAIT
#ifdef CACHE_CLEAN_BLOCK_INTR
msr cpsr_all, r3
@ -128,17 +136,33 @@ ENTRY(xscale_cache_cleanD_E)
*
* * Virtual address of the memory region to use
* * Size of memory region
*
* Note the virtual address for the Data cache clean operation
* does not need to be backed by physical memory, since no loads
* will actually be performed by the allocate-line operation.
*
* Note that the Mini-Data cache MUST be cleaned by executing
* loads from memory mapped into a region reserved exclusively
* for cleaning of the Mini-Data cache.
*/
.data
.global _C_LABEL(xscale_cache_clean_addr)
_C_LABEL(xscale_cache_clean_addr):
.word 0xf0000000
.word 0x00000000
.global _C_LABEL(xscale_cache_clean_size)
_C_LABEL(xscale_cache_clean_size):
.word 0x00008000
.global _C_LABEL(xscale_minidata_clean_addr)
_C_LABEL(xscale_minidata_clean_addr):
.word 0x00000000
.global _C_LABEL(xscale_minidata_clean_size)
_C_LABEL(xscale_minidata_clean_size):
.word 0x00000800
.text
Lxscale_cache_clean_addr:
@ -146,6 +170,11 @@ Lxscale_cache_clean_addr:
Lxscale_cache_clean_size:
.word _C_LABEL(xscale_cache_clean_size)
Lxscale_minidata_clean_addr:
.word _C_LABEL(xscale_minidata_clean_addr)
Lxscale_minidata_clean_size:
.word _C_LABEL(xscale_minidata_clean_size)
#ifdef CACHE_CLEAN_BLOCK_INTR
#define XSCALE_CACHE_CLEAN_BLOCK \
mrs r3, cpsr_all ; \
@ -195,9 +224,10 @@ ENTRY(xscale_cache_cleanD)
* kernel addresses, so there is no need to purge it on
* context switch.
*/
mov r1, #64
ldr r2, Lxscale_minidata_clean_addr
ldmia r2, {r0, r1}
1: ldr r3, [r0], #32
subs r1, r1, #1
subs r1, r1, #32
bne 1b
#endif
@ -319,9 +349,6 @@ ENTRY(xscale_context_switch)
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */
/* Make sure that pipeline is emptied */
mrc p15, 0, r0, c2, c0, 0 /* read some register in CP15 */
mov r0, r0 /* force the read to complete */
sub pc, pc, #4 /* branch to next instruction */
CPWAIT
mov pc, lr