Zephyr Project API 4.2.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
arch.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 Intel Corp.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
15#ifndef ZEPHYR_INCLUDE_ARCH_X86_ARCH_H_
16#define ZEPHYR_INCLUDE_ARCH_X86_ARCH_H_
17
18#include <zephyr/devicetree.h>
19
20/* Changing this value will require manual changes to exception and IDT setup
21 * in locore.S for intel64
22 */
23#define Z_X86_OOPS_VECTOR 32
24
25#if !defined(_ASMLANGUAGE)
26
27#include <zephyr/sys/sys_io.h>
28#include <zephyr/types.h>
29#include <stddef.h>
30#include <stdbool.h>
31#include <zephyr/irq.h>
34#include <zephyr/arch/x86/cet.h>
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41#ifdef CONFIG_PCIE_MSI
42
43struct x86_msi_vector {
44 unsigned int irq;
45 uint8_t vector;
46#ifdef CONFIG_INTEL_VTD_ICTL
47 bool remap;
48 uint8_t irte;
49#endif
50};
51
52typedef struct x86_msi_vector arch_msi_vector_t;
53
54#endif /* CONFIG_PCIE_MSI */
55
56static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
57{
58 if ((key & 0x00000200U) != 0U) { /* 'IF' bit */
59 __asm__ volatile ("sti" ::: "memory");
60 }
61}
62
63static ALWAYS_INLINE void sys_out8(uint8_t data, io_port_t port)
64{
65 __asm__ volatile("outb %b0, %w1" :: "a"(data), "Nd"(port));
66}
67
69{
70 uint8_t ret;
71
72 __asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port));
73
74 return ret;
75}
76
78{
79 __asm__ volatile("outw %w0, %w1" :: "a"(data), "Nd"(port));
80}
81
83{
84 uint16_t ret;
85
86 __asm__ volatile("inw %w1, %w0" : "=a"(ret) : "Nd"(port));
87
88 return ret;
89}
90
92{
93 __asm__ volatile("outl %0, %w1" :: "a"(data), "Nd"(port));
94}
95
97{
98 uint32_t ret;
99
100 __asm__ volatile("inl %w1, %0" : "=a"(ret) : "Nd"(port));
101
102 return ret;
103}
104
106{
107 __asm__ volatile("movb %0, %1"
108 :
109 : "q"(data), "m" (*(volatile uint8_t *)(uintptr_t) addr)
110 : "memory");
111}
112
114{
115 uint8_t ret;
116
117 __asm__ volatile("movb %1, %0"
118 : "=q"(ret)
119 : "m" (*(volatile uint8_t *)(uintptr_t) addr)
120 : "memory");
121
122 return ret;
123}
124
126{
127 __asm__ volatile("movw %0, %1"
128 :
129 : "r"(data), "m" (*(volatile uint16_t *)(uintptr_t) addr)
130 : "memory");
131}
132
134{
135 uint16_t ret;
136
137 __asm__ volatile("movw %1, %0"
138 : "=r"(ret)
139 : "m" (*(volatile uint16_t *)(uintptr_t) addr)
140 : "memory");
141
142 return ret;
143}
144
146{
147 __asm__ volatile("movl %0, %1"
148 :
149 : "r"(data), "m" (*(volatile uint32_t *)(uintptr_t) addr)
150 : "memory");
151}
152
154{
155 uint32_t ret;
156
157 __asm__ volatile("movl %1, %0"
158 : "=r"(ret)
159 : "m" (*(volatile uint32_t *)(uintptr_t) addr)
160 : "memory");
161
162 return ret;
163}
164
165static ALWAYS_INLINE void sys_set_bit(mem_addr_t addr, unsigned int bit)
166{
167 __asm__ volatile("btsl %1, %0"
168 : "+m" (*(volatile uint8_t *) (addr))
169 : "Ir" (bit)
170 : "memory");
171}
172
173static ALWAYS_INLINE void sys_clear_bit(mem_addr_t addr, unsigned int bit)
174{
175 __asm__ volatile("btrl %1, %0"
176 : "+m" (*(volatile uint8_t *) (addr))
177 : "Ir" (bit));
178}
179
180static ALWAYS_INLINE int sys_test_bit(mem_addr_t addr, unsigned int bit)
181{
182 int ret;
183
184 __asm__ volatile("btl %2, %1;"
185 "sbb %0, %0"
186 : "=r" (ret), "+m" (*(volatile uint8_t *) (addr))
187 : "Ir" (bit));
188
189 return ret;
190}
191
193 unsigned int bit)
194{
195 int ret;
196
197 __asm__ volatile("btsl %2, %1;"
198 "sbb %0, %0"
199 : "=r" (ret), "+m" (*(volatile uint8_t *) (addr))
200 : "Ir" (bit));
201
202 return ret;
203}
204
206 unsigned int bit)
207{
208 int ret;
209
210 __asm__ volatile("btrl %2, %1;"
211 "sbb %0, %0"
212 : "=r" (ret), "+m" (*(volatile uint8_t *) (addr))
213 : "Ir" (bit));
214
215 return ret;
216}
217
218#define sys_bitfield_set_bit sys_set_bit
219#define sys_bitfield_clear_bit sys_clear_bit
220#define sys_bitfield_test_bit sys_test_bit
221#define sys_bitfield_test_and_set_bit sys_test_and_set_bit
222#define sys_bitfield_test_and_clear_bit sys_test_and_clear_bit
223
224/*
225 * Map of IRQ numbers to their assigned vectors. On IA32, this is generated
226 * at build time and defined via the linker script. On Intel64, it's an array.
227 */
228
229extern unsigned char _irq_to_interrupt_vector[CONFIG_MAX_IRQ_LINES];
230
231#define Z_IRQ_TO_INTERRUPT_VECTOR(irq) \
232 ((unsigned int) _irq_to_interrupt_vector[(irq)])
233
234
235#endif /* _ASMLANGUAGE */
236
237#ifdef __cplusplus
238}
239#endif
240
242
243#ifdef CONFIG_X86_64
245#else
247#endif
248
250
251#ifdef __cplusplus
252extern "C" {
253#endif
254
255#ifndef _ASMLANGUAGE
256
257void arch_irq_enable(unsigned int irq);
258void arch_irq_disable(unsigned int irq);
259
261
262__pinned_func
263static inline uint32_t arch_k_cycle_get_32(void)
264{
265 return sys_clock_cycle_get_32();
266}
267
269
270__pinned_func
271static inline uint64_t arch_k_cycle_get_64(void)
272{
273 return sys_clock_cycle_get_64();
274}
275
276static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
277{
278 return (key & 0x200) != 0;
279}
280
285static ALWAYS_INLINE uint32_t z_do_read_cpu_timestamp32(void)
286{
287 uint32_t rv;
288
289 __asm__ volatile("rdtsc" : "=a" (rv) : : "%edx");
290
291 return rv;
292}
293
298__pinned_func
299static inline uint64_t z_tsc_read(void)
300{
301 union {
302 struct {
303 uint32_t lo;
304 uint32_t hi;
305 };
306 uint64_t value;
307 } rv;
308
309#ifdef CONFIG_X86_64
310 /*
311 * According to Intel 64 and IA-32 Architectures Software
312 * Developer’s Manual, volume 3, chapter 8.2.5, LFENCE provides
313 * a more efficient method of controlling memory ordering than
314 * the CPUID instruction. So use LFENCE here, as all 64-bit
315 * CPUs have LFENCE.
316 */
317 __asm__ volatile ("lfence");
318#else
319 /* rdtsc & cpuid clobbers eax, ebx, ecx and edx registers */
320 __asm__ volatile (/* serialize */
321 "xorl %%eax,%%eax;"
322 "cpuid"
323 :
324 :
325 : "%eax", "%ebx", "%ecx", "%edx"
326 );
327#endif
328
329#ifdef CONFIG_X86_64
330 /*
331 * We cannot use "=A", since this would use %rax on x86_64 and
332 * return only the lower 32bits of the TSC
333 */
334 __asm__ volatile ("rdtsc" : "=a" (rv.lo), "=d" (rv.hi));
335#else
336 /* "=A" means that value is in eax:edx pair. */
337 __asm__ volatile ("rdtsc" : "=A" (rv.value));
338#endif
339
340 return rv.value;
341}
342
343static ALWAYS_INLINE void arch_nop(void)
344{
345 __asm__ volatile("nop");
346}
347
348#endif /* _ASMLANGUAGE */
349
350#ifdef __cplusplus
351}
352#endif
353
354#endif /* ZEPHYR_INCLUDE_ARCH_X86_ARCH_H_ */
static ALWAYS_INLINE void arch_nop(void)
Definition arch.h:348
#define arch_irq_disable(irq)
Definition irq.h:44
#define arch_irq_enable(irq)
Definition irq.h:43
irp hi
Definition asm-macro-32-bit-gnu.h:10
Devicetree main header.
#define ALWAYS_INLINE
Definition common.h:160
Public interface for configuring interrupts.
static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
Definition arch.h:83
uint64_t sys_clock_cycle_get_64(void)
uint32_t sys_clock_cycle_get_32(void)
static uint32_t arch_k_cycle_get_32(void)
Definition arch.h:108
static uint64_t arch_k_cycle_get_64(void)
Definition arch.h:115
static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
Definition arch.h:96
Definitions of various linker Sections.
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT64_TYPE__ uint64_t
Definition stdint.h:91
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:105
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
uint32_t io_port_t
Definition sys_io.h:19
uintptr_t mm_reg_t
Definition sys_io.h:20
uintptr_t mem_addr_t
Definition sys_io.h:21
static ALWAYS_INLINE int sys_test_and_set_bit(mem_addr_t addr, unsigned int bit)
Definition arch.h:192
static ALWAYS_INLINE void sys_set_bit(mem_addr_t addr, unsigned int bit)
Definition arch.h:165
static ALWAYS_INLINE uint8_t sys_in8(io_port_t port)
Definition arch.h:68
static ALWAYS_INLINE void sys_write8(uint8_t data, mm_reg_t addr)
Definition arch.h:105
static ALWAYS_INLINE void sys_clear_bit(mem_addr_t addr, unsigned int bit)
Definition arch.h:173
static ALWAYS_INLINE int sys_test_bit(mem_addr_t addr, unsigned int bit)
Definition arch.h:180
static ALWAYS_INLINE void sys_out8(uint8_t data, io_port_t port)
Definition arch.h:63
static ALWAYS_INLINE uint32_t sys_read32(mm_reg_t addr)
Definition arch.h:153
static ALWAYS_INLINE void sys_out16(uint16_t data, io_port_t port)
Definition arch.h:77
static ALWAYS_INLINE uint16_t sys_read16(mm_reg_t addr)
Definition arch.h:133
static ALWAYS_INLINE uint16_t sys_in16(io_port_t port)
Definition arch.h:82
static ALWAYS_INLINE void sys_write16(uint16_t data, mm_reg_t addr)
Definition arch.h:125
static ALWAYS_INLINE int sys_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
Definition arch.h:205
static ALWAYS_INLINE uint8_t sys_read8(mm_reg_t addr)
Definition arch.h:113
static ALWAYS_INLINE void sys_out32(uint32_t data, io_port_t port)
Definition arch.h:91
static ALWAYS_INLINE void sys_write32(uint32_t data, mm_reg_t addr)
Definition arch.h:145
static ALWAYS_INLINE uint32_t sys_in32(io_port_t port)
Definition arch.h:96
IA-32 specific kernel interface header.
Intel-64 specific kernel interface header.