blob: 7368bb6d56abdff66c9424de7924f22d2eefd2ce [file] [log] [blame]
Kevin O'Connorf8e176c2009-05-06 23:33:32 -04001// Macros for entering C code
2//
Kevin O'Connor46000f52014-10-21 02:23:02 -04003// Copyright (C) 2008-2014 Kevin O'Connor <kevin@koconnor.net>
Kevin O'Connorf8e176c2009-05-06 23:33:32 -04004//
5// This file may be distributed under the terms of the GNU LGPLv3 license.
6
7
8/****************************************************************
Kevin O'Connor46000f52014-10-21 02:23:02 -04009 * Macros for save and restore of 'struct bregs' registers
Kevin O'Connorf8e176c2009-05-06 23:33:32 -040010 ****************************************************************/
11
Kevin O'Connoraa66d652014-11-05 09:05:36 -050012#define PUSHBREGS_size 32
13
Kevin O'Connor46000f52014-10-21 02:23:02 -040014 // Save registers (matches struct bregs) to stack
David Woodhouse02e94c12013-01-19 17:34:28 +000015 .macro PUSHBREGS
Kevin O'Connor46000f52014-10-21 02:23:02 -040016 pushl %eax
David Woodhouse02e94c12013-01-19 17:34:28 +000017 pushl %ecx
18 pushl %edx
19 pushl %ebx
20 pushl %ebp
21 pushl %esi
22 pushl %edi
23 pushw %es
24 pushw %ds
25 .endm
26
Kevin O'Connor46000f52014-10-21 02:23:02 -040027 // Restore registers (from struct bregs) from stack
David Woodhouse02e94c12013-01-19 17:34:28 +000028 .macro POPBREGS
Kevin O'Connor46000f52014-10-21 02:23:02 -040029 popw %ds
David Woodhouse02e94c12013-01-19 17:34:28 +000030 popw %es
31 popl %edi
32 popl %esi
33 popl %ebp
34 popl %ebx
35 popl %edx
36 popl %ecx
37 popl %eax
38 .endm
39
Kevin O'Connor46000f52014-10-21 02:23:02 -040040 // Save registers to struct bregs at %ds:%eax. The caller
41 // should "pushw %ds ; pushl %eax" prior to calling - this macro
42 // will pop them off.
43 .macro SAVEBREGS_POP_DSEAX
44 popl BREGS_eax(%eax)
45 popw BREGS_ds(%eax)
46 movl %edi, BREGS_edi(%eax)
47 movl %esi, BREGS_esi(%eax)
48 movl %ebp, BREGS_ebp(%eax)
49 movl %ebx, BREGS_ebx(%eax)
50 movl %edx, BREGS_edx(%eax)
51 movl %ecx, BREGS_ecx(%eax)
52 movw %es, BREGS_es(%eax)
53 .endm
54
55 // Restore registers from struct bregs at %ds:%eax
56 .macro RESTOREBREGS_DSEAX
57 movl BREGS_edi(%eax), %edi
58 movl BREGS_esi(%eax), %esi
59 movl BREGS_ebp(%eax), %ebp
60 movl BREGS_ebx(%eax), %ebx
61 movl BREGS_edx(%eax), %edx
62 movl BREGS_ecx(%eax), %ecx
63 movw BREGS_es(%eax), %es
64 pushl BREGS_eax(%eax)
65 movw BREGS_ds(%eax), %ds
66 popl %eax
67 .endm
68
69
70/****************************************************************
71 * Entry macros
72 ****************************************************************/
73
Kevin O'Connorf8e176c2009-05-06 23:33:32 -040074 // Call a C function - this does the minimal work necessary to
75 // call into C. It sets up %ds, backs up %es, and backs up
76 // those registers that are call clobbered by the C compiler.
77 .macro ENTRY cfunc
78 cli // In case something far-calls instead of using "int"
79 cld
80 pushl %eax // Save registers clobbered by C code
81 pushl %ecx
82 pushl %edx
83 pushw %es
84 pushw %ds
85 movw %ss, %ax // Move %ss to %ds
86 movw %ax, %ds
87 pushl %esp // Backup %esp, then clear high bits
88 movzwl %sp, %esp
89 calll \cfunc
90 popl %esp // Restore %esp (including high bits)
91 popw %ds // Restore registers saved above
92 popw %es
93 popl %edx
94 popl %ecx
95 popl %eax
96 .endm
97
98 // Call a C function with current register list as an
99 // argument. This backs up the registers and sets %eax
100 // to point to the backup. On return, the registers are
101 // restored from the structure.
102 .macro ENTRY_ARG cfunc
103 cli
104 cld
David Woodhouse02e94c12013-01-19 17:34:28 +0000105 PUSHBREGS
Kevin O'Connorf8e176c2009-05-06 23:33:32 -0400106 movw %ss, %ax // Move %ss to %ds
107 movw %ax, %ds
108 movl %esp, %ebx // Backup %esp, then zero high bits
109 movzwl %sp, %esp
110 movl %esp, %eax // First arg is pointer to struct bregs
111 calll \cfunc
112 movl %ebx, %esp // Restore %esp (including high bits)
David Woodhouse02e94c12013-01-19 17:34:28 +0000113 POPBREGS
Kevin O'Connorf8e176c2009-05-06 23:33:32 -0400114 .endm
115
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400116 // As above, but get calling function from stack.
117 .macro ENTRY_ARG_ST
118 cli
119 cld
120 pushl %ecx
121 pushl %edx
122 pushl %ebx
Kevin O'Connor7da210c2009-05-16 23:57:08 -0400123 pushl %ebp
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400124 pushl %esi
125 pushl %edi
126 pushw %es
127 pushw %ds
128 movw %ss, %cx // Move %ss to %ds
129 movw %cx, %ds
130 movl %esp, %ebx // Backup %esp, then zero high bits
131 movzwl %sp, %esp
Kevin O'Connor7da210c2009-05-16 23:57:08 -0400132 movl 28(%esp), %ecx // Get calling function
133 movl %eax, 28(%esp) // Save %eax
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400134 movl %esp, %eax // First arg is pointer to struct bregs
135 calll *%ecx
136 movl %ebx, %esp // Restore %esp (including high bits)
David Woodhouse02e94c12013-01-19 17:34:28 +0000137 POPBREGS
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400138 .endm
139
140 // Same as ENTRY_ARG, but don't mangle %esp
Kevin O'Connorf8e176c2009-05-06 23:33:32 -0400141 .macro ENTRY_ARG_ESP cfunc
142 cli
143 cld
David Woodhouse02e94c12013-01-19 17:34:28 +0000144 PUSHBREGS
Kevin O'Connorf8e176c2009-05-06 23:33:32 -0400145 movw %ss, %ax // Move %ss to %ds
146 movw %ax, %ds
147 movl %esp, %eax // First arg is pointer to struct bregs
148 calll \cfunc
David Woodhouse02e94c12013-01-19 17:34:28 +0000149 POPBREGS
Kevin O'Connorf8e176c2009-05-06 23:33:32 -0400150 .endm
151
152 // Reset stack, transition to 32bit mode, and call a C function.
Kevin O'Connorf8e176c2009-05-06 23:33:32 -0400153 .macro ENTRY_INTO32 cfunc
Kevin O'Connor283ae1f2014-10-21 03:19:55 -0400154 xorw %dx, %dx
155 movw %dx, %ss
Kevin O'Connorf8e176c2009-05-06 23:33:32 -0400156 movl $ BUILD_STACK_ADDR , %esp
Kevin O'Connor4057f982010-11-25 08:52:50 -0500157 movl $ \cfunc , %edx
Kevin O'Connorf8e176c2009-05-06 23:33:32 -0400158 jmp transition32
159 .endm
160
161 // Declare a function
162 .macro DECLFUNC func
163 .section .text.asm.\func
164 .global \func
165 .endm