1 /*
2  * Copyright (c) 2019 Intel Corp.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #ifndef ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_
7 #define ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_
8 
9 #include <zephyr/arch/x86/mmustructs.h>
10 #include <zephyr/arch/x86/cet.h>
11 
12 #ifndef _ASMLANGUAGE
13 
14 /* linker symbols defining the bounds of the kernel part loaded in locore */
15 
16 extern char _locore_start[], _locore_end[];
17 
18 /*
19  * Per-CPU bootstrapping parameters. See locore.S and cpu.c.
20  */
21 
22 struct x86_cpuboot {
23 	volatile int ready;	/* CPU has started */
24 	uint16_t tr;		/* selector for task register */
25 	struct x86_tss64 *gs_base; /* Base address for GS segment */
26 	uint64_t sp;		/* initial stack pointer */
27 	size_t stack_size;	/* size of stack */
28 	arch_cpustart_t fn;	/* kernel entry function */
29 	void *arg;		/* argument for above function */
30 	uint8_t cpu_id;		/* CPU ID */
31 };
32 
33 typedef struct x86_cpuboot x86_cpuboot_t;
34 
35 struct x86_interrupt_ssp_table {
36 	uintptr_t not_used;
37 	uintptr_t ist1;
38 	uintptr_t ist2;
39 	uintptr_t ist3;
40 	uintptr_t ist4;
41 	uintptr_t ist5;
42 	uintptr_t ist6;
43 	uintptr_t ist7;
44 };
45 
46 extern uint8_t x86_cpu_loapics[];	/* CPU logical ID -> local APIC ID */
47 #endif /* _ASMLANGUAGE */
48 
49 #ifdef CONFIG_X86_KPTI
50 #define Z_X86_TRAMPOLINE_STACK_SIZE	128
51 #endif
52 
53 #ifdef CONFIG_X86_KPTI
54 #define TRAMPOLINE_STACK(n)									\
55 	uint8_t z_x86_trampoline_stack##n[Z_X86_TRAMPOLINE_STACK_SIZE]				\
56 		__attribute__ ((section(".trampolines")));
57 
58 #define TRAMPOLINE_INIT(n)									\
59 	.ist2 = (uint64_t)z_x86_trampoline_stack##n + Z_X86_TRAMPOLINE_STACK_SIZE,
60 #else
61 #define TRAMPOLINE_STACK(n)
62 #define TRAMPOLINE_INIT(n)
63 #endif /* CONFIG_X86_KPTI */
64 
65 #define ACPI_CPU_INIT(n, _)									\
66 	uint8_t z_x86_exception_stack##n[CONFIG_X86_EXCEPTION_STACK_SIZE] __aligned(16);	\
67 	uint8_t z_x86_nmi_stack##n[CONFIG_X86_EXCEPTION_STACK_SIZE] __aligned(16);		\
68 	TRAMPOLINE_STACK(n);									\
69 	Z_GENERIC_SECTION(.tss)									\
70 	struct x86_tss64 tss##n = {								\
71 		TRAMPOLINE_INIT(n)								\
72 		.ist6 =	(uint64_t)z_x86_nmi_stack##n + CONFIG_X86_EXCEPTION_STACK_SIZE,		\
73 		.ist7 = (uint64_t)z_x86_exception_stack##n + CONFIG_X86_EXCEPTION_STACK_SIZE,	\
74 		.iomapb = 0xFFFF, .cpu = &(_kernel.cpus[n])	\
75 	}
76 
77 #define X86_CPU_BOOT_INIT(n, _)									\
78 	{											\
79 		.tr = (0x40 + (16 * n)),							\
80 		.gs_base = &tss##n,								\
81 		.sp = (uint64_t)z_interrupt_stacks[n] +						\
82 		      K_KERNEL_STACK_LEN(CONFIG_ISR_STACK_SIZE),				\
83 		.stack_size = K_KERNEL_STACK_LEN(CONFIG_ISR_STACK_SIZE),			\
84 		.fn = z_prep_c,									\
85 		.arg = &x86_cpu_boot_arg,							\
86 	}
87 
88 #define SHSTK_TOKEN_ENTRY(i, name, size)							\
89 		  [size * (i + 1) / sizeof(arch_thread_hw_shadow_stack_t) - 1] =		\
90 			(uintptr_t)name + size * (i + 1) - 1 *					\
91 			sizeof(arch_thread_hw_shadow_stack_t)
92 
93 #define X86_EXCEPTION_SHADOW_STACK_SIZE \
94 	K_THREAD_HW_SHADOW_STACK_SIZE(CONFIG_X86_EXCEPTION_STACK_SIZE)
95 
96 #define X86_IRQ_SHADOW_STACK_DEFINE(name, size)							\
97 	arch_thread_hw_shadow_stack_t Z_GENERIC_SECTION(.x86shadowstack)			\
98 	__aligned(CONFIG_X86_CET_SHADOW_STACK_ALIGNMENT)					\
99 	name[CONFIG_ISR_DEPTH * size / sizeof(arch_thread_hw_shadow_stack_t)] =			\
100 		{										\
101 			LISTIFY(CONFIG_ISR_DEPTH, SHSTK_TOKEN_ENTRY, (,), name, size)		\
102 		}
103 
104 #define X86_INTERRUPT_SHADOW_STACK_DEFINE(n)							\
105 	X86_IRQ_SHADOW_STACK_DEFINE(z_x86_nmi_shadow_stack##n,					\
106 				     X86_EXCEPTION_SHADOW_STACK_SIZE);				\
107 	X86_IRQ_SHADOW_STACK_DEFINE(z_x86_exception_shadow_stack##n,				\
108 				     X86_EXCEPTION_SHADOW_STACK_SIZE)
109 
110 #define SHSTK_LAST_ENTRY (X86_EXCEPTION_SHADOW_STACK_SIZE *					\
111 			  CONFIG_ISR_DEPTH / sizeof(arch_thread_hw_shadow_stack_t) - 1)
112 
113 #define IRQ_SHSTK_LAST_ENTRY sizeof(__z_interrupt_stacks_shstk_arr[0]) /			\
114 	sizeof(arch_thread_hw_shadow_stack_t) - 1
115 
116 #define X86_INTERRUPT_SSP_TABLE_INIT(n, _)							\
117 	{											\
118 		.ist1 = (uintptr_t)&__z_interrupt_stacks_shstk_arr[n][IRQ_SHSTK_LAST_ENTRY],	\
119 		.ist6 = (uintptr_t)&z_x86_nmi_shadow_stack##n[SHSTK_LAST_ENTRY],		\
120 		.ist7 = (uintptr_t)&z_x86_exception_shadow_stack##n[SHSTK_LAST_ENTRY],	\
121 	}
122 
123 #define STACK_ARRAY_IDX(n, _) n
124 
125 #define DEFINE_STACK_ARRAY_IDX\
126 	LISTIFY(CONFIG_MP_MAX_NUM_CPUS, STACK_ARRAY_IDX, (,))
127 
128 #endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_ */
129