x86: use z_bss_zero and z_data_copy
Instead of doing these in assembly, use the common z_bss_zero() and z_data_copy() C functions instead. This simplifies code a bit and we won't miss any additions to these two functions (if any) under x86 in the future (as x86_64 was actually not clearing gcov bss area). Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
dd98de880a
commit
c0ee8c4a43
3 changed files with 19 additions and 115 deletions
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
/* externs */
|
/* externs */
|
||||||
GTEXT(z_x86_prep_c)
|
GTEXT(z_x86_prep_c)
|
||||||
|
GTEXT(z_bss_zero)
|
||||||
|
GTEXT(z_data_copy)
|
||||||
|
|
||||||
GDATA(_idt_base_address)
|
GDATA(_idt_base_address)
|
||||||
GDATA(z_interrupt_stacks)
|
GDATA(z_interrupt_stacks)
|
||||||
|
@ -152,42 +154,17 @@ __csSet:
|
||||||
addl $CONFIG_ISR_STACK_SIZE, %esp
|
addl $CONFIG_ISR_STACK_SIZE, %esp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Clear BSS */
|
||||||
|
call z_bss_zero
|
||||||
|
|
||||||
#ifdef CONFIG_XIP
|
#ifdef CONFIG_XIP
|
||||||
/*
|
/* Copy data from flash to RAM.
|
||||||
* copy DATA section from ROM to RAM region
|
|
||||||
* DATA is followed by BSS section.
|
|
||||||
*/
|
|
||||||
|
|
||||||
movl $__data_ram_start, %edi /* DATA in RAM (dest) */
|
|
||||||
movl $__data_rom_start, %esi /* DATA in ROM (src) */
|
|
||||||
movl $__data_num_words, %ecx /* Size of DATA in quad bytes */
|
|
||||||
|
|
||||||
call _x86_data_copy
|
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
|
||||||
movl $_app_smem_start, %edi /* DATA in RAM (dest) */
|
|
||||||
movl $_app_smem_rom_start, %esi /* DATA in ROM (src) */
|
|
||||||
movl $_app_smem_num_words, %ecx /* Size of DATA in quad bytes */
|
|
||||||
|
|
||||||
call _x86_data_copy
|
|
||||||
#endif /* CONFIG_USERSPACE */
|
|
||||||
#endif /* CONFIG_XIP */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Clear BSS: bzero (__bss_start, __bss_num_words*4)
|
|
||||||
*
|
*
|
||||||
* It's assumed that BSS size will be a multiple of a long (4 bytes),
|
* This is a must is CONFIG_GDT_DYNAMIC is enabled,
|
||||||
* and aligned on a double word (32-bit) boundary
|
* as _gdt needs to be in RAM.
|
||||||
*/
|
*/
|
||||||
movl $__bss_start, %edi /* load BSS start address */
|
call z_data_copy
|
||||||
movl $__bss_num_words, %ecx /* number of quad bytes in .bss */
|
#endif
|
||||||
call _x86_bss_zero
|
|
||||||
|
|
||||||
#ifdef CONFIG_COVERAGE_GCOV
|
|
||||||
movl $__gcov_bss_start, %edi /* load gcov BSS start address */
|
|
||||||
movl $__gcov_bss_num_words, %ecx /* number of quad bytes */
|
|
||||||
call _x86_bss_zero
|
|
||||||
#endif /* CONFIG_COVERAGE_GCOV */
|
|
||||||
|
|
||||||
#ifdef CONFIG_GDT_DYNAMIC
|
#ifdef CONFIG_GDT_DYNAMIC
|
||||||
/* activate RAM-based Global Descriptor Table (GDT) */
|
/* activate RAM-based Global Descriptor Table (GDT) */
|
||||||
|
@ -227,70 +204,6 @@ __csSet:
|
||||||
pushl %ebx /* pointer to multiboot info, or NULL */
|
pushl %ebx /* pointer to multiboot info, or NULL */
|
||||||
call z_x86_prep_c /* enter kernel; never returns */
|
call z_x86_prep_c /* enter kernel; never returns */
|
||||||
|
|
||||||
_x86_bss_zero:
|
|
||||||
/* ECX = size, EDI = starting address */
|
|
||||||
#ifdef CONFIG_X86_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_X86_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_X86_SSE */
|
|
||||||
ret
|
|
||||||
|
|
||||||
#ifdef CONFIG_XIP
|
|
||||||
_x86_data_copy:
|
|
||||||
/* EDI = dest, ESI = source, ECX = size in 32-bit chunks */
|
|
||||||
#ifdef CONFIG_X86_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_X86_SSE */
|
|
||||||
|
|
||||||
rep
|
|
||||||
movsl /* copy data 4 bytes at a time */
|
|
||||||
ret
|
|
||||||
#endif /* CONFIG_XIP */
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_X86_SSE)
|
#if defined(CONFIG_X86_SSE)
|
||||||
|
|
||||||
/* SSE control & status register initial value */
|
/* SSE control & status register initial value */
|
||||||
|
|
|
@ -163,19 +163,18 @@ FUNC_NORETURN void z_x86_cpu_init(struct x86_cpuboot *cpuboot)
|
||||||
{
|
{
|
||||||
x86_sse_init(NULL);
|
x86_sse_init(NULL);
|
||||||
|
|
||||||
#if CONFIG_MP_NUM_CPUS > 1
|
|
||||||
/* The internal cpu_number is the index to x86_cpuboot[] */
|
/* The internal cpu_number is the index to x86_cpuboot[] */
|
||||||
unsigned char cpu_num = (unsigned char)(cpuboot - x86_cpuboot);
|
unsigned char cpu_num = (unsigned char)(cpuboot - x86_cpuboot);
|
||||||
|
|
||||||
if (cpu_num > 0) {
|
if (cpu_num == 0) {
|
||||||
/*
|
/* Only need to do these once per boot */
|
||||||
* For CPU #0, z_loapic_enable(0) will be done
|
z_bss_zero();
|
||||||
* inside z_x86_prep_c() so there is no need to do it
|
#ifdef CONFIG_XIP
|
||||||
* here.
|
z_data_copy();
|
||||||
*/
|
|
||||||
z_loapic_enable(cpu_num);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
z_loapic_enable(cpu_num);
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
/* Set landing site for 'syscall' instruction */
|
/* Set landing site for 'syscall' instruction */
|
||||||
|
|
|
@ -148,16 +148,8 @@ __start:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* N.B.: if multiboot info struct is present, "common.S"
|
* N.B.: if multiboot info struct is present, "common.S"
|
||||||
* has left a pointer to it in EBX. do not clobber (yet).
|
* has left a pointer to it in EBX.
|
||||||
*
|
|
||||||
* next, clear the BSS. note we're still in 32-bit mode,
|
|
||||||
* so the BSS must fit entirely in the first 4GB of RAM.
|
|
||||||
*/
|
*/
|
||||||
cld
|
|
||||||
xorl %eax, %eax
|
|
||||||
movl $__bss_start, %edi
|
|
||||||
movl $__bss_num_dwords, %ecx
|
|
||||||
rep stosl
|
|
||||||
|
|
||||||
movl $x86_cpuboot, %ebp /* BSP is always logical CPU id 0 */
|
movl $x86_cpuboot, %ebp /* BSP is always logical CPU id 0 */
|
||||||
movl %ebx, __x86_cpuboot_t_arg_OFFSET(%ebp) /* multiboot info */
|
movl %ebx, __x86_cpuboot_t_arg_OFFSET(%ebp) /* multiboot info */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue