1 /*
2 * Copyright (C) 1994 by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org>
3 * Copyright (C) 1997 by Poul-Henning Kamp <phk@FreeBSD.org>
4 *
5 * This software may be used, modified, copied, distributed, and sold,
6 * in both source and binary form provided that the above copyright and
7 * these terms are retained. Under no circumstances is the author
8 * responsible for the proper functioning of this software, nor does
9 * the author assume any responsibility for damages incurred with its
10 * use.
11 *
12 * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
13 *
14 * $FreeBSD$
15 */
16
17 #include "apm.h"
18
19 #if NAPM > 0
20
21 #define ASSEMBLER
22 #include "assym.s" /* system definitions */
23 #include <machine/asmacros.h> /* miscellaneous asm macros */
24 #include <machine/apm_bios.h>
25 #include <machine/apm_segments.h>
26 #define PADDR(addr) addr-KERNBASE
27
28 .file "apm_setup.s"
29
30 .data
31 _apm_init_image:
32 .globl _apm_init_image
33
34 1:
35 #include "i386/apm/apm_init/apm_init.inc"
36 2:
37
38 _apm_init_image_size:
39 .globl _apm_init_image_size
40 .long 2b - 1b
41
42 _apm_version:
43 .globl _apm_version
44 .long 0
45
46 _apm_cs_entry:
47 .globl _apm_cs_entry
48 .long 0
49
50 _apm_cs16_base:
51 .globl _apm_cs16_base
52 .word 0
53
54 _apm_cs32_base:
55 .globl _apm_cs32_base
56 .word 0
57
58 _apm_ds_base:
59 .globl _apm_ds_base
60 .word 0
61
62 _apm_cs32_limit:
63 .globl _apm_cs32_limit
64 .word 0
65
66 _apm_cs16_limit:
67 .globl _apm_cs16_limit
68 .word 0
69
70 _apm_ds_limit:
71 .globl _apm_ds_limit
72 .word 0
73
74 _apm_flags:
75 .globl _apm_flags
76 .word 0
77 .globl _apm_current_gdt_pdesc /* current GDT pseudo desc. */
78 _apm_current_gdt_pdesc:
79 .word 0, 0, 0
80
81 .globl _bootstrap_gdt
82 _bootstrap_gdt:
83 .space SIZEOF_GDT*BOOTSTRAP_GDT_NUM
84
85 .text
86 _apm_setup:
87 .globl _apm_setup
88
89 /*
90 * Setup APM BIOS:
91 *
92 * APM BIOS initialization should be done from real mode or V86 mode.
93 *
94 * (by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org>)
95 */
96
97 /*
98 * Don't trust the value of %fs and %gs (some AT-compatible BIOS
99 * implementations leave junk values in these segment registers
100 * on bootstrap)
101 */
102 xorl %eax, %eax /* null selector */
103 movw %ax, %fs
104 movw %ax, %gs
105
106 /*
107 * Copy APM initializer under 1MB boundary:
108 *
109 * APM initializer program must switch the CPU to real mode.
110 * But FreeBSD kernel runs above 1MB boundary. So we must
111 * copy the initializer code to conventional memory.
112 */
113 movl PADDR(_apm_init_image_size), %ecx /* size */
114 lea PADDR(_apm_init_image), %esi /* source */
115 movl $ APM_OURADDR, %edi /* destination */
116 cld
117 rep
118 movsb
119
120 /* get GDT base */
121 sgdt PADDR(_apm_current_gdt_pdesc)
122
123 /* copy GDT to _bootstrap_gdt */
124 xorl %ecx, %ecx
125 movw PADDR(_apm_current_gdt_pdesc), %cx
126 movl PADDR(_apm_current_gdt_pdesc + 2), %esi
127 lea PADDR(_bootstrap_gdt), %edi
128 cld
129 rep
130 movsb
131
132 /* setup GDT pseudo descriptor */
133 movw $(SIZEOF_GDT*BOOTSTRAP_GDT_NUM), %ax
134 movw %ax, PADDR(_apm_current_gdt_pdesc)
135 leal PADDR(_bootstrap_gdt), %eax
136 movl %eax, PADDR(_apm_current_gdt_pdesc + 2)
137
138 /* load new GDTR */
139 lgdt PADDR(_apm_current_gdt_pdesc)
140
141 /* setup GDT for APM initializer */
142 lea PADDR(_bootstrap_gdt), %ecx
143 movl $(APM_OURADDR), %eax /* use %ax for 15..0 */
144 movl %eax, %ebx
145 shrl $16, %ebx /* use %bl for 23..16 */
146 /* use %bh for 31..24 */
147 #define APM_SETUP_GDT(index, attrib) \
148 movl $(index), %si ; \
149 lea 0(%ecx,%esi,8), %edx ; \
150 movw $0xffff, (%edx) ; \
151 movw %ax, 2(%edx) ; \
152 movb %bl, 4(%edx) ; \
153 movw $(attrib), 5(%edx) ; \
154 movb %bh, 7(%edx)
155
156 APM_SETUP_GDT(APM_INIT_CS_INDEX , CS32_ATTRIB)
157 APM_SETUP_GDT(APM_INIT_DS_INDEX , DS32_ATTRIB)
158 APM_SETUP_GDT(APM_INIT_CS16_INDEX, CS16_ATTRIB)
159 APM_SETUP_GDT(APM_INIT_DS16_INDEX, DS16_ATTRIB)
160
161 /*
162 * Call the initializer:
163 *
164 * direct intersegment call to conventional memory code
165 */
166 .byte 0x9a /* actually, lcall $APM_INIT_CS_SEL, $0 */
167 .long 0
168 .word APM_INIT_CS_SEL
169
170 movl %eax, PADDR(_apm_version)
171 movl %ebx, PADDR(_apm_cs_entry)
172 movw %cx, PADDR(_apm_cs16_base)
173 shrl $16, %ecx
174 movw %cx, PADDR(_apm_cs32_base)
175 movw %dx, PADDR(_apm_ds_base)
176 movw %si, PADDR(_apm_cs32_limit)
177 shrl $16, %esi
178 movw %si, PADDR(_apm_ds_limit)
179 movw %di, PADDR(_apm_flags)
180
181 ret
182
183 .text
184 .align 2
185 .globl _apm_bios_call
186 _apm_bios_call:
187 pushl %ebp
188 movl 8(%esp),%ebp
189 pushl %esi
190 pushl %edi
191 pushl %ebx
192 movl 20(%ebp),%edi
193 movl 16(%ebp),%esi
194 movl 12(%ebp),%edx
195 movl 8(%ebp),%ecx
196 movl 4(%ebp),%ebx
197 movl 0(%ebp),%eax
198 pushl %ebp
199 lcall _apm_addr
200 popl %ebp
201 movl %eax,0(%ebp)
202 jc 1f
203 xorl %eax,%eax
204 jz 2f
205 1: movl $1, %eax
206 2: movl %ebx,4(%ebp)
207 movl %ecx,8(%ebp)
208 movl %edx,12(%ebp)
209 movl %esi,16(%ebp)
210 movl %edi,20(%ebp)
211 popl %ebx
212 popl %edi
213 popl %esi
214 popl %ebp
215 ret
216 #endif NAPM > 0
Cache object: a2bcd5f1f132c59e61b689b4f1726a56
|