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

[comboot] Support COMBOOT in 64-bit builds

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 роки тому
джерело
коміт
5e5450c2d0

+ 0
- 2
src/arch/i386/Makefile Переглянути файл

83
 # i386-specific directories containing source files
83
 # i386-specific directories containing source files
84
 #
84
 #
85
 SRCDIRS		+= arch/i386/core
85
 SRCDIRS		+= arch/i386/core
86
-SRCDIRS		+= arch/i386/image
87
 SRCDIRS		+= arch/i386/tests
86
 SRCDIRS		+= arch/i386/tests
88
-SRCDIRS		+= arch/i386/interface/syslinux
89
 
87
 
90
 # Include common x86 Makefile
88
 # Include common x86 Makefile
91
 #
89
 #

+ 1
- 0
src/arch/x86/Makefile Переглянути файл

16
 SRCDIRS		+= arch/x86/interface/pxeparent
16
 SRCDIRS		+= arch/x86/interface/pxeparent
17
 SRCDIRS		+= arch/x86/interface/efi
17
 SRCDIRS		+= arch/x86/interface/efi
18
 SRCDIRS		+= arch/x86/interface/vmware
18
 SRCDIRS		+= arch/x86/interface/vmware
19
+SRCDIRS		+= arch/x86/interface/syslinux
19
 SRCDIRS		+= arch/x86/prefix
20
 SRCDIRS		+= arch/x86/prefix
20
 SRCDIRS		+= arch/x86/hci/commands
21
 SRCDIRS		+= arch/x86/hci/commands
21
 SRCDIRS		+= arch/x86/drivers/xen
22
 SRCDIRS		+= arch/x86/drivers/xen

src/arch/i386/image/com32.c → src/arch/x86/image/com32.c Переглянути файл

76
 
76
 
77
 		assert ( avail_mem_top != 0 );
77
 		assert ( avail_mem_top != 0 );
78
 
78
 
79
-		com32_external_esp = phys_to_virt ( avail_mem_top );
80
-
81
 		/* Hook COMBOOT API interrupts */
79
 		/* Hook COMBOOT API interrupts */
82
 		hook_comboot_interrupts();
80
 		hook_comboot_interrupts();
83
 
81
 
88
 		 */
86
 		 */
89
 		unregister_image ( image );
87
 		unregister_image ( image );
90
 
88
 
91
-		__asm__ __volatile__ (
92
-			"movl %%esp, (com32_internal_esp)\n\t" /* Save internal virtual address space ESP */
93
-			"movl (com32_external_esp), %%esp\n\t" /* Switch to COM32 ESP (top of available memory) */
94
-			"call _virt_to_phys\n\t"               /* Switch to flat physical address space */
95
-			"sti\n\t"			       /* Enable interrupts */
96
-			"pushl %0\n\t"                         /* Pointer to CDECL helper function */
97
-			"pushl %1\n\t"                         /* Pointer to FAR call helper function */
98
-			"pushl %2\n\t"                         /* Size of low memory bounce buffer */
99
-			"pushl %3\n\t"                         /* Pointer to low memory bounce buffer */
100
-			"pushl %4\n\t"                         /* Pointer to INT call helper function */
101
-			"pushl %5\n\t"                         /* Pointer to the command line arguments */
102
-			"pushl $6\n\t"                         /* Number of additional arguments */
103
-			"call *%6\n\t"                         /* Execute image */
104
-			"cli\n\t"			       /* Disable interrupts */
105
-			"call _phys_to_virt\n\t"               /* Switch back to internal virtual address space */
106
-			"movl (com32_internal_esp), %%esp\n\t" /* Switch back to internal stack */
107
-		:
108
-		:
109
-			/* %0 */ "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ),
110
-			/* %1 */ "r" ( virt_to_phys ( com32_farcall_wrapper ) ),
111
-			/* %2 */ "r" ( get_fbms() * 1024 - (COM32_BOUNCE_SEG << 4) ),
112
-			/* %3 */ "i" ( COM32_BOUNCE_SEG << 4 ),
113
-			/* %4 */ "r" ( virt_to_phys ( com32_intcall_wrapper ) ),
114
-			/* %5 */ "r" ( virt_to_phys ( image->cmdline ?
115
-						      image->cmdline : "" ) ),
116
-			/* %6 */ "r" ( COM32_START_PHYS )
117
-		:
118
-			"memory" );
89
+		__asm__ __volatile__ ( PHYS_CODE (
90
+			/* Preserve registers */
91
+			"pushal\n\t"
92
+			/* Preserve stack pointer */
93
+			"subl $4, %k0\n\t"
94
+			"movl %%esp, (%k0)\n\t"
95
+			/* Switch to COM32 stack */
96
+			"movl %k0, %%esp\n\t"
97
+			/* Enable interrupts */
98
+			"sti\n\t"
99
+			/* Construct stack frame */
100
+			"pushl %k1\n\t"
101
+			"pushl %k2\n\t"
102
+			"pushl %k3\n\t"
103
+			"pushl %k4\n\t"
104
+			"pushl %k5\n\t"
105
+			"pushl %k6\n\t"
106
+			"pushl $6\n\t"
107
+			/* Call COM32 entry point */
108
+			"movl %k7, %k0\n\t"
109
+			"call *%k0\n\t"
110
+			/* Disable interrupts */
111
+			"cli\n\t"
112
+			/* Restore stack pointer */
113
+			"movl 24(%%esp), %%esp\n\t"
114
+			/* Restore registers */
115
+			"popal\n\t" )
116
+			:
117
+			: "r" ( avail_mem_top ),
118
+			  "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ),
119
+			  "r" ( virt_to_phys ( com32_farcall_wrapper ) ),
120
+			  "r" ( get_fbms() * 1024 - ( COM32_BOUNCE_SEG << 4 ) ),
121
+			  "i" ( COM32_BOUNCE_SEG << 4 ),
122
+			  "r" ( virt_to_phys ( com32_intcall_wrapper ) ),
123
+			  "r" ( virt_to_phys ( image->cmdline ?
124
+					       image->cmdline : "" ) ),
125
+			  "i" ( COM32_START_PHYS )
126
+			: "memory" );
119
 		DBGC ( image, "COM32 %p: returned\n", image );
127
 		DBGC ( image, "COM32 %p: returned\n", image );
120
 		break;
128
 		break;
121
 
129
 
147
 
155
 
148
 /**
156
 /**
149
  * Check image name extension
157
  * Check image name extension
150
- * 
158
+ *
151
  * @v image		COM32 image
159
  * @v image		COM32 image
152
  * @ret rc		Return status code
160
  * @ret rc		Return status code
153
  */
161
  */
155
 	const char *ext;
163
 	const char *ext;
156
 	static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 };
164
 	static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 };
157
 	uint8_t buf[5];
165
 	uint8_t buf[5];
158
-	
166
+
159
 	if ( image->len >= 5 ) {
167
 	if ( image->len >= 5 ) {
160
 		/* Check for magic number
168
 		/* Check for magic number
161
 		 * mov eax,21cd4cffh
169
 		 * mov eax,21cd4cffh

src/arch/i386/image/comboot.c → src/arch/x86/image/comboot.c Переглянути файл

64
 
64
 
65
 /**
65
 /**
66
  * Copy command line to PSP
66
  * Copy command line to PSP
67
- * 
67
+ *
68
  * @v image		COMBOOT image
68
  * @v image		COMBOOT image
69
  */
69
  */
70
 static void comboot_copy_cmdline ( struct image * image, userptr_t seg_userptr ) {
70
 static void comboot_copy_cmdline ( struct image * image, userptr_t seg_userptr ) {
97
 
97
 
98
 /**
98
 /**
99
  * Initialize PSP
99
  * Initialize PSP
100
- * 
100
+ *
101
  * @v image		COMBOOT image
101
  * @v image		COMBOOT image
102
  * @v seg_userptr	segment to initialize
102
  * @v seg_userptr	segment to initialize
103
  */
103
  */
213
 
213
 
214
 /**
214
 /**
215
  * Check image name extension
215
  * Check image name extension
216
- * 
216
+ *
217
  * @v image		COMBOOT image
217
  * @v image		COMBOOT image
218
  * @ret rc		Return status code
218
  * @ret rc		Return status code
219
  */
219
  */
254
 	seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 );
254
 	seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 );
255
 
255
 
256
 	/* Allow etra 0x100 bytes before image for PSP */
256
 	/* Allow etra 0x100 bytes before image for PSP */
257
-	filesz = image->len + 0x100; 
257
+	filesz = image->len + 0x100;
258
 
258
 
259
 	/* Ensure the entire 64k segment is free */
259
 	/* Ensure the entire 64k segment is free */
260
 	memsz = 0xFFFF;
260
 	memsz = 0xFFFF;
289
 
289
 
290
 	/* Check if this is a COMBOOT image */
290
 	/* Check if this is a COMBOOT image */
291
 	if ( ( rc = comboot_identify ( image ) ) != 0 ) {
291
 	if ( ( rc = comboot_identify ( image ) ) != 0 ) {
292
-		
292
+
293
 		return rc;
293
 		return rc;
294
 	}
294
 	}
295
 
295
 
304
  */
304
  */
305
 static int comboot_exec ( struct image *image ) {
305
 static int comboot_exec ( struct image *image ) {
306
 	int rc;
306
 	int rc;
307
-	
307
+
308
 	/* Sanity check for filesize */
308
 	/* Sanity check for filesize */
309
 	if( image->len >= 0xFF00 ) {
309
 	if( image->len >= 0xFF00 ) {
310
 		DBGC( image, "COMBOOT %p: image too large\n",
310
 		DBGC( image, "COMBOOT %p: image too large\n",

src/arch/i386/include/comboot.h → src/arch/x86/include/comboot.h Переглянути файл

29
 #define COMBOOT_FEATURE_LOCAL_BOOT (1 << 0)
29
 #define COMBOOT_FEATURE_LOCAL_BOOT (1 << 0)
30
 #define COMBOOT_FEATURE_IDLE_LOOP  (1 << 1)
30
 #define COMBOOT_FEATURE_IDLE_LOOP  (1 << 1)
31
 
31
 
32
-/** Maximum number of shuffle descriptors for 
32
+/** Maximum number of shuffle descriptors for
33
  * shuffle and boot functions
33
  * shuffle and boot functions
34
  * (INT 22h AX=0012h, 001Ah, 001Bh)
34
  * (INT 22h AX=0012h, 001Ah, 001Bh)
35
  */
35
  */
102
 extern void hook_comboot_interrupts ( );
102
 extern void hook_comboot_interrupts ( );
103
 extern void unhook_comboot_interrupts ( );
103
 extern void unhook_comboot_interrupts ( );
104
 
104
 
105
-/* These are not the correct prototypes, but it doens't matter, 
105
+/* These are not the correct prototypes, but it doens't matter,
106
  * as we only ever get the address of these functions;
106
  * as we only ever get the address of these functions;
107
  * they are only called from COM32 code running in PHYS_CODE
107
  * they are only called from COM32 code running in PHYS_CODE
108
  */
108
  */
116
 /* setjmp/longjmp context buffer used to return after loading an image */
116
 /* setjmp/longjmp context buffer used to return after loading an image */
117
 extern rmjmp_buf comboot_return;
117
 extern rmjmp_buf comboot_return;
118
 
118
 
119
-extern void *com32_external_esp;
120
-
121
 #define COMBOOT_EXIT 1
119
 #define COMBOOT_EXIT 1
122
 #define COMBOOT_EXIT_RUN_KERNEL 2
120
 #define COMBOOT_EXIT_RUN_KERNEL 2
123
 #define COMBOOT_EXIT_COMMAND 3
121
 #define COMBOOT_EXIT_COMMAND 3

src/arch/i386/interface/syslinux/com32_call.c → src/arch/x86/interface/syslinux/com32_call.c Переглянути файл

46
  */
46
  */
47
 void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physaddr_t outregs_phys ) {
47
 void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physaddr_t outregs_phys ) {
48
 
48
 
49
+	DBGC ( &com32_regs, "COM32 INT%x in %#08lx out %#08lx\n",
50
+	       interrupt, inregs_phys, outregs_phys );
51
+
49
 	memcpy_user ( virt_to_user( &com32_regs ), 0,
52
 	memcpy_user ( virt_to_user( &com32_regs ), 0,
50
 	              phys_to_user ( inregs_phys ), 0,
53
 	              phys_to_user ( inregs_phys ), 0,
51
 	              sizeof(com32sys_t) );
54
 	              sizeof(com32sys_t) );
76
 		            /* patch INT instruction */
79
 		            /* patch INT instruction */
77
 		            "pushw %%ax\n\t"
80
 		            "pushw %%ax\n\t"
78
 		            "movb %%ss:(com32_int_vector), %%al\n\t"
81
 		            "movb %%ss:(com32_int_vector), %%al\n\t"
79
-		            "movb %%al, %%cs:(com32_intcall_instr + 1)\n\t" 
82
+		            "movb %%al, %%cs:(com32_intcall_instr + 1)\n\t"
80
 		            /* perform a jump to avoid problems with cache
83
 		            /* perform a jump to avoid problems with cache
81
 		             * consistency in self-modifying code on some CPUs (486)
84
 		             * consistency in self-modifying code on some CPUs (486)
82
 		             */
85
 		             */
106
 
109
 
107
 	if ( outregs_phys ) {
110
 	if ( outregs_phys ) {
108
 		memcpy_user ( phys_to_user ( outregs_phys ), 0,
111
 		memcpy_user ( phys_to_user ( outregs_phys ), 0,
109
-		              virt_to_user( &com32_regs ), 0, 
112
+		              virt_to_user( &com32_regs ), 0,
110
 		              sizeof(com32sys_t) );
113
 		              sizeof(com32sys_t) );
111
 	}
114
 	}
112
 }
115
 }
116
  */
119
  */
117
 void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t outregs_phys ) {
120
 void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t outregs_phys ) {
118
 
121
 
122
+	DBGC ( &com32_regs, "COM32 farcall %04x:%04x in %#08lx out %#08lx\n",
123
+	       ( proc >> 16 ), ( proc & 0xffff ), inregs_phys, outregs_phys );
124
+
119
 	memcpy_user ( virt_to_user( &com32_regs ), 0,
125
 	memcpy_user ( virt_to_user( &com32_regs ), 0,
120
 	              phys_to_user ( inregs_phys ), 0,
126
 	              phys_to_user ( inregs_phys ), 0,
121
 	              sizeof(com32sys_t) );
127
 	              sizeof(com32sys_t) );
165
 
171
 
166
 	if ( outregs_phys ) {
172
 	if ( outregs_phys ) {
167
 		memcpy_user ( phys_to_user ( outregs_phys ), 0,
173
 		memcpy_user ( phys_to_user ( outregs_phys ), 0,
168
-		              virt_to_user( &com32_regs ), 0, 
174
+		              virt_to_user( &com32_regs ), 0,
169
 		              sizeof(com32sys_t) );
175
 		              sizeof(com32sys_t) );
170
 	}
176
 	}
171
 }
177
 }
176
 int __asmcall com32_cfarcall ( uint32_t proc, physaddr_t stack, size_t stacksz ) {
182
 int __asmcall com32_cfarcall ( uint32_t proc, physaddr_t stack, size_t stacksz ) {
177
 	int32_t eax;
183
 	int32_t eax;
178
 
184
 
185
+	DBGC ( &com32_regs, "COM32 cfarcall %04x:%04x params %#08lx+%#zx\n",
186
+	       ( proc >> 16 ), ( proc & 0xffff ), stack, stacksz );
187
+
179
 	copy_user_to_rm_stack ( phys_to_user ( stack ), stacksz );
188
 	copy_user_to_rm_stack ( phys_to_user ( stack ), stacksz );
180
 	com32_farcall_proc = proc;
189
 	com32_farcall_proc = proc;
181
 
190
 
182
 	__asm__ __volatile__ (
191
 	__asm__ __volatile__ (
183
 		REAL_CODE ( "lcall *%%ss:(com32_farcall_proc)\n\t" )
192
 		REAL_CODE ( "lcall *%%ss:(com32_farcall_proc)\n\t" )
184
 		: "=a" (eax)
193
 		: "=a" (eax)
185
-		: 
194
+		:
186
 		: "ecx", "edx" );
195
 		: "ecx", "edx" );
187
 
196
 
188
 	remove_user_from_rm_stack ( 0, stacksz );
197
 	remove_user_from_rm_stack ( 0, stacksz );

src/arch/i386/interface/syslinux/com32_wrapper.S → src/arch/x86/interface/syslinux/com32_wrapper.S Переглянути файл

19
 
19
 
20
 FILE_LICENCE ( GPL2_OR_LATER )
20
 FILE_LICENCE ( GPL2_OR_LATER )
21
 
21
 
22
+#include "librm.h"
23
+
22
 	.text
24
 	.text
23
-	.arch i386
24
-	.code32
25
 
25
 
26
+	.code32
26
 	.globl com32_farcall_wrapper
27
 	.globl com32_farcall_wrapper
27
 com32_farcall_wrapper:
28
 com32_farcall_wrapper:
29
+	movl	$VIRTUAL(com32_farcall), %eax
30
+	jmp	com32_wrapper
28
 
31
 
29
-	movl $com32_farcall, %eax
30
-	jmp com32_wrapper
31
-
32
-
32
+	.code32
33
 	.globl com32_cfarcall_wrapper
33
 	.globl com32_cfarcall_wrapper
34
 com32_cfarcall_wrapper:
34
 com32_cfarcall_wrapper:
35
+	movl	$VIRTUAL(com32_cfarcall), %eax
36
+	jmp	com32_wrapper
35
 
37
 
36
-	movl $com32_cfarcall, %eax
37
-	jmp com32_wrapper
38
-
39
-
38
+	.code32
40
 	.globl com32_intcall_wrapper
39
 	.globl com32_intcall_wrapper
41
 com32_intcall_wrapper:
40
 com32_intcall_wrapper:
41
+	movl	$VIRTUAL(com32_intcall), %eax
42
+	/* fall through */
42
 
43
 
43
-	movl $com32_intcall, %eax
44
-	/*jmp com32_wrapper*/ /* fall through */
45
-
44
+	.code32
46
 com32_wrapper:
45
 com32_wrapper:
46
+
47
+	/* Disable interrupts */
47
 	cli
48
 	cli
48
 
49
 
49
 	/* Switch to internal virtual address space */
50
 	/* Switch to internal virtual address space */
50
-	call _phys_to_virt
51
-
52
-	mov %eax, (com32_helper_function)
51
+	call	_phys_to_virt
53
 
52
 
54
-	/* Save external COM32 stack pointer */
55
-	movl %esp, (com32_external_esp)
53
+#ifdef __x86_64__
56
 
54
 
57
-	/* Copy arguments to caller-save registers */
58
-	movl 12(%esp), %eax
59
-	movl 8(%esp), %ecx
60
-	movl 4(%esp), %edx
55
+	.code64
61
 
56
 
62
-	/* Switch to internal stack */
63
-	movl (com32_internal_esp), %esp
57
+	/* Preserve registers which are callee-save for COM32 (i386 API) */
58
+	pushq	%rdi
59
+	pushq	%rsi
60
+	pushq	%rbp
64
 
61
 
65
-	/* Copy arguments to internal stack */
66
-	pushl %eax
67
-	pushl %ecx
68
-	pushl %edx
62
+	/* Extract parameters from stack */
63
+	movl	28(%rsp), %edi
64
+	movl	32(%rsp), %esi
65
+	movl	36(%rsp), %edx
69
 
66
 
70
-	call *(com32_helper_function)
67
+	/* Align stack pointer */
68
+	movq	%rsp, %rbp
69
+	andq	$~0x07, %rsp
71
 
70
 
72
-	/* Clean up stack */
73
-	addl $12, %esp
71
+	/* Call helper function */
72
+	movslq	%eax, %rax
73
+	call	*%rax
74
 
74
 
75
-	/* Save internal stack pointer and restore external stack pointer */
76
-	movl %esp, (com32_internal_esp)
77
-	movl (com32_external_esp), %esp
75
+	/* Restore stack pointer */
76
+	movq	%rbp, %rsp
78
 
77
 
79
-	/* Switch to external flat physical address space */
80
-	call _virt_to_phys
81
-
82
-	sti
83
-	ret
78
+	/* Restore registers */
79
+	popq	%rbp
80
+	popq	%rsi
81
+	popq	%rdi
84
 
82
 
83
+#else /* _x86_64 */
85
 
84
 
86
-	.data
85
+	/* Call helper function */
86
+	pushl	12(%esp)
87
+	pushl	12(%esp)
88
+	pushl	12(%esp)
89
+	call	*%eax
90
+	addl	$12, %esp
87
 
91
 
88
-/* Internal iPXE virtual address space %esp */
89
-.globl com32_internal_esp
90
-.lcomm com32_internal_esp, 4
92
+#endif /* _x86_64 */
91
 
93
 
92
-/* External flat physical address space %esp */
93
-.globl com32_external_esp
94
-.lcomm com32_external_esp, 4
94
+	/* Switch to external flat physical address space */
95
+	call	_virt_to_phys
96
+	.code32
95
 
97
 
96
-/* Function pointer of helper to call */
97
-.lcomm com32_helper_function, 4
98
+	/* Reenable interrupts and return */
99
+	sti
100
+	ret

src/arch/i386/interface/syslinux/comboot_call.c → src/arch/x86/interface/syslinux/comboot_call.c Переглянути файл

489
 			struct in_addr addr;
489
 			struct in_addr addr;
490
 
490
 
491
 			copy_from_user ( hostname, hostname_u, 0, len + 1 );
491
 			copy_from_user ( hostname, hostname_u, 0, len + 1 );
492
-			
492
+
493
 			/* TODO:
493
 			/* TODO:
494
 			 * "If the hostname does not contain a dot (.), the
494
 			 * "If the hostname does not contain a dot (.), the
495
 			 * local domain name is automatically appended."
495
 			 * local domain name is automatically appended."
519
 
519
 
520
 		/* Jump to real-mode entry point */
520
 		/* Jump to real-mode entry point */
521
 		__asm__ __volatile__ (
521
 		__asm__ __volatile__ (
522
-			REAL_CODE ( 
522
+			REAL_CODE (
523
 				"pushw %0\n\t"
523
 				"pushw %0\n\t"
524
 				"popw %%ds\n\t"
524
 				"popw %%ds\n\t"
525
 				"pushl %1\n\t"
525
 				"pushl %1\n\t"

src/arch/i386/interface/syslinux/comboot_resolv.c → src/arch/x86/interface/syslinux/comboot_resolv.c Переглянути файл


src/arch/i386/tests/comboot/shuffle-simple.asm → src/arch/x86/tests/comboot/shuffle-simple.asm Переглянути файл

37
 	dd shuffle_len
37
 	dd shuffle_len
38
 
38
 
39
 num_shuffle_descriptors equ 1
39
 num_shuffle_descriptors equ 1
40
-

src/arch/i386/tests/comboot/version.asm → src/arch/x86/tests/comboot/version.asm Переглянути файл


+ 64
- 2
src/arch/x86/transitions/librm.S Переглянути файл

567
 	popl	%eax
567
 	popl	%eax
568
 	ret
568
 	ret
569
 
569
 
570
-	/* Expose as _phys_to_virt for use by COMBOOT */
570
+.if32	/* Expose as _phys_to_virt for use by COMBOOT, if applicable */
571
 	.globl	_phys_to_virt
571
 	.globl	_phys_to_virt
572
 	.equ	_phys_to_virt, phys_to_prot
572
 	.equ	_phys_to_virt, phys_to_prot
573
+.endif
573
 
574
 
574
 /****************************************************************************
575
 /****************************************************************************
575
  * prot_to_phys (protected-mode near call, 32-bit virtual return address)
576
  * prot_to_phys (protected-mode near call, 32-bit virtual return address)
615
 	popl	%eax
616
 	popl	%eax
616
 	ret
617
 	ret
617
 
618
 
618
-	/* Expose as _virt_to_phys for use by COMBOOT */
619
+.if32	/* Expose as _virt_to_phys for use by COMBOOT, if applicable */
619
 	.globl	_virt_to_phys
620
 	.globl	_virt_to_phys
620
 	.equ	_virt_to_phys, prot_to_phys
621
 	.equ	_virt_to_phys, prot_to_phys
622
+.endif
621
 
623
 
622
 /****************************************************************************
624
 /****************************************************************************
623
  * intr_to_prot (protected-mode near call, 32-bit virtual return address)
625
  * intr_to_prot (protected-mode near call, 32-bit virtual return address)
1202
 	/* Return and discard function parameters */
1204
 	/* Return and discard function parameters */
1203
 	ret	$( PHC_OFFSET_END - PHC_OFFSET_PARAMS )
1205
 	ret	$( PHC_OFFSET_END - PHC_OFFSET_PARAMS )
1204
 
1206
 
1207
+/****************************************************************************
1208
+ * phys_to_long (protected-mode near call, 32-bit physical return address)
1209
+ *
1210
+ * Used by COMBOOT.
1211
+ *
1212
+ ****************************************************************************
1213
+ */
1214
+	.if64
1215
+
1216
+	.section ".text.phys_to_long", "ax", @progbits
1217
+	.code32
1218
+phys_to_long:
1219
+
1220
+	/* Switch to virtual addresses */
1221
+	call	phys_to_prot
1222
+
1223
+	/* Convert to 32-bit virtual return address */
1224
+	pushl	%eax
1225
+	movl	VIRTUAL(virt_offset), %eax
1226
+	subl	%eax, 4(%esp)
1227
+	popl	%eax
1228
+
1229
+	/* Switch to long mode and return */
1230
+	jmp	prot_to_long
1231
+
1232
+	/* Expose as _phys_to_virt for use by COMBOOT */
1233
+	.globl  _phys_to_virt
1234
+	.equ    _phys_to_virt, phys_to_long
1235
+
1236
+	.endif
1237
+
1238
+/****************************************************************************
1239
+ * long_to_phys (long-mode near call, 64-bit virtual return address)
1240
+ *
1241
+ * Used by COMBOOT.
1242
+ *
1243
+ ****************************************************************************
1244
+ */
1245
+	.if64
1246
+
1247
+	.section ".text.long_to_phys", "ax", @progbits
1248
+	.code64
1249
+long_to_phys:
1250
+
1251
+	/* Switch to protected mode */
1252
+	call	long_to_prot
1253
+	.code32
1254
+
1255
+	/* Convert to 32-bit virtual return address */
1256
+	popl	(%esp)
1257
+
1258
+	/* Switch to physical addresses and return */
1259
+	jmp	prot_to_phys
1260
+
1261
+	/* Expose as _virt_to_phys for use by COMBOOT */
1262
+	.globl  _virt_to_phys
1263
+	.equ    _virt_to_phys, long_to_phys
1264
+
1265
+	.endif
1266
+
1205
 /****************************************************************************
1267
 /****************************************************************************
1206
  * flatten_real_mode (real-mode near call)
1268
  * flatten_real_mode (real-mode near call)
1207
  *
1269
  *

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