Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano

<pmcnr@camoes.rnl.ist.utl.pt> and Jose Rufino <ruf@asterix.ist.utl.pt>
of NavIST (http://pandora.ist.utl.pt/).
This commit is contained in:
Joel Sherrill
1997-12-01 22:06:48 +00:00
parent ba1a2af91e
commit 7150f00f5b
33 changed files with 4898 additions and 0 deletions

View File

@@ -352,10 +352,12 @@ int get_errno()
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
#if !defined(pc386)
void _exit(int status)
{
rtems_shutdown_executive(status);
}
#endif
#else

View File

@@ -0,0 +1,496 @@
#
# $Id$
#
Joel's Note:
This has some information which is specific to 3.6.0. Other parts of the
document should be merged with the main RTEMS READMEs. Procedures for
building a boot floppy, from a network server, and other information
specific to this BSP should remain in this file.
-----------
RTEMS PC386 BSP HOWTO:
1. Introduction
---------------
This howto tries to explain how to setup the RTEMS host
environment on a Linux based PC so that RTEMS applications can be
built for and run in a bare PC 386+.
Please note that everything in the following text using the
notation '<...>' is just an alias to something and should always be
substituted by the real thing!
2. Unarchiving
--------------
Files which have been "tarred, zipped" (i.e. .tar.gz or .tgz
extension) may be unarchived with a command similar to one of the
following:
gzcat <file>.tgz | tar xvof -
OR
gunzip -c <file>.tgz | tar xvof -
OR
gtar xzvf <file>.tgz
NOTE: gunzip -c is equivalent to gzcat, while gtar is GNU tar.
Given that the necessary utility programs are installed, any of
the above commands will extract the contents of <file>.tar.gz into the
current directory. All of the RTEMS components will be extracted into
the subdirectory rtems-3.2.0. To view the contents of a component
without restoring any files, use a command similar to the following:
gzcat <file>.tgz | tar tvf -
3. The building tools (gcc, binutils, et al.)
---------------------------------------------
The PC386 BSP was developed so that the Linux native building
tools can be used to build the RTEMS binaries.
With this in mind all you have to do is check if you have gcc +
binutils (as, ld, ar, objcopy) installed in your system (which most
probably you'll have) and check their versions. You can do so with:
- 'gcc -v' (for gcc); --> version 2.7.2.1
- 'ld -v' (for binutils). --> version 2.8.1 (with BFD linux-2.8.1.0.1)
The above mentioned versions of gcc and binutils are almost
certainly guaranteed to work (their the ones we've been using). More
recent versions should also be ok, and older versions may be ok too.
The only known problem is with older versions of binutils which
still don't have a 'binary' target in 'objcopy'. We need objcopy's
binary target to produce our final binaries (this will probably be
enhanced in the future, so we get them directly from the 'elf32-i386'
object, but for now this is how we do it). There's a possible
workaround this, using older versions of 'objdump' with the flags used
to produce the Linux kernel binary. You can investigate this in the
Linux source makefiles. This hasn't been tested.
It should be ok to build a cross-compilation environment (gcc +
binutils) that supports the 'elf32-i386' target, so that you can use a
host system other than Linux. This hasn't been tested.
You can get 'gcc' and 'binutils', both pre-compiled binaries for
Linux and sources from:
ftp://sunsite.unc.edu/pub/Linux/GCC/
binutils-2.8.1.0.1.bin.tar.gz
binutils-2.8.1.0.1.tar.gz
gcc-2.7.2.1.bin.tar.gz
as well as from several other mirrors and sites.
4. Creating aliases for gcc and the binutils
--------------------------------------------
The NEWLIB expects to be compiled by a cross-compiler. The easiest
(as far as we could find out) way to do this, short of changing the
configuration files is to make symbolic links from cross-compiler
style names (the usual names with a 'i386-elf32-rtems-' prefix) to the
real name.
You can use the following shell script to create these links
quickly. It assumes that the native Linux 'gcc' and 'binutils' reside
in their usual place (i.e. '/usr/bin/'). It also assumes that you're
running it in the directory where the aliases will reside (which we
will refer to as <elf32-tools>). You should then add <elf32-tools> to
you path. This is necessary for building the NEWLIB package.
--- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE ---
#!sh
ln -sf /usr/bin/ar i386-elf32-rtems-ar
ln -sf /usr/bin/as i386-elf32-rtems-as
ln -sf /usr/bin/cpp i386-elf32-rtems-cpp
ln -sf /usr/bin/gasp i386-elf32-rtems-gasp
ln -sf /usr/bin/gcc i386-elf32-rtems-gcc
ln -sf /usr/bin/ld i386-elf32-rtems-ld
ln -sf /usr/bin/objcopy i386-elf32-rtems-objcopy
ln -sf /usr/bin/objdump i386-elf32-rtems-objdump
ln -sf /usr/bin/ranlib i386-elf32-rtems-ranlib
--- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE ---
5. Building Newlib
------------------
The next step is to build and install the NEWLIB package. The
version we've been using and have tested is:
newlib-1.7.0-posix-rtems-3.6.0.tgz
You can get it from:
ftp://lancelot.gcs.redstone.army.mil/pub/rtems/releases/current/c/
After unarchiving the NEWLIB distribution (discussed earlier), the
NEWLIB package must be configured for the desired host and target.
This is accomplished by changing the current directory to the top
level of the NEWLIB source tree and executing the configure script
with the appropriate arguments. This step configures the NEWLIB source
for the 'i386-elf32-rtems' target configuration. The libraries and
include files will be installed at <install_point>. The --verbose
option to the ./configure script is recommended so you can check how
the configuration process is progressing. Meanwhile we must do a
little patching: 'install.sh' and 'config.sub' are missing from the
'libgloss' sub-directory. A command sequence similar to the following
should be used:
cd newlib-<NEWLIB_Version>
cp configure.sub libgloss
cp install.sh libgloss
CC=gcc CFLAGS="-O4 -g" ./configure --verbose \
--target=i386-elf32-rtems \
--prefix=<install_point>
If the configure script successfully completes, then NEWLIB may be
built. This step builds the NEWLIB package in the local directory and
does NOT install any files. The example commands specifies that gcc
should be used as the C compiler and the arguments to be used by gcc.
A command similar to the following should be used:
make CC="gcc" CFLAGS="-O4 -g"
If the build process successfully completes, then the NEWLIB
package is ready to install. A command similar to the following should
be used:
make CC="gcc" CFLAGS="-O4 -g" install
If this successfully completes, then the NEWLIB package has been
installed at <install_point>.
The documentation for the NEWLIB package is formatted using
TeX. If TeX and some supporting tools are installed on the development
system, then the following command may be used to produce the
documentation in the "DVI" format:
gmake CC="gcc" CFLAGS="-O4 -g" dvi
If while the documentation is being formatted, the message "Cross reference values unknown; you must run TeX again." is printed, then the "DVI" files generated by this command (e.g. *.dvi in every subdirectory with documentation) must be removed and the command reexecuted.
6. Modules
----------
Modules eases the process of manipulating the environment
variables required to build RTEMS. If, for whatever reason, you do not
wish to use Modules, then it will be necessary to manually modify
shell initialization files and set the required RTEMS shell variables
"manually." In this case, the Modules files are still the best place
to look for information on what variables to set and example values.
The Modules package was utilized by the RTEMS developers to make
the initialization process shell independent. The Modules files used
by the RTEMS developers to configure their user environment while
working on a particular target board are included in the
distribution. These require only simple modifications to be
"localized" for the RTEMS developer. The modifications to these ASCII
files can be made with an editor such as vi or emacs.
The Modules Homepage is:
http://www.modules.org/
You can get the Modules distribution (the latest version, which
we've been using, is '3.0pre') via the homepage or directly from:
ftp://ftp.modules.org/pub/distrib/Modules-3.0pre.tar.gz
6.1. New Modules users
----------------------
Install Modules on the development system following the
instructions in the file README in the main Modules directory. When
Modules has been installed and a user account setup to use Modules,
then proceed to the section Current Modules Users.
6.2. Current Modules users
--------------------------
If the host computer already utilizes the Modules package, then
the assistance of the system administrator responsible for the Modules
package will be required to perform the modifications described below.
The system administrator must integrate the RTEMS modules into the
existing Modules configuration. A first alternative is to copy all of
the module files provided with RTEMS into an existing modulefiles
directory. This requires that future updates of RTEMS modules will
also have to be integrated into the existing modulefiles
directory. This alternative is not recommended.
The more preferable alternative is to add the RTEMS modulefiles
directory to the MODULEPATH. This can be accomplished on an individual
user or system wide basis. For individual users, the RTEMS modules
directory can be added to the MODULEPATH of those users requiring
access to RTEMS. The default MODULEPATH is established by the Modules
initialization routine. Thus, the RTEMS modules directory must be
added to the MODULEPATH in the user's shell initialization file
(~/.profile or ~/.cshrc for example) following the Modules
initialization statement. The proper way to accomplish this is to use
the Modules use statement. For example, the following line should be
added to the user's shell initialization file:
module use <rtems_path>/modules/modulefiles
For system wide access, the RTEMS modulefiles directory can be
added to each of the shell initialization scripts in the existing
Modules package. This will require modifying the initialization of
MODULEPATH in each shell initialization file.
After integrating RTEMS modules with the existing modules, one may
proceed to the Configuring An RTEMS User section.
7. RTEMS
--------
You can get the latest free release of the C distribuition of
RTEMS (version 3.6.0), from:
ftp://lancelot.gcs.redstone.army.mil/pub/rtems/releases/current/c/
Where you'll find:
rtems-3.6.0.tgz or rtems-c_src.tgz - RTEMS sources;
rtems-3.5.1-c_doc.tgz or rtems-c_doc.tgz - RTEMS documentation;
individual_manuals/ - Sub-directory where you can get the
manuals individually.
Please note that the RTEMS documentation is slightly outdated
(most noticeably some RTEMS primitives have different protoypes) since
it refers to the previous release (3.5.1.) of RTEMS.
After unarchiving the RTEMS distribution (discussed earlier), it
is necessary to add the PC386 BSP to the source tree. This is done in
two steps.
The first step consists in unarchiving the
'rtems-3.6.0-PC386-BSP.tgz' archive over the standard rtems-3.6.0
distribution. It should be done in the same directory where
'rtems-3.6.0.tgz' was unarchived.
Next you'll need to apply the patch in
'rtems-3.6.0-PC386-BSP.diff.gz' to the RTEMS source tree. The
following command should be used:
gzip -d -c rtems-3.6.0-PC386-BSP.diff.gz | patch
also from the same directory where 'rtems-3.6.0.tgz' was unarchived.
At this stage we have RTEMS + PC386 BSP, the user environment must
be setup to build and install RTEMS.
Using this process, you'll know which files are patched and which
files are new.
7.1. Board Support Package
--------------------------
A Board Support Package (BSP) is a collection of device drivers,
initialization code, and linker scripts necessary to execute RTEMS on
a particular target board. The minimum set of device drivers for a
single processor target includes a Clock, Console I/O, and Benchmark
Timer device drivers.
The source code for the PC386 BSP can be found in the directory 'c/src/lib/libbsp/i386/pc386.
7.2. Makefile Configuration Files
---------------------------------
There are two target specific configuration files used by the
Makefile system. These configuration files specify detailed
information about the toolset, the compilation process, as well as
some general configuration information regarding the target and the
development environment. The following is a list of these
configuration files:
c/make/compilers/gcc-pc386.cfg
c/make/custom/pc386.cfg
If you're compiling to a i386+ with FPU in a standard Linux
environment, you shouldn't require any changes to these files in order
to build RTEMS (though you'll probably want to fine tune them later
on).
7.3 Creating a Customized Modules File
--------------------------------------
Files which the Modules packages may use to customize a user's
environment for building, installing, and modifying RTEMS are found in
the c/Modules/rtems directory. Each of the files in this directory
corresponds to the configuration used by the RTEMS developers for
building and installing RTEMS for a particular target board. These
files contain the Modules commands necessary to set the following
environment variables:
Variable Description
RTEMS_BSP The name of the target BSP (e.g.
mvme136 or cvme961).
RTEMS_ROOT The full path of root directory of the
RTEMS source code.
RTEMS_GNUTOOLS The full path of the root directory for
the cross-development toolset to be
used.
RTEMS_HOST The name of the operating system for
the development system.
RTEMS_LIBC_DIR The full path of the root directory for
the Standard C Library to be used.
The Modules file for the PC386 BSP is: 'c/Modules/rtems/nav-pc386'.
You MUST edit this file and set the following variables to the
correct values in your system:
- RTEMS_ROOT;
- RTEMS_GNUTOOLS (this is the directory where the links in 4.
were created);
- RTEMS_LIBC_DIR (this is the directory where the Newlib target
specific root is installed, and with reference
to 5. should be '<install_point>/i386-elf32-rtems').
7.4 Configuring an RTEMS User Using Modules
-------------------------------------------
Each user building and installing RTEMS must have their
environment configured. The user environment must have a set of
variables set in it which indicate the target BSP, host operating
system, and numerous paths.
If you'll just be using the PC386 BSP then a line of the following
type may be added to the initialization file for your shell after the
Modules initialization statement.
module load nav-pc386
Note that you must logout and login before any changes to the shell
initialization files will take effect.
If you don't wish the RTEMS environment configuration to be added
to your shell initialization file, then the "module load" statement
may be entered at the command line.
You may switch from one RTEMS configuration to another with either
of the following command sequences:
module unload <old_rtems_modulefile>
module load <new_rtems_modulefile>
OR
module switch <old_rtems_modulefile> <new_rtems_modulefile>
The command "module avail" may be used to obtain a list of the
Module files which are available to be loaded using the "module load"
command.
The command "module list" provides a list of the currently loaded
Modules.
7.5. Building RTEMS
-------------------
By default, the PC386 RTEMS BSP is installed into the directory
'c/pc386_i386'. If this is not the desired installation point, then
modify the following line in the file 'c/make/custom/pc386.cfg':
PROJECT_HOME=$(PROJECT_ROOT)/$(RTEMS_BSP)
Once the root directory of the install point has been set, the
following steps are required to build and install RTEMS (NOTE: If the
Modules files are used, the environment variable '$r' is set to point
to the top directory for the RTEMS implementation selected in the
current environment. This is the directory 'c' in the RTEMS
distribution.):
cd $r
make install
If this completes successfully, then RTEMS has been built and
installed.
8. RTEMS Tests
--------------
If you've completed the last step successfully, you'll find the
RTEMS sample and test files in the 'c/pc386_i386/tests' directory.
The 'sp*.bt' are the single processor tests and should all work
correctly. The same applies to the 'tm*.bt' which are the timing
tests.
The other sample ('*.bt') files should also work with the
exception of 'spfatal.bt' and 'stackchk.bt' (see 9.).
To load the '*.bt' files you can either run the 'diskboot.exe'
(which can be found in 'c/pc386_i386/build-tools') under DOS with a
command line like (this is just a quick and dirty loader - you'll have
to press return twice after entering it):
diskboot sp01.bt
Alternatively, if you have a PC connected to a network with a
BOOTP server and a TFTP server (this can very well be you're Linux
RTEMS host system), you can use Gero Kuhlmann's netboot loader, to
load RTEMS to a diskless PC across a network. You can get it from:
ftp://sunsite.unc.edu/pub/Linux/system/boot/netboot-0.7.2.tar.gz
Follow the instructions contained in the package to setup the
server(s) and to build a boot ROM for the client PC network card, or a
boot diskette, and the client should be able to load the '*.bt' files
from the server.
For the network loader every relocation address from 0x10200 to
0x80200 are known to work correctly. For the DOS loader, relocation
addresses 0x20200, 0x40200 and 0x80200 are known to work under DOS
5.00, DOS 6.xx and DOS 7.00. You can set the relocation address in
'c/make/compilers/gcc-pc386.cfg' by setting the value of the
'RELOCADDR' variable.
9. Important Notes
------------------
The optional stack checker extension ('stackchk') doesn't seem to
be working properly. It reports blown task stacks even if everything
seems to work properly when 'stackchk' isn't activated... This should
be properly investigated: the problem can reside with the 'PC386 BSP',
or in the interface between 'stackchk' and the BSP (maybe something
isn't being correctly initialized...). Since this doesn't seem to be a
serious BSP problem, it hasn't been dealt with, due to more prioritary
problems.
The tests which exercise the fatal error mecanisms don't work
correctly either. I've been told by Joe that 'spfatal' is outdated, and
so this really isn't surprising.
This issues may be important and should be investigated as soon as
possible.
When programming interrupt handlers take into account that the PIC
is reprogrammed and so you should use the interface functions provided
to garantee that everything works ok.

View File

@@ -0,0 +1,15 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH=@srcdir@
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/directory.cfg
# wrapup is the one that actually builds and installs the library
# from the individual .rel files built in other directories
SUB_DIRS=include tools start startup clock console timer wrapup

View File

@@ -0,0 +1,18 @@
%rename cpp old_cpp
%rename lib old_lib
%rename endfile old_endfile
%rename startfile old_startfile
%rename link old_link
*cpp:
%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded)
*lib:
%{!qrtems: %(old_lib)} %{qrtems: --start-group -lrtemsall -lc -lgcc --end-group}
*startfile:
%{!qrtems: %(old_startfile)} %{qrtems: start.o%s}
*link:
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -T linkcmds%s -e start}

View File

@@ -0,0 +1,54 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH=@srcdir@
PGM=${ARCH}/clock.rel
# C source names, if any, go here -- minus the .c
C_PIECES=ckinit rtc
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
SRCS=$(C_FILES) $(H_FILES)
OBJS=$(C_O_FILES)
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all

View File

@@ -0,0 +1,285 @@
/*-------------------------------------------------------------------------+
| ckinit.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This file contains the PC386 clock package.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| ckinit.c,v 1.4 1995/12/19 20:07:13 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <bsp.h>
#include <irq.h>
#include <rtems/libio.h>
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
#define CLOCK_IRQ 0x00 /* Clock IRQ. */
/*-------------------------------------------------------------------------+
| Macros
+--------------------------------------------------------------------------*/
#if 0
/* This was dropped in the last revision. Its a nice thing to know. */
#define TICKS_PER_SECOND() \
(1000000 / (Clock_isrs_per_tick * microseconds_per_isr))
#endif /* 0 */
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
volatile rtems_unsigned32 Clock_driver_ticks; /* Tick (interrupt) counter. */
rtems_unsigned32 Clock_isrs_per_tick; /* ISRs per tick. */
rtems_unsigned32 Clock_isrs; /* ISRs until next tick. */
/* The following variables are set by the clock driver during its init */
rtems_device_major_number rtems_clock_major = ~0;
rtems_device_minor_number rtems_clock_minor;
/*-------------------------------------------------------------------------+
| Function: clockIsr
| Description: Interrupt Service Routine for clock (08h) interruption.
| Global Variables: Clock_driver_ticks, Clock_isrs.
| Arguments: vector - standard RTEMS argument - see documentation.
| Returns: standard return value - see documentation.
+--------------------------------------------------------------------------*/
static rtems_isr
clockIsr(rtems_vector_number vector)
{
/*-------------------------------------------------------------------------+
| PLEASE NOTE: The following is directly transcribed from the go32 BSP for
| those who wish to use it with PENTIUM based machine. It needs
| to be correctly integrated with the rest of the code!!!
+--------------------------------------------------------------------------*/
#if 0 && defined(pentium) /* more accurate clock for PENTIUMs (not supported) */
{
extern long long Last_RDTSC;
__asm __volatile(".byte 0x0F, 0x31" : "=A" (Last_RDTSC));
}
#endif /* 0 && pentium */
Clock_driver_ticks++;
if ( Clock_isrs == 1 )
{
rtems_clock_tick();
Clock_isrs = Clock_isrs_per_tick;
}
else
Clock_isrs--;
PC386_ackIrq(vector - PC386_IRQ_VECTOR_BASE);
} /* clockIsr */
/*-------------------------------------------------------------------------+
| Function: Clock_exit
| Description: Clock cleanup routine at RTEMS exit. NOTE: This routine is
| not really necessary, since there will be a reset at exit.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void Clock_exit(void)
{
if (BSP_Configuration.ticks_per_timeslice)
{
/* reset timer mode to standard (BIOS) value */
outport_byte(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
outport_byte(TIMER_CNTR0, 0);
outport_byte(TIMER_CNTR0, 0);
}
} /* Clock_exit */
/*-------------------------------------------------------------------------+
| Function: Install_clock
| Description: Initialize and install clock interrupt handler.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Install_clock(rtems_isr_entry isr)
{
rtems_unsigned32 microseconds_per_isr;
rtems_status_code status;
#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;
/* External Prototypes */
extern void init_rtc(void); /* defined in 'rtc.c' */
extern long rtc_read(rtems_time_of_day *); /* defined in 'rtc.c' */
init_rtc();
if (rtc_read(&now) >= 0)
clock_set(&now);
}
#endif /* 0 */
/* 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;
}
Clock_isrs = Clock_isrs_per_tick; /* Initialize Clock_isrs */
if (BSP_Configuration.ticks_per_timeslice)
{
/* 105/88 approximates TIMER_TICK * 1e-6 */
rtems_unsigned32 count = US_TO_TICK(microseconds_per_isr);
status = PC386_installRtemsIrqHandler(CLOCK_IRQ, isr);
if (status != RTEMS_SUCCESSFUL)
{
printk("Error installing clock interrupt handler!\n");
rtems_fatal_error_occurred(status);
}
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);
} /* Install_clock */
/*-------------------------------------------------------------------------+
| Clock device driver INITIALIZE entry point.
+--------------------------------------------------------------------------+
| Initilizes the clock driver.
+--------------------------------------------------------------------------*/
rtems_device_driver
Clock_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp)
{
Install_clock(clockIsr); /* Install the interrupt handler */
/* make major/minor avail to others such as shared memory driver */
rtems_clock_major = major;
rtems_clock_minor = minor;
return RTEMS_SUCCESSFUL;
} /* Clock_initialize */
/*-------------------------------------------------------------------------+
| Console device driver CONTROL entry point
+--------------------------------------------------------------------------*/
rtems_device_driver
Clock_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp)
{
if (pargp != NULL)
{
rtems_libio_ioctl_args_t *args = pargp;
/*-------------------------------------------------------------------------+
| This is hokey, but until we get a defined interface to do this, it will
| just be this simple...
+-------------------------------------------------------------------------*/
if (args->command == rtems_build_name('I', 'S', 'R', ' '))
clockIsr(PC386_IRQ_VECTOR_BASE + CLOCK_IRQ);
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
rtems_status_code status;
status = PC386_installRtemsIrqHandler(CLOCK_IRQ, clockIsr);
if (status != RTEMS_SUCCESSFUL)
{
printk("Error installing clock interrupt handler!\n");
rtems_fatal_error_occurred(status);
}
}
}
return RTEMS_SUCCESSFUL;
} /* Clock_control */
/*-------------------------------------------------------------------------+
| PLEASE NOTE: The following is directly transcribed from the go32 BSP for
| those who wish to use it with PENTIUM based machine. It needs
| to be correctly integrated with the rest of the code!!!
+--------------------------------------------------------------------------*/
#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;
} /* Kernel_Time_ns */
#endif /* 0 && pentium */

View File

@@ -0,0 +1,224 @@
/*-------------------------------------------------------------------------+
| rtc.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This file contains the real time clock manipulation package for the
| PC386 board.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| rtc.c,v 1.4 1995/12/19 20:07:15 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <string.h>
#include <bsp.h>
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
#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 */
/*-------------------------------------------------------------------------+
| Auxiliary Functions
+--------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------+
| Function: bcd
| Description: Convert 2 digit number to its BCD representation.
| Global Variables: None.
| Arguments: i - Number to convert.
| Returns: BCD representation of number.
+--------------------------------------------------------------------------*/
static inline rtems_unsigned8
bcd(rtems_unsigned8 i)
{
return ((i / 16) * 10 + (i % 16));
} /* bcd */
#define QUICK_READ /* Quick read of the RTC: don't return number of seconds. */
#ifndef QUICK_READ
#define SECS_PER_DAY (24 * 60 * 60)
#define SECS_PER_REG_YEAR (365 * SECS_PER_DAY)
/*-------------------------------------------------------------------------+
| Function: ytos
| Description: Convert years to seconds (since 1970).
| Global Variables: None.
| Arguments: y - year to convert (1970 <= y <= 2100).
| Returns: number of seconds since 1970.
+--------------------------------------------------------------------------*/
static inline rtems_unsigned32
ytos(rtems_unsigned16 y)
{ /* v NUM LEAP YEARS v */
return ((y - 1970) * SECS_PER_REG_YEAR + (y - 1970 + 1) / 4 * SECS_PER_DAY);
} /* ytos */
/*-------------------------------------------------------------------------+
| Function: mtos
| Description: Convert months to seconds since January.
| Global Variables: None.
| Arguments: m - month to convert, leap - is this a month of a leap year.
| Returns: number of seconds since January.
+--------------------------------------------------------------------------*/
static inline rtems_unsigned32
mtos(rtems_unsigned8 m, rtems_boolean leap)
{
static rtems_unsigned16 daysMonth[] = { 0, 0, 31, 59, 90, 120, 151, 181,
212, 243, 273, 304, 334, 365 };
/* Days since beginning of year until beginning of month. */
return ((daysMonth[m] + (leap ? 1 : 0)) * SECS_PER_DAY);
} /* mtos */
#endif /* QUICK_READ */
/*-------------------------------------------------------------------------+
| Function: rtcin
| Description: Perform action on RTC and return its result.
| Global Variables: None.
| Arguments: what - what to write to RTC port (what to do).
| Returns: result received from RTC port after action performed.
+--------------------------------------------------------------------------*/
static inline rtems_unsigned8
rtcin(rtems_unsigned8 what)
{
rtems_unsigned8 r;
outport_byte(IO_RTC, what);
inport_byte (IO_RTC+1, r);
return r;
} /* rtcin */
/*-------------------------------------------------------------------------+
| Functions
+--------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------+
| Function: init_rtc
| Description: Initialize real-time clock (RTC).
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
init_rtc(void)
{
rtems_unsigned8 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 (s)
printk("RTC BIOS diagnostic error %b\n", s);
/* FIXME: This was last line's original version. How was it supposed to work?
printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS); */
} /* init_rtc */
/*-------------------------------------------------------------------------+
| Function: rtc_read
| Description: Read present time from RTC and return it.
| Global Variables: None.
| Arguments: tod - to return present time in 'rtems_time_of_day' format.
| Returns: number of seconds from 1970/01/01 corresponding to 'tod'.
+--------------------------------------------------------------------------*/
long int
rtc_read(rtems_time_of_day *tod)
{
rtems_unsigned8 sa;
rtems_unsigned32 sec = 0;
memset(tod, 0, sizeof *tod); /* zero tod structure */
/* 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;
#ifndef QUICK_READ /* Quick read of the RTC: don't return number of seconds. */
sec = ytos(tod->year);
sec += mtos(tod->month, (tod->year % 4) == 0);
sec += tod->day * SECS_PER_DAY;
sec += tod->hour * 60 * 60; /* hour */
sec += tod->minute * 60; /* minutes */
sec += tod->second; /* seconds */
#endif /* QUICK_READ */
return (long int)sec;
} /* rtc_read */

View File

@@ -0,0 +1,53 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH=@srcdir@
PGM=${ARCH}/console.rel
# C source names, if any, go here -- minus the .c
C_PIECES=console inch outch printk
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
SRCS=$(C_FILES) $(H_FILES)
OBJS=$(C_O_FILES)
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all

View File

@@ -0,0 +1,250 @@
/*-------------------------------------------------------------------------+
| console.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This file contains the PC386 console I/O package.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| console.c,v 1.4 1995/12/19 20:07:23 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <bsp.h>
#include <irq.h>
#include <rtems/libio.h>
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
#define KEYBOARD_IRQ 0x01 /* Keyboard IRQ. */
/*-------------------------------------------------------------------------+
| External Prototypes
+--------------------------------------------------------------------------*/
extern rtems_isr _IBMPC_keyboard_isr(rtems_vector_number);
/* keyboard (IRQ 0x01) Interrupt Service Routine (defined in 'inch.c') */
/*-------------------------------------------------------------------------+
| Functions
+--------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------+
| Function: console_cleanup
| Description: This routine is called at exit to clean up the console
| hardware.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
console_cleanup(void)
{
/* nothing */
} /* console_cleanup */
/*-------------------------------------------------------------------------+
| Function: is_character_ready
| Description: Check if a character is available for input, and if so
| return it.
| Global Variables: None.
| Arguments: c - character read if available, otherwise unchanged.
| Returns: TRUE if there was a character available for input,
| FALSE otherwise.
+--------------------------------------------------------------------------*/
rtems_boolean
is_character_ready(char *c)
{
return (_IBMPC_chrdy(c) ? TRUE : FALSE);
} /* is_character_ready */
/*-------------------------------------------------------------------------+
| Function: inbyte
| Description: Read a character from the console (keyboard).
| Global Variables: None.
| Arguments: None.
| Returns: Caracter read from the console.
+--------------------------------------------------------------------------*/
unsigned char
inbyte(void)
{
char c = _IBMPC_inch();
/* Echo character to screen */
_IBMPC_outch(c);
if (c == '\r')
_IBMPC_outch('\n'); /* CR = CR + LF */
return c;
} /* inbyte */
/*-------------------------------------------------------------------------+
| Function: outbyte
| Description: Write a character to the console (display).
| Global Variables: None.
| Arguments: Character to be written.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
outbyte(char c)
{
_IBMPC_outch(c);
} /* outbyte */
/*-------------------------------------------------------------------------+
| Console device driver INITIALIZE entry point.
+--------------------------------------------------------------------------+
| Initilizes the I/O console (keyboard + VGA display) driver.
+--------------------------------------------------------------------------*/
rtems_device_driver
console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
/* Initialize video */
_IBMPC_initVideo();
/* Install keyboard interrupt handler */
status = PC386_installRtemsIrqHandler(KEYBOARD_IRQ, _IBMPC_keyboard_isr);
if (status != RTEMS_SUCCESSFUL)
{
printk("Error installing keyboard interrupt handler!\n");
rtems_fatal_error_occurred(status);
}
status =
rtems_io_register_name("/dev/console", major, (rtems_device_minor_number)0);
if (status != RTEMS_SUCCESSFUL)
{
printk("Error registering console device!\n");
rtems_fatal_error_occurred(status);
}
atexit(console_cleanup);
return RTEMS_SUCCESSFUL;
} /* console_initialize */
/*-------------------------------------------------------------------------+
| Console device driver OPEN entry point
+--------------------------------------------------------------------------*/
rtems_device_driver
console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return RTEMS_SUCCESSFUL;
} /* console_open */
/*-------------------------------------------------------------------------+
| Console device driver CLOSE entry point
+--------------------------------------------------------------------------*/
rtems_device_driver
console_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return RTEMS_SUCCESSFUL;
} /* console_close */
/*-------------------------------------------------------------------------+
| Console device driver READ entry point.
+--------------------------------------------------------------------------+
| Read characters from the I/O console. We only have stdin.
+--------------------------------------------------------------------------*/
rtems_device_driver
console_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
char *buffer = rw_args->buffer;
int count, maximum = rw_args->count;
for (count = 0; count < maximum; count++)
{
buffer[count] = inbyte();
if (buffer[count] == '\n' || buffer[count] == '\r')
{
/* What if this goes past the end of the buffer? We're hosed. [bhc] */
buffer[count++] = '\n';
buffer[count] = '\0';
break;
}
}
rw_args->bytes_moved = count;
return ((count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED);
} /* console_read */
/*-------------------------------------------------------------------------+
| Console device driver WRITE entry point.
+--------------------------------------------------------------------------+
| Write characters to the I/O console. Stderr and stdout are the same.
+--------------------------------------------------------------------------*/
rtems_device_driver
console_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
char *buffer = rw_args->buffer;
int count, maximum = rw_args->count;
for (count = 0; count < maximum; count++)
{
outbyte(buffer[count]);
if (buffer[count] == '\n')
outbyte('\r'); /* LF = LF + CR */
}
rw_args->bytes_moved = maximum;
return RTEMS_SUCCESSFUL;
} /* console_write */
/*-------------------------------------------------------------------------+
| Console device driver CONTROL entry point
+--------------------------------------------------------------------------*/
rtems_device_driver
console_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return RTEMS_SUCCESSFUL;
} /* console_control */

View File

@@ -0,0 +1,260 @@
/*-------------------------------------------------------------------------+
| inch.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| inch.c,v 1.3 1995/12/19 20:07:25 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <bsp.h>
#include <irq.h>
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
#define KBD_CTL 0x61 /* -------------------------------- */
#define KBD_DATA 0x60 /* Ports for PC keyboard controller */
#define KBD_STATUS 0x64 /* -------------------------------- */
#define KBD_BUF_SIZE 256
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
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
}; /* Keyboard scancode -> character map with no modifiers. */
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
}; /* Keyboard scancode -> character map with SHIFT key modifier. */
static char kbd_buffer[KBD_BUF_SIZE];
static rtems_unsigned16 kbd_first = 0;
static rtems_unsigned16 kbd_last = 0;
/*-------------------------------------------------------------------------+
| Function: _IBMPC_scankey
| Description: This function can be called during a poll for input, or by
| an ISR. Basically any time you want to process a keypress.
| Global Variables: key_map, shift_map.
| Arguments: outChar - character read in case of a valid reading,
| otherwise unchanged.
| Returns: TRUE in case a valid character has been read,
| FALSE otherwise.
+--------------------------------------------------------------------------*/
rtems_boolean
_IBMPC_scankey(char *outChar)
{
unsigned char inChar;
static int alt_pressed = 0;
static int ctrl_pressed = 0;
static int shift_pressed = 0;
static int caps_pressed = 0;
static int extended = 0;
*outChar = NULL; /* default value if we return FALSE */
/* Read keyboard controller, toggle enable */
inport_byte(KBD_CTL, inChar);
outport_byte(KBD_CTL, inChar & ~0x80);
outport_byte(KBD_CTL, inChar | 0x80);
outport_byte(KBD_CTL, inChar & ~0x80);
/* See if it has data */
inport_byte(KBD_STATUS, inChar);
if ((inChar & 0x01) == 0)
return FALSE;
/* Read the data. Handle nonsense with shift, control, etc. */
inport_byte(KBD_DATA, inChar);
if (extended)
extended--;
switch (inChar)
{
case 0xe0:
extended = 2;
return FALSE;
break;
case 0x38:
alt_pressed = 1;
return FALSE;
break;
case 0xb8:
alt_pressed = 0;
return FALSE;
break;
case 0x1d:
ctrl_pressed = 1;
return FALSE;
break;
case 0x9d:
ctrl_pressed = 0;
return FALSE;
break;
case 0x2a:
if (extended)
return FALSE;
case 0x36:
shift_pressed = 1;
return FALSE;
break;
case 0xaa:
if (extended)
return FALSE;
case 0xb6:
shift_pressed = 0;
return FALSE;
break;
case 0x3a:
caps_pressed = 1;
return FALSE;
break;
case 0xba:
caps_pressed = 0;
return FALSE;
break;
case 0x53:
if (ctrl_pressed && alt_pressed)
rtemsReboot(); /* ctrl+alt+del -> reboot */
break;
/*
* Ignore unrecognized keys--usually arrow and such
*/
default:
if ((inChar & 0x80) || (inChar > 0x39))
/* High-bit on means key is being released, not pressed */
return FALSE;
break;
} /* switch */
/* Strip high bit, look up in our map */
inChar &= 0x7f;
if (ctrl_pressed)
{
*outChar = key_map[inChar];
*outChar &= 037;
}
else
{
*outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
if (caps_pressed)
{
if (*outChar >= 'A' && *outChar <= 'Z')
*outChar += 'a' - 'A';
else if (*outChar >= 'a' && *outChar <= 'z')
*outChar -= 'a' - 'A';
}
}
return TRUE;
} /* _IBMPC_scankey */
/*-------------------------------------------------------------------------+
| Function: _IBMPC_keyboard_isr
| Description: Interrupt Service Routine for keyboard (0x01) IRQ.
| Global Variables: kbd_buffer, kbd_first, kbd_last.
| Arguments: vector - standard RTEMS argument - see documentation.
| Returns: standard return value - see documentation.
+--------------------------------------------------------------------------*/
rtems_isr
_IBMPC_keyboard_isr(rtems_vector_number vector)
{
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;
}
PC386_ackIrq(vector - PC386_IRQ_VECTOR_BASE); /* Mark interrupt as handled. */
} /* _IBMPC_keyboard_isr */
/*-------------------------------------------------------------------------+
| Function: _IBMPC_chrdy
| Description: Check keyboard ISR buffer and return character if not empty.
| Global Variables: kbd_buffer, kbd_first, kbd_last.
| Arguments: c - character read if keyboard buffer not empty, otherwise
| unchanged.
| Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
+--------------------------------------------------------------------------*/
rtems_boolean
_IBMPC_chrdy(char *c)
{
/* Check buffer our ISR builds */
if (kbd_first != kbd_last)
{
*c = kbd_buffer[kbd_first];
kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
return TRUE;
}
else
return FALSE;
} /* _IBMPC_chrdy */
/*-------------------------------------------------------------------------+
| Function: _IBMPC_inch
| Description: Poll keyboard until a character is ready and return it.
| Global Variables: None.
| Arguments: None.
| Returns: character read from keyboard.
+--------------------------------------------------------------------------*/
char
_IBMPC_inch(void)
{
char c;
while (!_IBMPC_chrdy(&c))
continue;
return c;
} /* _IBMPC_inch */

View File

@@ -0,0 +1,284 @@
/*-------------------------------------------------------------------------+
| outch.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| outch.c,v 1.4 1995/12/19 20:07:27 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <bsp.h>
#include <stdlib.h>
#include <string.h>
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
#define DISPLAY_CELL_COUNT (MAX_ROW * MAX_COL)
/* Number of display cells. */
#define TABSIZE 4 /* Number of spaces for TAB (\t) char. */
#define WHITE 0x0700 /* White on Black background colour. */
#define BLANK (WHITE | ' ') /* Blank character. */
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
static rtems_unsigned16 *videoRam = TVRAM;
/* Physical address of start of video text memory. */
static rtems_unsigned16 *videoRamPtr = TVRAM;
/* Pointer for current output position in display. */
static rtems_unsigned8 videoRows = MAX_ROW; /* Number of rows in display. */
static rtems_unsigned8 videoCols = MAX_COL; /* Number of columns in display. */
static rtems_unsigned8 cursRow = 0; /* Current cursor row. */
static rtems_unsigned8 cursCol = 0; /* Current cursor column. */
/*-------------------------------------------------------------------------+
| Function: setHardwareCursorPos
| Description: Set hardware video cursor at given offset into video RAM.
| Global Variables: None.
| Arguments: videoCursor - Offset into video memory.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static inline void
setHardwareCursorPos(rtems_unsigned16 videoCursor)
{
outport_byte(GDC_REG_PORT, 0xe);
outport_byte(GDC_VAL_PORT, (videoCursor >> 8) & 0xff);
outport_byte(GDC_REG_PORT, 0xf);
outport_byte(GDC_VAL_PORT, videoCursor & 0xff);
} /* setHardwareCursorPos */
/*-------------------------------------------------------------------------+
| Function: updateVideoRamPtr
| Description: Updates value of global variable "videoRamPtr" based on
| current window's cursor position.
| Global Variables: videoRamPtr, cursRow, cursCol.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static inline void
updateVideoRamPtr(void)
{
videoRamPtr = videoRam + cursRow * videoCols + cursCol;
} /* updateVideoRamPtr */
/*-------------------------------------------------------------------------+
| Function: scrollUp
| Description: Scrolls display up n lines.
| Global Variables: None.
| Arguments: lines - number of lines to scroll.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static void
scrollUp(rtems_unsigned8 lines)
{
rtems_unsigned16 blankCount;
/* Number of blank display cells on bottom of window. */
rtems_unsigned16 *ptrDst, *ptrSrc;
/* Source and destination pointers for memory copy operations. */
if (lines < videoRows) /* Move window's contents up. */
{
rtems_unsigned16 nonBlankCount;
/* Number of non-blank cells on upper part of display (total - blank). */
blankCount = lines * videoCols;
nonBlankCount = DISPLAY_CELL_COUNT - blankCount;
ptrSrc = videoRam + blankCount;
ptrDst = videoRam;
while(nonBlankCount--)
*ptrDst++ = *ptrSrc++;
}
else /* Clear the whole display. */
{
blankCount = DISPLAY_CELL_COUNT;
ptrDst = videoRam;
}
/* Fill bottom with blanks. */
while (blankCount-- > 0)
*ptrDst++ = BLANK;
} /* scrollUp */
/*-------------------------------------------------------------------------+
| Function: printCHAR
| Description: Print printable character to display.
| Global Variables: videoRamPtr, cursRow, cursCol.
| Arguments: c - character to write to display.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static void
printCHAR(char c)
{
*videoRamPtr++ = c | WHITE;
cursCol++;
if (cursCol == videoCols)
{
cursCol = 0;
cursRow++;
if (cursRow == videoRows)
{
cursRow--;
scrollUp(1);
videoRamPtr -= videoCols;
}
}
} /* printCHAR */
/*-------------------------------------------------------------------------+
| Function: printBS
| Description: Print BS (BackSpace - '\b') character to display.
| Global Variables: videoRamPtr, cursRow, cursCol.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static inline void
printBS(void)
{
/* Move cursor back one cell. */
if (cursCol > 0)
cursCol--;
else if (cursRow > 0)
{
cursRow--;
cursCol = videoCols - 1;
}
else
return;
/* Write a whitespace. */
*(--videoRamPtr) = BLANK;
} /* printBS */
/*-------------------------------------------------------------------------+
| Function: printHT
| Description: Print HT (Horizontal Tab - '\t') character to display.
| Global Variables: cursCol.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static inline void
printHT(void)
{
do
printCHAR(' ');
while (cursCol % TABSIZE);
} /* printHT */
/*-------------------------------------------------------------------------+
| Function: printLF
| Description: Print LF (Line Feed - '\n') character to display.
| Global Variables: cursRow.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static inline void
printLF(void)
{
cursRow++;
if (cursRow == videoRows)
{
cursRow--;
scrollUp(1);
}
updateVideoRamPtr();
} /* printLF */
/*-------------------------------------------------------------------------+
| Function: printCR
| Description: Print CR (Carriage Return - '\r') to display.
| Global Variables: cursCol.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static inline void
printCR(void)
{
cursCol = 0;
updateVideoRamPtr();
} /* printCR */
/*-------------------------------------------------------------------------+
| Function: consPutc
| Description: Print a character to display at current position.
| Global Variables: videoRamPtr, videoRam.
| Arguments: c - character to write to display.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static void
consPutc(char c)
{
switch (c)
{
case '\b': printBS(); break;
case '\t': printHT(); break;
case '\n': printLF(); break;
case '\r': printCR(); break;
default: printCHAR(c); break;
} /* switch */
setHardwareCursorPos(videoRamPtr - videoRam);
/* At current offset into videoRam */
} /* consPutc */
/*-------------------------------------------------------------------------+
| Function: _IBMPC_outch
| Description: Higher level (console) interface to consPutc.
| Global Variables: None.
| Arguments: c - character to write to console.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
_IBMPC_outch(char c)
{
consPutc(c);
} /* _IBMPC_outch */
/*-------------------------------------------------------------------------+
| Function: _IBMPC_initVideo
| Description: Video system initialization. Hook for any early setup.
| Global Variables: videoRows.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
_IBMPC_initVideo(void)
{
scrollUp(videoRows); /* Clear entire screen */
setHardwareCursorPos(0); /* Cursor at upper left corner */
} /* _IBMPC_initVideo */

View File

@@ -0,0 +1,32 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH=@srcdir@
H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h $(srcdir)/irq.h
#
# Equate files are for including from assembly preprocessed by
# gm4 or gasp. No examples are provided except for those for
# other CPUs. The best way to generate them would be to
# provide a program which generates the constants used based
# on the C equivalents.
#
EQ_FILES =
SRCS=$(H_FILES) $(EQ_FILES)
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
all: $(SRCS)
$(INSTALL) -m 444 $(H_FILES) $(PROJECT_INCLUDE)
$(INSTALL) -m 444 $(EQ_FILES) $(PROJECT_INCLUDE)

View File

@@ -0,0 +1,192 @@
/*-------------------------------------------------------------------------+
| bsp.h v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This include file contains definitions related to the PC386 BSP.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| bsp.h,v 1.5 1995/12/19 20:07:30 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#ifndef __BSP_H_
#define __BSP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#include <iosupp.h>
#include <console.h>
#include <clockdrv.h>
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
#define BSP_LIBIO_MAX_FDS 20 /* Number of libio files we want. */
/*-------------------------------------------------------------------------+
| Memory related constants.
+--------------------------------------------------------------------------*/
#ifdef RTEMS_SMALL_MEMORY /* We only have low (640K) memory. */
#define RAM_START 0x00000
#define RAM_END 0xA0000
#else /* We have at least 2048K of memory. */
#define RAM_START 0x100000
#define RAM_END 0x200000
#endif /* RTEMS_SMALL_MEMORY */
#define HEAP_SIZE 64 /* Size of libc Heap (used for malloc et al) in KBytes. */
/*-------------------------------------------------------------------------+
| Video (console) related constants.
+--------------------------------------------------------------------------*/
#define COLOUR 1 /* Assume colour console */
#if COLOUR
# define GDC_REG_PORT 0x3D4
# define GDC_VAL_PORT 0x3D5
# define TVRAM ((rtems_unsigned16 *)0xB8000)
#else
# define GDC_REG_PORT 0x3B4
# define GDC_VAL_PORT 0x3B5
# define TVRAM ((rtems_unsigned16 *)0xB0000)
#endif /* COLOUR */
/* Number of Video Lines & Columns */
#define MAX_COL 80
#ifdef RTEMS_VIDEO_80x50
#define MAX_ROW 50
#else
#define MAX_ROW 25
#endif /* RTEMS_VIDEO_80x50 */
/*-------------------------------------------------------------------------+
| Constants relating to the 8254 (or 8253) programmable interval timers.
+--------------------------------------------------------------------------*/
#define IO_TIMER1 0x40
/* Port address of the control port and timer channels */
#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 */
#define TIMER_TICK 1193182 /* The internal tick rate in ticks per second */
/*-------------------------------------------------------------------------+
| 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 */
/*-------------------------------------------------------------------------+
| Macros
+--------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------+
| Define the interrupt mechanism for Time Test 27.
| NOTE: Use a software interrupt for the i386 family.
+--------------------------------------------------------------------------*/
#define MUST_WAIT_FOR_INTERRUPT 0
#define Install_tm27_vector(handler) \
{ \
rtems_isr_entry dummy; \
rtems_interrupt_catch(handler, 0x90, &dummy); \
}
#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)); \
}
/*-------------------------------------------------------------------------+
| Convert microseconds to ticks and ticks to microseconds.
+--------------------------------------------------------------------------*/
#define US_TO_TICK(us) (((us)*105+44)/88)
#define TICK_TO_US(tk) (((tk)*88+52)/105)
/*-------------------------------------------------------------------------+
| External Variables.
+--------------------------------------------------------------------------*/
extern i386_IDT_slot Interrupt_descriptor_table[256];
extern i386_GDT_slot Global_descriptor_table [8192];
extern rtems_configuration_table BSP_Configuration;
/* User provided BSP configuration table. */
extern rtems_unsigned32 rtemsFreeMemStart;
/* Address of start of free memory - should be used when creating new
partitions or regions and updated afterwards. */
/*-------------------------------------------------------------------------+
| Function Prototypes.
+--------------------------------------------------------------------------*/
void _IBMPC_initVideo(void); /* from 'outch.c' */
void _IBMPC_outch (char); /* from 'outch.c' */
rtems_boolean _IBMPC_chrdy (char *); /* from 'inch.c' */
char _IBMPC_inch (void); /* from 'inch.c' */
void printk(char *fmt, ...); /* from 'printk.c' */
void rtemsReboot(void); /* from 'exit.c' */
#ifdef __cplusplus
}
#endif
#endif /* __BSP_H_ */
/* end of include file */

View 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.
*
* coverhd.h,v 1.2 1995/12/19 20:07:32 joel Exp
*/
#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 */

View File

@@ -0,0 +1,56 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH=@srcdir@
PGMS=${ARCH}/start.o
# C source names, if any, go here -- minus the .c
C_PIECES=
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .s
S_PIECES=start
S_FILES=$(S_PIECES:%=%.s)
S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
SRCS=$(C_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(S_O_FILES)
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
all: ${ARCH} $(SRCS) $(OBJS) $(PGM)
$(INSTALL_VARIANT) -m 555 ${PGMS} ${PROJECT_RELEASE}/lib
# Install the program(s), appending _g or _p as appropriate.
# for include files, just use $(INSTALL)

View File

@@ -0,0 +1,416 @@
/*-------------------------------------------------------------------------+
| start.s v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This file contains the entry point for the application.
| The name of this entry point is compiler dependent.
| It jumps to the BSP which is responsible for performing all initialization.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on an earlier generation RTEMS i386 start.s and the
| following copyright applies:
|
| **************************************************************************
| * COPYRIGHT (c) 1989-1997.
| * On-Line Applications Research Corporation (OAR).
| * Copyright assigned to U.S. Government, 1994.
| *
| * The license and distribution terms for this file may be
| * found in the file LICENSE in this distribution or at
| * http://www.OARcorp.com/rtems/license.html.
| **************************************************************************
|
| Also based on (from the Linux source tree):
| video.S - Copyright (C) 1995, 1996 Martin Mares <mj@k332.feld.cvut.cz>
+--------------------------------------------------------------------------*/
#include "asm.h"
/*----------------------------------------------------------------------------+
| Constants
+----------------------------------------------------------------------------*/
#ifdef pc386
.set PROT_CODE_SEG, 0x08 # offset of code segment descriptor into GDT
.set CR0_PE, 1 # protected mode flag on CR0 register
#endif /* pc386 */
/*----------------------------------------------------------------------------+
| A Descriptor table register has the following format:
+----------------------------------------------------------------------------*/
.set DTR_LIMIT, 0 # offset of two byte limit
.set DTR_BASE, 2 # offset of four byte base address
.set DTR_SIZE, 6 # size of DTR register
/*----------------------------------------------------------------------------+
| CODE section
+----------------------------------------------------------------------------*/
BEGIN_CODE
PUBLIC (start) # GNU default entry point
EXTERN (main)
EXTERN (load_segments)
EXTERN (exit)
SYM (start):
/*----------------------------------------------------------------------------+
| Switch VGA video to 80 lines x 50 columns mode. Has to be done before turning
| protected mode on since it uses BIOS int 10h (video) services.
+----------------------------------------------------------------------------*/
#if defined(pc386) && defined(RTEMS_VIDEO_80x50)
.code16
movw $0x0003, ax # forced set
int $0x10
movw $0x1112, ax # use 8x8 font
xorb %bl, %bl
int $0x10
movw $0x1201, ax # turn off cursor emulation
movb $0x34, %bl
int $0x10
movb $0x01, ah # define cursor (scan lines 0 to 7)
movw $0x0007, cx
int $0x10
.code32
#endif /* pc386 && RTEMS_VIDEO_80x50 */
nop
cli # DISABLE INTERRUPTS!!!
/*----------------------------------------------------------------------------+
| Bare PC machines boot in real mode! We have to turn protected mode on.
+----------------------------------------------------------------------------*/
#ifdef pc386
data16
movl $ SYM(gdtptr), eax
data16
andl $0x0000ffff, eax # get offset into segment
addr16
lgdt cs:(eax) # load Global Descriptor Table
data16
movl $ SYM(idtptr), eax
data16
andl $0x0000ffff, eax # get offset into segment
addr16
lidt cs:(eax) # load Interrupt Descriptor Table
movl %cr0, eax
data16
orl $CR0_PE, eax
movl eax, %cr0 # turn on protected mode
data16
ljmp $PROT_CODE_SEG, $ SYM(next) # flush prefetch queue
SYM(next):
#endif /* pc386 */
/*----------------------------------------------------------------------------+
| Load the segment registers (this is done by the board's BSP) and perform any
| other board specific initialization procedures.
|
| NOTE: Upon return, gs will contain the segment descriptor for a segment which
| maps directly to all of physical memory.
+----------------------------------------------------------------------------*/
jmp SYM (_load_segments) # load board dependent segments
/*----------------------------------------------------------------------------+
| Set up the stack
+----------------------------------------------------------------------------*/
PUBLIC (_establish_stack)
SYM (_establish_stack):
movl $_end, eax # eax = end of bss/start of heap
addl $heap_size, eax # eax = end of heap
movl eax, stack_start # Save for brk() routine
addl $stack_size, eax # make room for stack
andl $0xffffffc0, eax # align it on 16 byte boundary
movl eax, esp # set stack pointer
movl eax, ebp # set base pointer
/*----------------------------------------------------------------------------+
| Zero out the BSS segment
+----------------------------------------------------------------------------*/
SYM (zero_bss):
cld # make direction flag count up
movl $ SYM (_end), ecx # find end of .bss
movl $ SYM (_bss_start), edi # edi = beginning of .bss
subl edi, ecx # ecx = size of .bss in bytes
shll ecx # size of .bss in longs
xorl eax, eax # value to clear out memory
repne # while ecx != 0
stosl # clear a long in the bss
/*---------------------------------------------------------------------+
| Copy the Global Descriptor Table to our space
+---------------------------------------------------------------------*/
sgdt SYM (_Original_GDTR) # save original GDT
movzwl SYM (_Original_GDTR)+DTR_LIMIT, ecx # size of GDT in bytes;
# limit is 8192 entries * 8 bytes per
/*---------------------------------------------------------------------+
| make ds:esi point to the original GDT
+---------------------------------------------------------------------*/
movl SYM (_Original_GDTR)+DTR_BASE, esi
push ds # save ds
movw gs, ax
movw ax, ds
/*---------------------------------------------------------------------+
| make es:edi point to the new (our copy) GDT
+---------------------------------------------------------------------*/
movl $ SYM (_Global_descriptor_table), edi
rep
movsb # copy the GDT (ds:esi -> es:edi)
pop ds # restore ds
/*---------------------------------------------------------------------+
| Build and load new contents of GDTR
+---------------------------------------------------------------------*/
movw SYM (_Original_GDTR)+DTR_LIMIT, ecx # set new limit
movw cx, SYM (_New_GDTR)+DTR_LIMIT
push $ SYM (_Global_descriptor_table)
push es
call SYM (i386_Logical_to_physical)
addl $6, esp
movl eax, SYM (_New_GDTR)+DTR_BASE # set new base
cmpb $0, SYM (_Do_Load_GDT) # Should the new GDT be loaded?
je SYM (no_gdt_load) # NO, then branch
lgdt SYM (_New_GDTR) # load the new GDT
SYM (no_gdt_load):
/*---------------------------------------------------------------------+
| Copy the Interrupt Descriptor Table to our space
+---------------------------------------------------------------------*/
sidt SYM (_Original_IDTR) # save original IDT
movzwl SYM (_Original_IDTR)+DTR_LIMIT, ecx # size of IDT in bytes;
#limit is 256 entries * 8 bytes per
/*---------------------------------------------------------------------+
| make ds:esi point to the original IDT
+---------------------------------------------------------------------*/
movl SYM (_Original_IDTR)+DTR_BASE, esi
push ds # save ds
movw gs, ax
movw ax, ds
/*---------------------------------------------------------------------+
| make es:edi point to the new (our copy) IDT
+---------------------------------------------------------------------*/
movl $ SYM (Interrupt_descriptor_table), edi
rep
movsb # copy the IDT (ds:esi -> es:edi)
pop ds # restore ds
/*---------------------------------------------------------------------+
| Build and load new contents of IDTR
+---------------------------------------------------------------------*/
movw SYM (_Original_IDTR+DTR_LIMIT), ecx # set new limit
movw cx, SYM (_New_IDTR)+DTR_LIMIT
push $ SYM (Interrupt_descriptor_table)
push es
call SYM (i386_Logical_to_physical)
addl $6, esp
movl eax, SYM (_New_IDTR)+DTR_BASE # set new base
cmpb $0, SYM (_Do_Load_IDT) # Should the new IDT be loaded?
je SYM (no_idt_load) # NO, then branch
lidt SYM (_New_IDTR) # load the new IDT
SYM (no_idt_load):
/*---------------------------------------------------------------------+
| Initialize the i387.
|
| Using the NO WAIT form of the instruction insures that if it is not
| present the board will not lock up or get an exception.
+---------------------------------------------------------------------*/
fninit # MUST USE NO-WAIT FORM
/*---------------------------------------------------------------------+
| Transfer control to User's Board Support Package
+---------------------------------------------------------------------*/
pushl $0 # environp
pushl $0 # argv
pushl $0 # argc
call SYM (main)
addl $12, esp
/*---------------------------------------------------------------------+
| Clean up
+---------------------------------------------------------------------*/
EXTERN (return_to_monitor)
PUBLIC (Bsp_cleanup)
SYM (Bsp_cleanup):
cmpb $0, SYM (_Do_Load_IDT) # Was the new IDT loaded?
je SYM (no_idt_restore) # NO, then branch
lidt SYM (_Original_IDTR) # restore the new IDT
SYM (no_idt_restore):
cmpb $0, SYM (_Do_Load_GDT) # Was the new GDT loaded?
je SYM (no_gdt_restore) # NO, then branch
lgdt SYM (_Original_GDTR) # restore the new GDT
SYM (no_gdt_restore):
jmp SYM (_return_to_monitor)
END_CODE
/*----------------------------------------------------------------------------+
| DATA section
+----------------------------------------------------------------------------*/
BEGIN_DATA
#ifdef pc386
/**************************
* GLOBAL DESCRIPTOR TABLE *
**************************/
.align 4
SYM(gdtptr):
/* we use the NULL descriptor to store the GDT pointer - a trick quite
nifty due to: Robert Collins (rcollins@x86.org) */
.word gdtlen - 1
.long gdtptr
.word 0x0000
/* code segment */
.word 0xffff, 0
.byte 0, 0x9f, 0xcf, 0
/* data segment */
.word 0xffff, 0
.byte 0, 0x93, 0xcf, 0
.set gdtlen, . - gdtptr # length of GDT
/*************************************
* INTERRUPT DESCRIPTOR TABLE POINTER *
*************************************/
.align 4
SYM(idtptr):
.word 0x07ff # limit at maximum (allows all 256 interrupts)
.word 0, 0 # base at 0
#endif /* pc386 */
EXTERN (Do_Load_IDT) # defined in the BSP
EXTERN (Do_Load_GDT) # defined in the BSP
.align 2
PUBLIC (start_frame)
SYM (start_frame):
.long 0
PUBLIC (stack_start)
SYM (stack_start):
.long 0
END_DATA
/*----------------------------------------------------------------------------+
| BSS section
+----------------------------------------------------------------------------*/
BEGIN_BSS
PUBLIC (heap_size)
.set heap_size, 0x2000
PUBLIC (stack_size)
.set stack_size, 0x1000
PUBLIC (Interrupt_descriptor_table)
SYM (Interrupt_descriptor_table):
.space (256 * 8) # reserve space for all 256 interrupts
PUBLIC (_Original_IDTR)
SYM (_Original_IDTR):
.space DTR_SIZE
PUBLIC (_New_IDTR)
SYM (_New_IDTR):
.space DTR_SIZE
PUBLIC (_Global_descriptor_table)
SYM (_Global_descriptor_table):
#ifdef pc386
.space (3 * 8) # the PC386 bsp only needs 3 segment descriptors:
#else # NULL, CODE and DATA
.space (8192 * 8)
#endif /* pc386 */
PUBLIC (_Original_GDTR)
SYM (_Original_GDTR):
.space DTR_SIZE
PUBLIC (_New_GDTR)
SYM (_New_GDTR):
.space DTR_SIZE
PUBLIC (_Physical_base_of_ds)
SYM (_Physical_base_of_ds):
.space 4
PUBLIC (_Physical_base_of_cs)
SYM (_Physical_base_of_cs):
.space 4
END_BSS
END

View File

@@ -0,0 +1,58 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH=@srcdir@:@srcdir@/../../../shared
PGM=${ARCH}/startup.rel
# C source names, if any, go here -- minus the .c
C_PIECES=bspstart exit irq sbrk
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .s
S_PIECES=ldsegs
S_FILES=$(S_PIECES:%=%.s)
S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
SRCS=$(srcdir)/linkcmds $(C_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(S_O_FILES)
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
$(INSTALL) $(srcdir)/linkcmds ${PROJECT_RELEASE}/lib
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile

View File

@@ -0,0 +1,241 @@
/*-------------------------------------------------------------------------+
| bspstart.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This file contains the PC386 BSP startup package. It includes application,
| board, and monitor specific initialization and configuration. The generic CPU
| dependent initialization has been performed before this routine is invoked.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| bspstart.c,v 1.8 1996/05/28 13:12:40 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <fcntl.h>
#include <bsp.h>
#include <libcsupport.h>
#include <rtems/libio.h>
#ifdef STACK_CHECKER_ON
#include <stackchk.h>
#endif
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
#ifdef RTEMS_SMALL_MEMORY
extern rtems_unsigned32 _end; /* End of BSS. Defined in 'linkcmds'. */
rtems_unsigned32 rtemsFreeMemStart = (rtems_unsigned32)&_end;
/* Address of start of free memory - should be updated
after creating new partitions or regions. */
#else
rtems_unsigned32 rtemsFreeMemStart = RAM_START;
/* RAM_START defined in 'bsp.h'. */
#endif /* RTEMS_SMALL_MEMORY */
/* The original BSP configuration 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; /* CPU configuration table. */
char *rtems_progname; /* Program name - from main(). */
/*-------------------------------------------------------------------------+
| External Prototypes
+--------------------------------------------------------------------------*/
extern void _exit(int); /* define in exit.c */
/*-------------------------------------------------------------------------+
| Function: bsp_libc_init
| Description: Initialize whatever libc we are using. Called from
| pretasking hook.
| Global Variables: rtemsFreeMemStart.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static void
bsp_libc_init(void)
{
if (rtemsFreeMemStart & (CPU_ALIGNMENT - 1)) /* not aligned => align it */
rtemsFreeMemStart = (rtemsFreeMemStart+CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
RTEMS_Malloc_Initialize((void *)rtemsFreeMemStart, HEAP_SIZE << 10, 0);
rtemsFreeMemStart += HEAP_SIZE << 10; /* HEAP_SIZE is in KBytes */
/* Init the RTEMS libio facility to provide UNIX-like system calls for use by
newlib (ie: provide __rtems_open, __rtems_close, etc). Uses malloc()
to get area for the iops, so must be after malloc initialization. */
rtems_libio_init();
/* 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 */
} /* bsp_libc_init */
/*-------------------------------------------------------------------------+
| Function: bsp_pretasking_hook
| Description: BSP pretasking hook. Called just before drivers are
| initialized. Used to setup libc and install any BSP
| extensions. NOTE: Must not use libc (to do io) from here,
| since drivers are not yet initialized.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
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 /* STACK_CHECKER_ON */
#ifdef RTEMS_DEBUG
rtems_debug_enable(RTEMS_DEBUG_ALL_MASK);
#endif /* RTEMS_DEBUG */
} /* bsp_pretasking_hook */
/*-------------------------------------------------------------------------+
| Function: bsp_postdriver_hook
| Description: After drivers are setup, register some "filenames" and open
| stdin, stdout, stderr files. Newlib will automatically
| associate the files with these (it hardcodes the numbers).
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
bsp_postdriver_hook(void)
{
int stdin_fd, stdout_fd, stderr_fd;
rtems_status_code error_code;
error_code = 'S' << 24 | 'T' << 16;
/* open standard devices: stdout, stderr and stdin */
if ((stdin_fd = __rtems_open("/dev/console", O_RDONLY, 0)) < 0)
rtems_fatal_error_occurred( error_code | 'D' << 8 | '0' );
if ((stdout_fd = __rtems_open("/dev/console", O_WRONLY, 0)) < 0)
rtems_fatal_error_occurred( error_code | 'D' << 8 | '1' );
if ((stderr_fd = __rtems_open("/dev/console", O_WRONLY, 0)) < 1)
rtems_fatal_error_occurred( error_code | 'D' << 8 | '2' );
if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
rtems_fatal_error_occurred( error_code | 'I' << 8 | 'O' );
} /* bsp_postdriver_hook */
/*-------------------------------------------------------------------------+
| Function: main
| Description: Called from bsp's startup code ('start.s').
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
int main(int argc, char **argv, char **environp)
{
/* If we don't have command line arguments set default program name. */
if ((argc > 0) && argv && argv[0])
rtems_progname = argv[0];
else
rtems_progname = "RTEMS";
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
Cpu_table.predriver_hook = NULL; /* use system's */
Cpu_table.postdriver_hook = bsp_postdriver_hook;
Cpu_table.idle_task = NULL;
/* do not override system IDLE task */
Cpu_table.do_zero_of_workspace = TRUE;
Cpu_table.interrupt_table_segment = get_ds();
Cpu_table.interrupt_table_offset = (void *)Interrupt_descriptor_table;
Cpu_table.interrupt_stack_size = 4096;
Cpu_table.extra_mpci_receive_server_stack = 0;
/* Copy user's table and make necessary adjustments. */
BSP_Configuration = Configuration;
/* Place RTEMS workspace at top of physical RAM (RAM_END defined in 'bsp.h' */
BSP_Configuration.work_space_start =
(void *)(RAM_END - BSP_Configuration.work_space_size);
/* Add 1 region for Malloc in libc_low. */
BSP_Configuration.RTEMS_api_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
/* Tell libio how many fd's we want and allow it to tweak config. */
rtems_libio_config(&BSP_Configuration, BSP_LIBIO_MAX_FDS);
rtems_initialize_executive(&BSP_Configuration, &Cpu_table);
/* does not return */
/*-------------------------------------------------------------------------+
| We only return here if the executive has finished. This happens when the
| task has called exit(). We will then call _exit() which is part of the bsp.
+--------------------------------------------------------------------------*/
for (;;)
_exit(0);
/* no cleanup necessary for PC386 */
return 0;
} /* main */

View File

@@ -0,0 +1,73 @@
/*-------------------------------------------------------------------------+
| exit.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| Routines to shutdown and reboot the PC.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| exit.c,v 1.2 1995/12/19 20:07:36 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <stdio.h>
#include <bsp.h>
/*-------------------------------------------------------------------------+
| External Prototypes
+--------------------------------------------------------------------------*/
extern rtems_boolean _IBMPC_scankey(char *); /* define in 'inch.c' */
/*-------------------------------------------------------------------------+
| Function: rtemsReboot
| Description: Reboot the PC.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
inline void rtemsReboot(void)
{
/* shutdown and reboot */
outport_byte(0x64, 0xFE); /* use keyboard controler to do the job... */
} /* rtemsReboot */
/*-------------------------------------------------------------------------+
| Function: _exit
| Description: Shutdown the PC. Called from libc's 'exit'.
| Global Variables: None.
| Arguments: status - exit status (ignored).
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void _exit(int status)
{
unsigned char ch;
puts("\nEXECUTIVE SHUTDOWN! Any key to reboot...");
while(!_IBMPC_scankey(&ch))
;
rtemsReboot();
} /* _exit */

View File

@@ -0,0 +1,205 @@
/*-------------------------------------------------------------------------+
| ldsegs.s v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This file assists the board independent startup code by loading the proper
| segment register values. The values loaded are board dependent. In addition
| it contains code to enable the A20 line and to reprogram the PIC to relocate
| the IRQ interrupt vectors to 0x20 -> 0x2f.
| NOTE: No stack has been established when this routine is invoked.
| It returns by jumping back to bspentry.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is base on:
| ldsegs.s,v 1.4 1996/04/20 16:48:30 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
|
| Also based on (from the Linux source tree):
| setup.S - Copyright (C) 1991, 1992 Linus Torvalds
+--------------------------------------------------------------------------*/
#include "asm.h"
/*----------------------------------------------------------------------------+
| Constants
+----------------------------------------------------------------------------*/
.set PROT_DATA_SEG, 0x10 # offset in gdt
.set RESET_SS, PROT_DATA_SEG # initial value of stack segment register
.set RESET_DS, PROT_DATA_SEG # initial value of data segment register
.set RESET_ES, PROT_DATA_SEG # initial value of extra segment register
.set RESET_FS, PROT_DATA_SEG # initial value of "f" segment register
.set RESET_GS, PROT_DATA_SEG # initial value of "g" segment register
/*----------------------------------------------------------------------------+
| Macros
+----------------------------------------------------------------------------*/
#define LOAD_SEGMENTS(_value, _segment) \
movw $ ## _value, ax; \
movw ax, _segment
/*----------------------------------------------------------------------------+
| CODE section
+----------------------------------------------------------------------------*/
BEGIN_CODE
EXTERN (establish_stack)
/*----------------------------------------------------------------------------+
| empty_8042
+------------------------------------------------------------------------------
| This routine checks that the keyboard command queue is empty (after emptying
| the output buffers).
| No timeout is used - if this hangs there is something wrong with the machine,
| and we probably couldn't proceed anyway.
+----------------------------------------------------------------------------*/
SYM(empty_8042):
call delay
inb $0x64, al # 8042 status port
testb $0x01, al # output buffer?
jz SYM(no_output)
call SYM(delay)
in $0x60, al # read it
jmp SYM(empty_8042)
SYM(no_output):
test $0x02, al # is input buffer full?
jnz SYM(empty_8042) # yes - loop
ret
/*----------------------------------------------------------------------------+
| delay
+------------------------------------------------------------------------------
| Delay is needed after doing I/O. We do it by writing to a non-existent port.
+----------------------------------------------------------------------------*/
SYM(delay):
outb al, $0xED # about 1uS delay
ret
/*-------------------------------------------------------------------------+
| Function: _load_segments
| Description: Load board segment registers with apropriate values + enable
A20 line + reprogram PIC.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
PUBLIC (_load_segments)
SYM (_load_segments):
LOAD_SEGMENTS(RESET_SS, ss)
LOAD_SEGMENTS(RESET_DS, ds)
LOAD_SEGMENTS(RESET_ES, es)
LOAD_SEGMENTS(RESET_FS, fs)
LOAD_SEGMENTS(RESET_GS, gs)
/*---------------------------------------------------------------------+
| we have to enable A20 in order to access memory above 1MByte
+---------------------------------------------------------------------*/
call SYM(empty_8042)
movb $0xD1, al # command write
outb al, $0x64
call SYM(empty_8042)
movb $0xDF, al # A20 on
outb al, $0x60
call SYM(empty_8042)
/*---------------------------------------------------------------------+
| Now we have to reprogram the interrupts :-(. We put them right after
| the intel-reserved hardware interrupts, at int 0x20-0x2F. There they
| won't mess up anything. Sadly IBM really messed this up with the
| original PC, and they haven't been able to rectify it afterwards. Thus
| the bios puts interrupts at 0x08-0x0f, which is used for the internal
| hardware interrupts as well. We just have to reprogram the 8259's, and
| it isn't fun.
+---------------------------------------------------------------------*/
movb $0x11, al /* initialization sequence */
outb al, $0x20 /* send it to 8259A-1 */
call SYM(delay)
outb al, $0xA0 /* and to 8259A-2 */
call SYM(delay)
movb $0x20, al /* start of hardware int's (0x20) */
outb al, $0x21
call SYM(delay)
movb $0x28, al /* start of hardware int's 2 (0x28) */
outb al, $0xA1
call SYM(delay)
movb $0x04, al /* 8259-1 is master */
outb al, $0x21
call SYM(delay)
movb $0x02, al /* 8259-2 is slave */
outb al, $0xA1
call SYM(delay)
movb $0x01, al /* 8086 mode for both */
outb al, $0x21
call SYM(delay)
outb al, $0xA1
call SYM(delay)
movb $0xFF, al /* mask off all interrupts for now */
outb al, $0xA1
call SYM(delay)
movb $0xFB, al /* mask all irq's but irq2 which */
outb al, $0x21 /* is cascaded */
call SYM(delay)
jmp SYM (_establish_stack) # return to the bsp entry code
/*-------------------------------------------------------------------------+
| Function: _return_to_monitor
| Description: Return to board's monitor (we have none so simply restart).
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
PUBLIC (_return_to_monitor)
SYM (_return_to_monitor):
call SYM (Timer_exit)
call SYM (Clock_exit)
jmp SYM (start)
END_CODE
/*----------------------------------------------------------------------------+
| DATA section
+----------------------------------------------------------------------------*/
BEGIN_DATA
PUBLIC (_Do_Load_IDT)
SYM (_Do_Load_IDT):
.byte 1 # load RTEMS own Interrupt Descriptor Table
PUBLIC (_Do_Load_GDT)
SYM (_Do_Load_GDT):
.byte 0 # use the Global Descriptor Table that is already defined
END_DATA
END

View File

@@ -0,0 +1,62 @@
/*-------------------------------------------------------------------------+
| linkcmds v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This file contains directives for the GNU linker which are specific to the
| PC386 bsp.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| linkcmds,v 1.3 1995/12/19 20:06:58 joel Exp - FORCE CPU386 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
SECTIONS
{
.text :
{
_text_start = . ;
*(.text)
_etext = ALIGN( 0x10 ) ;
}
.rodata ADDR( .text ) + SIZEOF( .text ):
{
_rodata_start = . ;
*(.rodata)
_erodata = ALIGN( 0x10 ) ;
}
.data ADDR( .rodata ) + SIZEOF( .rodata ):
{
_data_start = . ;
*(.data)
_edata = ALIGN( 0x10 ) ;
}
.bss ADDR( .data ) + SIZEOF( .data ):
{
_bss_start = . ;
*(.bss)
*(COMMON)
_end = . ;
__end = . ;
}
}

View File

@@ -0,0 +1,50 @@
/*-------------------------------------------------------------------------+
| sbrk.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| If the BSP wants to dynamically allocate the memory for the C Library heap
| (malloc) and/or be able to extend the heap, then this routine must be
| functional. RTEMS newlib suppport has an implementation of malloc using
| RTEMS regions => the user can do mallocs.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| sbrk.c,v 1.2 1995/12/19 20:07:38 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <errno.h>
#include <sys/types.h>
/*-------------------------------------------------------------------------+
| Function: sbrk
| Description: Stub for sbrk.
| Global Variables: None.
| Arguments: Not relevant.
| Returns: Not relevant.
+--------------------------------------------------------------------------*/
void *sbrk(size_t incr)
{
errno = EINVAL;
return (void *)NULL;
} /* sbrk */

View File

@@ -0,0 +1,58 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH=@srcdir@
PGM=${ARCH}/timer.rel
# C source names, if any, go here -- minus the .c
C_PIECES=timer
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .s
S_PIECES=timerisr
S_FILES=$(S_PIECES:%=%.s)
S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
SRCS=$(C_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(S_O_FILES)
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all

View File

@@ -0,0 +1,256 @@
/*-------------------------------------------------------------------------+
| timer.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This file contains the PC386 timer package.
+--------------------------------------------------------------------------+
| NOTE: It is important that the timer start/stop overhead be determined
| when porting or modifying this code.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is base on:
| timer.c,v 1.7 1995/12/19 20:07:43 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <bsp.h>
#include <irq.h>
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
#define TIMER_IRQ 0x00 /* Timer IRQ. */
#define AVG_OVERHEAD 0 /* 0.1 microseconds to start/stop timer. */
#define LEAST_VALID 1 /* Don't trust a value lower than this. */
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
volatile rtems_unsigned32 Ttimer_val;
rtems_boolean Timer_driver_Find_average_overhead = TRUE;
/*-------------------------------------------------------------------------+
| Pentium optimized timer handling.
+--------------------------------------------------------------------------*/
#if defined(pentium)
/*-------------------------------------------------------------------------+
| Function: rdtsc
| Description: Read the value of PENTIUM on-chip cycle counter.
| Global Variables: None.
| Arguments: None.
| Returns: Value of PENTIUM on-chip cycle counter.
+--------------------------------------------------------------------------*/
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;
} /* rdtsc */
/*-------------------------------------------------------------------------+
| Function: Timer_exit
| Description: Timer cleanup routine at RTEMS exit. NOTE: This routine is
| not really necessary, since there will be a reset at exit.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Timer_exit(void)
{
PC386_disableIrq(TIMER_IRQ);
} /* Timer_exit */
/*-------------------------------------------------------------------------+
| Function: Timer_initialize
| Description: Timer initialization routine.
| Global Variables: Ttimer_val.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Timer_initialize(void)
{
static rtems_boolean First = TRUE;
if (First)
{
First = FALSE;
atexit(Timer_exit); /* Try not to hose the system at exit. */
PC386_enableIrq(TIMER_IRQ);
/* Disable the programmable timer so ticks don't interfere. */
}
Ttimer_val = rdtsc(); /* read starting time */
} /* Timer_initialize */
/*-------------------------------------------------------------------------+
| Function: Read_timer
| Description: Read hardware timer value.
| Global Variables: Ttimer_val, Timer_driver_Find_average_overhead.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
rtems_unsigned32
Read_timer(void)
{
register rtems_unsigned32 total;
total = (rtems_unsigned32)(rdtsc() - Ttimer_val);
if (Timer_driver_Find_average_overhead)
return total;
else if (total < LEAST_VALID)
return 0; /* below timer resolution */
else
return (total - AVG_OVERHEAD);
} /* Read_timer */
#else /* pentium */
/*-------------------------------------------------------------------------+
| Non-Pentium timer handling.
+--------------------------------------------------------------------------*/
#define US_PER_ISR 250 /* Number of micro-seconds per timer interruption */
/*-------------------------------------------------------------------------+
| External Prototypes
+--------------------------------------------------------------------------*/
extern rtems_isr timerisr(rtems_vector_number);
/* timer (int 08h) Interrupt Service Routine (defined in 'timerisr.s') */
/*-------------------------------------------------------------------------+
| Function: Timer_exit
| Description: Timer cleanup routine at RTEMS exit. NOTE: This routine is
| not really necessary, since there will be a reset at exit.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Timer_exit(void)
{
/* reset timer mode to standard (DOS) value */
outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
outport_byte(TIMER_CNTR0, 0);
outport_byte(TIMER_CNTR0, 0);
} /* Timer_exit */
/*-------------------------------------------------------------------------+
| Function: Timer_initialize
| Description: Timer initialization routine.
| Global Variables: Ttimer_val.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Timer_initialize(void)
{
static rtems_boolean First = TRUE;
if (First)
{
First = FALSE;
atexit(Timer_exit); /* Try not to hose the system at exit. */
/* install a raw interrupt handler for timer */
PC386_installRawIrqHandler(TIMER_IRQ, timerisr);
/* load timer for US_PER_ISR microsecond period */
outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 0 & 0xff);
outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 8 & 0xff);
}
/* wait for ISR to be called at least once */
Ttimer_val = 0;
while (Ttimer_val == 0)
continue;
Ttimer_val = 0;
} /* Timer_initialize */
/*-------------------------------------------------------------------------+
| Function: Read_timer
| Description: Read hardware timer value.
| Global Variables: Ttimer_val, Timer_driver_Find_average_overhead.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
rtems_unsigned32
Read_timer(void)
{
register rtems_unsigned32 total, clicks;
register rtems_unsigned8 lsb, msb;
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 * US_PER_ISR) + (US_PER_ISR - TICK_TO_US(clicks));
if (Timer_driver_Find_average_overhead)
return total;
else if (total < LEAST_VALID)
return 0; /* below timer resolution */
else
return (total - AVG_OVERHEAD);
}
#endif /* pentium */
/*-------------------------------------------------------------------------+
| Function: Empty_function
| Description: Empty function used in time tests.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
rtems_status_code Empty_function(void)
{
return RTEMS_SUCCESSFUL;
} /* Empty function */
/*-------------------------------------------------------------------------+
| Function: Set_find_average_overhead
| Description: Set internal Timer_driver_Find_average_overhead flag value.
| Global Variables: Timer_driver_Find_average_overhead.
| Arguments: find_flag - new value of the flag.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Set_find_average_overhead(rtems_boolean find_flag)
{
Timer_driver_Find_average_overhead = find_flag;
} /* Set_find_average_overhead */

View File

@@ -0,0 +1,59 @@
/*-------------------------------------------------------------------------+
| timerisr.s v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| This file contains the PC386 timer interrupt handler.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is base on:
| timerisr.s,v 1.5 1995/12/19 20:07:45 joel Exp - go32 BSP
| With the following copyright notice:
| **************************************************************************
| * 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. *
| **************************************************************************
+--------------------------------------------------------------------------*/
#include "asm.h"
BEGIN_CODE
EXTERN(Ttimer_val)
/*-------------------------------------------------------------------------+
| Function: rtems_isr timerisr(rtems_vector_number);
| Description: ISR for the timer. The timer is set up to generate an
| interrupt at maximum intervals.
| Global Variables: None.
| Arguments: standard - see RTEMS documentation.
| Returns: standard return value - see RTEMS documentation.
+--------------------------------------------------------------------------*/
PUBLIC(timerisr)
SYM (timerisr):
incl Ttimer_val # another tick
pushl eax
movb $0x20, al
outb al, $0x20 # signal generic End Of Interrupt (EOI) to PIC
popl eax
iret
END_CODE
END

View File

@@ -0,0 +1,191 @@
#
# Timing Test Suite Results for the go32 BSP using an i486DX
#
# times_i486dx,v 1.4 1996/07/02 18:14:27 joel Exp
#
Board: PC/AT clone
CPU: Intel i486DX
Clock Speed: 33 Mhz
Memory Configuration: DRAM w/256K cache
Wait States: unknown
Times Reported in: microseconds
Timer Source: i8254
Column A: 3.5.1 pre-release
Column B: 3.5.17 pre-release
# DESCRIPTION A B
== ================================================================= ==== ====
1 rtems_semaphore_create 57 66
rtems_semaphore_delete 59 61
rtems_semaphore_obtain: available 9 7
rtems_semaphore_obtain: not available -- NO_WAIT 8 7
rtems_semaphore_release: no waiting tasks 9 8
2 rtems_semaphore_obtain: not available -- caller blocks 39 37
3 rtems_semaphore_release: task readied -- preempts caller 25 24
4 rtems_task_restart: blocked task -- preempts caller 124 102
rtems_task_restart: ready task -- preempts caller 55 111
rtems_semaphore_release: task readied -- returns to caller 16 15
rtems_task_create 31 30
rtems_task_start 19 18
rtems_task_restart: suspended task -- returns to caller 20 19
rtems_task_delete: suspended task 28 26
rtems_task_restart: ready task -- returns to caller 20 19
rtems_task_restart: blocked task -- returns to caller 28 26
rtems_task_delete: blocked task 34 28
5 rtems_task_suspend: calling task 26 23
rtems_task_resume: task readied -- preempts caller 17 15
6 rtems_task_restart: calling task 22 19
rtems_task_suspend: returns to caller 10 8
rtems_task_resume: task readied -- returns to caller 10 8
rtems_task_delete: ready task 34 33
7 rtems_task_restart: suspended task -- preempts caller 37 34
8 rtems_task_set_priority: obtain current priority 7 5
rtems_task_set_priority: returns to caller 13 12
rtems_task_mode: obtain current mode 3 3
rtems_task_mode: no reschedule 4 4
rtems_task_mode: reschedule -- returns to caller 20 17
rtems_task_mode: reschedule -- preempts caller 39 37
rtems_task_set_note 7 5
rtems_task_get_note 7 5
rtems_clock_set 17 16
rtems_clock_get 2 1
9 rtems_message_queue_create 117 113
rtems_message_queue_send: no waiting tasks 22 19
rtems_message_queue_urgent: no waiting tasks 22 19
rtems_message_queue_receive: available 18 16
rtems_message_queue_flush: no messages flushed 15 14
rtems_message_queue_flush: messages flushed 17 17
rtems_message_queue_delete 63 63
10 rtems_message_queue_receive: not available -- NO_WAIT 10 8
rtems_message_queue_receive: not available -- caller blocks 42 40
11 rtems_message_queue_send: task readied -- preempts caller 38 37
12 rtems_message_queue_send: task readied -- returns to caller 27 24
13 rtems_message_queue_urgent: task readied -- preempts caller 38 36
14 rtems_message_queue_urgent: task readied -- returns to caller 26 24
15 rtems_event_receive: obtain current events 0 0
rtems_event_receive: not available -- NO_WAIT 6 5
rtems_event_receive: not available -- caller blocks 34 33
rtems_event_send: no task readied 6 5
rtems_event_receive: available 21 19
rtems_event_send: task readied -- returns to caller 19 15
16 rtems_event_send: task readied -- preempts caller 26 24
17 rtems_task_set_priority: preempts caller 36 33
18 rtems_task_delete: calling task 51 52
19 rtems_signal_catch 17 18
rtems_signal_send: returns to caller 38 39
rtems_signal_send: signal to self 46 62
exit ASR overhead: returns to calling task 20 25
exit ASR overhead: returns to preempting task 29 29
20 rtems_partition_create 65 67
rtems_region_create 59 54
rtems_partition_get_buffer: available 39 35
rtems_partition_get_buffer: not available 18 16
rtems_partition_return_buffer 36 30
rtems_partition_delete 32 30
rtems_region_get_segment: available 22 21
rtems_region_get_segment: not available -- NO_WAIT 29 25
rtems_region_return_segment: no waiting tasks 24 22
rtems_region_get_segment: not available -- caller blocks 83 81
rtems_region_return_segment: task readied -- preempts caller 85 84
rtems_region_return_segment: task readied -- returns to caller 39 41
rtems_region_delete 30 30
rtems_io_initialize 1 1
rtems_io_open 0 0
rtems_io_close 0 0
rtems_io_read 0 0
rtems_io_write 0 0
rtems_io_control 0 1
21 rtems_task_ident 116 114
rtems_message_queue_ident 113 111
rtems_semaphore_ident 122 120
rtems_partition_ident 113 110
rtems_region_ident 115 111
rtems_port_ident 113 109
rtems_timer_ident 113 109
rtems_rate_monotonic_ident 113 111
22 rtems_message_queue_broadcast: task readied -- returns to caller 82 85
rtems_message_queue_broadcast: no waiting tasks 11 9
rtems_message_queue_broadcast: task readied -- preempts caller 51 56
23 rtems_timer_create 8 7
rtems_timer_fire_after: inactive 14 12
rtems_timer_fire_after: active 13 12
rtems_timer_cancel: active 8 7
rtems_timer_cancel: inactive 7 6
rtems_timer_reset: inactive 11 10
rtems_timer_reset: active 11 11
rtems_timer_fire_when: inactive 17 16
rtems_timer_fire_when: active 17 17
rtems_timer_delete: active 10 9
rtems_timer_delete: inactive 9 8
rtems_task_wake_when 36 34
24 rtems_task_wake_after: yield -- returns to caller 5 3
rtems_task_wake_after: yields -- preempts caller 22 19
25 rtems_clock_tick 31 31
26 _ISR_Disable 11 12
_ISR_Flash 9 9
_ISR_Enable 31 67
_Thread_Disable_dispatch 11 10
_Thread_Enable_dispatch 18 18
_Thread_Set_state 20 22
_Thread_Disptach (NO FP) 37 41
context switch: no floating point contexts 29 26
context switch: self 14 10
context switch: to another task 12 12
context switch: restore 1st FP task 54 54
fp context switch: save idle, restore idle 47 46
fp context switch: save idle, restore initialized 25 25
fp context switch: save initialized, restore initialized 24 25
_Thread_Resume 23 24
_Thread_Unblock 14 14
_Thread_Ready 16 24
_Thread_Get 2 2
_Semaphore_Get 1 1
_Thread_Get: invalid id 0 0
27 interrupt entry overhead: returns to interrupted task 25 23
interrupt exit overhead: returns to interrupted task 14 15
interrupt entry overhead: returns to nested interrupt 12 12
interrupt exit overhead: returns to nested interrupt 14 14
interrupt entry overhead: returns to preempting task 14 16
interrupt exit overhead: returns to preempting task 42 38
28 rtems_port_create 43 42
rtems_port_external_to_internal 6 4
rtems_port_internal_to_external 6 4
rtems_port_delete 39 33
29 rtems_rate_monotonic_create 48 42
rtems_rate_monotonic_period: initiate period -- returns to caller 61 65
rtems_rate_monotonic_period: obtain status 23 21
rtems_rate_monotonic_cancel 38 35
rtems_rate_monotonic_delete: inactive 32 32
rtems_rate_monotonic_delete: active 22 22
rtems_rate_monotonic_period: conclude periods -- caller blocks 24 19

View File

@@ -0,0 +1,196 @@
#
# Timing Test Suite Results for the go32 BSP using a Pentium
#
# times_p5,v 1.3 1995/12/19 20:07:20 joel Exp
#
NOTE: To obtain the execution time in microseconds, divide the number of
cycles by the clock speed. For example, if rtems_semaphore create
is reported to be 1164 cycles, then at 66 Mhz it takes 17.64
microseconds or 8.75 microseconds at 133 Mhz.
Board: PC/AT clone
CPU: Intel Pentium
Clock Speed: 66 Mhz
Memory Configuration: DRAM w/512 Kb cache
Wait States: unknown
Times Reported in: cycles
Timer Source: on-CPU cycle counter
Column A: 3.5.1 pre-release
Column Y: unused
# DESCRIPTION A B
== ================================================================= ==== ====
1 rtems_semaphore_create 1164
rtems_semaphore_delete 976
rtems_semaphore_obtain: available 300
rtems_semaphore_obtain: not available -- NO_WAIT 300
rtems_semaphore_release: no waiting tasks 291
2 rtems_semaphore_obtain: not available -- caller blocks 1182
3 rtems_semaphore_release: task readied -- preempts caller 716
4 rtems_task_restart: blocked task -- preempts caller 2130
rtems_task_restart: ready task -- preempts caller 1861
rtems_semaphore_release: task readied -- returns to caller 491
rtems_task_create 1017
rtems_task_start 965
rtems_task_restart: suspended task -- returns to caller 816
rtems_task_delete: suspended task 926
rtems_task_restart: ready task -- returns to caller 850
rtems_task_restart: blocked task -- returns to caller 1076
rtems_task_delete: blocked task 927
5 rtems_task_suspend: calling task 714
rtems_task_resume: task readied -- preempts caller 575
6 rtems_task_restart: calling task 646
rtems_task_suspend: returns to caller 309
rtems_task_resume: task readied -- returns to caller 320
rtems_task_delete: ready task 994
7 rtems_task_restart: suspended task -- preempts caller 1025
8 rtems_task_set_priority: obtain current priority 223
rtems_task_set_priority: returns to caller 468
rtems_task_mode: obtain current mode 99
rtems_task_mode: no reschedule 114
rtems_task_mode: reschedule -- returns to caller 264
rtems_task_mode: reschedule -- preempts caller 836
rtems_task_set_note 236
rtems_task_get_note 232
rtems_clock_set 569
rtems_clock_get 107
9 rtems_message_queue_create 3287
rtems_message_queue_send: no waiting tasks 613
rtems_message_queue_urgent: no waiting tasks 615
rtems_message_queue_receive: available 534
rtems_message_queue_flush: no messages flushed 252
rtems_message_queue_flush: messages flushed 335
rtems_message_queue_delete 1195
10 rtems_message_queue_receive: not available -- NO_WAIT 333
rtems_message_queue_receive: not available -- caller blocks 1194
11 rtems_message_queue_send: task readied -- preempts caller 957
12 rtems_message_queue_send: task readied -- returns to caller 700
13 rtems_message_queue_urgent: task readied -- preempts caller 1261
14 rtems_message_queue_urgent: task readied -- returns to caller 697
15 rtems_event_receive: obtain current events 27
rtems_event_receive: not available -- NO_WAIT 226
rtems_event_receive: not available -- caller blocks 888
rtems_event_send: no task readied 221
rtems_event_receive: available 393
rtems_event_send: task readied -- returns to caller 496
16 rtems_event_send: task readied -- preempts caller 719
17 rtems_task_set_priority: preempts caller 959
18 rtems_task_delete: calling task 1295
19 rtems_signal_catch 223
rtems_signal_send: returns to caller 628
rtems_signal_send: signal to self 821
exit ASR overhead: returns to calling task 401
exit ASR overhead: returns to preempting task 482
20 rtems_partition_create 1337
rtems_region_create 1031
rtems_partition_get_buffer: available 680
rtems_partition_get_buffer: not available 303
rtems_partition_return_buffer 617
rtems_partition_delete 523
rtems_region_get_segment: available 458
rtems_region_get_segment: not available -- NO_WAIT 565
rtems_region_return_segment: no waiting tasks 388
rtems_region_get_segment: not available -- caller blocks 1683
rtems_region_return_segment: task readied -- preempts caller 1476
rtems_region_return_segment: task readied -- returns to caller 818
rtems_region_delete 477
rtems_io_initialize 48
rtems_io_open 22
rtems_io_close 22
rtems_io_read 22
rtems_io_write 22
rtems_io_control 23
21 rtems_task_ident 3381
rtems_message_queue_ident 3328
rtems_semaphore_ident 3593
rtems_partition_ident 3286
rtems_region_ident 3343
rtems_port_ident 3278
rtems_timer_ident 3282
rtems_rate_monotonic_ident 3287
22 rtems_message_queue_broadcast: task readied -- returns to caller 1322
rtems_message_queue_broadcast: no waiting tasks 347
rtems_message_queue_broadcast: task readied -- preempts caller 1385
23 rtems_timer_create 306
rtems_timer_fire_after: inactive 475
rtems_timer_fire_after: active 475
rtems_timer_cancel: active 277
rtems_timer_cancel: inactive 251
rtems_timer_reset: inactive 391
rtems_timer_reset: active 465
rtems_timer_fire_when: inactive 577
rtems_timer_fire_when: active 578
rtems_timer_delete: active 377
rtems_timer_delete: inactive 350
rtems_task_wake_when 1080
24 rtems_task_wake_after: yield -- returns to caller 159
rtems_task_wake_after: yields -- preempts caller 574
25 rtems_clock_tick 505
26 _ISR_Disable 33
_ISR_Flash 33
_ISR_Enable 26
_Thread_Disable_dispatch 36
_Thread_Enable_dispatch 240
_Thread_Set_state 315
_Thread_Disptach (NO FP) 623
context switch: no floating point contexts 594
context switch: self 89
context switch: to another task 122
context switch: restore 1st FP task 1043
fp context switch: save idle, restore idle 978
fp context switch: save idle, restore initialized 390
fp context switch: save initialized, restore initialized 392
_Thread_Resume 238
_Thread_Unblock 171
_Thread_Ready 176
_Thread_Get 71
_Semaphore_Get 61
_Thread_Get: invalid id 10
27 interrupt entry overhead: returns to interrupted task 391
interrupt exit overhead: returns to interrupted task 110
interrupt entry overhead: returns to nested interrupt 167
interrupt exit overhead: returns to nested interrupt 120
interrupt entry overhead: returns to preempting task 193
interrupt exit overhead: returns to preempting task 961
28 rtems_port_create 668
rtems_port_external_to_internal 215
rtems_port_internal_to_external 211
rtems_port_delete 491
29 rtems_rate_monotonic_create 823
rtems_rate_monotonic_period: initiate period -- returns to caller 1094
rtems_rate_monotonic_period: obtain status 345
rtems_rate_monotonic_cancel 602
rtems_rate_monotonic_delete: inactive 553
rtems_rate_monotonic_delete: active 528
rtems_rate_monotonic_period: conclude periods -- caller blocks 672

View File

@@ -0,0 +1,63 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH=@srcdir@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
manext = 1
mandir = @mandir@/man$(manext)
VPATH=@srcdir@
# we use host compiler in this directory
USE_HOST_COMPILER=yes
# C source names, if any, go here -- minus the .c
C_PIECES=bin2boot
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=$(ARCH)/%.o)
H_FILES=
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
PGMS=$(ARCH)/bin2boot
include $(RTEMS_CUSTOM)
include $(RTEMS_ROOT)/make/leaf.cfg
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS += $(HOST_ARCH)
CLOBBER_ADDITIONS +=
all: $(ARCH) $(SRCS) $(PGMS)
$(INSTALL_VARIANT) -m 555 $(PGMS) ${PROJECT_RELEASE}/build-tools
cd ${PROJECT_RELEASE}/build-tools/diskboot.exe ; \
uudecode < $(srcdir)/diskboot.uue

View File

@@ -0,0 +1,354 @@
2-28-1995 GK
In order to provide more functionality to the boot rom code I changed
Jamie's draft a little bit. All my changes have a bar sign (|) in the
79th column.
Gero Kuhlmann
===============================================================================
0. Numbering
This is Draft Net Boot Image Proposal 0.2, February 28, 1995 |
1. Preamble - the why
Whilst researching what other boot proms do (at least those implementing
TCP/IP protocols) it is clear that each 'does their own thing' in
terms of what they expect in a boot image.
If we could all agree on working toward an open standard, O/S suppliers
and boot rom suppliers can build their products to this norm, and be confident
that they will work with each other.
This is a description of how I will implement the boot rom for
Linux. I believe it to be flexible enough for any OS that will be loaded
when a PC boots from a network in the TCP/IP environment.
It would be good if this could be turned into some form of standard.
This is very much a first draft. I am inviting comment.
The ideas presented here should be independant of any implementation.
In the end, where there is a conflict between the final of this draft, and an
implementation, this description should prevail.
The terms I use are defined at the end.
2. The target
The target is to have a PC retrieve a boot image from a network in the TCP/IP
environment.
The boot may take place from a network adaptor rom, from a boot floppy, or
from a program in MSDOS.
3. Net Boot Process Description.
The net boot process can be started either as a result of the PC
boot process, or through normal DOS execution of a program. The net boot
program can reside on a rom, e.g. on an adaptor card, or in ram, either
as a result of reading off disk or transferred from ram.
The boot process may execute in any mode (e.g. 8086, 80386) it desires.
When it jumps to the start location in the boot image, it must be in
8086 mode and be capable of going into any mode supported by the
underlying processor.
The image cannot be loaded into address spaces below 10000h, or between
A0000h through FFFFFh, or between 98000h through 9FFFFh. Once the image
starts executing, all the memory is available to it, so it can relocate
parts of itself to these areas.
The boot process must be capable of loading the image into all other
memory locations. Specifically, where the machine supports this, this means
memory over 100000h.
The net boot process must execute the bootp protocol, followed by
the tftp protocol, as defined in the relevant rfc's.
The file name used in the tftp protocol must be that given by the bootp
record.
If less than 512 bytes are loaded, the net boot process attempts to display
on the screen any ascii data at the start of the image. The net boot
process then exits in the normal manner. For a boot prom, this will
allow normal disk booting. For DOS programs, this will mean a normal return
to DOS.
When the first 512 bytes have been loaded, the boot process checks
for an initial magic number, which is defined later. If this number
is present, the net process continues loading under the control
of the image format. The image, which is described later, tells the
net boot process where to put this record and all subsequent data.
If no initial magic number is present the net boot process checks for a second
magic number at offset 510. If the magic number 510 = 55h, 511 = AAh,
then the net process continues. If this second magic number is not
present, then the net boot process terminates the tftp protocol, displays
an error message and exits in the normal manner.
If no initial magic number is present and the second one is, the net boot
process relocates the 512 bytes to location 7c00h. The net boot process
continues to load any further image data to 10000h up. This data can overwrite
the first 512 boot bytes. If the image reaches 98000h, then any further data is
continued to be loaded above 100000h. When all the data has been loaded, the
net boot process jumps to location 0:7c00.
When the net boot process calls the image, it places 2 far pointers onto |
the stack, in standard intel order (e.g. segment:offset representation). |
The first far pointer which immediately follows the return address on |
the stack, points to the loaded boot image header. The second far pointer |
which is placed above the first one, shows to the memory area where the |
net boot process saved the bootp reply. |
4. Image Format with Initial Magic Number.
The first 512 bytes of the image file contain the image header,
and image loading information records. This contains all the
information needed by the net boot process as to where data
is to be loaded.
The magic number (in time-honoured tradition (well why not?)) is:
0 = 36h
1 = 13h
2 = 03h
3 = 1Bh
Apart from the two magic numbers, all words and double words are in PC
native endian.
Including the initial magic number the header record is:
+---------------------+
| |
| Initial Magic No. | 4 bytes
+---------------------+
| |
| Flags and length | double word
+---------------------+
| |
| Location Address | double word in ds:bx format
+---------------------+
| |
| Execute Address | double word in cs:ip format
+---------------------+
The Location address is where to place the 512 bytes. The net boot
process does this before loading the rest of the image. The location
address cannot be one of the reserved locations mentioned above, but
must be an address lower than 100000h.
The rest of the image must not overwrite these initial 512 bytes, placed
at the required location. The writing of data by the net boot process
into these 512 bytes is deprecated. These 512 bytes must be available for
the image to interogate once it is loaded and running.
The execute address is the location in cs:ip of the initial instruction
once the full image has been loaded. This must be lower than 100000h,
since the initial instructions will be executed in 8086 mode. When the
jump (actaully a far call) is made to the boot image, the stack contains a
far return address, with a far pointer parameter above that, pointing
to the location of this header.
The flags and length field is broken up in the following way:
Bits 0 to 3 (lowest 4 bits) define the length of the non vendor header in
double words. Currently the value is 4.
Bits 4 to 7 define the length required by the vendor extra information
in double words. A value of zero indicates no extra vendor information.
Bits 8 to 31 are reserved for future use and must be set to zero.
After this header, and any vendor header, come the image loading information
records. These specify where data is to be loaded, how long it is, and
communicates to the loaded image what sort of data it is.
The format of each image loading information record is :
+---------------------+
| Flags, tags and | double word
| lengths |
+---------------------+
| |
| Load Address | double word
+---------------------+
| |
| Image Length | double word
+---------------------+
| |
| Memory Length | double word
+---------------------+
Each image loading information record follows the previous, or the header.
The memory length, image length and load address fields are unsigned 32
numbers. They do not have the segment:offset format used by the 8086.
The flags, tags and lengths field is broken up as follows:
Bits 0 to 3 (lowest 4 bits) are the length of the non vendor part of this
header in double words. Currently this value is 4.
Bits 4 to 7 indicate the length of any vendor information, in double words.
Bits 8 to 15 are for vendor's tags. The vendor tag is a private number that
the loaded image can use to determine what sort of image is at this particular
location.
Bits 16 to 23 are for future expansion and should be set to zero.
Bits 24 to 31 are for flags, which are defined later.
Vendors may place further information after this information record, and
before the next. Each information record may have a different vendor
length.
There are two restrictions on vendor information.
One is that the header and all information records that the net boot process
is to use fall within the first 512 bytes.
The second restriction is that the net boot process must ignore all
vendor additions. The net boot process may not overwrite vendor supplied
information, or other undefined data in the initial 512 bytes.
The flags are used to modify the load address field, and to indicate
that this is the last information record that the net boot process should
use.
Bit 24 works in conjunction with bit 25 to specify the meaning of the
load address.
B24 B25
0 0 load address is an absolute 32 number
1 0 add the load address to the location one past the last byte
of the memory area required by the last image loaded.
If the first image, then add to 512 plus the location
where the 512 bytes were placed
0 1 subtract the load address from the one past the
last writeable location in memory. Thus 1 would
be the last location one could write in memory.
1 1 load address is subtracted from the start of
the last image loaded. If the first image, then
subtract from the start of where the 512 bytes were
placed
(For convenience bit 24 is byte 0 of the flag field)
Bit 26 is the end marker for the net boot process. It is set when
this is the last information record the net boot process should
look at. More records may be present, but the net boot process will not
look at them. (Vendors can continue information records out past the 512
boundary for private use in this manner).
The image length tells the net boot process how many bytes are to be loaded.
Zero is a valid value. This can be used to mark memory areas such as
shared memory for interprocessor communication, flash eproms, data in eproms.
The image length can also be different from the memory length. This allows
decompression programs to fluff up the kernel image. It also allows a file
system to be larger then the loaded file system image.
Bits 27 through 31 are not defined as yet and must be set to zero until
they are.
6. Boot prom entry points.
I have not defined boot entry points, and means of obtaining them.
It could be useful to down load part of an image, and have that image
load more of itself by using handy parts of the net boot program.
This can be considered 'for further study'.
7. Example of a boot image.
Here is an example of how the boot image would look for Linux:
0x1B031336, /* magic number */
0x4, /* length of header is 16 bytes, no vendor info */
0x90000000, /* location in ds:bx format */
0x90000200, /* execute address in cs:ip format */
/* 2048 setup.S bytes */
0x4, /* flags, not end, absolute address, 16 bytes this
record, no vendor info */
0x90200, /* load address - note format */
0x800, /* 4 8 512 byte blocks for linux */
0x800,
/* kernel image */
0x4, /* flags, not end, absolute address, 16 bytes this
record, no vendor info */
0x10000, /* load address - note format */
0x80000, /* 512K (this could be shorter */
0x80000,
/* ramdisk for root file system */
0x04000004, /* flags = last, absolute address, 16 bytes this
record, no vendor info *//
0x100000, /* load address - in extended memory */
0x80000, /* 512K for instance */
0x80000,
/* Then follows linux specific information */
8. Terms
When I say 'the net boot process', I mean the act of loading the image into
memory, setting up any tables, up until the jump to the required location
in the image.
The net booting program executes the net boot process. The net boot program
may be a rom, but not neccassarily. It is a set of instructions and data
residing on the booting machine.
The image, or boot image, consists of the data loaded by the net boot process.
When I say 'the PC boot process', I mean the general PC rom bios boot process,
the setting up of hardware, the scanning for adaptor roms, the execution
of adaptor roms, the loading in of the initial boot track. The PC boot
process will include the net boot process, if one is present.
When I say client, I mean the PC booting up.
When I say 'image host', I mean the host where the boot image is comming from.
This may not have the same architecture as the client.
The bootp protocol is defined in RFC951 and RFC1084. The tftp protocol
is defined in RFC783. These are available on many sites.
See Comer 1991 for details on how to obtain them.
A bootp server is the machine that answers the bootp request. It is not
neccassarily the image host.
'Can' and 'may' means doesn't have to, but is allowed to and might.
'Must' means just that. 'Cannot' means must not.
9 References
Comer, D.E. 1991, Internetworking with TCP/IP Vol I: Principles, Protocols,
and Architecture Second Edition, Prentice Hall, Englewood Cliffs, N.J., 1991
Stevens, W.R 1990, Unix Network Programming, Prentice Hall,
Englewood Cliffs, N.J., 1990

View File

@@ -0,0 +1,239 @@
/*-------------------------------------------------------------------------+
| bin2boot.c v1.1 - PC386 BSP - 1997/08/18
+--------------------------------------------------------------------------+
| This file contains the i386 binary to boot image filter.
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "bytetype.h"
#include "bootimg.h"
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
#define SEG_MASK 0xffff0000
/* Mask for segment part of seg:off address. */
#define OFF_MASK 0x0000ffff
/* Mask for offset part of seg:off address. */
#define DEFAULT_START_ADDR 0x10200 /* Default start address for binary. */
#define BOOTIMG_HDR_SIZE 0x0200 /* Size of output file header. */
#define BUFFER_BLOCK_SIZE 0x1000 /* Size of transfer buffer size. */
#define LAST_BLOCK_SIZE 0x0200
/* The output file must have a size multiple of this value. */
/*-------------------------------------------------------------------------+
| Macros
+--------------------------------------------------------------------------*/
#define getSeg(x) (Word)((x) >> 16)
/* Return seg part (Word) of a seg:off address (DWord). */
#define getOff(x) (Word)((x) & OFF_MASK)
/* Return off part (Word) of a seg:off address (DWord). */
#define getSegOff(x) ((((x) & SEG_MASK) << 12) + ((x) & OFF_MASK))
/* Converts a flat address to a seg:off address. */
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
const char UsageMsg[] = "\
Usage: bin2boot [<infile> [<outfile>]] [-s <start_address>] [-v]\n\
\n\
<infile> : input file name\n\
<outfile> : output file name\n\
-s <outfile> : start address of binary image\n\
-m <size> : actual size (for compressed images)\n\
-v : verbose output\n"; /* Usage message. */
/*-------------------------------------------------------------------------+
| External Prototypes (for use with getopt)
+--------------------------------------------------------------------------*/
extern char *optarg;
int getopt(int, char *const[], const char *);
/*-------------------------------------------------------------------------+
| Auxiliary Functions
+--------------------------------------------------------------------------*/
static DWord
getNumArg(char *arg)
{
char *dummy;
if (arg[0] == '0')
if ((arg[1] == 'x') || (arg[1] == 'X')) /* Hexadecimal */
return (DWord)strtol(arg, &dummy, 16);
else /* Octal */
return (DWord)strtol(arg, &dummy, 8);
else /* Decimal */
return (DWord)strtol(arg, &dummy, 10);
} /* getNumArg */
/*-------------------------------------------------------------------------+
| Main
+--------------------------------------------------------------------------*/
void main(int argc, char *argv[])
{
FileHeader bootimgFileHdr; /* Output file header. */
LoadingInfo imageInfo; /* Section header. */
Byte auxBuf[BUFFER_BLOCK_SIZE]; /* */
DWord nRead; /* Number of bytes read. */
Word padSize; /* Size of padding at end of file. */
char *progName = argv[0]; /* Program name for errors. */
FILE *fpIn = stdin;
FILE *fpOut = stdout;
DWord binStart = DEFAULT_START_ADDR; /* Start address of image. */
DWord memLen = 0; /* Real length for compressed images. */
char currArg;
int argCount;
int flag; /* general purpose flag */
int verbose = 0; /* flag for verbose output */
while ((currArg = getopt(argc, argv, "hm:s:v")) >= 0) /* parse command line */
switch (currArg)
{
case 'h' :
fprintf(stderr, UsageMsg);
exit(0);
break;
case 'm' :
memLen = getNumArg(optarg);
break;
case 's' :
binStart = getNumArg(optarg);
break;
case 'v' :
verbose = 1;
break;
default :
fprintf(stderr, UsageMsg);
exit(1);
break;
} /* switch */
flag = 0;
for (argCount = 1; argCount < argc; argCount++)
if (argv[argCount][0] == '-')
{
if (argv[argCount][1] == 's')
argCount++;
}
else if (flag) /* we already have the input file => output file */
{
if ((fpOut = fopen(argv[argCount], "w")) == NULL)
{
fprintf(stderr, "%s: can't open %s\n", progName, argv[argCount]);
exit(1);
}
}
else /* input file */
{
if ((fpIn = fopen(argv[argCount], "r")) == NULL)
{
fprintf(stderr, "%s: can't open %s\n", progName, argv[argCount]);
exit(1);
}
flag = 1;
}
/*** begin: Conversion to Bootimg */
/*** File Header */
if (verbose)
fprintf(stderr, "\nBoot Image File Header:\n\n");
bootimgFileHdr.magicNum = BOOT_IMAGE_MAGIC; /* 4 bytes - magic number */
bootimgFileHdr.flagsLen = NON_VENDOR_LEN; /* 4 bytes - flags and length */
bootimgFileHdr.locAddr = getSegOff(binStart - BOOTIMG_HDR_SIZE);
/* 4 bytes - location address in ds:bx format */
bootimgFileHdr.execAddr = getSegOff(binStart);
/* 4 bytes - execute address in cs:ip format */
if (verbose)
{
fprintf(stderr, ">> location address in ds:bx format: %04x:%04x\n",
getSeg(bootimgFileHdr.locAddr), getOff(bootimgFileHdr.locAddr));
fprintf(stderr, ">> execute address in cs:ip format: %04x:%04x\n",
getSeg(bootimgFileHdr.execAddr), getOff(bootimgFileHdr.execAddr));
}
/*** Write File Header to output file */
fwrite((void *)(& bootimgFileHdr), sizeof(FileHeader), 1, fpOut);
/*** Sections */
if (verbose)
fprintf(stderr, "\nCode Section:\n\n");
imageInfo.flagsTagsLens = 0x04000004;
/* flags, vendor's tags, vendor and non-vendor lengths */
imageInfo.loadAddr = binStart; /* load address */
rewind(fpIn);
fseek(fpIn, 0, SEEK_END);
nRead = ftell(fpIn);
rewind(fpIn);
padSize = LAST_BLOCK_SIZE - (nRead % LAST_BLOCK_SIZE);
imageInfo.imageLength = nRead + padSize; /* image length */
imageInfo.memoryLength = (memLen != 0) ? memLen : imageInfo.imageLength;
/* memory length */
fwrite((void *)(&imageInfo), sizeof(LoadingInfo), 1, fpOut);
if (verbose)
{
fprintf(stderr, ">> load address: 0x%08lx\n", imageInfo.loadAddr);
fprintf(stderr, ">> image length: 0x%08lx\n", imageInfo.imageLength);
fprintf(stderr, ">> memory length: 0x%08lx\n\n", imageInfo.memoryLength);
}
nRead = BOOTIMG_HDR_SIZE - sizeof(FileHeader) - sizeof(LoadingInfo);
memset((void *)auxBuf, 0x00, nRead);
fwrite((void *)auxBuf, 1, nRead, fpOut);
nRead = fread((void *)auxBuf, 1, BUFFER_BLOCK_SIZE, fpIn);
while (!feof(fpIn))
{
fwrite((void *)auxBuf, BUFFER_BLOCK_SIZE, 1, fpOut);
nRead = fread((void *)auxBuf, 1, BUFFER_BLOCK_SIZE, fpIn);
}
fwrite((void *)auxBuf, 1, nRead, fpOut);
memset((void *)auxBuf, 0x00, padSize);
fwrite((void *)auxBuf, 1, padSize, fpOut);
fclose(fpOut);
fclose(fpIn);
/*** end: Conversion to Bootimg */
exit(0);
} /* main */

View File

@@ -0,0 +1,48 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH=@srcdir@
BSP_PIECES=startup clock console timer
GENERIC_PIECES=
# bummer; have to use $foreach since % pattern subst rules only replace 1x
OBJS=$(foreach piece, $(BSP_PIECES), ../$(piece)/$(ARCH)/$(piece).rel) \
$(foreach piece, $(GENERIC_PIECES), ../../../$(piece)/$(ARCH)/$(piece).rel)
LIB=$(ARCH)/libbsp.a
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/lib.cfg
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
$(LIB): ${OBJS}
$(make-library)
all: ${ARCH} $(SRCS) $(LIB)
$(INSTALL_VARIANT) -m 644 $(LIB) ${PROJECT_RELEASE}/lib

View File

@@ -352,10 +352,12 @@ int get_errno()
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
#if !defined(pc386)
void _exit(int status)
{
rtems_shutdown_executive(status);
}
#endif
#else

View File

@@ -352,10 +352,12 @@ int get_errno()
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
#if !defined(pc386)
void _exit(int status)
{
rtems_shutdown_executive(status);
}
#endif
#else