![]() |
|
|||
File indexing completed on 2025-05-11 08:23:41
0001 /*-------------------------------------------------------------------------+ 0002 | ldsegs.s v1.1 - PC386 BSP - 1997/08/07 0003 +--------------------------------------------------------------------------+ 0004 | This file assists the board independent startup code by loading the proper 0005 | segment register values. The values loaded are board dependent. In addition 0006 | it contains code to enable the A20 line and to reprogram the PIC to relocate 0007 | the IRQ interrupt vectors to 0x20 -> 0x2f. 0008 | NOTE: No stack has been established when this routine is invoked. 0009 | It returns by jumping back to bspentry. 0010 +--------------------------------------------------------------------------+ 0011 | (C) Copyright 1997 - 0012 | - NavIST Group - Real-Time Distributed Systems and Industrial Automation 0013 | 0014 | http://pandora.ist.utl.pt 0015 | 0016 | Instituto Superior Tecnico * Lisboa * PORTUGAL 0017 +--------------------------------------------------------------------------+ 0018 | Disclaimer: 0019 | 0020 | This file is provided "AS IS" without warranty of any kind, either 0021 | expressed or implied. 0022 +--------------------------------------------------------------------------+ 0023 | This code is base on: 0024 | ldsegs.s,v 1.4 1996/04/20 16:48:30 joel Exp - go32 BSP 0025 | With the following copyright notice: 0026 | ************************************************************************** 0027 | * COPYRIGHT (c) 1989-1999. 0028 | * On-Line Applications Research Corporation (OAR). 0029 | * 0030 | * The license and distribution terms for this file may be 0031 | * found in the file LICENSE in this distribution or at 0032 | * http://www.rtems.org/license/LICENSE. 0033 | ************************************************************************** 0034 +--------------------------------------------------------------------------*/ 0035 0036 #include <rtems/asm.h> 0037 #include <bsp/tblsizes.h> /* contains sizes of GDT and IDT */ 0038 #include <bspopts.h> 0039 0040 /*----------------------------------------------------------------------------+ 0041 | CODE section 0042 +----------------------------------------------------------------------------*/ 0043 EXTERN (rtems_i8259_masks) 0044 0045 BEGIN_CODE 0046 0047 EXTERN (_establish_stack) 0048 EXTERN (Timer_exit) 0049 EXTERN (clockOff) 0050 0051 /*----------------------------------------------------------------------------+ 0052 | pc386_delay 0053 +------------------------------------------------------------------------------ 0054 | Delay is needed after doing I/O. 0055 | 0056 | The outb version is OK on most machines BUT the loop version ... 0057 | 0058 | will delay for 1us on 1Gz machine, it will take a little bit 0059 | longer on slower machines, however, it does not matter because we 0060 | are going to call this function only a few times 0061 0062 +----------------------------------------------------------------------------*/ 0063 #define DELAY_USE_OUTB 0064 0065 .p2align 4 0066 .globl _pc386_delay 0067 .globl pc386_delay 0068 pc386_delay: 0069 _pc386_delay: 0070 #ifdef DELAY_USE_OUTB 0071 outb al, $0x80 # about 1uS delay on most machines 0072 #else 0073 movl $0x200, eax 0074 pc386_delay1: 0075 dec eax 0076 jnz pc386_delay1 0077 #endif 0078 ret 0079 0080 /*-------------------------------------------------------------------------+ 0081 | Function: _load_segments 0082 | Description: Current environment is standard PC booted by grub. 0083 | So, there is no value in saving current GDT and IDT 0084 | settings we have to set it up ourseves. (Naturally 0085 | it will be not so in case we are booted by some 0086 | boot monitor, however, then it will be different 0087 | BSP). After that we have to load board segment registers 0088 | with apropriate values + reprogram PIC. 0089 | Global Variables: None. 0090 | Arguments: None. 0091 | Returns: Nothing. 0092 +--------------------------------------------------------------------------*/ 0093 .p2align 4 0094 0095 PUBLIC (_load_segments) 0096 SYM (_load_segments): 0097 0098 lgdt SYM(gdtdesc) 0099 lidt SYM(IDT_Descriptor) 0100 0101 /* Load CS, flush prefetched queue */ 0102 ljmp $0x8, $next_step 0103 0104 next_step: 0105 /* Load segment registers */ 0106 movw $0x10, ax 0107 movw ax, ss 0108 movw ax, ds 0109 movw ax, es 0110 movw ax, fs 0111 movw ax, gs 0112 0113 /*---------------------------------------------------------------------+ 0114 | Now we have to reprogram the interrupts :-(. We put them right after 0115 | the intel-reserved hardware interrupts, at int 0x20-0x2F. There they 0116 | won't mess up anything. Sadly IBM really messed this up with the 0117 | original PC, and they haven't been able to rectify it afterwards. Thus 0118 | the bios puts interrupts at 0x08-0x0f, which is used for the internal 0119 | hardware interrupts as well. We just have to reprogram the 8259's, and 0120 | it isn't fun. 0121 +---------------------------------------------------------------------*/ 0122 0123 movb $0x11, al /* initialization sequence */ 0124 outb al, $0x20 /* send it to 8259A-1 */ 0125 call SYM(pc386_delay) 0126 outb al, $0xA0 /* and to 8259A-2 */ 0127 call SYM(pc386_delay) 0128 0129 movb $0x20, al /* start of hardware int's (0x20) */ 0130 outb al, $0x21 0131 call SYM(pc386_delay) 0132 movb $0x28, al /* start of hardware int's 2 (0x28) */ 0133 outb al, $0xA1 0134 call SYM(pc386_delay) 0135 0136 movb $0x04, al /* 8259-1 is master */ 0137 outb al, $0x21 0138 call SYM(pc386_delay) 0139 movb $0x02, al /* 8259-2 is slave */ 0140 outb al, $0xA1 0141 call SYM(pc386_delay) 0142 0143 movb $0x01, al /* 8086 mode for both */ 0144 outb al, $0x21 0145 call SYM(pc386_delay) 0146 outb al, $0xA1 0147 call SYM(pc386_delay) 0148 0149 /* 0150 * The IMR values must correspond to the initial value of i8259s_cache. 0151 */ 0152 movb $0xFF, al /* mask off all interrupts for now */ 0153 outb al, $0xA1 0154 call SYM(pc386_delay) 0155 movb $0xFB, al /* mask all irq's but irq2 which */ 0156 outb al, $0x21 /* is cascaded */ 0157 call SYM(pc386_delay) 0158 jmp SYM (_establish_stack) # return to the bsp entry code 0159 0160 /*-------------------------------------------------------------------------+ 0161 | Function: _default_int_handler 0162 | Description: default interrupt handler 0163 | Global Variables: None. 0164 | Arguments: None. 0165 | Returns: Nothing. 0166 +--------------------------------------------------------------------------*/ 0167 .p2align 4 0168 0169 /*---------------------------------------------------------------------------+ 0170 | GDT itself 0171 +--------------------------------------------------------------------------*/ 0172 #if GDT_SIZE < NUM_SYSTEM_GDT_DESCRIPTORS 0173 #error "GDT_SIZE must be at least NUM_SYSTEM_GDT_DESCRIPTORS" 0174 #endif 0175 0176 BEGIN_DATA 0177 .p2align 4 0178 0179 PUBLIC (_Global_descriptor_table) 0180 SYM (_Global_descriptor_table): 0181 0182 /* NULL segment */ 0183 .word 0, 0 0184 .byte 0, 0, 0, 0 0185 0186 /* code segment */ 0187 .word 0xffff, 0 0188 .byte 0, 0x9e, 0xcf, 0 0189 0190 /* data segment */ 0191 .word 0xffff, 0 0192 .byte 0, 0x92, 0xcf, 0 0193 0194 /* gs segment(s) */ 0195 .rept (NUM_SYSTEM_GDT_DESCRIPTORS - 3) 0196 .word 0xffff, 0 0197 .byte 0, 0x92, 0xcf, 0 0198 .endr 0199 0200 /* allocated space for user segments */ 0201 .rept (GDT_SIZE - NUM_SYSTEM_GDT_DESCRIPTORS) 0202 .word 0,0,0,0 0203 .endr 0204 0205 /*---------------------------------------------------------------------------+ 0206 | Descriptor of GDT 0207 +--------------------------------------------------------------------------*/ 0208 PUBLIC(gdtdesc) 0209 SYM(gdtdesc): 0210 .word (GDT_SIZE*8 - 1) 0211 .long SYM (_Global_descriptor_table) 0212 0213 /*---------------------------------------------------------------------------+ 0214 | IDT itself 0215 +---------------------------------------------------------------------------*/ 0216 .p2align 4 0217 0218 PUBLIC(Interrupt_descriptor_table) 0219 SYM(Interrupt_descriptor_table): 0220 .rept IDT_SIZE 0221 .word 0,0,0,0 0222 .endr 0223 0224 /*---------------------------------------------------------------------------+ 0225 | Descriptor of IDT 0226 +--------------------------------------------------------------------------*/ 0227 0228 .p2align 4 0229 PUBLIC(IDT_Descriptor) 0230 SYM(IDT_Descriptor): 0231 .word (IDT_SIZE*8 - 1) 0232 .long SYM (Interrupt_descriptor_table) 0233 0234 END_DATA 0235 0236 .section .m_hdr 0237 .long 0x1BADB002 0238 .long 0 0239 .long 0xE4524FFE 0240 END
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |