1b341712e314a6161120c30d41e6308bc6aeb2213qhuang#/*++ 2b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 34ea9375a2d02a43671437e0d3d808d85afb30afahhtian#Copyright (c) 2006, Intel Corporation. All rights reserved.<BR> 44ea9375a2d02a43671437e0d3d808d85afb30afahhtian#This program and the accompanying materials 5b341712e314a6161120c30d41e6308bc6aeb2213qhuang#are licensed and made available under the terms and conditions of the BSD License 6b341712e314a6161120c30d41e6308bc6aeb2213qhuang#which accompanies this distribution. The full text of the license may be found at 7b341712e314a6161120c30d41e6308bc6aeb2213qhuang#http://opensource.org/licenses/bsd-license.php 8b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 9b341712e314a6161120c30d41e6308bc6aeb2213qhuang#THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10b341712e314a6161120c30d41e6308bc6aeb2213qhuang#WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 12b341712e314a6161120c30d41e6308bc6aeb2213qhuang#Module Name: 13b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 14b341712e314a6161120c30d41e6308bc6aeb2213qhuang# EfiCopyMem.c 15b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 16b341712e314a6161120c30d41e6308bc6aeb2213qhuang#Abstract: 17b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 18b341712e314a6161120c30d41e6308bc6aeb2213qhuang# This is the code that supports IA32-optimized CopyMem service 19b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 20b341712e314a6161120c30d41e6308bc6aeb2213qhuang#--*/ 21b341712e314a6161120c30d41e6308bc6aeb2213qhuang#include "EfiBind.h" 22b341712e314a6161120c30d41e6308bc6aeb2213qhuang#--------------------------------------------------------------------------- 23b341712e314a6161120c30d41e6308bc6aeb2213qhuang .686: 24b341712e314a6161120c30d41e6308bc6aeb2213qhuang #.MODEL flat,C 25b341712e314a6161120c30d41e6308bc6aeb2213qhuang .mmx: 26b341712e314a6161120c30d41e6308bc6aeb2213qhuang .code: 27b341712e314a6161120c30d41e6308bc6aeb2213qhuang 28b341712e314a6161120c30d41e6308bc6aeb2213qhuang#--------------------------------------------------------------------------- 29b341712e314a6161120c30d41e6308bc6aeb2213qhuang 30b341712e314a6161120c30d41e6308bc6aeb2213qhuang.globl ASM_PFX(EfiCommonLibCopyMem) 31b341712e314a6161120c30d41e6308bc6aeb2213qhuang 32b341712e314a6161120c30d41e6308bc6aeb2213qhuang#VOID 33b341712e314a6161120c30d41e6308bc6aeb2213qhuang#EfiCommonLibCopyMem ( 34b341712e314a6161120c30d41e6308bc6aeb2213qhuang# IN VOID *Destination, 35b341712e314a6161120c30d41e6308bc6aeb2213qhuang# IN VOID *Source, 36b341712e314a6161120c30d41e6308bc6aeb2213qhuang# IN UINTN Count 37b341712e314a6161120c30d41e6308bc6aeb2213qhuang# ) 38b341712e314a6161120c30d41e6308bc6aeb2213qhuang#/*++ 39b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 40b341712e314a6161120c30d41e6308bc6aeb2213qhuang#Routine Description: 41b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 42b341712e314a6161120c30d41e6308bc6aeb2213qhuang# Copy Length bytes from Source to Destination. 43b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 44b341712e314a6161120c30d41e6308bc6aeb2213qhuang#Arguments: 45b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 46b341712e314a6161120c30d41e6308bc6aeb2213qhuang# Destination - Target of copy 47b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 48b341712e314a6161120c30d41e6308bc6aeb2213qhuang# Source - Place to copy from 49b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 50b341712e314a6161120c30d41e6308bc6aeb2213qhuang# Length - Number of bytes to copy 51b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 52b341712e314a6161120c30d41e6308bc6aeb2213qhuang#Returns: 53b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 54b341712e314a6161120c30d41e6308bc6aeb2213qhuang# None 55b341712e314a6161120c30d41e6308bc6aeb2213qhuang# 56b341712e314a6161120c30d41e6308bc6aeb2213qhuang#--*/ 57b341712e314a6161120c30d41e6308bc6aeb2213qhuangASM_PFX(EfiCommonLibCopyMem): 58b341712e314a6161120c30d41e6308bc6aeb2213qhuang 59b341712e314a6161120c30d41e6308bc6aeb2213qhuang pushl %ebp 60b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl %esp, %ebp 61b341712e314a6161120c30d41e6308bc6aeb2213qhuang pushl %ecx # reserve space for Scratch Local variable UINT64 MmxSave 62b341712e314a6161120c30d41e6308bc6aeb2213qhuang pushl %ecx 63b341712e314a6161120c30d41e6308bc6aeb2213qhuang pushl %esi 64b341712e314a6161120c30d41e6308bc6aeb2213qhuang pushl %edi 65b341712e314a6161120c30d41e6308bc6aeb2213qhuang 66b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl 0x10(%ebp), %ecx # Count 67b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl 0xC(%ebp), %esi # Source 68b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl 8(%ebp), %edi # Destination 69b341712e314a6161120c30d41e6308bc6aeb2213qhuang 70b341712e314a6161120c30d41e6308bc6aeb2213qhuang##First off, make sure we have no overlap. That is to say, 71b341712e314a6161120c30d41e6308bc6aeb2213qhuang## if (Source == Destination) => do nothing 72b341712e314a6161120c30d41e6308bc6aeb2213qhuang## if (Source + Count <= Destination) => regular copy 73b341712e314a6161120c30d41e6308bc6aeb2213qhuang## if (Destination + Count <= Source) => regular copy 74b341712e314a6161120c30d41e6308bc6aeb2213qhuang## otherwise, do a reverse copy 75b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl %esi, %eax 76b341712e314a6161120c30d41e6308bc6aeb2213qhuang addl %ecx, %eax # Source + Count 77b341712e314a6161120c30d41e6308bc6aeb2213qhuang cmpl %edi, %eax 783e99020dbf0a159e34b84e7ae9125f2e368d5390lgao jbe _StartByteCopy 79b341712e314a6161120c30d41e6308bc6aeb2213qhuang 80b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl %edi, %eax 81b341712e314a6161120c30d41e6308bc6aeb2213qhuang addl %ecx, %eax # Dest + Count 82b341712e314a6161120c30d41e6308bc6aeb2213qhuang cmpl %esi, %eax 833e99020dbf0a159e34b84e7ae9125f2e368d5390lgao jbe _StartByteCopy 84b341712e314a6161120c30d41e6308bc6aeb2213qhuang 85b341712e314a6161120c30d41e6308bc6aeb2213qhuang cmpl %edi, %esi 86b341712e314a6161120c30d41e6308bc6aeb2213qhuang je _CopyMemDone 873e99020dbf0a159e34b84e7ae9125f2e368d5390lgao jb _CopyOverlapped # too bad -- overlaps 88b341712e314a6161120c30d41e6308bc6aeb2213qhuang 89b341712e314a6161120c30d41e6308bc6aeb2213qhuang # Pick up misaligned start bytes to get destination pointer 4-byte aligned 90b341712e314a6161120c30d41e6308bc6aeb2213qhuang_StartByteCopy: 91b341712e314a6161120c30d41e6308bc6aeb2213qhuang cmpl $0, %ecx 92b341712e314a6161120c30d41e6308bc6aeb2213qhuang je _CopyMemDone # Count == 0, all done 93b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl %edi, %edx 94b341712e314a6161120c30d41e6308bc6aeb2213qhuang andb $3, %dl # check lower 2 bits of address 95b341712e314a6161120c30d41e6308bc6aeb2213qhuang testb %dl, %dl 96b341712e314a6161120c30d41e6308bc6aeb2213qhuang je _CopyBlocks # already aligned? 97b341712e314a6161120c30d41e6308bc6aeb2213qhuang 98b341712e314a6161120c30d41e6308bc6aeb2213qhuang # Copy a byte 99b341712e314a6161120c30d41e6308bc6aeb2213qhuang movb (%esi), %al # get byte from Source 100b341712e314a6161120c30d41e6308bc6aeb2213qhuang movb %al, (%edi) # write byte to Destination 101b341712e314a6161120c30d41e6308bc6aeb2213qhuang decl %ecx 102b341712e314a6161120c30d41e6308bc6aeb2213qhuang incl %edi 103b341712e314a6161120c30d41e6308bc6aeb2213qhuang incl %esi 104b341712e314a6161120c30d41e6308bc6aeb2213qhuang jmp _StartByteCopy # back to top of loop 105b341712e314a6161120c30d41e6308bc6aeb2213qhuang 106b341712e314a6161120c30d41e6308bc6aeb2213qhuang_CopyBlocks: 107b341712e314a6161120c30d41e6308bc6aeb2213qhuang # Compute how many 64-byte blocks we can clear 108b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl %ecx, %eax # get Count in eax 109b341712e314a6161120c30d41e6308bc6aeb2213qhuang shrl $6, %eax # convert to 64-byte count 110b341712e314a6161120c30d41e6308bc6aeb2213qhuang shll $6, %eax # convert back to bytes 111b341712e314a6161120c30d41e6308bc6aeb2213qhuang subl %eax, %ecx # subtract from the original count 112b341712e314a6161120c30d41e6308bc6aeb2213qhuang shrl $6, %eax # and this is how many 64-byte blocks 113b341712e314a6161120c30d41e6308bc6aeb2213qhuang 114b341712e314a6161120c30d41e6308bc6aeb2213qhuang # If no 64-byte blocks, then skip 115b341712e314a6161120c30d41e6308bc6aeb2213qhuang cmpl $0, %eax 116b341712e314a6161120c30d41e6308bc6aeb2213qhuang je _CopyRemainingDWords 117b341712e314a6161120c30d41e6308bc6aeb2213qhuang 118b341712e314a6161120c30d41e6308bc6aeb2213qhuang # Save mm0 to UINT64 MmxSave 119b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %mm0, -8(%ebp) 120b341712e314a6161120c30d41e6308bc6aeb2213qhuang 121b341712e314a6161120c30d41e6308bc6aeb2213qhuangcopymmx: 122b341712e314a6161120c30d41e6308bc6aeb2213qhuang 123b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %ds:(%esi), %mm0 124b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %mm0, %ds:(%edi) 125b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %ds:8(%esi), %mm0 126b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %mm0, %ds:8(%edi) 127b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %ds:16(%esi), %mm0 128b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %mm0, %ds:16(%edi) 129b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %ds:24(%esi), %mm0 130b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %mm0, %ds:24(%edi) 131b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %ds:32(%esi), %mm0 132b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %mm0, %ds:32(%edi) 133b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %ds:40(%esi), %mm0 134b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %mm0, %ds:40(%edi) 135b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %ds:48(%esi), %mm0 136b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %mm0, %ds:48(%edi) 137b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %ds:56(%esi), %mm0 138b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq %mm0, %ds:56(%edi) 139b341712e314a6161120c30d41e6308bc6aeb2213qhuang 140b341712e314a6161120c30d41e6308bc6aeb2213qhuang addl $64, %edi 141b341712e314a6161120c30d41e6308bc6aeb2213qhuang addl $64, %esi 142b341712e314a6161120c30d41e6308bc6aeb2213qhuang decl %eax 143b341712e314a6161120c30d41e6308bc6aeb2213qhuang jnz copymmx 144b341712e314a6161120c30d41e6308bc6aeb2213qhuang 145b341712e314a6161120c30d41e6308bc6aeb2213qhuang# Restore mm0 from MmxSave 146b341712e314a6161120c30d41e6308bc6aeb2213qhuang movq -8(%ebp), %mm0 147b341712e314a6161120c30d41e6308bc6aeb2213qhuang emms # Exit MMX Instruction 148b341712e314a6161120c30d41e6308bc6aeb2213qhuang 149b341712e314a6161120c30d41e6308bc6aeb2213qhuang # Copy as many DWORDS as possible 150b341712e314a6161120c30d41e6308bc6aeb2213qhuang_CopyRemainingDWords: 151b341712e314a6161120c30d41e6308bc6aeb2213qhuang cmpl $4, %ecx 152b341712e314a6161120c30d41e6308bc6aeb2213qhuang jb _CopyRemainingBytes 153b341712e314a6161120c30d41e6308bc6aeb2213qhuang 154b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl (%esi), %eax # get data from Source 155b341712e314a6161120c30d41e6308bc6aeb2213qhuang movl %eax, (%edi) # write byte to Destination 156b341712e314a6161120c30d41e6308bc6aeb2213qhuang subl $4, %ecx # decrement Count 157b341712e314a6161120c30d41e6308bc6aeb2213qhuang addl $4, %esi # advance Source pointer 158b341712e314a6161120c30d41e6308bc6aeb2213qhuang addl $4, %edi # advance Destination pointer 159b341712e314a6161120c30d41e6308bc6aeb2213qhuang jmp _CopyRemainingDWords # back to top 160b341712e314a6161120c30d41e6308bc6aeb2213qhuang 161b341712e314a6161120c30d41e6308bc6aeb2213qhuang_CopyRemainingBytes: 162b341712e314a6161120c30d41e6308bc6aeb2213qhuang cmpl $0, %ecx 163b341712e314a6161120c30d41e6308bc6aeb2213qhuang je _CopyMemDone 164b341712e314a6161120c30d41e6308bc6aeb2213qhuang movb (%esi), %al # get byte from Source 165b341712e314a6161120c30d41e6308bc6aeb2213qhuang movb %al, (%edi) # write byte to Destination 166b341712e314a6161120c30d41e6308bc6aeb2213qhuang decl %ecx 167b341712e314a6161120c30d41e6308bc6aeb2213qhuang incl %esi 168b341712e314a6161120c30d41e6308bc6aeb2213qhuang incl %edi # advance Destination pointer 169b341712e314a6161120c30d41e6308bc6aeb2213qhuang jmp _CopyRemainingBytes # back to top of loop 170b341712e314a6161120c30d41e6308bc6aeb2213qhuang 171b341712e314a6161120c30d41e6308bc6aeb2213qhuang # 172b341712e314a6161120c30d41e6308bc6aeb2213qhuang # We do this block if the source and destination buffers overlap. To 173b341712e314a6161120c30d41e6308bc6aeb2213qhuang # handle it, copy starting at the end of the source buffer and work 174b341712e314a6161120c30d41e6308bc6aeb2213qhuang # your way back. Since this is the atypical case, this code has not 175b341712e314a6161120c30d41e6308bc6aeb2213qhuang # been optimized, and thus simply copies bytes. 176b341712e314a6161120c30d41e6308bc6aeb2213qhuang # 177b341712e314a6161120c30d41e6308bc6aeb2213qhuang_CopyOverlapped: 178b341712e314a6161120c30d41e6308bc6aeb2213qhuang 179b341712e314a6161120c30d41e6308bc6aeb2213qhuang # Move the source and destination pointers to the end of the range 180b341712e314a6161120c30d41e6308bc6aeb2213qhuang addl %ecx, %esi # Source + Count 181b341712e314a6161120c30d41e6308bc6aeb2213qhuang decl %esi 182b341712e314a6161120c30d41e6308bc6aeb2213qhuang addl %ecx, %edi # Dest + Count 183b341712e314a6161120c30d41e6308bc6aeb2213qhuang decl %edi 184b341712e314a6161120c30d41e6308bc6aeb2213qhuang 185b341712e314a6161120c30d41e6308bc6aeb2213qhuang_CopyOverlappedLoop: 186b341712e314a6161120c30d41e6308bc6aeb2213qhuang cmpl $0, %ecx 187b341712e314a6161120c30d41e6308bc6aeb2213qhuang je _CopyMemDone 188b341712e314a6161120c30d41e6308bc6aeb2213qhuang movb (%esi), %al # get byte from Source 189b341712e314a6161120c30d41e6308bc6aeb2213qhuang movb %al, (%edi) # write byte to Destination 190b341712e314a6161120c30d41e6308bc6aeb2213qhuang decl %ecx 191b341712e314a6161120c30d41e6308bc6aeb2213qhuang decl %esi 192b341712e314a6161120c30d41e6308bc6aeb2213qhuang decl %edi 193b341712e314a6161120c30d41e6308bc6aeb2213qhuang jmp _CopyOverlappedLoop # back to top of loop 194b341712e314a6161120c30d41e6308bc6aeb2213qhuang 195b341712e314a6161120c30d41e6308bc6aeb2213qhuang_CopyMemDone: 196b341712e314a6161120c30d41e6308bc6aeb2213qhuang 197b341712e314a6161120c30d41e6308bc6aeb2213qhuang popl %edi 198b341712e314a6161120c30d41e6308bc6aeb2213qhuang popl %esi 199b341712e314a6161120c30d41e6308bc6aeb2213qhuang leave 200b341712e314a6161120c30d41e6308bc6aeb2213qhuang ret 201b341712e314a6161120c30d41e6308bc6aeb2213qhuang#EfiCommonLibCopyMem ENDP 202b341712e314a6161120c30d41e6308bc6aeb2213qhuang 203