Переглянути джерело

Cope with regions bigger than 4GB.

We now split e820 regions around ourselves, rather than just
truncating the e820 region.  This avoids the worst-case scenario of
losing all memory over 4GB.

It's more important to get the memory map right now that we're
expecting to still be loaded when the OS starts in several situations
(e.g. Linux with UNDI driver, any OS with iSCSI/AoE boot, etc.).
tags/v0.9.3
Michael Brown 18 роки тому
джерело
коміт
5ec2b2c251
1 змінених файлів з 370 додано та 243 видалено
  1. 370
    243
      src/arch/i386/firmware/pcbios/e820mangler.S

+ 370
- 243
src/arch/i386/firmware/pcbios/e820mangler.S Переглянути файл

@@ -1,296 +1,423 @@
1
-#undef CODE16
2
-#if defined(PCBIOS)
3
-#define	CODE16
4
-#endif
5
-
6
-#ifdef CODE16
7
-	
8
-#define BOCHSBP xchgw %bx,%bx
1
+/*
2
+ * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
9 18
 	
10 19
 	.text
11 20
 	.arch i386
12 21
 	.section ".text16", "ax", @progbits
22
+	.section ".data16", "aw", @progbits
23
+	.section ".text16.data", "aw", @progbits
13 24
 	.code16
14 25
 
26
+#define SMAP 0x534d4150
27
+
15 28
 /****************************************************************************
16
- * Memory map mangling code
29
+ * Check for overlap
30
+ *
31
+ * Parameters:
32
+ *  %edx:%eax	Region start
33
+ *  %ecx:%ebx	Region end
34
+ *  %si		Pointer to hidden region descriptor
35
+ * Returns:
36
+ *  CF set	Region overlaps
37
+ *  CF clear	No overlap
17 38
  ****************************************************************************
18
- */
39
+ */ 
40
+	.section ".text16"
41
+check_overlap:
42
+	/* If start >= hidden_end, there is no overlap. */
43
+	testl	%edx, %edx
44
+	jnz	no_overlap
45
+	cmpl	4(%si), %eax
46
+	jae	no_overlap
47
+	/* If end <= hidden_start, there is no overlap; equivalently,
48
+	 * if end > hidden_start, there is overlap.
49
+	*/
50
+	testl	%ecx, %ecx
51
+	jnz	overlap
52
+	cmpl	0(%si), %ebx
53
+	ja	overlap
54
+no_overlap:
55
+	clc
56
+	ret
57
+overlap:
58
+	stc
59
+	ret
60
+	.size check_overlap, . - check_overlap
19 61
 
20
-	.globl	e820mangler
21
-e820mangler:
62
+/****************************************************************************
63
+ * Check for overflow/underflow
64
+ *
65
+ * Parameters:
66
+ *  %edx:%eax	Region start
67
+ *  %ecx:%ebx	Region end
68
+ * Returns:
69
+ *  CF set	start < end
70
+ *  CF clear	start >= end
71
+ ****************************************************************************
72
+ */
73
+	.section ".text16"
74
+check_overflow:
75
+	pushl	%ecx
76
+	pushl	%ebx
77
+	subl	%eax, %ebx
78
+	sbbl	%edx, %ecx
79
+	popl	%ebx
80
+	popl	%ecx
81
+	ret
82
+	.size check_overflow, . - check_overflow
83
+	
84
+/****************************************************************************
85
+ * Truncate towards start of region
86
+ *
87
+ * Parameters:
88
+ *  %edx:%eax	Region start
89
+ *  %ecx:%ebx	Region end
90
+ *  %si		Pointer to hidden region descriptor
91
+ * Returns:
92
+ *  %edx:%eax	Modified region start
93
+ *  %ecx:%ebx	Modified region end
94
+ *  CF set	Region was truncated
95
+ *  CF clear	Region was not truncated
96
+ ****************************************************************************
97
+ */
98
+	.section ".text16"
99
+truncate_to_start:
100
+	/* If overlaps, set region end = hidden region start */
101
+	call	check_overlap
102
+	jnc	99f
103
+	movl	0(%si), %ebx
104
+	xorl	%ecx, %ecx
105
+	/* If region end < region start, set region end = region start */
106
+	call	check_overflow
107
+	jnc	1f
108
+	movl	%eax, %ebx
109
+	movl	%edx, %ecx
110
+1:	stc
111
+99:	ret
112
+	.size truncate_to_start, . - truncate_to_start
22 113
 
23
-/* Macro to calculate offset of labels within code segment in
24
- * installed copy of code.
114
+/****************************************************************************
115
+ * Truncate towards end of region
116
+ *
117
+ * Parameters:
118
+ *  %edx:%eax	Region start
119
+ *  %ecx:%ebx	Region end
120
+ *  %si		Pointer to hidden region descriptor
121
+ * Returns:
122
+ *  %edx:%eax	Modified region start
123
+ *  %ecx:%ebx	Modified region end
124
+ *  CF set	Region was truncated
125
+ *  CF clear	Region was not truncated
126
+ ****************************************************************************
25 127
  */
26
-#define INSTALLED(x) ( (x) - e820mangler )
128
+	.section ".text16"
129
+truncate_to_end:
130
+	/* If overlaps, set region start = hidden region end */
131
+	call	check_overlap
132
+	jnc	99f
133
+	movl	4(%si), %eax
134
+	xorl	%edx, %edx
135
+	/* If region start > region end, set region start = region end */
136
+	call	check_overflow
137
+	jnc	1f
138
+	movl	%ebx, %eax
139
+	movl	%ecx, %edx
140
+1:	stc
141
+99:	ret
142
+	.size truncate_to_end, . - truncate_to_end
27 143
 	
28 144
 /****************************************************************************
29
- * Intercept INT 15 memory calls and remove the hidden memory ranges
30
- * from the resulting memory map.
145
+ * Truncate region
146
+ *
147
+ * Parameters:
148
+ *  %edx:%eax	Region start
149
+ *  %ecx:%ebx	Region length (*not* region end)
150
+ *  %bp		truncate_to_start or truncate_to_end
151
+ * Returns:
152
+ *  %edx:%eax	Modified region start
153
+ *  %ecx:%ebx	Modified region length
154
+ *  CF set	Region was truncated
155
+ *  CF clear	Region was not truncated
31 156
  ****************************************************************************
32 157
  */
33
-	.globl	_intercept_int15
34
-_intercept_int15:
35
-	/* Preserve registers */
36
-	pushw	%bp
37
-	/* Store %ax for future reference */
38
-	pushw	%ax
39
-	/* Make INT-style call to old INT15 routine */
158
+	.section ".text16"
159
+truncate:
160
+	pushw	%si
40 161
 	pushfw
41
-	lcall	%cs:*INSTALLED(_intercepted_int15)
42
-	/* Preserve flags returned by original E820 routine */
162
+	/* Convert (start,len) to (start,end) */
163
+	addl	%eax, %ebx
164
+	adcl	%edx, %ecx
165
+	/* Hide all hidden regions, truncating as directed */
166
+	movw	$hidden_regions, %si
167
+1:	call	*%bp
168
+	jnc	2f
169
+	popfw	/* If CF was set, set stored CF in flags word on stack */
170
+	stc
43 171
 	pushfw
44
-	/* Check for valid INT15 routine */
45
-	jc	intercept_int15_exit
46
-	/* Check for a routine we want to intercept */
47
-	movw	%sp, %bp
48
-	cmpw	$0xe820, 2(%bp)
49
-	je	intercept_e820
50
-	cmpw	$0xe801, 2(%bp)
51
-	je	intercept_e801
52
-	cmpb	$0x88, 3(%bp)
53
-	je	intercept_88
54
-intercept_int15_exit:
55
-	/* Restore registers and return */
172
+2:	addw	$8, %si
173
+	cmpl	$0, 0(%si)
174
+	jne	1b
175
+	/* Convert modified (start,end) back to (start,len) */
176
+	subl	%eax, %ebx
177
+	sbbl	%edx, %ecx
56 178
 	popfw
57
-	popw	%bp			/* discard original %ax */
58
-	popw	%bp
59
-	lret	$2			/* 'iret' - flags already loaded */
179
+	popw	%si
180
+	ret
181
+	.size truncate, . - truncate
60 182
 
61
-	.globl	_intercepted_int15
62
-_intercepted_int15:	.word 0,0
63
-		
64 183
 /****************************************************************************
65
- * Exclude an address range from a potentially overlapping address range
66
- *
67
- * Note: this *can* be called even if the range doesn't overlap; it
68
- * will simply return the range unaltered.  It copes with all the
69
- * possible cases of overlap, including total overlap (which will
70
- * modify the range to length zero).  If the to-be-excluded range is
71
- * in the middle of the target range, then the larger remaining
72
- * portion will be returned.  If %di is nonzero on entry then the
73
- * range will only be truncated from the high end, i.e. the base
74
- * address will never be altered.  All this in less than 30
75
- * instructions.  :)
184
+ * Patch "memory above 1MB" figure
76 185
  *
77 186
  * Parameters:
78
- *  %eax	Base address of memory range
79
- *  %ecx	Length of memory range
80
- *  %ebx	Base address of memory range to exclude
81
- *  %edx	Length of memory range to exclude
82
- *  %di		0 => truncate either end, 1 => truncate high end only
187
+ *  %ax		Memory above 1MB, in 1kB blocks
83 188
  * Returns:
84
- *  %eax	Updated base address of range
85
- *  %ecx	Updated length of range
86
- *  %ebx,%edx	Undefined
87
- *		All other registers (including %di) preserved
189
+ *  %ax		Modified memory above 1M in 1kB blocks
190
+ *  CF set	Region was truncated
191
+ *  CF clear	Region was not truncated
192
+ ****************************************************************************
193
+ */
194
+	.section ".text16"
195
+patch_1m:
196
+	pushal
197
+	/* Convert to (start,len) format and call truncate */
198
+	movw	$truncate_to_start, %bp
199
+	xorl	%ecx, %ecx
200
+	movzwl	%ax, %ebx
201
+	shll	$10, %ebx
202
+	xorl	%edx, %edx
203
+	movl	$0x100000, %eax
204
+	call	truncate
205
+	/* Convert back to "memory above 1MB" format and return via %ax */
206
+	pushfw
207
+	shrl	$10, %ebx
208
+	popfw
209
+	movw	%sp, %bp
210
+	movw	%bx, 28(%bp)
211
+	popal
212
+	ret
213
+	.size patch_1m, . - patch_1m
214
+
215
+/****************************************************************************
216
+ * Patch "memory above 16MB" figure
88 217
  *
89
- * Note: "ja" is used rather than "jg" because we are comparing
90
- * unsigned ints
218
+ * Parameters:
219
+ *  %bx		Memory above 16MB, in 64kB blocks
220
+ * Returns:
221
+ *  %bx		Modified memory above 16M in 64kB blocks
222
+ *  CF set	Region was truncated
223
+ *  CF clear	Region was not truncated
91 224
  ****************************************************************************
92 225
  */
93
-#ifdef TEST_EXCLUDE_ALGORITHM
94
-	.code32
95
-#endif /* TEST_EXCLUDE_ALGORITHM */
96
-exclude_memory_range:
97
-	/* Convert (start,length) to (start,end) */
98
-	addl	%eax, %ecx
99
-	addl	%ebx, %edx
100
-	/* Calculate "prefix" length */
101
-	subl	%eax, %ebx		/* %ebx = "prefix" length */
102
-	ja	1f
103
-	xorl	%ebx, %ebx		/* Truncate to zero if negative */
104
-1:	/* %di == 0 => truncate either end
105
-	 * %di != 0 => truncate only high end
106
-	 */
107
-	testw	%di, %di
108
-	je	use_either
109
-	cmpl	%eax, %edx
110
-	jbe	99f			/* excl. range is below target range */
111
-use_prefix:	/* Use prefix, discard suffix */
112
-	addl	%eax, %ebx		/* %ebx = candidate end address */
113
-	cmpl	%ecx, %ebx		/* %ecx = min ( %ebx, %ecx ) */
114
-	ja	1f
115
-	movl	%ebx, %ecx
116
-1:	jmp	99f
117
-use_either:		
118
-	/* Calculate "suffix" length */
119
-	subl	%ecx, %edx		/* %edx = -( "suffix" length ) */
120
-	jb	1f
121
-	xorl	%edx, %edx		/* Truncate to zero if negative */
122
-1:	negl	%edx			/* %edx = "suffix" length */
123
-	/* Use whichever is longest of "prefix" and "suffix" */
124
-	cmpl	%ebx, %edx
125
-	jbe	use_prefix
126
-use_suffix:	/* Use suffix, discard prefix */
127
-	negl	%edx
128
-	addl	%ecx, %edx		/* %edx = candidate start address */
129
-	cmpl	%eax, %edx		/* %eax = max ( %eax, %edx ) */
130
-	jb	1f
131
-	movl	%edx, %eax
132
-1:	
133
-99:	subl	%eax, %ecx		/* Convert back to (start,length) */
226
+	.section ".text16"
227
+patch_16m:
228
+	pushal
229
+	/* Convert to (start,len) format and call truncate */
230
+	movw	$truncate_to_start, %bp
231
+	xorl	%ecx, %ecx
232
+	shll	$16, %ebx
233
+	xorl	%edx, %edx
234
+	movl	$0x1000000, %eax
235
+	call	truncate
236
+	/* Convert back to "memory above 16MB" format and return via %bx */
237
+	pushfw
238
+	shrl	$16, %ebx
239
+	popfw
240
+	movw	%sp, %bp
241
+	movw	%bx, 24(%bp)
242
+	popal
134 243
 	ret
244
+	.size patch_16m, . - patch_16m
135 245
 
136
-#ifdef TEST_EXCLUDE_ALGORITHM
137
-	.globl	__test_exclude
138
-__test_exclude:
139
-	pushl   %ebx
140
-	pushl	%edi
141
-	movl    12(%esp), %eax
142
-	movl    16(%esp), %ecx
143
-	movl    20(%esp), %ebx
144
-	movl    24(%esp), %edx
145
-	movl	28(%esp), %edi
146
-	call    exclude_memory_range
147
-	shll    $16, %eax
148
-	orl     %ecx, %eax
149
-	popl	%edi
150
-	popl	%ebx
246
+/****************************************************************************
247
+ * Patch "memory between 1MB and 16MB" and "memory above 16MB" figures
248
+ *
249
+ * Parameters:
250
+ *  %ax		Memory between 1MB and 16MB, in 1kB blocks
251
+ *  %bx		Memory above 16MB, in 64kB blocks
252
+ * Returns:
253
+ *  %ax		Modified memory between 1MB and 16MB, in 1kB blocks
254
+ *  %bx		Modified memory above 16MB, in 64kB blocks
255
+ *  CF set	Region was truncated
256
+ *  CF clear	Region was not truncated
257
+ ****************************************************************************
258
+ */
259
+	.section ".text16"
260
+patch_1m_16m:
261
+	call	patch_1m
262
+	jc	1f
263
+	call	patch_16m
151 264
 	ret
152
-	.code16
153
-#endif /* TEST_EXCLUDE_ALGORITHM */
154
-	
265
+1:	/* 1m region was truncated; kill the 16m region */
266
+	xorw	%bx, %bx
267
+	ret
268
+	.size patch_1m_16m, . - patch_1m_16m
269
+
155 270
 /****************************************************************************
156
- * Exclude Etherboot-reserved address ranges from a potentially
157
- * overlapping address range
271
+ * Patch E820 memory map entry
158 272
  *
159 273
  * Parameters:
160
- *  %eax	Base address of memory range
161
- *  %ecx	Length of memory range
162
- *  %di		0 => truncate either end, 1 => truncate high end only
274
+ *  %es:di	Pointer to E820 memory map descriptor
275
+ *  %bp		truncate_to_start or truncate_to_end
163 276
  * Returns:
164
- *  %eax	Updated base address of range
165
- *  %ecx	Updated length of range
166
- *		All other registers (including %di) preserved
277
+ *  %es:di	Pointer to now-modified E820 memory map descriptor
278
+ *  CF set	Region was truncated
279
+ *  CF clear	Region was not truncated
167 280
  ****************************************************************************
168 281
  */
169
-exclude_hidden_memory_ranges:
170
-	pushw	%si
171
-	pushl	%ebx
172
-	pushl	%edx
173
-	movw	$INSTALLED(_hide_memory), %si
174
-2:	movl	%cs:0(%si), %ebx
175
-	movl	%cs:4(%si), %edx
176
-	call	exclude_memory_range
177
-	addw	$8, %si
178
-	cmpw	$INSTALLED(_hide_memory_end), %si
179
-	jl	2b
180
-	popl	%edx
181
-	popl	%ebx
182
-	popw	%si
282
+	.section ".text16"
283
+patch_e820:
284
+	pushal
285
+	movl	%es:0(%di), %eax
286
+	movl	%es:4(%di), %edx
287
+	movl	%es:8(%di), %ebx
288
+	movl	%es:12(%di), %ecx
289
+	call	truncate
290
+	movl	%eax, %es:0(%di)
291
+	movl	%edx, %es:4(%di)
292
+	movl	%ebx, %es:8(%di)
293
+	movl	%ecx, %es:12(%di)
294
+	popal
183 295
 	ret
184
-	
185
-	.globl	_hide_memory	
186
-_hide_memory:
187
-	.long	0,0			/* Etherboot text (base,length) */
188
-	.long	0,0			/* Heap (base,length) */
189
-_hide_memory_end:
296
+	.size patch_e820, . - patch_e820
190 297
 
191 298
 /****************************************************************************
192
- * Intercept INT 15,E820 calls and remove the hidden memory ranges
193
- * from the resulting memory map.
299
+ * INT 15,e820 handler
194 300
  ****************************************************************************
195 301
  */
196
-#define SMAP ( 0x534d4150 )
197
-intercept_e820:
198
-	/* Check for valid E820 routine */
199
-	cmpl	$SMAP, %eax
200
-	jne	intercept_int15_exit
201
-	/* If base address isn't in the low 4GB, return unaltered
202
-	 * (since we never claim memory above 4GB).  WARNING: we cheat
203
-	 * by assuming that no E820 region will straddle the 4GB
204
-	 * boundary: if this is not a valid assumption then things
205
-	 * will probably break.
206
-	 */
207
-	cmpl	$0, %es:4(%di)
208
-	jne	intercept_int15_exit
209
-	/* Preserve registers */
210
-	pushl	%eax
211
-	pushl	%ecx
212
-	/* Update returned memory range */
213
-	movl	%es:0(%di), %eax	/* Base */
214
-	movl	%es:8(%di), %ecx	/* Length */
215
-	pushw	%di
216
-	xorw	%di, %di		/* "truncate either end" flag */
217
-	call	exclude_hidden_memory_ranges
218
-	popw	%di
219
-	movl	%eax, %es:0(%di)	/* Store updated base */
220
-	movl	%ecx, %es:8(%di)	/* Store updated length */
221
-	/* Restore registers and return */
222
-	popl	%ecx
223
-	popl	%eax
224
-	jmp	intercept_int15_exit
302
+	.section ".text16"
303
+int15_e820:
304
+	pushw	%si
305
+	pushw	%bp
306
+	/* Caller's %bx => %si, real %ebx to %ebx, call previous handler */
307
+	pushfw
308
+	movw	%bx, %si
309
+	testl	%ebx, %ebx
310
+	jnz	1f
311
+	movl	%ebx, %cs:real_ebx
312
+1:	movl	%cs:real_ebx, %ebx
313
+	lcall	*%cs:int15_vector
314
+	pushfw
315
+	/* Edit result */
316
+	pushw	%ds
317
+	pushw	%cs:rm_ds
318
+	popw	%ds
319
+	movw	$truncate_to_start, %bp
320
+	incw	%si
321
+	jns	2f
322
+	movw	$truncate_to_end, %bp
323
+2:	call	patch_e820
324
+	jnc	3f
325
+	xorw	$0x8000, %si
326
+3:	testw	%si, %si
327
+	js	4f
328
+	movl	%ebx, %cs:real_ebx
329
+	testl	%ebx, %ebx
330
+	jz	5f
331
+4:	movw	%si, %bx
332
+5:	popw	%ds
333
+	/* Restore flags returned by previous handler and return */
334
+	popfw
335
+	popw	%bp
336
+	popw	%si
337
+	lret	$2
338
+	.size int15_e820, . - int15_e820
225 339
 
340
+	.section ".text16.data"
341
+real_ebx:
342
+	.long 0
343
+	.size real_ebx, . - real_ebx
344
+	
226 345
 /****************************************************************************
227
- * Intercept INT 15,E801 calls and remove the hidden memory ranges
228
- * from the resulting memory map.
346
+ * INT 15,e801 handler
229 347
  ****************************************************************************
230 348
  */
231
-intercept_e801:
232
-	/* Adjust return values */
233
-	call	e801_adjust
349
+	.section ".text16"
350
+int15_e801:
351
+	/* Call previous handler */
352
+	pushfw
353
+	lcall	*%cs:int15_vector
354
+	pushfw
355
+	/* Edit result */
356
+	pushw	%ds
357
+	pushw	%cs:rm_ds
358
+	popw	%ds
359
+	call	patch_1m_16m
234 360
 	xchgw	%ax, %cx
235 361
 	xchgw	%bx, %dx
236
-	call	e801_adjust
362
+	call	patch_1m_16m
237 363
 	xchgw	%ax, %cx
238 364
 	xchgw	%bx, %dx
239
-	jmp	intercept_int15_exit
240
-	
241
-	/* %ax = #KB from 1MB+, %bx = #64KB from 16MB+
242
-	 * Return with modified values in %ax, %bx.  Preserver other regs.
243
-	 */
244
-e801_adjust:
245
-	pushw	%di
246
-	pushl	%ecx
247
-	pushl	%eax
248
-	movw	$1, %di			/* "truncate only high end" flag */
249
-
250
-	/* Truncate #64KB from 16MB+ as appropriate */
251
-	movw	%bx, %cx		/* (no need to zero high word) */
252
-	shll	$16, %ecx		/* %ecx = length in bytes */
253
-	movl	$(1<<24), %eax		/* 16MB start address */
254
-	call	exclude_hidden_memory_ranges
255
-	shrl	$16, %ecx		/* %cx = updated length in 64KB */
256
-	movw	%cx, %bx		/* Return in %bx */
257
-	
258
-	/* Truncate #KB from 1MB+ as appropriate */
259
-	popw	%cx			/* Orig. %ax (high word already 0) */
260
-	shll	$10, %ecx		/* %ecx = length in bytes */
261
-	shrl	$4, %eax		/* 1MB start address */
262
-	call	exclude_hidden_memory_ranges
263
-	shrl	$10, %ecx		/* %cx = updated length in KB */
264
-	pushw	%cx			/* Will be picked up in %eax */
365
+	popw	%ds
366
+	/* Restore flags returned by previous handler and return */
367
+	popfw
368
+	lret	$2
369
+	.size int15_e801, . - int15_e801
265 370
 	
266
-	popl	%eax
267
-	popl	%ecx
268
-	popw	%di
269
-	ret
270
-
271 371
 /****************************************************************************
272
- * Intercept INT 15,88 calls and remove the hidden memory ranges
273
- * from the resulting memory map.
372
+ * INT 15,88 handler
274 373
  ****************************************************************************
275 374
  */
276
-intercept_88:
277
-	pushw	%bx			/* E801 adjust, ignore %bx */
278
-	call	e801_adjust
279
-	popw	%bx
280
-	jmp	intercept_int15_exit
281
-
282
-	.globl	e820mangler_end
283
-e820mangler_end:
284
-
285
-	.globl	_e820mangler_size
286
-	.equ	_e820mangler_size, e820mangler_end - e820mangler
287
-	.globl	e820mangler_size
288
-e820mangler_size:
289
-	.word	_e820mangler_size
290
-
291
-#else
292
-
293
-	.globl	_e820mangler_size
294
-	.equ	_e820mangler_size, 0
375
+	.section ".text16"
376
+int15_88:
377
+	/* Call previous handler */
378
+	pushfw
379
+	lcall	*%cs:int15_vector
380
+	pushfw
381
+	/* Edit result */
382
+	pushw	%ds
383
+	pushw	%cs:rm_ds
384
+	popw	%ds
385
+	call	patch_1m
386
+	popw	%ds
387
+	/* Restore flags returned by previous handler and return */
388
+	popfw
389
+	lret	$2
390
+	.size int15_88, . - int15_88
391
+		
392
+/****************************************************************************
393
+ * INT 15 handler
394
+ ****************************************************************************
395
+ */
396
+	.section ".text16"
397
+	.globl int15
398
+int15:
399
+	/* See if we want to intercept this call */
400
+	pushfw
401
+	cmpw	$0xe820, %ax
402
+	jne	1f
403
+	cmpl	$SMAP, %edx
404
+	jne	1f
405
+	popfw
406
+	jmp	int15_e820
407
+1:	cmpw	$0xe801, %ax
408
+	jne	2f
409
+	popfw
410
+	jmp	int15_e801
411
+2:	cmpb	$0x88, %ah
412
+	jne	3f
413
+	popfw
414
+	jmp	int15_88
415
+3:	popfw
416
+	ljmp	*%cs:int15_vector
417
+	.size int15, . - int15
295 418
 	
296
-#endif /* CODE16 */
419
+	.section ".text16.data"
420
+	.globl int15_vector
421
+int15_vector:
422
+	.long 0
423
+	.size int15_vector, . - int15_vector

Завантаження…
Відмінити
Зберегти