forked from Imagelibrary/rtems
Ada95, gnat, go32
This commit is contained in:
@@ -44,6 +44,9 @@ The following persons/organizations have made contributions:
|
||||
as well as the modifications to the m68k dependent executive code to
|
||||
support m68k family members based on the mc68000 core.
|
||||
|
||||
+ Bryce Cogswell (cogswell@cs.uoregon.edu) submitted the support for MS-DOS
|
||||
as a development environment as well as djgpp/go32 as a target environment.
|
||||
|
||||
Finally, the RTEMS project would like to thank those who have contributed
|
||||
to the other free software efforts which RTEMS utilizes. The primary RTEMS
|
||||
development environment is from the Free Software Foundation (the GNU
|
||||
|
||||
75
c/README.DOS
Normal file
75
c/README.DOS
Normal file
@@ -0,0 +1,75 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
tools
|
||||
-----
|
||||
The RTEMS build procedure was designed with the capabilitiies of a
|
||||
typical UNIX computer in mind. Making this procedure work under MS-DOS
|
||||
is not that difficult but requires that MS-DOS versions of a number
|
||||
of UNIX utilities be acquired and installed. For time being, the
|
||||
best advice which can be offered is:
|
||||
|
||||
"This is a nasty question, since when I first set up the DOS machine
|
||||
(long before I acquired RTEMS) I ftp'd a bunch of different tool
|
||||
sets (all from SimTel), and then picked individual tools from each
|
||||
set that worked best for me. The djgpp tools are probably a good
|
||||
starting point, especially to get a working sed. Next the gnu tools
|
||||
in SimTel/msdos/gnuish, and then others. Sorry I can't give you more
|
||||
specific names. The only real requirement for the tools is that
|
||||
they *must* accept redirection of command line arguments from a file
|
||||
using the '@' notation (i.e., "mkdir @/tmp/args" reads the argument
|
||||
list from file /tmp/args)."
|
||||
|
||||
There is a special version (source and executable) of GNU make 3.71 for
|
||||
MS-DOS which minimizes the amount of memory used by recursive makes
|
||||
available on lancelot.gcs.redstone.army.mil in the directory: ... XXX
|
||||
|
||||
go32
|
||||
----
|
||||
go32 dumps the stack when a program seg-faults, and if this happens while
|
||||
on an alternate stack an infinite loop can ensue. Setting the environment
|
||||
variable GO32="core /tmp/core" will prevent more than 20 lines or
|
||||
so of stack information from being dumped after a crash, and the output
|
||||
will go to a file rather than the screen.
|
||||
|
||||
The go32 debuggers get confused by the relocated stacks used by tasks,
|
||||
and tend to crash when variables are inspected.
|
||||
|
||||
make directory
|
||||
--------------
|
||||
gcc-go32.cfg is used for cross compiling to the go32 environment under RTEMS,
|
||||
while djgcc.cfg is used for "native" compilation; i.e. under MSDOS rather
|
||||
than under RTEMS. The difference is that "native" compilation uses the djgpp
|
||||
I/O libraries, while "cross" compilation uses the RTEMS I/O libraries.
|
||||
|
||||
djgcc.cfg is identical to gcc.cfg, except for the omission of the -pipe
|
||||
option.
|
||||
|
||||
djgcc include files
|
||||
-------------------
|
||||
In general, we use RTEMS include files because these contain the proper
|
||||
declarations for the libc, and in particular, the stdio functions.
|
||||
When calling go32-specific functions it is necessary to include some
|
||||
djgpp include files, as well. Unfortunately, there are some disagreements
|
||||
between RTEMS and djgpp as to how certain functions and types are
|
||||
declared. In these cases, I have modified to RTEMS source to special-
|
||||
case the differences.
|
||||
|
||||
cpu-specific files
|
||||
------------------
|
||||
rtems/c/src/exec/cpu/i80386 is intended to contain 386-specific
|
||||
functions for RTEMS. Since under djgpp we do not have *complete*
|
||||
control of the processor, we must cooperate with the djgpp runtime
|
||||
environment, this directory cannot be shared between the go32 port
|
||||
and other 386 BSPs.
|
||||
|
||||
other
|
||||
-----
|
||||
* F12 will immediately abort the program.
|
||||
See libbsp/i80386/go32/iosupp/inch.c.
|
||||
|
||||
* libbsp/i80386/go32/timer uses the on-board timer chip by default.
|
||||
However, if executing on a Pentium processor you can use the on-chip
|
||||
64-bit cycle counter, which counts at whatever clock rate your processor
|
||||
runs at. To use this, compile with -DPENTIUM
|
||||
@@ -282,7 +282,7 @@ exit(int status)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RTEMS_UNIX
|
||||
#if !defined(RTEMS_UNIX) && !defined(__GO32__)
|
||||
void _exit(int status)
|
||||
{
|
||||
rtems_shutdown_executive(status);
|
||||
|
||||
@@ -42,7 +42,7 @@ const rtems_multiprocessing_table
|
||||
*/
|
||||
|
||||
const char _RTEMS_version[] =
|
||||
"RTEMS RELEASE V3.2.0 (" CPU_NAME "/" RTEMS_MODEL_NAME ")";
|
||||
"RTEMS RELEASE V3.2.01 (" CPU_NAME "/" RTEMS_MODEL_NAME ")";
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -42,7 +42,7 @@ const rtems_multiprocessing_table
|
||||
*/
|
||||
|
||||
const char _RTEMS_version[] =
|
||||
"RTEMS RELEASE V3.2.0 (" CPU_NAME "/" RTEMS_MODEL_NAME ")";
|
||||
"RTEMS RELEASE V3.2.01 (" CPU_NAME "/" RTEMS_MODEL_NAME ")";
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -108,7 +108,27 @@ void _CPU_Initialize(
|
||||
_CPU_Table = *cpu_table;
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
/*
|
||||
* This is unsupported.
|
||||
*/
|
||||
|
||||
_CPU_Fatal_halt( 0xdeaddead );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
|
||||
@@ -492,6 +492,19 @@ void _CPU_Initialize(
|
||||
void (*thread_dispatch)
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*
|
||||
* This routine installs a "raw" interrupt handler directly into the
|
||||
* processor's vector table.
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
|
||||
@@ -40,6 +40,15 @@
|
||||
* have to define these as appropriate.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Go32 suffers the same bug as __REGISTER_PREFIX__
|
||||
*/
|
||||
|
||||
#if __GO32__
|
||||
#undef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
@@ -67,7 +67,60 @@ void _CPU_Initialize(
|
||||
}
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
#if __GO32__
|
||||
#include <cpu.h>
|
||||
#include <go32.h>
|
||||
#include <dpmi.h>
|
||||
#endif /* __GO32__ */
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
#if __GO32__
|
||||
_go32_dpmi_seginfo handler_info;
|
||||
|
||||
*old_handler = 0; /* XXX not supported */
|
||||
|
||||
handler_info.pm_offset = new_handler;
|
||||
handler_info.pm_selector = _go32_my_cs();
|
||||
|
||||
/* install the IDT entry */
|
||||
_go32_dpmi_set_protected_mode_interrupt_vector( vector, &handler_info );
|
||||
#else
|
||||
i386_IDT_slot idt;
|
||||
unsigned32 handler;
|
||||
|
||||
*old_handler = 0; /* XXX not supported */
|
||||
|
||||
handler = (unsigned32) new_handler;
|
||||
|
||||
/* build the IDT entry */
|
||||
idt.offset_0_15 = handler & 0xffff;
|
||||
idt.segment_selector = i386_get_cs();
|
||||
idt.reserved = 0x00;
|
||||
idt.p_dpl = 0x8e; /* present, ISR */
|
||||
idt.offset_16_31 = handler >> 16;
|
||||
|
||||
/* install the IDT entry */
|
||||
i386_Install_idt(
|
||||
(unsigned32) &idt,
|
||||
_CPU_Table.interrupt_table_segment,
|
||||
(unsigned32) _CPU_Table.interrupt_table_offset + (8 * vector)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
@@ -95,27 +148,15 @@ void _CPU_ISR_install_vector(
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
i386_IDT_slot idt;
|
||||
proc_ptr ignored;
|
||||
unsigned32 unique_handler;
|
||||
|
||||
*old_handler = _ISR_Vector_table[ vector ];
|
||||
|
||||
/* calculate the unique entry point for this vector */
|
||||
unique_handler = _Interrupt_Handler_entry( vector );
|
||||
|
||||
/* build the IDT entry */
|
||||
idt.offset_0_15 = ((unsigned32) unique_handler) & 0xffff;
|
||||
idt.segment_selector = i386_get_cs();
|
||||
idt.reserved = 0x00;
|
||||
idt.p_dpl = 0x8e; /* present, ISR */
|
||||
idt.offset_16_31 = ((unsigned32) unique_handler) >> 16;
|
||||
_CPU_ISR_install_raw_handler( vector, (void *)unique_handler, &ignored );
|
||||
|
||||
/* install the IDT entry */
|
||||
i386_Install_idt(
|
||||
(unsigned32) &idt,
|
||||
_CPU_Table.interrupt_table_segment,
|
||||
(unsigned32) _CPU_Table.interrupt_table_offset + (8 * vector)
|
||||
);
|
||||
|
||||
/* "portable" part */
|
||||
*old_handler = _ISR_Vector_table[ vector ];
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
}
|
||||
|
||||
@@ -308,6 +308,19 @@ void _CPU_Initialize(
|
||||
void (*thread_dispatch)
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*
|
||||
* This routine installs a "raw" interrupt handler directly into the
|
||||
* processor's vector table.
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
|
||||
@@ -547,6 +547,11 @@ SYM (_ISR_Dispatch):
|
||||
popa # restore general registers
|
||||
iret # return to interrupted thread
|
||||
|
||||
/*
|
||||
* GO32 does not require these segment related routines.
|
||||
*/
|
||||
|
||||
#ifndef __GO32__
|
||||
/*PAGE
|
||||
*
|
||||
* void i386_Install_idt(
|
||||
@@ -648,6 +653,7 @@ SYM (i386_Physical_to_logical):
|
||||
subl eax,ecx # ecx = logical address equivalent
|
||||
movl ecx,eax # eax = ecx
|
||||
ret
|
||||
#endif /* __GO32__ */
|
||||
|
||||
END_CODE
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ extern "C" {
|
||||
#ifdef i386
|
||||
#undef i386
|
||||
#endif
|
||||
#define i386
|
||||
#define i386 1
|
||||
|
||||
#ifdef REPLACE_THIS_WITH_THE_CPU_MODEL
|
||||
#undef REPLACE_THIS_WITH_THE_CPU_MODEL
|
||||
|
||||
@@ -47,7 +47,41 @@ void _CPU_Initialize(
|
||||
|
||||
}
|
||||
|
||||
/* _CPU__ISR_Install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
#define _Is_vector_caching_enabled( _prcb ) \
|
||||
((_prcb)->control_tbl->icon & 0x2000)
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
i960ca_PRCB *prcb = _CPU_Table.Prcb;
|
||||
proc_ptr *cached_intr_tbl = NULL;
|
||||
|
||||
/* The i80960CA does not support vectors 0-7. The first 9 entries
|
||||
* in the Interrupt Table are used to manage pending interrupts.
|
||||
* Thus vector 8, the first valid vector number, is actually in
|
||||
* slot 9 in the table.
|
||||
*/
|
||||
|
||||
*old_handler = prcb->intr_tbl[ vector + 1 ];
|
||||
|
||||
prcb->intr_tbl[ vector + 1 ] = new_handler;
|
||||
|
||||
if ( _Is_vector_caching_enabled( prcb ) )
|
||||
if ( (vector & 0xf) == 0x2 ) /* cacheable? */
|
||||
cached_intr_tbl[ vector >> 4 ] = new_handler;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU__ISR_install_vector
|
||||
*
|
||||
* Install the RTEMS vector wrapper in the CPU's interrupt table.
|
||||
*
|
||||
@@ -60,32 +94,19 @@ void _CPU_Initialize(
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Is_vector_caching_enabled( _prcb ) \
|
||||
((_prcb)->control_tbl->icon & 0x2000)
|
||||
|
||||
void _CPU_ISR_install_vector(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
i960ca_PRCB *prcb = _CPU_Table.Prcb;
|
||||
proc_ptr *cached_intr_tbl = NULL;
|
||||
|
||||
/* The i80960CA does not support vectors 0-7. The first 9 entries
|
||||
* in the Interrupt Table are used to manage pending interrupts.
|
||||
* Thus vector 8, the first valid vector number, is actually in
|
||||
* slot 9 in the table.
|
||||
*/
|
||||
proc_ptr ignored;
|
||||
|
||||
*old_handler = _ISR_Vector_table[ vector ];
|
||||
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
_CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored );
|
||||
|
||||
prcb->intr_tbl[ vector + 1 ] = _ISR_Handler;
|
||||
if ( _Is_vector_caching_enabled( prcb ) )
|
||||
if ( (vector & 0xf) == 0x2 ) /* cacheable? */
|
||||
cached_intr_tbl[ vector >> 4 ] = _ISR_Handler;
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
|
||||
@@ -357,6 +357,19 @@ void _CPU_Initialize(
|
||||
void (*thread_dispatch)
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*
|
||||
* This routine installs a "raw" interrupt handler directly into the
|
||||
* processor's vector table.
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
|
||||
@@ -40,7 +40,29 @@ void _CPU_Initialize(
|
||||
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
proc_ptr *interrupt_table = NULL;
|
||||
|
||||
m68k_get_vbr( interrupt_table );
|
||||
|
||||
*old_handler = interrupt_table[ vector ];
|
||||
|
||||
interrupt_table[ vector ] = new_handler;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
@@ -51,15 +73,6 @@ void _CPU_Initialize(
|
||||
* old_handler - former ISR for this vector number
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_vector(
|
||||
@@ -68,14 +81,13 @@ void _CPU_ISR_install_vector(
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
proc_ptr *interrupt_table = NULL;
|
||||
|
||||
m68k_get_vbr( interrupt_table );
|
||||
proc_ptr ignored;
|
||||
|
||||
*old_handler = _ISR_Vector_table[ vector ];
|
||||
|
||||
_CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored );
|
||||
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
interrupt_table[ vector ] = _ISR_Handler;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,21 +112,21 @@ void _CPU_Install_interrupt_stack( void )
|
||||
* Returns log2(x) 0<x<256
|
||||
*/
|
||||
const unsigned char __log2table[256] = {
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -328,17 +328,15 @@ EXTERN void *_CPU_Interrupt_stack_high;
|
||||
{ \
|
||||
extern const unsigned char __log2table[256]; \
|
||||
\
|
||||
(_output) = 0; /* avoids warnings */ \
|
||||
asm ( "move.w %1,%0\n"\
|
||||
"\tandi.w #0xff00,%0\n"\
|
||||
"\tjbne 0f\n"\
|
||||
"\tmoveq.l #0,%0\n"\
|
||||
"\tmove.b (%2,%1.w),%0\n"\
|
||||
"\tjbra 1f\n"\
|
||||
"0:\tmoveq.l #8,%0\n"\
|
||||
"\tlsr.w #8,%1\n"\
|
||||
"\tadd.b (%2,%1.w),%0\n"\
|
||||
"1:"\
|
||||
asm ( " tst.b %1\n" /* check for bits in ls byte */ \
|
||||
" beq.s 0f\n" /* branch if no bits set */ \
|
||||
" moveq.l #0,%0\n" /* set up for bits 0..7 */ \
|
||||
" andi.w #0x00ff,%1\n" /* clear ms byte for add inst */ \
|
||||
" bra.s 1f\n" /* go add */ \
|
||||
"0: moveq.l #8,%0\n" /* set up for bits 8..15 */ \
|
||||
" lsr.w #8,%1\n" /* shift ms byte to ls byte, */ \
|
||||
/* filling ms byte with 0s */ \
|
||||
"1: add.b (%2,%1.w),%0\n" /* add offset for bit pattern */ \
|
||||
: "=&d" ((_output)) \
|
||||
: "d" ((_value)), "ao" (__log2table) \
|
||||
: "cc" ) ; \
|
||||
@@ -384,6 +382,19 @@ void _CPU_Initialize(
|
||||
void (*thread_dispatch)
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*
|
||||
* This routine installs a "raw" interrupt handler directly into the
|
||||
* processor's vector table.
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
|
||||
@@ -61,7 +61,26 @@ void _CPU_Initialize(
|
||||
_CPU_Table = *cpu_table;
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
/*
|
||||
* This is where we install the interrupt handler into the "raw" interrupt
|
||||
* table used by the CPU to dispatch interrupt handlers.
|
||||
*/
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
@@ -75,7 +94,6 @@ void _CPU_Initialize(
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
void _CPU_ISR_install_vector(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
@@ -90,6 +108,8 @@ void _CPU_ISR_install_vector(
|
||||
* handler for this vector number.
|
||||
*/
|
||||
|
||||
_CPU_ISR_install_raw_handler( vector, new_handler, old_handler );
|
||||
|
||||
/*
|
||||
* We put the actual user ISR address in '_ISR_vector_table'. This will
|
||||
* be used by the _ISR_Handler so the user gets control.
|
||||
|
||||
@@ -701,6 +701,19 @@ void _CPU_Initialize(
|
||||
void (*thread_dispatch)
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*
|
||||
* This routine installs a "raw" interrupt handler directly into the
|
||||
* processor's vector table.
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
|
||||
@@ -17,20 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/fatal.h>
|
||||
#include <rtems/isr.h>
|
||||
#include <rtems/wkspace.h>
|
||||
/*
|
||||
* In order to get the types and prototypes used in this file under
|
||||
* Solaris 2.3, it is necessary to pull the following magic.
|
||||
*/
|
||||
|
||||
#if defined(solaris)
|
||||
#warning "Ignore the undefining __STDC__ warning"
|
||||
#undef __STDC__
|
||||
#define __STDC__ 0
|
||||
#undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -38,22 +25,17 @@
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
extern void set_vector(proc_ptr, int, int);
|
||||
extern void _Thread_Dispatch(void);
|
||||
#ifndef SA_RESTART
|
||||
#define SA_RESTART 0
|
||||
#endif
|
||||
|
||||
extern unsigned32 _Thread_Dispatch_disable_level;
|
||||
extern unsigned32 _SYSTEM_ID;
|
||||
extern boolean _Context_Switch_necessary;
|
||||
void _CPU_Signal_initialize(void);
|
||||
void _CPU_Stray_signal(int);
|
||||
void _CPU_ISR_Handler(int);
|
||||
|
||||
|
||||
rtems_status_code signal_initialize(void);
|
||||
void Stray_signal(int);
|
||||
void signal_enable(unsigned32);
|
||||
void signal_disable(unsigned32);
|
||||
void interrupt_handler();
|
||||
|
||||
sigset_t UNIX_SIGNAL_MASK;
|
||||
jmp_buf default_context;
|
||||
sigset_t _CPU_Signal_mask;
|
||||
Context_Control _CPU_Context_Default_with_ISRs_enabled;
|
||||
Context_Control _CPU_Context_Default_with_ISRs_disabled;
|
||||
|
||||
/*
|
||||
* Which cpu are we? Used by libcpu and libbsp.
|
||||
@@ -61,6 +43,144 @@ jmp_buf default_context;
|
||||
|
||||
int cpu_number;
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_From_CPU_Init
|
||||
*/
|
||||
|
||||
void _CPU_ISR_From_CPU_Init()
|
||||
{
|
||||
unsigned32 i;
|
||||
proc_ptr old_handler;
|
||||
|
||||
|
||||
/*
|
||||
* Block all the signals except SIGTRAP for the debugger
|
||||
* and SIGABRT for fatal errors.
|
||||
*/
|
||||
|
||||
_CPU_ISR_Enable(1);
|
||||
|
||||
(void) sigfillset(&_CPU_Signal_mask);
|
||||
(void) sigdelset(&_CPU_Signal_mask, SIGTRAP);
|
||||
(void) sigdelset(&_CPU_Signal_mask, SIGABRT);
|
||||
(void) sigdelset(&_CPU_Signal_mask, SIGIOT);
|
||||
(void) sigdelset(&_CPU_Signal_mask, SIGCONT);
|
||||
|
||||
sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);
|
||||
|
||||
/*
|
||||
* Set the handler for all signals to be signal_handler
|
||||
* which will then vector out to the correct handler
|
||||
* for whichever signal actually happened. Initially
|
||||
* set the vectors to the stray signal handler.
|
||||
*/
|
||||
|
||||
for (i = 0; i < CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
|
||||
(void)_CPU_ISR_install_vector(i, _CPU_Stray_signal, &old_handler);
|
||||
|
||||
_CPU_Signal_initialize();
|
||||
}
|
||||
|
||||
void _CPU_Signal_initialize( void )
|
||||
{
|
||||
struct sigaction act;
|
||||
sigset_t mask;
|
||||
|
||||
/* mark them all active except for TraceTrap and Abort */
|
||||
|
||||
sigfillset(&mask);
|
||||
sigdelset(&mask, SIGTRAP);
|
||||
sigdelset(&mask, SIGABRT);
|
||||
sigdelset(&mask, SIGIOT);
|
||||
sigdelset(&mask, SIGCONT);
|
||||
sigprocmask(SIG_UNBLOCK, &mask, 0);
|
||||
|
||||
act.sa_handler = _CPU_ISR_Handler;
|
||||
act.sa_mask = mask;
|
||||
act.sa_flags = SA_RESTART;
|
||||
|
||||
sigaction(SIGHUP, &act, 0);
|
||||
sigaction(SIGINT, &act, 0);
|
||||
sigaction(SIGQUIT, &act, 0);
|
||||
sigaction(SIGILL, &act, 0);
|
||||
sigaction(SIGEMT, &act, 0);
|
||||
sigaction(SIGFPE, &act, 0);
|
||||
sigaction(SIGKILL, &act, 0);
|
||||
sigaction(SIGBUS, &act, 0);
|
||||
sigaction(SIGSEGV, &act, 0);
|
||||
sigaction(SIGSYS, &act, 0);
|
||||
sigaction(SIGPIPE, &act, 0);
|
||||
sigaction(SIGALRM, &act, 0);
|
||||
sigaction(SIGTERM, &act, 0);
|
||||
sigaction(SIGUSR1, &act, 0);
|
||||
sigaction(SIGUSR2, &act, 0);
|
||||
sigaction(SIGCHLD, &act, 0);
|
||||
sigaction(SIGCLD, &act, 0);
|
||||
sigaction(SIGPWR, &act, 0);
|
||||
sigaction(SIGVTALRM, &act, 0);
|
||||
sigaction(SIGPROF, &act, 0);
|
||||
sigaction(SIGIO, &act, 0);
|
||||
sigaction(SIGWINCH, &act, 0);
|
||||
sigaction(SIGSTOP, &act, 0);
|
||||
sigaction(SIGTTIN, &act, 0);
|
||||
sigaction(SIGTTOU, &act, 0);
|
||||
sigaction(SIGURG, &act, 0);
|
||||
/*
|
||||
* XXX: Really should be on HPUX.
|
||||
*/
|
||||
|
||||
#if defined(hppa1_1)
|
||||
sigaction(SIGLOST, &act, 0);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Context_From_CPU_Init
|
||||
*/
|
||||
|
||||
void _CPU_Context_From_CPU_Init()
|
||||
{
|
||||
|
||||
#if defined(hppa1_1) && defined(RTEMS_UNIXLIB)
|
||||
/*
|
||||
* HACK - set the _SYSTEM_ID to 0x20c so that setjmp/longjmp
|
||||
* will handle the full 32 floating point registers.
|
||||
*
|
||||
* NOTE: Is this a bug in HPUX9?
|
||||
*/
|
||||
|
||||
{
|
||||
extern unsigned32 _SYSTEM_ID;
|
||||
|
||||
_SYSTEM_ID = 0x20c;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* get default values to use in _CPU_Context_Initialize()
|
||||
*/
|
||||
|
||||
_CPU_ISR_Set_level( 0 );
|
||||
setjmp( _CPU_Context_Default_with_ISRs_enabled.regs );
|
||||
sigprocmask(
|
||||
SIG_SETMASK, /* ignored when second arg is NULL */
|
||||
0,
|
||||
&_CPU_Context_Default_with_ISRs_enabled.isr_level
|
||||
);
|
||||
|
||||
_CPU_ISR_Set_level( 1 );
|
||||
setjmp( _CPU_Context_Default_with_ISRs_disabled.regs );
|
||||
sigprocmask(
|
||||
SIG_SETMASK, /* ignored when second arg is NULL */
|
||||
0,
|
||||
&_CPU_Context_Default_with_ISRs_disabled.isr_level
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/* _CPU_Initialize
|
||||
*
|
||||
* This routine performs processor dependent initialization.
|
||||
@@ -76,10 +196,8 @@ void _CPU_Initialize(
|
||||
void (*thread_dispatch) /* ignored on this CPU */
|
||||
)
|
||||
{
|
||||
unsigned32 i;
|
||||
|
||||
if ( cpu_table == NULL )
|
||||
rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED );
|
||||
_CPU_Fatal_halt( RTEMS_NOT_CONFIGURED );
|
||||
|
||||
/*
|
||||
* The thread_dispatch argument is the address of the entry point
|
||||
@@ -105,52 +223,29 @@ void _CPU_Initialize(
|
||||
|
||||
_CPU_Table = *cpu_table;
|
||||
|
||||
#if defined(hppa1_1) && defined(RTEMS_UNIXLIB)
|
||||
/*
|
||||
* HACK - set the _SYSTEM_ID to 0x20c so that setjmp/longjmp
|
||||
* will handle the full 32 floating point registers.
|
||||
*
|
||||
* NOTE: Is this a bug in HPUX9?
|
||||
*/
|
||||
_CPU_ISR_From_CPU_Init();
|
||||
|
||||
_SYSTEM_ID = 0x20c;
|
||||
#endif
|
||||
_CPU_Context_From_CPU_Init();
|
||||
|
||||
/*
|
||||
* get default values to use in _CPU_Context_Initialize()
|
||||
*/
|
||||
|
||||
setjmp(default_context);
|
||||
|
||||
/*
|
||||
* Block all the signals except SIGTRAP for the debugger
|
||||
* and SIGABRT for fatal errors.
|
||||
*/
|
||||
|
||||
_CPU_ISR_Set_signal_level(1);
|
||||
|
||||
sigfillset(&UNIX_SIGNAL_MASK);
|
||||
sigdelset(&UNIX_SIGNAL_MASK, SIGTRAP);
|
||||
sigdelset(&UNIX_SIGNAL_MASK, SIGABRT);
|
||||
sigdelset(&UNIX_SIGNAL_MASK, SIGIOT);
|
||||
sigdelset(&UNIX_SIGNAL_MASK, SIGCONT);
|
||||
|
||||
sigprocmask(SIG_BLOCK, &UNIX_SIGNAL_MASK, 0);
|
||||
|
||||
/*
|
||||
* Set the handler for all signals to be signal_handler
|
||||
* which will then vector out to the correct handler
|
||||
* for whichever signal actually happened. Initially
|
||||
* set the vectors to the stray signal handler.
|
||||
*/
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
(void)set_vector(Stray_signal, i, 1);
|
||||
|
||||
signal_initialize();
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
_CPU_Fatal_halt( 0xdeaddead );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
@@ -181,7 +276,7 @@ void _CPU_ISR_install_vector(
|
||||
|
||||
/*
|
||||
* We put the actual user ISR address in '_ISR_vector_table'. This will
|
||||
* be used by the _ISR_Handler so the user gets control.
|
||||
* be used by the _CPU_ISR_Handler so the user gets control.
|
||||
*/
|
||||
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
@@ -219,6 +314,11 @@ void _CPU_Internal_threads_Idle_thread_body( void )
|
||||
pause();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Context_Initialize
|
||||
*/
|
||||
|
||||
void _CPU_Context_Initialize(
|
||||
Context_Control *_the_context,
|
||||
unsigned32 *_stack_base,
|
||||
@@ -227,6 +327,7 @@ void _CPU_Context_Initialize(
|
||||
void *_entry_point
|
||||
)
|
||||
{
|
||||
void *source;
|
||||
unsigned32 *addr;
|
||||
unsigned32 jmp_addr;
|
||||
unsigned32 _stack_low; /* lowest "stack aligned" address */
|
||||
@@ -253,7 +354,12 @@ void _CPU_Context_Initialize(
|
||||
* Slam our jmp_buf template into the context we are creating
|
||||
*/
|
||||
|
||||
memcpy(_the_context, default_context, sizeof(jmp_buf));
|
||||
if ( _new_level == 0 )
|
||||
source = _CPU_Context_Default_with_ISRs_enabled.regs;
|
||||
else
|
||||
source = _CPU_Context_Default_with_ISRs_disabled.regs;
|
||||
|
||||
memcpy(_the_context, source, sizeof(jmp_buf));
|
||||
|
||||
addr = (unsigned32 *)_the_context;
|
||||
|
||||
@@ -289,68 +395,77 @@ void _CPU_Context_Initialize(
|
||||
#error "UNKNOWN CPU!!!"
|
||||
#endif
|
||||
|
||||
if (_new_level)
|
||||
_CPU_ISR_Set_signal_level(1);
|
||||
else
|
||||
_CPU_ISR_Set_signal_level(0);
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Context_restore
|
||||
*/
|
||||
|
||||
void _CPU_Context_restore(
|
||||
Context_Control *next
|
||||
)
|
||||
{
|
||||
longjmp(next->regs, 0);
|
||||
sigprocmask( SIG_SETMASK, &next->isr_level, 0 );
|
||||
longjmp( next->regs, 0 );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Context_switch
|
||||
*/
|
||||
|
||||
void _CPU_Context_switch(
|
||||
Context_Control *current,
|
||||
Context_Control *next
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Save the current context
|
||||
* Switch levels in one operation
|
||||
*/
|
||||
|
||||
if (setjmp(current->regs) == 0) {
|
||||
sigprocmask( SIG_SETMASK, &next->isr_level, ¤t->isr_level );
|
||||
|
||||
/*
|
||||
* Switch to the new context
|
||||
*/
|
||||
|
||||
longjmp(next->regs, 0);
|
||||
if (setjmp(current->regs) == 0) { /* Save the current context */
|
||||
longjmp(next->regs, 0); /* Switch to the new context */
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Save_float_context
|
||||
*/
|
||||
|
||||
void _CPU_Save_float_context(
|
||||
Context_Control_fp *fp_context
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Restore_float_context
|
||||
*/
|
||||
|
||||
void _CPU_Restore_float_context(
|
||||
Context_Control_fp *fp_context
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
void _CPU_ISR_Set_signal_level(unsigned32 level)
|
||||
{
|
||||
if (level)
|
||||
_CPU_Disable_signal();
|
||||
else
|
||||
_CPU_Enable_signal(0);
|
||||
}
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_Disable_support
|
||||
*/
|
||||
|
||||
|
||||
unsigned32 _CPU_Disable_signal(void)
|
||||
unsigned32 _CPU_ISR_Disable_support(void)
|
||||
{
|
||||
sigset_t old_mask;
|
||||
sigset_t empty_mask;
|
||||
|
||||
sigemptyset(&empty_mask);
|
||||
sigemptyset(&old_mask);
|
||||
sigprocmask(SIG_BLOCK, &UNIX_SIGNAL_MASK, &old_mask);
|
||||
sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, &old_mask);
|
||||
|
||||
if (memcmp((char *)&empty_mask, (char *)&old_mask, sizeof(sigset_t)) != 0)
|
||||
return 1;
|
||||
@@ -358,101 +473,37 @@ unsigned32 _CPU_Disable_signal(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_Enable
|
||||
*/
|
||||
|
||||
void _CPU_Enable_signal(unsigned32 level)
|
||||
void _CPU_ISR_Enable(
|
||||
unsigned32 level
|
||||
)
|
||||
{
|
||||
if (level == 0)
|
||||
sigprocmask(SIG_UNBLOCK, &UNIX_SIGNAL_MASK, 0);
|
||||
sigprocmask(SIG_UNBLOCK, &_CPU_Signal_mask, 0);
|
||||
else
|
||||
sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Support for external and spurious interrupts on HPPA
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_Handler
|
||||
*
|
||||
* TODO:
|
||||
* delete interrupt.c etc.
|
||||
* Count interrupts
|
||||
* make sure interrupts disabled properly
|
||||
* should handler check again for more interrupts before exit?
|
||||
* How to enable interrupts from an interrupt handler?
|
||||
* Make sure there is an entry for everything in ISR_Vector_Table
|
||||
*/
|
||||
|
||||
/*
|
||||
* Init the external interrupt scheme
|
||||
* called by bsp_start()
|
||||
*/
|
||||
|
||||
rtems_status_code
|
||||
signal_initialize(void)
|
||||
{
|
||||
struct sigaction act;
|
||||
sigset_t mask;
|
||||
|
||||
/* mark them all active except for TraceTrap and Abort */
|
||||
|
||||
sigfillset(&mask);
|
||||
sigdelset(&mask, SIGTRAP);
|
||||
sigdelset(&mask, SIGABRT);
|
||||
sigdelset(&mask, SIGIOT);
|
||||
sigdelset(&mask, SIGCONT);
|
||||
sigprocmask(SIG_UNBLOCK, &mask, 0);
|
||||
|
||||
act.sa_handler = interrupt_handler;
|
||||
act.sa_mask = mask;
|
||||
#if defined(solaris)
|
||||
act.sa_flags = SA_RESTART;
|
||||
#else
|
||||
act.sa_flags = 0;
|
||||
#endif
|
||||
|
||||
sigaction(SIGHUP, &act, 0);
|
||||
sigaction(SIGINT, &act, 0);
|
||||
sigaction(SIGQUIT, &act, 0);
|
||||
sigaction(SIGILL, &act, 0);
|
||||
sigaction(SIGEMT, &act, 0);
|
||||
sigaction(SIGFPE, &act, 0);
|
||||
sigaction(SIGKILL, &act, 0);
|
||||
sigaction(SIGBUS, &act, 0);
|
||||
sigaction(SIGSEGV, &act, 0);
|
||||
sigaction(SIGSYS, &act, 0);
|
||||
sigaction(SIGPIPE, &act, 0);
|
||||
sigaction(SIGALRM, &act, 0);
|
||||
sigaction(SIGTERM, &act, 0);
|
||||
sigaction(SIGUSR1, &act, 0);
|
||||
sigaction(SIGUSR2, &act, 0);
|
||||
sigaction(SIGCHLD, &act, 0);
|
||||
sigaction(SIGCLD, &act, 0);
|
||||
sigaction(SIGPWR, &act, 0);
|
||||
sigaction(SIGVTALRM, &act, 0);
|
||||
sigaction(SIGPROF, &act, 0);
|
||||
sigaction(SIGIO, &act, 0);
|
||||
sigaction(SIGWINCH, &act, 0);
|
||||
sigaction(SIGSTOP, &act, 0);
|
||||
sigaction(SIGTTIN, &act, 0);
|
||||
sigaction(SIGTTOU, &act, 0);
|
||||
sigaction(SIGURG, &act, 0);
|
||||
/*
|
||||
* XXX: Really should be on HPUX.
|
||||
*/
|
||||
|
||||
#if defined(hppa1_1)
|
||||
sigaction(SIGLOST, &act, 0);
|
||||
#endif
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* External interrupt handler.
|
||||
* This is installed as cpu interrupt handler.
|
||||
* It vectors out to specific external interrupt handlers.
|
||||
* This is installed as a UNIX signal handler.
|
||||
* It vectors out to specific user interrupt handlers.
|
||||
*/
|
||||
|
||||
void
|
||||
interrupt_handler(int vector)
|
||||
void _CPU_ISR_Handler(int vector)
|
||||
{
|
||||
extern void _Thread_Dispatch(void);
|
||||
extern unsigned32 _Thread_Dispatch_disable_level;
|
||||
extern boolean _Context_Switch_necessary;
|
||||
|
||||
|
||||
if (_ISR_Nest_level++ == 0) {
|
||||
/* switch to interrupt stack */
|
||||
}
|
||||
@@ -461,9 +512,8 @@ interrupt_handler(int vector)
|
||||
|
||||
if (_ISR_Vector_table[vector]) {
|
||||
_ISR_Vector_table[vector](vector);
|
||||
}
|
||||
else {
|
||||
Stray_signal(vector);
|
||||
} else {
|
||||
_CPU_Stray_signal(vector);
|
||||
}
|
||||
|
||||
if (_ISR_Nest_level-- == 0) {
|
||||
@@ -474,14 +524,17 @@ interrupt_handler(int vector)
|
||||
|
||||
if (_Thread_Dispatch_disable_level == 0 &&
|
||||
(_Context_Switch_necessary || _ISR_Signals_to_thread_executing)) {
|
||||
_CPU_Enable_signal(0);
|
||||
_CPU_ISR_Enable(0);
|
||||
_Thread_Dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Stray_signal
|
||||
*/
|
||||
|
||||
void
|
||||
Stray_signal(int sig_num)
|
||||
void _CPU_Stray_signal(int sig_num)
|
||||
{
|
||||
char buffer[ 80 ];
|
||||
|
||||
@@ -499,11 +552,10 @@ Stray_signal(int sig_num)
|
||||
/*
|
||||
* If it was a "fatal" signal, then exit here
|
||||
* If app code has installed a hander for one of these, then
|
||||
* we won't call Stray_signal, so this is ok.
|
||||
* we won't call _CPU_Stray_signal, so this is ok.
|
||||
*/
|
||||
|
||||
switch (sig_num)
|
||||
{
|
||||
switch (sig_num) {
|
||||
case SIGINT:
|
||||
case SIGHUP:
|
||||
case SIGQUIT:
|
||||
@@ -517,22 +569,30 @@ Stray_signal(int sig_num)
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Fatal_error
|
||||
*/
|
||||
|
||||
void
|
||||
_CPU_Fatal_error(unsigned32 error)
|
||||
void _CPU_Fatal_error(unsigned32 error)
|
||||
{
|
||||
setitimer(ITIMER_REAL, 0, 0);
|
||||
|
||||
_exit(error);
|
||||
}
|
||||
|
||||
int
|
||||
_CPU_ffs(unsigned32 value)
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ffs
|
||||
*/
|
||||
|
||||
int _CPU_ffs(unsigned32 value)
|
||||
{
|
||||
int output;
|
||||
extern int ffs( int );
|
||||
|
||||
output = ffs(value);
|
||||
output = output - 1;
|
||||
|
||||
return(output);
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -26,12 +26,37 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <rtems/unix.h>
|
||||
#ifndef ASM
|
||||
#include <rtems/unixtypes.h>
|
||||
#endif
|
||||
|
||||
#if defined(solaris2)
|
||||
#undef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 3
|
||||
#undef __STRICT_ANSI__
|
||||
#define __STRICT_ANSI__
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* In order to get the types and prototypes used in this file under
|
||||
* Solaris 2.3, it is necessary to pull the following magic.
|
||||
*/
|
||||
|
||||
#if defined(solaris2)
|
||||
#warning "Ignore the undefining __STDC__ warning"
|
||||
#undef __STDC__
|
||||
#define __STDC__ 0
|
||||
#undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* conditional compilation parameters */
|
||||
|
||||
/*
|
||||
@@ -398,6 +423,8 @@ extern "C" {
|
||||
|
||||
typedef struct {
|
||||
jmp_buf regs;
|
||||
sigset_t isr_level;
|
||||
int junk;
|
||||
} Context_Control;
|
||||
|
||||
typedef struct {
|
||||
@@ -567,9 +594,11 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
|
||||
* level is returned in _level.
|
||||
*/
|
||||
|
||||
extern unsigned32 _CPU_ISR_Disable_support(void);
|
||||
|
||||
#define _CPU_ISR_Disable( _level ) \
|
||||
do { \
|
||||
(_level) = _CPU_Disable_signal(); \
|
||||
(_level) = _CPU_ISR_Disable_support(); \
|
||||
} while ( 0 )
|
||||
|
||||
/*
|
||||
@@ -578,10 +607,7 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
|
||||
* _level is not modified.
|
||||
*/
|
||||
|
||||
#define _CPU_ISR_Enable( _level ) \
|
||||
do { \
|
||||
_CPU_Enable_signal( (_level) ); \
|
||||
} while ( 0 )
|
||||
void _CPU_ISR_Enable(unsigned32 level);
|
||||
|
||||
/*
|
||||
* This temporarily restores the interrupt to _level before immediately
|
||||
@@ -610,10 +636,8 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
|
||||
|
||||
#define _CPU_ISR_Set_level( new_level ) \
|
||||
{ \
|
||||
if ( new_level ) \
|
||||
(void) _CPU_Disable_signal(); \
|
||||
else \
|
||||
_CPU_Enable_signal( 0 ); \
|
||||
if ( new_level == 0 ) _CPU_ISR_Enable( 0 ); \
|
||||
else _CPU_ISR_Enable( 1 ); \
|
||||
}
|
||||
|
||||
/* end of ISR handler macros */
|
||||
@@ -792,6 +816,19 @@ void _CPU_Initialize(
|
||||
void (*thread_dispatch)
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*
|
||||
* This routine installs a "raw" interrupt handler directly into the
|
||||
* processor's vector table.
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
);
|
||||
|
||||
/*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
@@ -875,12 +912,6 @@ void _CPU_ISR_Set_signal_level(
|
||||
unsigned32 level
|
||||
);
|
||||
|
||||
unsigned32 _CPU_Disable_signal( void );
|
||||
|
||||
void _CPU_Enable_signal(
|
||||
unsigned32 level
|
||||
);
|
||||
|
||||
void _CPU_Fatal_error(
|
||||
unsigned32 _error
|
||||
);
|
||||
|
||||
135
c/src/lib/libbsp/i386/go32/clock/ckinit.c
Normal file
135
c/src/lib/libbsp/i386/go32/clock/ckinit.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/* Clock_initialize
|
||||
*
|
||||
* This routine initializes the 8254 timer under GO32.
|
||||
* The tick frequency is 1 millisecond.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <clockdrv.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
volatile rtems_unsigned32 Clock_driver_ticks;
|
||||
rtems_unsigned32 Clock_isrs_per_tick; /* ISRs per tick */
|
||||
rtems_unsigned32 Clock_isrs; /* ISRs until next tick */
|
||||
rtems_isr_entry Old_ticker;
|
||||
|
||||
rtems_device_driver Clock_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp,
|
||||
rtems_id tid,
|
||||
rtems_unsigned32 *rval
|
||||
)
|
||||
{
|
||||
Install_clock( Clock_isr );
|
||||
}
|
||||
|
||||
void ReInstall_clock(
|
||||
rtems_isr_entry clock_isr
|
||||
)
|
||||
{
|
||||
rtems_unsigned32 isrlevel = 0;
|
||||
|
||||
rtems_interrupt_disable( isrlevel );
|
||||
(void) set_vector( clock_isr, 0x8, 1 );
|
||||
rtems_interrupt_enable( isrlevel );
|
||||
}
|
||||
|
||||
void Install_clock(
|
||||
rtems_isr_entry clock_isr
|
||||
)
|
||||
{
|
||||
unsigned int microseconds_per_isr;
|
||||
|
||||
#if 0
|
||||
/* Initialize clock from on-board real time clock. This breaks the */
|
||||
/* test code which assumes which assumes the application will do it. */
|
||||
{
|
||||
rtems_time_of_day Now;
|
||||
extern void init_rtc( void );
|
||||
extern long rtc_read( rtems_time_of_day * tod );
|
||||
init_rtc();
|
||||
if ( rtc_read( &Now ) >= 0 )
|
||||
clock_set( &Now );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start by assuming hardware counter is large enough, then */
|
||||
/* scale it until it actually fits. */
|
||||
Clock_driver_ticks = 0;
|
||||
Clock_isrs_per_tick = 1;
|
||||
|
||||
if ( BSP_Configuration.microseconds_per_tick == 0 )
|
||||
microseconds_per_isr = 10000; /* default 10 ms */
|
||||
else
|
||||
microseconds_per_isr = BSP_Configuration.microseconds_per_tick;
|
||||
while ( US_TO_TICK(microseconds_per_isr) > 65535 ) {
|
||||
Clock_isrs_per_tick *= 10;
|
||||
microseconds_per_isr /= 10;
|
||||
}
|
||||
|
||||
/* Initialize count in ckisr.c */
|
||||
Clock_isrs = Clock_isrs_per_tick;
|
||||
|
||||
#if 0
|
||||
/* This was dropped in the last revision. Its a nice thing to know. */
|
||||
TICKS_PER_SECOND = 1000000 / (Clock_isrs_per_tick * microseconds_per_isr);
|
||||
#endif
|
||||
|
||||
if ( BSP_Configuration.ticks_per_timeslice ) {
|
||||
/* 105/88 approximates TIMER_TICK*1e-6 */
|
||||
unsigned int count = US_TO_TICK( microseconds_per_isr );
|
||||
|
||||
Old_ticker = (rtems_isr_entry) set_vector( clock_isr, 0x8, 1 );
|
||||
outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
|
||||
outport_byte( TIMER_CNTR0, count >> 0 & 0xff );
|
||||
outport_byte( TIMER_CNTR0, count >> 8 & 0xff );
|
||||
}
|
||||
atexit( Clock_exit );
|
||||
}
|
||||
|
||||
void Clock_exit( void )
|
||||
{
|
||||
if ( BSP_Configuration.ticks_per_timeslice ) {
|
||||
extern void rtc_set_dos_date( void );
|
||||
|
||||
/* reset to DOS value: */
|
||||
outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
|
||||
outport_byte( TIMER_CNTR0, 0 );
|
||||
outport_byte( TIMER_CNTR0, 0 );
|
||||
|
||||
/* reset time-of-day */
|
||||
rtc_set_dos_date();
|
||||
|
||||
/* re-enable old handler: assume it was one of ours */
|
||||
set_vector( (rtems_isr_entry)Old_ticker, 0x8, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0 && defined(pentium)
|
||||
/* This can be used to get extremely accurate timing on a pentium. */
|
||||
/* It isn't supported. [bryce] */
|
||||
#define HZ 90.0
|
||||
volatile long long Last_RDTSC;
|
||||
#define RDTSC()\
|
||||
({ long long _now; __asm __volatile (".byte 0x0F,0x31":"=A"(_now)); _now; })
|
||||
long long Kernel_Time_ns( void )
|
||||
{
|
||||
extern rtems_unsigned32 _TOD_Ticks_per_second;
|
||||
unsigned isrs_per_second = Clock_isrs_per_tick * _TOD_Ticks_per_second;
|
||||
long long now;
|
||||
int flags;
|
||||
disable_intr( flags );
|
||||
now = 1e9 * Clock_driver_ticks / isrs_per_second
|
||||
+ (RDTSC() - Last_RDTSC) * (1000.0/HZ);
|
||||
enable_intr( flags );
|
||||
return now;
|
||||
}
|
||||
#endif
|
||||
213
c/src/lib/libbsp/i386/go32/clock/rtc.c
Normal file
213
c/src/lib/libbsp/i386/go32/clock/rtc.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define IO_RTC 0x70 /* RTC */
|
||||
|
||||
#define RTC_SEC 0x00 /* seconds */
|
||||
#define RTC_SECALRM 0x01 /* seconds alarm */
|
||||
#define RTC_MIN 0x02 /* minutes */
|
||||
#define RTC_MINALRM 0x03 /* minutes alarm */
|
||||
#define RTC_HRS 0x04 /* hours */
|
||||
#define RTC_HRSALRM 0x05 /* hours alarm */
|
||||
#define RTC_WDAY 0x06 /* week day */
|
||||
#define RTC_DAY 0x07 /* day of month */
|
||||
#define RTC_MONTH 0x08 /* month of year */
|
||||
#define RTC_YEAR 0x09 /* month of year */
|
||||
#define RTC_STATUSA 0x0a /* status register A */
|
||||
#define RTCSA_TUP 0x80 /* time update, don't look now */
|
||||
|
||||
#define RTC_STATUSB 0x0b /* status register B */
|
||||
|
||||
#define RTC_INTR 0x0c /* status register C (R) interrupt source */
|
||||
#define RTCIR_UPDATE 0x10 /* update intr */
|
||||
#define RTCIR_ALARM 0x20 /* alarm intr */
|
||||
#define RTCIR_PERIOD 0x40 /* periodic intr */
|
||||
#define RTCIR_INT 0x80 /* interrupt output signal */
|
||||
|
||||
#define RTC_STATUSD 0x0d /* status register D (R) Lost Power */
|
||||
#define RTCSD_PWR 0x80 /* clock lost power */
|
||||
|
||||
#define RTC_DIAG 0x0e /* status register E - bios diagnostic */
|
||||
#define RTCDG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time"
|
||||
|
||||
#define RTC_CENTURY 0x32 /* current century - increment in Dec99 */
|
||||
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include <cpu.h>
|
||||
#include <memory.h>
|
||||
|
||||
void init_rtc( void )
|
||||
{
|
||||
int s;
|
||||
|
||||
/* initialize brain-dead battery powered clock */
|
||||
outport_byte( IO_RTC, RTC_STATUSA );
|
||||
outport_byte( IO_RTC+1, 0x26 );
|
||||
outport_byte( IO_RTC, RTC_STATUSB );
|
||||
outport_byte( IO_RTC+1, 2 );
|
||||
|
||||
outport_byte( IO_RTC, RTC_DIAG );
|
||||
inport_byte( IO_RTC+1, s );
|
||||
#if 0
|
||||
if (s) printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* convert 2 digit BCD number */
|
||||
static int bcd( unsigned int i )
|
||||
{
|
||||
return ((i/16)*10 + (i%16));
|
||||
}
|
||||
|
||||
/* convert years to seconds (from 1970) */
|
||||
static unsigned long ytos( int y )
|
||||
{
|
||||
int i;
|
||||
unsigned long ret;
|
||||
|
||||
ret = 0;
|
||||
for(i = 1970; i < y; i++) {
|
||||
if (i % 4) ret += 365*24*60*60;
|
||||
else ret += 366*24*60*60;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* convert months to seconds */
|
||||
static unsigned long mtos( int m, int leap )
|
||||
{
|
||||
int i;
|
||||
unsigned long ret;
|
||||
|
||||
ret = 0;
|
||||
for(i=1;i<m;i++) {
|
||||
switch(i){
|
||||
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
|
||||
ret += 31*24*60*60;
|
||||
break;
|
||||
case 4: case 6: case 9: case 11:
|
||||
ret += 30*24*60*60;
|
||||
break;
|
||||
case 2:
|
||||
if (leap)
|
||||
ret += 29*24*60*60;
|
||||
else
|
||||
ret += 28*24*60*60;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned int rtcin( unsigned int what )
|
||||
{
|
||||
unsigned int r;
|
||||
outport_byte( IO_RTC, what );
|
||||
inport_byte( IO_RTC+1, r );
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the time of day register, based on the time base which is, e.g.
|
||||
* from a filesystem.
|
||||
*/
|
||||
long rtc_read( rtems_time_of_day * tod )
|
||||
{
|
||||
int sa;
|
||||
unsigned long sec = 0;
|
||||
|
||||
memset( tod, 0, sizeof *tod );
|
||||
|
||||
/* do we have a realtime clock present? (otherwise we loop below) */
|
||||
sa = rtcin(RTC_STATUSA);
|
||||
if (sa == 0xff || sa == 0)
|
||||
return -1;
|
||||
|
||||
/* ready for a read? */
|
||||
while ((sa&RTCSA_TUP) == RTCSA_TUP)
|
||||
sa = rtcin(RTC_STATUSA);
|
||||
|
||||
tod->year = bcd(rtcin(RTC_YEAR)) + 1900; /* year */
|
||||
if (tod->year < 1970) tod->year += 100;
|
||||
tod->month = bcd(rtcin(RTC_MONTH)); /* month */
|
||||
tod->day = bcd(rtcin(RTC_DAY)); /* day */
|
||||
(void) bcd(rtcin(RTC_WDAY)); /* weekday */
|
||||
tod->hour = bcd(rtcin(RTC_HRS)); /* hour */
|
||||
tod->minute = bcd(rtcin(RTC_MIN)); /* minutes */
|
||||
tod->second = bcd(rtcin(RTC_SEC)); /* seconds */
|
||||
tod->ticks = 0;
|
||||
#if 0
|
||||
sec = ytos( tod->year );
|
||||
sec += mtos( tod->month, tod->year % 4 == 0 );
|
||||
sec += tod->day * 24*60*60;
|
||||
sec += tod->hour * 60*60; /* hour */
|
||||
sec += tod->minute * 60; /* minutes */
|
||||
sec += tod->second; /* seconds */
|
||||
#else
|
||||
sec = 0;
|
||||
#endif
|
||||
return sec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* from djgpp: include before rtems.h to avoid conflicts */
|
||||
#undef delay
|
||||
#include <dos.h>
|
||||
|
||||
void rtc_set_dos_date( void )
|
||||
{
|
||||
int s;
|
||||
struct date date;
|
||||
struct time time;
|
||||
|
||||
/* initialize brain-dead battery powered clock */
|
||||
outport_byte( IO_RTC, RTC_STATUSA );
|
||||
outport_byte( IO_RTC+1, 0x26 );
|
||||
outport_byte( IO_RTC, RTC_STATUSB );
|
||||
outport_byte( IO_RTC+1, 2 );
|
||||
|
||||
outport_byte( IO_RTC, RTC_DIAG );
|
||||
inport_byte( IO_RTC+1, s );
|
||||
if (s) {
|
||||
#if 0
|
||||
printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* check for presence of clock */
|
||||
s = rtcin(RTC_STATUSA);
|
||||
if ( s == 0xff || s == 0 ) {
|
||||
#if 0
|
||||
printf( "Real-time clock not found\n" );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* ready for a read? */
|
||||
while ((s & RTCSA_TUP) == RTCSA_TUP)
|
||||
s = rtcin(RTC_STATUSA);
|
||||
|
||||
date.da_year = bcd(rtcin(RTC_YEAR)) + 1900; /* year */
|
||||
if ( date.da_year < 1970) date.da_year += 100;
|
||||
date.da_year -= 1980;
|
||||
date.da_mon = bcd(rtcin(RTC_MONTH)); /* month */
|
||||
date.da_day = bcd(rtcin(RTC_DAY)); /* day */
|
||||
|
||||
(void)bcd(rtcin(RTC_WDAY)); /* weekday */
|
||||
|
||||
time.ti_hour = bcd(rtcin(RTC_HRS)); /* hour */
|
||||
time.ti_min = bcd(rtcin(RTC_MIN)); /* minutes */
|
||||
time.ti_sec = bcd(rtcin(RTC_SEC)); /* seconds */
|
||||
time.ti_hund = 0;
|
||||
|
||||
setdate( & date );
|
||||
settime( & time );
|
||||
}
|
||||
186
c/src/lib/libbsp/i386/go32/console/console.c
Normal file
186
c/src/lib/libbsp/i386/go32/console/console.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* This file contains the go32 console IO package.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define IBMPC_INIT
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include "console.h"
|
||||
#include "bsp.h"
|
||||
|
||||
#include <dpmi.h>
|
||||
#include <go32.h>
|
||||
|
||||
/* console_cleanup
|
||||
*
|
||||
* This routine is called at exit to clean up the console hardware.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
*/
|
||||
|
||||
void console_cleanup( void )
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
/* console_initialize
|
||||
*
|
||||
* This routine initializes the console IO driver.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
*/
|
||||
|
||||
/* Set this if console I/O should use go32 (DOS) read/write calls. */
|
||||
/* Otherwise, direct hardware accesses will be used. */
|
||||
int _IBMPC_Use_Go32_IO = 0;
|
||||
|
||||
static rtems_isr_entry old_keyboard_isr = NULL;
|
||||
extern void _IBMPC_keyboard_isr( rtems_unsigned32 interrupt );
|
||||
|
||||
|
||||
rtems_device_driver console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg,
|
||||
rtems_id self,
|
||||
rtems_unsigned32 *status
|
||||
)
|
||||
{
|
||||
if ( _IBMPC_Use_Go32_IO ) {
|
||||
/* Nothing. We let DOS and go32 do all the work. */
|
||||
} else {
|
||||
/* Grap the keyboard interrupt so DOS doesn't steal our */
|
||||
/* keystrokes. */
|
||||
rtems_status_code status;
|
||||
status = rtems_interrupt_catch( _IBMPC_keyboard_isr, 9,
|
||||
&old_keyboard_isr );
|
||||
if ( status ) {
|
||||
int write( int, void *, int );
|
||||
void exit( int );
|
||||
char msg[] = "error initializing keyboard\n";
|
||||
write( 2, msg, sizeof msg - 1 );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
atexit( console_cleanup );
|
||||
}
|
||||
|
||||
|
||||
/* is_character_ready
|
||||
*
|
||||
* This routine returns TRUE if a character is available.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
*/
|
||||
|
||||
rtems_boolean is_character_ready(
|
||||
char *ch
|
||||
)
|
||||
{
|
||||
return _IBMPC_chrdy( ch ) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/* inbyte
|
||||
*
|
||||
* This routine reads a character from the UART.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
* character read from UART
|
||||
*/
|
||||
|
||||
char inbyte( void )
|
||||
{
|
||||
char ch = _IBMPC_inch();
|
||||
#if 1
|
||||
/* Echo character to screen */
|
||||
void outbyte( char ch );
|
||||
outbyte( ch );
|
||||
if ( ch == '\r' )
|
||||
outbyte( '\n' );
|
||||
#endif
|
||||
return ch;
|
||||
}
|
||||
|
||||
/* outbyte
|
||||
*
|
||||
* This routine transmits a character out the port.
|
||||
*
|
||||
* Input parameters:
|
||||
* ch - character to be transmitted
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
void outbyte( char ch )
|
||||
{
|
||||
_IBMPC_outch( ch );
|
||||
}
|
||||
|
||||
/*
|
||||
* __read -- read bytes from the console. Ignore fd, since
|
||||
* we only have stdin.
|
||||
*/
|
||||
|
||||
int __read(
|
||||
int fd,
|
||||
char *buf,
|
||||
int nbytes
|
||||
)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for ( i = 0; i < nbytes; i++ ) {
|
||||
buf[i] = inbyte();
|
||||
if ( buf[i] == '\r' ) {
|
||||
/* What if this goes past the end of the buffer? We're hosed. [bhc] */
|
||||
buf[i++] = '\n';
|
||||
buf[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* __write -- write bytes to the console. Ignore fd, since
|
||||
* stdout and stderr are the same. Since we have no filesystem,
|
||||
* open will only return an error.
|
||||
*/
|
||||
|
||||
int __write(
|
||||
int fd,
|
||||
char *buf,
|
||||
int nbytes
|
||||
)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
if (*(buf + i) == '\n') {
|
||||
outbyte ('\r');
|
||||
}
|
||||
outbyte (*(buf + i));
|
||||
}
|
||||
return (nbytes);
|
||||
}
|
||||
163
c/src/lib/libbsp/i386/go32/console/inch.c
Normal file
163
c/src/lib/libbsp/i386/go32/console/inch.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <pc.h>
|
||||
#include <go32.h>
|
||||
#include <bsp.h>
|
||||
#include <cpu.h>
|
||||
|
||||
/*
|
||||
* Ports for PC keyboard
|
||||
*/
|
||||
#define KBD_CTL 0x61
|
||||
#define KBD_DATA 0x60
|
||||
#define KBD_STATUS 0x64
|
||||
|
||||
static char key_map[] = {
|
||||
0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
|
||||
'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
|
||||
'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
|
||||
0134,'z','x','c','v','b','n','m',',','.','/',0x80,
|
||||
'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,'0',0177
|
||||
};
|
||||
|
||||
static char shift_map[] = {
|
||||
0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
|
||||
'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
|
||||
'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
|
||||
'|','Z','X','C','V','B','N','M','<','>','?',0x80,
|
||||
'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
|
||||
'1','2','3','0',177
|
||||
};
|
||||
|
||||
extern int _IBMPC_Use_Go32_IO;
|
||||
|
||||
#define KBD_BUF_SIZE 256
|
||||
static char kbd_buffer[ KBD_BUF_SIZE ];
|
||||
static unsigned int kbd_first = 0;
|
||||
static unsigned int kbd_last = 0;
|
||||
|
||||
/* This function can be called during a poll for input, or by an ISR. */
|
||||
/* Basically any time you want to process a keypress. */
|
||||
int _IBMPC_scankey( char * ch )
|
||||
{
|
||||
unsigned char c;
|
||||
unsigned char outch;
|
||||
static int shift_pressed = 0;
|
||||
static int ctrl_pressed = 0;
|
||||
static int caps_pressed = 0;
|
||||
|
||||
/* Read keyboard controller, toggle enable */
|
||||
inport_byte( KBD_CTL, c );
|
||||
outport_byte( KBD_CTL, c & ~0x80 );
|
||||
outport_byte( KBD_CTL, c | 0x80 );
|
||||
outport_byte( KBD_CTL, c & ~0x80 );
|
||||
|
||||
/* See if it has data */
|
||||
inport_byte( KBD_STATUS, c );
|
||||
if ( ( c & 0x01 ) == 0 )
|
||||
return 0;
|
||||
|
||||
/* Read the data. Handle nonsense with shift, control, etc. */
|
||||
inport_byte( KBD_DATA, c );
|
||||
switch ( c ) {
|
||||
case 0x36:
|
||||
case 0x2a:
|
||||
shift_pressed = 1;
|
||||
return 0;
|
||||
case 0x3a:
|
||||
caps_pressed = 1;
|
||||
return 0;
|
||||
case 0x1d:
|
||||
ctrl_pressed = 1;
|
||||
return 0;
|
||||
case 0xb6:
|
||||
case 0xaa:
|
||||
shift_pressed = 0;
|
||||
return 0;
|
||||
case 0xba:
|
||||
caps_pressed = 0;
|
||||
return 0;
|
||||
case 0x9d:
|
||||
ctrl_pressed = 0;
|
||||
return 0;
|
||||
/*
|
||||
* Ignore unrecognized keys--usually arrow and such
|
||||
*/
|
||||
default:
|
||||
if ( c & 0x80 )
|
||||
/* High-bit on means key is being released, not pressed */
|
||||
return 0;
|
||||
if ( c == 88 )
|
||||
/* F12 - abort */
|
||||
exit( 1 );
|
||||
if ( c > 0x39 ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Strip high bit, look up in our map */
|
||||
c &= 127;
|
||||
if ( ctrl_pressed ) {
|
||||
outch = key_map[c];
|
||||
outch &= 037;
|
||||
} else {
|
||||
outch = shift_pressed ? shift_map[c] : key_map[c];
|
||||
if ( caps_pressed ) {
|
||||
if ( outch >= 'A' && outch <= 'Z' ) outch += 'a' - 'A';
|
||||
else if ( outch >= 'a' && outch <= 'z' ) outch -= 'a' - 'A';
|
||||
}
|
||||
}
|
||||
|
||||
*ch = outch;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void _IBMPC_keyboard_isr( rtems_unsigned32 interrupt )
|
||||
{
|
||||
if ( _IBMPC_scankey( & kbd_buffer[ kbd_last ] ) ) {
|
||||
/* Got one; save it if there is enough room in buffer. */
|
||||
unsigned int next = (kbd_last + 1) % KBD_BUF_SIZE;
|
||||
if ( next != kbd_first )
|
||||
kbd_last = next;
|
||||
}
|
||||
|
||||
/* Mark interrupt as handled */
|
||||
outport_byte( 0x20, 0x20 );
|
||||
}
|
||||
|
||||
|
||||
int _IBMPC_chrdy( char * ch )
|
||||
{
|
||||
if ( _IBMPC_Use_Go32_IO ) {
|
||||
/* Read keyboard via BIOS: raw mode. */
|
||||
if ( kbhit() ) {
|
||||
*ch = getkey();
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* Check buffer our ISR builds */
|
||||
if ( kbd_first != kbd_last ) {
|
||||
*ch = kbd_buffer[ kbd_first ];
|
||||
kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int _IBMPC_inch( void )
|
||||
{
|
||||
char Ch;
|
||||
while ( ! _IBMPC_chrdy( & Ch ) )
|
||||
continue;
|
||||
return Ch;
|
||||
}
|
||||
151
c/src/lib/libbsp/i386/go32/console/outch.c
Normal file
151
c/src/lib/libbsp/i386/go32/console/outch.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <go32.h>
|
||||
#include <bsp.h>
|
||||
#include <cpu.h>
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#define MAX_COL 80
|
||||
#define MAX_ROW 50
|
||||
|
||||
static unsigned nrow = 25;
|
||||
static unsigned ncol = 80;
|
||||
static unsigned short * tvram = TVRAM;
|
||||
static unsigned char current_col = 0;
|
||||
static unsigned char current_row = 0;
|
||||
static unsigned short screen_copy[ MAX_ROW*MAX_COL ];
|
||||
|
||||
static void init_cons( void );
|
||||
|
||||
/*
|
||||
* set_cursor_pos()
|
||||
* Set cursor position based on current absolute screen offset
|
||||
*/
|
||||
static void
|
||||
set_cursor_pos(void)
|
||||
{
|
||||
register unsigned short gdc_pos = current_row * ncol + current_col;
|
||||
outport_byte( GDC_REG_PORT, 0xe );
|
||||
outport_byte( GDC_VAL_PORT, (gdc_pos >> 8) & 0xff );
|
||||
outport_byte( GDC_REG_PORT, 0xf );
|
||||
outport_byte( GDC_VAL_PORT, gdc_pos & 0xff );
|
||||
}
|
||||
|
||||
/*
|
||||
* scroll_up()
|
||||
* Scroll screen up one line
|
||||
*/
|
||||
static void
|
||||
scroll_up( unsigned short * tv, unsigned short * copy, unsigned int lines )
|
||||
{
|
||||
if ( lines > nrow )
|
||||
lines = nrow;
|
||||
|
||||
/* move everything up */
|
||||
memmove( copy, copy+ncol*lines, (nrow-lines)*ncol*sizeof copy[0] );
|
||||
|
||||
/* fill bottom with blanks */
|
||||
{
|
||||
int loop = ncol*lines;
|
||||
unsigned short * ptr = copy + ncol*(nrow-lines);
|
||||
while ( --loop >= 0 )
|
||||
*ptr++ = (WHITE<<8) | ' ';
|
||||
}
|
||||
|
||||
/* copy new screen to video buffer */
|
||||
dosmemput( copy, nrow*ncol*sizeof copy[0], (int)tv );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PUT()
|
||||
* Write character at current screen location
|
||||
*/
|
||||
inline static void PUT( char c )
|
||||
{
|
||||
unsigned short loc = current_row*ncol+current_col;
|
||||
unsigned short val = (WHITE<<8) | c;
|
||||
screen_copy[loc] = val;
|
||||
dosmemput( &screen_copy[loc], sizeof screen_copy[0], (int)(tvram+loc) );
|
||||
}
|
||||
|
||||
/*
|
||||
* cons_putc()
|
||||
* Place a character on next screen position
|
||||
*/
|
||||
static void
|
||||
cons_putc( unsigned char c )
|
||||
{
|
||||
static int first = 1;
|
||||
if ( first ) {
|
||||
init_cons();
|
||||
first = 0;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case '\t':
|
||||
while ( current_row % 8 )
|
||||
cons_putc(' ');
|
||||
break;
|
||||
case '\r':
|
||||
current_col = 0;
|
||||
break;
|
||||
case '\n':
|
||||
if ( ++current_row >= nrow ) {
|
||||
scroll_up( tvram, screen_copy, 1 );
|
||||
current_row -= 1;
|
||||
}
|
||||
break;
|
||||
case '\b':
|
||||
if ( current_col > 0 ) {
|
||||
--current_col;
|
||||
PUT(' ');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PUT(c);
|
||||
current_col += 1;
|
||||
if ( current_col >= ncol ) {
|
||||
current_col = 0;
|
||||
current_row += 1;
|
||||
if ( current_row >= nrow ) {
|
||||
scroll_up( tvram, screen_copy, 1 );
|
||||
current_row -= 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
set_cursor_pos();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* init_cons()
|
||||
* Hook for any early setup
|
||||
*/
|
||||
static void
|
||||
init_cons( void )
|
||||
{
|
||||
#if 0
|
||||
/* Get a copy of original screen */
|
||||
dosmemget( (int)tvram, nrow*ncol*sizeof *tvram, screen_copy );
|
||||
#else
|
||||
/* Clear entire screen */
|
||||
scroll_up( tvram, screen_copy, nrow );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _IBMPC_outch( unsigned char ch )
|
||||
{
|
||||
extern int _IBMPC_Use_Go32_IO;
|
||||
|
||||
if ( _IBMPC_Use_Go32_IO ) {
|
||||
write( 1, &ch, 1 );
|
||||
} else {
|
||||
cons_putc( ch );
|
||||
}
|
||||
}
|
||||
157
c/src/lib/libbsp/i386/go32/include/bsp.h
Normal file
157
c/src/lib/libbsp/i386/go32/include/bsp.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/* bsp.h
|
||||
*
|
||||
* This include file definitions related to the ibm386 (go32) board.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __IBMPC_h
|
||||
#define __IBMPC_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <rtems.h>
|
||||
#include <cpu.h>
|
||||
#include <iosupp.h>
|
||||
|
||||
/*
|
||||
* Define the time limits for RTEMS Test Suite test durations.
|
||||
* Long test and short test duration limits are provided. These
|
||||
* values are in seconds and need to be converted to ticks for the
|
||||
* application.
|
||||
*
|
||||
*/
|
||||
|
||||
#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */
|
||||
#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
|
||||
|
||||
|
||||
/*
|
||||
* Define the interrupt mechanism for Time Test 27
|
||||
*
|
||||
* NOTE: Use a software interrupt for the i386.
|
||||
*/
|
||||
#define MUST_WAIT_FOR_INTERRUTPT 0
|
||||
#define Install_tm27_vector( handler ) set_vector( (handler), 0x90, 1 )
|
||||
#define Cause_tm27_intr() asm volatile( "int $0x90" : : );
|
||||
#define Clear_tm27_intr()
|
||||
#define Lower_tm27_intr()
|
||||
|
||||
|
||||
/*
|
||||
* Simple spin delay in microsecond units for device drivers.
|
||||
* This is very dependent on the clock speed of the target.
|
||||
*/
|
||||
|
||||
#define delay( _microseconds ) { \
|
||||
rtems_unsigned32 _cnt = (_microseconds); \
|
||||
asm volatile ("0: nop; mov %0,%0; loop 0b" : "=c"(_cnt) : "0"(_cnt) ); \
|
||||
}
|
||||
|
||||
|
||||
/* Constants */
|
||||
|
||||
/* Assume color console */
|
||||
#define COLOR 1
|
||||
#if COLOR
|
||||
# define GDC_REG_PORT 0x3d4
|
||||
# define GDC_VAL_PORT 0x3d5
|
||||
# define TVRAM ((unsigned short *)0xb8000L)
|
||||
#else
|
||||
# define GDC_REG_PORT 0x3b4
|
||||
# define GDC_VAL_PORT 0x3b5
|
||||
# define TVRAM ((unsigned short *)0xb0000L)
|
||||
#endif
|
||||
|
||||
/* White character attribute--works for MGA and CGA */
|
||||
#define WHITE 0x07
|
||||
|
||||
/* Ports for PC keyboard */
|
||||
#define KBD_CTL 0x61
|
||||
#define KBD_DATA 0x60
|
||||
#define KBD_STATUS 0x64
|
||||
|
||||
/* Constants relating to the 8254 (or 8253) programmable interval timers */
|
||||
/* Port address of the control port and timer channels */
|
||||
/*
|
||||
* Macros for specifying values to be written into a mode register.
|
||||
*/
|
||||
#define IO_TIMER1 0x40
|
||||
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
|
||||
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
|
||||
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
|
||||
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
|
||||
#define TIMER_SEL0 0x00 /* select counter 0 */
|
||||
#define TIMER_SEL1 0x40 /* select counter 1 */
|
||||
#define TIMER_SEL2 0x80 /* select counter 2 */
|
||||
#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */
|
||||
#define TIMER_ONESHOT 0x02 /* mode 1, one shot */
|
||||
#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */
|
||||
#define TIMER_SQWAVE 0x06 /* mode 3, square wave */
|
||||
#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */
|
||||
#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */
|
||||
#define TIMER_LATCH 0x00 /* latch counter for reading */
|
||||
#define TIMER_LSB 0x10 /* r/w counter LSB */
|
||||
#define TIMER_MSB 0x20 /* r/w counter MSB */
|
||||
#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
|
||||
#define TIMER_BCD 0x01 /* count in BCD */
|
||||
|
||||
/* The internal tick rate in ticks per second */
|
||||
#define TIMER_TICK 1193182
|
||||
#define US_TO_TICK(us) (((us)*105+44)/88)
|
||||
#define TICK_TO_US(tk) (((tk)*88+52)/105)
|
||||
|
||||
/* Structures */
|
||||
|
||||
#ifdef IBMPC_INIT
|
||||
#undef BSP_EXTERN
|
||||
#define BSP_EXTERN
|
||||
#else
|
||||
#undef BSP_EXTERN
|
||||
#define BSP_EXTERN extern
|
||||
#endif
|
||||
|
||||
/* functions */
|
||||
|
||||
int _IBMPC_chrdy( char * ch );
|
||||
int _IBMPC_inch( void );
|
||||
void _IBMPC_outch( unsigned char );
|
||||
|
||||
/* miscellaneous stuff assumed to exist */
|
||||
|
||||
extern rtems_configuration_table BSP_Configuration;
|
||||
|
||||
#if 0
|
||||
extern i386_IDT_slot Interrupt_descriptor_table[ 256 ];
|
||||
extern i386_GDT_slot Global_descriptor_table[ 8192 ];
|
||||
BSP_EXTERN unsigned short Idt[3]; /* Interrupt Descriptor Table Address */
|
||||
BSP_EXTERN unsigned short Gdt[3]; /* Global Descriptor Table Address */
|
||||
BSP_EXTERN unsigned int Idt_base;
|
||||
BSP_EXTERN unsigned int Gdt_base;
|
||||
#endif
|
||||
|
||||
/* routines */
|
||||
|
||||
i386_isr set_vector(
|
||||
rtems_isr_entry handler,
|
||||
rtems_vector_number vector,
|
||||
int type
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
|
||||
104
c/src/lib/libbsp/i386/go32/include/coverhd.h
Normal file
104
c/src/lib/libbsp/i386/go32/include/coverhd.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* coverhd.h
|
||||
*
|
||||
* This include file has defines to represent the overhead associated
|
||||
* with calling a particular directive from C on this target.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __COVERHD_h
|
||||
#define __COVERHD_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
|
||||
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
|
||||
#define CALLING_OVERHEAD_TASK_CREATE 0
|
||||
#define CALLING_OVERHEAD_TASK_IDENT 0
|
||||
#define CALLING_OVERHEAD_TASK_START 0
|
||||
#define CALLING_OVERHEAD_TASK_RESTART 0
|
||||
#define CALLING_OVERHEAD_TASK_DELETE 0
|
||||
#define CALLING_OVERHEAD_TASK_SUSPEND 0
|
||||
#define CALLING_OVERHEAD_TASK_RESUME 0
|
||||
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
|
||||
#define CALLING_OVERHEAD_TASK_MODE 0
|
||||
#define CALLING_OVERHEAD_TASK_GET_NOTE 0
|
||||
#define CALLING_OVERHEAD_TASK_SET_NOTE 0
|
||||
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0
|
||||
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
|
||||
#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
|
||||
#define CALLING_OVERHEAD_CLOCK_GET 0
|
||||
#define CALLING_OVERHEAD_CLOCK_SET 0
|
||||
#define CALLING_OVERHEAD_CLOCK_TICK 0
|
||||
|
||||
#define CALLING_OVERHEAD_TIMER_CREATE 0
|
||||
#define CALLING_OVERHEAD_TIMER_IDENT 0
|
||||
#define CALLING_OVERHEAD_TIMER_DELETE 0
|
||||
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
|
||||
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0
|
||||
#define CALLING_OVERHEAD_TIMER_RESET 0
|
||||
#define CALLING_OVERHEAD_TIMER_CANCEL 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
|
||||
|
||||
#define CALLING_OVERHEAD_EVENT_SEND 0
|
||||
#define CALLING_OVERHEAD_EVENT_RECEIVE 0
|
||||
#define CALLING_OVERHEAD_SIGNAL_CATCH 0
|
||||
#define CALLING_OVERHEAD_SIGNAL_SEND 0
|
||||
#define CALLING_OVERHEAD_PARTITION_CREATE 0
|
||||
#define CALLING_OVERHEAD_PARTITION_IDENT 0
|
||||
#define CALLING_OVERHEAD_PARTITION_DELETE 0
|
||||
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
|
||||
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
|
||||
#define CALLING_OVERHEAD_REGION_CREATE 0
|
||||
#define CALLING_OVERHEAD_REGION_IDENT 0
|
||||
#define CALLING_OVERHEAD_REGION_DELETE 0
|
||||
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
|
||||
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
|
||||
#define CALLING_OVERHEAD_PORT_CREATE 0
|
||||
#define CALLING_OVERHEAD_PORT_IDENT 0
|
||||
#define CALLING_OVERHEAD_PORT_DELETE 0
|
||||
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
|
||||
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
|
||||
|
||||
#define CALLING_OVERHEAD_IO_INITIALIZE 0
|
||||
#define CALLING_OVERHEAD_IO_OPEN 0
|
||||
#define CALLING_OVERHEAD_IO_CLOSE 0
|
||||
#define CALLING_OVERHEAD_IO_READ 0
|
||||
#define CALLING_OVERHEAD_IO_WRITE 0
|
||||
#define CALLING_OVERHEAD_IO_CONTROL 0
|
||||
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
|
||||
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
134
c/src/lib/libbsp/i386/go32/startup/bspstart.c
Normal file
134
c/src/lib/libbsp/i386/go32/startup/bspstart.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/* bsp_start()
|
||||
*
|
||||
* This routine starts the application. It includes application,
|
||||
* board, and monitor specific initialization and configuration.
|
||||
* The generic CPU dependent initialization has been performed
|
||||
* before this routine is invoked.
|
||||
*
|
||||
* INPUT: NONE
|
||||
*
|
||||
* OUTPUT: NONE
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <cpu.h>
|
||||
#include <libcsupport.h>
|
||||
|
||||
#include <stackchk.h>
|
||||
|
||||
/*
|
||||
* The original table from the application and our copy of it with
|
||||
* some changes.
|
||||
*/
|
||||
|
||||
extern rtems_configuration_table Configuration;
|
||||
rtems_configuration_table BSP_Configuration;
|
||||
|
||||
rtems_cpu_table Cpu_table;
|
||||
|
||||
/* Initialize whatever libc we are using
|
||||
* called from postdriver hook
|
||||
*/
|
||||
|
||||
void bsp_libc_init()
|
||||
{
|
||||
rtems_unsigned32 heap_start;
|
||||
|
||||
#if 0
|
||||
extern int end;
|
||||
heap_start = (rtems_unsigned32) &end;
|
||||
#else
|
||||
void * sbrk( int );
|
||||
heap_start = (rtems_unsigned32) sbrk( 64 * 1024 + CPU_ALIGNMENT );
|
||||
#endif
|
||||
if (heap_start & (CPU_ALIGNMENT-1))
|
||||
heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
|
||||
|
||||
RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0);
|
||||
|
||||
/*
|
||||
* Set up for the libc handling.
|
||||
*/
|
||||
|
||||
if (BSP_Configuration.ticks_per_timeslice > 0)
|
||||
libc_init(1); /* reentrant if possible */
|
||||
else
|
||||
libc_init(0); /* non-reentrant */
|
||||
|
||||
/*
|
||||
* Initialize the stack bounds checker
|
||||
*/
|
||||
|
||||
#ifdef STACK_CHECKER_ON
|
||||
Stack_check_Initialize();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void bsp_start()
|
||||
{
|
||||
extern void * sbrk( int );
|
||||
|
||||
Cpu_table.pretasking_hook = NULL;
|
||||
Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */
|
||||
Cpu_table.postdriver_hook = NULL; /* Call our main() for constructors */
|
||||
Cpu_table.idle_task = NULL; /* do not override system IDLE task */
|
||||
Cpu_table.do_zero_of_workspace = TRUE;
|
||||
Cpu_table.interrupt_table_segment = 0;/* get_ds(); */
|
||||
Cpu_table.interrupt_table_offset = (void *)0;
|
||||
Cpu_table.interrupt_stack_size = 4096;
|
||||
Cpu_table.extra_system_initialization_stack = 0;
|
||||
|
||||
/*
|
||||
* Copy the table
|
||||
*/
|
||||
BSP_Configuration = Configuration;
|
||||
|
||||
BSP_Configuration.work_space_start = sbrk( Configuration.work_space_size );
|
||||
if ( BSP_Configuration.work_space_start == 0 ) {
|
||||
/* Big trouble */
|
||||
int write( int, void *, int );
|
||||
void _exit( int );
|
||||
char msg[] = "bsp_start() couldn't sbrk() RTEMS work space\n";
|
||||
write( 2, msg, sizeof msg - 1 );
|
||||
_exit( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Add 1 region for Malloc in libc_low
|
||||
*/
|
||||
|
||||
BSP_Configuration.maximum_regions++;
|
||||
|
||||
/*
|
||||
* Add 1 extension for newlib libc
|
||||
*/
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
BSP_Configuration.maximum_extensions++;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Add another extension if using the stack checker
|
||||
*/
|
||||
|
||||
#ifdef STACK_CHECKER_ON
|
||||
BSP_Configuration.maximum_extensions++;
|
||||
#endif
|
||||
|
||||
rtems_initialize_executive( &BSP_Configuration, &Cpu_table );
|
||||
/* does not return */
|
||||
|
||||
/* no cleanup necessary for GO32 */
|
||||
}
|
||||
30
c/src/lib/libbsp/i386/go32/startup/exit.c
Normal file
30
c/src/lib/libbsp/i386/go32/startup/exit.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* exit
|
||||
*
|
||||
* This routine returns control to DOS.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <clockdrv.h>
|
||||
#include <iodrv.h>
|
||||
|
||||
#if 0
|
||||
/* Prefer to pick up _exit() in djgcc */
|
||||
void _exit( )
|
||||
{
|
||||
Io_cleanup();
|
||||
bsp_cleanup();
|
||||
}
|
||||
#endif
|
||||
|
||||
67
c/src/lib/libbsp/i386/go32/startup/setvec.c
Normal file
67
c/src/lib/libbsp/i386/go32/startup/setvec.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/* set_vector
|
||||
*
|
||||
* This routine installs an interrupt vector under go32.
|
||||
*
|
||||
* INPUT:
|
||||
* handler - interrupt handler entry point
|
||||
* vector - vector number
|
||||
* type - 0 indicates raw hardware connect
|
||||
* 1 indicates RTEMS interrupt connect
|
||||
*
|
||||
* RETURNS:
|
||||
* address of previous interrupt handler
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
|
||||
#include <dpmi.h>
|
||||
#include <go32.h>
|
||||
|
||||
i386_isr set_vector( /* returns old vector */
|
||||
rtems_isr_entry handler, /* isr routine */
|
||||
rtems_vector_number vector, /* vector number */
|
||||
int type /* RTEMS or RAW intr */
|
||||
)
|
||||
{
|
||||
i386_isr previous_isr;
|
||||
|
||||
if ( type ) {
|
||||
rtems_interrupt_catch( handler, vector,
|
||||
(rtems_isr_entry *) &previous_isr );
|
||||
} else {
|
||||
/* Interrupt goes straight to the supplied ISR. This code is */
|
||||
/* slightly different than that in _CPU_ISR_install_vector */
|
||||
/* (which is eventually called by the above) in that this code */
|
||||
/* returns the raw entry point as the old handler, while the */
|
||||
/* other version returns the old entry point pointed at by the */
|
||||
/* rtems ISR table. */
|
||||
_go32_dpmi_seginfo handler_info;
|
||||
|
||||
/* get the address of the old handler */
|
||||
_go32_dpmi_get_protected_mode_interrupt_vector( vector, &handler_info);
|
||||
|
||||
/* Notice how we're failing to save the pm_segment portion of the */
|
||||
/* structure here? That means we might crash the system if we */
|
||||
/* try to restore the ISR. Can't fix this until i386_isr is */
|
||||
/* redefined. XXX [BHC]. */
|
||||
previous_isr = (i386_isr) handler_info.pm_offset;
|
||||
|
||||
/* install the IDT entry */
|
||||
handler_info.pm_offset = (int)handler;
|
||||
handler_info.pm_selector = _go32_my_cs();
|
||||
_go32_dpmi_set_protected_mode_interrupt_vector( vector, &handler_info);
|
||||
}
|
||||
return previous_isr;
|
||||
}
|
||||
|
||||
107
c/src/lib/libbsp/i386/go32/timer/timer.c
Normal file
107
c/src/lib/libbsp/i386/go32/timer/timer.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/* Timer_init()
|
||||
*
|
||||
* This routine initializes the timer on the IBM 386.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* NOTE: It is important that the timer start/stop overhead be
|
||||
* determined when porting or modifying this code.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include <cpu.h>
|
||||
#include <bsp.h>
|
||||
|
||||
volatile rtems_unsigned32 Ttimer_val;
|
||||
rtems_boolean Timer_driver_Find_average_overhead;
|
||||
|
||||
#if defined(pentium)
|
||||
static inline unsigned long long rdtsc( void )
|
||||
{
|
||||
/* Return the value of the on-chip cycle counter. */
|
||||
unsigned long long result;
|
||||
__asm __volatile( ".byte 0x0F, 0x31" : "=A" (result) );
|
||||
return result;
|
||||
}
|
||||
#else /* pentium */
|
||||
rtems_isr timerisr();
|
||||
#endif /* pentium */
|
||||
|
||||
void Timer_initialize()
|
||||
{
|
||||
#if defined(pentium)
|
||||
Ttimer_val = rdtsc();
|
||||
#else /* pentium */
|
||||
static int First = 1;
|
||||
if ( First ) {
|
||||
/* install ISR */
|
||||
set_vector( timerisr, 0x8, 0 );
|
||||
|
||||
/* Wait for ISR to be called at least once */
|
||||
Ttimer_val = 0;
|
||||
while ( Ttimer_val == 0 )
|
||||
continue;
|
||||
|
||||
/* load timer for 250 microsecond period */
|
||||
outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
|
||||
outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 0 & 0xff);
|
||||
outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 8 & 0xff);
|
||||
|
||||
First = 0;
|
||||
}
|
||||
Ttimer_val = 0; /* clear timer ISR count */
|
||||
#endif /* PENTIUM */
|
||||
}
|
||||
|
||||
#define AVG_OVERHEAD 0 /* 0.1 microseconds to start/stop timer. */
|
||||
#define LEAST_VALID 1 /* Don't trust a value lower than this */
|
||||
|
||||
|
||||
int Read_timer()
|
||||
{
|
||||
register rtems_unsigned32 total;
|
||||
#if defined(pentium)
|
||||
total = rdtsc() - Ttimer_val;
|
||||
#else /* pentium */
|
||||
register rtems_unsigned8 lsb, msb;
|
||||
register rtems_unsigned32 clicks;
|
||||
outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_LATCH );
|
||||
inport_byte( TIMER_CNTR0, lsb );
|
||||
inport_byte( TIMER_CNTR0, msb );
|
||||
clicks = msb << 8 | lsb;
|
||||
total = Ttimer_val + 250 - TICK_TO_US( clicks );
|
||||
#endif /* pentium */
|
||||
|
||||
if ( Timer_driver_Find_average_overhead == 1 )
|
||||
return total;
|
||||
else if ( total < LEAST_VALID )
|
||||
return 0; /* below timer resolution */
|
||||
else
|
||||
return total - AVG_OVERHEAD;
|
||||
}
|
||||
|
||||
rtems_status_code Empty_function( void )
|
||||
{
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
void Set_find_average_overhead(
|
||||
rtems_boolean find_flag
|
||||
)
|
||||
{
|
||||
Timer_driver_Find_average_overhead = find_flag;
|
||||
}
|
||||
39
c/src/lib/libbsp/i386/go32/timer/timerisr.s
Normal file
39
c/src/lib/libbsp/i386/go32/timer/timerisr.s
Normal file
@@ -0,0 +1,39 @@
|
||||
# timer_isr()
|
||||
#
|
||||
# This routine provides the ISR for the timer. The timer is set up
|
||||
# to generate an interrupt at maximum intervals.
|
||||
#
|
||||
# Input parameters: NONE
|
||||
#
|
||||
# Output parameters: NONE
|
||||
#
|
||||
# COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
# On-Line Applications Research Corporation (OAR).
|
||||
# All rights assigned to U.S. Government, 1994.
|
||||
#
|
||||
# This material may be reproduced by or for the U.S. Government pursuant
|
||||
# to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
# notice must appear in all copies of this file and its derivatives.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
#include "asm.h"
|
||||
|
||||
BEGIN_CODE
|
||||
|
||||
EXTERN(_Ttimer_val)
|
||||
|
||||
SYM (_timerisr):
|
||||
addl $250,_Ttimer_val # another 250 microseconds
|
||||
push edx
|
||||
push eax
|
||||
movw $0x20,dx
|
||||
mov edx,eax
|
||||
outb al,(dx) # touch interrupt controller
|
||||
pop eax
|
||||
pop edx
|
||||
iret
|
||||
|
||||
END_CODE
|
||||
END
|
||||
122
c/src/lib/libbsp/unix/posix/clock/clock.c
Normal file
122
c/src/lib/libbsp/unix/posix/clock/clock.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/* Clock
|
||||
*
|
||||
* This routine initializes the interval timer on the
|
||||
* PA-RISC CPU. The tick frequency is specified by the bsp.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
extern rtems_configuration_table Configuration;
|
||||
extern sigset_t UNIX_SIGNAL_MASK;
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
|
||||
void Install_clock();
|
||||
void Clock_isr();
|
||||
void Clock_exit();
|
||||
|
||||
/*
|
||||
* CPU_HPPA_CLICKS_PER_TICK is either a #define or an rtems_unsigned32
|
||||
* allocated and set by bsp_start()
|
||||
*/
|
||||
|
||||
#ifndef CPU_HPPA_CLICKS_PER_TICK
|
||||
extern rtems_unsigned32 CPU_HPPA_CLICKS_PER_TICK;
|
||||
#endif
|
||||
|
||||
volatile rtems_unsigned32 Clock_driver_ticks;
|
||||
|
||||
struct itimerval new;
|
||||
|
||||
rtems_device_driver
|
||||
Clock_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp,
|
||||
rtems_id tid,
|
||||
rtems_unsigned32 *rval
|
||||
)
|
||||
{
|
||||
Install_clock(Clock_isr);
|
||||
}
|
||||
|
||||
void
|
||||
ReInstall_clock(rtems_isr_entry new_clock_isr)
|
||||
{
|
||||
rtems_unsigned32 isrlevel = 0;
|
||||
|
||||
rtems_interrupt_disable(isrlevel);
|
||||
(void)set_vector(new_clock_isr, SIGALRM, 1);
|
||||
rtems_interrupt_enable(isrlevel);
|
||||
}
|
||||
|
||||
void
|
||||
Install_clock(rtems_isr_entry clock_isr)
|
||||
{
|
||||
Clock_driver_ticks = 0;
|
||||
|
||||
new.it_value.tv_sec = 0;
|
||||
new.it_value.tv_usec = Configuration.microseconds_per_tick;
|
||||
new.it_interval.tv_sec = 0;
|
||||
new.it_interval.tv_usec = Configuration.microseconds_per_tick;
|
||||
|
||||
(void)set_vector(clock_isr, SIGALRM, 1);
|
||||
|
||||
setitimer(ITIMER_REAL, &new, 0);
|
||||
|
||||
atexit(Clock_exit);
|
||||
}
|
||||
|
||||
void
|
||||
Clock_isr(int vector)
|
||||
{
|
||||
Clock_driver_ticks++;
|
||||
|
||||
rtems_clock_tick();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called via atexit()
|
||||
* Remove the clock signal
|
||||
*/
|
||||
|
||||
void
|
||||
Clock_exit(void)
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
/*
|
||||
* Set the SIGALRM signal to ignore any last
|
||||
* signals that might come in while we are
|
||||
* disarming the timer and removing the interrupt
|
||||
* vector.
|
||||
*/
|
||||
|
||||
act.sa_handler = SIG_IGN;
|
||||
|
||||
sigaction(SIGALRM, &act, 0);
|
||||
|
||||
new.it_value.tv_sec = 0;
|
||||
new.it_value.tv_usec = 0;
|
||||
|
||||
setitimer(ITIMER_REAL, &new, 0);
|
||||
|
||||
(void)set_vector(0, SIGALRM, 1);
|
||||
}
|
||||
37
c/src/lib/libbsp/unix/posix/console/console.c
Normal file
37
c/src/lib/libbsp/unix/posix/console/console.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Console IO Support Routines
|
||||
*
|
||||
* These provide UNIX-like read and write calls for the C library.
|
||||
*
|
||||
* COPYRIGHT (c) 1994 by Division Incorporated
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies, and that the name of Division Incorporated not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific, written prior permission.
|
||||
* Division Incorporated makes no representations about the
|
||||
* suitability of this software for any purpose.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
rtems_device_driver
|
||||
console_initialize(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg,
|
||||
rtems_id self,
|
||||
rtems_unsigned32 * status)
|
||||
{
|
||||
*status = RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
88
c/src/lib/libbsp/unix/posix/include/bsp.h
Normal file
88
c/src/lib/libbsp/unix/posix/include/bsp.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* bsp.h
|
||||
*
|
||||
* This include file contains all Solaris 2.3 UNIX definitions.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __SOLARIS23_h
|
||||
#define __SOLARIS23_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <rtems.h>
|
||||
#include <iosupp.h>
|
||||
|
||||
/*
|
||||
* Define the time limits for RTEMS Test Suite test durations.
|
||||
* Long test and short test duration limits are provided. These
|
||||
* values are in seconds and need to be converted to ticks for the
|
||||
* application.
|
||||
*
|
||||
*/
|
||||
|
||||
#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */
|
||||
#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
|
||||
|
||||
/*
|
||||
* Stuff for Time Test 27
|
||||
*/
|
||||
|
||||
#define MUST_WAIT_FOR_INTERRUPT 1
|
||||
|
||||
#define Install_tm27_vector( handler ) \
|
||||
set_vector( (handler), 16, 1 )
|
||||
|
||||
#define Cause_tm27_intr() \
|
||||
raise( 16 )
|
||||
|
||||
#define Clear_tm27_intr()
|
||||
|
||||
#define Lower_tm27_intr() \
|
||||
_ISR_Set_level( 0 );
|
||||
|
||||
#define RAM_START 0
|
||||
#define RAM_END 0x100000
|
||||
|
||||
/* miscellaneous stuff assumed to exist */
|
||||
|
||||
extern rtems_configuration_table BSP_Configuration;
|
||||
|
||||
#define INTERRUPT_EXTERNAL_MPCI 0
|
||||
|
||||
/* functions */
|
||||
|
||||
void bsp_start( void );
|
||||
void bsp_cleanup( void );
|
||||
|
||||
/* miscellaneous stuff assumed to exist */
|
||||
|
||||
extern rtems_configuration_table BSP_Configuration; /* owned by BSP */
|
||||
extern rtems_cpu_table Cpu_table; /* owned by BSP */
|
||||
|
||||
extern int rtems_argc;
|
||||
extern char **rtems_argv;
|
||||
extern char **rtems_envp;
|
||||
|
||||
extern rtems_unsigned32 bsp_isr_level;
|
||||
|
||||
extern char *rtems_progname; /* UNIX executable name */
|
||||
|
||||
extern int cpu_number;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
111
c/src/lib/libbsp/unix/posix/include/coverhd.h
Normal file
111
c/src/lib/libbsp/unix/posix/include/coverhd.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* coverhd.h
|
||||
*
|
||||
* This include file has defines to represent the overhead associated
|
||||
* with calling a particular directive from C. These are used in the
|
||||
* Timing Test Suite to ignore the overhead required to pass arguments
|
||||
* to directives. On some CPUs and/or target boards, this overhead
|
||||
* is significant and makes it difficult to distinguish internal
|
||||
* RTEMS execution time from that used to call the directive.
|
||||
*
|
||||
* NOTE: If these are all zero, then the times reported include all
|
||||
* all calling overhead including passing of arguments.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __COVERHD_h
|
||||
#define __COVERHD_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
|
||||
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
|
||||
#define CALLING_OVERHEAD_TASK_CREATE 0
|
||||
#define CALLING_OVERHEAD_TASK_IDENT 0
|
||||
#define CALLING_OVERHEAD_TASK_START 0
|
||||
#define CALLING_OVERHEAD_TASK_RESTART 0
|
||||
#define CALLING_OVERHEAD_TASK_DELETE 0
|
||||
#define CALLING_OVERHEAD_TASK_SUSPEND 0
|
||||
#define CALLING_OVERHEAD_TASK_RESUME 0
|
||||
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
|
||||
#define CALLING_OVERHEAD_TASK_MODE 0
|
||||
#define CALLING_OVERHEAD_TASK_GET_NOTE 0
|
||||
#define CALLING_OVERHEAD_TASK_SET_NOTE 0
|
||||
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0
|
||||
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
|
||||
#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
|
||||
#define CALLING_OVERHEAD_CLOCK_GET 0
|
||||
#define CALLING_OVERHEAD_CLOCK_SET 0
|
||||
#define CALLING_OVERHEAD_CLOCK_TICK 0
|
||||
|
||||
#define CALLING_OVERHEAD_TIMER_CREATE 0
|
||||
#define CALLING_OVERHEAD_TIMER_IDENT 0
|
||||
#define CALLING_OVERHEAD_TIMER_DELETE 0
|
||||
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
|
||||
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0
|
||||
#define CALLING_OVERHEAD_TIMER_RESET 0
|
||||
#define CALLING_OVERHEAD_TIMER_CANCEL 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
|
||||
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
|
||||
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
|
||||
|
||||
#define CALLING_OVERHEAD_EVENT_SEND 0
|
||||
#define CALLING_OVERHEAD_EVENT_RECEIVE 0
|
||||
#define CALLING_OVERHEAD_SIGNAL_CATCH 0
|
||||
#define CALLING_OVERHEAD_SIGNAL_SEND 0
|
||||
#define CALLING_OVERHEAD_PARTITION_CREATE 0
|
||||
#define CALLING_OVERHEAD_PARTITION_IDENT 0
|
||||
#define CALLING_OVERHEAD_PARTITION_DELETE 0
|
||||
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
|
||||
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
|
||||
#define CALLING_OVERHEAD_REGION_CREATE 0
|
||||
#define CALLING_OVERHEAD_REGION_IDENT 0
|
||||
#define CALLING_OVERHEAD_REGION_DELETE 0
|
||||
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
|
||||
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
|
||||
#define CALLING_OVERHEAD_PORT_CREATE 0
|
||||
#define CALLING_OVERHEAD_PORT_IDENT 0
|
||||
#define CALLING_OVERHEAD_PORT_DELETE 0
|
||||
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
|
||||
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
|
||||
|
||||
#define CALLING_OVERHEAD_IO_INITIALIZE 0
|
||||
#define CALLING_OVERHEAD_IO_OPEN 0
|
||||
#define CALLING_OVERHEAD_IO_CLOSE 0
|
||||
#define CALLING_OVERHEAD_IO_READ 0
|
||||
#define CALLING_OVERHEAD_IO_WRITE 0
|
||||
#define CALLING_OVERHEAD_IO_CONTROL 0
|
||||
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
|
||||
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
|
||||
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
9
c/src/lib/libbsp/unix/posix/shmsupp/README
Normal file
9
c/src/lib/libbsp/unix/posix/shmsupp/README
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
This directory contains the SHM driver support files for
|
||||
System V/POSIX derived UNIX flavors.
|
||||
|
||||
WARNING: The interrupt support in this directory currently will
|
||||
only work in a homogeneous system.
|
||||
32
c/src/lib/libbsp/unix/posix/shmsupp/addrconv.c
Normal file
32
c/src/lib/libbsp/unix/posix/shmsupp/addrconv.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/* rtems_unsigned32 *Shm_Convert_address( addr )
|
||||
*
|
||||
* No address range conversion is required.
|
||||
*
|
||||
* Input parameters:
|
||||
* addr - address to convert
|
||||
*
|
||||
* Output parameters:
|
||||
* returns - converted address
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <shm.h>
|
||||
|
||||
void *Shm_Convert_address(
|
||||
void *addr
|
||||
)
|
||||
{
|
||||
return ( addr );
|
||||
}
|
||||
136
c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c
Normal file
136
c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/* void Shm_get_config( localnode, &shmcfg )
|
||||
*
|
||||
* This routine initializes, if necessary, and returns a pointer
|
||||
* to the Shared Memory Configuration Table for the UNIX
|
||||
* simulator.
|
||||
*
|
||||
* INPUT PARAMETERS:
|
||||
* localnode - local node number
|
||||
* shmcfg - address of pointer to SHM Config Table
|
||||
*
|
||||
* OUTPUT PARAMETERS:
|
||||
* *shmcfg - pointer to SHM Config Table
|
||||
*
|
||||
* NOTES: The MP interrupt used is the Runway bus' ability to directly
|
||||
* address the control registers of up to four CPUs and cause
|
||||
* interrupts on them.
|
||||
*
|
||||
* The following table illustrates the configuration limitations:
|
||||
*
|
||||
* BUS MAX
|
||||
* MODE ENDIAN NODES
|
||||
* ========= ====== =======
|
||||
* POLLED BIG 2+
|
||||
* INTERRUPT BIG 2..4
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <shm.h>
|
||||
#include <bsp.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/sem.h>
|
||||
|
||||
#define INTERRUPT 0 /* can be interrupt or polling */
|
||||
#define POLLING 1
|
||||
|
||||
shm_config_table BSP_shm_cfgtbl;
|
||||
|
||||
int semid;
|
||||
|
||||
void Shm_Cause_interrupt_unix(
|
||||
rtems_unsigned32 node
|
||||
);
|
||||
|
||||
void Shm_Get_configuration(
|
||||
rtems_unsigned32 localnode,
|
||||
shm_config_table **shmcfg
|
||||
)
|
||||
{
|
||||
rtems_unsigned32 maximum_nodes;
|
||||
int i;
|
||||
int shmid;
|
||||
char *shm_addr;
|
||||
key_t shm_key;
|
||||
key_t sem_key;
|
||||
struct sembuf sb;
|
||||
int status;
|
||||
|
||||
shm_key = 0xa000;
|
||||
|
||||
shmid = shmget(shm_key, 16 * KILOBYTE, IPC_CREAT | 0660);
|
||||
if ( shmid == -1 ) {
|
||||
perror( "shmget" );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
shm_addr = shmat(shmid, (char *)0, SHM_RND);
|
||||
if ( shm_addr == (void *)-1 ) {
|
||||
perror( "shmat" );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
sem_key = 0xa001;
|
||||
|
||||
maximum_nodes = Shm_RTEMS_MP_Configuration->maximum_nodes;
|
||||
semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
|
||||
if ( semid == -1 ) {
|
||||
perror( "semget" );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
if ( Shm_Is_master_node() ) {
|
||||
for ( i=0 ; i <= maximum_nodes ; i++ ) {
|
||||
sb.sem_op = 1;
|
||||
sb.sem_num = i;
|
||||
sb.sem_flg = 0;
|
||||
status = semop( semid, &sb, 1 );
|
||||
if ( status == -1 ) {
|
||||
fprintf( stderr, "Sem init failed %d\n", errno ); fflush( stderr );
|
||||
exit( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BSP_shm_cfgtbl.base = (vol_u32 *)shm_addr;
|
||||
BSP_shm_cfgtbl.length = 16 * KILOBYTE;
|
||||
BSP_shm_cfgtbl.format = SHM_BIG;
|
||||
|
||||
BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt_unix;
|
||||
|
||||
#ifdef NEUTRAL_BIG
|
||||
BSP_shm_cfgtbl.convert = NULL_CONVERT;
|
||||
#else
|
||||
BSP_shm_cfgtbl.convert = CPU_swap_u32;
|
||||
#endif
|
||||
|
||||
#if ( POLLING == 1 )
|
||||
BSP_shm_cfgtbl.poll_intr = POLLED_MODE;
|
||||
BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
|
||||
BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT;
|
||||
BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT;
|
||||
#else
|
||||
BSP_shm_cfgtbl.poll_intr = INTR_MODE;
|
||||
BSP_shm_cfgtbl.Intr.address = 0; /* process id? */
|
||||
BSP_shm_cfgtbl.Intr.value = 0; /* signal to send? */
|
||||
BSP_shm_cfgtbl.Intr.length = LONG;
|
||||
#endif
|
||||
|
||||
*shmcfg = &BSP_shm_cfgtbl;
|
||||
}
|
||||
31
c/src/lib/libbsp/unix/posix/shmsupp/intr.c
Normal file
31
c/src/lib/libbsp/unix/posix/shmsupp/intr.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/* void Shm_interrupt_unix( node )
|
||||
*
|
||||
* This routine is the shared memory driver routine which
|
||||
* generates interrupts to other CPUs.
|
||||
*
|
||||
* Input parameters:
|
||||
* node - destination of this packet (0 = broadcast)
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <shm.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void Shm_Cause_interrupt_unix(
|
||||
rtems_unsigned32 node
|
||||
)
|
||||
{
|
||||
}
|
||||
117
c/src/lib/libbsp/unix/posix/shmsupp/lock.c
Normal file
117
c/src/lib/libbsp/unix/posix/shmsupp/lock.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* Shared Memory Lock Routines
|
||||
*
|
||||
* This shared memory locked queue support routine need to be
|
||||
* able to lock the specified locked queue. Interrupts are
|
||||
* disabled while the queue is locked to prevent preemption
|
||||
* and deadlock when two tasks poll for the same lock.
|
||||
* previous level.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <shm.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/sem.h>
|
||||
|
||||
extern int semid;
|
||||
|
||||
/*
|
||||
* Shm_Initialize_lock
|
||||
*
|
||||
* Initialize the lock for the specified locked queue.
|
||||
*/
|
||||
|
||||
void Shm_Initialize_lock(
|
||||
Shm_Locked_queue_Control *lq_cb
|
||||
)
|
||||
{
|
||||
lq_cb->lock =
|
||||
( lq_cb - Shm_Locked_queues ) / sizeof( Shm_Locked_queue_Control );
|
||||
}
|
||||
|
||||
/* Shm_Lock( &lq_cb )
|
||||
*
|
||||
* This shared memory locked queue support routine locks the
|
||||
* specified locked queue. It disables interrupts to prevent
|
||||
* a deadlock condition.
|
||||
*/
|
||||
|
||||
void Shm_Lock(
|
||||
Shm_Locked_queue_Control *lq_cb
|
||||
)
|
||||
{
|
||||
rtems_unsigned32 isr_level;
|
||||
struct sembuf sb;
|
||||
int status;
|
||||
|
||||
isr_level = 0;
|
||||
|
||||
sb.sem_num = lq_cb->lock;
|
||||
sb.sem_op = -1;
|
||||
sb.sem_flg = 0;
|
||||
rtems_interrupt_disable( isr_level );
|
||||
|
||||
Shm_isrstat = isr_level;
|
||||
|
||||
while (1) {
|
||||
status = semop(semid, &sb, 1);
|
||||
if ( status == 0 )
|
||||
break;
|
||||
if ( status == -1 && errno == EINTR )
|
||||
continue;
|
||||
|
||||
fprintf( stderr, "shm lock (%d %d)\n", status, errno );
|
||||
exit( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Shm_Unlock
|
||||
*
|
||||
* Unlock the lock for the specified locked queue.
|
||||
*/
|
||||
|
||||
void Shm_Unlock(
|
||||
Shm_Locked_queue_Control *lq_cb
|
||||
)
|
||||
{
|
||||
rtems_unsigned32 isr_level;
|
||||
struct sembuf sb;
|
||||
int status;
|
||||
|
||||
isr_level = 0;
|
||||
|
||||
sb.sem_num = lq_cb->lock;
|
||||
sb.sem_op = 1;
|
||||
sb.sem_flg = 0;
|
||||
|
||||
while (1) {
|
||||
status = semop(semid, &sb, 1);
|
||||
if ( status == 0 )
|
||||
break;
|
||||
if ( status == -1 && errno == EINTR )
|
||||
continue;
|
||||
|
||||
fprintf( stderr, "shm lock (%d %d)\n", status, errno ); fflush( stderr );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
isr_level = Shm_isrstat;
|
||||
rtems_interrupt_enable( isr_level );
|
||||
}
|
||||
29
c/src/lib/libbsp/unix/posix/shmsupp/mpisr.c
Normal file
29
c/src/lib/libbsp/unix/posix/shmsupp/mpisr.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/* Shm_setvec
|
||||
*
|
||||
* This driver routine sets the SHM interrupt vector to point to the
|
||||
* driver's SHM interrupt service routine.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <shm.h>
|
||||
|
||||
void Shm_setvec( void )
|
||||
{
|
||||
set_vector( Shm_isr, INTERRUPT_EXTERNAL_MPCI, 1 );
|
||||
}
|
||||
37
c/src/lib/libbsp/unix/posix/startup/bspclean.c
Normal file
37
c/src/lib/libbsp/unix/posix/startup/bspclean.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/* bsp_cleanup()
|
||||
*
|
||||
* This routine normally is part of start.s and returns
|
||||
* control to a monitor but on the UNIX simulator
|
||||
* we do that directly from main.c.
|
||||
*
|
||||
* INPUT: NONE
|
||||
*
|
||||
* OUTPUT: NONE
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
|
||||
/*
|
||||
* The app has "exited" (called rtems_shutdown_executive)
|
||||
*/
|
||||
|
||||
void bsp_cleanup( void )
|
||||
{
|
||||
/*
|
||||
* Invoke any fatal error extension and "halt"
|
||||
* By definition, rtems_fatal_error_occurred does not return.
|
||||
*/
|
||||
|
||||
rtems_fatal_error_occurred(0);
|
||||
}
|
||||
314
c/src/lib/libbsp/unix/posix/startup/bspstart.c
Normal file
314
c/src/lib/libbsp/unix/posix/startup/bspstart.c
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* @(#)bspstart.c 1.7 - 95/04/07
|
||||
*
|
||||
*/
|
||||
|
||||
/* bsp_start()
|
||||
*
|
||||
* This routine starts the application. It includes application,
|
||||
* board, and monitor specific initialization and configuration.
|
||||
* The generic CPU dependent initialization has been performed
|
||||
* before this routine is invoked.
|
||||
*
|
||||
* Called by RTEMS::RTEMS constructor in startup-ctor.cc
|
||||
*
|
||||
* INPUT: NONE
|
||||
*
|
||||
* OUTPUT: NONE
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <libcsupport.h>
|
||||
|
||||
#ifdef STACK_CHECKER_ON
|
||||
#include <stackchk.h>
|
||||
#endif
|
||||
|
||||
extern rtems_configuration_table Configuration;
|
||||
|
||||
/*
|
||||
* A copy of the configuration table from the application
|
||||
* with some changes applied to it.
|
||||
*/
|
||||
|
||||
rtems_configuration_table BSP_Configuration;
|
||||
rtems_multiprocessing_table BSP_Multiprocessing;
|
||||
rtems_cpu_table Cpu_table;
|
||||
rtems_unsigned32 bsp_isr_level;
|
||||
rtems_unsigned32 Heap_size;
|
||||
int rtems_argc;
|
||||
char **rtems_argv;
|
||||
char **rtems_envp;
|
||||
|
||||
|
||||
#define WORKSPACE_SIZE (WORKSPACE_MB * (1024 * 1024))
|
||||
#define HEAPSPACE_SIZE (HEAPSPACE_MB * (1024 * 1024))
|
||||
|
||||
rtems_unsigned8 MY_WORK_SPACE[ WORKSPACE_SIZE ] CPU_STRUCTURE_ALIGNMENT;
|
||||
|
||||
/*
|
||||
* Amount to increment itimer by each pass
|
||||
* It is a variable instead of a #define to allow the 'looptest'
|
||||
* script to bump it without recompiling rtems
|
||||
*/
|
||||
|
||||
rtems_unsigned32 CPU_CLICKS_PER_TICK;
|
||||
|
||||
/*
|
||||
* Function: bsp_libc_init
|
||||
* Created: 94/12/6
|
||||
*
|
||||
* Description:
|
||||
* Initialize whatever libc we are using
|
||||
* called from bsp_postdriver_hook
|
||||
*
|
||||
*
|
||||
* Parameters:
|
||||
* none
|
||||
*
|
||||
* Returns:
|
||||
* none.
|
||||
*
|
||||
* Side Effects:
|
||||
*
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Deficiencies/ToDo:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
bsp_libc_init(void)
|
||||
{
|
||||
void *heap_start;
|
||||
|
||||
Heap_size = HEAPSPACE_SIZE;
|
||||
heap_start = 0;
|
||||
|
||||
RTEMS_Malloc_Initialize((void *)heap_start, Heap_size, 1024 * 1024);
|
||||
|
||||
libc_init(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: bsp_pretasking_hook
|
||||
* Created: 95/03/10
|
||||
*
|
||||
* Description:
|
||||
* BSP pretasking hook. Called just before drivers are initialized.
|
||||
* Used to setup libc and install any BSP extensions.
|
||||
*
|
||||
* Parameters:
|
||||
* none
|
||||
*
|
||||
* Returns:
|
||||
* nada
|
||||
*
|
||||
* Side Effects:
|
||||
* installs a few extensions
|
||||
*
|
||||
* Notes:
|
||||
* Must not use libc (to do io) from here, since drivers are
|
||||
* not yet initialized.
|
||||
*
|
||||
* Deficiencies/ToDo:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
bsp_pretasking_hook(void)
|
||||
{
|
||||
bsp_libc_init();
|
||||
|
||||
#ifdef STACK_CHECKER_ON
|
||||
/*
|
||||
* Initialize the stack bounds checker
|
||||
* We can either turn it on here or from the app.
|
||||
*/
|
||||
|
||||
Stack_check_Initialize();
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_DEBUG
|
||||
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: bsp_start
|
||||
* Created: 94/12/6
|
||||
*
|
||||
* Description:
|
||||
* called by crt0 as our "main" equivalent
|
||||
*
|
||||
*
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*
|
||||
* Side Effects:
|
||||
*
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*
|
||||
* Deficiencies/ToDo:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
bsp_start(void)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
char buf[256];
|
||||
char node[6];
|
||||
char *home;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* Copy the table
|
||||
*/
|
||||
|
||||
BSP_Configuration = Configuration;
|
||||
|
||||
/*
|
||||
* If the node number is -1 then the application better provide
|
||||
* it through the file $HOME/rtems_node
|
||||
*/
|
||||
|
||||
BSP_Multiprocessing.node = -1;
|
||||
|
||||
if (BSP_Configuration.User_multiprocessing_table) {
|
||||
if (BSP_Configuration.User_multiprocessing_table->node == -1) {
|
||||
home = getenv("HOME");
|
||||
sprintf(buf, "%s/%s", home, "rtems_node");
|
||||
if ((stat(buf, &stat_buf)) == 0) {
|
||||
fd = open(buf, O_RDONLY);
|
||||
read(fd, node, 5);
|
||||
close(fd);
|
||||
unlink(buf);
|
||||
BSP_Multiprocessing = *BSP_Configuration.User_multiprocessing_table;
|
||||
BSP_Multiprocessing.node = atoi(node);
|
||||
BSP_Configuration.User_multiprocessing_table = &BSP_Multiprocessing;
|
||||
}
|
||||
if (BSP_Configuration.User_multiprocessing_table->maximum_nodes == -1) {
|
||||
home = getenv("HOME");
|
||||
sprintf(buf, "%s/%s", home, "rtems_max_node");
|
||||
if ((stat(buf, &stat_buf)) == 0) {
|
||||
fd = open(buf, O_RDONLY);
|
||||
read(fd, node, 5);
|
||||
close(fd);
|
||||
BSP_Multiprocessing.maximum_nodes = atoi(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set cpu_number to accurately reflect our cpu number
|
||||
*/
|
||||
|
||||
if (BSP_Configuration.User_multiprocessing_table)
|
||||
cpu_number = BSP_Configuration.User_multiprocessing_table->node - 1;
|
||||
else
|
||||
cpu_number = 0;
|
||||
|
||||
BSP_Configuration.work_space_start = (void *)MY_WORK_SPACE;
|
||||
if (BSP_Configuration.work_space_size)
|
||||
BSP_Configuration.work_space_size = WORKSPACE_SIZE;
|
||||
|
||||
/*
|
||||
* Set up our hooks
|
||||
* Make sure libc_init is done before drivers init'd so that
|
||||
* they can use atexit()
|
||||
*/
|
||||
|
||||
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
|
||||
|
||||
Cpu_table.predriver_hook = NULL;
|
||||
|
||||
Cpu_table.postdriver_hook = NULL;
|
||||
|
||||
Cpu_table.idle_task = NULL; /* do not override system IDLE task */
|
||||
|
||||
/*
|
||||
* Don't zero out the workspace since it is in the BSS under UNIX.
|
||||
*/
|
||||
|
||||
Cpu_table.do_zero_of_workspace = FALSE;
|
||||
|
||||
/*
|
||||
* XXX; interrupt stack not currently used, so this doesn't matter
|
||||
*/
|
||||
|
||||
Cpu_table.interrupt_stack_size = (12 * 1024);
|
||||
|
||||
Cpu_table.extra_system_initialization_stack = 0;
|
||||
|
||||
/*
|
||||
* Add 1 region for RTEMS Malloc
|
||||
*/
|
||||
|
||||
BSP_Configuration.maximum_regions++;
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
/*
|
||||
* Add 1 extension for newlib libc
|
||||
*/
|
||||
|
||||
BSP_Configuration.maximum_extensions++;
|
||||
#endif
|
||||
|
||||
#ifdef STACK_CHECKER_ON
|
||||
/*
|
||||
* Add 1 extension for stack checker
|
||||
*/
|
||||
|
||||
BSP_Configuration.maximum_extensions++;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Add 1 extension for MPCI_fatal
|
||||
*/
|
||||
|
||||
if (BSP_Configuration.User_multiprocessing_table)
|
||||
BSP_Configuration.maximum_extensions++;
|
||||
|
||||
CPU_CLICKS_PER_TICK = 1;
|
||||
|
||||
/*
|
||||
* Start most of RTEMS
|
||||
* main() will start the rest
|
||||
*/
|
||||
|
||||
bsp_isr_level = rtems_initialize_executive_early(
|
||||
&BSP_Configuration,
|
||||
&Cpu_table
|
||||
);
|
||||
}
|
||||
28
c/src/lib/libbsp/unix/posix/startup/exit.c
Normal file
28
c/src/lib/libbsp/unix/posix/startup/exit.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* exit
|
||||
*
|
||||
* This routine returns control to "the pre-RTEMS environment".
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <clockdrv.h>
|
||||
|
||||
void _exit( void )
|
||||
{
|
||||
/* Clock or Timer cleanup is run by at_exit() */
|
||||
|
||||
Io_cleanup();
|
||||
|
||||
bsp_cleanup();
|
||||
}
|
||||
108
c/src/lib/libbsp/unix/posix/startup/rtems-ctor.cc
Normal file
108
c/src/lib/libbsp/unix/posix/startup/rtems-ctor.cc
Normal file
@@ -0,0 +1,108 @@
|
||||
// @(#)rtems-ctor.cc 1.6 - 95/04/25
|
||||
//
|
||||
//
|
||||
|
||||
/*
|
||||
* rtems-ctor.cc
|
||||
*
|
||||
* Description:
|
||||
* This file exists solely to (try to) ensure RTEMS is initialized
|
||||
* before any global constructors are run.
|
||||
*
|
||||
* The problem:
|
||||
* Global constructors might reasonably expect that new() will
|
||||
* work, but since new() uses malloc() which uses RTEMS regions,
|
||||
* it can not be called until after initialize_executive().
|
||||
*
|
||||
* Global constructors are called in GNU systems one of 2 ways:
|
||||
*
|
||||
* an "invisible" call to __main() inserted by compiler
|
||||
* This __main() calls __do_global_ctors() which
|
||||
* walks thru the table and calls all global
|
||||
* constructors.
|
||||
*
|
||||
* or -
|
||||
* A special section is put into the linked binary. The
|
||||
* system startup code knows to run the constructors in
|
||||
* this special section before calling main().
|
||||
*
|
||||
* By making RTEMS initialization a constructor, we avoid having
|
||||
* too much about all this. All we have to guarantee is that
|
||||
* this constructor is the first one run.
|
||||
*
|
||||
*
|
||||
* So for the first case above, this is what happens
|
||||
*
|
||||
* host crt0
|
||||
* main()
|
||||
* __main()
|
||||
* __do_global_ctors()
|
||||
* bsp_start()
|
||||
* init_executive_early()
|
||||
* <<any other constructors>>
|
||||
*
|
||||
* init_executive_late()
|
||||
* bsp_cleanup()
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
/*
|
||||
* RTEMS program name
|
||||
* Probably not used by anyone, but it is nice to have it.
|
||||
* Actually the UNIX version of CPU_INVOKE_DEBUGGER will probably
|
||||
* need to use it
|
||||
*/
|
||||
|
||||
char *rtems_progname;
|
||||
|
||||
class RTEMS {
|
||||
public:
|
||||
RTEMS();
|
||||
~RTEMS();
|
||||
};
|
||||
|
||||
RTEMS rtems_constructor;
|
||||
|
||||
RTEMS::RTEMS()
|
||||
{
|
||||
bsp_start();
|
||||
}
|
||||
|
||||
RTEMS::~RTEMS()
|
||||
{
|
||||
bsp_cleanup();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
int
|
||||
main(int argc,
|
||||
char **argv,
|
||||
char **environp)
|
||||
{
|
||||
rtems_argc = argc;
|
||||
rtems_argv = argv;
|
||||
rtems_envp = environp;
|
||||
|
||||
if ((argc > 0) && argv && argv[0])
|
||||
rtems_progname = argv[0];
|
||||
else
|
||||
rtems_progname = "RTEMS";
|
||||
|
||||
/*
|
||||
* Start multitasking
|
||||
*/
|
||||
|
||||
rtems_initialize_executive_late( bsp_isr_level );
|
||||
|
||||
/*
|
||||
* Returns when multitasking is stopped
|
||||
* This allows our destructors to get run normally
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
60
c/src/lib/libbsp/unix/posix/startup/setvec.c
Normal file
60
c/src/lib/libbsp/unix/posix/startup/setvec.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/* set_vector
|
||||
*
|
||||
* This routine installs an interrupt vector on UNIX.
|
||||
*
|
||||
* INPUT:
|
||||
* handler - interrupt handler entry point
|
||||
* vector - vector number
|
||||
* type - 0 indicates raw hardware connect
|
||||
* 1 indicates RTEMS interrupt connect
|
||||
*
|
||||
* NOTE 'type' is ignored on hppa; all interrupts are owned by RTEMS
|
||||
*
|
||||
* RETURNS:
|
||||
* address of previous interrupt handler
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* All rights assigned to U.S. Government, 1994.
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
|
||||
/*
|
||||
* Install an interrupt handler in the right place
|
||||
* given its vector number from cpu/hppa.h
|
||||
* There are 2 places an interrupt can be installed
|
||||
* _ISR_Vector_table
|
||||
* bsp interrupt XXX: nyi
|
||||
*
|
||||
* We decide which based on the vector number
|
||||
*/
|
||||
|
||||
unix_isr_entry
|
||||
set_vector( /* returns old vector */
|
||||
rtems_isr_entry handler, /* isr routine */
|
||||
rtems_vector_number vector, /* vector number */
|
||||
int type /* RTEMS or RAW intr */
|
||||
)
|
||||
{
|
||||
rtems_isr_entry rtems_isr_ptr;
|
||||
proc_ptr raw_isr_ptr;
|
||||
|
||||
if ( type ) {
|
||||
rtems_interrupt_catch( handler, vector, &rtems_isr_ptr );
|
||||
return (unix_isr_entry) rtems_isr_ptr;
|
||||
} else {
|
||||
_CPU_ISR_install_vector( vector, (proc_ptr) handler, &raw_isr_ptr );
|
||||
return (unix_isr_entry) raw_isr_ptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@ exit(int status)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RTEMS_UNIX
|
||||
#if !defined(RTEMS_UNIX) && !defined(__GO32__)
|
||||
void _exit(int status)
|
||||
{
|
||||
rtems_shutdown_executive(status);
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <rtems.h>
|
||||
|
||||
#include "symbols.h"
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <rtems.h>
|
||||
|
||||
#include "symbols.h"
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "conftbl.h"
|
||||
#include "gvar.h"
|
||||
|
||||
rtems_unsigned8 Partition_area[ 1024 ];
|
||||
rtems_unsigned8 Partition_area[ 1024 ] CPU_STRUCTURE_ALIGNMENT;
|
||||
|
||||
rtems_task Init(
|
||||
rtems_task_argument argument
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/config.h>
|
||||
#include <rtems/copyrt.h>
|
||||
@@ -47,6 +45,8 @@
|
||||
#include <rtems/wkspace.h>
|
||||
#include <rtems/mp.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* These are always defined by the executive.
|
||||
*
|
||||
* #include <rtems/copyrt.h>
|
||||
|
||||
@@ -282,7 +282,7 @@ exit(int status)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RTEMS_UNIX
|
||||
#if !defined(RTEMS_UNIX) && !defined(__GO32__)
|
||||
void _exit(int status)
|
||||
{
|
||||
rtems_shutdown_executive(status);
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <rtems.h>
|
||||
|
||||
#include "symbols.h"
|
||||
|
||||
|
||||
@@ -108,7 +108,27 @@ void _CPU_Initialize(
|
||||
_CPU_Table = *cpu_table;
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
/*
|
||||
* This is unsupported.
|
||||
*/
|
||||
|
||||
_CPU_Fatal_halt( 0xdeaddead );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
|
||||
@@ -40,6 +40,15 @@
|
||||
* have to define these as appropriate.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Go32 suffers the same bug as __REGISTER_PREFIX__
|
||||
*/
|
||||
|
||||
#if __GO32__
|
||||
#undef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
@@ -67,7 +67,60 @@ void _CPU_Initialize(
|
||||
}
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
#if __GO32__
|
||||
#include <cpu.h>
|
||||
#include <go32.h>
|
||||
#include <dpmi.h>
|
||||
#endif /* __GO32__ */
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
#if __GO32__
|
||||
_go32_dpmi_seginfo handler_info;
|
||||
|
||||
*old_handler = 0; /* XXX not supported */
|
||||
|
||||
handler_info.pm_offset = new_handler;
|
||||
handler_info.pm_selector = _go32_my_cs();
|
||||
|
||||
/* install the IDT entry */
|
||||
_go32_dpmi_set_protected_mode_interrupt_vector( vector, &handler_info );
|
||||
#else
|
||||
i386_IDT_slot idt;
|
||||
unsigned32 handler;
|
||||
|
||||
*old_handler = 0; /* XXX not supported */
|
||||
|
||||
handler = (unsigned32) new_handler;
|
||||
|
||||
/* build the IDT entry */
|
||||
idt.offset_0_15 = handler & 0xffff;
|
||||
idt.segment_selector = i386_get_cs();
|
||||
idt.reserved = 0x00;
|
||||
idt.p_dpl = 0x8e; /* present, ISR */
|
||||
idt.offset_16_31 = handler >> 16;
|
||||
|
||||
/* install the IDT entry */
|
||||
i386_Install_idt(
|
||||
(unsigned32) &idt,
|
||||
_CPU_Table.interrupt_table_segment,
|
||||
(unsigned32) _CPU_Table.interrupt_table_offset + (8 * vector)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
@@ -95,27 +148,15 @@ void _CPU_ISR_install_vector(
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
i386_IDT_slot idt;
|
||||
proc_ptr ignored;
|
||||
unsigned32 unique_handler;
|
||||
|
||||
*old_handler = _ISR_Vector_table[ vector ];
|
||||
|
||||
/* calculate the unique entry point for this vector */
|
||||
unique_handler = _Interrupt_Handler_entry( vector );
|
||||
|
||||
/* build the IDT entry */
|
||||
idt.offset_0_15 = ((unsigned32) unique_handler) & 0xffff;
|
||||
idt.segment_selector = i386_get_cs();
|
||||
idt.reserved = 0x00;
|
||||
idt.p_dpl = 0x8e; /* present, ISR */
|
||||
idt.offset_16_31 = ((unsigned32) unique_handler) >> 16;
|
||||
_CPU_ISR_install_raw_handler( vector, (void *)unique_handler, &ignored );
|
||||
|
||||
/* install the IDT entry */
|
||||
i386_Install_idt(
|
||||
(unsigned32) &idt,
|
||||
_CPU_Table.interrupt_table_segment,
|
||||
(unsigned32) _CPU_Table.interrupt_table_offset + (8 * vector)
|
||||
);
|
||||
|
||||
/* "portable" part */
|
||||
*old_handler = _ISR_Vector_table[ vector ];
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,15 @@
|
||||
* have to define these as appropriate.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Go32 suffers the same bug as __REGISTER_PREFIX__
|
||||
*/
|
||||
|
||||
#if __GO32__
|
||||
#undef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
@@ -47,7 +47,41 @@ void _CPU_Initialize(
|
||||
|
||||
}
|
||||
|
||||
/* _CPU__ISR_Install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
#define _Is_vector_caching_enabled( _prcb ) \
|
||||
((_prcb)->control_tbl->icon & 0x2000)
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
i960ca_PRCB *prcb = _CPU_Table.Prcb;
|
||||
proc_ptr *cached_intr_tbl = NULL;
|
||||
|
||||
/* The i80960CA does not support vectors 0-7. The first 9 entries
|
||||
* in the Interrupt Table are used to manage pending interrupts.
|
||||
* Thus vector 8, the first valid vector number, is actually in
|
||||
* slot 9 in the table.
|
||||
*/
|
||||
|
||||
*old_handler = prcb->intr_tbl[ vector + 1 ];
|
||||
|
||||
prcb->intr_tbl[ vector + 1 ] = new_handler;
|
||||
|
||||
if ( _Is_vector_caching_enabled( prcb ) )
|
||||
if ( (vector & 0xf) == 0x2 ) /* cacheable? */
|
||||
cached_intr_tbl[ vector >> 4 ] = new_handler;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU__ISR_install_vector
|
||||
*
|
||||
* Install the RTEMS vector wrapper in the CPU's interrupt table.
|
||||
*
|
||||
@@ -60,32 +94,19 @@ void _CPU_Initialize(
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Is_vector_caching_enabled( _prcb ) \
|
||||
((_prcb)->control_tbl->icon & 0x2000)
|
||||
|
||||
void _CPU_ISR_install_vector(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
i960ca_PRCB *prcb = _CPU_Table.Prcb;
|
||||
proc_ptr *cached_intr_tbl = NULL;
|
||||
|
||||
/* The i80960CA does not support vectors 0-7. The first 9 entries
|
||||
* in the Interrupt Table are used to manage pending interrupts.
|
||||
* Thus vector 8, the first valid vector number, is actually in
|
||||
* slot 9 in the table.
|
||||
*/
|
||||
proc_ptr ignored;
|
||||
|
||||
*old_handler = _ISR_Vector_table[ vector ];
|
||||
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
_CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored );
|
||||
|
||||
prcb->intr_tbl[ vector + 1 ] = _ISR_Handler;
|
||||
if ( _Is_vector_caching_enabled( prcb ) )
|
||||
if ( (vector & 0xf) == 0x2 ) /* cacheable? */
|
||||
cached_intr_tbl[ vector >> 4 ] = _ISR_Handler;
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
|
||||
@@ -40,7 +40,29 @@ void _CPU_Initialize(
|
||||
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
proc_ptr *interrupt_table = NULL;
|
||||
|
||||
m68k_get_vbr( interrupt_table );
|
||||
|
||||
*old_handler = interrupt_table[ vector ];
|
||||
|
||||
interrupt_table[ vector ] = new_handler;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
@@ -51,15 +73,6 @@ void _CPU_Initialize(
|
||||
* old_handler - former ISR for this vector number
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_vector(
|
||||
@@ -68,14 +81,13 @@ void _CPU_ISR_install_vector(
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
proc_ptr *interrupt_table = NULL;
|
||||
|
||||
m68k_get_vbr( interrupt_table );
|
||||
proc_ptr ignored;
|
||||
|
||||
*old_handler = _ISR_Vector_table[ vector ];
|
||||
|
||||
_CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored );
|
||||
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
interrupt_table[ vector ] = _ISR_Handler;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,21 +112,21 @@ void _CPU_Install_interrupt_stack( void )
|
||||
* Returns log2(x) 0<x<256
|
||||
*/
|
||||
const unsigned char __log2table[256] = {
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -61,7 +61,26 @@ void _CPU_Initialize(
|
||||
_CPU_Table = *cpu_table;
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
/*
|
||||
* This is where we install the interrupt handler into the "raw" interrupt
|
||||
* table used by the CPU to dispatch interrupt handlers.
|
||||
*/
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
@@ -75,7 +94,6 @@ void _CPU_Initialize(
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
void _CPU_ISR_install_vector(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
@@ -90,6 +108,8 @@ void _CPU_ISR_install_vector(
|
||||
* handler for this vector number.
|
||||
*/
|
||||
|
||||
_CPU_ISR_install_raw_handler( vector, new_handler, old_handler );
|
||||
|
||||
/*
|
||||
* We put the actual user ISR address in '_ISR_vector_table'. This will
|
||||
* be used by the _ISR_Handler so the user gets control.
|
||||
|
||||
@@ -17,20 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/fatal.h>
|
||||
#include <rtems/isr.h>
|
||||
#include <rtems/wkspace.h>
|
||||
/*
|
||||
* In order to get the types and prototypes used in this file under
|
||||
* Solaris 2.3, it is necessary to pull the following magic.
|
||||
*/
|
||||
|
||||
#if defined(solaris)
|
||||
#warning "Ignore the undefining __STDC__ warning"
|
||||
#undef __STDC__
|
||||
#define __STDC__ 0
|
||||
#undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -38,22 +25,17 @@
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
extern void set_vector(proc_ptr, int, int);
|
||||
extern void _Thread_Dispatch(void);
|
||||
#ifndef SA_RESTART
|
||||
#define SA_RESTART 0
|
||||
#endif
|
||||
|
||||
extern unsigned32 _Thread_Dispatch_disable_level;
|
||||
extern unsigned32 _SYSTEM_ID;
|
||||
extern boolean _Context_Switch_necessary;
|
||||
void _CPU_Signal_initialize(void);
|
||||
void _CPU_Stray_signal(int);
|
||||
void _CPU_ISR_Handler(int);
|
||||
|
||||
|
||||
rtems_status_code signal_initialize(void);
|
||||
void Stray_signal(int);
|
||||
void signal_enable(unsigned32);
|
||||
void signal_disable(unsigned32);
|
||||
void interrupt_handler();
|
||||
|
||||
sigset_t UNIX_SIGNAL_MASK;
|
||||
jmp_buf default_context;
|
||||
sigset_t _CPU_Signal_mask;
|
||||
Context_Control _CPU_Context_Default_with_ISRs_enabled;
|
||||
Context_Control _CPU_Context_Default_with_ISRs_disabled;
|
||||
|
||||
/*
|
||||
* Which cpu are we? Used by libcpu and libbsp.
|
||||
@@ -61,6 +43,144 @@ jmp_buf default_context;
|
||||
|
||||
int cpu_number;
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_From_CPU_Init
|
||||
*/
|
||||
|
||||
void _CPU_ISR_From_CPU_Init()
|
||||
{
|
||||
unsigned32 i;
|
||||
proc_ptr old_handler;
|
||||
|
||||
|
||||
/*
|
||||
* Block all the signals except SIGTRAP for the debugger
|
||||
* and SIGABRT for fatal errors.
|
||||
*/
|
||||
|
||||
_CPU_ISR_Enable(1);
|
||||
|
||||
(void) sigfillset(&_CPU_Signal_mask);
|
||||
(void) sigdelset(&_CPU_Signal_mask, SIGTRAP);
|
||||
(void) sigdelset(&_CPU_Signal_mask, SIGABRT);
|
||||
(void) sigdelset(&_CPU_Signal_mask, SIGIOT);
|
||||
(void) sigdelset(&_CPU_Signal_mask, SIGCONT);
|
||||
|
||||
sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);
|
||||
|
||||
/*
|
||||
* Set the handler for all signals to be signal_handler
|
||||
* which will then vector out to the correct handler
|
||||
* for whichever signal actually happened. Initially
|
||||
* set the vectors to the stray signal handler.
|
||||
*/
|
||||
|
||||
for (i = 0; i < CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
|
||||
(void)_CPU_ISR_install_vector(i, _CPU_Stray_signal, &old_handler);
|
||||
|
||||
_CPU_Signal_initialize();
|
||||
}
|
||||
|
||||
void _CPU_Signal_initialize( void )
|
||||
{
|
||||
struct sigaction act;
|
||||
sigset_t mask;
|
||||
|
||||
/* mark them all active except for TraceTrap and Abort */
|
||||
|
||||
sigfillset(&mask);
|
||||
sigdelset(&mask, SIGTRAP);
|
||||
sigdelset(&mask, SIGABRT);
|
||||
sigdelset(&mask, SIGIOT);
|
||||
sigdelset(&mask, SIGCONT);
|
||||
sigprocmask(SIG_UNBLOCK, &mask, 0);
|
||||
|
||||
act.sa_handler = _CPU_ISR_Handler;
|
||||
act.sa_mask = mask;
|
||||
act.sa_flags = SA_RESTART;
|
||||
|
||||
sigaction(SIGHUP, &act, 0);
|
||||
sigaction(SIGINT, &act, 0);
|
||||
sigaction(SIGQUIT, &act, 0);
|
||||
sigaction(SIGILL, &act, 0);
|
||||
sigaction(SIGEMT, &act, 0);
|
||||
sigaction(SIGFPE, &act, 0);
|
||||
sigaction(SIGKILL, &act, 0);
|
||||
sigaction(SIGBUS, &act, 0);
|
||||
sigaction(SIGSEGV, &act, 0);
|
||||
sigaction(SIGSYS, &act, 0);
|
||||
sigaction(SIGPIPE, &act, 0);
|
||||
sigaction(SIGALRM, &act, 0);
|
||||
sigaction(SIGTERM, &act, 0);
|
||||
sigaction(SIGUSR1, &act, 0);
|
||||
sigaction(SIGUSR2, &act, 0);
|
||||
sigaction(SIGCHLD, &act, 0);
|
||||
sigaction(SIGCLD, &act, 0);
|
||||
sigaction(SIGPWR, &act, 0);
|
||||
sigaction(SIGVTALRM, &act, 0);
|
||||
sigaction(SIGPROF, &act, 0);
|
||||
sigaction(SIGIO, &act, 0);
|
||||
sigaction(SIGWINCH, &act, 0);
|
||||
sigaction(SIGSTOP, &act, 0);
|
||||
sigaction(SIGTTIN, &act, 0);
|
||||
sigaction(SIGTTOU, &act, 0);
|
||||
sigaction(SIGURG, &act, 0);
|
||||
/*
|
||||
* XXX: Really should be on HPUX.
|
||||
*/
|
||||
|
||||
#if defined(hppa1_1)
|
||||
sigaction(SIGLOST, &act, 0);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Context_From_CPU_Init
|
||||
*/
|
||||
|
||||
void _CPU_Context_From_CPU_Init()
|
||||
{
|
||||
|
||||
#if defined(hppa1_1) && defined(RTEMS_UNIXLIB)
|
||||
/*
|
||||
* HACK - set the _SYSTEM_ID to 0x20c so that setjmp/longjmp
|
||||
* will handle the full 32 floating point registers.
|
||||
*
|
||||
* NOTE: Is this a bug in HPUX9?
|
||||
*/
|
||||
|
||||
{
|
||||
extern unsigned32 _SYSTEM_ID;
|
||||
|
||||
_SYSTEM_ID = 0x20c;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* get default values to use in _CPU_Context_Initialize()
|
||||
*/
|
||||
|
||||
_CPU_ISR_Set_level( 0 );
|
||||
setjmp( _CPU_Context_Default_with_ISRs_enabled.regs );
|
||||
sigprocmask(
|
||||
SIG_SETMASK, /* ignored when second arg is NULL */
|
||||
0,
|
||||
&_CPU_Context_Default_with_ISRs_enabled.isr_level
|
||||
);
|
||||
|
||||
_CPU_ISR_Set_level( 1 );
|
||||
setjmp( _CPU_Context_Default_with_ISRs_disabled.regs );
|
||||
sigprocmask(
|
||||
SIG_SETMASK, /* ignored when second arg is NULL */
|
||||
0,
|
||||
&_CPU_Context_Default_with_ISRs_disabled.isr_level
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/* _CPU_Initialize
|
||||
*
|
||||
* This routine performs processor dependent initialization.
|
||||
@@ -76,10 +196,8 @@ void _CPU_Initialize(
|
||||
void (*thread_dispatch) /* ignored on this CPU */
|
||||
)
|
||||
{
|
||||
unsigned32 i;
|
||||
|
||||
if ( cpu_table == NULL )
|
||||
rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED );
|
||||
_CPU_Fatal_halt( RTEMS_NOT_CONFIGURED );
|
||||
|
||||
/*
|
||||
* The thread_dispatch argument is the address of the entry point
|
||||
@@ -105,52 +223,29 @@ void _CPU_Initialize(
|
||||
|
||||
_CPU_Table = *cpu_table;
|
||||
|
||||
#if defined(hppa1_1) && defined(RTEMS_UNIXLIB)
|
||||
/*
|
||||
* HACK - set the _SYSTEM_ID to 0x20c so that setjmp/longjmp
|
||||
* will handle the full 32 floating point registers.
|
||||
*
|
||||
* NOTE: Is this a bug in HPUX9?
|
||||
*/
|
||||
_CPU_ISR_From_CPU_Init();
|
||||
|
||||
_SYSTEM_ID = 0x20c;
|
||||
#endif
|
||||
_CPU_Context_From_CPU_Init();
|
||||
|
||||
/*
|
||||
* get default values to use in _CPU_Context_Initialize()
|
||||
*/
|
||||
|
||||
setjmp(default_context);
|
||||
|
||||
/*
|
||||
* Block all the signals except SIGTRAP for the debugger
|
||||
* and SIGABRT for fatal errors.
|
||||
*/
|
||||
|
||||
_CPU_ISR_Set_signal_level(1);
|
||||
|
||||
sigfillset(&UNIX_SIGNAL_MASK);
|
||||
sigdelset(&UNIX_SIGNAL_MASK, SIGTRAP);
|
||||
sigdelset(&UNIX_SIGNAL_MASK, SIGABRT);
|
||||
sigdelset(&UNIX_SIGNAL_MASK, SIGIOT);
|
||||
sigdelset(&UNIX_SIGNAL_MASK, SIGCONT);
|
||||
|
||||
sigprocmask(SIG_BLOCK, &UNIX_SIGNAL_MASK, 0);
|
||||
|
||||
/*
|
||||
* Set the handler for all signals to be signal_handler
|
||||
* which will then vector out to the correct handler
|
||||
* for whichever signal actually happened. Initially
|
||||
* set the vectors to the stray signal handler.
|
||||
*/
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
(void)set_vector(Stray_signal, i, 1);
|
||||
|
||||
signal_initialize();
|
||||
}
|
||||
|
||||
/* _CPU_ISR_install_vector
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
_CPU_Fatal_halt( 0xdeaddead );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
@@ -181,7 +276,7 @@ void _CPU_ISR_install_vector(
|
||||
|
||||
/*
|
||||
* We put the actual user ISR address in '_ISR_vector_table'. This will
|
||||
* be used by the _ISR_Handler so the user gets control.
|
||||
* be used by the _CPU_ISR_Handler so the user gets control.
|
||||
*/
|
||||
|
||||
_ISR_Vector_table[ vector ] = new_handler;
|
||||
@@ -219,6 +314,11 @@ void _CPU_Internal_threads_Idle_thread_body( void )
|
||||
pause();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Context_Initialize
|
||||
*/
|
||||
|
||||
void _CPU_Context_Initialize(
|
||||
Context_Control *_the_context,
|
||||
unsigned32 *_stack_base,
|
||||
@@ -227,6 +327,7 @@ void _CPU_Context_Initialize(
|
||||
void *_entry_point
|
||||
)
|
||||
{
|
||||
void *source;
|
||||
unsigned32 *addr;
|
||||
unsigned32 jmp_addr;
|
||||
unsigned32 _stack_low; /* lowest "stack aligned" address */
|
||||
@@ -253,7 +354,12 @@ void _CPU_Context_Initialize(
|
||||
* Slam our jmp_buf template into the context we are creating
|
||||
*/
|
||||
|
||||
memcpy(_the_context, default_context, sizeof(jmp_buf));
|
||||
if ( _new_level == 0 )
|
||||
source = _CPU_Context_Default_with_ISRs_enabled.regs;
|
||||
else
|
||||
source = _CPU_Context_Default_with_ISRs_disabled.regs;
|
||||
|
||||
memcpy(_the_context, source, sizeof(jmp_buf));
|
||||
|
||||
addr = (unsigned32 *)_the_context;
|
||||
|
||||
@@ -289,68 +395,77 @@ void _CPU_Context_Initialize(
|
||||
#error "UNKNOWN CPU!!!"
|
||||
#endif
|
||||
|
||||
if (_new_level)
|
||||
_CPU_ISR_Set_signal_level(1);
|
||||
else
|
||||
_CPU_ISR_Set_signal_level(0);
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Context_restore
|
||||
*/
|
||||
|
||||
void _CPU_Context_restore(
|
||||
Context_Control *next
|
||||
)
|
||||
{
|
||||
longjmp(next->regs, 0);
|
||||
sigprocmask( SIG_SETMASK, &next->isr_level, 0 );
|
||||
longjmp( next->regs, 0 );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Context_switch
|
||||
*/
|
||||
|
||||
void _CPU_Context_switch(
|
||||
Context_Control *current,
|
||||
Context_Control *next
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Save the current context
|
||||
* Switch levels in one operation
|
||||
*/
|
||||
|
||||
if (setjmp(current->regs) == 0) {
|
||||
sigprocmask( SIG_SETMASK, &next->isr_level, ¤t->isr_level );
|
||||
|
||||
/*
|
||||
* Switch to the new context
|
||||
*/
|
||||
|
||||
longjmp(next->regs, 0);
|
||||
if (setjmp(current->regs) == 0) { /* Save the current context */
|
||||
longjmp(next->regs, 0); /* Switch to the new context */
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Save_float_context
|
||||
*/
|
||||
|
||||
void _CPU_Save_float_context(
|
||||
Context_Control_fp *fp_context
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Restore_float_context
|
||||
*/
|
||||
|
||||
void _CPU_Restore_float_context(
|
||||
Context_Control_fp *fp_context
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
void _CPU_ISR_Set_signal_level(unsigned32 level)
|
||||
{
|
||||
if (level)
|
||||
_CPU_Disable_signal();
|
||||
else
|
||||
_CPU_Enable_signal(0);
|
||||
}
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_Disable_support
|
||||
*/
|
||||
|
||||
|
||||
unsigned32 _CPU_Disable_signal(void)
|
||||
unsigned32 _CPU_ISR_Disable_support(void)
|
||||
{
|
||||
sigset_t old_mask;
|
||||
sigset_t empty_mask;
|
||||
|
||||
sigemptyset(&empty_mask);
|
||||
sigemptyset(&old_mask);
|
||||
sigprocmask(SIG_BLOCK, &UNIX_SIGNAL_MASK, &old_mask);
|
||||
sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, &old_mask);
|
||||
|
||||
if (memcmp((char *)&empty_mask, (char *)&old_mask, sizeof(sigset_t)) != 0)
|
||||
return 1;
|
||||
@@ -358,101 +473,37 @@ unsigned32 _CPU_Disable_signal(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_Enable
|
||||
*/
|
||||
|
||||
void _CPU_Enable_signal(unsigned32 level)
|
||||
void _CPU_ISR_Enable(
|
||||
unsigned32 level
|
||||
)
|
||||
{
|
||||
if (level == 0)
|
||||
sigprocmask(SIG_UNBLOCK, &UNIX_SIGNAL_MASK, 0);
|
||||
sigprocmask(SIG_UNBLOCK, &_CPU_Signal_mask, 0);
|
||||
else
|
||||
sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Support for external and spurious interrupts on HPPA
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_Handler
|
||||
*
|
||||
* TODO:
|
||||
* delete interrupt.c etc.
|
||||
* Count interrupts
|
||||
* make sure interrupts disabled properly
|
||||
* should handler check again for more interrupts before exit?
|
||||
* How to enable interrupts from an interrupt handler?
|
||||
* Make sure there is an entry for everything in ISR_Vector_Table
|
||||
*/
|
||||
|
||||
/*
|
||||
* Init the external interrupt scheme
|
||||
* called by bsp_start()
|
||||
*/
|
||||
|
||||
rtems_status_code
|
||||
signal_initialize(void)
|
||||
{
|
||||
struct sigaction act;
|
||||
sigset_t mask;
|
||||
|
||||
/* mark them all active except for TraceTrap and Abort */
|
||||
|
||||
sigfillset(&mask);
|
||||
sigdelset(&mask, SIGTRAP);
|
||||
sigdelset(&mask, SIGABRT);
|
||||
sigdelset(&mask, SIGIOT);
|
||||
sigdelset(&mask, SIGCONT);
|
||||
sigprocmask(SIG_UNBLOCK, &mask, 0);
|
||||
|
||||
act.sa_handler = interrupt_handler;
|
||||
act.sa_mask = mask;
|
||||
#if defined(solaris)
|
||||
act.sa_flags = SA_RESTART;
|
||||
#else
|
||||
act.sa_flags = 0;
|
||||
#endif
|
||||
|
||||
sigaction(SIGHUP, &act, 0);
|
||||
sigaction(SIGINT, &act, 0);
|
||||
sigaction(SIGQUIT, &act, 0);
|
||||
sigaction(SIGILL, &act, 0);
|
||||
sigaction(SIGEMT, &act, 0);
|
||||
sigaction(SIGFPE, &act, 0);
|
||||
sigaction(SIGKILL, &act, 0);
|
||||
sigaction(SIGBUS, &act, 0);
|
||||
sigaction(SIGSEGV, &act, 0);
|
||||
sigaction(SIGSYS, &act, 0);
|
||||
sigaction(SIGPIPE, &act, 0);
|
||||
sigaction(SIGALRM, &act, 0);
|
||||
sigaction(SIGTERM, &act, 0);
|
||||
sigaction(SIGUSR1, &act, 0);
|
||||
sigaction(SIGUSR2, &act, 0);
|
||||
sigaction(SIGCHLD, &act, 0);
|
||||
sigaction(SIGCLD, &act, 0);
|
||||
sigaction(SIGPWR, &act, 0);
|
||||
sigaction(SIGVTALRM, &act, 0);
|
||||
sigaction(SIGPROF, &act, 0);
|
||||
sigaction(SIGIO, &act, 0);
|
||||
sigaction(SIGWINCH, &act, 0);
|
||||
sigaction(SIGSTOP, &act, 0);
|
||||
sigaction(SIGTTIN, &act, 0);
|
||||
sigaction(SIGTTOU, &act, 0);
|
||||
sigaction(SIGURG, &act, 0);
|
||||
/*
|
||||
* XXX: Really should be on HPUX.
|
||||
*/
|
||||
|
||||
#if defined(hppa1_1)
|
||||
sigaction(SIGLOST, &act, 0);
|
||||
#endif
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* External interrupt handler.
|
||||
* This is installed as cpu interrupt handler.
|
||||
* It vectors out to specific external interrupt handlers.
|
||||
* This is installed as a UNIX signal handler.
|
||||
* It vectors out to specific user interrupt handlers.
|
||||
*/
|
||||
|
||||
void
|
||||
interrupt_handler(int vector)
|
||||
void _CPU_ISR_Handler(int vector)
|
||||
{
|
||||
extern void _Thread_Dispatch(void);
|
||||
extern unsigned32 _Thread_Dispatch_disable_level;
|
||||
extern boolean _Context_Switch_necessary;
|
||||
|
||||
|
||||
if (_ISR_Nest_level++ == 0) {
|
||||
/* switch to interrupt stack */
|
||||
}
|
||||
@@ -461,9 +512,8 @@ interrupt_handler(int vector)
|
||||
|
||||
if (_ISR_Vector_table[vector]) {
|
||||
_ISR_Vector_table[vector](vector);
|
||||
}
|
||||
else {
|
||||
Stray_signal(vector);
|
||||
} else {
|
||||
_CPU_Stray_signal(vector);
|
||||
}
|
||||
|
||||
if (_ISR_Nest_level-- == 0) {
|
||||
@@ -474,14 +524,17 @@ interrupt_handler(int vector)
|
||||
|
||||
if (_Thread_Dispatch_disable_level == 0 &&
|
||||
(_Context_Switch_necessary || _ISR_Signals_to_thread_executing)) {
|
||||
_CPU_Enable_signal(0);
|
||||
_CPU_ISR_Enable(0);
|
||||
_Thread_Dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Stray_signal
|
||||
*/
|
||||
|
||||
void
|
||||
Stray_signal(int sig_num)
|
||||
void _CPU_Stray_signal(int sig_num)
|
||||
{
|
||||
char buffer[ 80 ];
|
||||
|
||||
@@ -499,11 +552,10 @@ Stray_signal(int sig_num)
|
||||
/*
|
||||
* If it was a "fatal" signal, then exit here
|
||||
* If app code has installed a hander for one of these, then
|
||||
* we won't call Stray_signal, so this is ok.
|
||||
* we won't call _CPU_Stray_signal, so this is ok.
|
||||
*/
|
||||
|
||||
switch (sig_num)
|
||||
{
|
||||
switch (sig_num) {
|
||||
case SIGINT:
|
||||
case SIGHUP:
|
||||
case SIGQUIT:
|
||||
@@ -517,22 +569,30 @@ Stray_signal(int sig_num)
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_Fatal_error
|
||||
*/
|
||||
|
||||
void
|
||||
_CPU_Fatal_error(unsigned32 error)
|
||||
void _CPU_Fatal_error(unsigned32 error)
|
||||
{
|
||||
setitimer(ITIMER_REAL, 0, 0);
|
||||
|
||||
_exit(error);
|
||||
}
|
||||
|
||||
int
|
||||
_CPU_ffs(unsigned32 value)
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ffs
|
||||
*/
|
||||
|
||||
int _CPU_ffs(unsigned32 value)
|
||||
{
|
||||
int output;
|
||||
extern int ffs( int );
|
||||
|
||||
output = ffs(value);
|
||||
output = output - 1;
|
||||
|
||||
return(output);
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "conftbl.h"
|
||||
#include "gvar.h"
|
||||
|
||||
rtems_unsigned8 Partition_area[ 1024 ];
|
||||
rtems_unsigned8 Partition_area[ 1024 ] CPU_STRUCTURE_ALIGNMENT;
|
||||
|
||||
rtems_task Init(
|
||||
rtems_task_argument argument
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/config.h>
|
||||
#include <rtems/copyrt.h>
|
||||
@@ -47,6 +45,8 @@
|
||||
#include <rtems/wkspace.h>
|
||||
#include <rtems/mp.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* These are always defined by the executive.
|
||||
*
|
||||
* #include <rtems/copyrt.h>
|
||||
|
||||
Reference in New Issue
Block a user