arch/x86: initial Intel64 bootstrap framework
This patch adds basic build infrastructure, definitions, a linker script, etc. to use the Zephyr and 0.10.1 SDK to build a 64-bit ELF binary suitable for use with GRUB to minimally bootstrap an Apollo Lake (e.g., UpSquared) board. The resulting binary can hardly be called a Zephyr kernel as it is lacking most of the glue logic, but it is a starting point to flesh those out in the x86 tree. The "kernel" builds with a few harmless warnings, both with GCC from the Zephyr SDK and with ICC (which is currently being worked on in a separate branch). These warnings are either related to pointer size differences (since this is an LP64 build) and/or dummy functions that will be replaced with working versions shortly. Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
parent
c58b28ab0a
commit
34307a54f0
10 changed files with 291 additions and 1 deletions
|
@ -1,3 +1,14 @@
|
||||||
# Copyright (c) 2019 Intel Corp.
|
# Copyright (c) 2019 Intel Corp.
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#
|
||||||
|
# XXX: When using the Intel toolchain, cmake doesn't recognize .S files
|
||||||
|
# automatically, and I can't be bothered to figure out how to fix this.
|
||||||
|
#
|
||||||
|
|
||||||
|
set_property(SOURCE intel64/locore.S PROPERTY LANGUAGE ASM)
|
||||||
|
|
||||||
|
zephyr_library_sources(
|
||||||
|
intel64/locore.S
|
||||||
|
intel64/thread.c
|
||||||
|
)
|
||||||
|
|
156
arch/x86/core/intel64/locore.S
Normal file
156
arch/x86/core/intel64/locore.S
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Intel Corporation
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch/x86/multiboot.h>
|
||||||
|
#include <sys/util.h>
|
||||||
|
#include <arch/x86/msr.h>
|
||||||
|
#include <kernel_arch_data.h>
|
||||||
|
|
||||||
|
#define NR_IDT_VECTOR 256 /* full IDT, we're not short of RAM */
|
||||||
|
#define IRQ_STACK_SIZE 4096 /* must be a multiple of 16 */
|
||||||
|
|
||||||
|
.section .locore,"ax"
|
||||||
|
.code32
|
||||||
|
|
||||||
|
.globl __start
|
||||||
|
__start:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* multiboot starts us here in 32-bit flat mode with interrupts
|
||||||
|
* and paging disabled. first, switch to our own GDT and stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
lgdt gdt48
|
||||||
|
lidt idt48
|
||||||
|
jmpl $X86_KERNEL_CS_32, $1f
|
||||||
|
1: movw $X86_KERNEL_DS_32, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %ss
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
|
||||||
|
movl $(irq_stack + IRQ_STACK_SIZE), %esp
|
||||||
|
|
||||||
|
/*
|
||||||
|
* transition to long mode, by the book.
|
||||||
|
*/
|
||||||
|
|
||||||
|
movl %cr4, %eax /* enable PAE */
|
||||||
|
orl $CR4_PAE, %eax
|
||||||
|
movl %eax, %cr4
|
||||||
|
|
||||||
|
movl $pml4, %eax /* load page base */
|
||||||
|
movl %eax, %cr3
|
||||||
|
|
||||||
|
movl $X86_EFER_MSR, %ecx /* enable long mode */
|
||||||
|
rdmsr
|
||||||
|
orl $X86_EFER_MSR_LME, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
movl %cr0, %eax /* enable paging */
|
||||||
|
orl $CR0_PG, %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* jump into long mode, reload the segment registers (again).
|
||||||
|
*/
|
||||||
|
|
||||||
|
jmpl $X86_KERNEL_CS_64, $1f
|
||||||
|
.code64
|
||||||
|
1: movl $X86_KERNEL_DS_64, %eax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %ss
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
|
||||||
|
/*
|
||||||
|
* func() is just a placeholder C function. don't replace CALL
|
||||||
|
* with JMP; we must honor the ABI stack alignment requirements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
call func
|
||||||
|
|
||||||
|
stop: jmp stop
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The multiboot header is identical (for obvious reasons) to the 32-bit
|
||||||
|
* version in ia32/crt0.S. They should be refactored into a common file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_MULTIBOOT
|
||||||
|
.align 4
|
||||||
|
.long X86_MULTIBOOT_HEADER_MAGIC
|
||||||
|
.long X86_MULTIBOOT_HEADER_FLAGS
|
||||||
|
.long -(X86_MULTIBOOT_HEADER_MAGIC + X86_MULTIBOOT_HEADER_FLAGS)
|
||||||
|
#ifdef CONFIG_X86_MULTIBOOT_FRAMEBUF
|
||||||
|
.fill 5,4,0 /* (unused exec layout) */
|
||||||
|
.long 0 /* linear graphics mode */
|
||||||
|
.long CONFIG_X86_MULTIBOOT_FRAMEBUF_X /* width */
|
||||||
|
.long CONFIG_X86_MULTIBOOT_FRAMEBUF_Y /* height */
|
||||||
|
.long 32 /* depth */
|
||||||
|
#endif /* CONFIG_X86_MULTIBOOT_FRAMEBUF */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GDT - a single GDT is shared by all threads (and, eventually, all CPUs).
|
||||||
|
* This layout must agree with the selectors in intel64/kernel_arch_data.h.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
|
||||||
|
gdt:
|
||||||
|
.word 0, 0, 0, 0 /* 0x00: null descriptor */
|
||||||
|
.word 0xFFFF, 0, 0x9A00, 0x00CF /* 0x08: 32-bit kernel code */
|
||||||
|
.word 0xFFFF, 0, 0x9200, 0x00CF /* 0x10: 32-bit kernel data */
|
||||||
|
.word 0, 0, 0x9800, 0x0020 /* 0x18: 64-bit kernel code */
|
||||||
|
|
||||||
|
gdt48:
|
||||||
|
.word (gdt48 - gdt - 1)
|
||||||
|
.long gdt
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IDT. Empty for now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
|
||||||
|
idt: .fill (NR_IDT_VECTOR*16), 1, 0
|
||||||
|
idt48:
|
||||||
|
.word (idt48 - idt - 1)
|
||||||
|
.long idt
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Page tables. Long mode requires them, but we don't implement any memory
|
||||||
|
* protection yet, so these simply identity-map the first 4GB w/ 1GB pages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.align 4096
|
||||||
|
|
||||||
|
pml4:
|
||||||
|
.long pdp + 0x03 /* 0x03 = R/W, P */
|
||||||
|
.long 0
|
||||||
|
.fill 4088, 1, 0
|
||||||
|
|
||||||
|
pdp: .long 0x00000183 /* 0x183 = G, 1GB, R/W, P */
|
||||||
|
.long 0
|
||||||
|
.long 0x40000183
|
||||||
|
.long 0
|
||||||
|
.long 0x80000183
|
||||||
|
.long 0
|
||||||
|
.long 0xC0000183
|
||||||
|
.long 0
|
||||||
|
.fill 4064, 1, 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For now, the "IRQ stack" is just used as a scratch stack during
|
||||||
|
* early kernel initialization.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
irq_stack:
|
||||||
|
.fill IRQ_STACK_SIZE, 1, 0xFF
|
||||||
|
|
10
arch/x86/core/intel64/thread.c
Normal file
10
arch/x86/core/intel64/thread.c
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Intel Corporation
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
void func(void)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,4 +6,13 @@
|
||||||
#ifndef ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_
|
#ifndef ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_
|
||||||
#define ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_
|
#define ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GDT selectors - these must agree with the GDT layout in locore.S.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define X86_KERNEL_CS_32 0x08 /* 32-bit kernel code */
|
||||||
|
#define X86_KERNEL_DS_32 0x10 /* 32-bit kernel data */
|
||||||
|
#define X86_KERNEL_CS_64 0x18 /* 64-bit kernel code */
|
||||||
|
#define X86_KERNEL_DS_64 0x00 /* 64-bit kernel data (null!) */
|
||||||
|
|
||||||
#endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_ */
|
#endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_ */
|
||||||
|
|
|
@ -6,4 +6,21 @@
|
||||||
#ifndef ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_FUNC_H_
|
#ifndef ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_FUNC_H_
|
||||||
#define ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_FUNC_H_
|
#define ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_FUNC_H_
|
||||||
|
|
||||||
|
#ifndef _ASMLANGUAGE
|
||||||
|
|
||||||
|
#define z_is_in_isr() (0)
|
||||||
|
|
||||||
|
static ALWAYS_INLINE void
|
||||||
|
z_set_thread_return_value(struct k_thread *thread, unsigned int value)
|
||||||
|
{
|
||||||
|
/* nothing */ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void kernel_arch_init(void)
|
||||||
|
{
|
||||||
|
/* nothing */ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ASMLANGUAGE */
|
||||||
|
|
||||||
#endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_FUNC_H_ */
|
#endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_FUNC_H_ */
|
||||||
|
|
|
@ -6,4 +6,11 @@
|
||||||
#ifndef ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_THREAD_H_
|
#ifndef ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_THREAD_H_
|
||||||
#define ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_THREAD_H_
|
#define ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_THREAD_H_
|
||||||
|
|
||||||
|
#ifndef _ASMLANGUAGE
|
||||||
|
|
||||||
|
struct _callee_saved { };
|
||||||
|
struct _thread_arch { };
|
||||||
|
|
||||||
|
#endif /* _ASMLANGUAGE */
|
||||||
|
|
||||||
#endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_THREAD_H_ */
|
#endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_THREAD_H_ */
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
# Copyright (c) 2019 Intel Corp.
|
# Copyright (c) 2019 Intel Corp.
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
message(FATAL_ERROR "nice try, no Intel64 support yet")
|
zephyr_cc_option(-m64)
|
||||||
|
|
||||||
|
add_subdirectory(core)
|
||||||
|
|
|
@ -3,7 +3,32 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dummies for now
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_
|
#ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_
|
||||||
#define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_
|
#define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_
|
||||||
|
|
||||||
|
#define Z_ARCH_THREAD_STACK_DEFINE(sym, size) \
|
||||||
|
struct _k_thread_stack_element sym[size]
|
||||||
|
|
||||||
|
#define Z_ARCH_THREAD_STACK_SIZEOF(sym) sizeof(sym)
|
||||||
|
#define Z_ARCH_THREAD_STACK_BUFFER(sym) ((char *) sym)
|
||||||
|
|
||||||
|
#define Z_IRQ_TO_INTERRUPT_VECTOR(irq) (0)
|
||||||
|
#define Z_ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p)
|
||||||
|
|
||||||
|
#define z_arch_irq_lock() (0)
|
||||||
|
#define z_arch_irq_unlock(k)
|
||||||
|
|
||||||
|
#define z_x86_msr_read(a) (0)
|
||||||
|
|
||||||
|
#define sys_read8(x) (0)
|
||||||
|
#define sys_read32(x) (0)
|
||||||
|
#define sys_in32(x) (0)
|
||||||
|
#define sys_write8(x,y)
|
||||||
|
#define sys_write32(x,y)
|
||||||
|
#define sys_out32(x, y)
|
||||||
|
|
||||||
#endif /* ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_ */
|
#endif /* ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_ */
|
||||||
|
|
45
include/arch/x86/intel64/linker.ld
Normal file
45
include/arch/x86/intel64/linker.ld
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Intel Corp.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
ENTRY(CONFIG_KERNEL_ENTRY)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The "locore" must be in the 64K of RAM, so that 16-bit code (with
|
||||||
|
* segment registers == 0x0000) and 32/64-bit code agree on addresses.
|
||||||
|
* ... there is no 16-bit code yet, but there will be when we add SMP.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.locore 0x8000 : ALIGN(16)
|
||||||
|
{
|
||||||
|
*(.locore)
|
||||||
|
*(.locore.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The parts of the system that don't benefit from being in the locore
|
||||||
|
* start at the 1MB mark, otherwise the system size would be artificially
|
||||||
|
* clamped by the ISA memory hole/ROM space at 0x90000-0xFFFFF.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text 0x100000 : ALIGN(16)
|
||||||
|
{
|
||||||
|
*(.text)
|
||||||
|
*(.text.*)
|
||||||
|
*(.rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
*(.comment*)
|
||||||
|
*(.debug*)
|
||||||
|
*(.got*)
|
||||||
|
*(.igot.*)
|
||||||
|
*(.iplt)
|
||||||
|
*(.note.GNU-stack)
|
||||||
|
*(.rela.*)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2014, Wind River Systems, Inc.
|
* Copyright (c) 2011-2014, Wind River Systems, Inc.
|
||||||
|
* Copyright (c) 2019 Intel Corp.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -7,6 +8,12 @@
|
||||||
#include <autoconf.h>
|
#include <autoconf.h>
|
||||||
#include <generated_dts_board.h>
|
#include <generated_dts_board.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_LONGMODE
|
||||||
|
|
||||||
|
#include <arch/x86/intel64/linker.ld>
|
||||||
|
|
||||||
|
#else /* IA32 */
|
||||||
|
|
||||||
#define PHYS_LOAD_ADDR DT_PHYS_RAM_ADDR
|
#define PHYS_LOAD_ADDR DT_PHYS_RAM_ADDR
|
||||||
#define PHYS_RAM_ADDR DT_PHYS_RAM_ADDR
|
#define PHYS_RAM_ADDR DT_PHYS_RAM_ADDR
|
||||||
|
|
||||||
|
@ -25,3 +32,4 @@ MEMORY
|
||||||
|
|
||||||
#include <arch/x86/ia32/linker.ld>
|
#include <arch/x86/ia32/linker.ld>
|
||||||
|
|
||||||
|
#endif /* CONFIG_X86_LONGMODE */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue