* 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 <nuttx/config.h>
#include <nuttx/init.h>
#include <nuttx/tls.h>
#include <arch/board/board.h>
#include <arch/multiboot2.h>
#include <arch/acpi.h>
#include <debug.h>
#include "x86_64_internal.h"
#include "intel64_lowsetup.h"
#include "intel64_cpu.h"
#include "intel64_hwp.h"
* Public Data
****************************************************************************/
uint32_t g_mb_magic __attribute__((section(".loader.bss")));
uint32_t g_mb_info_struct __attribute__((section(".loader.bss")));
uintptr_t g_acpi_rsdp = 0;
#ifdef CONFIG_MULTBOOT2_FB
struct multiboot_tag_framebuffer *g_mb_fb_tag = NULL;
#endif
* 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;
if (g_mb_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
{
return;
}
for (tag = (struct multiboot_tag *)(uintptr_t)(g_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;
}
case MULTIBOOT_TAG_TYPE_ACPI_OLD:
{
struct multiboot_tag_old_acpi *acpi
= (struct multiboot_tag_old_acpi *)tag;
g_acpi_rsdp = (uintptr_t)acpi->rsdp;
break;
}
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
{
struct multiboot_tag_new_acpi *acpi =
(struct multiboot_tag_new_acpi *)tag;
g_acpi_rsdp = (uintptr_t)acpi->rsdp;
break;
}
#ifdef CONFIG_MULTBOOT2_FB
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
{
* at this boot stage we can't map >4GB memory yet and it's
* possible that frame bufer address is above 4GB.
*/
g_mb_fb_tag = (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)
{
uint64_t *dest = NULL;
* BSS cleanup can be optimized with vector instructions, so we need to
* enable SSE at this point.
*/
x86_64_check_and_enable_capability();
* so this *must be* called after enabling SSE instructions.
*/
#ifndef CONFIG_ARCH_SKIP_ZERO_BSS
for (dest = (uint64_t *)_sbss; dest < (uint64_t *)_ebss; )
{
*dest++ = 0;
}
#endif
#ifdef CONFIG_SCHED_THREAD_LOCAL
write_fsbase((uintptr_t)(g_idle_topstack[0] -
CONFIG_IDLETHREAD_STACKSIZE +
sizeof(struct tls_info_s) +
(_END_TBSS - _START_TDATA)));
#endif
intel64_lowsetup();
#ifdef CONFIG_ARCH_MULTIBOOT2
x86_64_mb2_config();
#endif
#if defined(CONFIG_MULTBOOT2_FB_TERM)
x86_64_mb2_fbinitialize(g_mb_fb_tag);
lowsyslog("framebuffer initialized\n");
#endif
#ifdef CONFIG_ARCH_X86_64_ACPI
acpi_init(g_acpi_rsdp);
#endif
#ifndef CONFIG_SMP
* x86_64_ap_boot() after the initialization of the last AP is finished.
*/
__revoke_low_memory();
#endif
x86_64_cpu_init();
x86_64_boardinitialize();
#ifdef USE_EARLYSERIALINIT
x86_64_earlyserialinit();
#endif
x86_64_timer_calibrate_freq();
#ifdef CONFIG_ARCH_HAVE_HWP
intel64_hwp_init();
#endif
x86_64_cpu_priv_set(0);
nx_start();
for (; ; );
}