[7150f00f] | 1 | /*-------------------------------------------------------------------------+ |
---|
| 2 | | ldsegs.s v1.1 - PC386 BSP - 1997/08/07 |
---|
| 3 | +--------------------------------------------------------------------------+ |
---|
| 4 | | This file assists the board independent startup code by loading the proper |
---|
| 5 | | segment register values. The values loaded are board dependent. In addition |
---|
| 6 | | it contains code to enable the A20 line and to reprogram the PIC to relocate |
---|
| 7 | | the IRQ interrupt vectors to 0x20 -> 0x2f. |
---|
| 8 | | NOTE: No stack has been established when this routine is invoked. |
---|
| 9 | | It returns by jumping back to bspentry. |
---|
| 10 | +--------------------------------------------------------------------------+ |
---|
| 11 | | (C) Copyright 1997 - |
---|
| 12 | | - NavIST Group - Real-Time Distributed Systems and Industrial Automation |
---|
| 13 | | |
---|
| 14 | | http://pandora.ist.utl.pt |
---|
| 15 | | |
---|
| 16 | | Instituto Superior Tecnico * Lisboa * PORTUGAL |
---|
| 17 | +--------------------------------------------------------------------------+ |
---|
| 18 | | Disclaimer: |
---|
| 19 | | |
---|
| 20 | | This file is provided "AS IS" without warranty of any kind, either |
---|
| 21 | | expressed or implied. |
---|
| 22 | +--------------------------------------------------------------------------+ |
---|
| 23 | | This code is base on: |
---|
| 24 | | ldsegs.s,v 1.4 1996/04/20 16:48:30 joel Exp - go32 BSP |
---|
| 25 | | With the following copyright notice: |
---|
| 26 | | ************************************************************************** |
---|
[08311cc3] | 27 | | * COPYRIGHT (c) 1989-1999. |
---|
[6f9c75c3] | 28 | | * On-Line Applications Research Corporation (OAR). |
---|
| 29 | | * |
---|
| 30 | | * The license and distribution terms for this file may be |
---|
| 31 | | * found in found in the file LICENSE in this distribution or at |
---|
[af2abc9e] | 32 | | * http://www.rtems.com/license/LICENSE. |
---|
[7150f00f] | 33 | | ************************************************************************** |
---|
| 34 | | |
---|
[6f9c75c3] | 35 | | $Id$ |
---|
[7150f00f] | 36 | +--------------------------------------------------------------------------*/ |
---|
| 37 | |
---|
[b14d8a48] | 38 | #include <rtems/asm.h> |
---|
[7150f00f] | 39 | |
---|
| 40 | /*----------------------------------------------------------------------------+ |
---|
| 41 | | CODE section |
---|
| 42 | +----------------------------------------------------------------------------*/ |
---|
[67a2288] | 43 | EXTERN (rtems_i8259_masks) |
---|
[6128a4a] | 44 | |
---|
[7150f00f] | 45 | BEGIN_CODE |
---|
| 46 | |
---|
[4050a7f] | 47 | EXTERN (_establish_stack) |
---|
| 48 | EXTERN (Timer_exit) |
---|
[67a2288] | 49 | EXTERN (clockOff) |
---|
[7150f00f] | 50 | |
---|
| 51 | /*----------------------------------------------------------------------------+ |
---|
[df49c60] | 52 | | pc386_delay |
---|
[7150f00f] | 53 | +------------------------------------------------------------------------------ |
---|
[6128a4a] | 54 | | Delay is needed after doing I/O. |
---|
[76c356f] | 55 | | |
---|
| 56 | | The outb version is OK on most machines BUT the loop version ... |
---|
[6128a4a] | 57 | | |
---|
[76c356f] | 58 | | will delay for 1us on 1Gz machine, it will take a little bit |
---|
| 59 | | longer on slower machines, however, it does not matter because we |
---|
| 60 | | are going to call this function only a few times |
---|
| 61 | |
---|
[7150f00f] | 62 | +----------------------------------------------------------------------------*/ |
---|
[2116e33] | 63 | #define DELAY_USE_OUTB |
---|
[6128a4a] | 64 | |
---|
[76c356f] | 65 | .p2align 4 |
---|
[df49c60] | 66 | .globl _pc386_delay |
---|
| 67 | .globl pc386_delay |
---|
| 68 | pc386_delay: |
---|
| 69 | _pc386_delay: |
---|
[2116e33] | 70 | #ifdef DELAY_USE_OUTB |
---|
| 71 | outb al, $0x80 # about 1uS delay on most machines |
---|
| 72 | #else |
---|
| 73 | movl $0x200, eax |
---|
[df49c60] | 74 | pc386_delay1: |
---|
[2116e33] | 75 | dec eax |
---|
[df49c60] | 76 | jnz pc386_delay1 |
---|
[2116e33] | 77 | #endif |
---|
[c3538f3] | 78 | ret |
---|
[76c356f] | 79 | |
---|
[7150f00f] | 80 | /*-------------------------------------------------------------------------+ |
---|
| 81 | | Function: _load_segments |
---|
[4050a7f] | 82 | | Description: Current environment is standard PC booted by grub. |
---|
| 83 | | So, there is no value in saving current GDT and IDT |
---|
[5d18fb0] | 84 | | settings we have to set it up ourseves. (Naturally |
---|
[4050a7f] | 85 | | it will be not so in case we are booted by some |
---|
| 86 | | boot monitor, however, then it will be different |
---|
[5d18fb0] | 87 | | BSP). After that we have to load board segment registers |
---|
[4050a7f] | 88 | | with apropriate values + reprogram PIC. |
---|
[7150f00f] | 89 | | Global Variables: None. |
---|
| 90 | | Arguments: None. |
---|
[6128a4a] | 91 | | Returns: Nothing. |
---|
[7150f00f] | 92 | +--------------------------------------------------------------------------*/ |
---|
[4050a7f] | 93 | .p2align 4 |
---|
[6128a4a] | 94 | |
---|
[7150f00f] | 95 | PUBLIC (_load_segments) |
---|
| 96 | SYM (_load_segments): |
---|
[4050a7f] | 97 | |
---|
| 98 | lgdt SYM(gdtdesc) |
---|
| 99 | lidt SYM(idtdesc) |
---|
| 100 | |
---|
| 101 | /* Load CS, flush prefetched queue */ |
---|
| 102 | ljmp $0x8, $next_step |
---|
| 103 | |
---|
[6128a4a] | 104 | next_step: |
---|
[4050a7f] | 105 | /* Load segment registers */ |
---|
| 106 | movw $0x10, ax |
---|
| 107 | movw ax, ss |
---|
| 108 | movw ax, ds |
---|
| 109 | movw ax, es |
---|
| 110 | movw ax, fs |
---|
| 111 | movw ax, gs |
---|
| 112 | |
---|
| 113 | /*---------------------------------------------------------------------+ |
---|
| 114 | | Now we have to reprogram the interrupts :-(. We put them right after |
---|
| 115 | | the intel-reserved hardware interrupts, at int 0x20-0x2F. There they |
---|
| 116 | | won't mess up anything. Sadly IBM really messed this up with the |
---|
| 117 | | original PC, and they haven't been able to rectify it afterwards. Thus |
---|
| 118 | | the bios puts interrupts at 0x08-0x0f, which is used for the internal |
---|
| 119 | | hardware interrupts as well. We just have to reprogram the 8259's, and |
---|
| 120 | | it isn't fun. |
---|
| 121 | +---------------------------------------------------------------------*/ |
---|
[7150f00f] | 122 | |
---|
| 123 | movb $0x11, al /* initialization sequence */ |
---|
| 124 | outb al, $0x20 /* send it to 8259A-1 */ |
---|
[df49c60] | 125 | call SYM(pc386_delay) |
---|
[7150f00f] | 126 | outb al, $0xA0 /* and to 8259A-2 */ |
---|
[df49c60] | 127 | call SYM(pc386_delay) |
---|
[6128a4a] | 128 | |
---|
[7150f00f] | 129 | movb $0x20, al /* start of hardware int's (0x20) */ |
---|
| 130 | outb al, $0x21 |
---|
[df49c60] | 131 | call SYM(pc386_delay) |
---|
[7150f00f] | 132 | movb $0x28, al /* start of hardware int's 2 (0x28) */ |
---|
| 133 | outb al, $0xA1 |
---|
[df49c60] | 134 | call SYM(pc386_delay) |
---|
[6128a4a] | 135 | |
---|
[7150f00f] | 136 | movb $0x04, al /* 8259-1 is master */ |
---|
| 137 | outb al, $0x21 |
---|
[df49c60] | 138 | call SYM(pc386_delay) |
---|
[7150f00f] | 139 | movb $0x02, al /* 8259-2 is slave */ |
---|
| 140 | outb al, $0xA1 |
---|
[df49c60] | 141 | call SYM(pc386_delay) |
---|
[6128a4a] | 142 | |
---|
[7150f00f] | 143 | movb $0x01, al /* 8086 mode for both */ |
---|
| 144 | outb al, $0x21 |
---|
[df49c60] | 145 | call SYM(pc386_delay) |
---|
[7150f00f] | 146 | outb al, $0xA1 |
---|
[df49c60] | 147 | call SYM(pc386_delay) |
---|
[6128a4a] | 148 | |
---|
[7150f00f] | 149 | movb $0xFF, al /* mask off all interrupts for now */ |
---|
| 150 | outb al, $0xA1 |
---|
[df49c60] | 151 | call SYM(pc386_delay) |
---|
[7150f00f] | 152 | movb $0xFB, al /* mask all irq's but irq2 which */ |
---|
| 153 | outb al, $0x21 /* is cascaded */ |
---|
[df49c60] | 154 | call SYM(pc386_delay) |
---|
[7150f00f] | 155 | |
---|
[99826740] | 156 | movw $0xFFFB, SYM(i8259s_cache) /* set up same values in cache */ |
---|
[6128a4a] | 157 | |
---|
[7150f00f] | 158 | jmp SYM (_establish_stack) # return to the bsp entry code |
---|
| 159 | |
---|
[4050a7f] | 160 | /*-------------------------------------------------------------------------+ |
---|
| 161 | | Function: _default_int_handler |
---|
| 162 | | Description: default interrupt handler |
---|
| 163 | | Global Variables: None. |
---|
| 164 | | Arguments: None. |
---|
[6128a4a] | 165 | | Returns: Nothing. |
---|
[4050a7f] | 166 | +--------------------------------------------------------------------------*/ |
---|
| 167 | .p2align 4 |
---|
[6128a4a] | 168 | |
---|
[4050a7f] | 169 | /*---------------------------------------------------------------------------+ |
---|
| 170 | | GDT itself |
---|
| 171 | +--------------------------------------------------------------------------*/ |
---|
| 172 | |
---|
[ebedf31] | 173 | BEGIN_DATA |
---|
[4050a7f] | 174 | .p2align 4 |
---|
[6128a4a] | 175 | |
---|
[4050a7f] | 176 | PUBLIC (_Global_descriptor_table) |
---|
| 177 | SYM (_Global_descriptor_table): |
---|
[7150f00f] | 178 | |
---|
[4050a7f] | 179 | /* NULL segment */ |
---|
[6128a4a] | 180 | .word 0, 0 |
---|
[4050a7f] | 181 | .byte 0, 0, 0, 0 |
---|
[7150f00f] | 182 | |
---|
[4050a7f] | 183 | /* code segment */ |
---|
| 184 | .word 0xffff, 0 |
---|
| 185 | .byte 0, 0x9e, 0xcf, 0 |
---|
[7150f00f] | 186 | |
---|
[4050a7f] | 187 | /* data segment */ |
---|
| 188 | .word 0xffff, 0 |
---|
| 189 | .byte 0, 0x92, 0xcf, 0 |
---|
[6128a4a] | 190 | |
---|
[4050a7f] | 191 | /*---------------------------------------------------------------------------+ |
---|
| 192 | | Descriptor of GDT |
---|
| 193 | +--------------------------------------------------------------------------*/ |
---|
| 194 | SYM (gdtdesc): |
---|
[6128a4a] | 195 | .word (3*8 - 1) |
---|
[4050a7f] | 196 | .long SYM (_Global_descriptor_table) |
---|
[7150f00f] | 197 | |
---|
[4050a7f] | 198 | /*---------------------------------------------------------------------------+ |
---|
| 199 | | IDT itself |
---|
| 200 | +---------------------------------------------------------------------------*/ |
---|
| 201 | .p2align 4 |
---|
[6128a4a] | 202 | |
---|
[4050a7f] | 203 | PUBLIC(Interrupt_descriptor_table) |
---|
| 204 | SYM(Interrupt_descriptor_table): |
---|
| 205 | .rept 256 |
---|
| 206 | .word 0,0,0,0 |
---|
| 207 | .endr |
---|
[359e537] | 208 | |
---|
[4050a7f] | 209 | /*---------------------------------------------------------------------------+ |
---|
| 210 | | Descriptor of IDT |
---|
| 211 | +--------------------------------------------------------------------------*/ |
---|
[ebedf31] | 212 | |
---|
[58f7c34] | 213 | .p2align 4 |
---|
[6128a4a] | 214 | SYM(idtdesc): |
---|
[4050a7f] | 215 | .word (256*8 - 1) |
---|
| 216 | .long SYM (Interrupt_descriptor_table) |
---|
[359e537] | 217 | |
---|
[ebedf31] | 218 | END_DATA |
---|
[7150f00f] | 219 | |
---|
[99826740] | 220 | .section .m_hdr |
---|
| 221 | .long 0x1BADB002 |
---|
| 222 | .long 0 |
---|
| 223 | .long 0xE4524FFE |
---|
[7150f00f] | 224 | END |
---|