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