|
@@ -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;
|