Просмотр исходного кода

Made copy_{to,from}_real volatile, so that they don't get optimised away.

Added REAL_FRAGMENT(), because it could conceivably be useful.
tags/v0.9.3
Michael Brown 19 лет назад
Родитель
Сommit
1a6ca649a2
1 измененных файлов: 49 добавлений и 18 удалений
  1. 49
    18
      src/arch/i386/include/libkir.h

+ 49
- 18
src/arch/i386/include/libkir.h Просмотреть файл

@@ -14,29 +14,31 @@
14 14
 
15 15
 static inline void copy_to_real_libkir ( uint16_t dest_seg, uint16_t dest_off,
16 16
 					 void *src, size_t n ) {
17
-	__asm__ ( "movw %4, %%es\n\t"
18
-		  "cld\n\t"
19
-		  "rep movsb\n\t"
20
-		  "pushw %%ds\n\t" /* restore %es */
21
-		  "popw %%es\n\t"
22
-		  : "=S" ( src ), "=D" ( dest_off ), "=c" ( n ) /* clobbered */
23
-		  : "S" ( src ), "r" ( dest_seg ), "D" ( dest_off ), "c" ( n )
24
-		  : "memory"
25
-		  );
17
+	__asm__ __volatile__ ( "movw %4, %%es\n\t"
18
+			       "cld\n\t"
19
+			       "rep movsb\n\t"
20
+			       "pushw %%ds\n\t" /* restore %es */
21
+			       "popw %%es\n\t"
22
+			       : "=S" ( src ), "=D" ( dest_off ),
23
+			         "=c" ( n ) /* clobbered */
24
+			       : "S" ( src ), "r" ( dest_seg ),
25
+			         "D" ( dest_off ), "c" ( n )
26
+			       : "memory" );
26 27
 }
27 28
 
28 29
 static inline void copy_from_real_libkir ( void *dest,
29 30
 					   uint16_t src_seg, uint16_t src_off,
30 31
 					   size_t n ) {
31
-	__asm__ ( "movw %%ax, %%ds\n\t"
32
-		  "cld\n\t"
33
-		  "rep movsb\n\t"
34
-		  "pushw %%es\n\t" /* restore %ds */
35
-		  "popw %%ds\n\t"
36
-		  : "=S" ( src_off ), "=D" ( dest ), "=c" ( n ) /* clobbered */
37
-		  : "a" ( src_seg ), "S" ( src_off ), "D" ( dest ), "c" ( n )
38
-		  : "memory"
39
-		  );
32
+	__asm__ __volatile__ ( "movw %%ax, %%ds\n\t"
33
+			       "cld\n\t"
34
+			       "rep movsb\n\t"
35
+			       "pushw %%es\n\t" /* restore %ds */
36
+			       "popw %%ds\n\t"
37
+			       : "=S" ( src_off ), "=D" ( dest ),
38
+			         "=c" ( n ) /* clobbered */
39
+			       : "a" ( src_seg ), "S" ( src_off ),
40
+			         "D" ( dest ), "c" ( n )
41
+			       : "memory" );
40 42
 }
41 43
 #define copy_to_real copy_to_real_libkir
42 44
 #define copy_from_real copy_from_real_libkir
@@ -122,6 +124,35 @@ static inline void copy_from_real_libkir ( void *dest,
122 124
 #define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBKIR
123 125
 #define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBKIR
124 126
 
127
+/* REAL_FRAGMENT: Declare and define a real-mode code fragment in
128
+ * .text16.  We don't need this for REAL_EXEC, since we can just
129
+ * execute our real-mode code inline, but it's handy in case someone
130
+ * genuinely wants to create a block of code that can be copied to a
131
+ * specific location and then executed.
132
+ *
133
+ * Note that we put the code in the data segment, since otherwise we
134
+ * can't (easily) access it in order to copy it to its target
135
+ * location.  We should never be calling any REAL_FRAGMENT routines
136
+ * directly anyway.
137
+ */
138
+#define	REAL_FRAGMENT( name, asm_code_str )				\
139
+	extern void name ( void );					\
140
+	extern char name ## _size[];					\
141
+	__asm__ __volatile__ (						\
142
+		".section \".data.text16\"\n\t"				\
143
+		".code16\n\t"						\
144
+		".arch i386\n\t"					\
145
+		#name ":\n\t"						\
146
+		asm_code_str "\n\t"					\
147
+		"lret\n\t"						\
148
+		#name "_end:\n\t"					\
149
+		".equ " #name "_size, " #name "_end - " #name "\n\t"	\
150
+		".code16gcc\n\t"					\
151
+		".previous\n\t"						\
152
+		: :							\
153
+	)
154
+#define FRAGMENT_SIZE( fragment ) ( (size_t) fragment ## _size )
155
+
125 156
 /* REAL_CALL: call an external real-mode routine */
126 157
 #define OUT_CONSTRAINTS(...) __VA_ARGS__
127 158
 #define IN_CONSTRAINTS(...) "m" ( __routine ), ## __VA_ARGS__

Загрузка…
Отмена
Сохранить