From c0ee8c4a4326d4fbe38905a94f608c9d94c552b5 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 10 Feb 2021 14:31:20 -0800 Subject: [PATCH] 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 --- arch/x86/core/ia32/crt0.S | 107 +++------------------------------ arch/x86/core/intel64/cpu.c | 17 +++--- arch/x86/core/intel64/locore.S | 10 +-- 3 files changed, 19 insertions(+), 115 deletions(-) diff --git a/arch/x86/core/ia32/crt0.S b/arch/x86/core/ia32/crt0.S index e886eebb3d8..f9c1405dca6 100644 --- a/arch/x86/core/ia32/crt0.S +++ b/arch/x86/core/ia32/crt0.S @@ -25,6 +25,8 @@ /* externs */ GTEXT(z_x86_prep_c) + GTEXT(z_bss_zero) + GTEXT(z_data_copy) GDATA(_idt_base_address) GDATA(z_interrupt_stacks) @@ -152,42 +154,17 @@ __csSet: addl $CONFIG_ISR_STACK_SIZE, %esp #endif + /* Clear BSS */ + call z_bss_zero + #ifdef CONFIG_XIP - /* - * 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) + /* Copy data from flash to RAM. * - * It's assumed that BSS size will be a multiple of a long (4 bytes), - * and aligned on a double word (32-bit) boundary + * This is a must is CONFIG_GDT_DYNAMIC is enabled, + * as _gdt needs to be in RAM. */ - movl $__bss_start, %edi /* load BSS start address */ - movl $__bss_num_words, %ecx /* number of quad bytes in .bss */ - 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 */ + call z_data_copy +#endif #ifdef CONFIG_GDT_DYNAMIC /* activate RAM-based Global Descriptor Table (GDT) */ @@ -227,70 +204,6 @@ __csSet: pushl %ebx /* pointer to multiboot info, or NULL */ 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) /* SSE control & status register initial value */ diff --git a/arch/x86/core/intel64/cpu.c b/arch/x86/core/intel64/cpu.c index 57c588e04e7..fd31d3719cf 100644 --- a/arch/x86/core/intel64/cpu.c +++ b/arch/x86/core/intel64/cpu.c @@ -163,19 +163,18 @@ FUNC_NORETURN void z_x86_cpu_init(struct x86_cpuboot *cpuboot) { x86_sse_init(NULL); -#if CONFIG_MP_NUM_CPUS > 1 /* The internal cpu_number is the index to x86_cpuboot[] */ unsigned char cpu_num = (unsigned char)(cpuboot - x86_cpuboot); - if (cpu_num > 0) { - /* - * For CPU #0, z_loapic_enable(0) will be done - * inside z_x86_prep_c() so there is no need to do it - * here. - */ - z_loapic_enable(cpu_num); - } + if (cpu_num == 0) { + /* Only need to do these once per boot */ + z_bss_zero(); +#ifdef CONFIG_XIP + z_data_copy(); #endif + } + + z_loapic_enable(cpu_num); #ifdef CONFIG_USERSPACE /* Set landing site for 'syscall' instruction */ diff --git a/arch/x86/core/intel64/locore.S b/arch/x86/core/intel64/locore.S index d715abfe9e9..00886226978 100644 --- a/arch/x86/core/intel64/locore.S +++ b/arch/x86/core/intel64/locore.S @@ -148,16 +148,8 @@ __start: /* * N.B.: if multiboot info struct is present, "common.S" - * has left a pointer to it in EBX. do not clobber (yet). - * - * next, clear the BSS. note we're still in 32-bit mode, - * so the BSS must fit entirely in the first 4GB of RAM. + * has left a pointer to it in EBX. */ - 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 %ebx, __x86_cpuboot_t_arg_OFFSET(%ebp) /* multiboot info */