diff --git a/arch/x86_64/src/intel64/CMakeLists.txt b/arch/x86_64/src/intel64/CMakeLists.txt index 3e7e4c8a269..7df5c87300a 100644 --- a/arch/x86_64/src/intel64/CMakeLists.txt +++ b/arch/x86_64/src/intel64/CMakeLists.txt @@ -36,6 +36,7 @@ set(SRCS intel64_schedulesigaction.c intel64_sigdeliver.c intel64_usestack.c + intel64_start.c intel64_handlers.c intel64_idle.c intel64_lowsetup.c diff --git a/arch/x86_64/src/intel64/Make.defs b/arch/x86_64/src/intel64/Make.defs index 7274d01e6b2..a7c1436e962 100644 --- a/arch/x86_64/src/intel64/Make.defs +++ b/arch/x86_64/src/intel64/Make.defs @@ -24,6 +24,7 @@ CMN_CSRCS += x86_64_allocateheap.c x86_64_copystate.c x86_64_exit.c CMN_CSRCS += x86_64_getintstack.c x86_64_mdelay.c x86_64_initialize.c CMN_CSRCS += x86_64_modifyreg8.c x86_64_modifyreg16.c x86_64_modifyreg32.c CMN_CSRCS += x86_64_nputs.c x86_64_switchcontext.c x86_64_udelay.c + CMN_CSRCS += intel64_createstack.c intel64_initialstate.c intel64_irq.c CMN_CSRCS += intel64_map_region.c intel64_regdump.c intel64_releasestack.c CMN_CSRCS += intel64_rtc.c intel64_restore_auxstate.c intel64_savestate.c @@ -33,7 +34,7 @@ CMN_CSRCS += intel64_sigdeliver.c intel64_usestack.c x86_64_tcbinfo.c # Required Intel64 files CHIP_ASRCS = intel64_saveusercontext.S intel64_fullcontextrestore.S intel64_vectors.S intel64_head.S -CHIP_CSRCS = intel64_handlers.c intel64_idle.c intel64_lowsetup.c +CHIP_CSRCS = intel64_start.c intel64_handlers.c intel64_idle.c intel64_lowsetup.c CHIP_CSRCS += intel64_serial.c intel64_rng.c intel64_check_capability.c # Configuration-dependent intel64 files diff --git a/arch/x86_64/src/intel64/intel64.h b/arch/x86_64/src/intel64/intel64.h index b8d644038e9..c07f688424c 100644 --- a/arch/x86_64/src/intel64/intel64.h +++ b/arch/x86_64/src/intel64/intel64.h @@ -72,7 +72,7 @@ extern "C" * Name: intel64_lowsetup * * Description: - * Called at the very beginning of _start. + * Called at the very beginning of _nxstart. * Performs low level initializationincluding setup of the console UART. * This UART done early so that the serial console is available for * debugging very early in the boot sequence. diff --git a/arch/x86_64/src/intel64/intel64_head.S b/arch/x86_64/src/intel64/intel64_head.S index 62782345caf..e462bdc2796 100644 --- a/arch/x86_64/src/intel64/intel64_head.S +++ b/arch/x86_64/src/intel64/intel64_head.S @@ -45,12 +45,11 @@ ****************************************************************************/ .global __pmode_entry /* The 32bit protected mode entry */ - .global __nxstart .global __enable_sse_avx .global __enable_pcid .global __revoke_low_memory + .global __nxstart /* __nxstart is defined elsewhere */ .global nx_start /* nx_start is defined elsewhere */ - .global up_lowsetup /* up_lowsetup is defined elsewhere */ .global g_idle_topstack /* The end of the idle stack, the start of the heap */ .global mb_info_struct .global mb_magic @@ -267,28 +266,7 @@ start64: mov %ax, %fs mov %ax, %gs - /* Finally, we can start the OS */ - movabs $__nxstart, %rbx - jmp *%rbx - .size __pmode_entry, . - __pmode_entry - -/**************************************************************************** - * Name: __nxstart - * - * Description: - * Do low-level initialization and call nx_start - * - ****************************************************************************/ - - .section .text, "ax" - .type __nxstart, @function - -__nxstart: - /* We are now in high memory, will revoke the lower 128MB memory mapping - * in lowsetup - */ - - /* clear out bss section */ + /* Clear out bss section */ movabs $_sbss, %rbx movabs $_ebss, %rdx clear_bss: @@ -301,20 +279,16 @@ clear_bss: movabs $g_idle_topstack, %rbx mov (%rbx), %rsp - /* Initialize and start NuttX */ - call up_lowsetup /* Low-level, pre-OS initialization */ + /* We use jmp instruction below which doesn't push 1 byte on stack, so we + * have to push a dummy value here, otherwise SSE instructions calledd + * during initialization will fail. + */ + pushq $0 - call nx_start /* Start NuttX */ - - /* NuttX will not return */ - /* We should never end up here */ - /* If we really do, then we are doomed, halting the processor for ever */ - - cli -hang: - hlt /* Halt machine should NuttX return */ - jmp hang - .size __nxstart, . - __nxstart + /* Finally, we can start the OS */ + movabs $__nxstart, %rbx + jmp *%rbx + .size __pmode_entry, . - __pmode_entry /**************************************************************************** * Name: __revoke_low_memory @@ -324,6 +298,7 @@ hang: * ****************************************************************************/ + .section .text, "ax" .type __revoke_low_memory, @function __revoke_low_memory: diff --git a/arch/x86_64/src/intel64/intel64_lowsetup.c b/arch/x86_64/src/intel64/intel64_lowsetup.c index c61864f6cbb..9718afd845c 100644 --- a/arch/x86_64/src/intel64/intel64_lowsetup.c +++ b/arch/x86_64/src/intel64/intel64_lowsetup.c @@ -25,8 +25,6 @@ #include #include -#include -#include #include "x86_64_internal.h" @@ -53,77 +51,24 @@ volatile uint64_t *pt; volatile struct ist_s *ist64; volatile struct gdt_entry_s *gdt64; -/* This holds information passed by the multiboot2 bootloader */ - -uint32_t mb_magic __attribute__((section(".loader.bss"))); -uint32_t mb_info_struct __attribute__((section(".loader.bss"))); - /**************************************************************************** * Private Functions ****************************************************************************/ -#ifdef CONFIG_ARCH_MULTIBOOT2 -/**************************************************************************** - * Name: x86_64_mb2_config - * - * Description: - * Parse multiboot2 info. - * - ****************************************************************************/ - -static void x86_64_mb2_config(void) -{ - struct multiboot_tag *tag; - - /* Check that we were actually booted by a mulitboot2 bootloader */ - - if (mb_magic != MULTIBOOT2_BOOTLOADER_MAGIC) - { - return; - } - - for (tag = (struct multiboot_tag *)(uintptr_t)(mb_info_struct + 8); - tag->type != MULTIBOOT_TAG_TYPE_END; - tag = (struct multiboot_tag *)((uint8_t *)tag + - ((tag->size + 7) & ~7))) - { - switch (tag->type) - { - case MULTIBOOT_TAG_TYPE_EFI64: - { - break; - } - -#ifdef CONFIG_MULTBOOT2_FB_TERM - case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: - { - x86_64_mb2_fbinitialize( - (struct multiboot_tag_framebuffer *)tag); - break; - } -#endif - - default: - break; - } - } -} -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: up_lowsetup + * Name: intel64_lowsetup * * Description: - * Called from intel64_head BEFORE starting the operating system in order + * Called from __nxstart BEFORE starting the operating system in order * perform any necessary, early initialization. * ****************************************************************************/ -void up_lowsetup(void) +void intel64_lowsetup(void) { /* we should be in long mode at this point */ @@ -148,30 +93,7 @@ void up_lowsetup(void) x86_64_check_and_enable_capability(); -#ifdef CONFIG_ARCH_MULTIBOOT2 - /* Handle multiboot2 info */ - - x86_64_mb2_config(); -#endif - /* Revoke the lower memory */ __revoke_low_memory(); - - /* perform board-specific initializations */ - - x86_64_boardinitialize(); - -#ifdef USE_EARLYSERIALINIT - /* Early serial driver initialization */ - - x86_64_earlyserialinit(); -#endif - - x86_64_timer_calibrate_freq(); - -#ifdef CONFIG_LIB_SYSCALL - enable_syscall(); -#endif } - diff --git a/arch/x86_64/src/intel64/intel64_start.c b/arch/x86_64/src/intel64/intel64_start.c new file mode 100644 index 00000000000..89e3e9960bd --- /dev/null +++ b/arch/x86_64/src/intel64/intel64_start.c @@ -0,0 +1,143 @@ +/**************************************************************************** + * arch/x86_64/src/intel64/intel64_start.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "x86_64_internal.h" +#include "intel64.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This holds information passed by the multiboot2 bootloader */ + +uint32_t mb_magic __attribute__((section(".loader.bss"))); +uint32_t mb_info_struct __attribute__((section(".loader.bss"))); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_ARCH_MULTIBOOT2 +/**************************************************************************** + * Name: x86_64_mb2_config + * + * Description: + * Parse multiboot2 info. + * + ****************************************************************************/ + +static void x86_64_mb2_config(void) +{ + struct multiboot_tag *tag; + + /* Check that we were actually booted by a multiboot2 bootloader */ + + if (mb_magic != MULTIBOOT2_BOOTLOADER_MAGIC) + { + return; + } + + for (tag = (struct multiboot_tag *)(uintptr_t)(mb_info_struct + 8); + tag->type != MULTIBOOT_TAG_TYPE_END; + tag = (struct multiboot_tag *)((uint8_t *)tag + + ((tag->size + 7) & ~7))) + { + switch (tag->type) + { + case MULTIBOOT_TAG_TYPE_EFI64: + { + break; + } + +#ifdef CONFIG_MULTBOOT2_FB_TERM + case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: + { + x86_64_mb2_fbinitialize( + (struct multiboot_tag_framebuffer *)tag); + break; + } +#endif + + default: + break; + } + } +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __nxstart + * + * Description: + * Do low-level initialization and call nx_start. + * + ****************************************************************************/ + +void __nxstart(void) +{ + /* Low-level, pre-OS initialization */ + + intel64_lowsetup(); + +#ifdef CONFIG_ARCH_MULTIBOOT2 + /* Handle multiboot2 info */ + + x86_64_mb2_config(); +#endif + + /* perform board-specific initializations */ + + x86_64_boardinitialize(); + +#ifdef USE_EARLYSERIALINIT + /* Early serial driver initialization */ + + x86_64_earlyserialinit(); +#endif + + x86_64_timer_calibrate_freq(); + +#ifdef CONFIG_LIB_SYSCALL + enable_syscall(); +#endif + + /* Start NuttX */ + + nx_start(); + + /* Shouldn't get here */ + + for (; ; ); +}