1 | #ifndef LIBRM_H |
---|
2 | #define LIBRM_H |
---|
3 | |
---|
4 | FILE_LICENCE ( GPL2_OR_LATER ); |
---|
5 | |
---|
6 | /* Segment selectors as used in our protected-mode GDTs. |
---|
7 | * |
---|
8 | * Don't change these unless you really know what you're doing. |
---|
9 | */ |
---|
10 | |
---|
11 | #define VIRTUAL_CS 0x08 |
---|
12 | #define VIRTUAL_DS 0x10 |
---|
13 | #define PHYSICAL_CS 0x18 |
---|
14 | #define PHYSICAL_DS 0x20 |
---|
15 | #define REAL_CS 0x28 |
---|
16 | #define REAL_DS 0x30 |
---|
17 | #if 0 |
---|
18 | #define LONG_CS 0x38 |
---|
19 | #define LONG_DS 0x40 |
---|
20 | #endif |
---|
21 | |
---|
22 | #ifndef ASSEMBLY |
---|
23 | |
---|
24 | #ifdef UACCESS_LIBRM |
---|
25 | #define UACCESS_PREFIX_librm |
---|
26 | #else |
---|
27 | #define UACCESS_PREFIX_librm __librm_ |
---|
28 | #endif |
---|
29 | |
---|
30 | /* Variables in librm.S */ |
---|
31 | extern unsigned long virt_offset; |
---|
32 | |
---|
33 | /** |
---|
34 | * Convert physical address to user pointer |
---|
35 | * |
---|
36 | * @v phys_addr Physical address |
---|
37 | * @ret userptr User pointer |
---|
38 | */ |
---|
39 | static inline __always_inline userptr_t |
---|
40 | UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) { |
---|
41 | return ( phys_addr - virt_offset ); |
---|
42 | } |
---|
43 | |
---|
44 | /** |
---|
45 | * Convert user buffer to physical address |
---|
46 | * |
---|
47 | * @v userptr User pointer |
---|
48 | * @v offset Offset from user pointer |
---|
49 | * @ret phys_addr Physical address |
---|
50 | */ |
---|
51 | static inline __always_inline unsigned long |
---|
52 | UACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) { |
---|
53 | return ( userptr + offset + virt_offset ); |
---|
54 | } |
---|
55 | |
---|
56 | static inline __always_inline userptr_t |
---|
57 | UACCESS_INLINE ( librm, virt_to_user ) ( volatile const void *addr ) { |
---|
58 | return trivial_virt_to_user ( addr ); |
---|
59 | } |
---|
60 | |
---|
61 | static inline __always_inline void * |
---|
62 | UACCESS_INLINE ( librm, user_to_virt ) ( userptr_t userptr, off_t offset ) { |
---|
63 | return trivial_user_to_virt ( userptr, offset ); |
---|
64 | } |
---|
65 | |
---|
66 | static inline __always_inline userptr_t |
---|
67 | UACCESS_INLINE ( librm, userptr_add ) ( userptr_t userptr, off_t offset ) { |
---|
68 | return trivial_userptr_add ( userptr, offset ); |
---|
69 | } |
---|
70 | |
---|
71 | static inline __always_inline void |
---|
72 | UACCESS_INLINE ( librm, memcpy_user ) ( userptr_t dest, off_t dest_off, |
---|
73 | userptr_t src, off_t src_off, |
---|
74 | size_t len ) { |
---|
75 | trivial_memcpy_user ( dest, dest_off, src, src_off, len ); |
---|
76 | } |
---|
77 | |
---|
78 | static inline __always_inline void |
---|
79 | UACCESS_INLINE ( librm, memmove_user ) ( userptr_t dest, off_t dest_off, |
---|
80 | userptr_t src, off_t src_off, |
---|
81 | size_t len ) { |
---|
82 | trivial_memmove_user ( dest, dest_off, src, src_off, len ); |
---|
83 | } |
---|
84 | |
---|
85 | static inline __always_inline void |
---|
86 | UACCESS_INLINE ( librm, memset_user ) ( userptr_t buffer, off_t offset, |
---|
87 | int c, size_t len ) { |
---|
88 | trivial_memset_user ( buffer, offset, c, len ); |
---|
89 | } |
---|
90 | |
---|
91 | static inline __always_inline size_t |
---|
92 | UACCESS_INLINE ( librm, strlen_user ) ( userptr_t buffer, off_t offset ) { |
---|
93 | return trivial_strlen_user ( buffer, offset ); |
---|
94 | } |
---|
95 | |
---|
96 | static inline __always_inline off_t |
---|
97 | UACCESS_INLINE ( librm, memchr_user ) ( userptr_t buffer, off_t offset, |
---|
98 | int c, size_t len ) { |
---|
99 | return trivial_memchr_user ( buffer, offset, c, len ); |
---|
100 | } |
---|
101 | |
---|
102 | |
---|
103 | /****************************************************************************** |
---|
104 | * |
---|
105 | * Access to variables in .data16 and .text16 |
---|
106 | * |
---|
107 | */ |
---|
108 | |
---|
109 | extern char *data16; |
---|
110 | extern char *text16; |
---|
111 | |
---|
112 | #define __data16( variable ) \ |
---|
113 | __attribute__ (( section ( ".data16" ) )) \ |
---|
114 | _data16_ ## variable __asm__ ( #variable ) |
---|
115 | |
---|
116 | #define __data16_array( variable, array ) \ |
---|
117 | __attribute__ (( section ( ".data16" ) )) \ |
---|
118 | _data16_ ## variable array __asm__ ( #variable ) |
---|
119 | |
---|
120 | #define __bss16( variable ) \ |
---|
121 | __attribute__ (( section ( ".bss16" ) )) \ |
---|
122 | _data16_ ## variable __asm__ ( #variable ) |
---|
123 | |
---|
124 | #define __bss16_array( variable, array ) \ |
---|
125 | __attribute__ (( section ( ".bss16" ) )) \ |
---|
126 | _data16_ ## variable array __asm__ ( #variable ) |
---|
127 | |
---|
128 | #define __text16( variable ) \ |
---|
129 | __attribute__ (( section ( ".text16.data" ) )) \ |
---|
130 | _text16_ ## variable __asm__ ( #variable ) |
---|
131 | |
---|
132 | #define __text16_array( variable, array ) \ |
---|
133 | __attribute__ (( section ( ".text16.data" ) )) \ |
---|
134 | _text16_ ## variable array __asm__ ( #variable ) |
---|
135 | |
---|
136 | #define __use_data16( variable ) \ |
---|
137 | ( * ( ( typeof ( _data16_ ## variable ) * ) \ |
---|
138 | & ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) ) |
---|
139 | |
---|
140 | #define __use_text16( variable ) \ |
---|
141 | ( * ( ( typeof ( _text16_ ## variable ) * ) \ |
---|
142 | & ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) ) |
---|
143 | |
---|
144 | #define __from_data16( pointer ) \ |
---|
145 | ( ( unsigned int ) \ |
---|
146 | ( ( ( void * ) (pointer) ) - ( ( void * ) data16 ) ) ) |
---|
147 | |
---|
148 | #define __from_text16( pointer ) \ |
---|
149 | ( ( unsigned int ) \ |
---|
150 | ( ( ( void * ) (pointer) ) - ( ( void * ) text16 ) ) ) |
---|
151 | |
---|
152 | /* Variables in librm.S, present in the normal data segment */ |
---|
153 | extern uint16_t rm_sp; |
---|
154 | extern uint16_t rm_ss; |
---|
155 | extern uint16_t __data16 ( rm_cs ); |
---|
156 | #define rm_cs __use_data16 ( rm_cs ) |
---|
157 | extern uint16_t __text16 ( rm_ds ); |
---|
158 | #define rm_ds __use_text16 ( rm_ds ) |
---|
159 | |
---|
160 | /* Functions that librm expects to be able to link to. Included here |
---|
161 | * so that the compiler will catch prototype mismatches. |
---|
162 | */ |
---|
163 | extern void gateA20_set ( void ); |
---|
164 | |
---|
165 | /** |
---|
166 | * Convert segment:offset address to user buffer |
---|
167 | * |
---|
168 | * @v segment Real-mode segment |
---|
169 | * @v offset Real-mode offset |
---|
170 | * @ret buffer User buffer |
---|
171 | */ |
---|
172 | static inline __always_inline userptr_t |
---|
173 | real_to_user ( unsigned int segment, unsigned int offset ) { |
---|
174 | return ( phys_to_user ( ( segment << 4 ) + offset ) ); |
---|
175 | } |
---|
176 | |
---|
177 | extern uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ); |
---|
178 | extern void remove_user_from_rm_stack ( userptr_t data, size_t size ); |
---|
179 | |
---|
180 | /* TEXT16_CODE: declare a fragment of code that resides in .text16 */ |
---|
181 | #define TEXT16_CODE( asm_code_str ) \ |
---|
182 | ".section \".text16\", \"ax\", @progbits\n\t" \ |
---|
183 | ".code16\n\t" \ |
---|
184 | asm_code_str "\n\t" \ |
---|
185 | ".code32\n\t" \ |
---|
186 | ".previous\n\t" |
---|
187 | |
---|
188 | /* REAL_CODE: declare a fragment of code that executes in real mode */ |
---|
189 | #define REAL_CODE( asm_code_str ) \ |
---|
190 | "pushl $1f\n\t" \ |
---|
191 | "call real_call\n\t" \ |
---|
192 | "addl $4, %%esp\n\t" \ |
---|
193 | TEXT16_CODE ( "\n1:\n\t" \ |
---|
194 | asm_code_str \ |
---|
195 | "\n\t" \ |
---|
196 | "ret\n\t" ) |
---|
197 | |
---|
198 | /* PHYS_CODE: declare a fragment of code that executes in flat physical mode */ |
---|
199 | #define PHYS_CODE( asm_code_str ) \ |
---|
200 | "call _virt_to_phys\n\t" \ |
---|
201 | asm_code_str \ |
---|
202 | "call _phys_to_virt\n\t" |
---|
203 | |
---|
204 | #endif /* ASSEMBLY */ |
---|
205 | |
---|
206 | #endif /* LIBRM_H */ |
---|