summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--c/src/exec/libcsupport/src/newlibc.c2
-rw-r--r--c/src/lib/libbsp/i386/pc386/HOWTO496
-rw-r--r--c/src/lib/libbsp/i386/pc386/Makefile.in15
-rw-r--r--c/src/lib/libbsp/i386/pc386/bsp_specs18
-rw-r--r--c/src/lib/libbsp/i386/pc386/clock/Makefile.in54
-rw-r--r--c/src/lib/libbsp/i386/pc386/clock/ckinit.c285
-rw-r--r--c/src/lib/libbsp/i386/pc386/clock/rtc.c224
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/Makefile.in53
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/console.c250
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/inch.c260
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/outch.c284
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/Makefile.in32
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/bsp.h192
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/coverhd.h104
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/Makefile.in56
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/start.s416
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/Makefile.in58
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c241
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/exit.c73
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/ldsegs.s205
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/linkcmds62
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/sbrk.c50
-rw-r--r--c/src/lib/libbsp/i386/pc386/timer/Makefile.in58
-rw-r--r--c/src/lib/libbsp/i386/pc386/timer/timer.c256
-rw-r--r--c/src/lib/libbsp/i386/pc386/timer/timerisr.s59
-rw-r--r--c/src/lib/libbsp/i386/pc386/times_i486dx191
-rw-r--r--c/src/lib/libbsp/i386/pc386/times_p5196
-rw-r--r--c/src/lib/libbsp/i386/pc386/tools/Makefile.in63
-rw-r--r--c/src/lib/libbsp/i386/pc386/tools/Spec.doc354
-rw-r--r--c/src/lib/libbsp/i386/pc386/tools/bin2boot.c239
-rw-r--r--c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in48
-rw-r--r--c/src/lib/libc/newlibc.c2
-rw-r--r--cpukit/libcsupport/src/newlibc.c2
33 files changed, 4898 insertions, 0 deletions
diff --git a/c/src/exec/libcsupport/src/newlibc.c b/c/src/exec/libcsupport/src/newlibc.c
index 9feb16e2db..d6a7f6fd6b 100644
--- a/c/src/exec/libcsupport/src/newlibc.c
+++ b/c/src/exec/libcsupport/src/newlibc.c
@@ -352,10 +352,12 @@ int get_errno()
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
+#if !defined(pc386)
void _exit(int status)
{
rtems_shutdown_executive(status);
}
+#endif
#else
diff --git a/c/src/lib/libbsp/i386/pc386/HOWTO b/c/src/lib/libbsp/i386/pc386/HOWTO
new file mode 100644
index 0000000000..1c239b6f92
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/HOWTO
@@ -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.
diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.in b/c/src/lib/libbsp/i386/pc386/Makefile.in
new file mode 100644
index 0000000000..bc37abe8d8
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/Makefile.in
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/bsp_specs b/c/src/lib/libbsp/i386/pc386/bsp_specs
new file mode 100644
index 0000000000..7e2a828674
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/bsp_specs
@@ -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}
+
diff --git a/c/src/lib/libbsp/i386/pc386/clock/Makefile.in b/c/src/lib/libbsp/i386/pc386/clock/Makefile.in
new file mode 100644
index 0000000000..6444b837e1
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/clock/Makefile.in
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/clock/ckinit.c b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c
new file mode 100644
index 0000000000..e02510c70e
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/clock/rtc.c b/c/src/lib/libbsp/i386/pc386/clock/rtc.c
new file mode 100644
index 0000000000..076e06c7e5
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/clock/rtc.c
@@ -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 */
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/Makefile.in b/c/src/lib/libbsp/i386/pc386/console/Makefile.in
new file mode 100644
index 0000000000..cd5b344be0
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/Makefile.in
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/console/console.c b/c/src/lib/libbsp/i386/pc386/console/console.c
new file mode 100644
index 0000000000..220b56f4a4
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/console.c
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/console/inch.c b/c/src/lib/libbsp/i386/pc386/console/inch.c
new file mode 100644
index 0000000000..e87e45728c
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/inch.c
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/console/outch.c b/c/src/lib/libbsp/i386/pc386/console/outch.c
new file mode 100644
index 0000000000..a7ee806ee4
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/outch.c
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/include/Makefile.in b/c/src/lib/libbsp/i386/pc386/include/Makefile.in
new file mode 100644
index 0000000000..a661e17cc5
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/include/Makefile.in
@@ -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)
diff --git a/c/src/lib/libbsp/i386/pc386/include/bsp.h b/c/src/lib/libbsp/i386/pc386/include/bsp.h
new file mode 100644
index 0000000000..b442389250
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/include/coverhd.h b/c/src/lib/libbsp/i386/pc386/include/coverhd.h
new file mode 100644
index 0000000000..55be1961bc
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/include/coverhd.h
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/start/Makefile.in b/c/src/lib/libbsp/i386/pc386/start/Makefile.in
new file mode 100644
index 0000000000..82e228c689
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/start/Makefile.in
@@ -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)
diff --git a/c/src/lib/libbsp/i386/pc386/start/start.s b/c/src/lib/libbsp/i386/pc386/start/start.s
new file mode 100644
index 0000000000..fb9019a742
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/start/start.s
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/startup/Makefile.in b/c/src/lib/libbsp/i386/pc386/startup/Makefile.in
new file mode 100644
index 0000000000..8d86ba9132
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/startup/Makefile.in
@@ -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
+
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
new file mode 100644
index 0000000000..73c9e6adeb
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/startup/exit.c b/c/src/lib/libbsp/i386/pc386/startup/exit.c
new file mode 100644
index 0000000000..b518c71418
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/startup/exit.c
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
new file mode 100644
index 0000000000..507eee92de
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/startup/linkcmds b/c/src/lib/libbsp/i386/pc386/startup/linkcmds
new file mode 100644
index 0000000000..516d9c3393
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/startup/linkcmds
@@ -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 = . ;
+ }
+}
diff --git a/c/src/lib/libbsp/i386/pc386/startup/sbrk.c b/c/src/lib/libbsp/i386/pc386/startup/sbrk.c
new file mode 100644
index 0000000000..851f9ed0e6
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/startup/sbrk.c
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/timer/Makefile.in b/c/src/lib/libbsp/i386/pc386/timer/Makefile.in
new file mode 100644
index 0000000000..c2ba3476d3
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/timer/Makefile.in
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/timer/timer.c b/c/src/lib/libbsp/i386/pc386/timer/timer.c
new file mode 100644
index 0000000000..0cbca572e8
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/timer/timer.c
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/timer/timerisr.s b/c/src/lib/libbsp/i386/pc386/timer/timerisr.s
new file mode 100644
index 0000000000..da9bf83b2b
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/timer/timerisr.s
@@ -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
+
diff --git a/c/src/lib/libbsp/i386/pc386/times_i486dx b/c/src/lib/libbsp/i386/pc386/times_i486dx
new file mode 100644
index 0000000000..3555c3ef7d
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/times_i486dx
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/times_p5 b/c/src/lib/libbsp/i386/pc386/times_p5
new file mode 100644
index 0000000000..c328fcecfc
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/times_p5
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/tools/Makefile.in b/c/src/lib/libbsp/i386/pc386/tools/Makefile.in
new file mode 100644
index 0000000000..d3ea3f7ce3
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/tools/Makefile.in
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/tools/Spec.doc b/c/src/lib/libbsp/i386/pc386/tools/Spec.doc
new file mode 100644
index 0000000000..c4ca3c4234
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/tools/Spec.doc
@@ -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
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c b/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
new file mode 100644
index 0000000000..f8eaa0faea
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
@@ -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 */
diff --git a/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
new file mode 100644
index 0000000000..bd06f5f90f
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
@@ -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
+
diff --git a/c/src/lib/libc/newlibc.c b/c/src/lib/libc/newlibc.c
index 9feb16e2db..d6a7f6fd6b 100644
--- a/c/src/lib/libc/newlibc.c
+++ b/c/src/lib/libc/newlibc.c
@@ -352,10 +352,12 @@ int get_errno()
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
+#if !defined(pc386)
void _exit(int status)
{
rtems_shutdown_executive(status);
}
+#endif
#else
diff --git a/cpukit/libcsupport/src/newlibc.c b/cpukit/libcsupport/src/newlibc.c
index 9feb16e2db..d6a7f6fd6b 100644
--- a/cpukit/libcsupport/src/newlibc.c
+++ b/cpukit/libcsupport/src/newlibc.c
@@ -352,10 +352,12 @@ int get_errno()
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
+#if !defined(pc386)
void _exit(int status)
{
rtems_shutdown_executive(status);
}
+#endif
#else