x86: implement bss zero and data copy for application
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
bf5228ea56
commit
3d8aaf7099
1 changed files with 77 additions and 54 deletions
|
@ -211,27 +211,15 @@ __csSet:
|
||||||
movl $__data_rom_start, %esi /* DATA in ROM (src) */
|
movl $__data_rom_start, %esi /* DATA in ROM (src) */
|
||||||
movl $__data_num_words, %ecx /* Size of DATA in quad bytes */
|
movl $__data_num_words, %ecx /* Size of DATA in quad bytes */
|
||||||
|
|
||||||
#ifdef CONFIG_SSE
|
call _x86_data_copy
|
||||||
/* copy 16 bytes at a time using XMM until < 16 bytes remain */
|
|
||||||
|
|
||||||
movl %ecx ,%edx /* save number of quad bytes */
|
#ifdef CONFIG_APPLICATION_MEMORY
|
||||||
shrl $2, %ecx /* How many 16 bytes? */
|
movl $__app_data_ram_start, %edi /* DATA in RAM (dest) */
|
||||||
je dataWords
|
movl $__app_data_rom_start, %esi /* DATA in ROM (src) */
|
||||||
|
movl $__app_data_num_words, %ecx /* Size of DATA in quad bytes */
|
||||||
|
|
||||||
dataDQ:
|
call _x86_data_copy
|
||||||
movdqu (%esi), %xmm0
|
#endif /* CONFIG_APPLICATION_MEMORY */
|
||||||
movdqu %xmm0, (%edi)
|
|
||||||
addl $16, %esi
|
|
||||||
addl $16, %edi
|
|
||||||
loop dataDQ
|
|
||||||
|
|
||||||
dataWords:
|
|
||||||
movl %edx, %ecx /* restore # quad bytes */
|
|
||||||
andl $0x3, %ecx /* only need to copy at most 3 quad bytes */
|
|
||||||
#endif /* CONFIG_SSE */
|
|
||||||
|
|
||||||
rep
|
|
||||||
movsl /* copy data 4 bytes at a time */
|
|
||||||
|
|
||||||
#endif /* CONFIG_XIP */
|
#endif /* CONFIG_XIP */
|
||||||
|
|
||||||
|
@ -241,44 +229,15 @@ dataWords:
|
||||||
* It's assumed that BSS size will be a multiple of a long (4 bytes),
|
* It's assumed that BSS size will be a multiple of a long (4 bytes),
|
||||||
* and aligned on a double word (32-bit) boundary
|
* and aligned on a double word (32-bit) boundary
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SSE
|
|
||||||
|
|
||||||
/* use XMM register to clear 16 bytes at a time */
|
|
||||||
|
|
||||||
pxor %xmm0, %xmm0 /* zero out xmm0 register */
|
|
||||||
movl $__bss_start, %edi /* load BSS start address */
|
movl $__bss_start, %edi /* load BSS start address */
|
||||||
movl $__bss_num_words, %ecx /* number of quad bytes in .bss */
|
movl $__bss_num_words, %ecx /* number of quad bytes in .bss */
|
||||||
movl %ecx, %edx /* make a copy of # quad bytes */
|
call _x86_bss_zero
|
||||||
shrl $2, %ecx /* How many multiples of 16 byte ? */
|
|
||||||
je bssWords
|
|
||||||
bssDQ:
|
|
||||||
movdqu %xmm0, (%edi) /* zero 16 bytes... */
|
|
||||||
addl $16, %edi
|
|
||||||
loop bssDQ
|
|
||||||
|
|
||||||
/* fall through to handle the remaining double words (32-bit chunks) */
|
#ifdef CONFIG_APPLICATION_MEMORY
|
||||||
|
movl $__app_bss_start, %edi /* load app BSS start address */
|
||||||
bssWords:
|
movl $__app_bss_num_words, %ecx /* number of quad bytes */
|
||||||
xorl %eax, %eax /* fill memory with 0 */
|
call _x86_bss_zero
|
||||||
movl %edx, %ecx /* move # quad bytes into ECX (for rep) */
|
#endif
|
||||||
andl $0x3, %ecx /* only need to zero at most 3 quad bytes */
|
|
||||||
cld
|
|
||||||
rep
|
|
||||||
stosl /* zero memory per 4 bytes */
|
|
||||||
|
|
||||||
#else /* !CONFIG_SSE */
|
|
||||||
|
|
||||||
/* clear out BSS double words (32-bits at a time) */
|
|
||||||
|
|
||||||
xorl %eax, %eax /* fill memory with 0 */
|
|
||||||
movl $__bss_start, %edi /* load BSS start address */
|
|
||||||
movl $__bss_num_words, %ecx /* number of quad bytes */
|
|
||||||
cld
|
|
||||||
rep
|
|
||||||
stosl /* zero memory per 4 bytes */
|
|
||||||
|
|
||||||
#endif /* CONFIG_SSE */
|
|
||||||
|
|
||||||
#ifdef CONFIG_GDT_DYNAMIC
|
#ifdef CONFIG_GDT_DYNAMIC
|
||||||
/* activate RAM-based Global Descriptor Table (GDT) */
|
/* activate RAM-based Global Descriptor Table (GDT) */
|
||||||
|
@ -308,6 +267,70 @@ bssWords:
|
||||||
|
|
||||||
jmp _Cstart
|
jmp _Cstart
|
||||||
|
|
||||||
|
|
||||||
|
_x86_bss_zero:
|
||||||
|
/* ECX = size, EDI = starting address */
|
||||||
|
#ifdef CONFIG_SSE
|
||||||
|
/* use XMM register to clear 16 bytes at a time */
|
||||||
|
pxor %xmm0, %xmm0 /* zero out xmm0 register */
|
||||||
|
|
||||||
|
movl %ecx, %edx /* make a copy of # quad bytes */
|
||||||
|
shrl $2, %ecx /* How many multiples of 16 byte ? */
|
||||||
|
je bssWords
|
||||||
|
bssDQ:
|
||||||
|
movdqu %xmm0, (%edi) /* zero 16 bytes... */
|
||||||
|
addl $16, %edi
|
||||||
|
loop bssDQ
|
||||||
|
|
||||||
|
/* fall through to handle the remaining double words (32-bit chunks) */
|
||||||
|
|
||||||
|
bssWords:
|
||||||
|
xorl %eax, %eax /* fill memory with 0 */
|
||||||
|
movl %edx, %ecx /* move # quad bytes into ECX (for rep) */
|
||||||
|
andl $0x3, %ecx /* only need to zero at most 3 quad bytes */
|
||||||
|
cld
|
||||||
|
rep
|
||||||
|
stosl /* zero memory per 4 bytes */
|
||||||
|
|
||||||
|
#else /* !CONFIG_SSE */
|
||||||
|
|
||||||
|
/* clear out BSS double words (32-bits at a time) */
|
||||||
|
|
||||||
|
xorl %eax, %eax /* fill memory with 0 */
|
||||||
|
cld
|
||||||
|
rep
|
||||||
|
stosl /* zero memory per 4 bytes */
|
||||||
|
|
||||||
|
#endif /* CONFIG_SSE */
|
||||||
|
ret
|
||||||
|
|
||||||
|
#ifdef CONFIG_XIP
|
||||||
|
_x86_data_copy:
|
||||||
|
/* EDI = dest, ESI = source, ECX = size in 32-bit chunks */
|
||||||
|
#ifdef CONFIG_SSE
|
||||||
|
/* copy 16 bytes at a time using XMM until < 16 bytes remain */
|
||||||
|
|
||||||
|
movl %ecx ,%edx /* save number of quad bytes */
|
||||||
|
shrl $2, %ecx /* How many 16 bytes? */
|
||||||
|
je dataWords
|
||||||
|
|
||||||
|
dataDQ:
|
||||||
|
movdqu (%esi), %xmm0
|
||||||
|
movdqu %xmm0, (%edi)
|
||||||
|
addl $16, %esi
|
||||||
|
addl $16, %edi
|
||||||
|
loop dataDQ
|
||||||
|
|
||||||
|
dataWords:
|
||||||
|
movl %edx, %ecx /* restore # quad bytes */
|
||||||
|
andl $0x3, %ecx /* only need to copy at most 3 quad bytes */
|
||||||
|
#endif /* CONFIG_SSE */
|
||||||
|
|
||||||
|
rep
|
||||||
|
movsl /* copy data 4 bytes at a time */
|
||||||
|
ret
|
||||||
|
#endif /* CONFIG_XIP */
|
||||||
|
|
||||||
#if defined(CONFIG_SSE)
|
#if defined(CONFIG_SSE)
|
||||||
|
|
||||||
/* SSE control & status register initial value */
|
/* SSE control & status register initial value */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue