From 7150f00f5be87fa8e37f7d00fbbef35645081138 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 1 Dec 1997 22:06:48 +0000 Subject: Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano and Jose Rufino of NavIST (http://pandora.ist.utl.pt/). --- c/src/exec/libcsupport/src/newlibc.c | 2 + c/src/lib/libbsp/i386/pc386/HOWTO | 496 ++++++++++++++++++++++++ c/src/lib/libbsp/i386/pc386/Makefile.in | 15 + c/src/lib/libbsp/i386/pc386/bsp_specs | 18 + c/src/lib/libbsp/i386/pc386/clock/Makefile.in | 54 +++ c/src/lib/libbsp/i386/pc386/clock/ckinit.c | 285 ++++++++++++++ c/src/lib/libbsp/i386/pc386/clock/rtc.c | 224 +++++++++++ c/src/lib/libbsp/i386/pc386/console/Makefile.in | 53 +++ c/src/lib/libbsp/i386/pc386/console/console.c | 250 ++++++++++++ c/src/lib/libbsp/i386/pc386/console/inch.c | 260 +++++++++++++ c/src/lib/libbsp/i386/pc386/console/outch.c | 284 ++++++++++++++ c/src/lib/libbsp/i386/pc386/include/Makefile.in | 32 ++ c/src/lib/libbsp/i386/pc386/include/bsp.h | 192 +++++++++ c/src/lib/libbsp/i386/pc386/include/coverhd.h | 104 +++++ c/src/lib/libbsp/i386/pc386/start/Makefile.in | 56 +++ c/src/lib/libbsp/i386/pc386/start/start.s | 416 ++++++++++++++++++++ c/src/lib/libbsp/i386/pc386/startup/Makefile.in | 58 +++ c/src/lib/libbsp/i386/pc386/startup/bspstart.c | 241 ++++++++++++ c/src/lib/libbsp/i386/pc386/startup/exit.c | 73 ++++ c/src/lib/libbsp/i386/pc386/startup/ldsegs.s | 205 ++++++++++ c/src/lib/libbsp/i386/pc386/startup/linkcmds | 62 +++ c/src/lib/libbsp/i386/pc386/startup/sbrk.c | 50 +++ c/src/lib/libbsp/i386/pc386/timer/Makefile.in | 58 +++ c/src/lib/libbsp/i386/pc386/timer/timer.c | 256 ++++++++++++ c/src/lib/libbsp/i386/pc386/timer/timerisr.s | 59 +++ c/src/lib/libbsp/i386/pc386/times_i486dx | 191 +++++++++ c/src/lib/libbsp/i386/pc386/times_p5 | 196 ++++++++++ c/src/lib/libbsp/i386/pc386/tools/Makefile.in | 63 +++ c/src/lib/libbsp/i386/pc386/tools/Spec.doc | 354 +++++++++++++++++ c/src/lib/libbsp/i386/pc386/tools/bin2boot.c | 239 ++++++++++++ c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in | 48 +++ c/src/lib/libc/newlibc.c | 2 + cpukit/libcsupport/src/newlibc.c | 2 + 33 files changed, 4898 insertions(+) create mode 100644 c/src/lib/libbsp/i386/pc386/HOWTO create mode 100644 c/src/lib/libbsp/i386/pc386/Makefile.in create mode 100644 c/src/lib/libbsp/i386/pc386/bsp_specs create mode 100644 c/src/lib/libbsp/i386/pc386/clock/Makefile.in create mode 100644 c/src/lib/libbsp/i386/pc386/clock/ckinit.c create mode 100644 c/src/lib/libbsp/i386/pc386/clock/rtc.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/Makefile.in create mode 100644 c/src/lib/libbsp/i386/pc386/console/console.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/inch.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/outch.c create mode 100644 c/src/lib/libbsp/i386/pc386/include/Makefile.in create mode 100644 c/src/lib/libbsp/i386/pc386/include/bsp.h create mode 100644 c/src/lib/libbsp/i386/pc386/include/coverhd.h create mode 100644 c/src/lib/libbsp/i386/pc386/start/Makefile.in create mode 100644 c/src/lib/libbsp/i386/pc386/start/start.s create mode 100644 c/src/lib/libbsp/i386/pc386/startup/Makefile.in create mode 100644 c/src/lib/libbsp/i386/pc386/startup/bspstart.c create mode 100644 c/src/lib/libbsp/i386/pc386/startup/exit.c create mode 100644 c/src/lib/libbsp/i386/pc386/startup/ldsegs.s create mode 100644 c/src/lib/libbsp/i386/pc386/startup/linkcmds create mode 100644 c/src/lib/libbsp/i386/pc386/startup/sbrk.c create mode 100644 c/src/lib/libbsp/i386/pc386/timer/Makefile.in create mode 100644 c/src/lib/libbsp/i386/pc386/timer/timer.c create mode 100644 c/src/lib/libbsp/i386/pc386/timer/timerisr.s create mode 100644 c/src/lib/libbsp/i386/pc386/times_i486dx create mode 100644 c/src/lib/libbsp/i386/pc386/times_p5 create mode 100644 c/src/lib/libbsp/i386/pc386/tools/Makefile.in create mode 100644 c/src/lib/libbsp/i386/pc386/tools/Spec.doc create mode 100644 c/src/lib/libbsp/i386/pc386/tools/bin2boot.c create mode 100644 c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in 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 .tgz | tar xvof - + + OR + + gunzip -c .tgz | tar xvof - + + OR + + gtar xzvf .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 .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 .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 ). You should then add 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 . 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- + + cp configure.sub libgloss + cp install.sh libgloss + + CC=gcc CFLAGS="-O4 -g" ./configure --verbose \ + --target=i386-elf32-rtems \ + --prefix= + + 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 . + + 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 /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 '/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 + module load + + OR + + module switch + + 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 + +#include +#include +#include + +/*-------------------------------------------------------------------------+ +| 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 + +#include + +/*-------------------------------------------------------------------------+ +| 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 + +#include +#include +#include + +/*-------------------------------------------------------------------------+ +| 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 +#include + +/*-------------------------------------------------------------------------+ +| 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 + +#include +#include + +/*-------------------------------------------------------------------------+ +| 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 +#include +#include +#include + +/*-------------------------------------------------------------------------+ +| 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 ++--------------------------------------------------------------------------*/ + + +#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 + +#include +#include +#include + +#ifdef STACK_CHECKER_ON +#include +#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 + +#include + +/*-------------------------------------------------------------------------+ +| 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 +#include + +/*-------------------------------------------------------------------------+ +| 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 + +#include +#include + +/*-------------------------------------------------------------------------+ +| 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 +#include +#include +#include +#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 [ []] [-s ] [-v]\n\ +\n\ + : input file name\n\ + : output file name\n\ + -s : start address of binary image\n\ + -m : 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 -- cgit v1.2.3