Mercurial > flash_v2
diff 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 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/hal/i386/pc/current/include/platform.inc @@ -0,0 +1,454 @@ +#ifndef CYGONCE_HAL_PLATFORM_INC +#define CYGONCE_HAL_PLATFORM_INC +##============================================================================= +## +## platform.inc +## +## PC platform support +## +##============================================================================= +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +##============================================================================= +#######DESCRIPTIONBEGIN#### +## +## Author(s): jskov +## Contributors:jskov, pjo, nickg +## Date: 1999-01-07 +## Purpose: PC platform support +## Description: This file contains any PC specific assembler macros needed to +## run eCos on a standard i386 PC. +## +## +######DESCRIPTIONEND#### +## +##============================================================================= + +#include <cyg/hal/i386.inc> + + +##============================================================================= +## CPU initialization + +#define CYGPKG_HAL_I386_CPU_INIT_DEFINED + + .macro hal_cpu_init + +#ifdef CYG_HAL_STARTUP_FLOPPY + + /* This code is loaded from a floppy disk when the PC powers up. */ + + .code16 + + .extern _end + + sectorsPerTrack = 18 + bytesPerSector = 512 + bytesPerTrack = sectorsPerTrack * bytesPerSector + dptLength = 3 /* words. */ + + cld /* always count up. */ + + /* Configure a stack that we can use. */ + + movl $_start, %eax + movw %ax, %sp + shr $4, %eax + andl $0xF000, %eax + movw %ax, %ss + + /* Ask the BIOS for info about the amount of RAM available. We push these + onto the stack for later use. + */ + + xorl %eax, %eax + movb $0x88, %ah /* Get the amount of extended memory. */ + int $0x15 + shl $10, %eax + pushl %eax + + xorl %eax, %eax + int $0x12 /* Get the amount of standard memory. */ + shl $10, %eax + pushl %eax + + + /* Read the rest of the image to _start. This code works by reading a track + at a time... + */ + + movl $_edata, %eax + movl $_start, %ebx /* Our destination address. */ + subl %ebx, %eax /* Number of bytes in the image. */ + movl $1, %ecx /* Track/sector to read from (starts at 1). */ + +0: + cmpl $0, %eax + jle 1f + + pushl %eax /* Save the number of bytes we want. */ + pushl %ebx /* Save our current address. */ + pushl %ecx /* Save our disk location. */ + + /* Read in a track with head 0. */ + + movl %ebx, %eax /* Put our address into ES:BX. */ + shr $4, %eax + movw %ax, %es + andl $0xF, %ebx + movw $0, %dx /* Disk 0, head 0 */ + movb $0x02, %ah + movb $sectorsPerTrack, %al /* Read the entire track. */ + movb $1, %cl + int $0x13 /* CX points to our track/sector. */ + + /* So go ahead and resume execution at the real starting address. This + only serves to move us quickly to the real starting location; and has + no effect after reading additional tracks. If we didn't jump after + reading the first track, then we limit ourselves to reading images of + 30k bytes max before overwriting ourselves at 0x7C00. + */ + + ljmp $0, $2f + hlt + + .align 4 +2: + + popl %ecx + popl %ebx + popl %eax + + /* Add our length to the address. */ + addl $bytesPerTrack, %ebx + subl $bytesPerTrack, %eax + + /* Maybe read in a track with head 1. */ + cmpl $0, %eax + jle 1f + + pushl %eax /* Save the number of bytes we want. */ + pushl %ebx /* Save our current address. */ + pushl %ecx + + movl %ebx, %eax /* Put our address into ES:BX. */ + shr $4, %eax + movw %ax, %es + andl $0xF, %ebx + movw $0x0100, %dx /* Disk 0, head 1 */ + movb $0x02, %ah + movb $sectorsPerTrack, %al /* Read the entire track. */ + movb $1, %cl + int $0x13 /* CX points to our track/sector. */ + + popl %ecx + popl %ebx + popl %eax + + /* Add our length to the address. */ + addl $bytesPerTrack, %ebx + subl $bytesPerTrack, %eax + + /* Move to the next track. */ + addb $0x1, %ch + + jmp 0b + + /* Write the 0x55/0xAA signature at the end of the first + block. Without this signature the BIOS won't consider this + block to be bootable. + */ + + . = _start + 510 + .byte 0x55 + .byte 0xAA + + +1: + + /* Lets be nice and wait for the diskette drive motor to go off before continuing. */ + + movw $0x40, %ax + movw %ax, %es + movl $0x40, %ebx +2: es + movb (%bx), %al + cmpb $0, %al + jne 2b + + /* Now we're all loaded up in memory. */ + + /* Disable interrupt handling. */ + cli + + /* Load GDTR and IDTR. */ + + lgdt %cs:gdt + lidt %cs:idt + + /* Switch to protected mode. */ + movl %cr0,%eax + orb $1, %al + movl %eax,%cr0 + ljmp $8, $3f + + hlt + + .align 4, 0xFF +gdt: + .word gdtEnd - gdtStart + .long gdtStart + + .align 4, 0xFF +idt: + .word 0x07FF /* Allow space for 256 interrupt vectors. */ + .long 0 + +gdtStart: + /* Selector 0x00 == invalid. */ + .word 0x0000 + .word 0x0000 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + + /* Selector 0x08 == code. */ + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0x9B + .byte 0xCF + .byte 0x00 + + /* Selector 0x10 == data. */ + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0x93 + .byte 0xCF + .byte 0x00 + + /* Selector 0x18 == shorter code: faults any code access 0xF0000000-0xFFFFFFFF. */ + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0x9B + .byte 0xC7 + .byte 0x00 + + /* Selector 0x20 == data; faults any access 0xF0000000-0xFFFFFFFF. */ + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0x93 + .byte 0xC7 + .byte 0x00 + + .align 4, 0xFF +gdtEnd: + + .code32 +3: + + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + /* Make our new stack point to the same place as the old one. */ + xorl %ebx, %ebx + movw %ss, %bx + shl $4, %ebx + addl %esp, %ebx + movw %ax, %ss + movl %ebx, %esp + movl $0, %ebp + +/* Reset the flags register. */ + pushl $0 + popfl + +/* Save the standard and extended memory lengths into some static variables... + I'm predicting that someone is going to break our way of passing a pointer + to this structure... may as well avoid that problem now. +*/ + .data + .align 4 + .globl pc_standard_memory_size +pc_standard_memory_size: + .long 0 + .globl pc_extended_memory_size +pc_extended_memory_size: + .long 0 + .text + movl 0(%esp), %eax + movl 4(%esp), %ebx + movl %eax, pc_standard_memory_size + movl %ebx, pc_extended_memory_size + +/* _pc_entry() takes a pointer to our startup array (which only has standard + and extended memory sizes in it, on the stack). +*/ + movl %esp, %ebx /* They are the last parameters on the stack. */ + pushl %ebx + +#endif /* CYG_HAL_STARTUP_FLOPPY */ + +#ifdef CYG_HAL_STARTUP_RAM + + /* In this case, the sizes of memory are pointed to by a pointer in IRQ + vector 15. + */ + + /* Save the standard and extended memory lengths into some static variables... + */ + .data + .align 4 + .globl pc_standard_memory_size +pc_standard_memory_size: + .long 0 + .globl pc_extended_memory_size +pc_extended_memory_size: + .long 0 + .text + movl (15 * 8), %ebp + movl 0(%ebp), %eax + movl 4(%ebp), %ebx + movl %eax, pc_standard_memory_size + movl %ebx, pc_extended_memory_size + +#endif /* CYG_HAL_STARTUP_RAM */ + + .endm /* hal_cpu_init */ + + +##============================================================================= +## Interrupt controller support + +#define CYGPKG_HAL_I386_INTC_INIT_DEFINED + + .macro hal_intc_init + + # The interrupt controller is configured so that IRQ levels 0-7 trigger + # interrupt vector 32-39; levels 8-15 trigger 40-47. + movb $0x11, %al + outb %al, $0x20 + movb $0x20, %al + outb %al, $0x21 + movb $0x04, %al + outb %al, $0x21 + movb $0x01, %al + outb %al, $0x21 + movb $0xFF, %al /* Mask off all interrupts. */ + outb %al, $0x21 + + movb $0x11, %al + outb %al, $0xA0 + movb $0x28, %al + outb %al, $0xA1 + movb $0x02, %al + outb %al, $0xA1 + movb $0x01, %al + outb %al, $0xA1 + movb $0xFF, %al /* Mask off all interrupts. */ + outb %al, $0xA1 + + .endm /* hal_intc_init */ + + .macro hal_intc_ack vector + # Use any registers you like. + movl \vector, %edx + movb $0x20, %al + cmpl $0x20, %edx + jl 8f + cmpl $0x30, %edx + jge 9f + outb %al, $0x20 + jmp 8f +9: outb %al, $0xA0 +8: nop + .endm + +##============================================================================= +## FPU support + +#define CYGPKG_HAL_I386_FPU_DEFINED + + .macro hal_fpu_init + # Tell the CPU to use the math hardware. + movl %cr0, %eax + orl $0x32, %eax + movl %eax, %cr0 + + finit # and initialize... + + ## Enable floating point exceptions. Bit mask: + ## 1 - invalid operation + ## 2 - denormalized operand + ## 4 - zero divide + ## 8 - overflow + ## 16 - underflow + ## 32 - precision + pushl $0 + fstcw 0(%esp) + movl 0(%esp),%eax + andb $(~0x04),%al + movl %eax,0(%esp) + fldcw 0(%esp) + addl $4,%esp + + # Tell the CPU to generate a interrupt 7 when the math device is used. +#if 0 + movl %cr0, %eax + orl $0x3A, %eax + movl %eax, %cr0 +#endif + + .endm /* hal_fpu_init */ + + + .macro hal_fpu_save regs + .endm /* hal_fpu_save */ + + .macro hal_fpu_save_caller regs + .endm /* hal_fpu_save_caller */ + + .macro hal_fpu_save_callee regs + .endm /* hal_fpu_save_callee */ + + .macro hal_fpu_load_caller regs + .endm /* hal_fpu_load_caller */ + + .macro hal_fpu_load_callee regs + .endm /* hal_fpu_load_callee */ + + .macro hal_fpu_load regs + .endm /* hal_fpu_load */ + + +##============================================================================= +#endif // ifndef CYGONCE_HAL_PLATFORM_INC +## end of platform.inc
