1 /*
2  * Copyright (c) 2019 Intel Corp.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_
7 #define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_
8 
9 #include <zephyr/arch/x86/intel64/exception.h>
10 #include <zephyr/arch/x86/intel64/thread.h>
11 #include <zephyr/arch/x86/thread_stack.h>
12 #if defined(CONFIG_PCIE) && !defined(_ASMLANGUAGE)
13 #include <zephyr/sys/iterable_sections.h>
14 #endif
15 
16 #if CONFIG_ISR_STACK_SIZE != (CONFIG_ISR_SUBSTACK_SIZE * CONFIG_ISR_DEPTH)
17 #error "Check ISR stack configuration (CONFIG_ISR_*)"
18 #endif
19 
20 #if CONFIG_ISR_SUBSTACK_SIZE % ARCH_STACK_PTR_ALIGN
21 #error "CONFIG_ISR_SUBSTACK_SIZE must be a multiple of 16"
22 #endif
23 
24 #ifndef _ASMLANGUAGE
25 
sys_write64(uint64_t data,mm_reg_t addr)26 static ALWAYS_INLINE void sys_write64(uint64_t data, mm_reg_t addr)
27 {
28 	__asm__ volatile("movq %0, %1"
29 			 :
30 			 : "r"(data), "m" (*(volatile uint64_t *)
31 					   (uintptr_t) addr)
32 			 : "memory");
33 }
34 
sys_read64(mm_reg_t addr)35 static ALWAYS_INLINE uint64_t sys_read64(mm_reg_t addr)
36 {
37 	uint64_t ret;
38 
39 	__asm__ volatile("movq %1, %0"
40 			 : "=r"(ret)
41 			 : "m" (*(volatile uint64_t *)(uintptr_t) addr)
42 			 : "memory");
43 
44 	return ret;
45 }
46 
arch_irq_lock(void)47 static ALWAYS_INLINE unsigned int arch_irq_lock(void)
48 {
49 	unsigned long key;
50 
51 	__asm__ volatile ("pushfq; cli; popq %0" : "=g" (key) : : "memory");
52 
53 	return (unsigned int) key;
54 }
55 
56 #define ARCH_EXCEPT(reason_p) do { \
57 	__asm__ volatile( \
58 		"movq %[reason], %%rax\n\t" \
59 		"int $32\n\t" \
60 		: \
61 		: [reason] "i" (reason_p)); \
62 	CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ \
63 } while (false)
64 
65 #ifdef CONFIG_PCIE
66 #define X86_RESERVE_IRQ(irq_p, name) \
67 	static TYPE_SECTION_ITERABLE(uint8_t, name, irq_alloc, name) = irq_p
68 #else
69 #define X86_RESERVE_IRQ(irq_p, name)
70 #endif
71 
72 #endif /* _ASMLANGUAGE */
73 
74 /*
75  * All Intel64 interrupts are dynamically connected.
76  */
77 
78 #define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
79 	X86_RESERVE_IRQ(irq_p, _CONCAT(_irq_alloc_fixed, __COUNTER__)); \
80 	arch_irq_connect_dynamic(irq_p, priority_p,			\
81 				 (void (*)(const void *))isr_p,		\
82 				 isr_param_p, flags_p)
83 
84 #ifdef CONFIG_PCIE
85 
86 #define ARCH_PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p,			\
87 			      isr_p, isr_param_p, flags_p)		\
88 	X86_RESERVE_IRQ(irq_p, _CONCAT(_irq_alloc_fixed, __COUNTER__)); \
89 	pcie_connect_dynamic_irq(bdf_p, irq_p, priority_p,		\
90 				 (void (*)(const void *))isr_p,		\
91 				 isr_param_p, flags_p)
92 
93 #endif /* CONFIG_PCIE */
94 
95 /*
96  * Thread object needs to be 16-byte aligned.
97  */
98 #define ARCH_DYNAMIC_OBJ_K_THREAD_ALIGNMENT	16
99 
100 #endif /* ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_ */
101