mirror of https://github.com/acidanthera/audk.git
97 lines
3.7 KiB
ArmAsm
97 lines
3.7 KiB
ArmAsm
//++
|
|
// Copyright (c) 2006, Intel Corporation
|
|
// All rights reserved. This program and the accompanying materials
|
|
// are licensed and made available under the terms and conditions of the BSD License
|
|
// which accompanies this distribution. The full text of the license may be found at
|
|
// http://opensource.org/licenses/bsd-license.php
|
|
//
|
|
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
//
|
|
// Module Name:
|
|
// FlushCacheRange.s
|
|
//
|
|
// Abstract:
|
|
// Assemble routine to flush cache lines
|
|
//
|
|
// Revision History:
|
|
//
|
|
//--
|
|
.file "IpfCpuCache.s"
|
|
|
|
#include "IpfMacro.i"
|
|
//#include "IpfDefines.h"
|
|
|
|
//
|
|
// Invalidates a range of instruction cache lines in the cache coherency domain
|
|
// of the calling CPU.
|
|
//
|
|
// Invalidates the instruction cache lines specified by Address and Length. If
|
|
// Address is not aligned on a cache line boundary, then entire instruction
|
|
// cache line containing Address is invalidated. If Address + Length is not
|
|
// aligned on a cache line boundary, then the entire instruction cache line
|
|
// containing Address + Length -1 is invalidated. This function may choose to
|
|
// invalidate the entire instruction cache if that is more efficient than
|
|
// invalidating the specified range. If Length is 0, the no instruction cache
|
|
// lines are invalidated. Address is returned.
|
|
//
|
|
// If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
|
|
//
|
|
// @param Address The base address of the instruction cache lines to
|
|
// invalidate. If the CPU is in a physical addressing mode, then
|
|
// Address is a physical address. If the CPU is in a virtual
|
|
// addressing mode, then Address is a virtual address.
|
|
//
|
|
// @param Length The number of bytes to invalidate from the instruction cache.
|
|
//
|
|
// @return Address
|
|
//
|
|
// VOID *
|
|
// EFIAPI
|
|
// IpfFlushCacheRange (
|
|
// IN VOID *Address,
|
|
// IN UINTN Length
|
|
// );
|
|
//
|
|
PROCEDURE_ENTRY (IpfFlushCacheRange)
|
|
|
|
NESTED_SETUP (5,8,0,0)
|
|
|
|
mov loc2 = ar.lc
|
|
|
|
mov loc3 = in0 // Start address.
|
|
mov loc4 = in1;; // Length in bytes.
|
|
|
|
cmp.eq p6,p7 = loc4, r0;; // If Length is zero then don't flush any cache
|
|
(p6) br.spnt.many DoneFlushingC;;
|
|
|
|
add loc4 = loc4,loc3
|
|
mov loc5 = 1;;
|
|
sub loc4 = loc4, loc5 ;; // the End address to flush
|
|
|
|
dep loc3 = r0,loc3,0,5
|
|
dep loc4 = r0,loc4,0,5;;
|
|
shr loc3 = loc3,5
|
|
shr loc4 = loc4,5;; // 32 byte cache line
|
|
|
|
sub loc4 = loc4,loc3;; // total flush count, It should be add 1 but
|
|
// the br.cloop will first execute one time
|
|
mov loc3 = in0
|
|
mov loc5 = 32
|
|
mov ar.lc = loc4;;
|
|
|
|
StillFlushingC:
|
|
fc loc3;;
|
|
sync.i;;
|
|
srlz.i;;
|
|
add loc3 = loc5,loc3;;
|
|
br.cloop.sptk.few StillFlushingC;;
|
|
|
|
DoneFlushingC:
|
|
mov ar.lc = loc2
|
|
mov r8 = in0 // return *Address
|
|
NESTED_RETURN
|
|
|
|
PROCEDURE_EXIT (IpfFlushCacheRange)
|
|
|