1 //==========================================================================
5 // HAL platform miscellaneous functions
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: nickg, jlarmour, pjo
46 // Purpose: HAL miscellaneous functions
47 // Description: This file contains miscellaneous functions provided by the
50 //####DESCRIPTIONEND####
52 //========================================================================*/
54 #include <pkgconf/hal.h>
56 #include <cyg/infra/cyg_type.h> // Base types
57 #include <cyg/infra/cyg_trac.h> // tracing macros
58 #include <cyg/infra/cyg_ass.h> // assertion macros
60 #include <cyg/hal/hal_arch.h> // architectural definitions
62 #include <cyg/hal/hal_intr.h> // Interrupt handling
64 #include <cyg/hal/hal_cache.h> // Cache handling
66 #include <cyg/hal/plf_misc.h>
68 #include <cyg/hal/hal_io.h>
70 #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
71 #include <cyg/hal/hal_if.h>
75 #include <pkgconf/kernel.h>
76 #include <cyg/kernel/ktypes.h>
77 #include <cyg/kernel/kapi.h>
78 #endif /* CYGPKG_KERNEL */
80 /*------------------------------------------------------------------------*/
82 extern void patch_dbg_syscalls(void * vector);
84 extern void hal_pcmb_init(void);
86 #ifdef CYGPKG_HAL_SMP_SUPPORT
87 __externC void cyg_hal_smp_init(void);
90 CYG_ADDRWORD cyg_hal_pc_memsize_base;
91 CYG_ADDRWORD cyg_hal_pc_memsize_extended;
93 //----------------------------------------------------------------------------
96 volatile CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
97 volatile CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
98 volatile CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
100 //-----------------------------------------------------------------------------
101 // IDT interrupt gate initialization
103 externC void cyg_hal_pc_set_idt_entry(CYG_ADDRESS routine,short *idtEntry)
106 idtEntry[0]=routine & 0xFFFF;
109 idtEntry[3]=routine >> 16;
112 /*------------------------------------------------------------------------*/
114 void hal_platform_init(void)
118 HAL_ICACHE_INVALIDATE_ALL();
120 HAL_DCACHE_INVALIDATE_ALL();
123 #ifdef CYGPKG_HAL_I386_PC_MEMSIZE_HARDCODE
124 cyg_hal_pc_memsize_base = CYGNUM_HAL_I386_PC_MEMSIZE_BASE;
125 cyg_hal_pc_memsize_extended = CYGNUM_HAL_I386_PC_MEMSIZE_EXTENDED;
128 #ifdef CYGPKG_HAL_I386_PC_MEMSIZE_BIOS
131 HAL_READ_CMOS( 0x15, lo );
132 HAL_READ_CMOS( 0x16, hi );
134 cyg_hal_pc_memsize_base = ((hi<<8)+lo)*1024;
136 #ifndef CYG_HAL_STARTUP_ROM
137 // If we started up under a BIOS, then it will have put
138 // the discovered extended memory size in CMOS bytes 30/31.
139 HAL_READ_CMOS( 0x30, lo );
140 HAL_READ_CMOS( 0x31, hi );
143 HAL_READ_CMOS( 0x17, lo );
144 HAL_READ_CMOS( 0x18, hi );
147 cyg_hal_pc_memsize_extended = ((hi<<8)+lo)*1024;
150 // Call motherboard init function
153 // ISR table setup: plant the default ISR in all interrupt handlers
154 // and the default interrupt VSR in the equivalent VSR table slots.
155 for (vector = CYGNUM_HAL_ISR_MIN; vector <= CYGNUM_HAL_ISR_MAX; vector++)
158 HAL_TRANSLATE_VECTOR( vector, index );
159 hal_interrupt_handlers[index] = (CYG_ADDRESS) HAL_DEFAULT_ISR;
160 HAL_VSR_SET( vector, &__default_interrupt_vsr, NULL );
163 #if !defined(CYG_HAL_STARTUP_RAM)
164 for (vector = CYGNUM_HAL_EXCEPTION_MIN;
165 vector <= CYGNUM_HAL_EXCEPTION_MAX;
168 #if defined(CYGHWR_HAL_I386_FPU_SWITCH_LAZY)
169 // If we are doing lazy FPU switching, the FPU switch VSR has
170 // already been installed, so avoid overwriting it.
171 if( vector != CYGNUM_HAL_VECTOR_NO_DEVICE )
174 HAL_VSR_SET( vector, &__default_exception_vsr, NULL );
179 #ifdef CYGPKG_REDBOOT
181 // Start the timer device running if we are in a RedBoot
184 HAL_CLOCK_INITIALIZE( CYGNUM_HAL_RTC_PERIOD );
190 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || \
191 defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
193 void hal_ctrlc_isr_init(void);
194 hal_ctrlc_isr_init();
199 #ifdef CYGPKG_HAL_SMP_SUPPORT
207 cyg_uint8 *hal_i386_mem_real_region_top( cyg_uint8 *regionend )
209 CYG_ASSERT( cyg_hal_pc_memsize_base > 0 , "No base RAM size set!");
210 CYG_ASSERT( cyg_hal_pc_memsize_extended > 0 , "No extended RAM size set!");
212 if( (CYG_ADDRESS)regionend <= 0x000A0000 )
213 regionend = (cyg_uint8 *)cyg_hal_pc_memsize_base;
214 else if( (CYG_ADDRESS)regionend >= 0x00100000 )
215 regionend = (cyg_uint8 *)cyg_hal_pc_memsize_extended+0x00100000;
220 /*------------------------------------------------------------------------*/
222 void hal_pc_reset(void)
224 /* Use Intel's IDT triple-fault trick. */
225 asm("movl $badIdt, %eax\n"
238 /*------------------------------------------------------------------------*/
247 cyg_uint32 cval1, cval2;
249 // Wait in bursts of 1s to avoid overflow problems with the
250 // multiply by 1000 below.
257 // The PC clock ticks at 838ns per tick. So we convert the us
258 // value we were given to clock ticks and wait for that many
261 ticks = (us1 * 1000UL) / 838UL;
263 HAL_CLOCK_READ( &cval1 );
265 // We just loop, waiting for clock ticks to happen,
266 // and subtracting them from ticks when they do.
271 HAL_CLOCK_READ( &cval2 );
273 diff = cval2 - cval1;
275 // Cope with counter wrap-around.
277 diff += CYGNUM_HAL_RTC_PERIOD;
287 /*------------------------------------------------------------------------*/
288 /* End of plf_misc.c */