xref: /haiku/headers/private/kernel/arch/x86/arch_cpu.h (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 /*
2 ** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 #ifndef _KERNEL_ARCH_x86_CPU_H
6 #define _KERNEL_ARCH_x86_CPU_H
7 
8 #include <ktypes.h>
9 #include <arch/x86/thread_struct.h>
10 #include <arch/x86/descriptors.h>
11 
12 #define PAGE_SIZE 4096
13 
14 #define _BIG_ENDIAN 0
15 #define _LITTLE_ENDIAN 1
16 
17 struct tss {
18 	uint16 prev_task;
19 	uint16 unused0;
20 	uint32 sp0;
21 	uint32 ss0;
22 	uint32 sp1;
23 	uint32 ss1;
24 	uint32 sp2;
25 	uint32 ss2;
26 	uint32 sp3;
27 	uint32 ss3;
28 	uint32 cr3;
29 	uint32 eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
30 	uint32 es, cs, ss, ds, fs, gs;
31 	uint32 ldt_seg_selector;
32 	uint16 unused1;
33 	uint16 io_map_base;
34 };
35 
36 /**************************************************************************/
37 
38 typedef struct ptentry {		// page table entry
39 	unsigned int present:1;
40 	unsigned int rw:1;
41 	unsigned int user:1;
42 	unsigned int write_through:1;
43 	unsigned int cache_disabled:1;
44 	unsigned int accessed:1;
45 	unsigned int dirty:1;
46 	unsigned int reserved:1;
47 	unsigned int global:1;
48 	unsigned int avail:3;
49 	unsigned int addr:20;
50 } ptentry;
51 
52 typedef struct pdentry {		// page directory entry
53 	unsigned int present:1;
54 	unsigned int rw:1;
55 	unsigned int user:1;
56 	unsigned int write_through:1;
57 	unsigned int cache_disabled:1;
58 	unsigned int accessed:1;
59 	unsigned int reserved:1;
60 	unsigned int page_size:1;
61 	unsigned int global:1;
62 	unsigned int avail:3;
63 	unsigned int addr:20;
64 } pdentry;
65 
66 struct iframe {
67 	unsigned int gs;
68 	unsigned int fs;
69 	unsigned int es;
70 	unsigned int ds;
71 	unsigned int edi;
72 	unsigned int esi;
73 	unsigned int ebp;
74 	unsigned int esp;
75 	unsigned int ebx;
76 	unsigned int edx;
77 	unsigned int ecx;
78 	unsigned int eax;
79 	unsigned int orig_eax;
80 	unsigned int orig_edx;
81 	unsigned int vector;
82 	unsigned int error_code;
83 	unsigned int eip;
84 	unsigned int cs;
85 	unsigned int flags;
86 	unsigned int user_esp;
87 	unsigned int user_ss;
88 };
89 
90 #define nop() __asm__ ("nop"::)
91 
92 void setup_system_time(unsigned int cv_factor);
93 void i386_context_switch(struct arch_thread *old_state, struct arch_thread *new_state, addr new_pgdir);
94 void i386_enter_uspace(addr entry, void *args1, void *args2, addr ustack_top);
95 void i386_set_tss_and_kstack(addr kstack);
96 void i386_switch_stack_and_call(addr stack, void (*func)(void *), void *arg);
97 void i386_swap_pgdir(addr new_pgdir);
98 void i386_fsave(void *fpu_state);
99 void i386_fxsave(void *fpu_state);
100 void i386_frstor(void *fpu_state);
101 void i386_fxrstor(void *fpu_state);
102 void i386_fsave_swap(void *old_fpu_state, void *new_fpu_state);
103 void i386_fxsave_swap(void *old_fpu_state, void *new_fpu_state);
104 
105 #define read_ebp(value) \
106 	__asm__("movl	%%ebp,%0" : "=r" (value))
107 
108 #define read_dr3(value) \
109 	__asm__("movl	%%dr3,%0" : "=r" (value))
110 
111 #define write_dr3(value) \
112 	__asm__("movl	%0,%%dr3" : : "r" (value))
113 
114 #define invalidate_TLB(va) \
115 	__asm__("invlpg (%0)" : : "r" (va))
116 
117 #define out8(value,port) \
118 __asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
119 
120 #define out16(value,port) \
121 __asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port))
122 
123 #define out32(value,port) \
124 __asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port))
125 
126 #define in8(port) ({ \
127 unsigned char _v; \
128 __asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \
129 _v; \
130 })
131 
132 #define in16(port) ({ \
133 unsigned short _v; \
134 __asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \
135 _v; \
136 })
137 
138 #define in32(port) ({ \
139 unsigned int _v; \
140 __asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \
141 _v; \
142 })
143 
144 #define out8_p(value,port) \
145 __asm__ ("outb %%al,%%dx\n" \
146 		"\tjmp 1f\n" \
147 		"1:\tjmp 1f\n" \
148 		"1:" : : "a" (value), "d" (port))
149 
150 #define in8_p(port) ({ \
151 unsigned char _v; \
152 __asm__ volatile ("inb %%dx,%%al\n" \
153 	"\tjmp 1f\n" \
154 	"1:\tjmp 1f\n" \
155 	"1:" : "=a" (_v) : "d" (port)); \
156 _v; \
157 })
158 
159 extern segment_descriptor *gGDT;
160 
161 #endif	/* _KERNEL_ARCH_x86_CPU_H */
162