comparison packages/hal/i386/pc/current/include/platform.inc @ 76:435cced73e2f ecos-v1_3_1-release

eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
author jlarmour
date Tue, 28 Mar 2000 14:10:45 +0000
parents
children 6ed91473a1cd
comparison
equal deleted inserted replaced
75:41bf073c0c32 76:435cced73e2f
1 #ifndef CYGONCE_HAL_PLATFORM_INC
2 #define CYGONCE_HAL_PLATFORM_INC
3 ##=============================================================================
4 ##
5 ## platform.inc
6 ##
7 ## PC platform support
8 ##
9 ##=============================================================================
10 #####COPYRIGHTBEGIN####
11 #
12 # -------------------------------------------
13 # The contents of this file are subject to the Red Hat eCos Public License
14 # Version 1.1 (the "License"); you may not use this file except in
15 # compliance with the License. You may obtain a copy of the License at
16 # http://www.redhat.com/
17 #
18 # Software distributed under the License is distributed on an "AS IS"
19 # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
20 # License for the specific language governing rights and limitations under
21 # the License.
22 #
23 # The Original Code is eCos - Embedded Configurable Operating System,
24 # released September 30, 1998.
25 #
26 # The Initial Developer of the Original Code is Red Hat.
27 # Portions created by Red Hat are
28 # Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
29 # All Rights Reserved.
30 # -------------------------------------------
31 #
32 #####COPYRIGHTEND####
33 ##=============================================================================
34 #######DESCRIPTIONBEGIN####
35 ##
36 ## Author(s): jskov
37 ## Contributors:jskov, pjo, nickg
38 ## Date: 1999-01-07
39 ## Purpose: PC platform support
40 ## Description: This file contains any PC specific assembler macros needed to
41 ## run eCos on a standard i386 PC.
42 ##
43 ##
44 ######DESCRIPTIONEND####
45 ##
46 ##=============================================================================
47
48 #include <cyg/hal/i386.inc>
49
50
51 ##=============================================================================
52 ## CPU initialization
53
54 #define CYGPKG_HAL_I386_CPU_INIT_DEFINED
55
56 .macro hal_cpu_init
57
58 #ifdef CYG_HAL_STARTUP_FLOPPY
59
60 /* This code is loaded from a floppy disk when the PC powers up. */
61
62 .code16
63
64 .extern _end
65
66 sectorsPerTrack = 18
67 bytesPerSector = 512
68 bytesPerTrack = sectorsPerTrack * bytesPerSector
69 dptLength = 3 /* words. */
70
71 cld /* always count up. */
72
73 /* Configure a stack that we can use. */
74
75 movl $_start, %eax
76 movw %ax, %sp
77 shr $4, %eax
78 andl $0xF000, %eax
79 movw %ax, %ss
80
81 /* Ask the BIOS for info about the amount of RAM available. We push these
82 onto the stack for later use.
83 */
84
85 xorl %eax, %eax
86 movb $0x88, %ah /* Get the amount of extended memory. */
87 int $0x15
88 shl $10, %eax
89 pushl %eax
90
91 xorl %eax, %eax
92 int $0x12 /* Get the amount of standard memory. */
93 shl $10, %eax
94 pushl %eax
95
96
97 /* Read the rest of the image to _start. This code works by reading a track
98 at a time...
99 */
100
101 movl $_edata, %eax
102 movl $_start, %ebx /* Our destination address. */
103 subl %ebx, %eax /* Number of bytes in the image. */
104 movl $1, %ecx /* Track/sector to read from (starts at 1). */
105
106 0:
107 cmpl $0, %eax
108 jle 1f
109
110 pushl %eax /* Save the number of bytes we want. */
111 pushl %ebx /* Save our current address. */
112 pushl %ecx /* Save our disk location. */
113
114 /* Read in a track with head 0. */
115
116 movl %ebx, %eax /* Put our address into ES:BX. */
117 shr $4, %eax
118 movw %ax, %es
119 andl $0xF, %ebx
120 movw $0, %dx /* Disk 0, head 0 */
121 movb $0x02, %ah
122 movb $sectorsPerTrack, %al /* Read the entire track. */
123 movb $1, %cl
124 int $0x13 /* CX points to our track/sector. */
125
126 /* So go ahead and resume execution at the real starting address. This
127 only serves to move us quickly to the real starting location; and has
128 no effect after reading additional tracks. If we didn't jump after
129 reading the first track, then we limit ourselves to reading images of
130 30k bytes max before overwriting ourselves at 0x7C00.
131 */
132
133 ljmp $0, $2f
134 hlt
135
136 .align 4
137 2:
138
139 popl %ecx
140 popl %ebx
141 popl %eax
142
143 /* Add our length to the address. */
144 addl $bytesPerTrack, %ebx
145 subl $bytesPerTrack, %eax
146
147 /* Maybe read in a track with head 1. */
148 cmpl $0, %eax
149 jle 1f
150
151 pushl %eax /* Save the number of bytes we want. */
152 pushl %ebx /* Save our current address. */
153 pushl %ecx
154
155 movl %ebx, %eax /* Put our address into ES:BX. */
156 shr $4, %eax
157 movw %ax, %es
158 andl $0xF, %ebx
159 movw $0x0100, %dx /* Disk 0, head 1 */
160 movb $0x02, %ah
161 movb $sectorsPerTrack, %al /* Read the entire track. */
162 movb $1, %cl
163 int $0x13 /* CX points to our track/sector. */
164
165 popl %ecx
166 popl %ebx
167 popl %eax
168
169 /* Add our length to the address. */
170 addl $bytesPerTrack, %ebx
171 subl $bytesPerTrack, %eax
172
173 /* Move to the next track. */
174 addb $0x1, %ch
175
176 jmp 0b
177
178 /* Write the 0x55/0xAA signature at the end of the first
179 block. Without this signature the BIOS won't consider this
180 block to be bootable.
181 */
182
183 . = _start + 510
184 .byte 0x55
185 .byte 0xAA
186
187
188 1:
189
190 /* Lets be nice and wait for the diskette drive motor to go off before continuing. */
191
192 movw $0x40, %ax
193 movw %ax, %es
194 movl $0x40, %ebx
195 2: es
196 movb (%bx), %al
197 cmpb $0, %al
198 jne 2b
199
200 /* Now we're all loaded up in memory. */
201
202 /* Disable interrupt handling. */
203 cli
204
205 /* Load GDTR and IDTR. */
206
207 lgdt %cs:gdt
208 lidt %cs:idt
209
210 /* Switch to protected mode. */
211 movl %cr0,%eax
212 orb $1, %al
213 movl %eax,%cr0
214 ljmp $8, $3f
215
216 hlt
217
218 .align 4, 0xFF
219 gdt:
220 .word gdtEnd - gdtStart
221 .long gdtStart
222
223 .align 4, 0xFF
224 idt:
225 .word 0x07FF /* Allow space for 256 interrupt vectors. */
226 .long 0
227
228 gdtStart:
229 /* Selector 0x00 == invalid. */
230 .word 0x0000
231 .word 0x0000
232 .byte 0x00
233 .byte 0x00
234 .byte 0x00
235 .byte 0x00
236
237 /* Selector 0x08 == code. */
238 .word 0xFFFF
239 .word 0x0000
240 .byte 0x00
241 .byte 0x9B
242 .byte 0xCF
243 .byte 0x00
244
245 /* Selector 0x10 == data. */
246 .word 0xFFFF
247 .word 0x0000
248 .byte 0x00
249 .byte 0x93
250 .byte 0xCF
251 .byte 0x00
252
253 /* Selector 0x18 == shorter code: faults any code access 0xF0000000-0xFFFFFFFF. */
254 .word 0xFFFF
255 .word 0x0000
256 .byte 0x00
257 .byte 0x9B
258 .byte 0xC7
259 .byte 0x00
260
261 /* Selector 0x20 == data; faults any access 0xF0000000-0xFFFFFFFF. */
262 .word 0xFFFF
263 .word 0x0000
264 .byte 0x00
265 .byte 0x93
266 .byte 0xC7
267 .byte 0x00
268
269 .align 4, 0xFF
270 gdtEnd:
271
272 .code32
273 3:
274
275 movw $0x10, %ax
276 movw %ax, %ds
277 movw %ax, %es
278 movw %ax, %fs
279 movw %ax, %gs
280
281 /* Make our new stack point to the same place as the old one. */
282 xorl %ebx, %ebx
283 movw %ss, %bx
284 shl $4, %ebx
285 addl %esp, %ebx
286 movw %ax, %ss
287 movl %ebx, %esp
288 movl $0, %ebp
289
290 /* Reset the flags register. */
291 pushl $0
292 popfl
293
294 /* Save the standard and extended memory lengths into some static variables...
295 I'm predicting that someone is going to break our way of passing a pointer
296 to this structure... may as well avoid that problem now.
297 */
298 .data
299 .align 4
300 .globl pc_standard_memory_size
301 pc_standard_memory_size:
302 .long 0
303 .globl pc_extended_memory_size
304 pc_extended_memory_size:
305 .long 0
306 .text
307 movl 0(%esp), %eax
308 movl 4(%esp), %ebx
309 movl %eax, pc_standard_memory_size
310 movl %ebx, pc_extended_memory_size
311
312 /* _pc_entry() takes a pointer to our startup array (which only has standard
313 and extended memory sizes in it, on the stack).
314 */
315 movl %esp, %ebx /* They are the last parameters on the stack. */
316 pushl %ebx
317
318 #endif /* CYG_HAL_STARTUP_FLOPPY */
319
320 #ifdef CYG_HAL_STARTUP_RAM
321
322 /* In this case, the sizes of memory are pointed to by a pointer in IRQ
323 vector 15.
324 */
325
326 /* Save the standard and extended memory lengths into some static variables...
327 */
328 .data
329 .align 4
330 .globl pc_standard_memory_size
331 pc_standard_memory_size:
332 .long 0
333 .globl pc_extended_memory_size
334 pc_extended_memory_size:
335 .long 0
336 .text
337 movl (15 * 8), %ebp
338 movl 0(%ebp), %eax
339 movl 4(%ebp), %ebx
340 movl %eax, pc_standard_memory_size
341 movl %ebx, pc_extended_memory_size
342
343 #endif /* CYG_HAL_STARTUP_RAM */
344
345 .endm /* hal_cpu_init */
346
347
348 ##=============================================================================
349 ## Interrupt controller support
350
351 #define CYGPKG_HAL_I386_INTC_INIT_DEFINED
352
353 .macro hal_intc_init
354
355 # The interrupt controller is configured so that IRQ levels 0-7 trigger
356 # interrupt vector 32-39; levels 8-15 trigger 40-47.
357 movb $0x11, %al
358 outb %al, $0x20
359 movb $0x20, %al
360 outb %al, $0x21
361 movb $0x04, %al
362 outb %al, $0x21
363 movb $0x01, %al
364 outb %al, $0x21
365 movb $0xFF, %al /* Mask off all interrupts. */
366 outb %al, $0x21
367
368 movb $0x11, %al
369 outb %al, $0xA0
370 movb $0x28, %al
371 outb %al, $0xA1
372 movb $0x02, %al
373 outb %al, $0xA1
374 movb $0x01, %al
375 outb %al, $0xA1
376 movb $0xFF, %al /* Mask off all interrupts. */
377 outb %al, $0xA1
378
379 .endm /* hal_intc_init */
380
381 .macro hal_intc_ack vector
382 # Use any registers you like.
383 movl \vector, %edx
384 movb $0x20, %al
385 cmpl $0x20, %edx
386 jl 8f
387 cmpl $0x30, %edx
388 jge 9f
389 outb %al, $0x20
390 jmp 8f
391 9: outb %al, $0xA0
392 8: nop
393 .endm
394
395 ##=============================================================================
396 ## FPU support
397
398 #define CYGPKG_HAL_I386_FPU_DEFINED
399
400 .macro hal_fpu_init
401 # Tell the CPU to use the math hardware.
402 movl %cr0, %eax
403 orl $0x32, %eax
404 movl %eax, %cr0
405
406 finit # and initialize...
407
408 ## Enable floating point exceptions. Bit mask:
409 ## 1 - invalid operation
410 ## 2 - denormalized operand
411 ## 4 - zero divide
412 ## 8 - overflow
413 ## 16 - underflow
414 ## 32 - precision
415 pushl $0
416 fstcw 0(%esp)
417 movl 0(%esp),%eax
418 andb $(~0x04),%al
419 movl %eax,0(%esp)
420 fldcw 0(%esp)
421 addl $4,%esp
422
423 # Tell the CPU to generate a interrupt 7 when the math device is used.
424 #if 0
425 movl %cr0, %eax
426 orl $0x3A, %eax
427 movl %eax, %cr0
428 #endif
429
430 .endm /* hal_fpu_init */
431
432
433 .macro hal_fpu_save regs
434 .endm /* hal_fpu_save */
435
436 .macro hal_fpu_save_caller regs
437 .endm /* hal_fpu_save_caller */
438
439 .macro hal_fpu_save_callee regs
440 .endm /* hal_fpu_save_callee */
441
442 .macro hal_fpu_load_caller regs
443 .endm /* hal_fpu_load_caller */
444
445 .macro hal_fpu_load_callee regs
446 .endm /* hal_fpu_load_callee */
447
448 .macro hal_fpu_load regs
449 .endm /* hal_fpu_load */
450
451
452 ##=============================================================================
453 #endif // ifndef CYGONCE_HAL_PLATFORM_INC
454 ## end of platform.inc