Browse Source

[comboot] Use built-in interrupt reflector

We now have the ability to handle interrupts while in protected mode,
and so no longer need to set up a dedicated interrupt descriptor table
while running COM32 executables.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
aaf276ccd4

+ 6
- 46
src/arch/i386/image/com32.c View File

@@ -41,13 +41,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
41 41
 #include <ipxe/init.h>
42 42
 #include <ipxe/io.h>
43 43
 
44
-struct idt_register com32_external_idtr = {
45
-	.limit = COM32_NUM_IDT_ENTRIES * sizeof ( struct idt_descriptor ) - 1,
46
-	.base = COM32_IDT
47
-};
48
-
49
-struct idt_register com32_internal_idtr;
50
-
51 44
 /**
52 45
  * Execute COMBOOT image
53 46
  *
@@ -95,8 +88,6 @@ static int com32_exec_loop ( struct image *image ) {
95 88
 		unregister_image ( image );
96 89
 
97 90
 		__asm__ __volatile__ (
98
-			"sidt com32_internal_idtr\n\t"
99
-			"lidt com32_external_idtr\n\t"	       /* Set up IDT */
100 91
 			"movl %%esp, (com32_internal_esp)\n\t" /* Save internal virtual address space ESP */
101 92
 			"movl (com32_external_esp), %%esp\n\t" /* Switch to COM32 ESP (top of available memory) */
102 93
 			"call _virt_to_phys\n\t"               /* Switch to flat physical address space */
@@ -110,8 +101,7 @@ static int com32_exec_loop ( struct image *image ) {
110 101
 			"pushl $6\n\t"                         /* Number of additional arguments */
111 102
 			"call *%6\n\t"                         /* Execute image */
112 103
 			"cli\n\t"			       /* Disable interrupts */
113
-			"call _phys_to_virt\n\t"	       /* Switch back to internal virtual address space */
114
-			"lidt com32_internal_idtr\n\t"	       /* Switch back to internal IDT (for debugging) */
104
+			"call _phys_to_virt\n\t"               /* Switch back to internal virtual address space */
115 105
 			"movl (com32_internal_esp), %%esp\n\t" /* Switch back to internal stack */
116 106
 		:
117 107
 		:
@@ -201,55 +191,25 @@ static int com32_identify ( struct image *image ) {
201 191
 
202 192
 
203 193
 /**
204
- * Load COM32 image into memory and set up the IDT
194
+ * Load COM32 image into memory
205 195
  * @v image		COM32 image
206 196
  * @ret rc		Return status code
207 197
  */
208 198
 static int com32_load_image ( struct image *image ) {
209
-	physaddr_t com32_irq_wrapper_phys;
210
-	struct idt_descriptor *idt;
211
-	struct ijb_entry *ijb;
212 199
 	size_t filesz, memsz;
213 200
 	userptr_t buffer;
214
-	int rc, i;
215
-
216
-	/* The interrupt descriptor table, interrupt jump buffer, and
217
-	 * image data are all contiguous in memory. Prepare them all at once.
218
-	 */
219
-	filesz = image->len +
220
-		COM32_NUM_IDT_ENTRIES * sizeof ( struct idt_descriptor ) +
221
-		COM32_NUM_IDT_ENTRIES * sizeof ( struct ijb_entry );
201
+	int rc;
202
+
203
+	filesz = image->len;
222 204
 	memsz = filesz;
223
-	buffer = phys_to_user ( COM32_IDT );
205
+	buffer = phys_to_user ( COM32_START_PHYS );
224 206
 	if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) {
225 207
 		DBGC ( image, "COM32 %p: could not prepare segment: %s\n",
226 208
 		       image, strerror ( rc ) );
227 209
 		return rc;
228 210
 	}
229 211
 
230
-	/* Write the IDT and IJB */
231
-	idt = phys_to_virt ( COM32_IDT );
232
-	ijb = phys_to_virt ( COM32_IJB );
233
-	com32_irq_wrapper_phys = virt_to_phys ( com32_irq_wrapper );
234
-
235
-	for ( i = 0; i < COM32_NUM_IDT_ENTRIES; i++ ) {
236
-		uint32_t ijb_address = virt_to_phys ( &ijb[i] );
237
-
238
-		idt[i].offset_low = ijb_address & 0xFFFF;
239
-		idt[i].selector = PHYSICAL_CS;
240
-		idt[i].flags = IDT_INTERRUPT_GATE_FLAGS;
241
-		idt[i].offset_high = ijb_address >> 16;
242
-
243
-		ijb[i].pusha_instruction = IJB_PUSHA;
244
-		ijb[i].mov_instruction = IJB_MOV_AL_IMM8;
245
-		ijb[i].mov_value = i;
246
-		ijb[i].jump_instruction = IJB_JMP_REL32;
247
-		ijb[i].jump_destination = com32_irq_wrapper_phys -
248
-			virt_to_phys ( &ijb[i + 1] );
249
-	}
250
-
251 212
 	/* Copy image to segment */
252
-	buffer = phys_to_user ( COM32_START_PHYS );
253 213
 	memcpy_user ( buffer, 0, image->data, 0, filesz );
254 214
 
255 215
 	return 0;

+ 0
- 45
src/arch/i386/include/comboot.h View File

@@ -13,50 +13,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
13 13
 #include <setjmp.h>
14 14
 #include <ipxe/in.h>
15 15
 
16
-/** Descriptor in a 32-bit IDT */
17
-struct idt_descriptor {
18
-	uint16_t offset_low;
19
-	uint16_t selector;
20
-	uint16_t flags;
21
-	uint16_t offset_high;
22
-} __attribute__ (( packed ));
23
-
24
-/** Operand for the LIDT instruction */
25
-struct idt_register {
26
-	uint16_t limit;
27
-	uint32_t base;
28
-} __attribute__ (( packed ));
29
-
30
-/** Entry in the interrupt jump buffer */
31
-struct ijb_entry {
32
-	uint8_t pusha_instruction;
33
-	uint8_t mov_instruction;
34
-	uint8_t mov_value;
35
-	uint8_t jump_instruction;
36
-	uint32_t jump_destination;
37
-} __attribute__ (( packed ));
38
-
39
-/** The x86 opcode for "pushal" */
40
-#define IJB_PUSHA 0x60
41
-
42
-/** The x86 opcode for "movb $imm8,%al" */
43
-#define IJB_MOV_AL_IMM8 0xB0
44
-
45
-/** The x86 opcode for "jmp rel32" */
46
-#define IJB_JMP_REL32 0xE9
47
-
48
-/** Flags that specify a 32-bit interrupt gate with DPL=0 */
49
-#define IDT_INTERRUPT_GATE_FLAGS 0x8E00
50
-
51
-/** Address of COM32 interrupt descriptor table */
52
-#define COM32_IDT 0x100000
53
-
54
-/** Number of entries in a fully populated IDT */
55
-#define COM32_NUM_IDT_ENTRIES 256
56
-
57
-/** Address of COM32 interrupt jump buffer */
58
-#define COM32_IJB 0x100800
59
-
60 16
 /** Segment used for COMBOOT PSP and image */
61 17
 #define COMBOOT_PSP_SEG 0x07C0
62 18
 
@@ -153,7 +109,6 @@ extern void unhook_comboot_interrupts ( );
153 109
 extern void com32_intcall_wrapper ( );
154 110
 extern void com32_farcall_wrapper ( );
155 111
 extern void com32_cfarcall_wrapper ( );
156
-extern void com32_irq_wrapper ( );
157 112
 
158 113
 /* Resolve a hostname to an (IPv4) address */
159 114
 extern int comboot_resolv ( const char *name, struct in_addr *address );

+ 0
- 17
src/arch/i386/interface/syslinux/com32_call.c View File

@@ -189,20 +189,3 @@ int __asmcall com32_cfarcall ( uint32_t proc, physaddr_t stack, size_t stacksz )
189 189
 
190 190
 	return eax;
191 191
 }
192
-
193
-/**
194
- * IRQ handler
195
- */
196
-void __asmcall com32_irq ( uint32_t vector ) {
197
-	uint32_t *ivt_entry = phys_to_virt( vector * 4 );
198
-
199
-	__asm__ __volatile__ (
200
-		REAL_CODE ( "pushfw\n\t"
201
-			    "pushw %%cs\n\t"
202
-			    "pushw $com32_irq_return\n\t"
203
-			    "pushl %0\n\t"
204
-			    "lret\n"
205
-			    "com32_irq_return:\n\t" )
206
-		: /* no outputs */
207
-		: "r" ( *ivt_entry ) );
208
-}

+ 0
- 26
src/arch/i386/interface/syslinux/com32_wrapper.S View File

@@ -23,26 +23,6 @@ FILE_LICENCE ( GPL2_OR_LATER )
23 23
 	.arch i386
24 24
 	.code32
25 25
 
26
-	/*
27
-	 * This code is entered after running the following sequence out of
28
-	 * the interrupt jump buffer:
29
-	 *
30
-	 * pushal
31
-	 * movb $vector, %al
32
-	 * jmp com32_irq_wrapper
33
-	 */
34
-
35
-	.globl com32_irq_wrapper
36
-com32_irq_wrapper:
37
-
38
-	movzbl %al,%eax
39
-	pushl %eax
40
-	movl $com32_irq, %eax
41
-	call com32_wrapper
42
-	popl %eax
43
-	popal
44
-	iret
45
-
46 26
 	.globl com32_farcall_wrapper
47 27
 com32_farcall_wrapper:
48 28
 
@@ -69,9 +49,6 @@ com32_wrapper:
69 49
 	/* Switch to internal virtual address space */
70 50
 	call _phys_to_virt
71 51
 
72
-	/* Switch to internal IDT (if we have one for debugging) */
73
-	lidt com32_internal_idtr
74
-
75 52
 	mov %eax, (com32_helper_function)
76 53
 
77 54
 	/* Save external COM32 stack pointer */
@@ -99,9 +76,6 @@ com32_wrapper:
99 76
 	movl %esp, (com32_internal_esp)
100 77
 	movl (com32_external_esp), %esp
101 78
 
102
-	/* Switch to com32 IDT */
103
-	lidt com32_external_idtr
104
-
105 79
 	/* Switch to external flat physical address space */
106 80
 	call _virt_to_phys
107 81
 

Loading…
Cancel
Save