forked from Imagelibrary/rtems
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:
@@ -352,10 +352,12 @@ int get_errno()
|
|||||||
|
|
||||||
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
|
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
|
||||||
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
|
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
|
||||||
|
#if !defined(pc386)
|
||||||
void _exit(int status)
|
void _exit(int status)
|
||||||
{
|
{
|
||||||
rtems_shutdown_executive(status);
|
rtems_shutdown_executive(status);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|||||||
496
c/src/lib/libbsp/i386/pc386/HOWTO
Normal file
496
c/src/lib/libbsp/i386/pc386/HOWTO
Normal 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.
|
||||||
15
c/src/lib/libbsp/i386/pc386/Makefile.in
Normal file
15
c/src/lib/libbsp/i386/pc386/Makefile.in
Normal 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
|
||||||
18
c/src/lib/libbsp/i386/pc386/bsp_specs
Normal file
18
c/src/lib/libbsp/i386/pc386/bsp_specs
Normal 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}
|
||||||
|
|
||||||
54
c/src/lib/libbsp/i386/pc386/clock/Makefile.in
Normal file
54
c/src/lib/libbsp/i386/pc386/clock/Makefile.in
Normal 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
|
||||||
285
c/src/lib/libbsp/i386/pc386/clock/ckinit.c
Normal file
285
c/src/lib/libbsp/i386/pc386/clock/ckinit.c
Normal 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 */
|
||||||
224
c/src/lib/libbsp/i386/pc386/clock/rtc.c
Normal file
224
c/src/lib/libbsp/i386/pc386/clock/rtc.c
Normal 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 */
|
||||||
|
|
||||||
|
|
||||||
53
c/src/lib/libbsp/i386/pc386/console/Makefile.in
Normal file
53
c/src/lib/libbsp/i386/pc386/console/Makefile.in
Normal 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
|
||||||
250
c/src/lib/libbsp/i386/pc386/console/console.c
Normal file
250
c/src/lib/libbsp/i386/pc386/console/console.c
Normal 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 */
|
||||||
260
c/src/lib/libbsp/i386/pc386/console/inch.c
Normal file
260
c/src/lib/libbsp/i386/pc386/console/inch.c
Normal 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 */
|
||||||
284
c/src/lib/libbsp/i386/pc386/console/outch.c
Normal file
284
c/src/lib/libbsp/i386/pc386/console/outch.c
Normal 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 */
|
||||||
32
c/src/lib/libbsp/i386/pc386/include/Makefile.in
Normal file
32
c/src/lib/libbsp/i386/pc386/include/Makefile.in
Normal 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)
|
||||||
192
c/src/lib/libbsp/i386/pc386/include/bsp.h
Normal file
192
c/src/lib/libbsp/i386/pc386/include/bsp.h
Normal 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 */
|
||||||
104
c/src/lib/libbsp/i386/pc386/include/coverhd.h
Normal file
104
c/src/lib/libbsp/i386/pc386/include/coverhd.h
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/* coverhd.h
|
||||||
|
*
|
||||||
|
* This include file has defines to represent the overhead associated
|
||||||
|
* with calling a particular directive from C on this target.
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* All rights assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* This material may be reproduced by or for the U.S. Government pursuant
|
||||||
|
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||||
|
* notice must appear in all copies of this file and its derivatives.
|
||||||
|
*
|
||||||
|
* 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 */
|
||||||
56
c/src/lib/libbsp/i386/pc386/start/Makefile.in
Normal file
56
c/src/lib/libbsp/i386/pc386/start/Makefile.in
Normal 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)
|
||||||
416
c/src/lib/libbsp/i386/pc386/start/start.s
Normal file
416
c/src/lib/libbsp/i386/pc386/start/start.s
Normal 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
|
||||||
58
c/src/lib/libbsp/i386/pc386/startup/Makefile.in
Normal file
58
c/src/lib/libbsp/i386/pc386/startup/Makefile.in
Normal 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
|
||||||
|
|
||||||
241
c/src/lib/libbsp/i386/pc386/startup/bspstart.c
Normal file
241
c/src/lib/libbsp/i386/pc386/startup/bspstart.c
Normal 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 */
|
||||||
73
c/src/lib/libbsp/i386/pc386/startup/exit.c
Normal file
73
c/src/lib/libbsp/i386/pc386/startup/exit.c
Normal 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 */
|
||||||
205
c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
Normal file
205
c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
Normal 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
|
||||||
62
c/src/lib/libbsp/i386/pc386/startup/linkcmds
Normal file
62
c/src/lib/libbsp/i386/pc386/startup/linkcmds
Normal 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 = . ;
|
||||||
|
}
|
||||||
|
}
|
||||||
50
c/src/lib/libbsp/i386/pc386/startup/sbrk.c
Normal file
50
c/src/lib/libbsp/i386/pc386/startup/sbrk.c
Normal 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 */
|
||||||
58
c/src/lib/libbsp/i386/pc386/timer/Makefile.in
Normal file
58
c/src/lib/libbsp/i386/pc386/timer/Makefile.in
Normal 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
|
||||||
256
c/src/lib/libbsp/i386/pc386/timer/timer.c
Normal file
256
c/src/lib/libbsp/i386/pc386/timer/timer.c
Normal 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 */
|
||||||
59
c/src/lib/libbsp/i386/pc386/timer/timerisr.s
Normal file
59
c/src/lib/libbsp/i386/pc386/timer/timerisr.s
Normal 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
|
||||||
|
|
||||||
191
c/src/lib/libbsp/i386/pc386/times_i486dx
Normal file
191
c/src/lib/libbsp/i386/pc386/times_i486dx
Normal 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
|
||||||
196
c/src/lib/libbsp/i386/pc386/times_p5
Normal file
196
c/src/lib/libbsp/i386/pc386/times_p5
Normal 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
|
||||||
63
c/src/lib/libbsp/i386/pc386/tools/Makefile.in
Normal file
63
c/src/lib/libbsp/i386/pc386/tools/Makefile.in
Normal 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
|
||||||
354
c/src/lib/libbsp/i386/pc386/tools/Spec.doc
Normal file
354
c/src/lib/libbsp/i386/pc386/tools/Spec.doc
Normal 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
|
||||||
|
|
||||||
|
|
||||||
239
c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
Normal file
239
c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
Normal 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 */
|
||||||
48
c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
Normal file
48
c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
Normal 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
|
||||||
|
|
||||||
@@ -352,10 +352,12 @@ int get_errno()
|
|||||||
|
|
||||||
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
|
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
|
||||||
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
|
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
|
||||||
|
#if !defined(pc386)
|
||||||
void _exit(int status)
|
void _exit(int status)
|
||||||
{
|
{
|
||||||
rtems_shutdown_executive(status);
|
rtems_shutdown_executive(status);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|||||||
@@ -352,10 +352,12 @@ int get_errno()
|
|||||||
|
|
||||||
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
|
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
|
||||||
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
|
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
|
||||||
|
#if !defined(pc386)
|
||||||
void _exit(int status)
|
void _exit(int status)
|
||||||
{
|
{
|
||||||
rtems_shutdown_executive(status);
|
rtems_shutdown_executive(status);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user