FOC/L4RE: Upstream revision 40

This commit is contained in:
Sebastian Sumpf
2013-01-11 17:00:47 +01:00
commit 808d228872
7744 changed files with 987172 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
IMPORTANT NOTE ON BENCHMARKING Fiasco.OC/L4RE SOFTWARE
======================================================
Owing to the flexibility of configurations possible with this software we
urge you to send any benchmarking results for review prior to publication to
benchmarking@os.inf.tu-dresden.de
to get feedback and an 'OK' from our side that the presented figures are
reasonable.
Thanks.

339
kernel/fiasco/COPYING Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

1
kernel/fiasco/MAINTAINER Normal file
View File

@@ -0,0 +1 @@
mailaddr aw11@os.inf.tu-dresden.de, adam@os.inf.tu-dresden.de

213
kernel/fiasco/Makefile Normal file
View File

@@ -0,0 +1,213 @@
#
#
# GLOBAL Makefile for FIASCO
# enviroment
DFLBUILDDIR := build
ALLBUILDDIR := build-all
RANDBUILDDIR := build-rand
TEMPLDIR := src/templates
MAKEFILETEMPL := $(TEMPLDIR)/Makefile.builddir.templ
MANSUBDIRS := man
INSTALLSUBDIRS := $(MANSUBDIRS)
CLEANSUBDIRS := $(MANSUBDIRS) $(wildcard $(DFLBUILDDIR))
CONFIG_FILE := $(TEMPLDIR)/globalconfig.out
TEST_TEMPLATES := $(patsubst $(CONFIG_FILE).%,%,$(wildcard $(CONFIG_FILE).*))
TEST_TEMPLATES := $(if $(TEMPLATE_FILTER),$(filter $(TEMPLATE_FILTER),$(TEST_TEMPLATES)),$(TEST_TEMPLATES))
DFL_TEMPLATE := ia32-1
PL ?= 1
getdir = $(shell \
bd="$(1)"; \
if [ "$${bd\#/}" = "$$bd" -a \
"$${bd\#*..}" = "$$bd" ]; then \
relp=".."; \
while [ "$${bd\#*/}" != "$$bd" ]; do \
relp="$$relp/.."; \
bd="$${bd\#*/}"; \
done; \
echo "$$relp"; \
else \
pwd; \
fi \
)
buildmakefile = mkdir -p "$(1)"; \
perl -p -i -e '$$s = "$(CURDIR)/src"; s/\@SRCDIR\@/$$s/' \
< $(MAKEFILETEMPL) > $(1)/Makefile
ifneq ($(strip $(B)),)
BUILDDIR := $(B)
endif
ifneq ($(strip $(BUILDDIR)),)
builddir:
@echo "Creating build directory \"$(BUILDDIR)\"..."
@if [ -e "$(BUILDDIR)" ]; then \
echo "Already exists, aborting."; \
exit 1; \
fi
@$(call buildmakefile,$(BUILDDIR))
@echo "done."
endif
ifneq ($(strip $(T)),)
this:
set -e; \
test -f $(TEMPLDIR)/globalconfig.out.$(T); \
bdir=T-$(DFLBUILDDIR)-$(T); \
rm -rf $$bdir; \
$(call buildmakefile,T-$(DFLBUILDDIR)-$(T)); \
cp $(TEMPLDIR)/globalconfig.out.$(T) $$bdir/globalconfig.out; \
$(MAKE) -C $$bdir
endif
$(DFLBUILDDIR): fiasco.builddir.create
$(MAKE) -C $@ -j$(PL)
all: fiasco man
clean cleanall:
set -e; for i in $(CLEANSUBDIRS); do $(MAKE) -C $$i $@; done
purge: cleanall
$(RM) -r $(DFLBUILDDIR)
man:
set -e; for i in $(MANSUBDIRS); do $(MAKE) -C $$i; done
fiasco.builddir.create:
[ -e $(DFLBUILDDIR)/Makefile ] || \
($(call buildmakefile,$(DFLBUILDDIR)))
[ -f $(DFLBUILDDIR)/globalconfig.out ] || { \
cp $(TEMPLDIR)/globalconfig.out.$(DFL_TEMPLATE) \
$(DFLBUILDDIR)/globalconfig.out; \
}
config $(filter config %config,$(MAKECMDGOALS)): fiasco.builddir.create
$(MAKE) -C $(DFLBUILDDIR) $@
fiasco: fiasco.builddir.create
$(MAKE) -C $(DFLBUILDDIR) -j$(PL)
checkall l4check:
error=0; \
$(RM) -r $(ALLBUILDDIR); \
for X in $(TEST_TEMPLATES); do \
echo -e "\n= Building configuration: $$X\n\n"; \
$(call buildmakefile,$(ALLBUILDDIR)/$$X); \
cp $(TEMPLDIR)/globalconfig.out.$$X \
$(ALLBUILDDIR)/$$X/globalconfig.out; \
if $(MAKE) -C $(ALLBUILDDIR)/$$X -j$(PL); then \
[ -z "$(KEEP_BUILD_DIRS)" ] && \
$(RM) -r $(ALLBUILDDIR)/$$X; \
else \
error=$$?; \
failed="$$failed $$X"; \
fi \
done; \
rmdir $(ALLBUILDDIR) >/dev/null 2>&1; \
[ "$$failed" ] && echo -e "\nFailed configurations:$$failed"; \
exit $$error;
checkallp:
$(RM) -r $(ALLBUILDDIR)
$(MAKE) dobuildparallel SHELL=bash
.PHONY: dobuildparallel checkallp
dobuildparallel: $(addprefix $(ALLBUILDDIR)/,$(TEST_TEMPLATES))
error=0; \
echo "======================================================"; \
for d in $(TEST_TEMPLATES); do \
if [ -e $(ALLBUILDDIR)/$$d/build.failed ]; then \
error=1; failed="$$failed $$d"; \
fi; \
done; \
for f in $$failed; do echo "====== Failed Build Log: $$f ======"; \
tail -60 $(ALLBUILDDIR)/$$f/build.log; \
done; \
rmdir $(ALLBUILDDIR) >/dev/null 2>&1; \
[ "$$failed" ] && echo -e "\nFailed configurations:$$failed"; \
exit $$error;
$(addprefix $(ALLBUILDDIR)/,$(TEST_TEMPLATES)):
$(call buildmakefile,$@)
cp $(TEMPLDIR)/globalconfig.out.$(patsubst $(ALLBUILDDIR)/%,%,$@) \
$@/globalconfig.out
$(MAKE) -C $@ 2>&1 | tee $@/build.log; \
if [ $${PIPESTATUS[0]} = 0 ]; \
then [ -z "$(KEEP_BUILD_DIRS)" ] && $(RM) -r $@; \
else echo $${PIPESTATUS[0]} > $@/build.failed; fi
list:
@echo "Templates:"
@echo $(TEST_TEMPLATES)
randcheck:
$(RM) -r $(RANDBUILDDIR); \
$(call buildmakefile,$(RANDBUILDDIR)/b); \
while true; do \
$(RM) $(RANDBUILDDIR)/b/globalconfig.out; \
$(MAKE) -C $(RANDBUILDDIR)/b randconfig; \
fn=$$(cat $(RANDBUILDDIR)/b/globalconfig.out \
| grep -e "^CONFIG_" | sort | sha1sum \
| cut -f1 -d\ ); \
if [ -e "ok-$$fn" -o -e "failed-$$fn" ]; then \
echo "Configuration $$fn already checked." \
continue; \
fi; \
if $(MAKE) -C $(RANDBUILDDIR)/b -j$(PL); then \
cp $(RANDBUILDDIR)/b/globalconfig.out \
$(RANDBUILDDIR)/ok-$$fn; \
else \
[ -n "$$STOP_ON_ERROR" ] && exit 1; \
cp -a $(RANDBUILDDIR)/b \
$(RANDBUILDDIR)/failed-$$fn; \
fi; \
done
randcheckstop:
$(MAKE) STOP_ON_ERROR=1 randcheck
randcheckagain:
for f in $(RANDBUILDDIR)/failed-*; do \
if $(MAKE) -C $$f -j$(PL); then \
$(RM) -rf $$f; \
else \
[ -n "$$STOP_ON_ERROR" ] && exit 1; \
fi \
done
randcheckagainstop:
$(MAKE) STOP_ON_ERROR=1 randcheckagain
help:
@echo
@echo "fiasco Builds the default configuration ($(DFL_TEMPLATE))"
@echo "T=template Build a certain configuration"
@echo "checkall Build all template configurations in one go"
@echo "list List templates"
@echo
@echo "config menuconfig xconfig oldconfig"
@echo " Configure kernel in \"$(DFLBUILDDIR)\""
@echo "$(DFLBUILDDIR) Build kernel in \"$(DFLBUILDDIR)\""
@echo "clean cleanall clean or cleanall in \"$(CLEANSUBDIRS)\""
@echo "purge cleanall, remove \"$(DFLBUILDDIR)\" and build helper"
@echo
@echo "Creating a custom kernel:"
@echo
@echo " Create a build directory with:"
@echo " make BUILDDIR=builddir"
@echo " Then build the kernel:"
@echo " cd builddir"
@echo " make config"
@echo " make"
@echo
@echo "Call \"make help\" in the build directory for more information on build targets."
@echo
@echo "Default target: $(DFLBUILDDIR)"
@echo
.PHONY: man install clean cleanall fiasco.builddir.create fiasco \
l4check checkall config oldconfig menuconfig nconfig xconfig \
randcheck randcheckstop help

71
kernel/fiasco/README Normal file
View File

@@ -0,0 +1,71 @@
Welcome to Fiasco.OC!
----------------------
Fiasco is a microkernel and an be used to construct flexible systems. We at
TU Dresden use it as a base for our TUD:OS system which supports running
real-time and time-sharing applications as well as virtualization
concurrently on one system. However, Fiasco is not only suitable for big and
complex systems, but also for small, embedded applications.
This distribution contains the Fiasco.OC microkernel and tools to build
it. User level applications are not included in this package.
Licensing
---------
Fiasco is freely redistributable under the GPL (see l4/kernel/fiasco/COPYING).
For different licensing schemes please contact us at:
fiasco-core@os.inf.tu-dresden.de
This is a closed list, proper mails will be let through by the moderator.
For more details, see our webpage at: http://os.inf.tu-dresden.de/fiasco/
Supported architectures and ABIs
--------------------------------
* IA32 (32-bit Intel, AMD and compatible CPUs, i486 and above)
* AMD64 (64-bit Intel, AMD and compatible CPUs)
* ARM (various ARM CPUs and platforms)
* UX (Linux usermode emulation of Fiasco/L4)
A list of changes since the last release can be found in the CHANGES file.
Building the Fiasco kernel
--------------------------
To compile Fiasco you need a recent version of gcc and a recent version of
GNU binutils, GNU make and Perl version 5.6 or later.
Change to the directory fiasco/l4/kernel/fiasco/ and
create a build directory with "make BUILDDIR=build" and change to the
'build' directory. Optionally modify the default configuration using
"make menuconfig". Then compile the kernel by typing "make".
The kernel image can then be found in fiasco/l4/kernel/fiasco/build/ as
'fiasco'.
For further information refer to: http://os.inf.tu-dresden.de/fiasco/build.html
Mailing List
------------
For problem reports and suggestions regarding the Fiasco microkernel,
please subscribe and send mail to the l4-hackers mailing list:
http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers/
Remote SVN
----------
The latest development versions are available from our SVN server.
The truly bleeding edge will want to check out daily snapshots from there.
However, be aware that these may not always run correctly.
You can also get user land programs for L4 from this SVN.
For information how to use SVN see:
http://os.inf.tu-dresden.de/L4Re/download.html
Enjoy!
The Fiasco Team

View File

@@ -0,0 +1,22 @@
define tcb
p *(class thread_t*)((unsigned)&_tcbs_1 + (($arg0 << 17) + ($arg1 << 10) << 1))
end
define dtcb
graph display *(class thread_t*)((unsigned)&_tcbs_1 + (($arg0 << 17) + ($arg1 << 10) << 1))
end
define tcbat
p *(class thread_t*)($arg0)
end
file fiasco.image
set remotebaud 115200
## for debugging on COM2
target remote /dev/ttyS1
## for debugging on COM2
#target remote /dev/ttyS0
set output-radix 16
set history save on

View File

@@ -0,0 +1,31 @@
This is a list of (funny) things, you have to check before you dig
into deep debugging sessions.
* Check for assumptions about structure layout (and v-table
pointers)
* Check for assumptions about bitfield layout (just the same
as above, but as reminder)
* Is there code with side effects (i++=i++ or so)?
* Some unclobbered registers or memory in inline assembly?
- Keep in mind there was a problem on x86 with the clobber
list, you have to mark clobbered registers as output to
a dummy variable.
- Clobbering ebp has no effects. Really! We've tried it!
Also there is no output constraint, so if you use ebp,
you must explicitly save/restore it.
* Missing 'volatile' on shared and manipulated data?
* You made assumptions about the width of native data types?
Put some printfs into the code, and hope they will not cover
the bug. Or just use JDB and find the bug.
Remember: FIND THE BUG.

View File

@@ -0,0 +1,18 @@
Do "make DEPS" for full fine-grained dependency information.
---
checksum
boot_info
checksum
---
boot_info
checksum
boot_info
---
TOTAL CIRCULAR DEPS:
2

View File

@@ -0,0 +1,6 @@
Do "make DEPS" for full fine-grained dependency information.
---
TOTAL CIRCULAR DEPS:
0

View File

@@ -0,0 +1,18 @@
Do "make DEPS" for full fine-grained dependency information.
---
checksum
boot_info
checksum
---
boot_info
checksum
boot_info
---
TOTAL CIRCULAR DEPS:
2

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
Do "make DEPS" for full fine-grained dependency information.
---
TOTAL CIRCULAR DEPS:
0

View File

@@ -0,0 +1,13 @@
# lines starting with '*' are black lists for dependents and dependees
# lines starting with '->' are black lists for dependees
# lines starting with ':' are black lists for dependents
# KERNEL
*config.* l4_types types globalconfig
# LIBC
*.?stdlib .?assert .?stdio .?stdarg .?string __main _exit initfini
*.?ctype .?setjmp .?alloca .?limits .?stddef .?cdefs .?signal
*sys_wait sys_types sys_ptrace sys_user .?errno asm_unistd sys_stat
*sys_mman fcntl sys_poll sys_ucontext simpleio keycodes

804
kernel/fiasco/src/Kconfig Normal file
View File

@@ -0,0 +1,804 @@
mainmenu "Fiasco configuration"
config KERNELVERSION
string
option env="KERNELVERSION"
config INCLUDE_PPC32
bool
option env="INCLUDE_PPC32"
help
Use "INCLUDE_PPC32=y make config" to include ppc32 options.
config INCLUDE_SPARC
bool
option env="INCLUDE_SPARC"
help
Use "INCLUDE_SPARC=y make config" to include sparc options.
menu "Target configuration"
choice
prompt "Architecture"
default IA32
config IA32
bool "Intel IA-32 processor family"
config AMD64
bool "AMD64 processor family"
select CONTEXT_4K
config ARM
bool "ARM processor family"
config PPC32
bool "PowerPC 32 processor family (Caution: INCOMPLETE!)"
depends on EXPERIMENTAL && INCLUDE_PPC32
help
PPC32 testing version, mainly for MPC5200 (603e). Currently,
there is no support whatsoever.
select CONTEXT_4K
select BIG_ENDIAN
config SPARC
bool "SPARC v8 processor family (Caution: EXPERIMENTAL)"
depends on EXPERIMENTAL && INCLUDE_SPARC
help
SPARC v8 is supposed to run on the LEON3 platform.
It is unsupported at the moment.
select CONTEXT_4K
endchoice
config BIG_ENDIAN
bool
choice
prompt "Platform"
default PF_INTEGRATOR if ARM
default PF_PC if IA32
default PF_PC if AMD64
default PF_MP52CXX if PPC32
default PF_LEON3 if SPARC
config PF_PC
bool "PC platform"
depends on IA32 || AMD64
config PF_UX
bool "Linux Usermode Platform"
depends on IA32
select JDB
# PF_CHOICE
endchoice
# PF_INCLUDE
config ABI_VF
def_bool y
config PF_ARM_MP_CAPABLE
bool
default y if ARM_MPCORE || ARM_CORTEX_A9
config CAN_ARM_CPU_SA1100
bool
config CAN_ARM_CPU_XSCALE
bool
config CAN_ARM_CPU_920T
bool
config CAN_ARM_CPU_926
bool
config CAN_ARM_CPU_1136
bool
config CAN_ARM_CPU_1176
bool
config CAN_ARM_CPU_MPCORE
bool
config CAN_ARM_CPU_CORTEX_A8
bool
config CAN_ARM_CPU_CORTEX_A9
bool
config CAN_ARM_CACHE_L2CXX0
bool
choice
prompt "CPU"
default IA32_686 if IA32
default ARM_926 if ARM
default AMD64_K8 if AMD64
default PPC32_603e if PPC32
default LEON3 if SPARC
config ARM_PXA
bool "Intel XScale"
depends on PF_XSCALE
config ARM_SA
bool "Intel StrongARM"
depends on PF_SA1100
config ARM_920T
bool "ARM 920T Processor"
depends on PF_S3C2410
config ARM_926
bool "ARM 926 Processor"
depends on CAN_ARM_CPU_926
config ARM_1136
bool "ARM 1136 CPU"
depends on CAN_ARM_CPU_1136
config ARM_1176
bool "ARM 1176 CPU"
depends on CAN_ARM_CPU_1176
config ARM_MPCORE
bool "ARM MPCore CPU"
depends on CAN_ARM_CPU_MPCORE
config ARM_CORTEX_A8
bool "ARM Cortex-A8 CPU"
depends on CAN_ARM_CPU_CORTEX_A8
config ARM_CORTEX_A9
bool "ARM Cortex-A9 CPU"
depends on CAN_ARM_CPU_CORTEX_A9
config IA32_486
bool "Intel 80486"
depends on IA32
help
Choose this if you have an Intel 80486 or equivalent CPU (i486).
config IA32_586
bool "Intel Pentium / AMD K5"
depends on IA32
help
Choose this if you have an Intel Pentium or compatible i586 CPU.
config IA32_686
bool "Intel Pentium Pro"
depends on IA32
help
Choose this if you have an Intel Pentium Pro or compatible i686 CPU.
config IA32_P2
bool "Intel Pentium II / Celeron II"
depends on IA32
help
Choose this if you have an Intel Pentium II or Pentium II based Celeron.
config IA32_P3
bool "Intel Pentium III / Celeron III"
depends on IA32
help
Choose this if you have an Intel Pentium III or Pentium III based Celeron.
config IA32_P4
bool "Intel Pentium 4 / Celeron 4"
depends on IA32
help
Choose this if you have an Intel Pentium 4 or Pentium 4 based Celeron.
config IA32_PM
bool "Intel Pentium M"
depends on IA32
help
Choose this if you have an Intel Pentium M.
config IA32_CORE2
bool "Intel Core 2"
depends on IA32
help
Choose this if you have an Intel Core 2.
config IA32_ATOM
bool "Intel Atom"
depends on IA32
help
Choose this if you have an Intel Atom.
config IA32_K6
bool "AMD K6 / K6-II / K6-III"
depends on IA32
help
Choose this if you have an AMD K6 CPU.
config IA32_K7
bool "AMD Athlon / Duron"
depends on IA32
help
Choose this if you have an AMD Athlon or Duron CPU.
config IA32_K8
bool "AMD Opteron / Athlon64"
depends on IA32
help
Choose this if you have an AMD Opteron or Athlon64 CPU.
config IA32_K10
bool "AMD Barcelona (K10)"
depends on IA32
help
Choose this if you have an AMD Barcelona based CPU.
config AMD64_K8
bool "AMD Opteron / Athlon64"
depends on AMD64
help
Choose this if you have an AMD Opteron or Athlon64 CPU.
config AMD64_CORE2
bool "Intel Core 2"
depends on AMD64
help
Choose this if you have an Intel Core 2.
config AMD64_ATOM
bool "Intel Atom"
depends on AMD64
help
Choose this if you have an Intel Atom.
config AMD64_K10
bool "AMD Barcelona (K10)"
depends on AMD64
help
Choose this if you have an AMD Barcelona based CPU.
config PPC32_603e
bool "PowerPC 603e"
depends on PPC32
help
Choose this if you have an PowerPC 603e CPU.
config LEON3
bool "Gaisler SPARC LEON3"
depends on SPARC
help
Choose this if you have a LEON3 CPU.
endchoice
config CPU_VIRT
bool "Enable CPU virtualization (SVM and VT)"
depends on PF_PC
help
Support virtualization extensions that comes with x86 CPUs,
including nested paging. This feature allows you to run a virtual
machine monitor (VMM) on top of Fiasco.
config ARM_ALIGNMENT_CHECK
bool "Enable alignment check"
depends on ARM
help
Enable if you want to have alignment check enabled.
config ARM_TZ
bool "Enable ARM TrustZone support"
depends on (ARM_1176 || ARM_CORTEX_A8 || ARM_CORTEX_A9) && EXPERIMENTAL
help
Support ARM TrustZone security extension.
config ARM_CA9_ENABLE_SWP
bool "Enable the deprecated 'swp' instruction"
depends on ARM_CORTEX_A9
help
Enabling this option enables the deprecated 'swp' instruction.
Avoid to enable it.
config ARM_CACHE_L2CXX0
bool "Enable L2 Cache"
default y
depends on CAN_ARM_CACHE_L2CXX0
help
Enable L2 cache functionality.
choice
prompt "Timer tick source"
depends on PF_PC || PF_UX
default SCHED_APIC
config SCHED_PIT
bool "Use PIT for scheduling"
depends on (PF_PC || PF_UX) && !MP
help
Normally, Fiasco uses the RTC at IRQ8 for scheduling. This can be
disadvantageous in certain circumstances, e.g. VMWare doesn't seem
to emulate the RTC good enough so that not enough timer interrupts
are produced. The PIT mode (using IRQ0) seems to work better in
this case. It is generally safe to use this option, so if you are
unsure, say 'Y'.
Consider that the interrupt priorities change: Using RTC, IRQ8 has
the highest priority. Using PIT, IRQ0 has the highest priority.
The only case where PIT scheduling does not work is with
profiling. If profiling is enabled the PIT is used for generating
the profiling interrupts.
config SCHED_RTC
bool "Use RTC for scheduling"
depends on PF_PC && !MP
help
'Yes' is the standard for this option. If this option is set
Fiasco uses the RTC on IRQ 8 for scheduling. This can be
disadvantageous in certain circumstances, e.g. VMWare doesn't seem
to emulate the RTC good enough so that not enough timer interrupts
are produced. The PIT (8254) mode (say 'no' here), seems to work
better in this case. It is generally safe to use the PIT, so if
you are unsure, say 'no'.
Consider that the interrupt priorities change: Using RTC, IRQ8 has
the highest priority. Using PIT, IRQ0 has the highest priority.
The only case where PIT scheduling does not work is with
profiling. If profiling is enabled the PIT is used for generating
the profiling interrupts and the RTC must be used for scheduling.
In the case where profiling shall be used within VMWare the
SLOW_RTC option must be set, so that the timer resolution of
Fiasco is reduced to 100Hz.
config SCHED_APIC
bool "Use APIC timer for scheduling"
depends on PF_PC
help
Use the Local APIC for scheduling.
config SCHED_HPET
bool "Use HPET timer for scheduling (EXPERIMENTAL)"
depends on PF_PC && !MP && EXPERIMENTAL
help
Use the HPET timer for scheduling.
endchoice
config WORKAROUND_AMD_FPU_LEAK
bool "Enables workaroud for AMD FPU security leak"
depends on PF_PC
help
If you use Fiasco for high assurance, high security and use AMD
CPUs you should enable this option. In any other case it is no
harm to disable it.
config REGPARM3
bool "Compile with regparm=3"
default y
depends on IA32 && PF_PC
help
Compile Fiasco with -mregparm=3. This uses a different ABI and
passes the first three arguments of a function call in registers.
config FPU
bool "Enable FPU co-processor"
depends on ARM
help
Enable this if your platform has hardware floating point support.
config ARM_1176_CACHE_ALIAS_FIX
bool "Use cache restriction to supress aliasing issue on ARM1176"
depends on ARM_1176
help
The ARM1176 processor might have a memory aliasing problem when
using cache sizes of more than 16kB cache. Enabling this option
enables the workaround of reducing the cache size to 16kB.
endmenu # target
menu "Kernel options"
config MP
bool "Enable multi processor support"
depends on (PF_PC || PF_ARM_MP_CAPABLE || (PF_UX && EXPERIMENTAL))
help
Enable support for machines with multiple processors.
config MP_MAX_CPUS
int "Maximal supported number of CPUs"
depends on MP
range 1 128
default 4
help
The maximum number of CPUs the kernel supports.
#config ASSEMBLER_IPC_SHORTCUT
# bool "Assembler IPC shortcut"
# default y
# depends on (PF_PC || PF_UX) && !MP
# help
# Use the assembler IPC shortcut to get even better short IPC
# performance in the common case.
config CONTEXT_4K
bool #"TCB size of 4k"
default y
help
Use this option to use 4K kernel stacks. Only disable this option
when you know what you're doing.
config IO_PROT
bool "Enable I/O port protection"
default y
depends on PF_PC
help
Enabling this option adds I/O port protection to the kernel. That
means that every thread starts running at IOPL 0 which means that
only the kernel has full access to all I/O ports. This includes
the right to set and clear the interrupt flags (that is using cli
and sti). Access rights to I/O ports can be mapped like memory. If
a task has access to the whole I/O port space, its IOPL is raised
to 3 allowing the task to use cli and sti.
config SLOW_RTC
bool "Use RTC with 100 ticks per second"
depends on SCHED_RTC
help
This option should be enabled if you use VMWare and no PIT
scheduling. The timer resolution is lowered to 100 ticks per
second.
config ONE_SHOT
bool "Use scheduling timer in one-shot mode"
depends on SCHED_APIC && SYNC_TSC
help
More costly than periodic but more fine-granular scheduling
possible. EXPERIMENTAL!
config SYNC_TSC
bool "Use time-stamp counter for KIP and scheduling accounting"
depends on PF_PC && IA32
help
Synchronize the internal kernel clock with the CPU time stamp
counter.
config FINE_GRAINED_CPUTIME
bool "Fine-grained CPU time"
help
Measure CPU time consumed by a thread from switching to the thread
until switching to another thread. Induces an overhead during each
thread switch, so only activate it for debugging.
config UX_CON
bool "Graphical console (requires SDL library!)"
depends on PF_UX
help
Fiasco-UX can supply a graphical console for the L4 program it is
running. Enabling this option will build the additional program
but needs the SDL library including development header files
installed.
config UX_NET
bool "Network support"
depends on PF_UX
help
Enabling this option makes Fiasco-UX provide network support for
L4 programs.
choice
prompt "Scheduler"
default FIXED_PRIO
config SCHED_FIXED_PRIO
bool "Fixed priority scheduler"
help
Choose this for the standard fixed priority scheduler with
256 priority levels.
config SCHED_WFQ
bool "Weighted fair queueing scheduler"
depends on EXPERIMENTAL
help
Choose this scheduler for a weighted fair queueing scheduler
running with dynamic priorities.
config SCHED_FP_WFQ
bool "Combined fixed priority RT and WFQ scheduler"
depends on EXPERIMENTAL
help
Combination of Fixed priority and weighted fair queueing
scheduler.
endchoice
config DISABLE_VIRT_OBJ_SPACE
bool "No virtually mapped array for cap tables"
depends on (PF_PC || ARM) && EXPERIMENTAL
default n
endmenu # kernel options
menu "Debugging"
config INLINE
bool "Generate inline code"
default y
help
Inlining specifies that it is desirable for the compiler to
integrate functions declared 'inline' into the calling routine.
This usually leads to faster code, so unless you want to debug the
kernel you should say 'Y' here.
config NDEBUG
bool "Do not compile assertions"
help
Don't insert assertions into the code. Should be enabled for
kernels which are used for measurements.
config NO_FRAME_PTR
bool "Compile without frame pointer"
default y
help
Enabling this option optimizes for speed but makes debugging more
difficult.
config STACK_DEPTH
bool "Measure stack depth of threads"
help
When this option is enabled, each thread control block is marked
with magic numbers while creation. The function ``show thread
lists'' scans the TCB for these magic numbers and shows the
currently used depth of each thread.
config LIST_ALLOC_SANITY
bool "Sanity checks in low level allocator"
help
When this option is enabled the low level memory allocator does
extra sanity checks on its data structures before and after every
operation. This can halp detect flaws like double frees or memory
corruption by other means.
These tests are very expensive so only enable them if a problem
with memory allocation is expected.
config BEFORE_IRET_SANITY
bool "Sanity checks at syscall entry/exit"
depends on PF_PC
help
Perform the following additional sanity checks before returning to
usermode:
- Does the thread hold any locks?
- Is the thread locked by any other thread?
- Does the thread have the right state:
* Thread_ready must be set.
* Thread_cancel and Thread_fpu_owner might be set.
* Any other state bit must not be set.
Don't use Fiasco compiled with this option for performance analysis!
config GSTABS
bool "Compile with gstabs+ debugging information"
depends on n
help
Enabling this option includes the debugging information using the
older gstabs+ format into the kernel image. This is necessary to
access line number information of the kernel from JDB.
config IRQ_SPINNER
bool "Display IRQ activity on VGA screen"
depends on PF_PC
help
Display IRQ activity on VGA screen.
config WATCHDOG
bool "Enable Watchdog support"
default y
depends on PF_PC
help
Enable support for watchdog using the builtin Local APIC and a
performance counter. The watchdog can be enabled using the
-watchdog command line option.
config SERIAL
bool "Support for debugging over serial line"
depends on PF_PC || ARM || PPC32 || SPARC
default y
help
This option enables support for input/output over serial interface.
menuconfig JDB
bool "JDB kernel debugger"
default y
help
The powerful Fiasco kernel debugger.
if JDB
config JDB_LOGGING
bool "JDB extended logging"
help
There are two classes of logging events: Basic events don't
consume any time if they are disabled (ipc, ipc result,
pagefaults, unmap). Extended logging events add an additional
overhead of most probably less than 10 cycles if they are
disabled. These events can be activated/deactivated by the 'O'
command in jdb.
Should be disabled for kernels which are used for measurements.
config JDB_DISASM
bool "JDB disassembler"
default n if ARM
default y
help
Add support for disassembly. Increases memory foot-print, only
enable when needed.
config JDB_GZIP
bool "GZIP compressed dumps"
default n if ARM
default y
help
Add supprt for gzip compressed dumps of the trace buffer.
Increases memory foot-print, only enabled when needed.
config JDB_ACCOUNTING
bool "JDB accounting"
depends on IA32
help
Enable accounting information about IPCs, context switches, page
faults, and other events. The counters are accessible from
userland through the tbuf status page.
Should be disabled for kernels which are used for measurements.
config JDB_MISC
bool "Miscellaneous JDB modules"
depends on PF_UX || PF_PC
endif # JDB
config VMEM_ALLOC_TEST
bool "Run test for Vmem_alloc allocator"
depends on ARM
config DEBUG_KERNEL_PAGE_FAULTS
bool "Debugging of kernel page-faults"
depends on ARM
help
This option enables logging of kernel page-faults (aka page faults
from kernel mode). The page faults are logged to the normal
console in the format *KP[pfa, error_code, ip].
config POWERSAVE_GETCHAR
bool "Save power in getchar()"
default y
depends on PF_PC
help
This option uses a processor HALT in getchar() to save power and
prevent some P4 processors from being overheated. This option
requires a working timer IRQ to wakeup getchar periodically.
choice
prompt "Warn levels"
default WARN_WARNING
config WARN_NONE
bool "Do not show show any kernel warning"
config WARN_WARNING
bool "Show messages of warning level"
config WARN_ANY
bool "Show all kernel warnings"
endchoice # warn levels
endmenu # debugging
menu "Compiling"
config CC
string "C compiler"
default "gcc"
help
Use this option to override the default C compiler (gcc).
config CXX
string "C++ compiler"
default "g++"
help
Use this option to override the default C++ compiler (g++).
config HOST_CC
string "C host compiler"
default "gcc"
help
Use this option to override the default C host compiler (gcc).
config HOST_CXX
string "C++ host compiler"
default "g++"
help
Use this option to override the default C++ host compiler (g++).
config MAINTAINER_MODE
bool "Do additional checks at build time"
help
This enables the circular dependency and initcall checks.
Say 'Yes' here if you do kernel hacking.
config LABEL
string "Configuration label"
help
Text string with a name for this configuration. To be displayed in
the kernel boot-up.
endmenu
config EXPERIMENTAL
bool "Prompt for experimental features"
help
Experimental features are available when enabling this option.
Enabling these features might be less than fully secure and may
disrupt the stability of your kernel.
Use with caution!
config PERF_CNT
def_bool y if JDB && (IA32 || AMD64 || ARM)
config BIT32
def_bool y if ARM || IA32 || PPC32 || SPARC
config BIT64
def_bool y if AMD64
config ARM_V6
def_bool y if ARM_1136 || ARM_1176 || ARM_MPCORE
config ARM_V7
def_bool y if ARM_CORTEX_A8 || ARM_CORTEX_A9
config ARM_V6PLUS
def_bool y if ARM_V6 || ARM_V7
config WARN_LEVEL
int
default 2 if WARN_ANY
default 1 if WARN_WARNING
default 0 if WARN_NONE
config XARCH
string
default "arm" if ARM
default "ux" if PF_UX
default "amd64" if AMD64 && PF_PC
default "ia32" if IA32 && PF_PC
default "ppc32" if PPC32
default "sparc" if SPARC
config IA32_TARGET
string
default "Intel 80486" if IA32_486
default "Intel Pentium" if IA32_586
default "Intel Pentium Pro" if IA32_686
default "Intel Pentium II" if IA32_P2
default "Intel Pentium III" if IA32_P3
default "Intel Pentium 4" if IA32_P4
default "Pentium M" if IA32_PM
default "AMD K6" if IA32_K6
default "AMD Athlon" if IA32_K7
default "Intel Core2" if IA32_CORE2 || AMD64_CORE2
default "Intel Atom" if IA32_ATOM || AMD64_ATOM
default "AMD Opteron" if IA32_K8 || AMD64_K8 || AMD64_K10 || IA32_K10
config ABI
string
default "vf"

205
kernel/fiasco/src/Makeconf Normal file
View File

@@ -0,0 +1,205 @@
# -*- Makefile -*-
# Fiasco make configuration file
#
# created 1996/04/20 by hohmuth
#
CHECKCC = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
CHECKCXX = $(shell if $(CXX) $(1) -S -o /dev/null -xc++ /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
eval_impl = $(if $($(1)_IMPL),$($(1)_IMPL),$(1))
include $(objbase)/globalconfig.out
# use patsubst here to prevent confusion of syntax highlighting editors :-)
CONFIG_XARCH := $(patsubst "%",%,$(CONFIG_XARCH))
CONFIG_ABI := $(patsubst "%",%,$(CONFIG_ABI))
SYSTEM := $(shell uname)
CC := $(patsubst "%",%,$(CONFIG_CC))
CXX := $(patsubst "%",%,$(CONFIG_CXX))
HOST_CC := $(patsubst "%",%,$(CONFIG_HOST_CC))
HOST_CXX := $(patsubst "%",%,$(CONFIG_HOST_CXX))
RM := rm -f
RM_R := rm -rf
ECHO := echo
ECHO_E := bash --norc -c 'echo -e "$$0" "$$@"'
CP := cp
GREP := GREP_OPTIONS= grep
AWKP ?= gawk --posix
CFLAGS :=
CXXFLAGS := -std=c++0x
OPT_CFLAGS := -O2
OPT_CXXFLAGS := -O2
NOOPT_CFLAGS := -Os
NOOPT_CXXFLAGS := -Os
ARFLAGS := crs
srcdir ?= .
L4DIR ?= $(srcdir)/../../../l4
tooldir := $(srcdir)/../tool
MOVE_IF_CHANGE := $(srcdir)/../tool/move-if-change
SHOWDEPS := $(srcdir)/../tool/showdeps
PREPROCESSDEPS := $(srcdir)/../tool/parsedeps
CIRCULAR := $(srcdir)/../tool/circular
ifeq ($(SYSTEM),FreeBSD)
MD5SUM := /sbin/md5
else
MD5SUM := md5sum
endif
# The name of this file can be overridden from the command line or in
# objdir/Makeconf.local.
MODULES_FILE = $(srcdir)/Modules.$(CONFIG_XARCH)
PREPROCESS = $(srcdir)/../tool/preprocess/src/preprocess
ifeq ($(CONFIG_INLINE),y)
PREPROCESS_FLAGS = -i -t
else
PREPROCESS_FLAGS = -t
endif
AS = $(SYSTEM_TARGET)as
LD = $(SYSTEM_TARGET)ld
AR = $(SYSTEM_TARGET)ar
NM = $(SYSTEM_TARGET)nm
RANLIB = $(SYSTEM_TARGET)ranlib
SIZE = $(SYSTEM_TARGET)size
STRIP = $(SYSTEM_TARGET)strip
OBJCOPY = $(SYSTEM_TARGET)objcopy
OBJDUMP = $(SYSTEM_TARGET)objdump
# Include architecture-specific rules. These may overwrite anything above
include $(srcdir)/Makeconf.$(CONFIG_XARCH)
# Include user-specific rules. These may overwrite anything above
-include $(srcdir)/Makeconf.local
-include $(objbase)/Makeconf.local
ifneq ($(CCXX_VERSION),)
CCXX_SUFFIX := -$(CCXX_VERSION)
endif
CPP := $(SYSTEM_TARGET)cpp$(CCXX_SUFFIX)
CC := $(CCXX_WRAP) $(SYSTEM_TARGET)$(CC)$(CCXX_SUFFIX)
CXX := $(CCXX_WRAP) $(SYSTEM_TARGET)$(CXX)$(CCXX_SUFFIX)
CC_TYPE := $(if $(findstring clang,$(shell $(CXX) --version)),clang,gcc)
CCVER_MAJOR := $(shell $(CXX) -dumpversion | cut -d . -f 1)
CCVER_MINOR := $(shell $(CXX) -dumpversion | cut -d . -f 2)
LIBGCC := $(shell $(CXX) -print-libgcc-file-name)
L4ALL_INCDIR ?= $(addprefix -I, $(PRIVATE_INCDIR))
L4STD_INCDIR ?= -nostdinc
L4STD_INCDIR_LAST ?= -I$(wildcard $(dir $(LIBGCC))/include \
$(dir $(LIBGCC))/../include)
KERNEL_LDFLAGS += -gc-sections
SHARED_FLAGS-gcc += -fno-defer-pop -freg-struct-return
SHARED_FLAGS += -g -Wall -W
SHARED_FLAGS += -Wno-parentheses
SHARED_FLAGS += $(call CHECKCC,-Wformat=2,)
SHARED_FLAGS += $(call CHECKCC,-fno-stack-protector,)
SHARED_FLAGS += $(call CHECKCC,-fdiagnostics-show-option)
OPT_CXXFLAGS-gcc += $(call CHECKCXX,-fweb,)
OPT_CFLAGS-gcc += $(call CHECKCC,-fweb,)
OPT_SHARED_FLAGS-gcc += $(call CHECKCC,-frename-registers,)
OPT_SHARED_FLAGS-gcc += $(call CHECKCC,-fgcse-after-reload,)
CXXFLAGS-gcc += -fno-implement-inlines
-include $(objbase)/.Host-config
# Configuration dependent compile flags
SHARED_FLAGS-$(CONFIG_NDEBUG) += -DNDEBUG
SHARED_FLAGS-$(CONFIG_NO_FRAME_PTR) += -fomit-frame-pointer
SHARED_FLAGS-$(CONFIG_GSTABS) += -gstabs+
SHARED_FLAGS-$(CONFIG_UNREACHABLE_CODE) += $(call CHECKCC,-Wunreachable-code,)
# Eagerly compute SHARED_FLAGS to avoid calling CHECKCC over and over again.
SHARED_FLAGS := $(SHARED_FLAGS) $(SHARED_FLAGS-y)
SHARED_FLAGS += $(SHARED_FLAGS-$(CC_TYPE))
OPT_SHARED_FLAGS += $(OPT_SHARED_FLAGS-$(CC_TYPE))
NOOPT_SHARED_FLAGS += $(NOOPT_SHARED_FLAGS-$(CC_TYPE))
# Standard compile flags
ASFLAGS += $(SHARED_FLAGS) -DASSEMBLER
ASFLAGS-clang += -no-integrated-as
CFLAGS += $(SHARED_FLAGS)
CXXFLAGS += $(SHARED_FLAGS) -fno-rtti -fno-exceptions
OPT_CFLAGS += $(OPT_SHARED_FLAGS)
OPT_CXXFLAGS += $(OPT_SHARED_FLAGS)
NOOPT_CFLAGS += $(NOOPT_SHARED_FLAGS)
NOOPT_CXXFLAGS += $(NOOPT_SHARED_FLAGS)
CPPFLAGS += $(L4STD_INCDIR) $(L4ALL_INCDIR) $(L4STD_INCDIR_LAST)
CXXFLAGS += $(call CHECKCXX,-fno-threadsafe-statics,)
CXXFLAGS += $(call CHECKCXX,-Wno-non-virtual-dtor,)
ASFLAGS += $(ASFLAGS-$(CC_TYPE))
CXXFLAGS += $(CXXFLAGS-$(CC_TYPE))
OPT_CFLAGS += $(OPT_CFLAGS-$(CC_TYPE))
OPT_CXXFLAGS += $(OPT_CXXFLAGS-$(CC_TYPE))
NOOPT_CFLAGS += $(NOOPT_CFLAGS-$(CC_TYPE))
NOOPT_CXXFLAGS += $(NOOPT_CXXFLAGS-$(CC_TYPE))
# Output formatting, set V=1 to see command line, V=0 to prevent printing them
VERBOSE ?= @
ifeq ($(V),1)
VERBOSE :=
PREP_MESSAGE ?= @$(ECHO) " ... Preprocessing $(filter %.cpp,$^)"
endif
AR_MESSAGE ?= @$(ECHO) " ==> Archiving into $@"
COMP_MESSAGE ?= @$(ECHO) " ... Making $@"
LINK_MESSAGE ?= @$(ECHO) " ==> Linking $@"
DEP_MESSAGE ?= @$(ECHO) " ... Building dependencies for $<"
PREP_MESSAGE ?= @$(ECHO) " ... Preprocessing $*"
CHKSUM_MESSAGE ?= @$(ECHO) " ... Generating checksum for "
PATCH_MESSAGE ?= @$(ECHO) " ... Writing checksum into "
STRIP_MESSAGE ?= @$(ECHO) " ... Stripping $@"
GENVER_MESSAGE ?= @$(ECHO) " ... Generating version information"
CLEAN_MESSAGE ?= @$(ECHO) "Removing created files"
CLEANALL_MESSAGE?= @$(ECHO) "Removing all created files"
INST_MESSAGE ?= @$(ECHO) "Installing $(^F)"
OK_MESSAGE ?=
COMP_MESSAGE_NOOPT ?= $(COMP_MESSAGE)
ifneq ($(VERBOSE),)
MOVE_IF_CHANGE += -q
endif
SRC_ALL = $(SRC_S) $(SRC_CPP) $(SRC_C) $(SRC_CC)
ifeq ($(filter clean cleanall mrproper,$(MAKECMDGOALS)),)
DEPS = $(foreach file,$(SRC_ALL), $(dir $(file)).$(notdir $(file)).d)
else
DEPS = /dev/null
endif
# To enable all warning ...
ENABLE_ALL_WARNINGS ?= n
ifeq ($(CC_TYPE),gcc)
ifeq ($(ENABLE_ALL_WARNINGS),y)
tmp := $(call CHECKCC,-Wframe-larger-than=512)
CFLAGS += $(tmp)
CXXFLAGS += $(tmp)
tmp :=
else
F_UNINITIALIZED := $(firstword $(call CHECKCC,-Wmaybe-uninitialized) \
$(call CHECKCC,-Wuninitialized))
F_SET_NOT_USED := $(call CHECKCC,-Wunused-but-set-variable)
F_UNINITIALIZED := $(patsubst -W%,-Wno-%,$(F_UNINITIALIZED))
F_SET_NOT_USED := $(patsubst -W%,-Wno-%,$(F_SET_NOT_USED))
CFLAGS += $(F_UNINITIALIZED) $(F_SET_NOT_USED)
CXXFLAGS += $(F_UNINITIALIZED) $(F_SET_NOT_USED)
endif
endif

View File

@@ -0,0 +1,27 @@
# -*- makefile -*-
#OPT_SHARED_FLAGS += $(call CHECKCC,-finline-limit=10000,)
#OPT_CXXFLAGS += $(call CHECKCXX,--param large-function-insns=10000)
#OPT_CFLAGS += $(call CHECKCC,--param large-function-insns=10000)
# The -Os option of gcc-4.0 sets max-inline-insns-single to 5 which prevents
# inlining of almost every function
NOOPT_SHARED_FLAGS-gcc += $(call CHECKCC,--param max-inline-insns-single=50)
SHARED_FLAGS-gcc += -mpreferred-stack-boundary=4
SHARED_FLAGS += -m64 -mcmodel=kernel -mno-red-zone -funit-at-a-time
OPT_CFLAGS += -mno-red-zone -funit-at-a-time
OPT_CXXFLAGS += -mno-red-zone -funit-at-a-time
SHARED_FLAGS-$(CONFIG_AMD64_CORE2) += $(call CHECKCC,-march=core2,)
SHARED_FLAGS-$(CONFIG_AMD64_ATOM) += $(call CHECKCC,-march=atom,)
SHARED_FLAGS-$(CONFIG_AMD64_K8) += $(call CHECKCC,-march=k8,)
SHARED_FLAGS += $(call CHECKCC,-mno-mmx,)
SHARED_FLAGS += $(call CHECKCC,-mno-sse,)
SHARED_FLAGS += $(call CHECKCC,-mno-sse2,)
SHARED_FLAGS += $(call CHECKCC,-mno-sse3,)
SHARED_FLAGS += $(call CHECKCC,-mno-3dnow,)
ASFLAGS += -m64 -mcmodel=kernel
OFORMAT := elf64-x86-64
LD_EMULATION_CHOICE := elf_x86_64 elf_x86_64_fbsd

View File

@@ -0,0 +1,17 @@
# -*- makefile -*-
#OPT_SHARED_FLAGS += $(call CHECKCC,-finline-limit=10000,)
SYSTEM_TARGET ?= arm-linux-
SHARED_FLAGS-$(CONFIG_ARM_PXA) += -mcpu=xscale
SHARED_FLAGS-$(CONFIG_ARM_SA) += -mcpu=strongarm1100
SHARED_FLAGS-$(CONFIG_ARM_920T) += -mcpu=arm920t
SHARED_FLAGS-$(CONFIG_ARM_926) += -mcpu=arm926ej-s
SHARED_FLAGS-$(CONFIG_ARM_1136) += -mcpu=arm1136jf-s
SHARED_FLAGS-$(CONFIG_ARM_1176) += -mcpu=arm1176jzf-s
SHARED_FLAGS-$(CONFIG_ARM_MPCORE) += -mcpu=mpcore
SHARED_FLAGS-$(CONFIG_ARM_CORTEX_A8) += $(call CHECKCC,-mcpu=cortex-a8)
SHARED_FLAGS-$(CONFIG_ARM_CORTEX_A9) += $(call CHECKCC,-mcpu=cortex-a9)
SHARED_FLAGS += -msoft-float
SHARED_FLAGS += $(call CHECKCC,-mno-thumb-interwork)
SHARED_FLAGS += -marm -mabi=apcs-gnu
LDFLAGS += --no-warn-mismatch
LD_EMULATION_CHOICE := armelf armelf_linux_eabi armelf_fbsd

View File

@@ -0,0 +1,40 @@
# -*- makefile -*-
#OPT_SHARED_FLAGS += $(call CHECKCC,-finline-limit=10000,)
#OPT_CXXFLAGS += $(call CHECKCXX,--param large-function-insns=10000)
#OPT_CFLAGS += $(call CHECKCC,--param large-function-insns=10000)
# The -Os option of gcc-4.0 sets max-inline-insns-single to 5 which prevents
# inlining of almost every function
NOOPT_SHARED_FLAGS-gcc += $(call CHECKCC,--param max-inline-insns-single=50)
SHARED_FLAGS-gcc += -mpreferred-stack-boundary=2
SHARED_FLAGS += -m32
SHARED_FLAGS-$(CONFIG_REGPARM3) += -mregparm=3
SHARED_FLAGS-$(CONFIG_IA32_486) += -march=i486
SHARED_FLAGS-$(CONFIG_IA32_586) += -march=i586
SHARED_FLAGS-$(CONFIG_IA32_686) += -march=i686
SHARED_FLAGS-$(CONFIG_IA32_P2) += -march=i686 $(call CHECKCC,-mtune=pentium2,\
$(call CHECKCC,-mcpu=pentium2))
SHARED_FLAGS-$(CONFIG_IA32_P3) += -march=i686 $(call CHECKCC,-mtune=pentium3,\
$(call CHECKCC,-mcpu=pentium3))
SHARED_FLAGS-$(CONFIG_IA32_P4) += -march=i686 $(call CHECKCC,-mtune=pentium4,\
$(call CHECKCC,-mcpu=pentium4))
SHARED_FLAGS-$(CONFIG_IA32_PM) += -march=i686 $(call CHECKCC,-mtune=pentium-m,\
$(call CHECKCC,-mcpu=pentiumm))
SHARED_FLAGS-$(CONFIG_IA32_CORE2) += $(call CHECKCC,-march=core2,-march=i686)
SHARED_FLAGS-$(CONFIG_IA32_ATOM) += $(call CHECKCC,-march=atom,-march=i686)
SHARED_FLAGS-$(CONFIG_IA32_K6) += $(call CHECKCC,-march=k6,-march=i586)
SHARED_FLAGS-$(CONFIG_IA32_K7) += $(call CHECKCC,-march=athlon,-march=i686)
SHARED_FLAGS-$(CONFIG_IA32_K8) += $(call CHECKCC,-march=k8,-march=i686)
SHARED_FLAGS-$(CONFIG_IA32_K10) += $(call CHECKCC,-march=barcelona,-march=i686)
SHARED_FLAGS += $(call CHECKCC,-mno-mmx,)
SHARED_FLAGS += $(call CHECKCC,-mno-sse,)
SHARED_FLAGS += $(call CHECKCC,-mno-sse2,)
SHARED_FLAGS += $(call CHECKCC,-mno-sse3,)
SHARED_FLAGS += $(call CHECKCC,-mno-3dnow,)
ASFLAGS += -m32
OFORMAT := elf32-i386
LD_EMULATION_CHOICE := elf_i386 elf_i386_fbsd

View File

@@ -0,0 +1,5 @@
SYSTEM_TARGET ?= powerpc-linux-
LD_EMULATION_CHOICE := elf32ppc
SHARED_FLAGS += -m32
ASFLAGS += -m32

View File

@@ -0,0 +1,2 @@
SYSTEM_TARGET ?= sparc-elf-
LD_EMULATION_CHOICE := sparcleon

View File

@@ -0,0 +1,34 @@
# -*- makefile -*-
OPT_SHARED_FLAGS += $(call CHECKCC,-finline-limit=10000,)
OPT_CXXFLAGS += $(call CHECKCXX,--param large-function-insns=10000)
OPT_CFLAGS += $(call CHECKCC,--param large-function-insns=10000)
# The -Os option of gcc-4.0 sets max-inline-insns-single to 5 which prevents
# inlining of almost every function
NOOPT_SHARED_FLAGS += $(call CHECKCC,--param max-inline-insns-single=50)
SHARED_FLAGS += -mpreferred-stack-boundary=2 -m32
L4STD_INCDIR := -include $(srcdir)/kern/ux/format.h
L4STD_INCDIR_LAST :=
CPPFLAGS += -D_GNU_SOURCE
SHARED_FLAGS-$(CONFIG_IA32_486) += -march=i486
SHARED_FLAGS-$(CONFIG_IA32_586) += -march=i586
SHARED_FLAGS-$(CONFIG_IA32_686) += -march=i686
SHARED_FLAGS-$(CONFIG_IA32_P2) += $(call CHECKCC,-march=pentium2,-march=i686)
SHARED_FLAGS-$(CONFIG_IA32_P3) += $(call CHECKCC,-march=pentium3,-march=i686)
SHARED_FLAGS-$(CONFIG_IA32_P4) += $(call CHECKCC,-march=pentium4,-march=i686)
SHARED_FLAGS-$(CONFIG_IA32_K6) += $(call CHECKCC,-march=k6,-march=i586)
SHARED_FLAGS-$(CONFIG_IA32_K7) += $(call CHECKCC,-march=athlon,-march=i686)
SHARED_FLAGS-$(CONFIG_IA32_K8) += $(call CHECKCC,-march=k8,-march=i686)
SHARED_FLAGS += $(call CHECKCC,-mno-mmx,)
SHARED_FLAGS += $(call CHECKCC,-mno-sse,)
SHARED_FLAGS += $(call CHECKCC,-mno-sse2,)
SHARED_FLAGS += $(call CHECKCC,-mno-sse3,)
SHARED_FLAGS += $(call CHECKCC,-mno-3dnow,)
ASFLAGS += -m32
OFORMAT := elf32-i386
LD_EMULATION_CHOICE := elf_i386 elf_i386_fbsd

246
kernel/fiasco/src/Makefile Normal file
View File

@@ -0,0 +1,246 @@
srcdir ?= NOT_SET
tooldir := $(srcdir)/../tool
CONFIG_BANNER_STRING ?= "Fiasco - prepare for world domination"
.PHONY: all do-all test-all config textconfig menuconfig xconfig \
oldconfig regenconfig mrproper doc help update nconfig
all:
help:
@echo "Possible targets are:"
@echo " menuconfig - configure Fiasco (ncurses mode)"
@echo " config - like menuconfig"
@echo " textconfig - line-oriented config"
@echo " xconfig - configure Fiasco (graphical mode)"
@echo " all - Fiasco binary"
@echo " clean - clear all auto-generated files in auto"
@echo " cleanall - like clean + dependencies"
@echo " mrproper - like cleanall + config files"
@echo " update - update Fiasco and preprocess using svn"
@echo " DEPS - dependencies between kernel object files"
@echo " DEPS.ps - graphical (ps) representation of DEPS"
@echo " DEPS.svg - graphical (svg) representation of DEPS"
@echo " DEPS.tred.ps - transitive reduction of DEPS.ps"
@echo " DEPS.tred.svg - transitive reduction of DEPS.svg"
@echo " doc - doxygen HTML documentation into docs/"
@echo " TAGS tags - create tags files"
ifneq ($(srcdir),NOT_SET)
Makefile: $(srcdir)/templates/Makefile.builddir.templ
perl -p -i -e '$$s = "$(srcdir)"; s/\@SRCDIR\@/$$s/' \
< $< >$@
endif
ifneq ($(MAKECMDGOALS),help)
ifeq ($(srcdir),NOT_SET)
all $(filter config %config,$(MAKECMDGOALS)):
@echo "======================================================================"
@echo " Building Fiasco in the src directory is not possible!"
@echo ""
@echo " Go to the Fiasco root directory and create your build directory with"
@echo " cd .. && make BUILDDIR=build-dir"
@echo "======================================================================"
@exit 1
else # srcdir != NOT_SET
all: globalconfig.h
ifeq ($(filter config %config,$(MAKECMDGOALS)),)
-include globalconfig.out
# use patsubst here to prevent confusion of syntax highlighting editors :-)
CONFIG_XARCH := $(patsubst "%",%,$(CONFIG_XARCH))
CONFIG_ABI := $(patsubst "%",%,$(CONFIG_ABI))
ifeq ("$(CONFIG_XARCH)","")
all: menuconfig
@echo "========================================================="
@echo "Now run make again to build!"
@echo "========================================================="
@exit 1
else # ! no XARCH
ifeq ("$(CONFIG_ABI)","")
all:
@echo "========================================================="
@echo "ERROR: No ABI version set (run 'make menuconfig')!"
@echo "========================================================="
@exit 1
else # ! no ABI
#
# At this point, globalconfig.out is up-to-date. Update Modules and
# .Modules.deps, then restart using Makefile.sub1, Makefile.sub2.
#
# Read Make configuration
include $(srcdir)/Makeconf
include $(MODULES_FILE)
MODULES_FILES += $(srcdir)/Modules.generic
ifdef SUBSYSTEMS
_modules_read_ = true
endif
ifdef _modules_read_
GENERATED_MODULES = $(foreach subsys, $(SUBSYSTEMS), \
$(INTERFACES_$(subsys)))
ALL = $(foreach subsys, $(SUBSYSTEMS), $($(subsys)) $($(subsys)_EXTRA))
$(foreach m, $(GENERATED_MODULES), auto/stamp-$(m).ready): $(MODULES_FILES)
.PRECIOUS: .Modules.deps
.Modules.deps: $(MODULES_FILES) globalconfig.h
@mkdir -p auto
@echo "Creating $@"
@($(foreach mod, $(GENERATED_MODULES), \
echo 'auto/stamp-$(mod).ready: \
$(addsuffix .cpp,$(call eval_impl,$(mod)))'; \
echo '$(patsubst %,auto/%.cc,$(call eval_impl,$(mod)))' \
'auto/$(mod).h auto/$(mod)_i.h: \
auto/stamp-$(mod).ready ; \
@[ -e $$@ ] || { $$(RM) $$<; $$(MAKE) $$<; }'; \
)) > $@.new
@($(foreach subsys, $(SUBSYSTEMS), \
echo 'IFDEPS += $(addprefix ., $(addsuffix .cc.d, \
$(foreach in,$(INTERFACES_$(subsys)), \
$(call eval_impl,$(in)))))' ; \
echo 'CXXSRC_$(subsys) += $(addsuffix .cc, \
$(foreach in,$(INTERFACES_$(subsys)), \
$(call eval_impl,$(in))))'; \
echo 'OBJ_$(subsys) += $$(CXXSRC_$(subsys):.cc=.o) \
$$(CSRC_$(subsys):.c=.o) \
$$(ASSRC_$(subsys):.S=.o)' ; ) ) >> $@.new
@echo "GENERATED_MODULES = $(GENERATED_MODULES)" >> $@.new
@echo "ALL = $(ALL)" >> $@.new
@echo "_modules_deps_read_ = true" >> $@.new
@mv $@.new $@
endif # _modules_read_
#
# Makefile.sub1: Create source files.
#
.PHONY: create-sources
create-sources: $(MODULES_FILES) globalconfig.h .Modules.deps
$(MAKE) srcdir=$(srcdir) objbase=$(objbase) -f $(srcdir)/Makefile.sub1
auto/stamp-%.ready: $(MODULES_FILES) globalconfig.h .Modules.deps
$(MAKE) srcdir=$(srcdir) objbase=$(objbase) -f $(srcdir)/Makefile.sub1 $@
DEPS_FILES=DEPS DEPS.a4 DEPS.tred
#
# Makefile.sub2: Create everything else.
#
all doc $(addsuffix .ps,$(DEPS_FILES)) $(addsuffix .svg,$(DEPS_FILES)) TAGS tags: \
$(MODULES_FILES) .Modules.deps create-sources globalconfig.h
$(MAKE) srcdir=$(srcdir) objbase=$(objbase) -f $(srcdir)/Makefile.sub2 $@
%.o %_t: $(MODULES_FILES) .Modules.deps create-sources globalconfig.h
$(MAKE) srcdir=$(srcdir) objbase=$(objbase) -f $(srcdir)/Makefile.sub2 $@
# Divert any target we do not explicitly mention in this Makefile to
# Makefile.sub2. (Unfortunately 1, this does not work for file
# targets that already exist in this directory. Unfortunately 2,
# .DEFAULT does not accept prerequisites, so we must "make
# create-sources" manually.)
.DEFAULT:
$(MAKE) create-sources
$(MAKE) srcdir=$(srcdir) objbase=$(objbase) -f $(srcdir)/Makefile.sub2 $@
# Well, we need to provide some empty rules for some targets to
# prevent the above catch-all from running amok.
Makerules.local $(srcdir)/Makeconf.local $(objbase)/Makeconf.local \
$(objbase)/.Host-config: ;
%: %.o # delete implicit rule
endif # ! no ABI
endif # ! no XARCH
endif # ! config xconfig menuconfig oldconfig
auto:
test -e auto || mkdir auto
BSP_DIR := $(srcdir)/kern/arm/bsp $(srcdir)/kern/ppc32/bsp $(srcdir)/kern/sparc/bsp
KCONFIG_FILE := Kconfig
KCONFIG_SRC_FILE := $(srcdir)/Kconfig
KCONFIG_BSP_FILES := $(shell find $(BSP_DIR) -name Kconfig -follow -print)
kconfig_call = $(MAKE) -C $(tooldir)/kconfig O=$(objbase) \
Kconfig=$(KCONFIG_FILE) \
KCONFIG_AUTOHEADER=globalconfig.h \
KCONFIG_TRISTATE=config/tristate.conf \
KCONFIG_CONFIG=globalconfig.out \
KCONFIG_AUTOCONFIG=config/auto.conf \
KERNELVERSION=SVN MENUCONFIG_COLOR=blackbg \
INCLUDE_PPC32=$(INCLUDE_PPC32) \
INCLUDE_SPARC=$(INCLUDE_SPARC) \
fiasco_srcdir=$(srcdir)/..
$(KCONFIG_FILE): $(KCONFIG_SRC_FILE) $(KCONFIG_BSP_FILES) $(srcdir)/Makefile
@$(tooldir)/gen_kconfig $(KCONFIG_SRC_FILE) $(KCONFIG_FILE) $(KCONFIG_BSP_FILES)
globalconfig.out: $(KCONFIG_FILE)
+$(kconfig_call) oldconfig
globalconfig.h: globalconfig.out
+$(kconfig_call) silentoldconfig
config: $(KCONFIG_FILE)
+$(kconfig_call) menuconfig silentoldconfig
textconfig: $(KCONFIG_FILE)
+$(kconfig_call) config silentoldconfig
menuconfig oldconfig xconfig gconfig nconfig randconfig allyesconfig allnoconfig: $(KCONFIG_FILE)
+$(kconfig_call) $@ silentoldconfig
ifneq ($(filter clean cleanall mrproper,$(MAKECMDGOALS)),)
# Try to suck in clean targets from subsystems' Makefile fragments
ifdef _modules_read_
MAKERULES_SUBSYS = $(foreach subsys, $(SUBSYSTEMS), $(firstword $(wildcard $(addsuffix /Makerules.$(subsys),$(addprefix $(srcdir)/,$(VPATH)) $(srcdir)))))
-include $(MAKERULES_SUBSYS)
endif
.DEFAULT:
.PHONY: clean cleanall mrproper \
$(foreach subsys, $(SUBSYSTEMS), clean-$(subsys)) \
$(foreach subsys, $(SUBSYSTEMS), cleanall-$(subsys))
clean: $(foreach subsys, $(SUBSYSTEMS), clean-$(subsys))
$(RM) $(ALL)
$(RM) *.o fiasco
$(RM) auto/*.cc auto/*.h auto/*.S auto/stamp-*.ready
$(RM) .Clean-auto .Compiler-config
cleanall: clean $(foreach subsys, $(SUBSYSTEMS), cleanall-$(subsys))
$(foreach subdir, $(SUBDIRS), $(RM) $(subdir)/{.,}*.d)
$(RM) {.,}*.d {.,}*.d.new *~ globalconfig.{h,h.old} Circular
$(RM) .Modules.deps
mrproper: cleanall
$(RM_R) globalconfig.out Modules.* DEPS*
$(RM_R) auto docs config scripts
endif # clean, cleanall, mrproper
update:
cd $(srcdir)/.. && svn update
cd $(dir $(PREPROCESS))/.. && svn update
endif # srcdir != NOT_SET
endif # MAKECMDGOALS != help

View File

@@ -0,0 +1,118 @@
# -*- makefile -*-
# Targets in this Makefile:
# - all: Create C++ sources from Preprocess input
#
# This Makefile is invoked in a sub-Make from the top-level Makefile
# (via Makerules.global) when globalconfig.out, Modules and
# .Modules.deps are up-to-date.
all: do-all
BUILD_SOURCES=true
include $(srcdir)/Makeconf # also reads srcdir/Makeconf.local
# and objdir/Makeconf.local
include $(MODULES_FILE)
include .Modules.deps
include $(srcdir)/Makerules.global # also reads objdir/Makerules.local
# Read subsystem Makefile fragments. We do not explicity use any
# targets of these fragments in this Makefile, but this include allows
# subsystem Makefile fragments to implicitly create more Makefile
# fragments.
include $(MAKERULES_SUBSYS)
ALL_STAMPS = $(foreach m, $(GENERATED_MODULES), auto/stamp-$(m).ready)
.PHONY: do-all
do-all: $(ALL_STAMPS)
#
# Auto-created source files
#
.Clean-auto: $(MODULES_FILES) .Modules.deps globalconfig.out
rm -f \
$(filter-out \
$(addprefix auto/, \
$(addsuffix .cc, \
$(foreach mod, $(GENERATED_MODULES), $(call eval_impl,$(mod)))) \
$(foreach mod, $(GENERATED_MODULES), \
$(mod).h $(mod)_i.h stamp-$(mod).ready)), \
$(wildcard auto/*))
touch $@
define find_ld_emulation
emulations=$$(LANG= $(LD) --help | \
grep -i "supported emulations:" | \
sed -e 's/.*supported emulations: //') ; \
unset found_it; \
for e in $$emulations; do \
for c in $(2); do \
if [ "$$e" = "$$c" ]; then \
echo LD_EMULATION = $$e >> $(1); \
found_it=1; \
break; \
fi; \
done; \
done; \
if [ "$$found_it" != "1" ]; then \
echo "No known ld emulation found"; exit 1; \
fi
endef
# Force that rule to ensure that compiler changes caused by make command line
# or system-wide compiler updates are noticed.
# Do not use .PHONY, because preprocess would then be triggered everytime.
.Compiler-config: force-the-rule
@echo -n "Checking compiler config... "
@echo "CC = $(CC)" > $@.new
@echo "CXX = $(CXX)" >> $@.new
@echo "CPPFLAGS = $(CPPFLAGS)" >> $@.new
@echo "CFLAGS = $(CFLAGS)" >> $@.new
@echo "CXXFLAGS = $(CXXFLAGS)" >> $@.new
@echo "OPT_CFLAGS = $(OPT_CFLAGS)" >> $@.new
@echo "OPT_CXXFLAGS = $(OPT_CXXFLAGS)" >> $@.new
@echo "ASFLAGS = $(ASFLAGS)" >> $@.new
@echo "CONFIG_XARCH = $(CONFIG_XARCH)" >> $@.new
# If the compiler configuration has changed, remove all dependency
# files -- they have just become useless.
@$(MOVE_IF_CHANGE) $@.new $@ \
&& { $(RM) .*.d */.*.d; echo "CHANGED. Recompiling."; } \
|| echo "unchanged."
.Host-config: force-the-rule
@$(call find_ld_emulation,$@.new,$(LD_EMULATION_CHOICE))
@$(MOVE_IF_CHANGE) $@.new $@ || true
force-the-rule: ;
$(ALL_STAMPS): $(MODULES_FILES) .Modules.deps globalconfig.out \
.Clean-auto .Compiler-config .Host-config
# Basename of implementation files = Basename of first .cpp file
impl_name = $(basename $(firstword $(subst -, ,\
$(firstword $(filter %.cpp, $(notdir $(1)))))))
$(ALL_STAMPS): auto/stamp-%.ready:
$(PREP_MESSAGE)
@test -e auto || mkdir auto
$(VERBOSE)$(PREPROCESS) \
$(PREPROCESS_FLAGS) \
$(if $(filter $(call impl_name,$^),$(ALWAYS_INLINE)),-i,) \
-p auto/new_ \
-e "$(PREPROCESS_PARTS)" -s \
-h $* -c $(call impl_name,$^) $(filter %.cpp, $^)
@for i in $*.h $(call impl_name,$^)_i.h \
$(patsubst %.cpp, %.cc, $(filter %.cpp, $(notdir $^))); \
do \
$(MOVE_IF_CHANGE) auto/new_$$i auto/$$i || true; \
done
$(OK_MESSAGE)
$(VERBOSE)touch $@
.PRECIOUS: auto/stamp-%.ready
.PRECIOUS: %.cc %.h %_i.h

View File

@@ -0,0 +1,261 @@
# -*- makefile -*-
# Targets in this Makefile:
# - all: Run all subsystems' "all" targets
# - doc: Create doxygen documentation in directory "docs"
# - DEPS, DEPS.ps, DEPS.a4.ps, DEPS.tred.ps:
# Create dependency graphs
# - TAGS, tags:
# Create editor tags
# This Makefile is invoked in a sub-Make from the top-level Makefile
# when globalconfig.out, Modules and .Modules.deps are up-to-date and
# all `preprocess'd C++ source files have been created.
all: do-all
$(VERBOSE)echo " --> Build-Nr: $$(cat .build_nr)"
BUILD_OBJECTS=true
include $(srcdir)/Makeconf # also reads srcdir/Makeconf.local
# and objdir/Makeconf.local
include $(MODULES_FILE)
include .Modules.deps
# Compute sets of sources. From these variables, Makeconf computes
# $(DEPS) and $(SRC_ALL). Set them before including Makerules.global.
SRC_S = $(foreach subsys, $(SUBSYSTEMS), $(ASSRC_$(subsys)))
SRC_C = $(foreach subsys, $(SUBSYSTEMS), $(CSRC_$(subsys)))
SRC_CC = $(foreach subsys, $(SUBSYSTEMS), $(CXXSRC_$(subsys)))
include $(srcdir)/Makerules.global # also reads objdir/Makerules.local
include $(MAKERULES_SUBSYS)
-include $(DEPS)
# Recompile everything if the compiler configuration has changed.
OBJS = $(foreach subsys, $(SUBSYSTEMS), $(OBJ_$(subsys)))
$(OBJS): .Compiler-config
#
# Subsystem-specific rules and targets
#
ifeq ("$(CONFIG_MAINTAINER_MODE)","y")
do-all: Checkinitcalls Circular-ok ToDoItems compilertest $(ALL)
ifeq ($(CONFIG_XARCH),ux)
# disabled until unittests fixed
#do-all: unittest
endif # UX
else # ! maintainer mode
do-all: compilertest $(ALL)
endif # ! maintainer mode
ifeq ($(CC_TYPE),gcc)
ifneq ($(findstring $(CCVER_MAJOR),4 5 6 7),)
ifeq ($(CCVER_MAJOR),4)
ifeq ($(findstring $(CCVER_MINOR), 0 1 2 3),)
CC_OK := 1
endif
else
CC_OK := 1
endif
endif
CC_OK := 1
endif
compilertest:
ifeq ($(CC_TYPE),gcc)
ifeq ($(CC_OK),)
@$(ECHO_E) "\033[31m\n" \
" ERROR: gcc version "$(CCVER_MAJOR).$(CCVER_MINOR)" is not supported for "\
"Fiasco -- \n"\
" please update gcc to at least version 4.4.\033[m\n"; exit -1
endif
endif
ifeq ($(CC_TYPE),gcc)
ifeq ($(CC_OK),)
@$(ECHO_E) "\033[31m\n" \
" ERROR: clang version "$(CCVER_MAJOR).$(CCVER_MINOR)" is not supported for "\
"Fiasco -- \n"\
" please update clang to at least version ?.?.\033[m\n"; exit -1
endif
endif
Checkinitcalls: $(KERNEL) $(OBJ_KERNEL)
ifneq ($(shell $(CXX) -dumpversion | cut -d . -f1-2),3.4)
@echo "Checking initcalls"
$(VERBOSE)$(srcdir)/../tool/checkinitcalls \
-k fiasco.image \
-Werror $(filter-out fiasco.image, $^) \
$(if $(SYSTEM_TARGET),-t $(SYSTEM_TARGET)) && \
echo "Initcalls OK"
else
@echo "Initcall check disabled due to gcc-3.4"
endif
ToDoItems:
@files=$$(cd $(srcdir) && \
find . -type f -name '*.cpp' -o -name '*.cc' -o \
-name '*.h' -o -name '*.S' -o -name '*.h'); \
fixme=$$(cd $(srcdir) && cat $$files | grep -wc FIXME); \
XXX=$$(cd $(srcdir) && cat $$files | grep -wc XXX); \
if [ "$$fixme" -ne "0" -o "$$XXX" -ne "0" ]; then \
echo "Found $$fixme times 'FIXME' and $$XXX times 'XXX'"; \
fi
doc: docs/stamp-doc.ready
docs/stamp-doc.ready: $(foreach m, $(GENERATED_MODULES), auto/stamp-$(m).ready)
@mkdir -p docs
@touch $@
@doxygen $(srcdir)/doxygen.conf
###
# Make function "makedeps": Creates (on stdout) a list of Make-like
# dependencies in a format suitable for $(SHOWDEPS). Expects a list
# of source (BASE-suffix.{cpp,cc,c}, BASE[_i].h) files as input and extracts
# include directives from them. Dependecies contain only basenames of
# files (up to the first "-"). Suffixes and extensions are stripped.
makedeps= implname () { echo $$1 | sed 's|.*/||; s|_i\.h|.h|; s|[.-].*||;'; };\
for i in $(1); \
do \
echo $$(implname $$i): $$(perl -n -e \
'/^\s*\#include\s+["<](.*).h[">]/ && print "$$1 "; next;' \
$$i); \
done
DEPS: $(SRC_ALL) $(foreach idir, $(PRIVATE_INCDIR), $(wildcard $(idir)/*.h))
$(call makedeps, $^) | $(SHOWDEPS) > $@.new
mv $@.new $@
# Graphical version of DEPS dependency graph.
# XXX DEPS.{dot,ps} only contain dependency graphs for the KERNEL and
# LIBK subsystem. Also, we remove a number of top-level and low-level
# modules from the resulting graph to reduce the overwhelming number
# of edges; however, `gendotdeps' ensures that modules participating
# in circular dependencies are never removed.
GENDOT_FLAGS ?= -t1u1
KERNEL_MODULES_CPP = $(foreach mod, $(INTERFACES_KERNEL) $(INTERFACES_LIBK), \
$(addsuffix .cpp,$(call eval_impl,$(mod)))) \
$(foreach idir, $(srcdir)/kern $(srcdir)/kern/shared \
$(srcdir)/kern/$(CONFIG_XARCH), \
$(wildcard $(idir)/*.h))
ifeq ($(CONFIG_XARCH),ux)
EXTRA_INCLUDES = -I/usr/include/c++/$(shell $(CXX) -dumpversion) -I/usr/include
endif
DEPS.dot: $(KERNEL_MODULES_CPP)
@echo -n > source_files.mkdeps
@for f in $^ ; do \
echo $$f >> source_files.mkdeps ; \
done
$(srcdir)/../tool/gendotdeps \
-E "$(PREPROCESS_PARTS)" $(addprefix -I,$(PRIVATE_INCDIR)) \
$(EXTRA_INCLUDES) $(addprefix --vpath=,$(VPATH)) $(GENDOT_FLAGS) \
-v -b $(srcdir)/DEPS.blacklist source_files.mkdeps -o $@ || $(RM) $@
@$(RM) source_files.mkdeps
%.ps: %.dot
dot -Tps -Gmclimit=200.0 -Gnslimit=500.0 \
-Gsize=11,10 -Grotate=90 -o $@ $<
%.a4.ps: %.dot
dot -Tps -Gmclimit=200.0 -Gnslimit=500.0 \
-Gsize="11,8" -Granksep=0.7 -Grotate=90 -o $@ $<
%.tred.ps: %.dot
tred $< | dot -Tps -Gmclimit=200.0 -Gnslimit=500.0 \
-Gsize="11,8" -Granksep=0.7 -Grotate=90 -o $@
%.svg: %.dot
dot -Tsvg -Gmclimit=200.0 -Gnslimit=500.0 \
-Gsize=11,10 -Grotate=90 -o $@ $<
%.a4.svg: %.dot
dot -Tsvg -Gmclimit=200.0 -Gnslimit=500.0 \
-Gsize="11,8" -Granksep=0.7 -Grotate=90 -o $@ $<
%.tred.svg: %.dot
tred $< | dot -Tsvg -Gmclimit=200.0 -Gnslimit=500.0 \
-Gsize="11,8" -Granksep=0.7 -Grotate=90 -o $@
###
# Circular should really be dependent on $(DEPS). However, we cannot
# enforce that all $(DEPS) are made before this target, because the
# Makefile contains "-include $(DEPS)" (which can result in Circular
# being created/updated before all $(DEPS) are). Therefore, depend on
# the fiasco.image and on main (not with Fiasco-UX). Once this is made,
# we know all $(DEPS) have been updated.
Circular: $(KERNEL) $(BOOT) $(RUN_TESTS) $(CHECKSUM)
@echo "Creating $@"
@( \
echo 'Do "make DEPS" for full fine-grained dependency information.';\
for i in $(DEPS); \
do \
$(PREPROCESSDEPS) $$i; \
done | $(SHOWDEPS) | $(CIRCULAR) \
) > $@.new
@mv $@.new $@
# Create a Circular.max file for the first time. Usually this target
# is not needed -- there should be a Circular.max file in the CVS.
$(srcdir)/Circular.max.$(CONFIG_XARCH):
# Circular is not in the dependencies because we do not want a new
# copy of Circular.max every time Circular changes. We nevertheless
# need it to so the copy -- so create it explicitly
$(MAKE) -f $(srcdir)/Makefile.sub2 Circular
cp Circular $@
# Check that the number of circular dependency has not increased in
# this build.
.PHONY: Circular-ok
Circular-ok: $(srcdir)/Circular.max.$(CONFIG_XARCH) Circular
# Circular.max.* must be the first dependency: We are going to
# reference it as $<.
@ max=$$(tail -1 $<); \
current=$$(tail -1 Circular); \
if [ $$current -gt $$max ]; \
then \
echo "Number of circular dependencies increased!"; \
diff -up $< Circular; \
exit 1; \
fi; \
echo "Circular-dependency check OK ($$current <= $$max)"
###
.PHONY: TAGS tags
# Find directories for source and header files. There may be
# duplicates, so weed out the list using a tiny Perl script.
define source-files
( find $(shell perl -e ' \
%seen = (); \
foreach $$i (@ARGV) { \
next if ! -e $$i || $$i eq "."; \
next if defined $$seen{$$i}; \
$$seen{$$i} = 1; \
print "$$i "; \
}' $(filter-out auto, $(VPATH) $(PRIVATE_INCDIR))) \
-maxdepth 1 -type f -name '*.cpp' -o -name '*.h' \
-o -name '*.cc' -o -name '*.c' )
endef
TAGS:
$(source-files) | etags --members --language=c++ -
tags:
$(source-files) | ctags --members --language=c++ -d -w -T -

View File

@@ -0,0 +1,8 @@
# -*- makefile -*-
$(ABI): $(OBJ_ABI)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,13 @@
# -*- makefile -*-
# Boot Makefile
# Add future prerequisites somewhere among the list of libraries.
# You really should not have to add anything in the $(LD) line.
include $(srcdir)/boot/$(CONFIG_XARCH)/Makerules.BOOT.$(CONFIG_XARCH)
clean-BOOT:
rm -f kernel kernel.o
cleanall-BOOT:
rm -f fiasco

View File

@@ -0,0 +1,40 @@
# -*- makefile -*-
checksum.ro: genchecksum $(KERNEL) $(BOOT)
$(CHKSUM_MESSAGE)"$(BOOT) text section"
$(VERBOSE)$(OBJDUMP) \
--start-address=0x`$(NM) $(KERNEL) | $(GREP) -w _start | cut -f1 -d' '` \
--stop-address=0x`$(NM) $(KERNEL) | $(GREP) -w _etext | cut -f1 -d' '` \
-s $(BOOT) | cut -f3,4,5,6 -d' ' | ./genchecksum > $@
checksum.rw: genchecksum $(KERNEL) $(BOOT)
$(CHKSUM_MESSAGE)"$(BOOT) data section"
$(VERBOSE)$(OBJDUMP) \
--start-address=0x`$(NM) $(KERNEL) | $(GREP) -w _kernel_data_start | cut -f1 -d' '` \
--stop-address=0x`$(NM) $(KERNEL) | $(GREP) -w _edata | cut -f1 -d' '` \
-s $(BOOT) | cut -f3,4,5,6 -d' ' | ./genchecksum > $@
$(CHECKSUM): checksum.ro checksum.rw setchecksum $(BOOT)
$(PATCH_MESSAGE)"$(BOOT)"
$(VERBOSE)./setchecksum $(BOOT) \
"0x$(shell cat checksum.ro)" \
"0x$(shell cat checksum.rw)" && echo done >$@
$(call INSTALLFILE_RULE,fiasco,fiasco)
setchecksum: setchecksum.c
$(COMP_MESSAGE)
$(VERBOSE)$(HOST_CC) -O2 -Wall $(HOST_CPPFLAGS) $(HOST_CFLAGS) -o $@ $^
genchecksum: $(OBJ_CHECKSUM)
$(LINK_MESSAGE)
$(VERBOSE)$(HOST_CXX) -fno-rtti -fno-exceptions $(HOST_CPPFLAGS) $(HOST_CXXFLAGS) -o $@ $^
$(OBJ_CHECKSUM): %.o: %.cc
$(COMP_MESSAGE)
$(VERBOSE)$(HOST_CXX) -fno-rtti -fno-exceptions -c -MD -MP -MF .$*.cc.d.new -O2 $(HOST_CPPFLAGS) $(HOST_CXXFLAGS) $< -o $@
@mv .$*.cc.d.new .$*.cc.d
clean-CHECKSUM:
rm -f genchecksum setchecksum checksum.ro checksum.rw

View File

@@ -0,0 +1,5 @@
# -*- makefile -*-
# No special rules -- crt0.o can be build using implicit rules.
clean-CRT0:

View File

@@ -0,0 +1,7 @@
# -*- makefile -*-
$(CXXLIB): $(OBJ_CXXLIB)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,17 @@
# -*- makefile -*-
#$(DRIVERS): $(OBJ_DRIVERS)
# $(AR_MESSAGE)
# $(VERBOSE)$(RM) $@
# $(VERBOSE)$(AR) $(ARFLAGS) $@ $?
libdrivers.a: $(filter-out glue%.o, $(OBJ_DRIVERS))
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^
libgluedriverslibc.a: $(filter glue%.o, $(OBJ_DRIVERS))
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,19 @@
# -*- makefile -*-
# 'date -r' doesn't work on BSDs, so we use stat there
filedate = $(shell if date --version 2>&1 | grep -q "Free Software F"; then \
date -R -r $(1); \
else \
stat -f '%Sm' $(1); \
fi)
$(GBLCFG): globalconfig.out
$(VERBOSE)$(GREP) "CONFIG_.*=[^n].*$$" globalconfig.out | cut -f2- -d'_' > $@.txt
$(VERBOSE)echo "$(call filedate,globalconfig.out)" >> $@.txt
$(VERBOSE)$(LD) -m $(LD_EMULATION) -r --oformat $(OFORMAT) \
-b binary -o $@ $@.txt
$(VERBOSE)$(RM) $@.txt
clean-GBLCFG:
rm -f $(GBLCFG)

View File

@@ -0,0 +1,7 @@
# -*- makefile -*-
$(JABI): $(OBJ_JABI)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,10 @@
$(JDB): $(OBJ_JDB) .$(JDB).deps
$(AR_MESSAGE)
$(VERBOSE)$(LD) -T/dev/null -m $(LD_EMULATION) -r -o $@ $(OBJ_JDB)
.$(JDB).deps: FORCE
$(VERBOSE)echo $(OBJ_JDB) > $@.new
$(VERBOSE)$(MOVE_IF_CHANGE) $@.new $@ || true

View File

@@ -0,0 +1,7 @@
# -*- makefile -*-
$(LIBDISASM): $(OBJ_LIBDISASM)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,7 @@
# -*- makefile -*-
$(LIBGZIP): $(OBJ_LIBGZIP)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,12 @@
# -*- makefile -*-
# Kernel library: stuff which is linked in optionally. This includes
# everything in the lib subdirectory, but may also include optional
# kernel subsystems which may be optimized away
$(LIBK): $(OBJ_LIBK)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^
clean-LIBK:

View File

@@ -0,0 +1,7 @@
# -*- makefile -*-
$(LIBKERN): $(OBJ_LIBKERN)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,7 @@
# -*- makefile -*-
$(LIBPERFCTR): $(OBJ_LIBPERFCTR)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,7 @@
# -*- makefile -*-
$(LIBREGEX): $(OBJ_LIBREGEX)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,19 @@
# vim:set ft=make:
rel2abs = $(foreach f, $(1),$(shell cd $(f); pwd))
LIBUART_srcdir := $(strip $(call rel2abs, $(srcdir)))
LIBUART_VPATH_abs := $(call rel2abs, $(VPATH_LIBUART))
$(LIBUART): FORCE
$(VERBOSE)if [ -e $(dir $@) ]; then true; else mkdir -p $(dir $@); fi
$(MAKE_MESSAGE)
$(VERBOSE)$(MAKE) -C uart \
-f $(LIBUART_srcdir)/lib/uart/Makefile \
srcdir=$(LIBUART_srcdir) \
objbase=$(objbase) \
VERBOSE="$(VERBOSE)" \
OBJECTS="$(OBJECTS_LIBUART)" \
TARGET="$(LIBUART)" \
VPATH_LIBUART="$(LIBUART_VPATH_abs)" \
PRIVATE_INCDIR="$(LIBUART_srcdir)/lib/uart $(PRIVATE_INCDIR)"

View File

@@ -0,0 +1,15 @@
# -*- makefile -*-
$(LINES): $(PROG_LINES) $(KERNEL)
$(COMP_MESSAGE)
$(VERBOSE)./$< $(KERNEL) > $@.new || true
$(VERBOSE)mv $@.new $@
$(VERBOSE)chmod 644 $@
$(call INSTALLFILE_RULE,$@,fiasco_lines)
$(PROG_LINES): genlines.c
$(LINK_MESSAGE)
$(VERBOSE)$(HOST_CC) -O2 -Wall $(HOST_CPPFLAGS) $(HOST_CXXFLAGS) -o $@ $^
clean-LINES:
rm -f $(LINES) $(PROG_LINES)

View File

@@ -0,0 +1,7 @@
# -*- makefile -*-
$(MINILIBC): $(OBJ_MINILIBC)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,3 @@
# -*- makefile -*-
include $(srcdir)/kern/$(CONFIG_XARCH)/Makerules.SYMBOLS.$(CONFIG_XARCH)

View File

@@ -0,0 +1,20 @@
# -*- makefile -*-
$(TCBOFFSET): dump_tcboffsets tcboffset.bin
./$< tcboffset.bin > $@.new
mv $@.new $@
dump_tcboffsets: dump_tcboffsets.cc tcboffset_in.h globalconfig.h .Compiler-config
$(COMP_MESSAGE)
$(VERBOSE)$(HOST_CXX) -MD -MP -MF .$@.cc.d.new -Wall -W -I . $(HOST_CPPFLAGS) $(HOST_CXXFLAGS) -o $@ $<
@mv .$@.cc.d.new .$@.cc.d
tcboffset.o: tcboffset_in.h
tcboffset.bin: tcboffset.o
$(LINK_MESSAGE)
$(VERBOSE)$(OBJCOPY) -j .e_length -j .offsets --adjust-section-vma .offsets=32 -Obinary $< $@
clean-TCBOFFSET:
rm -f tcboffset.o tcboffset.bin $(TCBOFFSET) dump_tcboffsets

View File

@@ -0,0 +1,8 @@
# -*- makefile -*-
$(TYPES): $(OBJ_TYPES)
$(AR_MESSAGE)
$(VERBOSE)$(RM) $@
$(VERBOSE)$(AR) $(ARFLAGS) $@ $^

View File

@@ -0,0 +1,116 @@
# -*- makefile -*-
# Unit tests for the KERN subsystem
UNITTEST = unittest
ALL_TESTS = $(INTERFACES_UNITTEST)
RUN_TESTS = $(addsuffix .ok, $(ALL_TESTS))
.PHONY: unittest
unittest: $(RUN_TESTS)
#
# Dependency calculation. WARNING: Black Art [tm].
# Algorithm: For each module M:
# - Include everything mentioned in the INTERFACES_KERNEL before M
# - Optimization: Sibling weed-out: Remove all modules mentioned
# directly before M that M does not #include
# - Find object files comprising these modules
# - Finally, add objects comprising module M_t, and all libraries
# subsystem KERNEL depends on
#
# Trim trailing "_t"
module_of_test = $(patsubst %_t,%,$(1))
# return sublist of $(2) which contains all elements before $(1)
earlier_modules = $(shell echo $(2) | sed 's, $(strip $(1)) *.*$$,,')
# return list of modules included by module $(1); candidates are in $(2)
inc_sedstr = 's/^ *\# *include *"\(.*\)\.h"/\1/p'
includes = $(filter $(2), \
$(shell sed -n $(inc_sedstr) auto/$(strip $(1)).h auto/$(strip $(1))_i.h))
# remove elements trailing list $(1) that do not appear in list $(2)
comma = ,
define trimlist
$(shell perl -e '@l = split " ", "$(strip $(1))";
%inc = ( $(addsuffix =>" "$(comma),$(2)) );
sub trim { return () if ! scalar @_;
my $$last = $$_[-1];
return @_ if defined $$inc{$$last};
pop @_;
return trim(@_); }
print join(" ", trim(@l));')
endef
# return list of objects belonging to a list of module
objects = $(addsuffix .o, $(foreach mod, $(1), \
$(if $($(mod)_IMPL), $($(mod)_IMPL), $(mod))))
ifdef BUILD_SOURCES
do-all: .Unittest.deps
.Unittest.deps: $(MODULES_FILE)
@echo "Generating $@"
$(VERBOSE)( $(foreach test, $(ALL_TESTS), \
test_base=$(call module_of_test, $(test)); \
echo '$(test): $(call objects, $(test)) \
$$(call objects, '"$$test_base"' $$(call trimlist, \
$(call earlier_modules, \
$(call module_of_test, $(test)), \
$(INTERFACES_KERNEL)), \
$$(call includes, '"$$test_base"', \
$$(INTERFACES_KERNEL))))';) \
) > $@.new
mv $@.new $@
endif
ifdef BUILD_OBJECTS
include .Unittest.deps
endif
# List of subsystems on which KERNEL depends
$(ALL_TESTS): $(ABI) $(JABI) $(DRIVERS) $(LIBK) $(LIBAMM) $(CXXLIB)
$(ALL_TESTS): kernel.ux.lds
# XXX Hacks
$(ALL_TESTS): sighandler.o
#
# Compilation Rules
#
$(ALL_TESTS): %: %.o
@echo "Linking test $@"
$(VERBOSE)$(CXX) -m32 -Wl,-Tkernel.ux.lds,--gc-sections \
-static $(CXXFLAGS) $(LDFLAGS) $(PROF_FLAGS) $(OPT_CXXFLAGS) \
$(filter-out kernel.ux.lds,$^) -o $@ $(TEST_LIB)
%.ok: %
ifeq ($(SYSTEM_TARGET)$(CONFIG_XARCH),ux) # Test execution for non-cross UX builds
@echo -n "Running test $* ... "
@./$< --test --quiet > $*.out
ifeq ($(RECREATE_OUTPUT),1)
@cp $*.out $(srcdir)/test/unit/$*.out.verify.$(CONFIG_ABI)
endif # RECREATE_OUTPUT
@set -e; \
testbase=$(srcdir)/test/unit/$*.out.verify; \
if [ -f $$testbase ]; then \
if [ -f $$testbase.$(CONFIG_ABI) ]; then \
echo "Error: $$testbase.$(CONFIG_ABI) and $$testbase both exist."; \
exit 1; \
fi; \
else \
testbase=$$testbase.$(CONFIG_ABI); \
fi; \
diff -u $(DIFF_FLAGS) $$testbase $*.out
else # ! ux
# Add commands for executing tests built for other architectures.
endif # ! ux
@touch $@
clean-UNITTEST:
rm -f *_t *_t.ok *_t.out .Unittest.deps

View File

@@ -0,0 +1,31 @@
# -*- makefile -*-
# vim:set ft=make:
# recent version.h required for any kip*.o files
$(filter kip%.o,$(OBJ_ABI)): $(VERSION)
$(VERSION): FORCE
$(GENVER_MESSAGE)
$(VERBOSE)if [ -d $(srcdir)/.svn ]; then \
v=`svnversion -nc $(srcdir)`; v=$${v%[A-Z]}; \
echo "#define CODE_VERSION \"r$${v#*:}\"" > $@; \
elif [ -d $(srcdir)/.git ]; then \
v=`git rev-parse --verify --short HEAD 2>/dev/null` \
echo "#define CODE_VERSION \"$$v\"" > $@; \
elif [ -d $(srcdir)/.hg ]; then \
v=`hg id 2>/dev/null` \
echo "#define CODE_VERSION \"$${v% *}\"" > $@; \
else \
echo "#define CODE_VERSION \"UNKNOWN\"" > $@; \
fi
$(VERBOSE)echo "#define BUILD_DATE \"$$(date)\"" >> $@
$(VERBOSE)if [ -e .build_nr ]; then \
nr=$$(($$(cat .build_nr) + 1)); \
else \
nr=1; \
fi; \
echo $$nr > .build_nr; \
echo "#define BUILD_NR \"$$nr\"" >> $@
clean-VERSION:
rm -f $(VERSION)

View File

@@ -0,0 +1,169 @@
# -*- makefile -*-
#
# Makerules for the sources of Fiasco
#
#
# Source-code locations
#
# If building in a separate srcdir, prepend it to module-provided include paths
ifneq ($(srcdir),.)
VPATH := $(addprefix $(srcdir)/, $(VPATH))
PRIVATE_INCDIR := $(addprefix $(srcdir)/, $(PRIVATE_INCDIR))
endif
# Finally add the current directory and the preprocessor directory
VPATH += . auto
PRIVATE_INCDIR += . auto
#
# Function for all Makreuls.<subsystem> files
#
MAKERULES_SUBSYS = $(foreach subsys, $(SUBSYSTEMS), $(firstword $(wildcard $(addsuffix /Makerules.$(subsys),$(VPATH) $(srcdir)))))
#
# special: build certain sources without profiling flags
#
NOPROFILE_C = $(filter $(addsuffix .c, $(NOPROFILE)), $(SRC_C))
NOPROFILE_CC = $(filter $(addsuffix .cc, $(NOPROFILE)), $(SRC_CC))
NOOPT_C = $(filter $(addsuffix .c, $(NOOPT)), $(SRC_C))
NOOPT_CC = $(filter $(addsuffix .cc, $(NOOPT)), $(SRC_CC))
NONDEBUG_C = $(filter $(addsuffix .c, $(NONDEBUG)), $(SRC_C))
NONDEBUG_CC = $(filter $(addsuffix .cc, $(NONDEBUG)), $(SRC_CC))
INSTRUMENT_C = $(filter $(addsuffix .c, $(INSTRUMENT)), $(SRC_C))
INSTRUMENT_CC = $(filter $(addsuffix .cc, $(INSTRUMENT)), $(SRC_CC))
$(NOPROFILE_CC:.cc=.o) : %.o: %.cc
$(COMP_MESSAGE)
$(VERBOSE)$(CXX) -c -MD -MP -MF .$*.cc.d.new -o $@ \
$(CPPFLAGS) $(CXXFLAGS) $(OPT_CXXFLAGS) $<
@mv .$*.cc.d.new .$*.cc.d
$(NOPROFILE_C:.c=.o) : %.o: %.c
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -c -MD -MP -MF .$*.c.d.new -o $@ \
$(CPPFLAGS) $(CFLAGS) $(OPT_CFLAGS) $<
@mv .$*.c.d.new .$*.c.d
$(NOOPT_CC:.cc=.o) : %.o: %.cc
$(COMP_MESSAGE_NOOPT)
$(VERBOSE)$(CXX) -c -MD -MP -MF .$*.cc.d.new -o $@ \
$(CPPFLAGS) $(CXXFLAGS) $(NOOPT_CXXFLAGS) $<
@mv .$*.cc.d.new .$*.cc.d
$(NOOPT_CC:.cc=.S) : %.S: %.cc
$(COMP_MESSAGE_NOOPT)
$(VERBOSE)$(CXX) -S -o $@ \
$(CPPFLAGS) $(CXXFLAGS) $(NOOPT_CXXFLAGS) $<
$(NOOPT_C:.c=.o) : %.o: %.c
$(COMP_MESSAGE_NOOPT)
$(VERBOSE)$(CC) -c -MD -MP -MF .$*.c.d.new -o $@ \
$(CPPFLAGS) $(CFLAGS) $(NOOPT_CFLAGS) $<
@mv .$*.c.d.new .$*.c.d
$(NOOPT_C:.c=.S) : %.S: %.c
$(COMP_MESSAGE_NOOPT)
$(VERBOSE)$(CC) -S -o $@ \
$(CPPFLAGS) $(CFLAGS) $(NOOPT_CFLAGS) $<
$(INSTRUMENT_CC:.cc=.o) : %.o: %.cc
$(COMP_MESSAGE)
$(VERBOSE)$(CXX) -c -MD -MP -MF .$*.cc.d.new -o $@ \
$(CPPFLAGS) $(CXXFLAGS) $(PROF_FLAGS) $(OPT_CXXFLAGS) $(INST_FLAGS) $<
@mv .$*.cc.d.new .$*.cc.d
$(INSTRUMENT_C:.c=.o) : %.o: %.c
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -c -MD -MP -MF .$*.c.d.new -o $@ \
$(CPPFLAGS) $(CFLAGS) $(PROF_FLAGS) $(OPT_CFLAGS) $(INST_FLAGS) $<
@mv .$*.c.d.new .$*.c.d
$(NONDEBUG_CC:.cc=.o) : %.o: %.cc
$(COMP_MESSAGE)
$(VERBOSE)$(CXX) -c -MD -MP -MF .$*.cc.d.new -o $@ $(filter-out -DNDEBUG, \
$(CPPFLAGS) $(CXXFLAGS) $(PROF_FLAGS) $(OPT_CXXFLAGS)) $<
@mv .$*.cc.d.new .$*.cc.d
$(NONDEBUG_CC:.cc=.S) : %.S: %.cc
$(COMP_MESSAGE)
$(VERBOSE)$(CXX) -S -o $@ $(filter-out -DNDEBUG, \
$(CPPFLAGS) $(CXXFLAGS) $(PROF_FLAGS) $(OPT_CXXFLAGS)) $<
$(NONDEBUG_C:.c=.o) : %.o: %.c
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -c -MD -MP -MF .$*.c.d.new -o $@ $(filter-out -DNDEBUG, \
$(CPPFLAGS) $(CFLAGS) $(PROF_FLAGS) $(OPT_CFLAGS)) $<
@mv .$*.c.d.new .$*.c.d
$(NONDEBUG_C:.c=.S) : %.S: %.c
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -S -o $@ $(filter-out -DNDEBUG, \
$(CPPFLAGS) $(CFLAGS) $(PROF_FLAGS) $(OPT_CFLAGS)) $<
###
#
# Implicit rules
#
.PHONY: FORCE
%.o: %.cc
$(COMP_MESSAGE)
$(VERBOSE)$(CXX) -c -MD -MP -MF .$*.cc.d.new -o $@ \
$(CPPFLAGS) $(CXXFLAGS) $(PROF_FLAGS) $(OPT_CXXFLAGS) $<
@mv .$*.cc.d.new .$*.cc.d
%.S: %.cc
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -S -o $@ -fverbose-asm \
$(CPPFLAGS) $(CXXFLAGS) $(PROF_FLAGS) $(OPT_CXXFLAGS) $<
%.o: %.c
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -c -MD -MP -MF .$*.c.d.new -o $@ \
$(CPPFLAGS) $(CFLAGS) $(PROF_FLAGS) $(OPT_CFLAGS) $<
@mv .$*.c.d.new .$*.c.d
%.S: %.c
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -S -o $@ -fverbose-asm \
$(CPPFLAGS) $(CFLAGS) $(PROF_FLAGS) $(OPT_CFLAGS) $<
%.o: %.S
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -c -MD -MP -MF .$*.S.d.new -o $@ \
$(CPPFLAGS) $(ASFLAGS) $<
@mv .$*.S.d.new .$*.S.d
%.i: %.c
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -E -dD -o $@ \
$(CPPFLAGS) $(CFLAGS) $(PROF_FLAGS) $(OPT_CFLAGS) $<
%.i: %.cc
$(COMP_MESSAGE)
$(VERBOSE)$(CXX) -E -dD -o $@ \
$(CPPFLAGS) $(CXXFLAGS) $(PROF_FLAGS) $(OPT_CXXFLAGS) $<
%.i: %.S
$(COMP_MESSAGE)
$(VERBOSE)$(CC) -E -dD -o $@ $(CPPFLAGS) $(ASFLAGS) $<
%.lds: %.ld
$(COMP_MESSAGE)
$(VERBOSE)$(CPP) -undef -P -DASSEMBLER -o $@ $(CPPFLAGS) $<
(%): %
$(AR_MESSAGE)
$(VERBOSE)$(AR) $(ARFLAGS) $@ $<
vpath %.ld $(srcdir)
# Suck in user-specific optional Makerules files
-include Makerules.local

View File

@@ -0,0 +1,447 @@
# -*- makefile -*-
include $(srcdir)/Modules.generic
SUBSYSTEMS = JABI ABI DRIVERS KERNEL CRT0 BOOT LIBK \
CHECKSUM CXXLIB MINILIBC LIBKERN TCBOFFSET SYMBOLS VERSION GBLCFG
ifeq ("$(CONFIG_GSTABS)","y")
SUBSYSTEMS += LINES
endif
PREPROCESS_PARTS += arch $(CONFIG_ABI) 64bit iofp \
$(CONFIG_XARCH) apic abs-timeout-hack \
i8259 pc i8254 fpu \
auto_map_kip
OBJ_SPACE-y = phys
OBJ_SPACE- = virt
OBJ_SPACE = $(OBJ_SPACE-$(CONFIG_DISABLE_VIRT_OBJ_SPACE))
PREPROCESS_PARTS += obj_space_$(OBJ_SPACE)
PREPROCESS_PARTS-$(CONFIG_MP) += mp
PREPROCESS_PARTS-$(CONFIG_LIST_ALLOC_SANITY) += list_alloc_debug
PREPROCESS_PARTS-$(CONFIG_JDB) += debug log
PREPROCESS_PARTS-$(CONFIG_SCHED_PIT) += pit_timer
PREPROCESS_PARTS-$(CONFIG_SCHED_RTC) += rtc_timer
PREPROCESS_PARTS-$(CONFIG_SCHED_APIC) += apic_timer
PREPROCESS_PARTS-$(CONFIG_SCHED_HPET) += hpet_timer
PREPROCESS_PARTS-$(CONFIG_SERIAL) += serial 16550
PREPROCESS_PARTS-$(CONFIG_WATCHDOG) += watchdog
PREPROCESS_PARTS-$(CONFIG_PERF_CNT) += perf_cnt
PREPROCESS_PARTS-$(CONFIG_IO_PROT) += io
PREPROCESS_PARTS-$(CONFIG_CPU_VIRT) += svm vmx
PREPROCESS_PARTS-$(CONFIG_SCHED_FIXED_PRIO) += sched_fixed_prio
PREPROCESS_PARTS-$(CONFIG_SCHED_WFQ) += sched_wfq
PREPROCESS_PARTS-$(CONFIG_SCHED_FP_WFQ) += sched_fp_wfq
PREPROCESS_PARTS += $(PREPROCESS_PARTS-y)
#
# TYPES subsystem
#
PRIVATE_INCDIR += types/$(CONFIG_XARCH) types
#
# ABI Subsystem
#
ABI := libabi.a
VPATH += abi/$(CONFIG_XARCH) abi
INTERFACES_ABI := l4_fpage l4_msg_item l4_buf_desc kip l4_types \
l4_error virt
kip_IMPL := kip kip-debug kip-amd64 kip-amd64-debug
l4_types_IMPL := l4_types l4_types-debug
virt_IMPL := virt-ia32-amd64
#
# JABI Subsystem
#
JABI := libjabi.a
VPATH += jabi/$(CONFIG_XARCH) jabi
INTERFACES_JABI := jdb_ktrace
#
# DRIVERS subsystem
#
DRIVERS := libdrivers.a libgluedriverslibc.a
VPATH += drivers/$(CONFIG_XARCH) drivers
PRIVATE_INCDIR += drivers/$(CONFIG_XARCH) drivers
INTERFACES_DRIVERS := mux_console console keyb io pci vga_console reset \
processor delayloop mem
ifeq ("$(CONFIG_SERIAL)","y")
INTERFACES_DRIVERS += filter_console uart
endif
reset_IMPL := reset-amd64
uart_IMPL := uart uart-16550
CXXSRC_DRIVERS := glue_libc.cc
NOOPT += $(patsubst %.o, %, $(OBJ_DRIVERS))
keyb_IMPL := keyb keyb-pc
io_IMPL := io io-amd64
mem_IMPL := mem mem-amd64
processor_IMPL := processor processor-amd64
#
# KERNEL subsystem
#
KERNEL := fiasco.image
VPATH += kern/$(CONFIG_XARCH) kern/ia32/64 kern/ia32 kern
PRIVATE_INCDIR += kern/$(CONFIG_XARCH) kern/ia32/64 kern/ia32 kern
INTERFACES_KERNEL += __main acpi io_apic irq_chip_ia32 irq_chip_pic \
irq_msi io_space apic pit checksum \
boot_console x86desc gdt idt tss timer_irq \
dirq
INTERFACES_KERNEL-$(CONFIG_CPU_VIRT) += svm vmx vm vm_svm vm_vmx
apic_IMPL := apic-ia32 apic-ia32-mp
boot_console_IMPL := boot_console-ia32-amd64
boot_info_IMPL := boot_info boot_info-ia32
clock_IMPL := clock clock-ia32
config_IMPL := config config-ia32-64 config-ia32
context_IMPL := context context-ia32 context-ia32-64 context-vcpu
continuation_IMPL := continuation-ia32-64
cpu_IMPL := cpu cpu-ia32 cpu-64
dirq_IMPL := dirq-ia32-ux
entry_frame_IMPL := entry_frame entry_frame-amd64 \
entry_frame-abs-timeout-hack
fpu_IMPL := fpu fpu-ia32-ux fpu-ia32
ipi_IMPL := ipi ipi-ia32
kdb_ke_IMPL := kdb_ke kdb_ke-ia32
kernel_thread_IMPL := kernel_thread kernel_thread-std kernel_thread-ia32
kernel_uart_IMPL := kernel_uart kernel_uart-16550
kip_init_IMPL := kip_init-ia32
kmem_IMPL := kmem-ia32 kmem-ia32-64
kmem_alloc_IMPL := kmem_alloc kmem_alloc-ia32
main_IMPL := main-ia32-64 main-ia32
mapping_IMPL := mapping-ia32-64 mapping
map_util_IMPL := map_util map_util-mem map_util-io map_util-objs
mem_layout_IMPL := mem_layout mem_layout-ia32 mem_layout-ia32-64
mem_space_IMPL := mem_space mem_space-user mem_space-ia32
mem_unit_IMPL := mem_unit-amd64
obj_space_IMPL := obj_space obj_space-$(OBJ_SPACE)
paging_IMPL := paging-ia32-64 paging-ia32 paging
perf_cnt_IMPL := perf_cnt perf_cnt-ia32
pic_IMPL := pic pic-i8259
pit_IMPL := pit-i8254
pmem_alloc_IMPL := pmem_alloc pmem_alloc-ia32-ux
rtc_IMPL := rtc-ia32
sched_context_IMPL := sched_context-wfq sched_context-fixed_prio \
sched_context-fp_wfq sched_context
space_IMPL := space space-ia32
spin_lock_IMPL := spin_lock spin_lock-ia32
startup_IMPL := startup startup-ia32
task_IMPL := task task-ia32-amd64
tb_entry_IMPL := tb_entry tb_entry-ia32-64
timer_IMPL := timer timer-ia32-amd64-ux
thread_IMPL := thread thread-ia32 thread-ia32-64 \
thread-ipc thread-pagefault thread-log \
thread-debug thread-dbf thread-vcpu
trap_state_IMPL := trap_state-amd64
tss_IMPL := tss-amd64
utcb_init_IMPL := utcb_init utcb_init-ia32
vmem_alloc_IMPL := vmem_alloc vmem_alloc-ia32
vm_factory_IMPL := vm_factory vm_factory-ia32
watchdog_IMPL := watchdog watchdog-ia32
INTERFACES_KERNEL-$(CONFIG_SERIAL) += uart_console
cpu_lock_IMPL := cpu_lock cpu_lock-generic
ifeq ("$(CONFIG_SCHED_PIT)","y")
timer_IMPL += timer-pit
timer_tick_IMPL += timer_tick-single-vector timer_tick-ia32
endif
ifeq ("$(CONFIG_SCHED_RTC)","y")
timer_IMPL += timer-rtc
timer_tick_IMPL += timer_tick-single-vector timer_tick-ia32
INTERFACES_KERNEL += rtc
endif
ifeq ("$(CONFIG_SCHED_APIC)","y")
timer_IMPL += timer-apic
timer_tick_IMPL += timer_tick-apic
endif
ifeq ("$(CONFIG_SCHED_HPET)","y")
timer_IMPL += timer-hpet
INTERFACES_KERNEL += hpet
endif
ifeq ("$(CONFIG_IO_PROT)","y")
space_IMPL += space-io
sigma0_task_IMPL = sigma0_task sigma0_task-io
thread_IMPL += thread-io
endif
ifeq ("$(CONFIG_JDB)","y")
JDB := jdb_compound.o
SUBSYSTEMS += JDB
VPATH += jdb/ia32/64 jdb/ia32 jdb
INTERFACES_KERNEL += jdb_tbuf jdb_trace tb_entry jdb_tbuf_init
INTERFACES_JDB += jdb jdb_util jdb_prompt_ext jdb_symbol jdb_lines \
jdb_dbinfo jdb_bp \
jdb_module jdb_core jdb_io_ports \
jdb_kern_info jdb_prompt_module jdb_tbuf_output \
jdb_input jdb_dump jdb_ptab jdb_misc jdb_mapdb \
jdb_tcb jdb_attach_irq \
jdb_trace_set jdb_counters jdb_table kern_cnt \
tb_entry_output jdb_exit_module \
jdb_tbuf_show jdb_console_buffer \
jdb_list jdb_screen push_console jdb_timeout \
jdb_handler_queue jdb_halt_thread \
jdb_kern_info_kmem_alloc \
jdb_kern_info_kip jdb_kern_info_config \
loadcnt jdb_utcb jdb_thread_list \
jdb_entry_frame jdb_kobject jdb_space jdb_io_apic \
jdb_trap_state jdb_ipi jdb_kobject_names \
jdb_rcupdate jdb_bt jdb_ipc_gate jdb_obj_space \
jdb_log jdb_factory jdb_iomap \
jdb_thread jdb_scheduler jdb_sender_list \
jdb_regex jdb_disasm
apic_IMPL += apic-debug
jdb_IMPL := jdb jdb-ia32-amd64 jdb-ansi jdb-ia32-ux jdb-thread \
jdb-int3-ia32-amd64 jdb-int3-ia32-ux
jdb_bp_IMPL := jdb_bp-ia32-ux jdb_bp-ia32-amd64 jdb_bp-amd64
jdb_bt_IMPL := jdb_bt-ia32-ux
jdb_entry_frame_IMPL := jdb_entry_frame-ia32
jdb_kern_info_IMPL := jdb_kern_info jdb_kern_info-ia32-amd64 \
jdb_kern_info-ia32-ux jdb_kern_info-apic \
jdb_kern_info-pci jdb_kern_info-bench \
jdb_kern_info-bench-ia32-64 \
jdb_kern_info-dr jdb_kern_info-mtrr
jdb_misc_IMPL := jdb_misc-ia32-amd64
jdb_ptab_IMPL := jdb_ptab jdb_ptab-amd64
jdb_screen_IMPL := jdb_screen jdb_screen-ia32
jdb_tcb_IMPL := jdb_tcb jdb_tcb-amd64
jdb_trace_set_IMPL := jdb_trace_set jdb_trace_set-ia32-ux
INTERFACES_JDB-$(CONFIG_JDB_MISC) += jdb_tetris
INTERFACES_JDB += $(INTERFACES_JDB-y)
endif
CXXSRC_KERNEL := kernel_panic.cc libc_backend_lock.cc
ASSRC_KERNEL := entry.S entry-native.S shortcut.S
ASSRC_KERNEL-$(CONFIG_KIP_SYSCALLS_ABS) += sys_call_page-asm.S
ASSRC_KERNEL-$(CONFIG_MP) += tramp-mp.S entry-mp.S
ASSRC_KERNEL-$(CONFIG_CPU_VIRT) += vm_svm_asm.S vm_vmx_asm.S
ASSRC_KERNEL += $(ASSRC_KERNEL-y)
NOOPT += $(filter jdb%,\
$(foreach in,$(INTERFACES_KERNEL), \
$(if $($(in)_IMPL),$($(in)_IMPL),$(in))))
NOOPT += tb_entry_output $(tb_entry_IMPL) $(perf_cnt_IMPL) \
kern_cnt loadcnt $(apic_IMPL) $(watchdog_IMPL) kdb \
$(kernel_uart_IMPL) push_console thread-dbf \
trap_state
### When testing with test threads, uncomment the following:
#
# VPATH += kern-test
# PRIVATE_INCDIR += kern-test
#
# INTERFACES_KERNEL += generic_test_thread test_thread node cpu \
# back_trace cpu_guard types
#
# node_IMPL := node node-up
# cpu_IMPL := cpu cpu-perf cpu-perfp4
# config_IMPL := config config-test
#
# kernel_thread_IMPL := $(filter-out kernel_thread-std,$(kernel_thread_IMPL)) \
# kernel_thread-test
#
# Replace this definition with your own test thread.
# test_thread_IMPL := test_thread-test26
#
### End of test-thread section
#
# CRT0 subsystem
#
CRT0 := crt0.o
ASSRC_CRT0 := crt0.S
#
# BOOT subsystem
#
BOOT := main
VPATH += boot/$(CONFIG_XARCH) boot
PRIVATE_INCDIR += boot boot/amd64
CXXSRC_BOOT := boot_libc_glue.cc bootstrap.cc boot_cpu.cc \
direct_cons_putchar.cc
ASSRC_BOOT := boot.S boot_idt.S
NOOPT += $(patsubst %.o, %, $(OBJ_BOOT))
#
# TCBOFFSET subsystem
#
TCBOFFSET := tcboffset.h
CXXSRC_TCBOFFSET := tcboffset.cc dump_tcboffsets.cc
#
# SYMBOLS subsystem
#
SYMBOLS := Symbols
#
# LINES subsystem
#
LINES := Lines
PROG_LINES := genlines
#
# CHECKSUM subsystem
#
CHECKSUM := checksum
CXXSRC_CHECKSUM := genchecksum.cc
#
# VERSION subsystem
#
VERSION := version.h
#
# GBLCFG subsystem
#
GBLCFG := gblcfg.o
OBJ_KERNEL += gblcfg.o
#
# CXXLIB Subsystem
#
CXXLIB := libcxx.a
VPATH += lib/cxxlib
INTERFACES_CXXLIB := paranoia s_cruft
#
# LIBK subsystem
#
LIBK := libk.a
VPATH += lib/libk/$(CONFIG_XARCH) lib/libk
PRIVATE_INCDIR += lib/libk/$(CONFIG_XARCH) lib/libk
INTERFACES_LIBK := atomic lock_guard auto_ptr std_macros
CXXSRC_LIBK += construction.cc
atomic_IMPL := atomic atomic-amd64
#
# LIBKERN Subsystem
#
LIBKERN := libkern.a
VPATH += lib/kern
PRIVATE_INCDIR += lib/kern/include
CSRC_LIBKERN :=
NOOPT += $(patsubst %.o, %, $(OBJ_LIBKERN))
#
# LIBGZIP subsystem (only for Jdb)
#
ifneq ($(CONFIG_JDB_GZIP),)
LIBGZIP := libgzip.a
VPATH += lib/gzip
PRIVATE_INCDIR += lib/gzip
CSRC_LIBGZIP := adler32.c crc32.c gzip.c trees.c deflate.c zutil.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBGZIP))
endif
#
# LIBDISASM subsystem (only for Jdb)
#
ifeq ("$(CONFIG_JDB_DISASM)","y")
# $(srcdir)/lib/disasm may be removed
ifeq ($(wildcard $(srcdir)/lib/disasm),)
$(error $(srcdir)/lib/disasm is missing, disable CONFIG_JDB_DISASM)
endif
SUBSYSTEMS += LIBDISASM
KERNEL_EXTRA_LIBS += $(LIBDISASM)
PREPROCESS_PARTS += jdb_disasm
LIBDISASM := libdisasm.a
VPATH += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm
CXXSRC_LIBDISASM := disasm.cc
CSRC_LIBDISASM := dis-init.c i386-dis.c dis-buf.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBDISASM))
endif
#
# LIBPERFCTR subsystem (only for Jdb)
#
LIBPERFCTR := libperfctr.a
VPATH += lib/perfctr
PRIVATE_INCDIR += lib/perfctr
CSRC_LIBPERFCTR := event_set_p5.c event_set_p6.c event_set_amd.c \
event_set_p4.c event_set_x86.c perfctr.c \
event_set_centaur.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBPERFCTR))
#
# LIBREGEX subsystem (only for Jdb)
#
LIBREGEX := libregex.a
VPATH += lib/regex
PRIVATE_INCDIR += lib/regex
CSRC_LIBREGEX := alloc.c rx.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBREGEX))
#
# MINILIBC Subsystem
#
MINILIBC := libc.a
VPATH += lib/minilibc/$(CONFIG_XARCH) lib/minilibc
PRIVATE_INCDIR += lib/minilibc/$(CONFIG_XARCH)/include lib/minilibc/include
CSRC_MINILIBC := atexit.c memccpy.c memcmp.c memmove.c memset.c memcpy.c \
memchr.c strchr.c strcmp.c strcpy.c strlen.c strncmp.c \
strncpy.c strstr.c __assert_fail.c printf.c __v_printf.c \
vprintf.c strtol.c strtoul.c lltostr.c __ltostr.c \
putchar.c puts.c getchar.c gets.c sprintf.c \
snprintf.c vsnprintf.c vsprintf.c longjmp.c isalnum.c \
isalpha.c isascii.c isblank.c iscntrl.c isdigit.c \
isgraph.c islower.c isprint.c ispunct.c isspace.c \
isupper.c isxdigit.c tolower.c strcspn.c strspn.c panic.c
ASSRC_MINILIBC := setjmp.S
# do not profile all of MINILIBC, because it is used in the BOOT subsystem
NOOPT += $(patsubst %.o, %, $(OBJ_MINILIBC))
ifeq ("$(CONFIG_JDB)","y")
ifneq ($(CONFIG_JDB_GZIP),)
ifneq ($(wildcard $(srcdir)/lib/gzip),)
SUBSYSTEMS += LIBGZIP
KERNEL_EXTRA_LIBS += $(LIBGZIP)
INTERFACES_KERNEL += jdb_gzip
endif
endif
ifneq ($(wildcard $(srcdir)/lib/perfctr),)
SUBSYSTEMS += LIBPERFCTR
KERNEL_EXTRA_LIBS += $(LIBPERFCTR)
KERNEL_UNRES_SYMS += -u perfctr_set_cputype
endif
ifneq ($(wildcard $(srcdir)/lib/regex),)
SUBSYSTEMS += LIBREGEX
KERNEL_EXTRA_LIBS += $(LIBREGEX)
PREPROCESS_PARTS += jdb_regex
endif
endif
MODULES_FILES = $(MODULES_FILE) $(MODULES_FILE_BSP)
INTERFACES_KERNEL += $(INTERFACES_KERNEL-y)

View File

@@ -0,0 +1,334 @@
# -*- makefile -*-
###############################################################################
include $(srcdir)/Modules.generic
SUBSYSTEMS := ABI KERNEL LIBK DRIVERS MINILIBC \
CXXLIB VERSION JABI TCBOFFSET CRT0
PREPROCESS_PARTS += arch $(CONFIG_ABI) 32bit $(CONFIG_XARCH) \
h3800 noncont_mem abs_syscalls
PREPROCESS_PARTS-$(CONFIG_SERIAL) += serial
PREPROCESS_PARTS-$(CONFIG_MP) += mp
PREPROCESS_PARTS-$(CONFIG_FPU) += fpu
PREPROCESS_PARTS-$(CONFIG_LIST_ALLOC_SANITY) += list_alloc_debug
PREPROCESS_PARTS-$(CONFIG_JDB) += debug jdb log
PREPROCESS_PARTS-$(CONFIG_PERF_CNT) += perf_cnt
PREPROCESS_PARTS-$(CONFIG_ARM_CACHE_L2CXX0) += outer_cache outer_cache_l2cxx0
PREPROCESS_PARTS-$(CONFIG_ARM_920T) += armv5 arm920t vcache
PREPROCESS_PARTS-$(CONFIG_ARM_926) += armv5 926 vcache
PREPROCESS_PARTS-$(CONFIG_ARM_V6PLUS) += armv6plus
PREPROCESS_PARTS-$(CONFIG_ARM_V6) += armv6
PREPROCESS_PARTS-$(CONFIG_ARM_V7) += armv7
PREPROCESS_PARTS-$(CONFIG_ARM_1136) += arm1136
PREPROCESS_PARTS-$(CONFIG_ARM_1176) += arm1176
PREPROCESS_PARTS-$(CONFIG_ARM_MPCORE) += mpcore
PREPROCESS_PARTS-$(CONFIG_ARM_CORTEX_A8) += armca8
PREPROCESS_PARTS-$(CONFIG_ARM_CORTEX_A9) += armca9
PREPROCESS_PARTS-$(CONFIG_ARM_TZ) += tz
PREPROCESS_PARTS-$(CONFIG_ARM_1176_CACHE_ALIAS_FIX) += arm1176_cache_alias_fix
PREPROCESS_PARTS-$(CONFIG_SCHED_FIXED_PRIO) += sched_fixed_prio
PREPROCESS_PARTS-$(CONFIG_SCHED_WFQ) += sched_wfq
PREPROCESS_PARTS-$(CONFIG_SCHED_FP_WFQ) += sched_fp_wfq
OBJ_SPACE-y = phys
OBJ_SPACE- = virt
OBJ_SPACE = $(OBJ_SPACE-$(CONFIG_DISABLE_VIRT_OBJ_SPACE))
ifeq ("$(CONFIG_ARM_1176)@$(CONFIG_ARM_1176_CACHE_ALIAS_FIX)","y@")
OBJ_SPACE_TYPE = phys
else
OBJ_SPACE_TYPE = $(if $(CONFIG_ARM_V6PLUS),$(OBJ_SPACE),phys)
endif
PREPROCESS_PARTS += obj_space_$(OBJ_SPACE_TYPE)
#
# TYPES subsystem
#
PRIVATE_INCDIR += types/$(CONFIG_XARCH) types
VPATH_LIBUART := $(srcdir)/lib/uart
PRIVATE_INCDIR += lib/uart
#
# DRIVERS Subsystem
#
DRIVERS := libdrivers.a libgluedriverslibc.a
VPATH += drivers/$(CONFIG_XARCH) drivers
PRIVATE_INCDIR += drivers/$(CONFIG_XARCH) drivers
INTERFACES_DRIVERS := sa1100 mux_console console uart filter_console \
h3xxx io mem mmu reset processor delayloop
io_IMPL := io io-arm
mmu_IMPL := mmu mmu-arm
mem_IMPL := mem mem-arm
uart_IMPL := uart uart-mmio
reset_IMPL :=
processor_IMPL := processor processor-arm
CXXSRC_DRIVERS := glue_libc.cc
NOOPT += $(patsubst %.o, %, $(OBJ_DRIVERS))
ALWAYS_INLINE += mem
#
# MINILIBC Subsystem
#
MINILIBC := libc.a
VPATH += lib/minilibc/$(CONFIG_XARCH) lib/minilibc
PRIVATE_INCDIR += lib/minilibc/$(CONFIG_XARCH)/include lib/minilibc/include
CSRC_MINILIBC := atexit.c memccpy.c memcmp.c memmove.c memset.c memcpy.c \
memchr.c panic.c strchr.c strcmp.c strcpy.c strlen.c \
strncmp.c strncpy.c strstr.c __assert_fail.c printf.c \
__v_printf.c vprintf.c strtol.c strtoul.c __lltostr.c \
__ltostr.c putchar.c puts.c getchar.c gets.c \
sprintf.c snprintf.c vsnprintf.c vsprintf.c \
longjmp.c isalnum.c isalpha.c isascii.c isblank.c \
iscntrl.c isdigit.c isgraph.c islower.c isprint.c \
ispunct.c isspace.c isupper.c isxdigit.c strspn.c \
strcspn.c tolower.c raise.c aeabi.c
ASSRC_MINILIBC := setjmp.S
NOOPT += $(patsubst %.o, %, $(OBJ_MINILIBC))
#
# LIBGZIP subsystem (only for Jdb)
#
ifneq ($(CONFIG_JDB_GZIP),)
LIBGZIP := libgzip.a
VPATH += lib/gzip
PRIVATE_INCDIR += lib/gzip
CSRC_LIBGZIP := adler32.c crc32.c gzip.c trees.c deflate.c zutil.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBGZIP))
endif
#
# JABI Subsystem
#
JABI := libjabi.a
VPATH += jabi/$(CONFIG_XARCH) jabi
INTERFACES_JABI := jdb_ktrace
#
# ABI Subsystem
#
ABI := libabi.a
VPATH += abi/$(CONFIG_XARCH) abi
INTERFACES_ABI := kip l4_types l4_fpage l4_msg_item \
l4_buf_desc l4_error
l4_types_IMPL := l4_types l4_types-debug
# x0!=32Bit UIDs
kip_IMPL := kip kip-debug kip-arm
#
# KERNEL subsystem
#
KERNEL := fiasco
KERNEL_EXTRA := Symbols
VPATH += kern/$(CONFIG_XARCH) kern
VPATH += jdb/arm jdb
PRIVATE_INCDIR += kern/$(CONFIG_XARCH) kern
INTERFACES_KERNEL += __main mem_op pagetable kmem_space boot_uart_init \
irq_chip_generic bootstrap kern_lib_page \
jdb_extensions outer_cache utcb_support cascade_irq \
irq_mgr_multi_chip
INTERFACES_KERNEL-$(CONFIG_SERIAL) += uart_console
INTERFACES_KERNEL-$(CONFIG_ARM_TZ) += vm
INTERFACES_KERNEL += $(INTERFACES_KERNEL-y)
boot_info_IMPL := boot_info boot_info-arch
bootstrap_IMPL := bootstrap
clock_IMPL := clock
config_IMPL := config config-arm
context_IMPL := context context-arm context-vcpu
continuation_IMPL := continuation-arm
cpu_IMPL := cpu cpu-arm
cpu_lock_IMPL := cpu_lock cpu_lock-generic
entry_frame_IMPL := entry_frame entry_frame-arm \
entry_frame-abs-timeout-hack
fpu_IMPL := fpu fpu-arm
ipi_IMPL := ipi ipi-arm
kdb_ke_IMPL := kdb_ke kdb_ke-arm
kernel_task_IMPL := kernel_task kernel_task-arm
kernel_thread_IMPL := kernel_thread kernel_thread-std kernel_thread-arm
kernel_uart_IMPL := kernel_uart
map_util_IMPL := map_util map_util-mem map_util-objs
mapping_IMPL := mapping-arm mapping
mem_layout_IMPL := mem_layout mem_layout-arm mem_layout-noncont
mem_space_IMPL := mem_space mem_space-arm mem_space-user
kmem_alloc_IMPL := kmem_alloc kmem_alloc-arm
obj_space_IMPL := obj_space obj_space-$(OBJ_SPACE_TYPE)
outer_cache_IMPL := outer_cache outer_cache-l2cxx0
pagetable_IMPL := pagetable pagetable-arch
paging_IMPL := paging-arm paging
perf_cnt_IMPL := perf_cnt perf_cnt-arm
pic_IMPL := pic
sched_context_IMPL := sched_context-wfq sched_context-fixed_prio \
sched_context-fp_wfq sched_context
space_IMPL := space space-arm
spin_lock_IMPL := spin_lock spin_lock-arm
startup_IMPL := startup startup-arm
sys_call_page_IMPL := sys_call_page sys_call_page-arm
task_IMPL := task task-arm
thread_IMPL := thread thread-arm \
thread-jdb thread-ipc \
thread-pagefault thread-log \
thread-vcpu
timer_IMPL := timer timer-arm
timer_tick_IMPL := timer_tick timer_tick-arm
utcb_init_IMPL := utcb_init utcb_init-arm
utcb_support_IMPL := utcb_support utcb_support-arm
vmem_alloc_IMPL := vmem_alloc vmem_alloc-arch
tb_entry_IMPL := tb_entry tb_entry-arm
ifeq ("$(CONFIG_JDB)","y")
JDB := jdb_compound.o
SUBSYSTEMS += JDB
INTERFACES_JDB := jdb_handler_queue jdb_module jdb_pic \
jdb jdb_core jdb_prompt_ext jdb_list \
jdb_prompt_module jdb_exit_module jdb_kern_info \
jdb_tcb jdb_screen jdb_thread_list jdb_input \
jdb_symbol jdb_lines push_console \
jdb_timeout jdb_dump jdb_ptab \
jdb_attach_irq jdb_table \
jdb_kern_info_kmem_alloc \
jdb_kern_info_kip jdb_mapdb kern_cnt \
jdb_trace_set jdb_entry_frame \
jdb_kobject jdb_kobject_names \
jdb_util jdb_space jdb_utcb \
jdb_trap_state jdb_ipi jdb_rcupdate \
jdb_ipc_gate jdb_obj_space jdb_log jdb_factory \
jdb_thread jdb_scheduler jdb_sender_list\
jdb_perf jdb_vm jdb_regex jdb_disasm jdb_bp \
jdb_tbuf_output jdb_tbuf_show tb_entry_output \
jdb_idle_stats
INTERFACES_KERNEL += jdb_tbuf jdb_tbuf_init tb_entry jdb_trace
jdb_IMPL := jdb jdb-arm jdb-ansi jdb-thread
jdb_kern_info_IMPL := jdb_kern_info jdb_kern_info-arm \
jdb_kern_info-bench jdb_kern_info-bench-arm \
jdb_kern_info-cpu-arm
jdb_dump_entry_frame_IMPL:= jdb_dump_entry_frame-arm
jdb_tcb_IMPL := jdb_tcb jdb_tcb-arm
jdb_ptab_IMPL := jdb_ptab jdb_ptab-ia32-ux-arm jdb_ptab-arm
jdb_entry_frame_IMPL := jdb_entry_frame-arm
jdb_trace_set_IMPL := jdb_trace_set jdb_trace_set-arm
jdb_bp := jdb_bp
thread_IMPL += thread-debug
ifneq ($(CONFIG_JDB_GZIP),)
ifneq ($(wildcard $(srcdir)/lib/gzip),)
SUBSYSTEMS += LIBGZIP
KERNEL_EXTRA_LIBS += $(LIBGZIP)
INTERFACES_KERNEL += jdb_gzip
endif
endif
INTERFACES_JDB += $(INTERFACES_JDB-y)
endif
CXXSRC_KERNEL := kernel_panic.cc libc_backend_lock.cc
ASSRC_KERNEL := ivt.S $(if $(CONFIG_MP),tramp-mp.S)
CPPFLAGS += $(if $(CONFIG_MP),-DMPCORE_PHYS_BASE=$(MPCORE_PHYS_BASE))
NOOPT += $(filter jdb%,\
$(foreach in,$(INTERFACES_KERNEL), \
$(if $($(in)_IMPL),$($(in)_IMPL),$(in))))
NOOPT += tb_entry tb_entry_output
#
# CRT0 subsystem
#
CRT0 := crt0.o
ASSRC_CRT0 := crt0.S
#
# CXXLIB Subsystem
#
CXXLIB := libcxx.a
VPATH += lib/cxxlib
INTERFACES_CXXLIB := paranoia s_cruft
#
# LIBK subsystem
#
LIBK := libk.a
VPATH += lib/libk/$(CONFIG_XARCH) lib/libk
PRIVATE_INCDIR += lib/libk/$(CONFIG_XARCH) lib/libk
#INTERFACES_LIBK:= atomic lock_guard profile uuencode gmon unistd panic auto_ptr
INTERFACES_LIBK := std_macros atomic lock_guard auto_ptr
CXXSRC_LIBK += construction.cc
atomic_IMPL := atomic atomic-arm-up
ifeq ("$(CONFIG_JDB_DISASM)","y")
# $(srcdir)/lib/disasm may be removed
ifeq ($(wildcard $(srcdir)/lib/disasm),)
$(error $(srcdir)/lib/disasm is missing, disable CONFIG_JDB_DISASM)
endif
SUBSYSTEMS += LIBDISASM
KERNEL_EXTRA_LIBS += $(LIBDISASM)
PREPROCESS_PARTS += jdb_disasm
LIBDISASM := libdisasm.a
VPATH += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm
CXXSRC_LIBDISASM := disasm.cc
CSRC_LIBDISASM := arm-dis.c dis-init.c dis-buf.c safe-ctype.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBDISASM))
endif
#
# VERSION subsystem
#
VERSION := version.h
TCBOFFSET := tcboffset.h
CXXSRC_TCBOFFSET := tcboffset.cc dump_tcboffsets.cc
BSP_NAME := $(patsubst "%",%,$(CONFIG_BSP_NAME))
MODULES_FILE_BSP := $(srcdir)/kern/arm/bsp/$(BSP_NAME)/Modules
ifeq ($(wildcard $(MODULES_FILE_BSP)),)
$(error No BSP name defined or no BSP Modules file available)
endif
include $(MODULES_FILE_BSP)
VPATH += kern/arm/bsp/$(BSP_NAME)
PREPROCESS_PARTS += $(PREPROCESS_PARTS-y)
ifeq ("$(filter LIBUART, $(SUBSYSTEMS))","LIBUART")
LIBUART := uart/libuart.a
endif
ifneq ($(CONFIG_MP),)
ifeq ($(MPCORE_PHYS_BASE),)
$(error $(MODULES_FILE_BSP) needs to set MPCORE_PHYS_BASE variable)
endif
endif
MODULES_FILES = $(MODULES_FILE) $(MODULES_FILE_BSP)

View File

@@ -0,0 +1,29 @@
INTERFACES_KERNEL := cpu_mask rcupdate kobject_mapdb context_base \
mem_region per_cpu_data startup boot_info \
queue queue_item l4_buf_iter bitmap \
mapping spin_lock mapping_tree mappable \
dbg_page_info mapdb pic kobject_dbg koptions \
kobject_iface kobject ready_queue_wfq \
ready_queue_fp obj_space ptab_base ram_quota \
ref_ptr ref_obj mem_space space \
vlog kmem kmem_alloc slab_cache mem_layout \
kmem_slab switch_lock kip_init \
thread_lock helping_lock cpu_lock timer timeout \
ipc_timeout timeslice_timeout per_cpu_data_alloc \
vcpu kobject_helper icu_helper thread_state \
context mp_lock sender receiver mem_unit factory \
lock ipc_sender thread thread_object syscalls \
kernel_thread map_util irq banner warn \
app_cpu_thread globals watchdog kernel_uart \
main config vmem_alloc paging fpu \
fpu_state fpu_alloc cpu entry_frame \
kernel_console ipc_gate task sigma0_task \
kernel_task \
irq_controller irq_chip irq_mgr terminate \
continuation timer_tick \
sched_context utcb_init perf_cnt trap_state \
buddy_alloc vkey kdb_ke prio_list ipi scheduler \
clock vm_factory sys_call_page boot_alloc
syscalls_IMPL := syscalls syscalls-log
timer_tick_IMPL := timer_tick

View File

@@ -0,0 +1,448 @@
# -*- makefile -*-
include $(srcdir)/Modules.generic
SUBSYSTEMS = JABI ABI DRIVERS KERNEL CRT0 BOOT LIBK \
CHECKSUM CXXLIB MINILIBC LIBKERN TCBOFFSET VERSION GBLCFG
ifeq ("$(CONFIG_GSTABS)","y")
SUBSYSTEMS += LINES
endif
PREPROCESS_PARTS += arch $(CONFIG_ABI) 32bit iofp \
$(CONFIG_XARCH) apic abs-timeout-hack \
i8259 pc i8254 fpu \
abs_syscalls auto_map_kip
OBJ_SPACE-y = phys
OBJ_SPACE- = virt
OBJ_SPACE = $(OBJ_SPACE-$(CONFIG_DISABLE_VIRT_OBJ_SPACE))
PREPROCESS_PARTS += obj_space_$(OBJ_SPACE)
PREPROCESS_PARTS-$(CONFIG_MP) += mp
PREPROCESS_PARTS-$(CONFIG_LIST_ALLOC_SANITY) += list_alloc_debug
PREPROCESS_PARTS-$(CONFIG_JDB) += debug log
PREPROCESS_PARTS-$(CONFIG_SCHED_PIT) += pit_timer
PREPROCESS_PARTS-$(CONFIG_SCHED_RTC) += rtc_timer
PREPROCESS_PARTS-$(CONFIG_SCHED_APIC) += apic_timer
PREPROCESS_PARTS-$(CONFIG_SCHED_HPET) += hpet_timer
PREPROCESS_PARTS-$(CONFIG_SERIAL) += serial 16550
PREPROCESS_PARTS-$(CONFIG_WATCHDOG) += watchdog
PREPROCESS_PARTS-$(CONFIG_PERF_CNT) += perf_cnt
PREPROCESS_PARTS-$(CONFIG_IO_PROT) += io
PREPROCESS_PARTS-$(CONFIG_CPU_VIRT) += svm vmx
PREPROCESS_PARTS-$(CONFIG_SCHED_FIXED_PRIO) += sched_fixed_prio
PREPROCESS_PARTS-$(CONFIG_SCHED_WFQ) += sched_wfq
PREPROCESS_PARTS-$(CONFIG_SCHED_FP_WFQ) += sched_fp_wfq
PREPROCESS_PARTS += $(PREPROCESS_PARTS-y)
#
# TYPES subsystem
#
PRIVATE_INCDIR += types/$(CONFIG_XARCH) types
#
# ABI Subsystem
#
ABI := libabi.a
VPATH += abi/$(CONFIG_XARCH) abi
INTERFACES_ABI := l4_fpage l4_msg_item l4_buf_desc kip l4_types \
l4_error virt
kip_IMPL := kip kip-debug kip-ia32 kip-ia32-debug
l4_types_IMPL := l4_types l4_types-debug
virt_IMPL := virt-ia32-amd64
#
# JABI Subsystem
#
JABI := libjabi.a
VPATH += jabi/$(CONFIG_XARCH) jabi
INTERFACES_JABI := jdb_ktrace
#
# DRIVERS subsystem
#
DRIVERS := libdrivers.a libgluedriverslibc.a
VPATH += drivers/$(CONFIG_XARCH) drivers
PRIVATE_INCDIR += drivers/$(CONFIG_XARCH) drivers
INTERFACES_DRIVERS := mux_console console keyb io pci vga_console reset \
processor delayloop mem
ifeq ("$(CONFIG_SERIAL)","y")
INTERFACES_DRIVERS += filter_console uart
endif
reset_IMPL := reset-ia32
uart_IMPL := uart uart-16550
CXXSRC_DRIVERS := glue_libc.cc
NOOPT += $(patsubst %.o, %, $(OBJ_DRIVERS))
keyb_IMPL := keyb keyb-pc
io_IMPL := io io-ia32
mem_IMPL := mem mem-ia32
processor_IMPL := processor processor-ia32
#
# KERNEL subsystem
#
KERNEL := fiasco.image
VPATH += kern/$(CONFIG_XARCH) kern/ia32/32 kern/ia32 kern
PRIVATE_INCDIR += kern/$(CONFIG_XARCH) kern/ia32/32 kern/ia32 kern
INTERFACES_KERNEL += __main acpi irq_chip_ia32 irq_chip_pic io_apic \
irq_msi boot_console \
io_space apic pit checksum x86desc gdt idt tss \
timer_irq dirq
INTERFACES_KERNEL-$(CONFIG_CPU_VIRT) += svm vmx vm vm_svm vm_vmx
apic_IMPL := apic-ia32 apic-ia32-mp
boot_console_IMPL := boot_console-ia32-amd64
boot_info_IMPL := boot_info boot_info-ia32
clock_IMPL := clock clock-ia32
config_IMPL := config config-ia32-32 config-ia32
context_IMPL := context context-ia32 context-ia32-32 context-vcpu
continuation_IMPL := continuation-ia32-32
cpu_IMPL := cpu cpu-ia32 cpu-32
dirq_IMPL := dirq-ia32-ux
entry_frame_IMPL := entry_frame entry_frame-ia32-ux \
entry_frame-abs-timeout-hack
fpu_IMPL := fpu fpu-ia32-ux fpu-ia32
ipi_IMPL := ipi ipi-ia32
kdb_ke_IMPL := kdb_ke kdb_ke-ia32
kernel_thread_IMPL := kernel_thread kernel_thread-std kernel_thread-ia32
kernel_uart_IMPL := kernel_uart kernel_uart-16550
kip_init_IMPL := kip_init-ia32
kmem_IMPL := kmem-ia32 kmem-ia32-32
kmem_alloc_IMPL := kmem_alloc kmem_alloc-ia32
main_IMPL := main-ia32-32 main-ia32
mapping_IMPL := mapping-ia32-32 mapping
map_util_IMPL := map_util map_util-mem map_util-io map_util-objs
mem_layout_IMPL := mem_layout mem_layout-ia32 mem_layout-ia32-32
mem_space_IMPL := mem_space mem_space-user mem_space-ia32
mem_unit_IMPL := mem_unit-ia32
obj_space_IMPL := obj_space obj_space-$(OBJ_SPACE)
paging_IMPL := paging-ia32-32 paging-ia32 paging
perf_cnt_IMPL := perf_cnt perf_cnt-ia32
pic_IMPL := pic pic-i8259
pit_IMPL := pit-i8254
pmem_alloc_IMPL := pmem_alloc pmem_alloc-ia32-ux
rtc_IMPL := rtc-ia32
sched_context_IMPL := sched_context-wfq sched_context-fixed_prio \
sched_context-fp_wfq sched_context
space_IMPL := space space-ia32
spin_lock_IMPL := spin_lock spin_lock-ia32
startup_IMPL := startup startup-ia32
sys_call_page_IMPL := sys_call_page sys_call_page-abs-ia32
task_IMPL := task task-ia32-amd64
tb_entry_IMPL := tb_entry tb_entry-ia32-32
timer_IMPL := timer timer-ia32-amd64-ux
thread_IMPL := thread thread-ia32 thread-ia32-32 \
thread-ipc thread-pagefault thread-log \
thread-debug thread-dbf thread-vcpu
utcb_init_IMPL := utcb_init utcb_init-ia32
vmem_alloc_IMPL := vmem_alloc vmem_alloc-ia32
vm_factory_IMPL := vm_factory vm_factory-ia32
watchdog_IMPL := watchdog watchdog-ia32
INTERFACES_KERNEL-$(CONFIG_SERIAL) += uart_console
cpu_lock_IMPL := cpu_lock cpu_lock-generic
ifeq ("$(CONFIG_SCHED_PIT)","y")
timer_IMPL += timer-pit
timer_tick_IMPL += timer_tick-single-vector timer_tick-ia32
endif
ifeq ("$(CONFIG_SCHED_RTC)","y")
timer_IMPL += timer-rtc
timer_tick_IMPL += timer_tick-single-vector timer_tick-ia32
INTERFACES_KERNEL += rtc
endif
ifeq ("$(CONFIG_SCHED_APIC)","y")
timer_IMPL += timer-apic
timer_tick_IMPL += timer_tick-apic
endif
ifeq ("$(CONFIG_SCHED_HPET)","y")
timer_IMPL += timer-hpet
timer_tick_IMPL += timer_tick-single-vector timer_tick-ia32
INTERFACES_KERNEL += hpet
endif
ifeq ("$(CONFIG_IO_PROT)","y")
space_IMPL += space-io
sigma0_task_IMPL = sigma0_task sigma0_task-io
thread_IMPL += thread-io
endif
ifeq ("$(CONFIG_JDB)","y")
JDB := jdb_compound.o
SUBSYSTEMS += JDB
VPATH += jdb/ia32/32 jdb/ia32 jdb
INTERFACES_KERNEL += jdb_tbuf jdb_tbuf_init jdb_trace tb_entry
INTERFACES_JDB += jdb jdb_util jdb_prompt_ext jdb_symbol jdb_lines \
jdb_dbinfo jdb_bp \
jdb_module jdb_core jdb_io_ports \
jdb_kern_info jdb_prompt_module jdb_tbuf_output \
jdb_input jdb_dump jdb_ptab jdb_misc jdb_mapdb \
jdb_tcb jdb_attach_irq \
jdb_trace_set jdb_counters jdb_table kern_cnt \
tb_entry_output jdb_exit_module \
jdb_tbuf_show jdb_console_buffer \
jdb_list jdb_screen push_console jdb_timeout \
jdb_handler_queue jdb_halt_thread \
jdb_kern_info_kmem_alloc \
jdb_kern_info_kip jdb_kern_info_config \
loadcnt jdb_utcb jdb_thread_list \
jdb_entry_frame jdb_kobject jdb_space jdb_io_apic \
jdb_trap_state jdb_ipi jdb_kobject_names \
jdb_rcupdate jdb_bt jdb_ipc_gate jdb_obj_space \
jdb_log jdb_factory jdb_iomap \
jdb_thread jdb_scheduler jdb_sender_list \
jdb_regex jdb_disasm
apic_IMPL += apic-debug
jdb_IMPL := jdb jdb-ia32-amd64 jdb-ansi jdb-ia32-ux jdb-thread \
jdb-int3-ia32-amd64 jdb-int3-ia32-ux
jdb_bp_IMPL := jdb_bp-ia32-ux jdb_bp-ia32-amd64 jdb_bp-ia32
jdb_bt_IMPL := jdb_bt-ia32-ux
jdb_entry_frame_IMPL := jdb_entry_frame-ia32
jdb_kern_info_IMPL := jdb_kern_info jdb_kern_info-ia32-amd64 \
jdb_kern_info-ia32-ux jdb_kern_info-apic \
jdb_kern_info-pci jdb_kern_info-bench \
jdb_kern_info-bench-ia32-32 \
jdb_kern_info-dr jdb_kern_info-mtrr
jdb_misc_IMPL := jdb_misc-ia32-amd64
jdb_ptab_IMPL := jdb_ptab jdb_ptab-ia32-ux-arm
jdb_screen_IMPL := jdb_screen jdb_screen-ia32
jdb_tcb_IMPL := jdb_tcb jdb_tcb-ia32-ux
jdb_trace_set_IMPL := jdb_trace_set jdb_trace_set-ia32-ux
INTERFACES_JDB-$(CONFIG_JDB_MISC) += jdb_tetris
INTERFACES_JDB += $(INTERFACES_JDB-y)
endif
CXXSRC_KERNEL := kernel_panic.cc libc_backend_lock.cc
ASSRC_KERNEL := entry.S entry-native.S sys_call_page-asm.S
ASSRC_KERNEL-$(CONFIG_MP) += tramp-mp.S entry-mp.S
ASSRC_KERNEL-$(CONFIG_CPU_VIRT) += vm_svm_asm.S vm_vmx_asm.S
ASSRC_KERNEL += $(ASSRC_KERNEL-y)
NOOPT += $(filter jdb%,\
$(foreach in,$(INTERFACES_KERNEL), \
$(if $($(in)_IMPL),$($(in)_IMPL),$(in))))
NOOPT += tb_entry_output $(tb_entry_IMPL) $(perf_cnt_IMPL) \
kern_cnt loadcnt $(apic_IMPL) $(watchdog_IMPL) kdb \
$(kernel_uart_IMPL) push_console virq thread-dbf \
trap_state
NOOPT += $(foreach in,$(INTERFACES_JDB), \
$(if $($(in)_IMPL),$($(in)_IMPL),$(in)))
### When testing with test threads, uncomment the following:
#
# VPATH += kern-test
# PRIVATE_INCDIR += kern-test
#
# INTERFACES_KERNEL += generic_test_thread test_thread node cpu \
# back_trace cpu_guard types
#
# node_IMPL := node node-up
# cpu_IMPL := cpu cpu-perf cpu-perfp4
# config_IMPL := config config-test
#
# kernel_thread_IMPL := $(filter-out kernel_thread-std,$(kernel_thread_IMPL)) \
# kernel_thread-test
#
# Replace this definition with your own test thread.
# test_thread_IMPL := test_thread-test26
#
### End of test-thread section
#
# CRT0 subsystem
#
CRT0 := crt0.o
ASSRC_CRT0 := crt0.S
#
# BOOT subsystem
#
BOOT := main
VPATH += boot/$(CONFIG_XARCH) boot
PRIVATE_INCDIR += boot boot/ia32
CXXSRC_BOOT := boot_libc_glue.cc bootstrap.cc boot_cpu.cc \
direct_cons_putchar.cc
ASSRC_BOOT := boot.S boot_idt.S
NOOPT += $(patsubst %.o, %, $(OBJ_BOOT))
#
# TCBOFFSET subsystem
#
TCBOFFSET := tcboffset.h
CXXSRC_TCBOFFSET := tcboffset.cc dump_tcboffsets.cc
#
# SYMBOLS subsystem
#
SYMBOLS := Symbols
#
# LINES subsystem
#
LINES := Lines
PROG_LINES := genlines
#
# CHECKSUM subsystem
#
CHECKSUM := checksum
CXXSRC_CHECKSUM := genchecksum.cc
#
# VERSION subsystem
#
VERSION := version.h
#
# GBLCFG subsystem
#
GBLCFG := gblcfg.o
OBJ_KERNEL += gblcfg.o
#
# CXXLIB Subsystem
#
CXXLIB := libcxx.a
VPATH += lib/cxxlib
INTERFACES_CXXLIB := paranoia s_cruft
#
# LIBK subsystem
#
LIBK := libk.a
VPATH += lib/libk/$(CONFIG_XARCH) lib/libk
PRIVATE_INCDIR += lib/libk/$(CONFIG_XARCH) lib/libk
INTERFACES_LIBK := atomic lock_guard auto_ptr std_macros
CSRC_LIBK += gcc_lib.c
CXXSRC_LIBK += construction.cc
#
# LIBKERN Subsystem
#
LIBKERN := libkern.a
VPATH += lib/kern
PRIVATE_INCDIR += lib/kern/include
CSRC_LIBKERN :=
NOOPT += $(patsubst %.o, %, $(OBJ_LIBKERN))
#
# LIBGZIP subsystem (only for Jdb)
#
ifneq ($(CONFIG_JDB_GZIP),)
LIBGZIP := libgzip.a
VPATH += lib/gzip
PRIVATE_INCDIR += lib/gzip
CSRC_LIBGZIP := adler32.c crc32.c gzip.c trees.c deflate.c zutil.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBGZIP))
endif
#
# LIBDISASM subsystem (only for Jdb)
#
ifeq ("$(CONFIG_JDB_DISASM)","y")
# $(srcdir)/lib/disasm may be removed
ifeq ($(wildcard $(srcdir)/lib/disasm),)
$(error $(srcdir)/lib/disasm is missing, disable CONFIG_JDB_DISASM)
endif
SUBSYSTEMS += LIBDISASM
KERNEL_EXTRA_LIBS += $(LIBDISASM)
PREPROCESS_PARTS += jdb_disasm
LIBDISASM := libdisasm.a
VPATH += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm
CXXSRC_LIBDISASM := disasm.cc
CSRC_LIBDISASM := dis-init.c i386-dis.c dis-buf.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBDISASM))
endif
#
# LIBPERFCTR subsystem (only for Jdb)
#
LIBPERFCTR := libperfctr.a
VPATH += lib/perfctr
PRIVATE_INCDIR += lib/perfctr
CSRC_LIBPERFCTR := event_set_p5.c event_set_p6.c event_set_amd.c \
event_set_p4.c event_set_x86.c perfctr.c \
event_set_centaur.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBPERFCTR))
#
# LIBREGEX subsystem (only for Jdb)
#
LIBREGEX := libregex.a
VPATH += lib/regex
PRIVATE_INCDIR += lib/regex
CSRC_LIBREGEX := alloc.c rx.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBREGEX))
#
# MINILIBC Subsystem
#
MINILIBC := libc.a
VPATH += lib/minilibc/$(CONFIG_XARCH) lib/minilibc
PRIVATE_INCDIR += lib/minilibc/$(CONFIG_XARCH)/include lib/minilibc/include
CSRC_MINILIBC := atexit.c memccpy.c memcmp.c memmove.c memset.c memcpy.c \
memchr.c strchr.c strcmp.c strcpy.c strlen.c strncmp.c \
strncpy.c strstr.c __assert_fail.c printf.c __v_printf.c \
vprintf.c strtol.c strtoul.c lltostr.c __ltostr.c \
putchar.c puts.c getchar.c gets.c sprintf.c \
snprintf.c vsnprintf.c vsprintf.c longjmp.c isalnum.c \
isalpha.c isascii.c isblank.c iscntrl.c isdigit.c \
isgraph.c islower.c isprint.c ispunct.c isspace.c \
isupper.c isxdigit.c tolower.c strcspn.c strspn.c panic.c
ASSRC_MINILIBC := setjmp.S
# do not profile all of MINILIBC, because it is used in the BOOT subsystem
NOOPT += $(patsubst %.o, %, $(OBJ_MINILIBC))
ifeq ("$(CONFIG_JDB)","y")
ifneq ($(CONFIG_JDB_GZIP),)
ifneq ($(wildcard $(srcdir)/lib/gzip),)
SUBSYSTEMS += LIBGZIP
KERNEL_EXTRA_LIBS += $(LIBGZIP)
INTERFACES_KERNEL += jdb_gzip
endif
endif
ifneq ($(wildcard $(srcdir)/lib/perfctr),)
SUBSYSTEMS += LIBPERFCTR
KERNEL_EXTRA_LIBS += $(LIBPERFCTR)
KERNEL_UNRES_SYMS += -u perfctr_set_cputype
endif
ifneq ($(wildcard $(srcdir)/lib/regex),)
SUBSYSTEMS += LIBREGEX
KERNEL_EXTRA_LIBS += $(LIBREGEX)
PREPROCESS_PARTS += jdb_regex
endif
endif
MODULES_FILES = $(MODULES_FILE) $(MODULES_FILE_BSP)
INTERFACES_KERNEL += $(INTERFACES_KERNEL-y)

View File

@@ -0,0 +1,259 @@
# -*- makefile -*-
###############################################################################
include $(srcdir)/Modules.generic
SUBSYSTEMS := ABI KERNEL LIBUART LIBK DRIVERS MINILIBC CXXLIB CRT0 \
VERSION JABI TCBOFFSET
PREPROCESS_PARTS += $(CONFIG_XARCH) $(CONFIG_ABI) 32bit \
abs_syscalls big_endian jdb_thread_names \
obj_space_phys
PREPROCESS_PARTS-$(CONFIG_SERIAL) += serial
PREPROCESS_PARTS-$(CONFIG_JDB) += debug jdb log
PREPROCESS_PARTS-$(CONFIG_SCHED_FIXED_PRIO) += sched_fixed_prio
PREPROCESS_PARTS-$(CONFIG_SCHED_WFQ) += sched_wfq
PREPROCESS_PARTS-$(CONFIG_SCHED_FP_WFQ) += sched_fp_wfq
PREPROCESS_PARTS += $(PREPROCESS_PARTS-y)
#
# TYPES subsystem
#
PRIVATE_INCDIR += types/$(CONFIG_XARCH) types
#
# LIBUART subsystem
#
ifeq ("$(filter LIBUART, $(SUBSYSTEMS))","LIBUART")
LIBUART := uart/libuart.a
PREPROCESS_PARTS += libuart
endif
OBJECTS_LIBUART += uart_of.o uart_mpc52xx.o
VPATH_LIBUART := $(srcdir)/lib/uart
PRIVATE_INCDIR += lib/uart drivers/$(CONFIG_XARCH)/include
#
# DRIVERS Subsystem
#
DRIVERS := libdrivers.a libgluedriverslibc.a
VPATH += drivers/$(CONFIG_XARCH) drivers
PRIVATE_INCDIR += drivers/$(CONFIG_XARCH) drivers
INTERFACES_DRIVERS := mux_console console mem reset uart filter_console \
processor delayloop io
io_IMPL := io io-ppc32
mem_IMPL := mem mem-ppc32
uart_IMPL := uart uart-mmio
reset_IMPL := reset-ppc32
processor_IMPL := processor processor-ppc32
CXXSRC_DRIVERS := glue_libc.cc
NOOPT += $(patsubst %.o, %, $(OBJ_DRIVERS))
#
# MINILIBC Subsystem
#
MINILIBC := libc.a
VPATH += lib/minilibc/$(CONFIG_XARCH) lib/minilibc
PRIVATE_INCDIR += lib/minilibc/$(CONFIG_XARCH)/include lib/minilibc/include
CSRC_MINILIBC := atexit.c memccpy.c memcmp.c memmove.c memset.c memcpy.c \
memchr.c panic.c strchr.c strcmp.c strcpy.c strlen.c \
strncmp.c strncpy.c strstr.c __assert_fail.c printf.c \
__v_printf.c vprintf.c strtol.c strtoul.c __lltostr.c \
__ltostr.c putchar.c puts.c getchar.c gets.c \
sprintf.c snprintf.c vsnprintf.c vsprintf.c \
longjmp.c isalnum.c isalpha.c isascii.c isblank.c \
iscntrl.c isdigit.c isgraph.c islower.c isprint.c \
ispunct.c isspace.c isupper.c isxdigit.c strspn.c \
strcspn.c tolower.c
ASSRC_MINILIBC := setjmp.S
NOOPT += $(patsubst %.o, %, $(OBJ_MINILIBC))
#
# JABI Subsystem
#
JABI := libjabi.a
VPATH += jabi/$(CONFIG_XARCH) jabi
INTERFACES_JABI := jdb_ktrace
#
# ABI Subsystem
#
ABI := libabi.a
VPATH += abi/$(CONFIG_XARCH) abi
INTERFACES_ABI := kip l4_types l4_fpage l4_msg_item l4_buf_desc l4_error
kip_IMPL := kip kip-debug kip-ppc32
l4_types_IMPL := l4_types l4_types-debug
#
# KERNEL subsystem
#
KERNEL := fiasco
KERNEL_EXTRA := Symbols
VPATH += kern/$(CONFIG_XARCH) kern
VPATH += jdb/$(CONFIG_XARCH) jdb
PRIVATE_INCDIR += kern/$(CONFIG_XARCH) kern kern/ia32
INTERFACES_KERNEL += boot_uart_init bootstrap decrementer msr ppc_types \
util utcb_support irq_chip_generic dirq
INTERFACES_KERNEL-$(CONFIG_SERIAL) += uart_console
INTERFACES_KERNEL += $(INTERFACES_KERNEL-y)
boot_info_IMPL := boot_info boot_info-ppc32
clock_IMPL := clock
config_IMPL := config config-ppc32
context_IMPL := context context-ppc32 context-vcpu
continuation_IMPL := continuation-ppc32
cpu_IMPL := cpu cpu-ppc32
cpu_lock_IMPL := cpu_lock cpu_lock-generic
dirq_IMPL := dirq-ppc32
entry_frame_IMPL := entry_frame entry_frame-ppc32
kdb_ke_IMPL := kdb_ke kdb_ke-ppc32
kernel_task_IMPL := kernel_task kernel_task-ppc32
kernel_thread_IMPL := kernel_thread kernel_thread-std kernel_thread-ppc32
kernel_uart_IMPL := kernel_uart kernel_uart-ppc32
kmem_alloc_IMPL := kmem_alloc kmem_alloc-ppc32
map_util_IMPL := map_util map_util-mem map_util-objs
mapping_IMPL := mapping-ppc32 mapping
mem_layout_IMPL := mem_layout mem_layout-ppc32
mem_unit_IMPL := mem_unit-ppc32
mem_space_IMPL := mem_space mem_space-user mem_space-ppc32 \
mem_space-htab mem_space-cache
obj_space_IMPL := obj_space obj_space-phys
paging_IMPL := paging-ppc32 paging
pic_IMPL := pic
sched_context_IMPL := sched_context-wfq sched_context-fixed_prio \
sched_context-fp_wfq sched_context
space_IMPL := space space-ppc32
startup_IMPL := startup startup-ppc32
sys_call_page_IMPL := sys_call_page sys_call_page-ppc32
task_IMPL := task task-ppc32
timer_IMPL := timer timer-decr-ppc32
timer_tick_IMPL := timer_tick timer_tick-ppc32
thread_IMPL := thread thread-log thread-pagefault \
thread-ppc32 thread-ipc thread-jdb \
thread-vcpu
utcb_init_IMPL := utcb_init utcb_init-ppc32
utcb_support_IMPL := utcb_support utcb_support-ppc32
vmem_alloc_IMPL := vmem_alloc vmem_alloc-ppc32
tb_entry_IMPL := tb_entry tb_entry-ppc32
warn_IMPL := warn warn-ppc32
ifeq ("$(CONFIG_JDB)","y")
JDB := jdb_compound.o
SUBSYSTEMS += JDB
INTERFACES_JDB := jdb jdb_attach_irq jdb_core jdb_scheduler jdb_entry_frame \
jdb_exit_module jdb_factory jdb_handler_queue \
jdb_input jdb_ipc_gate jdb_kobject jdb_kobject_names\
jdb_lines jdb_list jdb_module jdb_prompt_module \
jdb_obj_space jdb_prompt_ext jdb_screen jdb_space \
jdb_symbol jdb_table jdb_tcb jdb_thread \
jdb_thread_list jdb_util kern_cnt \
push_console jdb_regex jdb_disasm jdb_bp \
jdb_tbuf_output \
jdb_tbuf_show tb_entry_output
INTERFACES_KERNEL += jdb_tbuf jdb_tbuf_init tb_entry jdb_trace
jdb_IMPL := jdb jdb-ansi jdb-ppc32 jdb-thread
jdb_tcb_IMPL := jdb_tcb jdb_tcb-ppc32
jdb_entry_frame_IMPL := jdb_entry_frame-ppc32
jdb_bp := jdb_bp
thread_IMPL += thread-debug
INTERFACES_JDB += $(INTERFACES_JDB-y)
endif
CXXSRC_KERNEL := kernel_panic.cc libc_backend_lock.cc
ASSRC_KERNEL := exception.S phys_mem.S
NOOPT += $(filter jdb%,\
$(foreach in,$(INTERFACES_KERNEL), \
$(if $($(in)_IMPL),$($(in)_IMPL),$(in))))
NOOPT += tb_entry #tb_entry_output
#
# CRT0 subsystem
#
CRT0 := crt0.o
ASSRC_CRT0 := crt0.S
#
# CXXLIB Subsystem
#
CXXLIB := libcxx.a
VPATH += lib/cxxlib
INTERFACES_CXXLIB := paranoia s_cruft
#
# LIBK subsystem
#
LIBK := libk.a
VPATH += lib/libk/$(CONFIG_XARCH) lib/libk
PRIVATE_INCDIR += lib/libk/$(CONFIG_XARCH) lib/libk
INTERFACES_LIBK := auto_ptr atomic lock_guard std_macros
CXXSRC_LIBK += construction.cc
atomic_IMPL := atomic atomic-ppc32
#
# LIBDISASM subsystem (only for Jdb)
#
ifeq ("$(CONFIG_JDB_DISASM)","y")
# $(srcdir)/lib/disasm may be removed
ifeq ($(wildcard $(srcdir)/lib/disasm),)
$(error $(srcdir)/lib/disasm is missing, disable CONFIG_JDB_DISASM)
endif
SUBSYSTEMS += LIBDISASM
KERNEL_EXTRA_LIBS += $(LIBDISASM)
PREPROCESS_PARTS += jdb_disasm
LIBDISASM := libdisasm.a
VPATH += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm
CXXSRC_LIBDISASM := disasm.cc
CSRC_LIBDISASM := ppc-dis.c ppc-opc.c dis-init.c dis-buf.c \
safe-ctype.c libbfd.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBDISASM))
endif
#
# VERSION subsystem
#
VERSION := version.h
TCBOFFSET := tcboffset.h
CXXSRC_TCBOFFSET := tcboffset.cc dump_tcboffsets.cc
#
# BSP subsystem
#
BSP_NAME := $(patsubst "%",%,$(CONFIG_BSP_NAME))
MODULES_FILE_BSP := $(srcdir)/kern/ppc32/bsp/$(BSP_NAME)/Modules
ifeq ($(wildcard $(MODULES_FILE_BSP)),)
$(error No BSP name defined or no BSP Modules file available)
endif
include $(MODULES_FILE_BSP)
VPATH += kern/ppc32/bsp/$(BSP_NAME) kern/ppc32/bsp
ifeq ("$(filter LIBUART, $(SUBSYSTEMS))","LIBUART")
LIBUART := uart/libuart.a
endif
MODULES_FILES = $(MODULES_FILE) $(MODULES_FILE_BSP)

View File

@@ -0,0 +1,257 @@
# -*- makefile -*-
###############################################################################
include $(srcdir)/Modules.generic
SUBSYSTEMS := ABI KERNEL LIBUART LIBK DRIVERS MINILIBC CXXLIB CRT0 \
VERSION JABI TCBOFFSET
PREPROCESS_PARTS += $(CONFIG_XARCH) $(CONFIG_ABI) 32bit \
abs_syscalls big_endian jdb_thread_names \
obj_space_phys
PREPROCESS_PARTS-$(CONFIG_SERIAL) += serial
PREPROCESS_PARTS-$(CONFIG_JDB) += debug jdb log
PREPROCESS_PARTS-$(CONFIG_SCHED_FIXED_PRIO) += sched_fixed_prio
PREPROCESS_PARTS-$(CONFIG_SCHED_WFQ) += sched_wfq
PREPROCESS_PARTS-$(CONFIG_SCHED_FP_WFQ) += sched_fp_wfq
PREPROCESS_PARTS += $(PREPROCESS_PARTS-y)
#
# TYPES subsystem
#
PRIVATE_INCDIR += types/$(CONFIG_XARCH) types
#
# LIBUART subsystem
#
ifeq ("$(filter LIBUART, $(SUBSYSTEMS))","LIBUART")
LIBUART := uart/libuart.a
PREPROCESS_PARTS += libuart
endif
OBJECTS_LIBUART += uart_leon3.o
VPATH_LIBUART := $(srcdir)/lib/uart
PRIVATE_INCDIR += lib/uart drivers/$(CONFIG_XARCH)/include
#
# DRIVERS Subsystem
#
DRIVERS := libdrivers.a libgluedriverslibc.a
VPATH += drivers/$(CONFIG_XARCH) drivers
PRIVATE_INCDIR += drivers/$(CONFIG_XARCH) drivers
INTERFACES_DRIVERS := mux_console console mem reset uart filter_console \
processor delayloop io
io_IMPL := io io-sparc
mem_IMPL := mem mem-sparc
reset_IMPL := reset-sparc
processor_IMPL := processor processor-sparc
uart_IMPL := uart uart-asi
CXXSRC_DRIVERS := glue_libc.cc
NOOPT += $(patsubst %.o, %, $(OBJ_DRIVERS))
#
# MINILIBC Subsystem
#
MINILIBC := libc.a
VPATH += lib/minilibc/$(CONFIG_XARCH) lib/minilibc
PRIVATE_INCDIR += lib/minilibc/$(CONFIG_XARCH)/include lib/minilibc/include
CSRC_MINILIBC := atexit.c memccpy.c memcmp.c memmove.c memset.c memcpy.c \
memchr.c panic.c strchr.c strcmp.c strcpy.c strlen.c \
strncmp.c strncpy.c strstr.c __assert_fail.c printf.c \
__v_printf.c vprintf.c strtol.c strtoul.c __lltostr.c \
__ltostr.c putchar.c puts.c getchar.c gets.c \
sprintf.c snprintf.c vsnprintf.c vsprintf.c \
longjmp.c isalnum.c isalpha.c isascii.c isblank.c \
iscntrl.c isdigit.c isgraph.c islower.c isprint.c \
ispunct.c isspace.c isupper.c isxdigit.c strspn.c \
strcspn.c tolower.c
ASSRC_MINILIBC := setjmp.S
NOOPT += $(patsubst %.o, %, $(OBJ_MINILIBC))
#
# JABI Subsystem
#
JABI := libjabi.a
VPATH += jabi/$(CONFIG_XARCH) jabi
INTERFACES_JABI := jdb_ktrace
#
# ABI Subsystem
#
ABI := libabi.a
VPATH += abi/$(CONFIG_XARCH) abi
INTERFACES_ABI := kip l4_types l4_fpage l4_msg_item l4_buf_desc l4_error
kip_IMPL := kip kip-debug kip-sparc
l4_types_IMPL := l4_types l4_types-debug
#
# KERNEL subsystem
#
KERNEL := fiasco
KERNEL_EXTRA := Symbols
VPATH += kern/$(CONFIG_XARCH) kern
VPATH += jdb/$(CONFIG_XARCH) jdb
PRIVATE_INCDIR += kern/$(CONFIG_XARCH) kern kern/ia32
INTERFACES_KERNEL += boot_uart_init bootstrap decrementer psr sparc_types \
util utcb_support irq_chip_generic
INTERFACES_KERNEL-$(CONFIG_SERIAL) += uart_console
INTERFACES_KERNEL += $(INTERFACES_KERNEL-y)
boot_info_IMPL := boot_info boot_info-sparc
clock_IMPL := clock
config_IMPL := config config-sparc
context_IMPL := context context-sparc context-vcpu
continuation_IMPL := continuation-sparc
cpu_IMPL := cpu cpu-sparc
cpu_lock_IMPL := cpu_lock cpu_lock-generic
dirq_IMPL := dirq-sparc
entry_frame_IMPL := entry_frame entry_frame-sparc
kdb_ke_IMPL := kdb_ke kdb_ke-sparc
kernel_task_IMPL := kernel_task kernel_task-sparc
kernel_thread_IMPL := kernel_thread kernel_thread-std kernel_thread-sparc
kernel_uart_IMPL := kernel_uart kernel_uart-sparc
kmem_alloc_IMPL := kmem_alloc kmem_alloc-sparc
map_util_IMPL := map_util map_util-mem map_util-objs
mapping_IMPL := mapping-sparc mapping
mem_layout_IMPL := mem_layout mem_layout-sparc
mem_unit_IMPL := mem_unit-sparc
mem_space_IMPL := mem_space mem_space-user mem_space-sparc
obj_space_IMPL := obj_space obj_space-phys
paging_IMPL := paging-sparc paging
pic_IMPL := pic
sched_context_IMPL := sched_context-wfq sched_context-fixed_prio \
sched_context-fp_wfq sched_context
space_IMPL := space space-sparc
startup_IMPL := startup startup-sparc
sys_call_page_IMPL := sys_call_page sys_call_page-sparc
task_IMPL := task task-sparc
timer_IMPL := timer timer-decr-sparc
thread_IMPL := thread thread-log thread-pagefault \
thread-sparc thread-ipc thread-jdb \
thread-vcpu
utcb_init_IMPL := utcb_init utcb_init-sparc
utcb_support_IMPL := utcb_support utcb_support-sparc
vmem_alloc_IMPL := vmem_alloc vmem_alloc-sparc
tb_entry_IMPL := tb_entry tb_entry-sparc
warn_IMPL := warn warn-sparc
ifeq ("$(CONFIG_JDB)","y")
JDB := jdb_compound.o
SUBSYSTEMS += JDB
INTERFACES_JDB := jdb jdb_attach_irq jdb_core jdb_scheduler jdb_entry_frame \
jdb_exit_module jdb_factory jdb_handler_queue \
jdb_input jdb_ipc_gate jdb_kobject jdb_kobject_names\
jdb_lines jdb_list jdb_module jdb_prompt_module \
jdb_obj_space jdb_prompt_ext jdb_screen jdb_space \
jdb_symbol jdb_table jdb_tcb jdb_thread \
jdb_thread_list jdb_util kern_cnt \
push_console jdb_regex jdb_disasm jdb_bp \
jdb_tbuf_output \
jdb_tbuf_show tb_entry_output
INTERFACES_KERNEL += jdb_tbuf jdb_tbuf_init tb_entry jdb_trace
jdb_IMPL := jdb jdb-ansi jdb-sparc jdb-thread
jdb_tcb_IMPL := jdb_tcb jdb_tcb-sparc
jdb_entry_frame_IMPL := jdb_entry_frame-sparc
jdb_bp := jdb_bp
thread_IMPL += thread-debug
INTERFACES_JDB += $(INTERFACES_JDB-y)
endif
CXXSRC_KERNEL := kernel_panic.cc libc_backend_lock.cc
ASSRC_KERNEL := exceptions.S
NOOPT += $(filter jdb%,\
$(foreach in,$(INTERFACES_KERNEL), \
$(if $($(in)_IMPL),$($(in)_IMPL),$(in))))
NOOPT += tb_entry #tb_entry_output
#
# CRT0 subsystem
#
CRT0 := crt0.o
ASSRC_CRT0 := crt0.S
#
# CXXLIB Subsystem
#
CXXLIB := libcxx.a
VPATH += lib/cxxlib
INTERFACES_CXXLIB := paranoia s_cruft
#
# LIBK subsystem
#
LIBK := libk.a
VPATH += lib/libk/$(CONFIG_XARCH) lib/libk
PRIVATE_INCDIR += lib/libk/$(CONFIG_XARCH) lib/libk
INTERFACES_LIBK := auto_ptr atomic lock_guard std_macros
CXXSRC_LIBK += construction.cc
atomic_IMPL := atomic atomic-sparc
#
# LIBDISASM subsystem (only for Jdb)
#
ifeq ("$(CONFIG_JDB_DISASM)","y")
# $(srcdir)/lib/disasm may be removed
ifeq ($(wildcard $(srcdir)/lib/disasm),)
$(error $(srcdir)/lib/disasm is missing, disable CONFIG_JDB_DISASM)
endif
SUBSYSTEMS += LIBDISASM
KERNEL_EXTRA_LIBS += $(LIBDISASM)
PREPROCESS_PARTS += jdb_disasm
LIBDISASM := libdisasm.a
VPATH += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm
CXXSRC_LIBDISASM := disasm.cc
CSRC_LIBDISASM := sparc-dis.c sparc-opc.c dis-init.c dis-buf.c \
safe-ctype.c libbfd.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBDISASM))
endif
#
# VERSION subsystem
#
VERSION := version.h
TCBOFFSET := tcboffset.h
CXXSRC_TCBOFFSET := tcboffset.cc dump_tcboffsets.cc
#
# BSP subsystem
#
BSP_NAME := $(patsubst "%",%,$(CONFIG_BSP_NAME))
MODULES_FILE_BSP := $(srcdir)/kern/sparc/bsp/$(BSP_NAME)/Modules
ifeq ($(wildcard $(MODULES_FILE_BSP)),)
$(error No BSP name defined or no BSP Modules file available)
endif
include $(MODULES_FILE_BSP)
VPATH += kern/sparc/bsp/$(BSP_NAME) kern/sparc/bsp
ifeq ("$(filter LIBUART, $(SUBSYSTEMS))","LIBUART")
LIBUART := uart/libuart.a
endif
MODULES_FILES = $(MODULES_FILE) $(MODULES_FILE_BSP)

View File

@@ -0,0 +1,362 @@
# -*- makefile -*-
SUBSYSTEMS = JABI ABI DRIVERS KERNEL LIBK CXXLIB JDB \
TCBOFFSET SYMBOLS VERSION GBLCFG MINILIBC
ifeq ("$(CONFIG_GSTABS)","y")
SUBSYSTEMS += LINES
endif
PREPROCESS_PARTS += arch $(CONFIG_ABI) 32bit $(CONFIG_XARCH) \
fpu jdb_thread_names iofp \
obj_space_phys abs_syscalls auto_map_kip \
kernel_can_exit
PREPROCESS_PARTS-$(CONFIG_MP) += mp
PREPROCESS_PARTS-$(CONFIG_LIST_ALLOC_SANITY) += list_alloc_debug
PREPROCESS_PARTS-$(CONFIG_JDB) += debug log
PREPROCESS_PARTS-$(CONFIG_PERF_CNT) += perf_cnt
PREPROCESS_PARTS-$(CONFIG_CONTEXT_4K) += context_4k
PREPROCESS_PARTS-$(CONFIG_SCHED_FIXED_PRIO) += sched_fixed_prio
PREPROCESS_PARTS-$(CONFIG_SCHED_WFQ) += sched_wfq
PREPROCESS_PARTS-$(CONFIG_SCHED_FP_WFQ) += sched_fp_wfq
PREPROCESS_PARTS += $(PREPROCESS_PARTS-y)
#
# TYPES subsystem
#
PRIVATE_INCDIR += types/$(CONFIG_XARCH) types
#
# ABI Subsystem
#
ABI := libabi.a
VPATH += abi/ia32 abi
INTERFACES_ABI := l4_fpage l4_msg_item l4_buf_desc kip l4_types \
l4_error
kip_IMPL := kip kip-ia32 kip-debug kip-ia32-debug
l4_types_IMPL := l4_types l4_types-debug
#
# JABI Subsystem
#
JABI := libjabi.a
VPATH += jabi/$(CONFIG_XARCH) jabi
INTERFACES_JABI := jdb_ktrace
#
# DRIVERS subsystem
#
DRIVERS := libdrivers.a
VPATH += drivers/ux drivers/ia32 drivers
PRIVATE_INCDIR += drivers/ux drivers/ia32 drivers
INTERFACES_DRIVERS := mux_console console filter_console processor \
delayloop mem
processor_IMPL := processor processor-ux
mem_IMPL := mem mem-ia32
#
# KERNEL subsystem
#
KERNEL := fiasco.image
KERNEL_EXTRA := irq0
VPATH += kern/$(CONFIG_XARCH) kern/ia32/32 kern/ia32 kern
VPATH += jdb/ia32 jdb/ia32/32 jdb/ux jdb
PRIVATE_INCDIR += kern/$(CONFIG_XARCH) kern/ia32/32 kern/ia32 kern
KERNEL_EXTRA-$(CONFIG_UX_CON) += ux_con
KERNEL_EXTRA-$(CONFIG_UX_NET) += ux_net
KERNEL_EXTRA += $(KERNEL_EXTRA-y)
# KERNEL modules.
# Important: The following list must be roughly sorted according to
# link dependencies. The Unit test for a module M links against all
# modules that precede M in this list, minus sibling modules (those
# modules that _directly_ precede M and that M does not include).
INTERFACES_KERNEL := mem_region simpleio kernel_console panic warn \
bitmap buddy_alloc koptions context_base \
mem_layout per_cpu_data globals loader vhw \
kip_init ipi queue_item queue cpu_mask rcupdate \
boot_info config jdb_symbol jdb_util \
tb_entry perf_cnt jdb_tbuf x86desc \
emulation pic usermode cpu trampoline cpu_lock \
spin_lock boot_alloc \
entry_frame continuation \
kmem mem_unit \
ram_quota kmem_alloc ptab_base per_cpu_data_alloc \
ref_ptr ref_obj \
slab_cache kmem_slab dbg_page_info \
vmem_alloc paging fpu_state fpu \
ready_queue_wfq ready_queue_fp \
sched_context switch_lock timer timeout \
obj_space kobject_dbg kobject kobject_iface \
l4_buf_iter lock \
mem_space space vcpu context \
helping_lock \
mp_lock ipc_gate irq_controller \
mapping mapping_tree mappable \
mapdb kobject_mapdb map_util \
hostproc task sigma0_task kernel_task prio_list \
thread_lock timeslice_timeout \
ipc_timeout thread_state \
sender receiver ipc_sender thread thread_object \
kobject_helper timer_tick \
syscalls \
kernel_thread dirq irq_chip irq_mgr \
irq_chip_ia32 irq_chip_pic \
banner fpu_alloc irq icu_helper main \
startup libc_support \
jdb_dbinfo jdb fb net utcb_init \
jdb_core jdb_module jdb_table \
jdb_thread_list jdb_input jdb_dump jdb_thread \
jdb_lines jdb_tcb jdb_prompt_module jdb_bt \
jdb_mapdb jdb_ptab jdb_kern_info jdb_counters \
glibc_getchar jdb_trace jdb_trace_set \
tb_entry_output jdb_tbuf_init kern_cnt \
jdb_tbuf_output jdb_tbuf_show \
jdb_misc checksum watchdog terminate \
jdb_screen push_console jdb_bp \
jdb_attach_irq sys_call_page \
jdb_timeout gdt factory \
idt tss trap_state jdb_prompt_ext \
jdb_handler_queue jdb_exit_module \
jdb_halt_thread jdb_tetris \
jdb_kern_info_kip \
jdb_kern_info_kmem_alloc jdb_kern_info_config \
jdb_space jdb_trap_state \
vkey jdb_utcb vlog \
jdb_entry_frame kdb_ke jdb_ipi app_cpu_thread \
jdb_rcupdate jdb_kobject jdb_kobject_names \
jdb_list jdb_ipc_gate jdb_obj_space \
jdb_log jdb_factory scheduler \
jdb_scheduler clock jdb_sender_list \
jdb_disasm jdb_regex
boot_info_IMPL := boot_info boot_info-ia32 boot_info-ux
clock_IMPL := clock clock-ia32
config_IMPL := config config-ia32-32 config-ux
context_IMPL := context context-ia32 context-ia32-32 context-ux \
context-vcpu
continuation_IMPL := continuation-ia32-32-ux
cpu_IMPL := cpu cpu-ia32 cpu-ux cpu-32
cpu_lock_IMPL := cpu_lock cpu_lock-generic
dirq_IMPL := dirq-ia32-ux
dirq_pic_pin_IMPL := dirq_pic_pin dirq_pic_pin-ia32-ux
entry_frame_IMPL := entry_frame entry_frame-ia32-ux \
entry_frame-abs-timeout-hack
fpu_IMPL := fpu fpu-ia32-ux fpu-ux
irq_IMPL := irq irq-ux
ipi_IMPL := ipi ipi-ux
jdb_IMPL := jdb jdb-ux jdb-ansi jdb-ia32-ux jdb-thread \
jdb-int3 jdb-int3-ia32-ux
jdb_tcb_IMPL := jdb_tcb jdb_tcb-ia32-ux
jdb_bp_IMPL := jdb_bp-ia32-ux jdb_bp-ux
jdb_bt_IMPL := jdb_bt-ia32-ux
jdb_entry_frame_IMPL := jdb_entry_frame-ia32
jdb_kern_info_IMPL := jdb_kern_info jdb_kern_info-ux \
jdb_kern_info-ia32-ux jdb_kern_info-ia32-amd64
jdb_misc_IMPL := jdb_misc-ia32-amd64
jdb_ptab_IMPL := jdb_ptab jdb_ptab-ia32-ux-arm
jdb_screen_IMPL := jdb_screen jdb_screen-ia32
jdb_trace_set_IMPL := jdb_trace_set jdb_trace_set-ia32-ux
kdb_ke_IMPL := kdb_ke kdb_ke-ia32
kernel_thread_IMPL := kernel_thread kernel_thread-std kernel_thread-ux
kip_init_IMPL := kip_init-ia32 kip_init-ux
kmem_IMPL := kmem-ia32 kmem-ux
kmem_alloc_IMPL := kmem_alloc kmem_alloc-ia32
main_IMPL := main-ia32-32 main-ux
mapping_IMPL := mapping-ia32-32 mapping
map_util_IMPL := map_util map_util-mem map_util-objs
mem_layout_IMPL := mem_layout mem_layout-ia32 mem_layout-ux
mem_space_IMPL := mem_space mem_space-user mem_space-ia32 \
mem_space-ux
mem_unit_IMPL := mem_unit-ux
obj_space_IMPL := obj_space obj_space-phys
paging_IMPL := paging-ia32-32 paging-ia32 paging
perf_cnt_IMPL := perf_cnt perf_cnt-ia32
pic_IMPL := pic pic-ux
pmem_alloc_IMPL := pmem_alloc pmem_alloc-ia32-ux
sched_context_IMPL := sched_context-wfq sched_context-fixed_prio \
sched_context-fp_wfq sched_context
space_IMPL := space space-ux
syscalls_IMPL := syscalls syscalls-log
sys_call_page_IMPL := sys_call_page sys_call_page-abs-ux
task_IMPL := task task-ux
tb_entry_IMPL := tb_entry tb_entry-ia32-32
terminate_IMPL := terminate-ux
thread_IMPL := thread thread-ia32 thread-ia32-32 thread-ux \
thread-ipc thread-pagefault thread-log \
thread-debug thread-io thread-vcpu
timer_IMPL := timer timer-ia32-amd64-ux timer-ux
timer_tick_IMPL := timer_tick timer_tick-single-vector timer_tick-ia32
utcb_init_IMPL := utcb_init utcb_init-ux
vmem_alloc_IMPL := vmem_alloc vmem_alloc-ia32 vmem_alloc-ux
spin_lock_IMPL := spin_lock spin_lock-ia32
CXXSRC_KERNEL := libc_backend_nolock.cc glue_libc_ux.cc
ASSRC_KERNEL := entry-ux.S entry.S sighandler.S \
sys_call_page-asm.S
ifeq ($(CONFIG_MP),y)
ASSRC_KERNEL += tramp-mp.S entry-mp.S
endif
NOOPT += $(filter jdb%,\
$(foreach in,$(INTERFACES_KERNEL), \
$(if $($(in)_IMPL),$($(in)_IMPL),$(in))))
NOOPT += tb_entry tb_entry_output
#
# TCBOFFSET subsystem
#
TCBOFFSET := tcboffset.h
CXXSRC_TCBOFFSET := tcboffset.cc dump_tcboffsets.cc
#
# SYMBOLS subsystem
#
SYMBOLS := Symbols
#
# LINES subsystem
#
LINES := Lines
PROG_LINES := genlines
#
# VERSION subsystem
#
VERSION := version.h
#
# GBLCFG subsystem
#
GBLCFG := gblcfg.o
OBJ_KERNEL += gblcfg.o
#
# CXXLIB Subsystem
#
CXXLIB := libcxx.a
VPATH += lib/cxxlib
INTERFACES_CXXLIB := s_cruft paranoia
#
# LIBK subsystem
#
LIBK := libk.a
VPATH += lib/libk/$(CONFIG_XARCH) lib/libk
PRIVATE_INCDIR += lib/libk/$(CONFIG_XARCH) lib/libk
INTERFACES_LIBK := atomic lock_guard auto_ptr std_macros
CXXSRC_LIBK += construction.cc
ifneq ($(CONFIG_JDB_GZIP),)
ifneq ($(wildcard $(srcdir)/lib/gzip),)
SUBSYSTEMS += LIBGZIP
KERNEL_EXTRA_LIBS += $(LIBGZIP)
INTERFACES_KERNEL += jdb_gzip
LIBGZIP := libgzip.a
VPATH += lib/gzip
PRIVATE_INCDIR += lib/gzip
CSRC_LIBGZIP := adler32.c crc32.c gzip.c trees.c deflate.c zutil.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBGZIP))
endif
endif
#
# LIBDISASM subsystem (only for Jdb)
#
ifeq ("$(CONFIG_JDB_DISASM)","y")
# $(srcdir)/lib/disasm may be removed
ifeq ($(wildcard $(srcdir)/lib/disasm),)
$(error $(srcdir)/lib/disasm is missing, disable CONFIG_JDB_DISASM)
endif
SUBSYSTEMS += LIBDISASM
KERNEL_EXTRA_LIBS += $(LIBDISASM)
PREPROCESS_PARTS += jdb_disasm
LIBDISASM := libdisasm.a
VPATH += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm lib/disasm/elf lib/disasm/include \
lib/disasm/include/opcode lib/disasm/opcodes \
lib/disasm/libiberty lib/disasm/bfd
PRIVATE_INCDIR += lib/disasm
CXXSRC_LIBDISASM := disasm.cc
CSRC_LIBDISASM := dis-init.c i386-dis.c dis-buf.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBDISASM))
endif
#
# LIBPERFCTR subsystem (only for Jdb)
#
LIBPERFCTR := libperfctr.a
VPATH += lib/perfctr
PRIVATE_INCDIR += lib/perfctr
CSRC_LIBPERFCTR := event_set_p5.c event_set_p6.c event_set_amd.c \
event_set_p4.c event_set_x86.c perfctr.c \
event_set_centaur.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBPERFCTR))
#
# LIBREGEX subsystem (only for Jdb)
#
LIBREGEX := libregex.a
VPATH += lib/regex
PRIVATE_INCDIR += lib/regex
CSRC_LIBREGEX := alloc.c rx.c
NOOPT += $(patsubst %.o, %, $(OBJ_LIBREGEX))
ifneq ($(wildcard $(srcdir)/lib/perfctr),)
SUBSYSTEMS += LIBPERFCTR
KERNEL_EXTRA_LIBS += $(LIBPERFCTR)
KERNEL_UNRES_SYMS += -u perfctr_set_cputype
endif
ifneq ($(wildcard $(srcdir)/lib/regex),)
SUBSYSTEMS += LIBREGEX
KERNEL_EXTRA_LIBS += $(LIBREGEX)
PREPROCESS_PARTS += jdb_regex
endif
#
# UNITTEST subsystem
#
# disabled until unittests fixed
SUBSYSTEMS += UNITTEST
VPATH += test/unit
INTERFACES_UNITTEST += mapdb_t map_util_t
# Compile all unit tests without -DNDEBUG.
NONDEBUG += $(patsubst %.o, %, $(OBJ_UNITTEST))
MODULES_FILES = $(MODULES_FILE) $(MODULES_FILE_BSP)
#
# MINILIBC Subsystem
#
MINILIBC := libc.a
VPATH += lib/minilibc/ia32 lib/minilibc
CSRC_MINILIBC := printf.c __v_printf.c \
vprintf.c lltostr.c __ltostr.c \
putchar.c puts.c gets.c sprintf.c \
snprintf.c vsnprintf.c vsprintf.c fprintf.c \
memccpy.c memchr.c memcmp.c memcpy.c memmove.c memset.c \
strcpy.c strlen.c strstr.c \
strcmp.c strcspn.c strncmp.c strspn.c
# do not profile all of MINILIBC, because it is used in the BOOT subsystem
NOOPT += $(patsubst %.o, %, $(OBJ_MINILIBC))

168
kernel/fiasco/src/README Normal file
View File

@@ -0,0 +1,168 @@
Fiasco's build system
Michael Hohmuth
Motivation
##########
My main goal when I designed Fiasco's build system was to allow for
multiple configurations of the kernel, based on different
implementations of the same interface, to coexist in multiple object
directories.
Configuration
#############
Fiasco's build system consists of a number of configuration files, and
it also makes use of the L4 source tree's global Make configuration
file, l4/Makeconf. All configuration files are written in Makefile
language.
:l4/Makeconf:
Global Make rules and search paths
:l4/kernel/fiasco/src/Makefile:
``Fiasco's build system'' rules
:l4/kernel/fiasco/src/Modules.in:
Standard configuration for Fiasco
:<object directory> /Modules:
Current configuration for Fiasco
:l4/kernel/fiasco/src/Makerules.*:
Make rules for each subsystem defined in Modules
:l4/kernel/fiasco/src/Makerules.local':
(Optional) User-specific configuration files
:l4/Makeconf.local':
(Optional) User-specific configuration files
(By default, the object directory is the main source directory,
l4/kernel/fiasco/src/. See the next section on how to use other
object directories with custom configurations.)
Users configure the build system by creating a Modules file. If no
Modules file exists, the standard configuration Modules.in is copied
to Modules. The build system warns the user if (after a "cvs update")
Modules.in is newer than Modules.
The Modules file defines a number of subsystems that should be built.
For each subsystem, there must be a Makerules.<subsystem> file that
defines rules for building the subsystem's targets.
In the remainder of this section, I describe by example the language
used in Modules file and the contents of the Makerules.* files.
!SUBSYSTEMS = FOO BAR
! # Defines two subsystems, FOO and BAR. This means that there
! # exist two files, Makerules.FOO and Makerules.BAR, that
! # contain rules on how to build the targets of these
! # subsystems. These targets are defined later.
!
!### Definitions for subsystem FOO follow
!
!FOO = foo
! # Defines the main target of subsystem FOO: a file named
! # "foo".
!
!FOO_EXTRA = foo.man
! # (Optional) Defines more targets that should be built for
! # subsystem FOO.
!
!INTERFACES_FOO = foo1 foo2 foo3
! # (Optional) C++ modules for subsystem FOO (written in
! # `preprocess' format; see
! # <URL:http://os.inf.tu-dresden.de/~hohmuth/prj/preprocess/>)
! # Each module normally consists of one implementation file
! # such as foo1.cpp -- unless IMPL definitions such as the
! # following ones are given:
!
!foo2_IMPL = foo2 foo2-more
! # (Optional) C++ module foo2 is implemented in two files
! # foo2.cpp and foo2-more.cpp (instead of just foo2.cpp). The
! # public header file generated from these implementation files
! # will be called foo2.h.
!
!foo3_IMPL = foo3-debug
! # (Optional) C++ module foo3 is implemented in foo3-debug.cpp,
! # not foo3.cpp. The public header file generated from this
! # implementation file will be called foo3.h.
!
!CXXSRC_FOO = frob1.cc frob2.cc
! # (Optional) Additional C++ sources for subsystem FOO (not in
! # `preprocess' format)
!
!CSRC_FOO = frob3.c frob4.c
! # (Optional) Additional C sources for subsystem FOO
!
!ASSRC_FOO = frob5.S
! # (Optional) Additional assembly-language sources for
! # subsystem FOO
!
!OBJ_FOO = frob6.o
! # (Optional) Additional objects for subsystem FOO. These
! # objects can be precompiled or generated using custom rules
! # in Makerules.FOO.
!
!NOPROFILE += frob2
! # (Optional) Basenames of objects that should not be compiled
! # with profiling options in profiling builds.
!
!NOOPT += frob3
! # (Optional) Basenames of objects that should not be compiled
! # with optimization options.
!
!PRIVATE_INCDIR += incdir
! # (Optional) Add incdir to the include path for all source
! # files. (This feature is implemented by l4/Makeconf.)
!
!VPATH += foodir
! # (Optional) Add foodir to Make's source-file search
! # path. (This feature is implemented internally by Make.)
!
!### Definitions for subsystem BAR follow
!### (similar to FOO's definitions)
The Makerules.FOO file usually contains just rules for linking the
subsystem's targets. Additionally, it must contain a rule
"clean-FOO:" that cleans the object directory from files created by
this configuration file.
It can access the following Make variables:
:'FOO', 'FOO_EXTRA':
names of targets
:'OBJ_FOO':
expanded to contain _all_ objects that will be created for subsystem FOO
:'BAR':
targets of other subsystems
Building in separate object directories
#######################################
It is possible to configure multiple directories, each with its own
Modules file, as separate object directories. (This usage is
supported only if the main source directory [the one containing
Modules.in] is not also used as an object directory.)
To use a directory as an object directory, create in it a Makefile
like this:
!srcdir = ..
!
!all:
!
!%:
! $(MAKE) -I $(srcdir) -f $(srcdir)/Makefile \
! srcdir=$(srcdir) $@
Change the "srcdir" definition to point to the main source directory.
You can then create custom Modules files (and custom source files and
Makerules.* files) in each object directory.

View File

@@ -0,0 +1,785 @@
Fiasco style guide
Michael Hohmuth
; To generate a printable version of this document, please type
; cd ../doc/style; make
Introduction
############
Motivation and intended audience
================================
This document is meant as a quick reference to a number of guidelines
meant for existing and especially new Fiasco kernel developers.
How to follow these rules: Metarules
====================================
This document does not differentiate between strict rules and ``soft''
guidelines. Also, when browsing the source code, you will notice a
large number of deviations from these rules (because most rules are
younger than the current kernel code). In this sense, all rules are
``soft.''
However, as the master guideline, when writing new code, please ensure
that the number of rule violations does not grow. (In the future, we
might even enforce this property automatically when someone is
checking in code.)
Programming language, dialect, and subset
#########################################
Fiasco has been written in C++. However, it uses C++ in a special
dialect supported by the Preprocess tool [Hohmuth: Preprocess]. In
effect, programmers do not need to write C++ header files, and do not
need to declare (member) functions -- Preprocess automates these
tasks.
We use some features of Preprocess for configuration
management---please refer to Section [Configuration-specific source code].
Preprocess lacks support for the following C++ features, which
therefore cannot be used in Fiasco source code (but can be used in
third-party source code used, i.e., can be included, by Fiasco):
* Name spaces --- use static class interfaces or global or static free
functions instead (Section [Singletons])
* Nested classes --- use forward-declared ``private classes'' instead
* '#ifdef' and
'#if' on file top level, except for
'#if 0' --- use
Preprocess' configuration features instead (Section
[Configuration-specific source code])
Some features of C++ are explicitly disallowed because Fiasco contains
no run-time support for them:
* Exceptions
* Run-time type identification and dynamic_cast
These features are always disabled on the compiler command line.
On the other hand, templates are allowed. However, please keep in
mind that Fiasco's source code needs to be interpreted not only by the
latest version of GCC, but also by at least the two preceding stable
versions of GCC, _and_ ---more significantly---by the VFiasco project's
semantics compiler, which is a custom compiler _we_ (in a broader
sense of we) have to maintain. Therefore, using advanced tricks such
as expression templates or partial specialization is strongly
discouraged.
Source-code organization and directory structure
################################################
Subsystems
==========
Fiasco consists of a number of subsystems; among them:
:KERNEL: The kernel proper. This is the part that implements the L4
specification.
:ABI: ABI-specific definitions, mostly type definitions and accessor
functions.
:JDB: The built-in kernel debugger.
:BOOT: The bootstrapper. This part sets up virtual memory, copies the
kernel to its standard virtual-address-space location (0xf0001000),
and runs the kernel.
Subsystems are defined in the Modules file, which is the main
configuration file for Fiasco's build system. Please refer to
the build-system documentation [README] for more information on this
build system.
Directory structure
===================
Subsystems usually reside in their own directory under src (the
exception being those subsystems which do not contain any source code,
but which exist only for maintenance purposes).
Inside each (source-code) subsystem directory such as kern, the
directory layout is as follows:
:kern/: Source files shared for all Fiasco-supported
architectures
:kern/shared/: Source files shared by more than one, but not
all architectures.
:kern/ia32, kern/ia64, kern/ux, and so on: Source files that are
specific for only one architecture.
Currently, hardware architectures is the only configuration dimension
that motivates moving a source file into a subdirectory. In other
words, source files pertaining to a particular configuration option
(other than hardware architecture), but not another, are located in
one of the mentioned directories.
Source-file naming
==================
Usually, source files belong to exactly one module, consisting of one
main C++ class plus, optionally, public utility functions, small
interface classes for exchanging data with the main class, and private
auxiliary classes and functions. A module can be comprised of
multiple source files. These source files all start with the name of
the module's main class, in all lower case (e.g., for class
Thread_state, file names start with the string "thread_state"). When
multiple source files implement one module, each file name (except for
the main file's) add a submodule-specific suffix, separated with a
dash (-). For example:
* kern/thread.cpp
* kern/thread-ipc.cpp
Fiasco's build system mandates that all source files (of all
subsystems) have different names, even if they reside in different
directories. To make file names different, our naming convention is
to add architecture-configuration strings to the file names, separated
by dashes (-). For example:
* kern/thread.cpp
* kern/shared/thread-ia32-ux.cpp
* kern/ia64/thread-ia64.cpp
Occasionally, it is useful to separate configuration-specific code
into a source file of its own (see Section
[Configuration-specific source code]). In this case, the file name
contains the configuration string as a suffix, separated by dashes
(-). For example:
* kern/thread-v4.cpp
* kern/thread-v2x0.cpp
* kern/ia32/thread-ia32-smas.cpp
Header files and the C++ preprocessor
=====================================
As Preprocess assumes the task of writing header files, programmers
should not add new header files. The exception to this rule is that
header files are required when defining constants that are needed by
both assembly code and C++ code.
When using header files, these files must be protected from multiple
inclusions using include-file guards, as in the following example for
the file config_gdt.h:
! #ifndef CONFIG_GDT_H
! #define CONFIG_GDT_H
! // File contents
! #endif
Configuration management
########################
The configuration tool
======================
The interactive configuration tool is started using "make menuconfig".
The tool creates two files, intended for inclusion in C++ code and in
makefiles:
:globalconfig.h: This file defines a preprocessor symbol for each
_enabled_ configuration option.
:globalconfig.out: This file defines a Make variable for set _each_
configuration option. Variables for enables options are set to "y",
those for disabled options are set to "n".
Adding new configuration options
--------------------------------
Help texts for configuration options in the rules file (rules.cml) are
sorted by order in which the options appear in the menu defined at the
bottom of the file. New configuration options must add such a help text
describing what the config option does. After a new config option
has been added, define under which conditions the config option should
be suppressed, if any. It is generally a good idea to suppress config
options for architectures and configurations where the option is
meaningless. Options which can be suppressed for certain configurations
usually require consistency rules to ensure they are not left in an
undefined state from a previous selection.
An example suppression rule is:
! when UX suppress SERIAL
The corresponding consistency rule is:
! require UX implies (SERIAL == n)
This ensures that 'SERIAL' is set to "n" when someone had previously chosen
'IA32' and 'SERIAL' set to "y" and then changes the architecture to 'UX'.
Do not forget to update the configuration templates in the directory
src/templates after modifying configuration options.
Class Config
============
This class defines boot-time and constant configuration variables for
Fiasco.
The constant variables can be derived from options the configuration
tool has written to globalconfig.h. As a special exception, '#ifdef'
is allowed here.
Boot-time configuration variables can be derived from the kernel's
command line (class Cmdline).
Configuration-specific source code
==================================
Single or multiple source files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Source code that is specific to one or a single combination of
configuration options can reside in a separate file or in the same
file as code for other configuration options. The decision of which
works better is in the developer's discretion. Developers should try
to combine logically cohesive code fragments in one source file, even
if the fragments are mutually exclusive.
Conditional compilation
~~~~~~~~~~~~~~~~~~~~~~~
Using preprocessor constants and '#ifdef' for conditional compilation
is only allowed for source code passed to the assembler (assembly
files and header files meant to be included in assembly code). In C++
source code, this style is discouraged, and Preprocess does not even
support it (for top-level conditional compilation).
Configuration-specific C++ code blocks are labeled using Preprocess'
configuration-tag feature with 'IMPLEMENTATION' and 'INTERFACE'
directives.
This feature is available only on file top level. Conditional
compilation inside function or class blocks is not allowed. Instead,
programmers have the following options:
:For class definitions:
Use Preprocess' 'EXTENSION' feature to extend class data with
configuration-specific contents.
:For function definitions:
# Create a Boolean constant in class Config that depends on the
configuration option ('#ifdef' is allowed there; see Section
[Class Config]), and use the normal C++ 'if' statement to
conditionalize the code. We rely on the C++ compiler's optimizer
to remove dead code.
# Factor out configuration-specific functions with a common
interface.
Compile-time polymorphism
=========================
Many configurable aspects of Fiasco are implemented as a set of
(member) functions that implement a given interface in a specific way.
However, unlike typical C++ programs, Fiasco usually does not define
these interfaces as abstract base classes and then derives
configuration-specific subclass implementations from them. We have
deemed the overhead of virtual-function calls as too high in many
cases.
Instead, in Fiasco these interfaces are not declared as virtual
functions, but as nonvirtual functions. These functions are then
defined in configuration-specific 'IMPLEMENTATION' sections, which can
be combined in one file or spread across multiple files (see Section
[Configuration-specific source code]). Preprocess assists in this
kind of compile-time polymorphism by allowing configuration-specific
inline functions and private member functions.
These interfaces do not need to be split out into separate classes.
It is often useful to have a part of a class interface that is
implemented in a configuration-specific way.
Usually, Preprocess assumes the task of copying (member-) function
declarations into a module's public header file, and this is our
preferred usage. However, for interfaces that are implemented in a
configuration-specific source-code block, we make an exception: The
``public'' interface (i.e., the interface used by generic client code,
which not necessarily needs consist of only public member functions)
can be declared and documented in the 'INTERFACE' section of the
corresponding module. To prevent Preprocess from adding another
declaration, the definition needs to add the 'IMPLEMENT' directive.
The prerequisite is that the interface is implemented in an
'IMPLEMENTATION' section that depends on _more_ configuration options
than the 'INTERFACE' section containing the declaration. For example:
! INTERFACE:
!
! class Pic
! {
! public:
! /**
! * Static initalization of the interrupt controller.
! */
! static void init();
! // ...
! };
!
! IMPLEMENTATION[i8259]:
!
! IMPLEMENT
! void
! Pic::init()
! {
! pic_init(0x20,0x28);
! }
Maintainer-mode configuration
=============================
Fiasco's build process can be instrumented with a number of checks
that ensure some of the rules defined in this document. Fiasco
developers should enable this option in the interactive configuration
tool; the option is called 'MAINTAINER_MODE' (``Do additional checks
at build time'').
The checks enabled by this option include:
* Checking for mutual or circular dependencies between modules (see
Section [Dependency management])
* Checking for use of deallocated initialization data after
initialization time.
Dependency management
#####################
Fiasco has been designed to be configurable and robust. A
precondition for achieving these properties is that modules and
subsystems can be removed from the kernel and tested in isolation,
which in turn depends on the absence of mutual or circular
dependencies between modules and subsystems.
Therefore, as a rule, these dependencies must be avoided. Please
consult [Lakos: Large-scale C++ Software Design] for standard methods to
resolve circular dependencies.
The current dependency graph can be generated in text or graphics form
using "make DEPS" and "make DEPS.ps".
Source-code style and indentation
#################################
Naming conventions
==================
In general, Fiasco developers despise the ugly
MixedCapsNamingConvention made popular by Java. If you really must
use such names, please go hack some Java project, not Fiasco. In
Fiasco, words in multi-word identifier names are generally separated
with underscores, with the sequencing words starting with a lowercase
letter or a digit (the only exception being preprocessor symbols).
Examples:
! Funky_type
! thread_id
! Thread_ready
! _current_sched
! _thread_0
In particular, the conventions are as follows:
* Type names (class names, typedef names, enum names) all start with a
capital letter. Examples: 'Thread', 'Jdb', 'Boot_info'
* Function names (both member functions and free functions) start with
a lowercase letter. Examples: 'fpage_map()', 'ipc_send_regs()'
* Nonstatic member variables start with an underscore (_). Examples:
'_mode', '_ready_time'
* Other variables (including static member variables, global and local
variables, function-argument names) start with a lower-case letter.
Examples: 'preempter', 'cpu_lock'
* Enumeration constants start with a capital letter. Examples:
'Thread_ready', 'Page_writable'
The Fiasco architecture board has declared that having the same
naming convention for types and constants is not confusing.
* Preprocessor-symbol identifiers are all-uppercase and start with a
letter. As with all other identifiers, multiple words are separated
using underscores. Examples: 'THREAD_BLOCK_SIZE', 'CONFIG_IA32_486'
Please note that preprocessor constants are deprecated and allowed
only in assembly files and header files meant to be included in
assembly code (see Section [Constant definitions]).
(For file-naming conventions refer to Section [Source-file naming].)
Comments
========
All comments must be in English. American / Aussie / Kiwi English are
OK, too, but Pidgin English or Denglisch are not.
Doxygen comments
~~~~~~~~~~~~~~~~
Please document at least all interfaces of all classes that are meant
for client-code use. These interfaces usually include all public and
protected member functions and all nonstatic free functions, but
possibly more if there is a private interface implemented by
configuration-specific code.
The interface documentation belongs to the function definition, except
if configuration-specific functions (with the 'IMPLEMENT' directive)
are declared in an 'INTERFACE' section. In the that case, the
documentation belongs to the declaration.
Please use Doxygen's Javadoc-like style (the style using '@' instead
of backslashes) to document your interfaces. Fiasco's documentation
is generated using Doxygen's auto-brief feature, so '@brief'
directives are unnecessary [Heesch: Doxygen Manual].
Comment style
~~~~~~~~~~~~~
The style of multi-line comments is not prescribed, but please be
consistent within one source file. All of the following forms are
OK:
! /** The foo function.
! * This function frobnifies its arguments.
! */
!
! /**
! * The foo function.
! * This function frobnifies its arguments.
! */
!
! /** The foo function.
! This function frobnifies its arguments.
! */
Marking incomplete code
~~~~~~~~~~~~~~~~~~~~~~~
Please use the token 'XXX' inside a comment to mark broken or
incomplete code.
Module-level rules
==================
Singletons
~~~~~~~~~~
Singleton objects (classes that will be instantiated only once) should
be implemented as static class interfaces instead of a normal
instantiable class in order to save kernel-stack space (the this
pointer does not need to be passed to these classes). However,
developers should use normal classes when it is foreseeable that the
class needs to be instantiated multiple times in the future, for
instance to support SMP machines.
Constant definitions
~~~~~~~~~~~~~~~~~~~~
Constants should generally only be defined in enumerations.
Preprocessor constants are discouraged except for source code passed
to the assembler (assembly files and header files meant to be included
in assembly code).
In C++ code, preprocessor constants must not be used for conditional
compilation using '#ifdef' and friends (see Section
[Conditional compilation]).
Bit-field types
~~~~~~~~~~~~~~~
When implementing a binary interface that has been specified in terms
of bits of machine words (such as the L4 ABI or a device interface),
it is a bad idea to implement the interface using bit-field types,
unless the interface is architecture-specific. The reason is that the
assignment of bit-field members to bit offsets is both
compiler-dependent and architecture-dependent. If bit fiddling is
required, please define a class that wraps an integral type (such as
'unsigned') and manipulate the bits using bit-and and bit-or
operators.
Bit-field structures are OK when the exact order of bits in the type's
memory representation does not matter.
Block-level rules
=================
Assertions
~~~~~~~~~~
Use assertions generously.
Fiasco supports two kinds of runtime assertions: 'assert' and 'check'.
Both cause a kernel panic when their argument evaluates to false.
The first, 'assert', works just like 'assert' in standard C. It can
be removed from the build by defining the preprocessor symbol 'NDEBUG'
and therefore must not include code that has side effects.
When side effects are desired, use 'check' instead of assert. The
contents of this macro are not optimized away with 'NDEBUG' -- only
the error-checking code is.
Common idioms
~~~~~~~~~~~~~
* Endless loops are programmed like this:
! for (;;)
! // do stuff
* Sometimes a private inline function is desired, for example if it
needs to be wrapped by a stub that is callable from assembly code.
In this case, use 'inline NOEXPORT' to avoid having to specify a
lengthy 'NEEDS[]' directive for the inline function:
! extern "C"
! void
! asm_callable_stub (Thread* t)
! {
! t->do_stuff();
! }
!
! PRIVATE inline NOEXPORT
! Thread::do_stuff ()
! {
! // ...
! }
* Macros are discouraged. Use inline functions instead.
* If you really, absolutely have to define a macro, please make sure
it can be used as single-statement blocks after 'if', 'else', and
the like, by wrapping it like this:
! #define foo(x) do { /* your stuff */ } while (0)
Rules for spacing, bracing, and indentation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If not specified more precisely in this standard, the GNU Coding
Conventions for spacing and bracing apply ([GNU Coding Standards],
Section 5.1).
* The tabulator size is 8. A tabulator can always be replaced with
spaces that lead to the next tab stop.
* The maximum line length is 80. If a code line becomes longer than
80 characters, it must be broken into shorter lines. If line length
becomes excessive, developers should factor out utility functions.
* The indentation increment is 2 spaces.
* In function definitions, put both the return type and the function
signature on a line by themselves. Example:
! PUBLIC inline
! void
! Preemption::set_preempter (Receiver *preempter)
! {
! // ...
! }
* Put whitespace before each opening parenthesis, except if it is
preceded by another opening parenthesis. Put whitespace after each
closing parenthesis, except if it is followed by another closing
parenthesis or a comma or semicolon. As a special exception, you do
not need to put a space between a function name and the
function-call operator.
! a = f (b(), sin ((x + y) * z));
* Do not wrap the argument to the 'return' statement into parentheses.
* Opening and closing braces ('\{', '\}', including the form '\};')
always reside on a line of their own. The braces are indented for
nested code blocks, but not for type and function definitions. The
braced content is always indented with respect to the braces.
Goto labels are back-indented 1 space, class-access specifiers
(public, protected, private) are back-indented 2 spaces.
! class Thread
! {
! public:
! enum Thread_state
! {
! Thread_invalid, Thread_running
! };
!
! int _prio;
! };
! PUBLIC
! void
! Thread::stuff ()
! {
! if (receiver()->ipc_try_lock (this) == 0)
! {
! do_stuff();
! }
! }
As an exception, if a function definition fits into a single line,
the whole function can be defined in one line. This style can aid
readability when defining many small functions in a row.
* Curly braces around single-statement code blocks for 'if', 'while',
'do', and 'for' are optional, except if the control expression(s) of
these statement spans more than one line, the statement following it
must be braced.
* Spacing inside expressions is not prescribed. Please do something
sensible to save us from adding more rules to this document.
; Fiasco style rules
;
; Y Directory organization
;
; Y Naming: Classes, methods, constants
;
; Y No exceptions, no RTTI
;
; Y Singleton objects as static class interfaces, to save stack space
;
; Y no preprocessor variables -- use enums
;
; Y IMPLEMENT nur für definitionen in spezielleren Subsections
;
; Y config class vs configuration management
;
; Y header files: unusally not. otherwise, multi-inc protection
;
; Y assert, check
;
; Y Max. 80 Zeichen pro Zeile
;
; Y Doxygen-Style
;
; Y Doxygen: Bei deklarierten Memberfunktionen (mit IMPLEMENT
; implementiert) kommt die Doku vor die Deklaration
;
; Y Member-Vars: _member_name
; Klassen: Class_name
; Konstanten: Constant_name
;
; Y XXX-Kommentare
;
; Y wann eigenes Quellfile, wann mehrere IMPLEMENTATION-Sections in
; einem File?
;
; Y Funktionname an Zeilenbeginn, Name/Parameter auf einer Zeile
;
; Y Rückgabetyp auf Extra-Zeile
;
; Y Einrücke-Standards
; . Enums
;
; Y Endlosschleife: for (;;)
;
; Y Makros: use do {} while (0); (else-kompatibel)
;
; Y Use inline NOEXPORT für lokale Inlines (ohne NEEDS)
;
; - kleine Interfaces erwünscht -- minimiere PUBLIC
;
; Y Makros vermeiden
;
; Y Konstanten als enums
;
; Y cyclic dependencies,
;
; - initcalls
;
; - boolean return values -- bool vs Mword, maybe a new type Bool?
;
; - "Thread*" t vs "Thread *t"
;
; - Style of CVS commit messages
;
; - Code duplication avoidance
;
; - C++ default parameters -- discouraged?
;
; - Passing structures as const structure&
;
; - Makeconf.local: the place to set CC, CXX
;
; - Sort IMPLEMENTATION[xyz] sections alphabetically: ARM vor IA32 vor
; UX, V2 vor V4 vor X0 bzw. V2,X0 vor V4.
;
; - declaration/IMPLEMENT are not for documentation purposes, which
; would not work anyway; use the files in auto/ or Doxygen.
;
; ----------------------------------------------------------------------
;
; René:
;
; Was mir am Anfang nicht klar war:
;
; Y Namenskonvention, member mit _foo, Klassen mit Grossbuchstaben
; beginnen & co, Namen allg.
;
; Y Comments englisch only
;
; Y Klammersetzung!! Auch wo man Klammern weglassen soll!
;
; - IMPLEMENT vs PUBLIC, PRIVATE, PROTECTED
;
; Erwaehnenswert waere noch fuer Neuanfaenger
;
; Y keine ifdefs
;
; - vieleicht Waechter-Style:
; also nicht
;
; if foo
; if bar
; if foobar
;
; sondern eher
; if !foo
; return
; if !bar
; return
; usw.
;
; Y Vieleicht sollten wir die maximale Einruecktiefe begrenzen. Ich bin fuer
; 3-4. Ich weis das vieles im Code noch nicht so ist, aber man kann ja mal
; anfangen.
;
; - Generic vs Arch.-spezifische Sachen, zB im generic kein regs()->ecx &
; co.
;
;
;
; Assemblermacros:
; Bis vor kurzen habe ich noch die #define Version genommen.
; Macht sich aber richtig ******* beim schreiben.
; Habe jetzt mein Zeug auf .macro umgestellt, sieht erheblich freundlicher
; aus.
;
; Ein paar hinweise allg zu Assembler, wann man lieber
; Funktionen/gemeinsamen Code sollte und wann Makros.
;Local Variables:
;mode:flyspell
;ispell-local-dictionary: "american"
;comment-start: ";"
;comment-start-skip: "; *"
;End:
; LocalWords: accessor Hohmuth tex pdflatex README Preprocess GCC polymorphism
; LocalWords: nonvirtual instantiable NDEBUG Doxygen's Doxygen XXX Javadoc cpp
; LocalWords: NOEXPORT Metarules ifdef

74
kernel/fiasco/src/TODO Normal file
View File

@@ -0,0 +1,74 @@
- make kobject_start_addr and co depend on debug feature
- remote TLB handling
- testing, testing, testing
#########################################################################
Older stuff, needs reviewing:
Functionality
#############
- Kill (deadline) timeouts if a thread is terminated.
- Fix Receiver::sender_enqueue (see ktest: "unfair scheduling").
- Long IPC: Reserve first 4MB page after User_max as ``not available'' to
allow user to use the last 4MB page for long IPC (keyword IPC window)
- Lazy IPC windowing for long IPC (similar to lazy FPU). The kernel should
store the IPC owner per address space (e.g. the last thread that called
setup_ipc_window()). When switching to a thread which performs long IPC
only flush the IPC window if it doesn't own the IPC window.
* Udo: It is also possible to setup the IPC window for the other thread
(saves pagefaults) but don't do this in switch_to()
- Compare version numbers in IPC (and not only there).
- Add receiver lists (similar to sender lists). A thread A stays in closed
wait to thread B. The IPC is not aborted if thread B is killed.
* Udo: Receiver lists are probably also needed for time donation.
- Enhance the mapping database to support I/O flexpages for x86.
- Enhance the mapping database to support Memory-Mapped flexpages.
- Add scatter/gather as defined in the X.0 specification.
- Replace fixed addresses of TCBs with e.g. a slab allocator and a hash table
for mapping Threadid->TCB (even for V2?)
- IPC via chiefs. Does that still make sense?
- The current profiling implementation produces the old BSD-GPROF4 format
which don't includes a magic number and the sample frequency. Either use
the 4.4BSD format (which isn't recognized by the binutils by default) or
use the GNU format (take the libc6 sources).
- Vkey IRQ support for Fiasco-UX.
- UTCBs for all architectures.
Code cosmetics
##############
- Use the minilibc as GlibC replacement for Fiasco-UX. This would reduce the
stack footprint of printf() & colleagues and would allow to use these
functions from kernel thread contexts without switching the stack.
- Remove all 32 bit values of -1 (0xffffffff). Replace them by a constant
defined as static_cast<Mword>(-1).
- Remove multiple definitions of offsetof macro.
- Unify long IPC pathes of all architectures.
- More unification between the kernel debugger of IA32 and UX.
- Fiasco-UX platform/subarchitecture separation.
- Class Kmem should be related to Space. Kmem should be a ``real'' object.
- ``Signal'' should be renamed to ``transactional message''.
- Rename object variables ``my_foo'' to ``_foo''.
- Simplify the IPC path by reducing the number of possible states.
- Unify the Thread stuff in ARM and IA32 V4.
Performance
###########
- The most important members of the TCB should have an offset less than 0x80
to achive smaller code (can save up to 3 bytes per instruction).
- TCB cache line optimization.
- Selective assertions, differ between ``normal'' assertions and ``expensive
assertions''.
* Frank: Assertions are quite cheap because they are marked as EXPECT_FALSE
(at least with gcc-3).

View File

@@ -0,0 +1,7 @@
IMPLEMENTATION [amd64-debug]:
IMPLEMENT inline
void
Kip::debug_print_syscalls() const
{}

View File

@@ -0,0 +1,71 @@
/*
* AMD64 Kernel-Info Page
*/
INTERFACE [amd64]:
#include "types.h"
EXTENSION class Kip
{
public:
/* 0x00 */
Mword magic;
Mword version;
Unsigned8 offset_version_strings;
Unsigned8 fill2[7];
Unsigned8 kip_sys_calls;
Unsigned8 fill3[7];
/* the following stuff is undocumented; we assume that the kernel
info page is located at offset 0x1000 into the L4 kernel boot
image so that these declarations are consistent with section 2.9
of the L4 Reference Manual */
/* 0x20 */
Mword sched_granularity;
Mword _res1[3];
/* 0x40 */
Mword sigma0_sp, sigma0_ip;
Mword _res2[2];
/* 0x60 */
Mword sigma1_sp, sigma1_ip;
Mword _res3[2];
/* 0x80 */
Mword root_sp, root_ip;
Mword _res4[2];
/* 0xA0 */
Mword _res_a0;
Mword _mem_info;
Mword _res_b0[2];
/* 0xC0 */
Mword _res5[16];
/* 0x140 */
volatile Cpu_time clock;
Unsigned64 _res6;
/* 0x150 */
Mword frequency_cpu;
Mword frequency_bus;
/* 0x160 */
Mword _res7[12];
/* 0x1C0 */
Mword user_ptr;
Mword vhw_offset;
/* 0x1D0 */
Mword _res8[2];
/* 0x1E0 */
Unsigned32 __reserved[20];
};

View File

@@ -0,0 +1,82 @@
/*
* ARM Kernel-Info Page
*/
INTERFACE [arm]:
#include "types.h"
EXTENSION class Kip
{
public:
struct Platform_info
{
Unsigned32 cpuid;
Unsigned32 mp;
};
/* 0x00 */
Mword magic;
Mword version;
Unsigned8 offset_version_strings;
Unsigned8 fill0[3];
Unsigned8 kip_sys_calls;
Unsigned8 fill1[3];
/* the following stuff is undocumented; we assume that the kernel
info page is located at offset 0x1000 into the L4 kernel boot
image so that these declarations are consistent with section 2.9
of the L4 Reference Manual */
/* 0x10 */
Mword sched_granularity;
Mword _res1[3];
/* 0x20 */
Mword sigma0_sp, sigma0_ip;
Mword _res2[2];
/* 0x30 */
Mword sigma1_sp, sigma1_ip;
Mword _res3[2];
/* 0x40 */
Mword root_sp, root_ip;
Mword _res4[2];
/* 0x50 */
Mword _res_50;
Mword _mem_info;
Mword _res_58[2];
/* 0x60 */
Mword _res5[16];
/* 0xA0 */
volatile Cpu_time clock;
Unsigned64 _res6;
/* 0xB0 */
Mword frequency_cpu;
Mword frequency_bus;
/* 0xB8 */
Mword _res7[10];
/* 0xE0 */
Mword user_ptr;
Mword vhw_offset;
Unsigned32 _res8[2];
/* 0xF0 */
Platform_info platform_info;
Unsigned32 __reserved[18];
};
//---------------------------------------------------------------------------
IMPLEMENTATION [arm && debug]:
IMPLEMENT inline
void
Kip::debug_print_syscalls() const
{}

View File

@@ -0,0 +1,20 @@
IMPLEMENTATION [{ia32,ux}-debug]:
#include <cstring>
#include "types.h"
IMPLEMENT
void
Kip::debug_print_syscalls() const
{
unsigned kips = kip_sys_calls;
static char const* const KIPS[] = {"No KIP syscalls supported",
"KIP syscalls via KIP relative stubs",
"KIP syscalls via absolute stubs",
"KIP syscalls ERROR: bad value"};
if (kips > 3)
kips = 3;
printf("%s\n", KIPS[kips]);
}

View File

@@ -0,0 +1,82 @@
/*
* IA-32 Kernel-Info Page
*/
INTERFACE [ux]:
#include "vhw.h"
INTERFACE [ia32 || ux]:
#include "types.h"
EXTENSION class Kip
{
public:
/* 0x00 */
Mword magic;
Mword version;
Unsigned8 offset_version_strings;
Unsigned8 fill0[3];
Unsigned8 kip_sys_calls;
Unsigned8 fill1[3];
/* the following stuff is undocumented; we assume that the kernel
info page is located at offset 0x1000 into the L4 kernel boot
image so that these declarations are consistent with section 2.9
of the L4 Reference Manual */
/* 0x10 */
Mword sched_granularity;
Mword _res1[3];
/* 0x20 */
Mword sigma0_sp, sigma0_ip;
Mword _res2[2];
/* 0x30 */
Mword sigma1_sp, sigma1_ip;
Mword _res3[2];
/* 0x40 */
Mword root_sp, root_ip;
Mword _res4[2];
/* 0x50 */
Mword _res_50;
Mword _mem_info;
Mword _res_58[2];
/* 0x60 */
Mword _res5[16];
/* 0xA0 */
volatile Cpu_time clock;
Unsigned64 _res6;
/* 0xB0 */
Mword frequency_cpu;
Mword frequency_bus;
/* 0xB8 */
Mword _res7[10];
/* 0xE0 */
Mword user_ptr;
Mword vhw_offset;
Unsigned32 _res8[2];
/* 0xF0 */
Unsigned32 __reserved[20];
};
//---------------------------------------------------------------------------
IMPLEMENTATION [ux]:
PUBLIC
Vhw_descriptor *
Kip::vhw() const
{
return reinterpret_cast<Vhw_descriptor*>(((unsigned long)this) + vhw_offset);
}

View File

@@ -0,0 +1,94 @@
INTERFACE [debug]:
EXTENSION class Kip
{
private:
void debug_print_syscalls() const;
};
IMPLEMENTATION [debug]:
#include <cstdio>
#include <cstring>
#include "simpleio.h"
static char const *const memory_desc_types[] = {
"Undefined",
"Conventional",
"Reserved",
"Dedicated",
"Shared",
"(undef)",
"(undef)",
"(undef)",
"(undef)",
"(undef)",
"(undef)",
"(undef)",
"(undef)",
"(undef)",
"Bootloader",
"Arch" };
PUBLIC
void
Mem_desc::dump() const
{
printf("%s [%016lx-%016lx] %s", is_virtual()?"virt":"phys",
start(), end() + 1, memory_desc_types[type()]);
}
PRIVATE
void
Kip::debug_print_memory() const
{
printf("Memory (max %d descriptors):\n",num_mem_descs());
Mem_desc const *m = mem_descs();
Mem_desc const *const e = m + num_mem_descs();
for (;m<e;++m)
{
if (m->type() != Mem_desc::Undefined)
{
printf(" %2d:", (int)(m - mem_descs() + 1));
m->dump();
puts("");
}
}
}
PRIVATE
void
Kip::debug_print_features() const
{
printf("Kernel features:");
char const *f = version_string();
for (f += strlen(f) + 1; *f; f += strlen(f) + 1)
{
putchar(' ');
putstr(f);
}
putchar('\n');
}
IMPLEMENT
void Kip::print() const
{
printf("KIP @ %p\n", this);
printf("magic: %.4s version: 0x%lx\n",(char*)&magic, version);
printf("clock: " L4_X64_FMT " (%lld)\n", clock, clock);
printf("freq_cpu: %ldkHz\n", frequency_cpu);
printf("freq_bus: %ldkHz\n", frequency_bus);
printf("sigma0_ip: " L4_PTR_FMT " sigma0_sp: " L4_PTR_FMT "\n", sigma0_ip, sigma0_sp);
printf("sigma1_ip: " L4_PTR_FMT " sigma1_sp: " L4_PTR_FMT "\n", sigma1_ip, sigma1_sp);
printf("root_ip: " L4_PTR_FMT " root_sp: " L4_PTR_FMT "\n", root_ip, root_sp);
debug_print_memory();
debug_print_syscalls();
printf("user_ptr: %p vhw_offset: " L4_MWORD_FMT "\n",
(void*)user_ptr, vhw_offset);
debug_print_features();
}

View File

@@ -0,0 +1,169 @@
INTERFACE:
class Mem_desc
{
public:
enum Mem_type
{
Undefined = 0x0,
Conventional = 0x1,
Reserved = 0x2,
Dedicated = 0x3,
Shared = 0x4,
Kernel_tmp = 0x7,
Bootloader = 0xe,
Arch = 0xf,
};
private:
Mword _l, _h;
};
//----------------------------------------------------------------------------
INTERFACE [ia32]:
/* Empty class for VHW descriptor in KIP for native ia32 */
class Vhw_descriptor {};
//----------------------------------------------------------------------------
INTERFACE:
#include "mem_region.h"
#include "types.h"
class Kip
{
public:
void print() const;
char const *version_string() const;
// returns the 1st address beyond all available physical memory
Address main_memory_high() const;
private:
static Kip *global_kip asm ("GLOBAL_KIP");
};
#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */
//============================================================================
IMPLEMENTATION:
#include "assert.h"
#include "config.h"
#include "panic.h"
#include "static_assert.h"
#include "version.h"
PUBLIC inline
Mem_desc::Mem_desc(Address start, Address end, Mem_type t, bool v = false,
unsigned st = 0)
: _l((start & ~0x3ffUL) | (t & 0x0f) | ((st << 4) & 0x0f0)
| (v?0x0200:0x0)),
_h(end)
{}
PUBLIC inline
Address Mem_desc::start() const
{ return _l & ~0x3ffUL; }
PUBLIC inline
Address Mem_desc::end() const
{ return _h | 0x3ffUL; }
PUBLIC inline
void
Mem_desc::type(Mem_type t)
{ _l = (_l & ~0x0f) | (t & 0x0f); }
PUBLIC inline
Mem_desc::Mem_type Mem_desc::type() const
{ return (Mem_type)(_l & 0x0f); }
PUBLIC inline
unsigned Mem_desc::ext_type() const
{ return _l & 0x0f0; }
PUBLIC inline
unsigned Mem_desc::is_virtual() const
{ return _l & 0x200; }
PUBLIC inline
bool Mem_desc::contains(unsigned long addr)
{
return start() <= addr && end() >= addr;
}
PUBLIC inline
bool Mem_desc::valid() const
{ return type() && start() < end(); }
PUBLIC inline
Mem_desc *Kip::mem_descs()
{ return (Mem_desc*)(((Address)this) + (_mem_info >> (MWORD_BITS/2))); }
PUBLIC inline
Mem_desc const *Kip::mem_descs() const
{ return (Mem_desc const *)(((Address)this) + (_mem_info >> (MWORD_BITS/2))); }
PUBLIC inline
unsigned Kip::num_mem_descs() const
{ return _mem_info & ((1UL << (MWORD_BITS/2))-1); }
PUBLIC inline
void Kip::num_mem_descs (unsigned n)
{
_mem_info = (_mem_info & ~((1UL << (MWORD_BITS/2))-1)
| (n & ((1UL << (MWORD_BITS/2))-1)));
}
PUBLIC
Mem_desc *Kip::add_mem_region(Mem_desc const &md)
{
Mem_desc *m = mem_descs();
Mem_desc *end = m + num_mem_descs();
for (;m<end;++m)
{
if (m->type() == Mem_desc::Undefined)
{
*m = md;
return m;
}
}
// Add mem region failed -- must be a Fiasco startup problem. Bail out.
panic("Too few memory descriptors in KIP");
return 0;
}
Kip *Kip::global_kip;
PUBLIC static
void Kip::init_global_kip(Kip *kip)
{
global_kip = kip;
// check that the KIP has actually been set up
assert(kip->sigma0_ip && kip->root_ip && kip->user_ptr);
}
PUBLIC static inline Kip *Kip::k() { return global_kip; }
IMPLEMENT
char const *Kip::version_string() const
{
static_assert((sizeof(Kip) & 0xf) == 0, "Invalid KIP structure size");
return reinterpret_cast <char const *> (this) + (offset_version_strings << 4);
}
asm(".section .initkip.version, \"a\", %progbits \n" \
".string \"" CONFIG_KERNEL_VERSION_STRING "\" \n" \
".previous \n");
asm(".section .initkip.features.fini, \"a\", %progbits \n" \
".string \"\" \n" \
".previous \n");

View File

@@ -0,0 +1,109 @@
INTERFACE:
#include "types.h"
/**
* Description of the mapping buffer registers contained in the UTCB
* (used e.g. during IPC).
* The utcb can contain buffers that describe memory regions, bits in the
* I/O bitmap or capabilities. The buffer description is used to find the
* first buffer for each type.
* Additionally, the buffer description contains a flag to specify the
* willingness to receive FPU state in an IPC operation.
*
* Note that a single buffer might occupy more than one word in the buffer-
* registers array in the UTCB. The L4_buf_iter class can be used to iterate
* over buffers.
*/
class L4_buf_desc
{
public:
enum Flags
{
/**
* \brief Flag the willingness to receive FPU state during IPC.
*
* If this flag is set, the receiving thread in an IPC is willing
* to receive the status of the floating point unit (FPU) from its partner
* as part of an IPC. Conceptually, this flag adds the FPU of the
* receiver as an additional message receiver buffer.
* The sender must set the corresponding flag L4_msg_tag::Transfer_fpu.
*/
Inherit_fpu = (1UL << 24)
};
/**
* Create an uninitialized buffer descriptor.
* \note The value of the buffer descriptor is unpredictable.
*/
L4_buf_desc() {}
/**
* Create a buffer descriptor with given values.
* \param mem the BR index for the first memory buffer item.
* \param io the BR index for the first I/O-port buffer item.
* \param obj the BR index for the first object/capability buffer item.
* \param flags the flags, such as, Inherit_fpu.
*
* The buffer registers must contain blocks of buffers of identical
* type (memory, caps, I/O-ports) starting at the given index. The first
* non-matching item terminates the items of the particular type.
* \see Utcb and L4_msg_tag
*/
L4_buf_desc(unsigned mem, unsigned io, unsigned obj,
unsigned flags = 0)
: _raw(mem | (io << 5) | (obj << 10) | flags)
{}
/**
* Index of the first memory receive buffer.
* \return the index of the first receive buffer for memory mappings.
*
* The memory receive items use two BRs each.
* \see L4_fpage, L4_msg_item
*/
unsigned mem() const { return _raw & ((1UL << 5)-1); }
/**
* Index of the first I/O-port buffer item.
* \return the index of the first BR containing a I/O-port buffer.
*
* The I/O-port buffer items use two BRs each.
* \see L4_fpage, L4_msg_item.
*/
unsigned io() const { return (_raw >> 5) & ((1UL << 5)-1); }
/**
* Index of the first object receive buffer.
* \return the BR index for the first object/capability receive buffer.
*
* An object receive buffer may use one or two BRs depending on the
* value in the L4_msg_item in the first BR.
* \see L4_msg_item, L4_fpage.
*/
unsigned obj() const { return (_raw >> 10) & ((1UL << 5)-1); }
/**
* The flags of the BDR.
* \return flags encoded in the BDR, see #Inherit_fpu, L4_buf_desc::Flags.
* \note The return value may have reserved bits set.
*/
Mword flags() const { return _raw; }
/**
* Get the raw binary representation of the buffer descriptor.
* \return binary representation of the buffer descriptor.
*/
Mword raw() const { return _raw; }
private:
/**
* A single machine word that describes the buffers that follow:
* - Bits 0..4: The index of the first memory buffer.
* - Bits 5..9: The index of the first io buffer.
* - Bits 10..14: The index of the first capability buffer.
* - Bits 15..23: Unused
* - Bits 24..31: Flags as defined above (only #Inherit_fpu is in use).
*/
Mword _raw;
};

View File

@@ -0,0 +1,62 @@
INTERFACE:
#include "types.h"
class L4_error
{
public:
enum Error_code
{
None = 0,
Timeout = 2,
R_timeout = 3,
Not_existent = 4,
Canceled = 6,
R_canceled = 7,
Overflow = 8,
Snd_xfertimeout = 10,
Rcv_xfertimeout = 12,
Aborted = 14,
R_aborted = 15,
Map_failed = 16,
};
enum Phase
{
Snd = 0,
Rcv = 1
};
L4_error(Error_code ec = None, Phase p = Snd) : _raw(ec | p) {}
L4_error(L4_error const &e, Phase p = Snd) : _raw(e._raw | p) {}
bool ok() const { return _raw == 0; }
Error_code error() const { return Error_code(_raw & 0x1e); }
Mword raw() const { return _raw; }
bool snd_phase() const { return !(_raw & Rcv); }
static L4_error from_raw(Mword raw) { return L4_error(true, raw); }
private:
L4_error(bool, Mword raw) : _raw(raw) {}
Mword _raw;
};
//----------------------------------------------------------------------------
IMPLEMENTATION [debug]:
static char const *__errors[] =
{ "OK", "timeout", "not existent", "canceled", "overflow",
"xfer snd", "xfer rcv", "aborted", "map failed" };
PUBLIC
char const *
L4_error::str_error()
{
return __errors[(_raw >> 1) & 0xf];
}

View File

@@ -0,0 +1,274 @@
INTERFACE:
#include "types.h"
/**
* A L4 flex page.
*
* A flex page represents a naturally aligned area of mappable space,
* such as memory, I/O-ports, and capabilities (kernel objects).
* There is also a representation for describing a flex page that represents
* the whole of all these address spaces. The size of a flex page is given
* as a power of two.
*
*
* The internal representation is a single machine word with the following
* layout:
* \verbatim
* +- bitsize-12 +- 11-6 -+ 5-4 -+-- 3-0 -+
* | page number | order | type | rights |
* +-------------+--------+------+--------+
* \endverbatim
*
* - The rights bits (0-3) denote the access rights to an object, see
* L4_fpage::Rights.
* - The \a type of a flex page is denotes the address space that is
* referenced by that flex page (see L4_fpage::Type).
* - The order is the exponent for the size calculation (size = 2^order).
* - The page number denotes the page address within the address space
* denoted by \a type. For example when \a type is #Memory, the \a page
* \a number must contain the most significant bits of a virtual address
* that must be aligned to \a order bits. In the case that \a type
* equals either #Io or #Obj, the \a page \a number contains all bits of
* the I/O-port number or the capability index, respectively (note, the
* values must also be aligned according to the value of \a order).
*
*/
class L4_fpage
{
public:
/**
* Data type to represent the binary representation of a flex page.
*/
typedef Mword Raw;
/**
* Address space type of a flex page.
*/
enum Type
{
Special = 0, ///< Special flex pages, either invalid or all spaces.
Memory, ///< Memory flex page
Io, ///< I/O-port flex page
Obj ///< Object flex page (capabilities)
};
enum { Addr_shift = 12 };
private:
/**
* Create a flex page with the given parameters.
*/
L4_fpage(Type type, Mword address, unsigned char order,
unsigned char rights)
: _raw(address | Raw(rights) | (Raw(order) << 6) | (Raw(type) << 4))
{}
public:
enum
{
Whole_space = 63 ///< Value to use as \a order for a whole address space.
};
/**
* Create an I/O flex page.
*
* IO flex pages do not support access rights other than RW or nothing.
* \param port base I/O-port number (0..65535), must be aligned to
* 2^\a order. The value is shifted by #Addr_shift bits to the
* left.
* \param order the order of the I/O flex page, size is 2^\a order ports.
*/
static L4_fpage io(Mword port, unsigned char order)
{ return L4_fpage(Io, port << Addr_shift, order, 0); }
/**
* Create an object flex page.
*
* \param idx capability index, note capability indexes are multiples of
* 0x1000. (hence \a idx is not shifted)
* \param order The size of the flex page is 2^\a order. The value in \a idx
* must be aligned to 2^(\a order + #Addr_shift.
*/
static L4_fpage obj(Mword idx, unsigned char order, unsigned char rights = 0)
{ return L4_fpage(Obj, idx & (~0UL << Addr_shift), order, rights); }
/**
* Create a memory flex page.
*
* \param addr The virtual address. Only the most significant bits are
* considered, bits from 0 to \a order-1 are dropped.
* \param order The size of the flex page is 2^\a order in bytes.
*/
static L4_fpage mem(Mword addr, unsigned char order, unsigned char rights = 0)
{ return L4_fpage(Memory, addr & (~0UL << Addr_shift), order, rights); }
/**
* Create a nil (invalid) flex page.
*/
static L4_fpage nil()
{ return L4_fpage(0); }
/**
* Create a special receive flex page representing
* all available address spaces at once. This is used
* for page-fault and exception IPC.
*/
static L4_fpage all_spaces(unsigned char rights = 0)
{ return L4_fpage(Special, 0, Whole_space, rights); }
/**
* Create a flex page from the raw value.
*/
explicit L4_fpage(Raw raw) : _raw(raw) {}
/**
* Get the type, see #L4_fpage::Type.
* \return the type of the flex page.
*/
Type type() const { return Type((_raw >> 4) & 3); }
/**
* Get the order of a flex page.
* \return the order of the flex page (size is 2^\a order).
*/
unsigned char order() const { return (_raw >> 6) & 0x3f; }
/**
* The robust type for carrying virtual memory addresses.
*/
typedef Virt_addr Mem_addr;
/**
* Get the virtual address of a memory flex page.
*
* \pre type() must return #Memory to return a valid value.
* \return The virtual memory base address of the flex page.
*/
Virt_addr mem_address() const
{ return Virt_addr(_raw & (~0UL << Addr_shift)); }
/**
* Get the capability address of an object flex page.
*
* \pre type() must return #Obj to return a valid value.
* \return The capability value (index) of this flex page.
* This value is not shifted, so it is a multiple of 0x1000.
* See obj_index() for reference.
*/
Mword obj_address() const { return _raw & (~0UL << Addr_shift); }
/**
* Get the I/O-port number of an I/O flex page.
* \pre type() must return #Io to return a valid value.
* \return The I/O-port index of this flex page.
*/
Mword io_address() const { return _raw >> Addr_shift; }
/**
* Get the capability index of an object flex page.
*
* \pre type() must return #Obj to return a valid value.
* \return The index into the capability table provided by this flex page.
* This value is shifted #Addr_shift to be a real index
* (opposed to obj_address()).
*/
Mword obj_index() const { return _raw >> Addr_shift; }
/**
* Test for memory flex page (if type() is #Memory).
* \return true if type() is #Memory.
*/
bool is_mempage() const { return type() == Memory; }
/**
* Test for I/O flex page (if type() is #Io).
* \return true if type() is #Io.
*/
bool is_iopage() const { return type() == Io; }
/**
* Test for object flex page (if type() is #Obj).
* \return true if type() is #Obj.
*/
bool is_objpage() const { return type() == Obj; }
/**
* Is the flex page the whole address space?
* @return not zero, if the flex page covers the
* whole address space.
*/
Mword is_all_spaces() const { return (_raw & 0xff8) == (Whole_space << 6); }
/**
* Is the flex page valid?
* \return not zero if the flex page
* contains a value other than 0.
*/
Mword is_valid() const { return _raw; }
/**
* Get the binary representation of the flex page.
* \return this flex page in binary representation.
*/
Raw raw() const { return _raw; }
private:
Raw _raw;
public:
/**
* Rights bits for flex pages.
*
* The particular semantics of the rights bits in a flex page differ depending on the
* type of the flex page. For memory there are #R, #W, and #X rights. For
* I/O-ports there must be #R and #W, to get access. For object (capabilities)
* there are #CD, #CR, #CS, and #CW rights on the object and additional
* rights in the map control value of the map operation (see L4_fpage::Obj_map_ctl).
*/
enum Rights
{
R = 4, ///< Memory flex page is readable
W = 2, ///< Memory flex page is writable
X = 1, ///< Memory flex page is executable (often equal to #R)
RX = R | X, ///< Memory flex page is readable and executable
RWX = R | W | X, ///< Memory flex page is readable, writeable, and executable
RW = R | W, ///< Memory flex page is readable and writable
WX = W | X, ///< Memory flex page is writable and executable
CD = 0x8, ///< Object flex page: delete rights
CR = 0x4, ///< Object flex page: read rights (w/o this the mapping is not present)
CS = 0x2, ///< Object flex page: strong semantics (object specific, i.e. not having
/// this right on an IPC gate demotes all capabilities transferred via this
/// IPC gate to also suffer this right.
CW = 0x1, ///< Object flex page: write rights (purely object specific)
CRW = CR | CW, ///< Object flex page: combine #CR and #CW
CRS = CR | CS, ///< Object flex page: combine #CR and #CS
CRWS = CRW | CS, ///< Object flex page: combine #CR, #CW, and #CS
CWS = CW | CS, ///< Object flex page: combine #CS and #CW
CWSD = CW | CS | CD, ///< Object flex page: combine #CS, #CW, and #CD
CRWSD = CRWS | CD, ///< Object flex page: combine #CR, #CW, #CS, and #CD
FULL = 0xf, ///< All rights shall be transferred, independent of the type
};
/**
* Get the rights associated with this flexpage.
* \return The rights associated with this flex page. The semantics of this
* value also depends on the type (type()) of the flex page.
*/
Rights rights() const { return Rights(_raw & FULL); }
/**
* Remove the given rights from this flex page.
* \param r the rights to remove. The semantics depend on the
* type (type()) of the flex page.
*/
void mask_rights(Rights r) { _raw &= (Mword(r) | ~0x0fUL); }
};

View File

@@ -0,0 +1,218 @@
INTERFACE:
#include "types.h"
#include "l4_fpage.h"
/**
* The first word of a message item, either a send item or a receive buffer.
*
* L4_msg_item is the first word of a typed message item in system calls (incl.
* IPC) The L4_msg_item is usually followed by a second word. The
* interpretation of the second word depends on the contents of the
* L4_msg_item.
*
* A generic message item has the following binary layout.
* \verbatim
* +----------------------------+ 3 + 2 .. 1 + 0 +
* | | t | | c |
* +----------------------------+---+--------+---+ \endverbatim
*
* Bit 3 (\a t) is the type bit, if t is set the item is a map
* item. \note Fiasco.OC currently has no support for other types
* than map items.
*
* Bit 0 (\a c) is the compound bit and is available
* for scatter-gather behavior. For map items the \a c bit is useful
* for send items only, and described afterwards.
*
* A map item has a more specific layout:
* \verbatim
* +-- x .. 12 --+- 11 .. 8 -+- 7 .. 4 -+ 3 + 2 +- 1 -+ 0 +
* | hot_spot | SBZ | attr | 1 | i | g/s | c |
* +-------------+-----------+----------+---+---+-----+---+ \endverbatim
*
* Bit 0 (\a c), the compound bit: if this bit is set on a send map item
* the next message item of the same type shall be mapped using the same
* receive buffer as this send item. The caller should properly use the
* \a hot_spot to avoid overlapping mappings.
*
* Bit 1 (\a g/s): On a send map item a set \a g bit flags a grant operation.
* This means, the sender delegates access to the receiver and atomically
* removes the own rights (basically a move operation). On a receive buffer
* a set \a s bit flags a small object buffer. This means, the whole buffer
* item is just a single buffer register in size and provides a receive buffer
* for a single object mapping, the address of the buffer is stored in the
* \a hot_spot.
*
* Bit 2 (\a i): This bit is defined for small receive buffers only, a set \a i
* bit denotes that he receiver wants to avoid a full mapping. Instead, if all
* preconditions are met, the receiver will get either the label of an Ipc_gate
* or a capability selector in its message registers. A label of an Ipc_gate
* is sent if and only if the receiving thread is in the same task as the
* thread that is attached to the Ipc_gate. A capability selector is received
* if the sending and the receiving thread are in the same task.
*
* Bits 7..4 (\a attr): This bits contain extra attributes that influence the
* mapping itself. For memory mapping these bits contain cachebility information.
* For object mappings these bits contain extra rights on the object.
*
* Bits x..12 (\a hot_spot): These bits are the so called hot spot and are used
* to disambiguate the cases where either the send flex page or the receive flex
* page is larger that the other.
*/
class L4_msg_item
{
private:
enum
{
Addr_shift = 12, ///< number of bits an index must be shifted, or
/// an address must be aligned to, in the control word
};
public:
/**
* Additional rights for objects (capabilities) apply to the control word of L4_msg_item.
*/
enum Obj_attribs
{
C_weak_ref = 0x10, ///< Map a weak reference (not counted in the kernel)
C_ref = 0x00, ///< Map a normal reference (counted, if not derived
/// from a weak reference)
C_obj_right_1 = 0x20, ///< Some kernel internal, object-type specific right
C_obj_right_2 = 0x40, ///< Some kernel internal, object-type specific right
C_obj_right_3 = 0x80, ///< Some kernel internal, object-type specific right
C_obj_specific_rights = C_obj_right_1 | C_obj_right_2 | C_obj_right_3,
C_ctl_rights = C_obj_specific_rights | C_weak_ref,
};
/**
* Additional flags for memory send items.
*
* These flags are to control the caching attributes of memory mappings.
*/
enum Memory_attribs
{
Caching_opt = 0x10, ///< This flag denotes the presence of a cachability option
Cached = 0x30, ///< Map the memory cachable
Buffered = 0x50, ///< Map the memory bufferable (write combining in Intel speech)
Uncached = 0x10, ///< Map the memory fully uncachable
};
enum Type
{
Map = 8,
};
/**
* Create a message item from its binary represenation.
* \param raw is the binary representation of the message item.
*/
explicit L4_msg_item(Mword raw) : _raw(raw) {}
/**
* Use the same receive buffer for the next send item.
* \pre The item must be a send item.
* \return true if the next send item shall be handled with the
* same receive buffer as this one.
*/
Mword compound() const { return _raw & 1; }
/**
* Get the type of the message item.
* \return the type of the message item, currently Fiasco.OC
* supports map items only, see #L4_msg_item::Map).
*/
Type type() const { return Type(_raw & 8); }
/**
* Is the item a a void item?
* \return true if the item is \a void, false if it is valid.
*/
bool is_void() const { return _raw == 0; }
/**
* Is the buffer item a small object buffer?
* \pre The item must be a receive buffer.
* \pre type() == #L4_msg_item::Map
* \return true if the buffer is a single-word single-object
* receive buffer, false else.
*/
Mword is_small_obj() const { return _raw & 2; }
/**
* Receiver tries to receive an object ID or a
* capability selector?
* \pre The item must be a receive buffer.
* \pre type() == #L4_msg_item::Map
* \pre is_small_obj() == true
* \return true if the receiver is willing to receive an object ID
* or a capability selector, if possible.
*/
Mword is_rcv_id() const { return _raw & 4; }
/**
* Is the map item actually a grant item?
* \pre type() == #L4_msg_item::Map
* \pre The item is a send item.
* \return true if the sender does a grant operation.
*/
Mword is_grant() const { return _raw & 2; }
/**
* Get the binary representation of the item.
* \return the binary representation of this item.
*/
Mword raw() const { return _raw; }
/**
* Get the extra attributes for the send item.
* \pre The item is a send item.
* \pre type() == #L4_msg_item::Map.
* \return the extra attributes for this send item.
*
* The semantics of the extra attributes depends on
* the type of the second word, the L4_fpage, of the
* complete send item.
* \see L4_msg_item::Memory_attribs, L4_msg_item::Obj_attribs
*/
Mword attr() const { return _raw & 0xf0; }
/**
* Get the value of the most significant bits of a map item.
* \pre type() == #L4_msg_item::Map
* \return the most significant bits (shifted by #L4_msg_item::Addr_shift).
*/
Mword index() const { return _raw >> Addr_shift; }
/**
* Get the most significant bits of a map item (masked).
* \pre type() == #L4_msg_item::Map
* \return the most significant bits (masked the lower
* #L4_msg_item::Addr_shift bits).
*/
Mword address() const { return _raw & (~0UL << Addr_shift); }
/**
* Get the L4_fpage that represents the small buffer item.
* \pre type() == #L4_msg_item::Map
* \pre is_small_obj() == true
* \return the flex page (L4_fpage) representing the single
* object slot with index index().
*/
L4_fpage get_small_buf() { return L4_fpage::obj(_raw, 0, attr() >> 4); }
/**
* Create a map item.
* \param base the hot spot address of the map item.
*/
static L4_msg_item map(Mword base) { return L4_msg_item(base | Map); }
private:
/**
* The binary representation.
*/
Mword _raw;
};

View File

@@ -0,0 +1,43 @@
IMPLEMENTATION [debug]:
#include <cstdio>
#include "simpleio.h"
PUBLIC void L4_timeout::print() const
{
printf("m=%ld e=%ld", man(), exp());
}
PUBLIC void L4_timeout_pair::print() const
{
printf("snd: ");
snd.print();
printf(" rcv: ");
rcv.print();
}
PUBLIC
void
Utcb::print() const
{
puts("Values:");
for (unsigned i = 0; i < Max_words; ++i)
printf("%2d:%16lx%c", i, values[i], !((i+1) % 4) ? '\n' : ' ');
if (Max_words % 4)
puts("");
printf("Reserved: %16lx\n", utcb_addr);
printf("Buffers: desc=%16lx\n", buf_desc.raw());
for (unsigned i = 0; i < sizeof(buffers) / sizeof(buffers[0]); ++i)
printf("%2d:%16lx%c", i, buffers[i], !((i+1) % 4) ? '\n' : ' ');
if ((sizeof(buffers) / sizeof(buffers[0])) % 4)
puts("");
printf("Xfer timeout: ");
xfer.print();
puts("");
printf("Error: %16lx\n", error.raw());
printf("User values: %16lx %16lx %16lx\n", user[0], user[1], user[2]);
}

View File

@@ -0,0 +1,124 @@
INTERFACE:
EXTENSION class L4_fpage
{
public:
/**
* task cap specific constants.
*/
enum {
Whole_obj_space = 25, ///< The order used to cover the whole x-cap space
Obj_max = 1L << Whole_obj_space, ///< Number of available task caps.
};
/**
* Create the given task flex page.
* @param port the port address.
* @param order the size of the flex page is 2^order.
* @param grant if not zero the grant bit is to be set.
*/
static L4_fpage obj(Mword index, Mword order, Mword grant);
/**
* Get the x-cap flexpage base address.
* @return The x-cap flexpage base address.
*/
Mword obj() const;
/**
* Set the x-cap flexpage base address.
* @param addr the x-cap flexpage base address.
*/
void obj( Mword index );
/**
* Is the flex page a task-cap flex page?
* @returns not zero if this flex page is a task-cap flex page.
*/
Mword is_objpage() const;
/**
* Does the flex page cover the whole task-cap space.
* @pre The is_cappage() method must return true or the
* behavior is undefined.
* @return not zero if the flex page covers the whole task-cap
* space.
*/
Mword is_whole_obj_space() const;
private:
enum {
Obj_mask = 0x007ff000,
Obj_shift = 12,
};
};
INTERFACE [32bit]:
EXTENSION class L4_fpage
{
private:
enum
{
Obj_id = 0xf0000300,
};
};
INTERFACE [64bit]:
EXTENSION class L4_fpage
{
private:
enum
{
Obj_id = 0xfffffffff0000300UL,
};
};
//---------------------------------------------------------------------------
IMPLEMENTATION [!caps]:
IMPLEMENT inline
Mword L4_fpage::obj() const
{
return 0;
}
IMPLEMENT inline
Mword L4_fpage::is_objpage() const
{
return 0;
}
//---------------------------------------------------------------------------
IMPLEMENTATION [caps]:
IMPLEMENT inline
Mword L4_fpage::is_objpage() const
{ return (_raw & Special_fp_mask) == Obj_id; }
IMPLEMENT inline
void L4_fpage::obj( Mword w )
{
_raw = (_raw & ~Obj_mask) | ((w << Obj_shift) & Obj_mask);
}
IMPLEMENT inline
Mword L4_fpage::obj() const
{
return (_raw & Obj_mask) >> Obj_shift;
}
IMPLEMENT inline
L4_fpage L4_fpage::obj(Mword index, Mword order, Mword grant)
{
return L4_fpage( (grant ? 1 : 0)
| ((index << Obj_shift) & Obj_mask)
| ((order << Size_shift) & Size_mask)
| Obj_id);
}
IMPLEMENT inline
Mword L4_fpage::is_whole_obj_space() const
{ return (_raw >> 2) == Whole_obj_space; }

View File

@@ -0,0 +1,934 @@
/*
* arch. independent L4 Types
*/
INTERFACE:
#include "types.h"
#include "l4_fpage.h"
#include "l4_buf_desc.h"
#include "l4_error.h"
typedef Address Local_id;
class Utcb;
/**
* A reference to a kernel object (capability selector),
* as passed from user level.
*
* A capability selector contains an index into the capability table/object
* space of a task. The index is usually stored in the most significant bits
* of the binary representation. The twelve least significant bits are used to
* to denote the type of operation that shall be invoked and also so flags for
* special capabilities, such as the invalid cap, the reply capability, or the
* self capability.
*
* Generally all operations on kernel objects are modelled as message passing
* primitives that consist of two phases, the send phase and the receive phase.
* However, both phases are optional and come in slightly different flavors.
* \see L4_obj_ref::Operation.
* The terms send and receive are from the invokers point of view. This means,
* a client doing RPC needs a send for sending the requested operation an
* parameters and a receive to receive the return code of the RPC.
*/
class L4_obj_ref
{
public:
/**
* Operation codes, stored in the four least significant bits of a capability
* selector.
*/
enum Operation
{
/// A no-op on the capability (undefined from user level).
None = 0,
/**
* \deprecated Use #Ipc_call_ipc.
* Deprecated call code, do not use this operation code.
*/
Ipc_call = 0,
/**
* Set this bit to include a send phase.
*
* In the case of a send phase, the message is send to the object
* denoted by either the capability selector (cap()), the reply capability
* (if #Ipc_reply is also set), or to the thread itself (if the cap is the
* special self capability).
*/
Ipc_send = 1,
/**
* Set this bit to include a receive phase.
*
* During the receive phase the caller waits for a message from either a
* specific sender (closed wait) or from any possible sender
* (#Ipc_open_wait) that has a capability to send messages to the invoker.
*/
Ipc_recv = 2,
/**
* Set this bit to denote an open-wait receive phase.
*
* An open wait means that the invoker shall wait for a message from any
* sender that has a capability to send messages to the invoker. In this
* case the index (cap()) in the capability selector are ignored for the
* receive phase.
*/
Ipc_open_wait = 4,
/**
* Set this bit to make the send phase a reply.
*
* A reply operation uses the implicit reply capability that is stored
* in per thread storage and can be used only once. The reply capability
* also vanishes in the case of an abort due to the caller or a newly
* received call operation by the same thread.
* \see #Ipc_send.
*/
Ipc_reply = 8,
/**
* Denotes a wait operation. (#Ipc_recv | #Ipc_open_wait).
*
* The wait operation is usually used by servers to implement remote
* objects.
*/
Ipc_wait = Ipc_open_wait | Ipc_recv,
/**
* Denotes a combination of a send and a wait operation (#Ipc_send |
* #Ipc_recv | #Ipc_open_wait).
*
* \note this is not used for usual RPC, see #Ipc_reply_and_wait for that.
*/
Ipc_send_and_wait = Ipc_open_wait | Ipc_send | Ipc_recv,
/**
* Denotes a reply and wait operation (#Ipc_send | #Ipc_reply | #Ipc_recv |
* #Ipc_open_wait).
*
* This operation is usually used to send replies to RPC requests.
*/
Ipc_reply_and_wait = Ipc_open_wait | Ipc_send | Ipc_recv | Ipc_reply,
/**
* Denotes a call operation (#Ipc_send | #Ipc_recv).
*
* A call is usually used by a client to invoke an operation on a remote
* object and wait for a result. The call operation establishes the
* implicit reply capability for the partner thread (see #Ipc_reply)
* and enables the implementation of an object to respond to an invocation
* without knowledge of the invoker thread.
*/
Ipc_call_ipc = Ipc_send | Ipc_recv,
};
/**
* Special capability selectors (e.g., Invalid cap).
*/
enum Special
{
/**
* Invalid capability selector.
*/
Invalid = 1UL << 11UL,
/**
* Bit that flags a capability selector as special.
*/
Special_bit = 1UL << 11UL,
/**
* Value for the self capability selector. This means, the invoking thread
* references itself.
*/
Self = (~0UL) << 11UL,
/**
* Mask for getting all bits of special capabilities.
*/
Special_mask = (~0UL) << 11UL,
};
enum
{
Cap_shift = 12UL
};
/**
* Create a special capability selector from \a s.
* \param s which special cap selector shall be created
* (see L4_obj_ref::Special).
*
* Special capability selectors are the invalid capability and the self
* Capability. All special capability selectors must have the #Special_bit
* set.
*/
L4_obj_ref(Special s = Invalid) : _raw(s) {}
/**
* Create a capability selector from it's binary representation.
* \param raw the raw binary representation of a capability selector. As
* passed from user land.
*/
static L4_obj_ref from_raw(Mword raw) { return L4_obj_ref(true, raw); }
/**
* Is the capability selector a valid capability (no special capability).
* \return true if the capability selector is a valid index into the
* capability table, or false if the selector is a special
* capability.
*/
bool valid() const { return !(_raw & Special_bit); }
/**
* Is the capability selector a special capability (i.e., not an index
* into the capability table).
* \return true if the capability selector denotes a special capability
* (see L4_obj_ref::Special), or false if this capability is a
* valid index into a capability table.
*
*/
bool special() const { return _raw & Special_bit; }
/**
* Is this capability selector the special \a self capability.
* \return true if this capability is the special self capability for the
* invoking thread.
*/
bool self() const { return special(); }
/**
* Get the value of a special capability.
* \pre special() == true
* \return the value of a special capability selector, see
* L4_obj_ref::Special.
*/
Special special_cap() const { return Special(_raw & Special_mask); }
//bool self() const { return (_raw & Invalid_mask) == Self; }
/**
* Does the operation contain a receive phase?
* \return true if the operation encoded in the capability selector
* comprises a receive phase, see #L4_obj_ref::Ipc_recv.
*/
unsigned have_recv() const { return _raw & Ipc_recv; }
/**
* Get the index into the capability table.
* \pre valid() == true
* \return The index into the capability table stored in the capability
* selector (i.e., the most significant bits of the selector).
*/
unsigned long cap() const { return _raw >> 12; }
/**
* Get the operation stored in this selector (see L4_obj_ref::Operation).
* \return The operation encoded in the lower 4 bits of the capability
* selector, see L4_obj_ref::Operation.
*/
Operation op() const { return Operation(_raw & 0xf); }
/**
* Get the raw binary representation of this capability selector.
* \return the binary representation of this cap selector.
*/
Mword raw() const { return _raw; }
/**
* Create a valid capability selector for the shifted cap-table index
* and the operation.
* \param cap the shifted (<< #Cap_shift) capability-table index.
* \param op the operation to be encoded in bits 0..3.
*/
explicit L4_obj_ref(Mword cap, Operation op = None) : _raw(cap | op) {}
/**
* Create a capability selector (index 0) with the given operation.
* \param op the operation to be encoded into the capability selector,
* see L4_obj_ref::Operation.
*/
L4_obj_ref(Operation op) : _raw(op) {}
/**
* Compare two capability selectors for equality.
* \param o the right hand side for te comparison.
* \note Capability selectors are compared by their binary representation.
*/
bool operator == (L4_obj_ref const &o) const { return _raw == o._raw; }
private:
L4_obj_ref(bool, Mword raw) : _raw(raw) {}
Mword _raw;
};
/**
* Flags for unmap operations.
*/
class L4_map_mask
{
public:
/**
* Create a from binary representation.
* \param raw the binary representation, as passed from user level.
*/
explicit L4_map_mask(Mword raw = 0) : _raw(raw) {}
/**
* Get the flags for a full unmap.
* \return A L4_map_mask for doing a full unmap operation.
*/
static L4_map_mask full() { return L4_map_mask(0xc0000002); }
/**
* Get the raw binary representation for the map mask.
* \return the binary value of the flags.
*/
Mword raw() const { return _raw; }
/**
* Unmap from the calling Task too.
* \return true if the caller wishes to unmap from its own address space too.
*/
Mword self_unmap() const { return _raw & 0x80000000; }
/**
* Shall the unmap delete the object if allowed?
* \return true if the unmap operation shall also delete the kernel
* object if permitted to the caller.
*/
Mword do_delete() const { return _raw & 0x40000000; }
private:
Mword _raw;
};
/**
* Description of a message to the kernel or other thread.
*
* A message tag determines the number of untyped message words (words()), the
* number of typed message items (items(), L4_msg_item), some flags, and a
* protocol ID. The number of typed and untyped items in the UTCB's message
* registers, as well as the flags, control the kernels message passing
* mechanism. The protocol ID is not interpreted by the message passing
* itself, however is interpreted by the receiving object itself. In thread to
* thread IPC the all contents besides the flags are copied from the sender to
* the receiver. The flags on the receiver side contain some information about
* the operation itself.
*
* The untyped message words are copied to the receiving object/thread
* uninterpreted. The typed items directly following the untyped words in
* the message registers are interpreted by the message passing and contain,
* for example, map items for memory or kernel objects (see L4_msg_item,
* L4_fpage).
*/
class L4_msg_tag
{
public:
/**
* Flags in the message tag.
*
* The input flags control the send phase of an IPC operation. Flags might
* have a different semantics in the returned message tag, the result of an
* IPC operation, see L4_msg_tag::Output_flags. However, the #Transfer_fpu
* and #Schedule flags are passed to the receiver.
*/
enum Flags
{
/**
* The sender is transferring the state of the floating-point unit (FPU)
* as part of the message.
* \note The receiver needs to agree with that by setting
* L4_buf_desc::Inherit_fpu in its buffer descriptor register (BDR).
* \note This flag is passed through to the receiver.
*/
Transfer_fpu = 0x1000,
/**
* The sender does not want to donate its remaining time-slice to the
* receiver (partner) thread.
* \note This flag is passed on to the receiver.
*/
Schedule = 0x2000,
/**
* The sender wants to propagate an incoming call operation to a different
* thread.
* \note Not implemented in Fiasco.OC.
*
* Propagation means that the reply capability shall be passed on to the
* receiver of this message to enable a direct reply.
*/
Propagate = 0x4000, // snd only flag
};
/**
* Result flags for IPC operations.
*
* These flags are dedicated return values for an IPC operation.
*/
enum Output_flags
{
/**
* The IPC operation did not succeed, the detailed error code
* is in the error register in the UTCB.
*/
Error = 0x8000,
/**
* The IPC operation did cross CPU boundaries.
*/
X_cpu = 0x4000,
/**
* Combination of flags that are not pass through.
*/
Rcv_flags = Error | X_cpu,
};
/**
* Protocol IDs that are defined by the kernel ABI.
*
* These protocol IDs are used for either kernel implemented
* objects, or used for kernel-synthesized requests to user
* objects.
*/
enum Protocol
{
Label_none = 0, ///< No protocol, the default
/**
* Value to allow the current system call for an alien thread.
*
* This value is used in the reply to an alien pre-syscall exception IPC.
*/
Label_allow_syscall = 1,
Label_irq = -1L, ///< IRQ object protocol.
Label_page_fault = -2L, ///< Page fault messages use this protocol.
Label_preemption = -3L, ///< Preemption IPC protocol. \note unused.
Label_sys_exception = -4L, ///< Sys exception protocol. \note unused.
Label_exception = -5L, ///< Exception IPC protocol.
Label_sigma0 = -6L, ///< Protocol for sigma0 objects.
Label_io_page_fault = -8L, ///< Protocol for I/O-port page faults.
Label_kobject = -10L, ///< Control protocol iD for IPC gates (server
/// side).
Label_task = -11L, ///< Protocol ID for task and VM objects.
Label_thread = -12L, ///< Protocol ID for thread objects.
Label_log = -13L, ///< Protocol ID for log / vcon objects.
Label_scheduler = -14L, ///< Protocol ID for scheduler objects.
Label_factory = -15L, ///< Protocol ID for factory objects.
Label_vm = -16L, ///< Protocol ID for VM objects (used for create
/// operations on a factory).
Label_semaphore = -20L, ///< Protocol ID for semaphore objects.
};
private:
Mword _tag;
};
/**
* L4 timeouts data type.
*/
class L4_timeout
{
public:
/// Typical timeout constants.
enum {
Never = 0, ///< Never timeout.
Zero = 0x400, ///< Zero timeout.
};
/**
* Create the specified timeout.
* @param man mantissa of the send timeout.
* @param exp exponent of the send timeout
* (exp=0: infinite timeout,
* exp>0: t=2^(exp)*man,
* man=0 & exp!=0: t=0).
*/
L4_timeout(Mword man, Mword exp);
L4_timeout(Mword man, Mword exp, bool clock);
/**
* Create a timeout from it's binary representation.
* @param t the binary timeout value.
*/
L4_timeout(unsigned short t = 0);
/**
* Get the binary representation of the timeout.
* @return The timeout as binary representation.
*/
unsigned short raw() const;
/**
* Get the receive exponent.
* @return The exponent of the receive timeout.
* @see rcv_man()
*/
Mword exp() const;
/**
* Set the exponent of the receive timeout.
* @param er the exponent for the receive timeout (see L4_timeout()).
* @see rcv_man()
*/
void exp(Mword er);
/**
* Get the receive timout's mantissa.
* @return The mantissa of the receive timeout (see L4_timeout()).
* @see rcv_exp()
*/
Mword man() const;
/**
* Set the mantissa of the receive timeout.
* @param mr the mantissa of the recieve timeout (see L4_timeout()).
* @see rcv_exp()
*/
void man(Mword mr);
/**
* Get the relative receive timeout in microseconds.
* @param clock Current value of kernel clock
* @return The receive timeout in micro seconds.
*/
Unsigned64 microsecs_rel(Unsigned64 clock) const;
/**
* Get the absolute receive timeout in microseconds.
* @param clock Current value of kernel clock
* @return The receive timeout in micro seconds.
*/
Unsigned64 microsecs_abs(Utcb *u) const;
private:
enum
{
Clock_mask = 0x0400,
Abs_mask = 0x8000,
Exp_mask = 0x7c00,
Exp_shift = 10,
Man_mask = 0x3ff,
Man_shift = 0,
};
unsigned short _t;
} __attribute__((packed));
struct L4_timeout_pair
{
L4_timeout rcv;
L4_timeout snd;
L4_timeout_pair(L4_timeout const &rcv, L4_timeout const &snd)
: rcv(rcv), snd(snd) {}
L4_timeout_pair(unsigned long v) : rcv(v), snd(v >> 16) {}
Mword raw() const { return (Mword)rcv.raw() | (Mword)snd.raw() << 16; }
};
/**
* This class contains constants for the message size for exception IPC.
*
* This information is architecture dependent, see #Msg_size.
*/
class L4_exception_ipc
{};
class L4_semaphore
{
public:
Smword counter;
Mword flags;
};
/**
* Constants for error codes returned by kernel objects.
*/
class L4_err
{
public:
enum Err
{
EPerm = 1, ///< Permission denied.
ENoent = 2, ///< Some object was not found.
ENomem = 12, ///< Out of memory.
EBusy = 16, ///< The object is busy, try again.
EExists = 17, ///< Some object does already exist.
ENodev = 19, ///< Objects of the specified type cannot be created.
EInval = 22, ///< Invalid parameters passed.
ENosys = 38, ///< No such operation.
EBadproto = 39, ///< Protocol not supported by object.
EAddrnotavail = 99, ///< The given address is not available.
};
};
//----------------------------------------------------------------------------
INTERFACE [ia32 || ux]:
EXTENSION class L4_exception_ipc
{
public:
enum { Msg_size = 16 };
};
//----------------------------------------------------------------------------
INTERFACE [arm]:
EXTENSION class L4_exception_ipc
{
public:
enum { Msg_size = 20 };
};
//----------------------------------------------------------------------------
INTERFACE [amd64]:
EXTENSION class L4_exception_ipc
{
public:
enum { Msg_size = 23 };
};
INTERFACE [ppc32]:
EXTENSION class L4_exception_ipc
{
public:
enum { Msg_size = 39 };
};
INTERFACE [sparc]:
EXTENSION class L4_exception_ipc
{
public:
enum { Msg_size = 12 }; // XXX whatever?
};
//----------------------------------------------------------------------------
INTERFACE:
/**
* User-level Thread Control Block (UTCB).
*
* The UTCB is a virtual extension of the registers of a thread. A UTCB
* comprises three sets of registers: the message registers (MRs), the buffer
* registers (BRs and BDR), and the control registers (TCRs).
*
* The message registers (MRs) contain the contents of the messages that are
* sent to objects or received from objects. The message contents consist of
* untyped data and typed message items (see L4_msg_tag). The untyped must be
* stored in the first \a n message registers (\a n = L4_msg_tag::words()) and
* are transferred / copied uninterpreted to the receiving object (MRs of
* receiver thread or kernel object). The typed items follow starting at MR[\a
* n+1]. Each typed item is stored in two MRs and is interpreted by the kernel
* (see L4_msg_item, L4_fpage). The number of items is denoted by
* L4_msg_tag::items(). On the receiver side the typed items are translated
* into a format that is useful for the receiver and stored at into the same
* MRs in the receivers UTCB.
*
* The buffer registers (BRs and BDR) contain information that describe receive
* buffers for incoming typed items. The contents of these registers are not
* altered by the kernel. The buffer descriptor register (BDR, Utcb::buf_desc)
* contains information about the items in the buffer registers (BRs) and
* flags to enable FPU state transfer. The BRs contain a set of receive
* message items (L4_msg_item) that describe receive buffers, such as, virtual
* memory regions for incoming memory mappings or buffers for capabilities.
* The BRs are also used to store absolute 64bit timeout values for operations,
* The value of the timeout pair encodes the number of the BR if an absolute
* timeout is used.
*
* The thread control registers (TCRs) comprise an error code for errors during
* message passing and a set of user-level registers. The user-level registers
* are not used by the kernel and provide and anchor for thread-local storage.
*/
class Utcb
{
/* must be 2^n bytes */
public:
/**
* Type for time values in the UTCB (size is fix 64bit).
*
* On 32bit architectures this type uses two MRs on 64bit one Mr is used.
* This type is used for conversion of time values stored in MRs or BRs.
*/
union Time_val
{
enum { Words = sizeof(Cpu_time)/sizeof(Mword) /**< Number of MRs used. */ };
Mword b[Words]; ///< The array of MRs to use.
Cpu_time t; ///< The time value itself.
};
enum
{
Max_words = 63, ///< Number of MRs.
Max_buffers = 58 ///< Number of BRs.
};
/// The message registers (MRs).
Mword values[Max_words];
Mword utcb_addr;
/// The buffer descriptor register (BDR).
L4_buf_desc buf_desc;
/// The buffer registers (BRs).
Mword buffers[Max_buffers];
/// The error code for IPC (TCR).
L4_error error;
/// \deprecated transfer timeout is not used currently (TCR).
L4_timeout_pair xfer;
/// The user-level registers for TLS (TCR).
Mword user[3];
};
//----------------------------------------------------------------------------
IMPLEMENTATION:
#include <minmax.h>
/**
* Receiver is ready to receive FPU contents?
* \return true if the receiver is ready to receive the state of the FPU as
* part of a message.
* \see L4_buf_desc::Inherit_fpu, L4_buf_desc.
*/
PUBLIC inline
bool Utcb::inherit_fpu() const
{ return buf_desc.flags() & L4_buf_desc::Inherit_fpu; }
/**
* Create a message tag from its parts.
* \param words the number of untyped message words to transfer.
* \param items the number of typed message items, following the untyped words
* in the message registers. See L4_msg_item.
* \param flags the flags, see L4_msg_tag::Flags and L4_msg_tag::Output_flags.
* \param proto the protocol ID to use.
*/
PUBLIC inline
L4_msg_tag::L4_msg_tag(unsigned words, unsigned items, unsigned long flags,
unsigned long proto)
: _tag((words & 0x3f) | ((items & 0x3f) << 6) | flags | (proto << 16))
{}
/**
* Create an uninitialized message tag.
* \note the value of the tag is unpredictable.
*/
PUBLIC inline
L4_msg_tag::L4_msg_tag()
{}
/**
* Create a message tag from another message tag, replacing
* the L4_msg_tag::Output_flags.
* \param o the message tag to copy.
* \param flags the output flags to set in the new tag.
* \pre (flags & ~Rcv_flags) == 0
*/
PUBLIC inline
L4_msg_tag::L4_msg_tag(L4_msg_tag const &o, Mword flags)
: _tag((o.raw() & ~Mword(Rcv_flags)) | flags)
{}
/**
* Create msg tag from the binary representation.
* \param raw the raw binary representation, as passed from user level.
*/
PUBLIC explicit inline
L4_msg_tag::L4_msg_tag(Mword raw)
: _tag(raw)
{}
/**
* Get the protocol ID.
* \return the protocol ID.
*/
PUBLIC inline
long
L4_msg_tag::proto() const
{ return long(_tag) >> 16; }
/**
* Get the binary representation.
* \return the binary value of the tag.
*/
PUBLIC inline
unsigned long
L4_msg_tag::raw() const
{ return _tag; }
/**
* Get the number of untyped words to deliver.
* \return number message registers that shall be transferred
* uninterpreted to the receiving object.
*/
PUBLIC inline
unsigned L4_msg_tag::words() const
{ return _tag & 63; }
/**
* Get the number of typed message items in the message.
* \return the number of typed items, directly following the
* untyped words in the message registers.
* \see L4_msg_item.
*/
PUBLIC inline
unsigned L4_msg_tag::items() const
{ return (_tag >> 6) & 0x3f; }
/**
* Get the flags of the tag.
* \return the flags of the message tag, note reserved bits might be
* set in the result.
*/
PUBLIC inline
Mword L4_msg_tag::flags() const
{ return _tag; }
/**
* Transfer the FPU?
* \return true if the sender wishes to transfer FPU contents.
* \see #Transfer_fpu.
*/
PUBLIC inline
bool L4_msg_tag::transfer_fpu() const
{ return _tag & Transfer_fpu; }
/**
* Do time-slice donation?
* \return true if the sender is willing to donate its remaining time-
* slice to the receiver.
* \see #Schedule.
*/
PUBLIC inline
bool L4_msg_tag::do_switch() const
{ return !(_tag & Schedule); }
/**
* Set the error flag to \a e.
* \param e the value of the error flag to be set.
*/
PUBLIC inline
void L4_msg_tag::set_error(bool e = true)
{ if (e) _tag |= Error; else _tag &= ~Mword(Error); }
/**
* Is there an error flagged?
* \return true if the error flag of the message tag is set.
*/
PUBLIC inline
bool L4_msg_tag::has_error() const
{ return _tag & Error; }
//
// L4_timeout implementation
//
IMPLEMENT inline L4_timeout::L4_timeout(unsigned short t)
: _t(t)
{}
IMPLEMENT inline unsigned short L4_timeout::raw() const
{ return _t; }
PUBLIC inline
Mword L4_timeout::abs_exp() const
{ return (_t >> 11) & 0xf; }
PUBLIC inline
bool L4_timeout::abs_clock() const
{ return _t & Clock_mask; }
IMPLEMENT inline
Unsigned64
L4_timeout::microsecs_rel(Unsigned64 clock) const
{
if (man() == 0)
return 0;
else
return clock + ((Unsigned64)man() << exp());
}
IMPLEMENT inline NEEDS[<minmax.h>]
Unsigned64
L4_timeout::microsecs_abs(Utcb *u) const
{
int idx = min<int>(_t & 0x3f, Utcb::Max_buffers);
Utcb::Time_val const *top
= reinterpret_cast<Utcb::Time_val const *>(&u->buffers[idx]);
return top->t;
}
PUBLIC inline
bool
L4_timeout::is_absolute() const
{ return _t & Abs_mask; }
PUBLIC inline
Unsigned64
L4_timeout::microsecs(Unsigned64 clock, Utcb *u) const
{
if (is_absolute())
return microsecs_abs(u);
else
return microsecs_rel(clock);
}
PUBLIC inline
bool L4_timeout::is_never() const
{ return !_t; }
PUBLIC inline
bool L4_timeout::is_zero() const
{ return _t == Zero; }
PUBLIC inline
unsigned short L4_timeout::is_finite() const
{ return _t; }
//
// L4_timeout implementation
//
IMPLEMENT inline
L4_timeout::L4_timeout(Mword man, Mword exp)
: _t (((man & Man_mask) | ((exp << Exp_shift) & Exp_mask)))
{}
IMPLEMENT inline
L4_timeout::L4_timeout(Mword man, Mword exp, bool clock)
: _t (((man & Man_mask) | ((exp << (Exp_shift+1)) & Exp_mask)
| (clock ? Clock_mask : 0) | Abs_mask))
{}
IMPLEMENT inline Mword L4_timeout::exp() const
{ return (_t & Exp_mask) >> Exp_shift; }
IMPLEMENT inline void L4_timeout::exp(Mword w)
{ _t = (_t & ~Exp_mask) | ((w << Exp_shift) & Exp_mask); }
IMPLEMENT inline Mword L4_timeout::man() const
{ return (_t & Man_mask) >> Man_shift; }
IMPLEMENT inline void L4_timeout::man (Mword w)
{ _t = (_t & ~Man_mask) | ((w << Man_shift) & Man_mask); }

View File

@@ -0,0 +1,76 @@
/*
* PPC32 Kernel-Info Page
*/
INTERFACE [ppc32]:
#include "types.h"
EXTENSION class Kip
{
public:
/* 0x00 */
Mword magic;
Mword version;
Unsigned8 offset_version_strings;
Unsigned8 fill0[3];
Unsigned8 kip_sys_calls;
Unsigned8 fill1[3];
/* the following stuff is undocumented; we assume that the kernel
info page is located at offset 0x1000 into the L4 kernel boot
image so that these declarations are consistent with section 2.9
of the L4 Reference Manual */
/* 0x10 */
Mword sched_granularity;
Mword _res1[3];
/* 0x20 */
Mword sigma0_sp, sigma0_ip;
Mword _res2[2];
/* 0x30 */
Mword sigma1_sp, sigma1_ip;
Mword _res3[2];
/* 0x40 */
Mword root_sp, root_ip;
Mword _res4[2];
/* 0x50 */
Mword _res_50;
Mword _mem_info;
Mword _res_58[2];
/* 0x60 */
Mword _res5[16];
/* 0xA0 */
volatile Cpu_time clock;
Unsigned64 _res6;
/* 0xB0 */
Mword frequency_cpu;
Mword frequency_bus;
/* 0xB8 */
Mword _res7[10];
/* 0xE0 */
Mword user_ptr;
Mword vhw_offset;
Unsigned32 _res8[2];
/* 0xF0 */
Unsigned32 __reserved[20];
};
//---------------------------------------------------------------------------
IMPLEMENTATION [ppc32 && debug]:
IMPLEMENT inline
void
Kip::debug_print_syscalls() const
{}

View File

@@ -0,0 +1,76 @@
/*
* SPARC Kernel-Info Page
*/
INTERFACE [sparc]:
#include "types.h"
EXTENSION class Kip
{
public:
/* 0x00 */
Mword magic;
Mword version;
Unsigned8 offset_version_strings;
Unsigned8 fill0[3];
Unsigned8 kip_sys_calls;
Unsigned8 fill1[3];
/* the following stuff is undocumented; we assume that the kernel
info page is located at offset 0x1000 into the L4 kernel boot
image so that these declarations are consistent with section 2.9
of the L4 Reference Manual */
/* 0x10 */
Mword sched_granularity;
Mword _res1[3];
/* 0x20 */
Mword sigma0_sp, sigma0_ip;
Mword _res2[2];
/* 0x30 */
Mword sigma1_sp, sigma1_ip;
Mword _res3[2];
/* 0x40 */
Mword root_sp, root_ip;
Mword _res4[2];
/* 0x50 */
Mword _res_50;
Mword _mem_info;
Mword _res_58[2];
/* 0x60 */
Mword _res5[16];
/* 0xA0 */
volatile Cpu_time clock;
Unsigned64 _res6;
/* 0xB0 */
Mword frequency_cpu;
Mword frequency_bus;
/* 0xB8 */
Mword _res7[10];
/* 0xE0 */
Mword user_ptr;
Mword vhw_offset;
Unsigned32 _res8[2];
/* 0xF0 */
Unsigned32 __reserved[20];
};
//---------------------------------------------------------------------------
IMPLEMENTATION [sparc && debug]:
IMPLEMENT inline
void
Kip::debug_print_syscalls() const
{}

View File

@@ -0,0 +1,147 @@
INTERFACE [svm]:
#include "l4_types.h"
// TODO: Make this sharable with user-land (see uarts)
struct Vmcb_control_area
{
Unsigned16 intercept_rd_crX;
Unsigned16 intercept_wr_crX;
Unsigned16 intercept_rd_drX;
Unsigned16 intercept_wr_drX;
Unsigned32 intercept_exceptions;
Unsigned32 intercept_instruction0;
Unsigned32 intercept_instruction1;
Unsigned8 _reserved0[44];
Unsigned64 iopm_base_pa;
Unsigned64 msrpm_base_pa;
Unsigned64 tsc_offset;
Unsigned64 guest_asid_tlb_ctl;
Unsigned64 interrupt_ctl;
Unsigned64 interrupt_shadow;
Unsigned64 exitcode;
Unsigned64 exitinfo1;
Unsigned64 exitinfo2;
Unsigned64 exitintinfo;
Unsigned64 np_enable;
Unsigned8 _reserved1[16];
Unsigned64 eventinj;
Unsigned64 n_cr3;
Unsigned64 lbr_virtualization_enable;
Unsigned8 _reserved2[832];
} __attribute__((packed));
struct Vmcb_state_save_area
{
Unsigned16 es_sel;
Unsigned16 es_attrib;
Unsigned32 es_limit;
Unsigned64 es_base;
Unsigned16 cs_sel;
Unsigned16 cs_attrib;
Unsigned32 cs_limit;
Unsigned64 cs_base;
Unsigned16 ss_sel;
Unsigned16 ss_attrib;
Unsigned32 ss_limit;
Unsigned64 ss_base;
Unsigned16 ds_sel;
Unsigned16 ds_attrib;
Unsigned32 ds_limit;
Unsigned64 ds_base;
Unsigned16 fs_sel;
Unsigned16 fs_attrib;
Unsigned32 fs_limit;
Unsigned64 fs_base;
Unsigned16 gs_sel;
Unsigned16 gs_attrib;
Unsigned32 gs_limit;
Unsigned64 gs_base;
Unsigned16 gdtr_sel;
Unsigned16 gdtr_attrib;
Unsigned32 gdtr_limit;
Unsigned64 gdtr_base;
Unsigned16 ldtr_sel;
Unsigned16 ldtr_attrib;
Unsigned32 ldtr_limit;
Unsigned64 ldtr_base;
Unsigned16 idtr_sel;
Unsigned16 idtr_attrib;
Unsigned32 idtr_limit;
Unsigned64 idtr_base;
Unsigned16 tr_sel;
Unsigned16 tr_attrib;
Unsigned32 tr_limit;
Unsigned64 tr_base;
Unsigned8 _reserved0[43];
Unsigned8 cpl;
Unsigned32 _reserved1;
Unsigned64 efer;
Unsigned8 _reserved2[112];
Unsigned64 cr4;
Unsigned64 cr3;
Unsigned64 cr0;
Unsigned64 dr7;
Unsigned64 dr6;
Unsigned64 rflags;
Unsigned64 rip;
Unsigned8 _reserved3[88];
Unsigned64 rsp;
Unsigned8 _reserved4[24];
Unsigned64 rax;
Unsigned64 star;
Unsigned64 lstar;
Unsigned64 cstar;
Unsigned64 sfmask;
Unsigned64 kernelgsbase;
Unsigned64 sysenter_cs;
Unsigned64 sysenter_esp;
Unsigned64 sysenter_eip;
Unsigned64 cr2;
Unsigned8 _reserved5[32];
Unsigned64 g_pat;
Unsigned64 dbgctl;
Unsigned64 br_from;
Unsigned64 br_to;
Unsigned64 lastexcpfrom;
Unsigned64 last_excpto;
Unsigned8 _reserved6[2408];
} __attribute__((packed));
struct Vmcb
{
unsigned np_enabled() const { return control_area.np_enable & 1; }
Vmcb_control_area control_area;
Vmcb_state_save_area state_save_area;
} __attribute__((packed));

View File

@@ -0,0 +1,37 @@
# -*- makefile -*-
# Boot Makefile
# Add future prerequisites somewhere among the list of libraries.
# You really should not have to add anything in the $(LD) line.
boot_img.o: boot_img.x2 boot_img.ren_syms
$(LINK_MESSAGE)
$(VERBOSE)$(OBJCOPY) --redefine-syms=boot_img.ren_syms $< $@
boot_img.ren_syms: boot_img.x2
$(LINK_MESSAGE)
$(VERBOSE)$(NM) -u $^ | perl -n -e 'if (/^\s*U\s+bootstrap_(.*)$$/) { print "bootstrap_$$1 $$1\n"; }' > $@
boot_img.x1: $(OBJ_BOOT) $(DRIVERS) $(MINILIBC)
$(LINK_MESSAGE)
$(VERBOSE)$(LD) -m $(LD_EMULATION) -r -s -o $@ \
-T $(srcdir)/boot/amd64/bootstrap.ld $^ $(LIBGCC)
boot_img.x2: boot_img.x1
$(LINK_MESSAGE)
$(VERBOSE)$(OBJCOPY) --prefix-alloc-sections=.bootstrap --prefix-symbols=bootstrap_ -G bootstrap__boot_start $^ $@
kernel.amd64.lds: linking.h
$(KERNEL): kernel.amd64.lds boot_img.o $(CRT0) $(OBJ_KERNEL) $(JDB) $(LIBK) $(KERNEL_EXTRA_LIBS) $(ABI) $(JABI) libdrivers.a $(CXXLIB) $(LIBKERN) $(MINILIBC) libgluedriverslibc.a
$(LINK_MESSAGE)
$(VERBOSE)$(LD) -m elf_x86_64 -N -T $< -gc-sections \
-o $@ $(filter-out $<,$+) $(LIBGCC) $(KERNEL_UNRES_SYMS)
$(BOOT): $(KERNEL)
$(LINK_MESSAGE)
$(VERBOSE)$(STRIP) -o $@ $<
$(VERBOSE)chmod 755 $@
$(VERBOSE)ln -sf $@ fiasco

View File

@@ -0,0 +1,21 @@
/* -*- c -*- */
.globl _boot_start
.p2align 4
_boot_start:
lea _stack,%rsp
push $0 /* no return address */
jmp bootstrap
.align 4
.p2align(2), 0x90
.long 0x1BADB002 /* magic */
.long 0x00000000 /* feature flags */
.long 0 - 0x1BADB002
.bss
.align 8
.space 4096
_stack:

View File

@@ -0,0 +1,634 @@
#include <cassert>
#include <cstring>
#include <cstdio>
#include "types.h"
#include "boot_cpu.h"
#include "boot_paging.h"
#include "mem_layout.h"
#include "processor.h"
#include "regdefs.h"
enum
{
PML4ESHIFT = 38,
PML4EMASK = 0x1ff,
PDPESHIFT = 30,
PDPEMASK = 0x1ff,
PDESHIFT = 21,
PDEMASK = 0x1ff,
PTESHIFT = 12,
PTEMASK = 0x1ff,
INTEL_PTE_VALID = 0x0000000000000001LL,
INTEL_PTE_WRITE = 0x0000000000000002LL,
INTEL_PTE_USER = 0x0000000000000004LL,
INTEL_PTE_WTHRU = 0x00000008,
INTEL_PTE_NCACHE = 0x00000010,
INTEL_PTE_REF = 0x00000020,
INTEL_PTE_MOD = 0x00000040,
INTEL_PTE_GLOBAL = 0x00000100,
INTEL_PTE_AVAIL = 0x00000e00,
INTEL_PTE_PFN = 0x000ffffffffff000LL,
INTEL_PDE_VALID = 0x0000000000000001LL,
INTEL_PDE_WRITE = 0x0000000000000002LL,
INTEL_PDE_USER = 0x0000000000000004LL,
INTEL_PDE_WTHRU = 0x00000008,
INTEL_PDE_NCACHE = 0x00000010,
INTEL_PDE_REF = 0x00000020,
INTEL_PDE_MOD = 0x00000040,
INTEL_PDE_SUPERPAGE = 0x0000000000000080LL,
INTEL_PDE_GLOBAL = 0x00000100,
INTEL_PDE_AVAIL = 0x00000e00,
INTEL_PDE_PFN = 0x000ffffffffff000LL,
INTEL_PDPE_VALID = 0x0000000000000001LL,
INTEL_PDPE_WRITE = 0x0000000000000002LL,
INTEL_PDPE_USER = 0x0000000000000004LL,
INTEL_PDPE_PFN = 0x000ffffffffff000LL,
INTEL_PML4E_VALID = 0x0000000000000001LL,
INTEL_PML4E_WRITE = 0x0000000000000002LL,
INTEL_PML4E_USER = 0x0000000000000004LL,
INTEL_PML4E_PFN = 0x000ffffffffff000LL,
CPUF_4MB_PAGES = 0x00000008,
BASE_TSS = 0x08,
KERNEL_DS = 0x18,
KERNEL_CS_64 = 0x20, // XXX
DBF_TSS = 0x28, // XXX check this value
ACC_TSS = 0x09,
ACC_TSS_BUSY = 0x02,
ACC_CODE_R = 0x1a,
ACC_DATA_W = 0x12,
ACC_PL_K = 0x00,
ACC_P = 0x80,
SZ_32 = 0x4,
SZ_16 = 0x0,
SZ_G = 0x8,
SZ_CODE_64 = 0x2, // XXX 64 Bit Code Segment
GDTSZ = (0x30/8), // XXX check this value
IDTSZ = 256,
};
struct pseudo_descriptor
{
Unsigned16 pad;
Unsigned16 limit;
Unsigned64 linear_base;
} __attribute__((packed));
struct x86_desc
{
Unsigned16 limit_low;
Unsigned16 base_low;
Unsigned8 base_med;
Unsigned8 access;
Unsigned8 limit_high:4;
Unsigned8 granularity:4;
Unsigned8 base_high;
} __attribute__((packed));
struct idt_desc
{
Unsigned16 offset_low0;
Unsigned16 selector;
Unsigned8 zero_and_ist;
Unsigned8 access;
Unsigned16 offset_low1;
Unsigned32 offset_high;
Unsigned32 ignored;
} __attribute__((packed));
struct x86_tss
{
Unsigned32 ign0;
Unsigned64 rsp0;
Unsigned64 rsp1;
Unsigned64 rsp2;
Unsigned32 ign1;
Unsigned32 ign2;
Unsigned64 ist1;
Unsigned64 ist2;
Unsigned64 ist3;
Unsigned64 ist4;
Unsigned64 ist5;
Unsigned64 ist6;
Unsigned64 ist7;
Unsigned32 ign3;
Unsigned32 ign4;
Unsigned16 ign5;
Unsigned16 io_bit_map_offset;
} __attribute__((packed));
struct idt_init_entry
{
Unsigned64 entrypoint;
Unsigned16 vector;
Unsigned16 type;
} __attribute__((packed));
struct trap_state
{
Unsigned64 rax, rbx, rcx, rdx;
Unsigned64 rdi, rsi, rbp, cr2;
Unsigned64 r8, r9, r10, r11;
Unsigned64 r12, r13, r14, r15;
Unsigned64 trapno, err;
Unsigned64 rip, cs, rflags, rsp, ss;
};
static Unsigned64 cpu_feature_flags;
static Address base_pml4_pa;
static struct x86_tss base_tss;
static struct x86_desc base_gdt[GDTSZ];
static struct idt_desc base_idt[IDTSZ];
static char dbf_stack[2048];
extern "C" void _exit(int code) __attribute__((noreturn));
static inline Unsigned64* find_pml4e(Address pml4_pa, Address la)
{ return (&((Unsigned64*)pml4_pa)[(la >> PML4ESHIFT) & PML4EMASK]); }
static inline Unsigned64* find_pdpe(Address pdp_pa, Address la)
{ return (&((Unsigned64*)pdp_pa)[(la >> PDPESHIFT) & PDPEMASK]); }
static inline Unsigned64* find_pde(Address pdir_pa, Address la)
{ return (&((Unsigned64*)pdir_pa)[(la >> PDESHIFT) & PDEMASK]); }
static inline Unsigned64* find_pte(Address ptab_pa, Address la)
{ return (&((Unsigned64*)ptab_pa)[(la >> PTESHIFT) & PTEMASK]); }
extern inline Unsigned32 get_eflags()
{ Mword efl; asm volatile("pushf \n\t pop %0" : "=r" (efl)); return efl; }
extern inline void set_eflags(Mword efl)
{ asm volatile("push %0 ; popf" : : "r" (efl) : "memory"); }
extern inline void set_ds(Unsigned16 ds)
{ asm volatile("mov %w0,%%ds" : : "r" (ds)); }
extern inline void set_es(Unsigned16 es)
{ asm volatile("mov %w0,%%es" : : "r" (es)); }
extern inline void set_fs(Unsigned16 fs)
{ asm volatile("mov %w0,%%fs" : : "r" (fs)); }
extern inline void set_gs(Unsigned16 gs)
{ asm volatile("mov %w0,%%gs" : : "r" (gs)); }
extern inline void set_ss(Unsigned16 ss)
{ asm volatile("mov %w0,%%ss" : : "r" (ss)); }
extern inline Unsigned16 get_ss()
{ Unsigned16 ss; asm volatile("mov %%ss,%w0" : "=r" (ss)); return ss; }
#define set_idt(pseudo_desc) \
asm volatile("lidt %0" : : "m"((pseudo_desc)->limit), "m"(*pseudo_desc))
#define set_gdt(pseudo_desc) \
asm volatile("lgdt %0" : : "m"((pseudo_desc)->limit), "m"(*pseudo_desc))
#define set_tr(seg) \
asm volatile("ltr %0" : : "rm" ((Unsigned16)(seg)))
#define get_esp() \
({ register Unsigned64 _temp__; \
asm("mov %%rsp, %0" : "=r" (_temp__)); _temp__; })
#define get_cr0() \
({ register Unsigned64 _temp__; \
asm volatile("mov %%cr0, %0" : "=r" (_temp__)); _temp__; })
#define set_cr3(value) \
({ register Unsigned64 _temp__ = (value); \
asm volatile("mov %0, %%cr3" : : "r" (_temp__)); })
#define get_cr4() \
({ register Unsigned64 _temp__; \
asm volatile("mov %%cr4, %0" : "=r" (_temp__)); _temp__; })
#define set_cr4(value) \
({ register Unsigned64 _temp__ = (value); \
asm volatile("mov %0, %%cr4" : : "r" (_temp__)); })
extern inline void enable_longmode()
{ Proc::efer(Proc::efer() | Proc::Efer_lme_flag); }
static inline void
fill_descriptor(struct x86_desc *desc, Unsigned32 base, Unsigned32 limit,
Unsigned8 access, Unsigned8 sizebits)
{
if (limit > 0xfffff)
{
limit >>= 12;
sizebits |= SZ_G;
}
desc->limit_low = limit & 0xffff;
desc->base_low = base & 0xffff;
desc->base_med = (base >> 16) & 0xff;
desc->access = access | ACC_P;
desc->limit_high = limit >> 16;
desc->granularity = sizebits;
desc->base_high = base >> 24;
}
static inline void
fill_idt_desc(struct idt_desc *desc, Unsigned64 offset,
Unsigned16 selector, Unsigned8 access, Unsigned8 ist_entry)
{
desc->offset_low0 = offset & 0x000000000000ffffLL;
desc->selector = selector;
desc->zero_and_ist = ist_entry;
desc->access = access | ACC_P;
desc->offset_low1 = (offset & 0x00000000ffff0000LL) >> 16;
desc->offset_high = (offset & 0xffffffff00000000LL) >> 32;
desc->ignored = 0;
}
inline void ALWAYS_INLINE
paging_enable(Address pml4)
{
/* Enable Physical Address Extension (PAE). */
set_cr4(get_cr4() | CR4_PAE);
/* Load the page map level 4. */
set_cr3(pml4);
/* Enable long mode. */
enable_longmode();
/* Turn on paging and switch to long mode. */
asm volatile("mov %0,%%cr0 ; jmp 1f ; 1:" : : "r" (get_cr0() | CR0_PG));
}
static void
panic(const char *str)
{
printf("\n%s\n", str);
_exit(-1);
}
static void
cpuid()
{
int orig_eflags = get_eflags();
/* Check for a dumb old 386 by trying to toggle the AC flag. */
set_eflags(orig_eflags ^ EFLAGS_AC);
if ((get_eflags() ^ orig_eflags) & EFLAGS_AC)
{
/* It's a 486 or better. Now try toggling the ID flag. */
set_eflags(orig_eflags ^ EFLAGS_ID);
if ((get_eflags() ^ orig_eflags) & EFLAGS_ID)
{
int highest_val, dummy;
asm volatile("cpuid"
: "=a" (highest_val)
: "a" (0) : "ebx", "ecx", "edx");
if (highest_val >= 1)
{
asm volatile("cpuid"
: "=a" (dummy),
"=d" (cpu_feature_flags)
: "a" (1)
: "ebx", "ecx");
}
}
}
set_eflags(orig_eflags);
}
extern "C" struct idt_init_entry boot_idt_inittab[];
static void
base_idt_init(void)
{
struct idt_desc *dst = base_idt;
const struct idt_init_entry *src = boot_idt_inittab;
while (src->entrypoint)
{
fill_idt_desc(&dst[src->vector], src->entrypoint, KERNEL_CS_64,
src->type,(src->vector==8)?1:0);
src++;
}
}
static void
base_gdt_init(void)
{
printf("base_tss @%p\n", &base_tss);
/* Initialize the base TSS descriptor. */
fill_descriptor(&base_gdt[BASE_TSS / 8],
(Address)&base_tss, sizeof(base_tss) - 1,
ACC_PL_K | ACC_TSS, 0);
memset(&base_gdt[(BASE_TSS / 8) + 1], 0, 8);
/* Initialize the 64-bit kernel code and data segment descriptors
to point to the base of the kernel linear space region. */
fill_descriptor(&base_gdt[KERNEL_CS_64 / 8], 0, 0xffffffff,
ACC_PL_K | ACC_CODE_R, SZ_CODE_64);
fill_descriptor(&base_gdt[KERNEL_DS / 8], 0, 0xffffffff,
ACC_PL_K | ACC_DATA_W, SZ_32);
}
static void
base_tss_init(void)
{
base_tss.rsp0 = get_esp(); /* only temporary */
base_tss.ist1 = (Unsigned64)(dbf_stack + sizeof(dbf_stack));
base_tss.io_bit_map_offset = sizeof(base_tss);
}
static void
base_gdt_load(void)
{
struct pseudo_descriptor pdesc;
/* Create a pseudo-descriptor describing the GDT. */
pdesc.limit = sizeof(base_gdt) - 1;
pdesc.linear_base = (Address)&base_gdt;
/* Load it into the CPU. */
set_gdt(&pdesc);
// XXX must be fixed
/* Reload all the segment registers from the new GDT. */
asm volatile (
"movabsq $1f, %%rax \n"
"pushq %%rbx \n"
"pushq %%rax \n"
"lretq \n"
"1: \n"
:
: "b" (KERNEL_CS_64)
: "rax", "memory");
set_ds(KERNEL_DS);
set_es(KERNEL_DS);
set_ss(KERNEL_DS);
set_fs(0);
set_gs(0);
}
static void
base_idt_load(void)
{
struct pseudo_descriptor pdesc;
/* Create a pseudo-descriptor describing the GDT. */
pdesc.limit = sizeof(base_idt) - 1;
pdesc.linear_base = (Address)&base_idt;
set_idt(&pdesc);
}
static void
base_tss_load(void)
{
/* Make sure the TSS isn't marked busy. */
base_gdt[BASE_TSS / 8].access &= ~ACC_TSS_BUSY;
asm volatile ("" : : : "memory");
set_tr(BASE_TSS);
}
void
base_cpu_setup(void)
{
cpuid();
base_idt_init();
base_gdt_init();
base_tss_init();
// force tables to memory before loading segment registers
asm volatile ("" : : : "memory");
base_gdt_load();
base_idt_load();
base_tss_load();
}
static void
ptab_alloc(Address *out_ptab_pa)
{
static char pool[69<<12] __attribute__((aligned(4096)));
static Address pdirs;
static int initialized;
if (! initialized)
{
initialized = 1;
memset(pool, 0, sizeof(pool));
pdirs = ((Address)pool + PAGE_SIZE - 1) & ~PAGE_MASK;
}
if (pdirs > (Address)pool + sizeof(pool))
panic("Cannot allocate page table -- increase ptab_alloc::pool");
*out_ptab_pa = pdirs;
pdirs += PAGE_SIZE;
}
static void
pdir_map_range(Address pml4_pa, Address la, Address pa,
Unsigned32 size, Unsigned32 mapping_bits)
{
assert(la+size-1 > la); // avoid 4GB wrap around
while (size > 0)
{
Unsigned64 *pml4e = find_pml4e(pml4_pa, la);
/* Create new pml4e with corresponding pdp (page directory pointer)
* if no valid entry exists. */
if (!(*pml4e & INTEL_PML4E_VALID))
{
Address pdp_pa;
/* Allocate new page for pdp. */
ptab_alloc(&pdp_pa);
/* Set the pml4 to point to it. */
*pml4e = (pdp_pa & INTEL_PML4E_PFN)
| INTEL_PML4E_VALID | INTEL_PML4E_USER | INTEL_PML4E_WRITE;
}
do
{
Unsigned64 *pdpe = find_pdpe(*pml4e & INTEL_PML4E_PFN, la);
/* Create new pdpe with corresponding pd (page directory)
* if no valid entry exists. */
if (!(*pdpe & INTEL_PDPE_VALID))
{
Address pd_pa;
/* Allocate new page for pd. */
ptab_alloc(&pd_pa);
/* Set the pdpe to point to it. */
*pdpe = (pd_pa & INTEL_PDPE_PFN)
| INTEL_PDPE_VALID | INTEL_PDPE_USER | INTEL_PDPE_WRITE;
}
do
{
Unsigned64 *pde = find_pde(*pdpe & INTEL_PDPE_PFN, la);
/* Use a 2MB page if we can. */
if (superpage_aligned(la) && superpage_aligned(pa)
&& (size >= SUPERPAGE_SIZE))
//&& (cpu_feature_flags & CPUF_4MB_PAGES)) XXX
{
/* a failed assertion here may indicate a memory wrap
around problem */
assert(!(*pde & INTEL_PDE_VALID));
/* XXX what if an empty page table exists
from previous finer-granularity mappings? */
*pde = pa | mapping_bits | INTEL_PDE_SUPERPAGE;
la += SUPERPAGE_SIZE;
pa += SUPERPAGE_SIZE;
size -= SUPERPAGE_SIZE;
}
else
{
/* Find the page table, creating one if necessary. */
if (!(*pde & INTEL_PDE_VALID))
{
Address ptab_pa;
/* Allocate a new page table. */
ptab_alloc(&ptab_pa);
/* Set the pde to point to it. */
*pde = (ptab_pa & INTEL_PTE_PFN)
| INTEL_PDE_VALID | INTEL_PDE_USER | INTEL_PDE_WRITE;
}
assert(!(*pde & INTEL_PDE_SUPERPAGE));
/* Use normal 4KB page mappings. */
do
{
Unsigned64 *pte = find_pte(*pde & INTEL_PDE_PFN, la);
assert(!(*pte & INTEL_PTE_VALID));
/* Insert the mapping. */
*pte = pa | mapping_bits;
/* Advance to the next page. */
//pte++;
la += PAGE_SIZE;
pa += PAGE_SIZE;
size -= PAGE_SIZE;
}
while ((size > 0) && !superpage_aligned(la));
}
}
while ((size > 0) && !pd_aligned(la));
}
while ((size > 0) && !pdp_aligned(la));
}
}
void
base_paging_init(void)
{
ptab_alloc(&base_pml4_pa);
// Establish one-to-one mappings for the first 4MB of physical memory
pdir_map_range(base_pml4_pa, /*virt*/0, /*phys*/0, /*size*/4 << 20,
INTEL_PDE_VALID | INTEL_PDE_WRITE | INTEL_PDE_USER);
// map in the first 4MB of physical memory to 0xfffffffff0000000
pdir_map_range(base_pml4_pa, Mem_layout::Kernel_image,
Mem_layout::Kernel_image_phys,
Mem_layout::Kernel_image_end - Mem_layout::Kernel_image,
INTEL_PDE_VALID | INTEL_PDE_WRITE | INTEL_PDE_USER);
// Adapter memory needs a seperate mapping
if (!Mem_layout::Adap_in_kernel_image)
// map in the adapter memory (superpage) of physical memory to ...
pdir_map_range(base_pml4_pa, /*virt*/Mem_layout::Adap_image,
/*phys*/Mem_layout::Adap_image_phys,
/*size*/Config::SUPERPAGE_SIZE,
INTEL_PDE_VALID | INTEL_PDE_WRITE | INTEL_PDE_USER);
// XXX Turn on paging and activate 64Bit mode
paging_enable(base_pml4_pa);
}
void
base_map_physical_memory_for_kernel()
{
unsigned long sz = Mem_layout::pmem_size;
printf("map pmem %14lx-%14lx to %14lx-%14lx\n",
Mem_layout::pmem_to_phys(Mem_layout::Physmem),
Mem_layout::pmem_to_phys(Mem_layout::Physmem) + sz,
Mem_layout::Physmem,
Mem_layout::Physmem + sz);
// map in the last 60MB of physical memory to 0xfc400000
pdir_map_range(base_pml4_pa,
/*virt*/Mem_layout::Physmem,
/*phys*/Mem_layout::pmem_to_phys(Mem_layout::Physmem),
/*size*/sz,
INTEL_PDE_VALID | INTEL_PDE_WRITE | INTEL_PDE_USER);
}
extern "C" void
trap_dump_panic(const struct trap_state *st)
{
int from_user = (st->cs & 3);
int i;
printf("RAX %016llx RBX %016llx\n", st->rax, st->rbx);
printf("RCX %016llx RDX %016llx\n", st->rcx, st->rdx);
printf("RSI %016llx RDI %016llx\n", st->rsi, st->rdi);
printf("RBP %016llx RSP %016llx\n",
st->rbp, from_user ? st->rsp : (Address)&st->rsp);
printf("R8 %016llx R9 %016llx\n", st->r8, st->r9);
printf("R10 %016llx R11 %016llx\n", st->r10, st->r11);
printf("R12 %016llx R13 %016llx\n", st->r12, st->r13);
printf("R14 %016llx R15 %016llx\n", st->r14, st->r15);
printf("RIP %016llx RFLAGS %016llx\n", st->rip, st->rflags);
printf("CS %04llx SS %04llx\n",
st->cs & 0xffff, from_user ? st->ss & 0xffff : get_ss());
printf("trapno %lld, error %08llx, from %s mode\n",
st->trapno, st->err, from_user ? "user" : "kernel");
if (st->trapno == 0x0d)
{
if (st->err & 1)
printf("(external event");
else
printf("(internal event");
if (st->err & 2)
{
printf(" regarding IDT gate descriptor no. 0x%02llx)\n",
st->err >> 3);
}
else
{
printf(" regarding %s entry no. 0x%02llx)\n",
st->err & 4 ? "LDT" : "GDT", st->err >> 3);
}
}
else if (st->trapno == 0x0e)
printf("page fault linear address %016llx\n", st->cr2);
if (!from_user)
{
for (i = 0; i < 32; i++)
printf("%016llx%c", (&st->rsp)[i], ((i & 7) == 7) ? '\n' : ' ');
}
panic("Unexpected trap while booting Fiasco!");
}

View File

@@ -0,0 +1,99 @@
#define GATE_INITTAB_BEGIN(name) \
.text 1 ;\
.globl name ;\
name: ;\
.text
#define GATE_ENTRY(n,entry,type) \
.text 1 ;\
.quad entry ;\
.word n ;\
.word type ;\
.text
#define GATE_INITTAB_END \
.text 1 ;\
.quad 0 ;\
.text
#define EXCEPTION(n,name) \
GATE_ENTRY(n,name,0x0e) ;\
name: ;\
push $(0) ;\
push $(n) ;\
jmp alltraps
#define EXCEP_USR(n,name) \
GATE_ENTRY(n,name,0x6e) ;\
name: ;\
push $(0) ;\
push $(n) ;\
jmp alltraps
#define EXCEP_ERR(n,name) \
GATE_ENTRY(n,name,0x0e) ;\
name: ;\
push $(n) ;\
jmp alltraps
GATE_INITTAB_BEGIN(boot_idt_inittab)
EXCEPTION(0x00,t_zero_div)
EXCEPTION(0x01,t_debug)
EXCEPTION(0x02,t_nmi)
EXCEP_USR(0x03,t_int3)
EXCEP_USR(0x04,t_into)
EXCEP_USR(0x05,t_bounds)
EXCEPTION(0x06,t_invop)
EXCEPTION(0x07,t_nofpu)
EXCEPTION(0x08,t_double_fault)
EXCEPTION(0x09,a_fpu_over)
EXCEP_ERR(0x0a,a_inv_tss)
EXCEP_ERR(0x0b,t_segnp)
EXCEP_ERR(0x0c,t_stack_fault)
EXCEP_ERR(0x0d,t_gen_prot)
EXCEP_ERR(0x0e,t_page_fault)
EXCEPTION(0x0f,t_trap_0f)
EXCEPTION(0x10,t_fpu_err)
EXCEPTION(0x11,t_trap_11)
EXCEPTION(0x12,t_trap_12)
EXCEPTION(0x13,t_trap_13)
EXCEPTION(0x14,t_trap_14)
EXCEPTION(0x15,t_trap_15)
EXCEPTION(0x16,t_trap_16)
EXCEPTION(0x17,t_trap_17)
EXCEPTION(0x18,t_trap_18)
EXCEPTION(0x19,t_trap_19)
EXCEPTION(0x1a,t_trap_1a)
EXCEPTION(0x1b,t_trap_1b)
EXCEPTION(0x1c,t_trap_1c)
EXCEPTION(0x1d,t_trap_1d)
EXCEPTION(0x1e,t_trap_1e)
EXCEPTION(0x1f,t_trap_1f)
GATE_INITTAB_END
alltraps:
push %r15
push %r14
push %r13
push %r12
push %r11
push %r10
push %r9
push %r8
mov %cr2,%r8
push %r8
push %rbp
push %rsi
push %rdi
push %rdx
push %rcx
push %rbx
push %rax
call trap_dump_panic

View File

@@ -0,0 +1,39 @@
#ifndef BOOT_PAGING_H
#define BOOT_PAGING_H
#include "types.h"
enum
{
PAGE_SIZE = (1 << 12),
PAGE_MASK = (PAGE_SIZE - 1),
SUPERPAGE_SIZE = (1 << 21),
SUPERPAGE_MASK = (SUPERPAGE_SIZE - 1),
PD_SIZE = (1 << 30),
PD_MASK = (PD_SIZE - 1),
PDP_SIZE = (1LL << 39),
PDP_MASK = (PDP_SIZE - 1),
};
static inline int
superpage_aligned(Address x)
{ return (x & SUPERPAGE_MASK) == 0; }
static inline int
pd_aligned(Address x)
{ return (x & PD_MASK) == 0; }
static inline int
pdp_aligned(Address x)
{ return (x & PDP_MASK) == 0; }
static inline Address trunc_page(Address x)
{ return x & ~PAGE_MASK; }
static inline Address round_page(Address x)
{ return (x + PAGE_MASK) & ~PAGE_MASK; }
static inline Address round_superpage(Address x)
{ return (x + SUPERPAGE_MASK) & ~SUPERPAGE_MASK; }
#endif

View File

@@ -0,0 +1,19 @@
FORCE_COMMON_ALLOCATION
SECTIONS
{
.text :
{
*(.init)
*(.text .text.* .gnu.linkonce.t.*)
*(.fini)
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.data .data.* .gnu.linkonce.d.*)
*(.anno)
} = 0x90909090
.bss :
{
*(.bss .gnu.linkonce.b.* COMMON)
}
}

View File

@@ -0,0 +1,23 @@
# -*- makefile -*-
# Boot Makefile
# Add future prerequisites somewhere among the list of libraries.
# You really should not have to add anything in the $(LD) line.
$(BOOT): $(BOOT).elf
$(OBJCOPY) -O binary $< $@
chmod 755 $@
ln -sf $@ fiasco
$(call INSTALLFILE_RULE,fiasco,fiasco)
$(BOOT).elf: $(KERNEL)
cp $(KERNEL) $(BOOT).elf
$(STRIP) $(BOOT).elf
%.img.o: %.elf
$(OBJCOPY) -S $< $*
$(OBJCOPY) -B arm -I binary -O elf32-littlearm $* $@
kernel.o: $(KERNEL)
$(OBJCOPY) -S $(KERNEL) $(@:.o=)
$(OBJCOPY) -B arm -I binary -O elf32-littlearm $(@:.o=) $@

View File

@@ -0,0 +1,10 @@
#ifndef BOOT_CPU_H
#define BOOT_CPU_H
#include "types.h"
void base_paging_init (void);
void base_map_physical_memory_for_kernel ();
void base_cpu_setup (void);
#endif

View File

@@ -0,0 +1,6 @@
#ifndef BOOT_DIRECT_CONS_H
#define BOOT_DIRECT_CONS_H
void direct_cons_putchar(unsigned char c);
#endif

View File

@@ -0,0 +1,17 @@
#include <libc_backend.h>
#include "boot_direct_cons.h"
unsigned long __libc_backend_printf_lock()
{ return 0; }
void __libc_backend_printf_unlock(unsigned long)
{}
int __libc_backend_outs(const char *s, size_t len)
{
size_t i = 0;
for (; i < len; ++i)
direct_cons_putchar(s[i]);
return 1;
}

View File

@@ -0,0 +1,107 @@
/* this code is run directly from boot.S. our task is to setup the
paging just enough so that L4 can run in its native address space
at 0xf0001000, and then start up L4. */
#include <cassert>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include "boot_cpu.h"
#include "boot_paging.h"
#include "boot_console.h"
#include "kernel_console.h"
#include "checksum.h"
#include "config.h"
#include "globalconfig.h"
#include "kip.h"
#include "kmem_alloc.h"
#include "mem_layout.h"
#include "mem_region.h"
#include "panic.h"
#include "processor.h"
#include "reset.h"
struct check_sum
{
char delimiter[16];
Unsigned32 checksum_ro;
Unsigned32 checksum_rw;
} check_sum = {"FIASCOCHECKSUM=", 0, 0};
extern "C" char _start[];
extern "C" char _end[];
extern "C" void exit(int rc) __attribute__((noreturn));
void
exit(int)
{
for (;;)
Proc::pause();
}
// test if [start1..end1-1] overlaps [start2..end2-1]
static
void
check_overlap (const char *str,
Address start1, Address end1, Address start2, Address end2)
{
if ((start1 >= start2 && start1 < end2) || (end1 > start2 && end1 <= end2))
panic("Kernel [0x%014lx,0x%014lx) overlaps %s [0x%014lx,0x%014lx).",
start1, end1, str, start2, end2);
}
typedef void (*Start)(void *, unsigned, unsigned) FIASCO_FASTCALL;
extern "C" FIASCO_FASTCALL
void
bootstrap (void *, unsigned int flag)
{
extern Kip my_kernel_info_page;
Start start;
// setup stuff for base_paging_init()
base_cpu_setup();
// now do base_paging_init(): sets up paging with one-to-one mapping
base_paging_init();
asm volatile ("" ::: "memory");
Kip::init_global_kip(&my_kernel_info_page);
Kconsole::init();
Boot_console::init();
printf("Boot: KIP @ %p\n", Kip::k());
printf("Boot: Kmem_alloc::base_init();\n");
if (!Kmem_alloc::base_init())
{
panic("FATAL: Could not reserve kernel memory, halted\n");
}
printf("Boot: kernel memory reserved\n");
// make sure that we did not forgot to discard an unused header section
// (compare "objdump -p fiasco.image")
if ((Address)_start < Mem_layout::Kernel_image)
panic("Fiasco kernel occupies memory below %014lx",
(unsigned long)Mem_layout::Kernel_image);
if ((Address)&_end - Mem_layout::Kernel_image > 4<<20)
panic("Fiasco boot system occupies more than 4MB");
base_map_physical_memory_for_kernel();
start = (Start)_start;
Address phys_start = (Address)_start - Mem_layout::Kernel_image + Mem_layout::Kernel_image_phys;
Address phys_end = (Address)_end - Mem_layout::Kernel_image + Mem_layout::Kernel_image_phys;
check_overlap ("VGA/IO", phys_start, phys_end, 0xa0000, 0x100000);
if (Checksum::get_checksum_ro() != check_sum.checksum_ro)
panic("Read-only (text) checksum does not match.");
if (Checksum::get_checksum_rw() != check_sum.checksum_rw)
panic("Read-write (data) checksum does not match.");
start (0, flag, check_sum.checksum_ro);
}

View File

@@ -0,0 +1,44 @@
#include <string.h>
#include "boot_direct_cons.h"
#include "boot_paging.h"
void
direct_cons_putchar(unsigned char c)
{
static int ofs = -1;
unsigned char *vidbase = ((unsigned char*)0xb8000);
if (ofs < 0)
{
ofs = 0;
direct_cons_putchar('\n');
}
switch (c)
{
case '\n':
memcpy(vidbase, vidbase+80*2, 80*2*24);
memset(vidbase+80*2*24,0, 80*2);
/* fall through... */
case '\r':
ofs = 0;
break;
case '\t':
ofs = (ofs + 8) & ~7;
break;
default:
if (ofs >= 80)
direct_cons_putchar('\n');
{
volatile unsigned char *p = vidbase + 80*2*24 + ofs*2;
p[0] = c;
p[1] = 0x0f;
ofs++;
}
break;
}
}

View File

@@ -0,0 +1,43 @@
# -*- makefile -*-
# Boot Makefile
# Add future prerequisites somewhere among the list of libraries.
# You really should not have to add anything in the $(LD) line.
#
# Don't link against libgcc because of -mregparm=3. The library
# would only be necessary for 64-bit arithmetics. These functions
# can be replaced by using div32/mod32 from lib/libk (and should
# for efficency reasons).
boot_img.o: boot_img.x2 boot_img.ren_syms
$(LINK_MESSAGE)
$(VERBOSE)$(OBJCOPY) --redefine-syms=boot_img.ren_syms $< $@
boot_img.ren_syms: boot_img.x2
$(LINK_MESSAGE)
$(VERBOSE)$(NM) -u $^ | perl -n -e 'if (/^\s*U\s+bootstrap_(.*)$$/) { print "bootstrap_$$1 $$1\n"; }' > $@
boot_img.x1: $(OBJ_BOOT) $(DRIVERS) $(MINILIBC)
$(LINK_MESSAGE)
$(VERBOSE)$(LD) -m $(LD_EMULATION) -r -s -o $@ \
-T $(srcdir)/boot/ia32/bootstrap.ld $^ $(LIBGCC)
boot_img.x2: boot_img.x1
$(LINK_MESSAGE)
$(VERBOSE)$(OBJCOPY) --prefix-alloc-sections=.bootstrap --prefix-symbols=bootstrap_ -G bootstrap__boot_start $^ $@
kernel.ia32.lds: linking.h
$(KERNEL): kernel.ia32.lds boot_img.o $(CRT0) $(OBJ_KERNEL) $(JDB) $(LIBK) $(KERNEL_EXTRA_LIBS) $(ABI) $(JABI) libdrivers.a $(CXXLIB) $(LIBKERN) $(MINILIBC) libgluedriverslibc.a
$(LINK_MESSAGE)
$(VERBOSE)$(LD) -m $(LD_EMULATION) -N -o $@ \
-T $< -gc-sections $(filter-out $<,$+) \
$(KERNEL_UNRES_SYMS)
$(BOOT): $(KERNEL)
$(LINK_MESSAGE)
$(VERBOSE)$(STRIP) -o $@ $<
$(VERBOSE)chmod 755 $@
$(VERBOSE)ln -sf $@ fiasco

View File

@@ -0,0 +1,19 @@
/* -*- c -*- */
.globl _boot_start
_boot_start:
leal _stack,%esp
movl %eax,%edx /* mbinfo_flag */
movl %ebx,%eax /* mbinfo */
pushl $0 /* no return address */
jmp bootstrap
.align 4, 0x90
.long 0x1BADB002 /* magic */
.long 0x00000000 /* feature flags */
.long 0 - 0x1BADB002
.bss
.space 1024
_stack:

View File

@@ -0,0 +1,561 @@
#include <cassert>
#include <cstring>
#include <cstdio>
#include "types.h"
#include "boot_cpu.h"
#include "boot_paging.h"
#include "mem_layout.h"
#include "panic.h"
#include "regdefs.h"
enum
{
PDESHIFT = 22,
PDEMASK = 0x3ff,
PTESHIFT = 12,
PTEMASK = 0x3ff,
INTEL_PTE_VALID = 0x00000001,
INTEL_PTE_WRITE = 0x00000002,
INTEL_PTE_USER = 0x00000004,
INTEL_PTE_WTHRU = 0x00000008,
INTEL_PTE_NCACHE = 0x00000010,
INTEL_PTE_REF = 0x00000020,
INTEL_PTE_MOD = 0x00000040,
INTEL_PTE_GLOBAL = 0x00000100,
INTEL_PTE_AVAIL = 0x00000e00,
INTEL_PTE_PFN = 0xfffff000,
INTEL_PDE_VALID = 0x00000001,
INTEL_PDE_WRITE = 0x00000002,
INTEL_PDE_USER = 0x00000004,
INTEL_PDE_WTHRU = 0x00000008,
INTEL_PDE_NCACHE = 0x00000010,
INTEL_PDE_REF = 0x00000020,
INTEL_PDE_MOD = 0x00000040,
INTEL_PDE_SUPERPAGE = 0x00000080,
INTEL_PDE_GLOBAL = 0x00000100,
INTEL_PDE_AVAIL = 0x00000e00,
INTEL_PDE_PFN = 0xfffff000,
CPUF_4MB_PAGES = 0x00000008,
BASE_TSS = 0x08,
KERNEL_CS = 0x10,
KERNEL_DS = 0x18,
DBF_TSS = 0x20,
ACC_TSS = 0x09,
ACC_TSS_BUSY = 0x02,
ACC_CODE_R = 0x1a,
ACC_DATA_W = 0x12,
ACC_PL_K = 0x00,
ACC_P = 0x80,
SZ_32 = 0x4,
SZ_16 = 0x0,
SZ_G = 0x8,
GDTSZ = (0x28/8),
IDTSZ = 0x14,
};
struct pseudo_descriptor
{
Unsigned16 pad;
Unsigned16 limit;
Unsigned32 linear_base;
};
struct x86_desc
{
Unsigned16 limit_low; /* limit 0..15 */
Unsigned16 base_low; /* base 0..15 */
Unsigned8 base_med; /* base 16..23 */
Unsigned8 access; /* access byte */
Unsigned8 limit_high:4; /* limit 16..19 */
Unsigned8 granularity:4; /* granularity */
Unsigned8 base_high; /* base 24..31 */
} __attribute__((packed));
struct x86_gate
{
Unsigned16 offset_low; /* offset 0..15 */
Unsigned16 selector;
Unsigned8 word_count;
Unsigned8 access;
Unsigned16 offset_high; /* offset 16..31 */
} __attribute__((packed));
struct x86_tss
{
Unsigned32 back_link;
Unsigned32 esp0, ss0;
Unsigned32 esp1, ss1;
Unsigned32 esp2, ss2;
Unsigned32 cr3;
Unsigned32 eip, eflags;
Unsigned32 eax, ecx, edx, ebx, esp, ebp, esi, edi;
Unsigned32 es, cs, ss, ds, fs, gs;
Unsigned32 ldt;
Unsigned16 trace_trap;
Unsigned16 io_bit_map_offset;
};
struct gate_init_entry
{
Unsigned32 entrypoint;
Unsigned16 vector;
Unsigned16 type;
};
struct trap_state
{
Unsigned32 gs, fs, es, ds;
Unsigned32 edi, esi, ebp, cr2, ebx, edx, ecx, eax;
Unsigned32 trapno, err;
Unsigned32 eip, cs, eflags, esp, ss;
};
static Unsigned32 cpu_feature_flags;
static Address base_pdir_pa;
static struct x86_tss base_tss;
static struct x86_desc base_gdt[GDTSZ];
static struct x86_gate base_idt[IDTSZ];
static void handle_dbf(void);
static char dbf_stack[2048];
static struct x86_tss dbf_tss =
{
0/*back_link*/,
0/*esp0*/, 0/*ss0*/, 0/*esp1*/, 0/*ss1*/, 0/*esp2*/, 0/*ss2*/,
0/*cr3*/,
(Unsigned32)handle_dbf/*eip*/, 0x00000082/*eflags*/,
0/*eax*/, 0/*ecx*/, 0/*edx*/, 0/*ebx*/,
(Unsigned32)dbf_stack + sizeof(dbf_stack)/*esp*/,
0/*ebp*/, 0/*esi*/, 0/*edi*/,
KERNEL_DS/*es*/, KERNEL_CS/*cs*/, KERNEL_DS/*ss*/,
KERNEL_DS/*ds*/, KERNEL_DS/*fs*/, KERNEL_DS/*gs*/,
0/*ldt*/, 0/*trace_trap*/, 0x8000/*io_bit_map_offset*/
};
extern "C" void _exit(int code) __attribute__((noreturn));
static inline Address* pdir_find_pde(Address pdir_pa, Address la)
{ return (&((Address*)pdir_pa)[(la >> PDESHIFT) & PDEMASK]); }
static inline Address* ptab_find_pte(Address ptab_pa, Address la)
{ return (&((Address*)ptab_pa)[(la >> PTESHIFT) & PTEMASK]); }
extern inline Unsigned32 get_eflags()
{ Unsigned32 efl; asm volatile("pushf ; popl %0" : "=r" (efl)); return efl; }
extern inline void set_eflags(Unsigned32 efl)
{ asm volatile("pushl %0 ; popf" : : "r" (efl) : "memory"); }
extern inline void set_ds(Unsigned16 ds)
{ asm volatile("movw %w0,%%ds" : : "r" (ds)); }
extern inline void set_es(Unsigned16 es)
{ asm volatile("movw %w0,%%es" : : "r" (es)); }
extern inline void set_fs(Unsigned16 fs)
{ asm volatile("movw %w0,%%fs" : : "r" (fs)); }
extern inline void set_gs(Unsigned16 gs)
{ asm volatile("movw %w0,%%gs" : : "r" (gs)); }
extern inline void set_ss(Unsigned16 ss)
{ asm volatile("movw %w0,%%ss" : : "r" (ss)); }
extern inline Unsigned16 get_ss()
{ Unsigned16 ss; asm volatile("movw %%ss,%w0" : "=r" (ss)); return ss; }
#define set_idt(pseudo_desc) \
asm volatile("lidt %0" : : "m"((pseudo_desc)->limit), "m"(*pseudo_desc))
#define set_gdt(pseudo_desc) \
asm volatile("lgdt %0" : : "m"((pseudo_desc)->limit), "m"(*pseudo_desc))
#define set_tr(seg) \
asm volatile("ltr %0" : : "rm"((Unsigned16)(seg)))
#define get_esp() \
({ register Unsigned32 _temp__; \
asm("movl %%esp, %0" : "=r" (_temp__)); _temp__; })
#define get_cr0() \
({ register Unsigned32 _temp__; \
asm volatile("mov %%cr0, %0" : "=r" (_temp__)); _temp__; })
#define get_cr2() \
({ register Unsigned32 _temp__; \
asm volatile("mov %%cr2, %0" : "=r" (_temp__)); _temp__; })
#define set_cr3(value) \
({ register Unsigned32 _temp__ = (value); \
asm volatile("mov %0, %%cr3" : : "r" (_temp__)); })
#define get_cr4() \
({ register Unsigned32 _temp__; \
asm volatile("mov %%cr4, %0" : "=r" (_temp__)); _temp__; })
#define set_cr4(value) \
({ register Unsigned32 _temp__ = (value); \
asm volatile("mov %0, %%cr4" : : "r" (_temp__)); })
static inline void
fill_descriptor(struct x86_desc *desc, Unsigned32 base, Unsigned32 limit,
Unsigned8 access, Unsigned8 sizebits)
{
if (limit > 0xfffff)
{
limit >>= 12;
sizebits |= SZ_G;
}
desc->limit_low = limit & 0xffff;
desc->base_low = base & 0xffff;
desc->base_med = (base >> 16) & 0xff;
desc->access = access | ACC_P;
desc->limit_high = limit >> 16;
desc->granularity = sizebits;
desc->base_high = base >> 24;
}
static inline void
fill_gate(unsigned vector, Unsigned32 offset,
Unsigned16 selector, Unsigned8 access)
{
base_idt[vector].offset_low = offset & 0xffff;
base_idt[vector].selector = selector;
base_idt[vector].word_count = 0;
base_idt[vector].access = access | ACC_P;
base_idt[vector].offset_high = (offset >> 16) & 0xffff;
}
inline void ALWAYS_INLINE
paging_enable(Address pdir)
{
/* Load the page directory. */
set_cr3(pdir);
/* Turn on paging. */
asm volatile("movl %0,%%cr0 ; jmp 1f ; 1:" : : "r" ((get_cr0() & ~0xf0000000) | CR0_PG));
}
static void
cpuid()
{
int orig_eflags = get_eflags();
/* Check for a dumb old 386 by trying to toggle the AC flag. */
set_eflags(orig_eflags ^ EFLAGS_AC);
if ((get_eflags() ^ orig_eflags) & EFLAGS_AC)
{
/* It's a 486 or better. Now try toggling the ID flag. */
set_eflags(orig_eflags ^ EFLAGS_ID);
if ((get_eflags() ^ orig_eflags) & EFLAGS_ID)
{
int highest_val, dummy;
asm volatile("cpuid"
: "=a" (highest_val)
: "a" (0) : "ebx", "ecx", "edx");
if (highest_val >= 1)
{
asm volatile("cpuid"
: "=a" (dummy),
"=d" (cpu_feature_flags)
: "a" (1)
: "ebx", "ecx");
}
}
}
set_eflags(orig_eflags);
}
extern "C" struct gate_init_entry boot_idt_inittab[];
static void
base_idt_init(void)
{
const struct gate_init_entry *src = boot_idt_inittab;
while (src->entrypoint)
{
if ((src->type & 0x1f) == 0x05)
// task gate
fill_gate(src->vector, 0, src->entrypoint, src->type);
else
// interrupt gate
fill_gate(src->vector, src->entrypoint, KERNEL_CS, src->type);
src++;
}
}
static void
base_gdt_init(void)
{
/* Initialize the base TSS descriptor. */
fill_descriptor(&base_gdt[BASE_TSS / 8],
(Address)&base_tss, sizeof(base_tss) - 1,
ACC_PL_K | ACC_TSS, 0);
/* Initialize the TSS descriptor for the double fault handler */
fill_descriptor(&base_gdt[DBF_TSS / 8],
(Address)&dbf_tss, sizeof(dbf_tss) - 1,
ACC_PL_K | ACC_TSS, 0);
/* Initialize the 32-bit kernel code and data segment descriptors
to point to the base of the kernel linear space region. */
fill_descriptor(&base_gdt[KERNEL_CS / 8], 0, 0xffffffff,
ACC_PL_K | ACC_CODE_R, SZ_32);
fill_descriptor(&base_gdt[KERNEL_DS / 8], 0, 0xffffffff,
ACC_PL_K | ACC_DATA_W, SZ_32);
}
static void
base_tss_init(void)
{
base_tss.ss0 = KERNEL_DS;
base_tss.esp0 = get_esp(); /* only temporary */
base_tss.io_bit_map_offset = sizeof(base_tss);
}
static void
base_gdt_load(void)
{
struct pseudo_descriptor pdesc;
/* Create a pseudo-descriptor describing the GDT. */
pdesc.limit = sizeof(base_gdt) - 1;
pdesc.linear_base = (Address)&base_gdt;
/* Load it into the CPU. */
set_gdt(&pdesc);
/* Reload all the segment registers from the new GDT. */
asm volatile("ljmp %0,$1f ; 1:" : : "i" (KERNEL_CS));
set_ds(KERNEL_DS);
set_es(KERNEL_DS);
set_ss(KERNEL_DS);
set_fs(0);
set_gs(0);
}
static void
base_idt_load(void)
{
struct pseudo_descriptor pdesc;
/* Create a pseudo-descriptor describing the GDT. */
pdesc.limit = sizeof(base_idt) - 1;
pdesc.linear_base = (Address)&base_idt;
set_idt(&pdesc);
}
static void
base_tss_load(void)
{
/* Make sure the TSS isn't marked busy. */
base_gdt[BASE_TSS / 8].access &= ~ACC_TSS_BUSY;
set_tr(BASE_TSS);
}
void
base_cpu_setup(void)
{
cpuid();
base_idt_init();
base_gdt_init();
base_tss_init();
// force tables to memory before loading segment registers
asm volatile ("" : : : "memory");
base_gdt_load();
base_idt_load();
base_tss_load();
}
static void
ptab_alloc(Address *out_ptab_pa)
{
static char pool[140<<12] __attribute__((aligned(4096)));
static Address pdirs;
static int initialized;
if (! initialized)
{
initialized = 1;
memset(pool, 0, sizeof(pool));
pdirs = round_page((Address)pool);
}
if (pdirs >= (Address)pool + sizeof(pool))
panic("Cannot allocate page table -- increase ptab_alloc::pool");
*out_ptab_pa = pdirs;
pdirs += PAGE_SIZE;
}
static void
pdir_map_range(Address pdir_pa, Address la, Address pa,
Unsigned32 size, Unsigned32 mapping_bits)
{
while (size > 0)
{
Address *pde = pdir_find_pde(pdir_pa, la);
/* Use a 4MB page if we can. */
if (superpage_aligned(la) && superpage_aligned(pa)
&& (size >= SUPERPAGE_SIZE)
&& (cpu_feature_flags & CPUF_4MB_PAGES))
{
/* a failed assertion here may indicate a memory wrap
around problem */
assert(!(*pde & INTEL_PDE_VALID));
/* XXX what if an empty page table exists
from previous finer-granularity mappings? */
*pde = pa | mapping_bits | INTEL_PDE_SUPERPAGE;
la += SUPERPAGE_SIZE;
pa += SUPERPAGE_SIZE;
size -= SUPERPAGE_SIZE;
}
else
{
Address *pte;
/* Find the page table, creating one if necessary. */
if (!(*pde & INTEL_PDE_VALID))
{
Address ptab_pa;
/* Allocate a new page table. */
ptab_alloc(&ptab_pa);
/* Set the pde to point to it. */
*pde = (ptab_pa & INTEL_PTE_PFN)
| INTEL_PDE_VALID | INTEL_PDE_USER | INTEL_PDE_WRITE;
}
assert(!(*pde & INTEL_PDE_SUPERPAGE));
pte = ptab_find_pte(*pde & INTEL_PDE_PFN, la);
/* Use normal 4KB page mappings. */
do
{
assert(!(*pte & INTEL_PTE_VALID));
/* Insert the mapping. */
*pte = pa | mapping_bits;
/* Advance to the next page. */
pte++;
la += PAGE_SIZE;
pa += PAGE_SIZE;
size -= PAGE_SIZE;
}
while ((size > 0) && !superpage_aligned(la));
}
}
}
void
base_paging_init(void)
{
// We assume that we only have to map the first 4MB page. This has
// to be checked before base_paging_init was called.
ptab_alloc(&base_pdir_pa);
// Establish one-to-one mapping for the first 4MB of physical memory
pdir_map_range(base_pdir_pa, /*virt*/0, /*phys*/0, /*size*/4 << 20,
INTEL_PDE_VALID | INTEL_PDE_WRITE | INTEL_PDE_USER);
// Enable superpage support if we have it
if (cpu_feature_flags & CPUF_4MB_PAGES)
set_cr4(get_cr4() | CR4_PSE);
dbf_tss.cr3 = base_pdir_pa;
// Turn on paging
paging_enable(base_pdir_pa);
// map in the Kernel image (superpage) of physical memory to 0xf0000000
pdir_map_range(base_pdir_pa, /*virt*/Mem_layout::Kernel_image,
Mem_layout::Kernel_image_phys,
/*size*/Mem_layout::Kernel_image_end -
Mem_layout::Kernel_image,
INTEL_PDE_VALID | INTEL_PDE_WRITE | INTEL_PDE_USER);
// Adapter memory is already contrained in the kernel-image mapping
if (Mem_layout::Adap_in_kernel_image)
return;
// map in the adapter memory (superpage) of physical memory to ...
pdir_map_range(base_pdir_pa, /*virt*/Mem_layout::Adap_image,
/*phys*/Mem_layout::Adap_image_phys,
/*size*/Config::SUPERPAGE_SIZE,
INTEL_PDE_VALID | INTEL_PDE_WRITE | INTEL_PDE_USER);
}
void
base_map_physical_memory_for_kernel()
{
unsigned long sz = Mem_layout::pmem_size;
// map in the last 60MB of physical memory to 0xfc400000
pdir_map_range(base_pdir_pa,
/*virt*/Mem_layout::Physmem,
/*phys*/Mem_layout::pmem_to_phys(Mem_layout::Physmem),
/*size*/sz,
INTEL_PDE_VALID | INTEL_PDE_WRITE | INTEL_PDE_USER);
}
static char const * const base_regs =
"\n"
"EAX %08x EBX %08x ECX %08x EDX %08x\n"
"ESI %08x EDI %08x EBP %08x ESP %08x\n"
"EIP %08x EFLAGS %08x\n"
"CS %04x SS %04x DS %04x ES %04x FS %04x GS %04x\n";
extern "C" FIASCO_FASTCALL
void
trap_dump_panic(const struct trap_state *st)
{
int from_user = (st->cs & 3);
int i;
printf(base_regs,
st->eax, st->ebx, st->ecx, st->edx,
st->esi, st->edi, st->ebp, from_user ? st->esp : (Unsigned32)&st->esp,
st->eip, st->eflags,
st->cs & 0xffff, from_user ? st->ss & 0xffff : get_ss(),
st->ds & 0xffff, st->es & 0xffff, st->fs & 0xffff, st->gs & 0xffff);
printf("trapno %d, error %08x, from %s mode\n",
st->trapno, st->err, from_user ? "user" : "kernel");
if (st->trapno == 0x0d)
{
printf("(%sternal event regarding ", st->err & 1 ? "ex" : "in");
if (st->err & 2)
printf("IDT gate descriptor");
else
printf("%cDT entry", st->err & 4 ? 'L' : 'G');
printf(" no. 0x%02x)\n", st->err >> 3);
}
else if (st->trapno == 0x0e)
printf("page fault linear address %08x\n", get_cr2());
if (!from_user)
{
for (i = 0; i < 32; i++)
printf("%08x%c", (&st->esp)[i], ((i & 7) == 7) ? '\n' : ' ');
}
panic("Unexpected trap while booting Fiasco!");
}
static void
handle_dbf()
{
printf(base_regs,
base_tss.eax, base_tss.ebx, base_tss.ecx, base_tss.edx,
base_tss.esi, base_tss.edi, base_tss.ebp, base_tss.esp,
base_tss.eip, base_tss.eflags,
base_tss.cs & 0xffff, base_tss.ss & 0xffff, base_tss.ds & 0xffff,
base_tss.es & 0xffff, base_tss.fs & 0xffff, base_tss.gs & 0xffff);
panic("Unexpected DOUBLE FAULT while booting Fiasco!");
}

View File

@@ -0,0 +1,74 @@
#include "globalconfig.h"
#define GATE_INITTAB_BEGIN(name) \
.text 1 ;\
.globl name ;\
name: ;\
.text
#define GATE_ENTRY(n,entry,type) \
.text 1 ;\
.long entry ;\
.word n ;\
.word type ;\
.text
#define GATE_INITTAB_END \
.text 1 ;\
.long 0 ;\
.text
#define EXCEPTION(n,name) \
GATE_ENTRY(n,1f,0x0e) ;\
1: pushl $(0) ;\
pushl $(n) ;\
jmp 2f
#define EXCEP_USR(n,name) \
GATE_ENTRY(n,1f,0x6e) ;\
1: pushl $(0) ;\
pushl $(n) ;\
jmp 2f
#define EXCEP_ERR(n,name) \
GATE_ENTRY(n,1f,0x0e) ;\
1: pushl $(n) ;\
jmp 2f
GATE_INITTAB_BEGIN(boot_idt_inittab)
EXCEPTION(0x00,t_zero_div)
EXCEPTION(0x01,t_debug)
EXCEPTION(0x02,t_nmi)
EXCEP_USR(0x03,t_int3)
EXCEP_USR(0x04,t_into)
EXCEP_USR(0x05,t_bounds)
EXCEPTION(0x06,t_invop)
EXCEPTION(0x07,t_nofpu)
GATE_ENTRY(0x08,0x20,0x05)
EXCEPTION(0x09,a_fpu_over)
EXCEP_ERR(0x0a,a_inv_tss)
EXCEP_ERR(0x0b,t_segnp)
EXCEP_ERR(0x0c,t_stack_fault)
EXCEP_ERR(0x0d,t_gen_prot)
EXCEP_ERR(0x0e,t_page_fault)
EXCEPTION(0x0f,t_trap_0f)
EXCEPTION(0x10,t_fpu_err)
EXCEPTION(0x11,t_trap_11)
EXCEPTION(0x12,t_trap_12)
EXCEPTION(0x13,t_trap_13)
GATE_INITTAB_END
2: pusha
pushl %ds
pushl %es
pushl %fs
pushl %gs
movl %ss,%eax
movl %eax,%ds
movl %eax,%es
movl %esp,%eax
call trap_dump_panic

View File

@@ -0,0 +1,30 @@
#ifndef BOOT_PAGING_H
#define BOOT_PAGING_H
#include "types.h"
enum
{
PAGE_SIZE = (1 << 12),
PAGE_MASK = (PAGE_SIZE - 1),
SUPERPAGE_SIZE = (1 << 22),
SUPERPAGE_MASK = (SUPERPAGE_SIZE - 1),
};
static inline int
superpage_aligned(Address x)
{ return (x & SUPERPAGE_MASK) == 0; }
static inline Address trunc_superpage(Address x)
{ return x & ~SUPERPAGE_MASK; }
static inline Address trunc_page(Address x)
{ return x & ~PAGE_MASK; }
static inline Address round_page(Address x)
{ return (x + PAGE_MASK) & ~PAGE_MASK; }
static inline Address round_superpage(Address x)
{ return (x + SUPERPAGE_MASK) & ~SUPERPAGE_MASK; }
#endif

View File

@@ -0,0 +1,18 @@
SECTIONS
{
.text :
{
*(.init)
*(.text .text.* .gnu.linkonce.t.*)
*(.fini)
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.data .data.* .gnu.linkonce.d.*)
*(.anno)
} = 0x90909090
.bss :
{
*(.bss .gnu.linkonce.b.* COMMON)
}
}

View File

@@ -0,0 +1,939 @@
# Doxyfile 1.2.15
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = Fiasco Microkernel
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = docs
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French,
# German, Greek, Hungarian, Italian, Japanese, Korean, Norwegian, Polish,
# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish.
OUTPUT_LANGUAGE = English
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these class will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
# members of a class in the documentation of that class as if those members were
# ordinary class members. Constructors, destructors and assignment operators of
# the base classes will not be shown.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = NO
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. It is allowed to use relative paths in the argument list.
STRIP_FROM_PATH =
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
# file names in lower case letters. If set to YES upper case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# users are adviced to set this option to NO.
CASE_SENSE_NAMES = YES
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like the Qt-style comments (thus requiring an
# explict @brief command for a brief description.
#JAVADOC_AUTOBRIEF = NO
JAVADOC_AUTOBRIEF = YES
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# reimplements.
INHERIT_DOCS = YES
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 8
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
# The GENERATE_BUGLIST tag can be used to enable (YES) or
# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.
GENERATE_BUGLIST = YES
# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
ALIASES =
# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
# the initial value of a variable or define consist of for it to appear in
# the documentation. If the initializer consists of more lines than specified
# here it will be hidden. Use a value of 0 to hide initializers completely.
# The appearance of the initializer of individual variables and defines in the
# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
MAX_INITIALIZER_LINES = 30
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C.
# For instance some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = NO
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
# only. Doxygen will then generate output that is more tailored for Java.
# For instance namespaces will be presented as packages, qualified scopes
# will look different, etc.
OPTIMIZE_OUTPUT_JAVA = NO
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
SHOW_USED_FILES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text.
WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning
# and error messages should be written. If left blank the output is written
# to stderr.
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = auto/
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank the following patterns are tested:
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
# *.h++ *.idl *.odl
FILE_PATTERNS = *.h *.cc
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
# that are symbolic links (a Unix filesystem feature) are excluded from the input.
EXCLUDE_SYMLINKS = NO
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
EXCLUDE_PATTERNS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude
# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.
EXAMPLE_RECURSIVE = NO
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
INPUT_FILTER =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse.
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
SOURCE_BROWSER = NO
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
# If the REFERENCED_BY_RELATION tag is set to YES (the default)
# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = YES
# If the REFERENCES_RELATION tag is set to YES (the default)
# then for each documented function all documented entities
# called/used by that function will be listed.
REFERENCES_RELATION = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = NO
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.
HTML_FILE_EXTENSION = .html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI = NO
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the Html help documentation and to the tree view.
TOC_EXPAND = NO
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
# This tag can be used to set the number of enum values (range [1..20])
# that doxygen will group on one line in the generated HTML documentation.
ENUM_VALUES_PER_LINE = 4
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
# generated containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+,
# or Internet explorer 4.0+). Note that for large projects the tree generation
# can take a very long time. In such cases it is better to disable this feature.
# Windows users are probably better off using the HTML help feature.
GENERATE_TREEVIEW = NO
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.
MAKEINDEX_CMD_NAME = makeindex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimised for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using WORD or other
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assigments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
# then it will generate one additional man file for each entity
# documented in the real man page(s). These additional files
# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation. Note that this
# feature is still experimental and incomplete at the
# moment.
GENERATE_XML = NO
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
# generate an AutoGen Definitions (see autogen.sf.net) file
# that captures the structure of the code including all
# documentation. Note that this feature is still experimental
# and incomplete at the moment.
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all function-like macros that are alone
# on a line and do not end with a semicolon. Such function macros are typically
# used for boiler-plate code, and will confuse the parser if not removed.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tagfiles.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or
# super classes. Setting the tag to NO turns the diagrams off. Note that this
# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
# recommended to install and use dot, since it yield more powerful graphs.
CLASS_DIAGRAMS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = NO
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS = YES
# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
# or is not a class.
HIDE_UNDOC_RELATIONS = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
# tags are set to YES then doxygen will generate a graph for each documented
# file showing the direct and indirect include dependencies of the file with
# other documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are png, jpg, or gif
# If left blank png will be used.
DOT_IMAGE_FORMAT = png
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found on the path.
DOT_PATH =
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).
DOTFILE_DIRS =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 1024
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
# remove the intermedate dot files that are used to generate
# the various graphs.
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
# The CGI_NAME tag should be the name of the CGI script that
# starts the search engine (doxysearch) with the correct parameters.
# A script with this name will be generated by doxygen.
CGI_NAME = search.cgi
# The CGI_URL tag should be the absolute URL to the directory where the
# cgi binaries are located. See the documentation of your http daemon for
# details.
CGI_URL =
# The DOC_URL tag should be the absolute URL to the directory where the
# documentation is located. If left blank the absolute path to the
# documentation, with file:// prepended to it, will be used.
DOC_URL =
# The DOC_ABSPATH tag should be the absolute path to the directory where the
# documentation is located. If left blank the directory on the local machine
# will be used.
DOC_ABSPATH =
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
# is installed.
BIN_ABSPATH = /usr/local/bin/
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
# documentation generated for other projects. This allows doxysearch to search
# the documentation for these projects as well.
EXT_DOC_PATHS =

View File

@@ -0,0 +1,53 @@
IMPLEMENTATION[amd64]:
/* This is a more reliable delay than a few short jmps. */
IMPLEMENT inline
void Io::iodelay()
{
asm("inb $0x80,%%al; inb $0x80,%%al" : : : "eax");
}
IMPLEMENT inline
Unsigned8 Io::in8 ( unsigned long port )
{
Unsigned8 tmp;
asm volatile ("inb %w1, %b0": "=a"(tmp) : "Nd"(port) );
return tmp;
}
IMPLEMENT inline
Unsigned16 Io::in16( unsigned long port )
{
Unsigned16 tmp;
asm volatile ("inw %w1, %w0": "=a"(tmp) : "Nd"(port) );
return tmp;
}
IMPLEMENT inline
Unsigned32 Io::in32( unsigned long port )
{
Unsigned32 tmp;
asm volatile ("in %w1, %0": "=a"(tmp) : "Nd"(port) );
return tmp;
}
IMPLEMENT inline
void Io::out8 ( Unsigned8 val, unsigned long port )
{
asm volatile ("outb %b0, %w1": : "a"(val), "Nd"(port) );
}
IMPLEMENT inline
void Io::out16( Unsigned16 val, unsigned long port )
{
asm volatile ("outw %w0, %w1": : "a"(val), "Nd"(port) );
}
IMPLEMENT inline
void Io::out32( Unsigned32 val, unsigned long port )
{
asm volatile ("out %0, %w1": : "a"(val), "Nd"(port) );
}

View File

@@ -0,0 +1,15 @@
/* -*- c++ -*- */
#ifndef KEYCODES_ARCH_H__
#define KEYCODES_ARCH_H__
enum
{
KEY_BACKSPACE = 0x08,
KEY_TAB = 0x09,
KEY_ESC = 0x1b,
KEY_RETURN = 0x0d,
};
#endif // KEYCODES_ARCH_H__

View File

@@ -0,0 +1,91 @@
IMPLEMENTATION [amd64]:
IMPLEMENT static inline
void
Mem::memset_mwords (void *dst, unsigned long value, unsigned long n)
{
unsigned long dummy1, dummy2;
asm volatile ("cld \n\t"
"rep stosq \n\t"
: "=c" (dummy1), "=D" (dummy2)
: "a"(value), "c" (n), "D" (dst)
: "memory");
}
IMPLEMENT static inline
void
Mem::memcpy_bytes (void *dst, void const *src, unsigned long n)
{
unsigned long dummy1, dummy2, dummy3;
asm volatile ("cld \n\t"
"repz movsq (%%rsi), (%%rdi) \n\t"
"mov %%rdx, %%rcx \n\t"
"repz movsb (%%rsi), (%%rdi) \n\t"
: "=c" (dummy1), "=S" (dummy2), "=D" (dummy3)
: "c" (n >> 3), "d" (n & 7), "S" (src), "D" (dst)
: "memory");
}
IMPLEMENT static inline
void
Mem::memcpy_mwords (void *dst, void const *src, unsigned long n)
{
unsigned long dummy1, dummy2, dummy3;
asm volatile ("cld \n\t"
"rep movsq (%%rsi), (%%rdi) \n\t"
: "=c" (dummy1), "=S" (dummy2), "=D" (dummy3)
: "c" (n), "S" (src), "D" (dst)
: "memory");
}
PUBLIC static inline
void
Mem::memcpy_bytes_fs (void *dst, void const *src, unsigned long n)
{
unsigned long dummy1, dummy2, dummy3;
asm volatile ("cld \n\t"
"rep movsq (%%rsi), (%%rdi) \n\t"
"mov %%rdx, %%rcx \n\t"
"repz movsb (%%rsi), (%%rdi) \n\t"
: "=c" (dummy1), "=S" (dummy2), "=D" (dummy3)
: "c" (n >> 3), "d" (n & 7), "S" (src), "D" (dst)
: "memory");
}
PUBLIC static inline
void
Mem::memcpy_mwords_fs (void *dst, void const *src, unsigned long n)
{
unsigned long dummy1, dummy2, dummy3;
asm volatile ("cld \n\t"
"rep movsq (%%rsi), (%%rdi) \n\t"
: "=c" (dummy1), "=S" (dummy2), "=D" (dummy3)
: "c" (n), "S" (src), "D" (dst)
: "memory");
}
// ------------------------------------------------------------------------
IMPLEMENTATION [amd64 && mp]:
IMPLEMENT inline static void Mem::mb()
{ __asm__ __volatile__ ("mfence" : : : "memory"); }
IMPLEMENT inline static void Mem::rmb()
{ __asm__ __volatile__ ("lfence" : : : "memory"); }
IMPLEMENT inline static void Mem::wmb()
{ /* Just barrier should be enough */
__asm__ __volatile__ ("sfence" : : : "memory");
}
IMPLEMENT inline static void Mem::mp_mb() { mb(); }
IMPLEMENT inline static void Mem::mp_rmb() { rmb(); }
IMPLEMENT inline static void Mem::mp_wmb() { wmb(); }

View File

@@ -0,0 +1,139 @@
INTERFACE[amd64]:
EXTENSION class Proc
{
public:
enum Efer_bits
{
Efer_sce_flag = 0x00000001, // Syscall Enable Flag
Efer_lme_flag = 0x00000100, // Long Mode Enable Flag
Efer_nxe_flag = 0x00000800, // Not-executable
Efer_svme_flag = 0x00001000, // Enable SVM
};
};
IMPLEMENTATION[amd64]:
#include "types.h"
#include "std_macros.h"
IMPLEMENT static inline
Mword Proc::stack_pointer()
{
Mword sp;
asm volatile ("mov %%rsp, %0 \n" : "=r"(sp) );
return sp;
}
IMPLEMENT static inline
void Proc::stack_pointer(Mword sp)
{
asm volatile ("mov %0, %%rsp \n" : : "r"(sp) );
}
IMPLEMENT static inline
Mword ALWAYS_INLINE Proc::program_counter()
{
Mword pc;
asm volatile ("call 1f ; 1: pop %0" : "=r"(pc));
return pc;
}
IMPLEMENT static inline
void Proc::pause()
{
asm volatile (" .byte 0xf3, 0x90 #pause \n" );
}
/*
* The following simple ASM statements need the clobbering to work around
* a bug in (at least) gcc-3.2.x up to x == 1. The bug was fixed on
* Jan 9th 2003 (see gcc-bugs #9242 and #8832), so a released gcc-3.2.2
* won't have it. It's safe to take the clobber statements out after
* some time (e.g. when gcc-3.3 is used as a standard compiler).
*/
IMPLEMENT static inline
void Proc::halt()
{
asm volatile ("hlt" : : : "memory");
}
IMPLEMENT static inline
void Proc::cli()
{
asm volatile ("cli" : : : "memory");
}
IMPLEMENT static inline
void Proc::sti()
{
asm volatile ("sti" : : : "memory");
}
IMPLEMENT static inline
Proc::Status Proc::cli_save()
{
Status ret;
asm volatile ("pushfq \n\t"
"popq %0 \n\t"
"cli \n\t"
: "=g"(ret) : /* no input */ : "memory");
return ret;
}
IMPLEMENT static inline
void Proc::sti_restore(Status st)
{
if (st & 0x0200)
asm volatile ("sti" : : : "memory");
}
IMPLEMENT static inline
Proc::Status Proc::interrupts()
{
Status ret;
asm volatile ("pushfq \n"
"popq %0 \n"
: "=g"(ret) : /* no input */ : "memory");
return ret & 0x0200;
}
IMPLEMENT static inline
void Proc::irq_chance()
{
asm volatile ("nop; nop;" : : : "memory");
}
PUBLIC static inline
Unsigned64
Proc::rdmsr(Unsigned32 msr)
{
Unsigned32 h,l;
asm volatile ("rdmsr" : "=a" (l), "=d" (h) : "c" (msr));
return (((Mword)h) << 32) | l;
}
PUBLIC static inline
void
Proc::wrmsr(Unsigned32 msr, Unsigned64 value)
{
asm volatile ("wrmsr" : :
"a" ((Unsigned32)value),
"d" ((Unsigned32)(value >> 32)),
"c" (msr));
}
PUBLIC static inline
Mword
Proc::efer()
{ return rdmsr(0xc0000080); }
PUBLIC static inline
void
Proc::efer(Mword value)
{ wrmsr(0xc0000080, value); }

View File

@@ -0,0 +1,41 @@
IMPLEMENTATION[amd64]:
#include "io.h"
#include "processor.h"
// reset PC
void __attribute__ ((noreturn))
platform_reset()
{
// i8042: store the next byte at port 0x60 as command byte
while (Io::in8 (0x64) & 0x2)
;
Io::out8_p (0x60, 0x64);
// i8042 command byte (PS/2-compatible mode):
// b0=0 ... no IRQ 1 is generated when data available in input buffer
// b1=0 ... no IRQ 1 is generated when mouse data available in input buffer
// b2=1 ... set SYS flag in status register -- tells POST to perform
// "warm boot" tests/initiailization
// b3=0 ... reserved
// b4=0 ... keyboard interface enabled
// b5=0 ... auxillary PS/2 device (mouse) interface enabled
// b6=0 ... translation disabled -- data appears at input buffer exactly
// as read from keyboard
// b7=0 ... reserved
while (Io::in8 (0x64) & 0x2)
;
Io::out8_p (0x4, 0x60);
// i8042: pulse output port with 1110b
// b0=0 ... reset computer
// b1=1 ... set gate A20
// b2=1 ... pull mouse data low
// b3=1 ... pull mouse clock low
while (Io::in8 (0x64) & 0x2)
;
Io::out8_p (0xfe,0x64);
for (;;)
Proc::pause();
}

View File

@@ -0,0 +1,57 @@
// Source for generating some asm for cut'n'paste, why program asm ourselves
// when the compiler can do it?
// arm-linux-g++ -fverbose-asm -fPIC -W -Wall -Os -S cache_func_gen.cpp
#include <cstdio>
enum {
DEBUG = 0,
};
void num_way_l1_cache_op()
{
asm volatile("@ Start:");
register unsigned long ccsidr;
asm volatile("mcr p15, 2, %0, c0, c0, 0" : : "r" (0)); // L1, data or unified
asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (ccsidr));
if (DEBUG)
printf("ccsidr = %08lx\n", ccsidr);
// sets
register unsigned numsets = ((ccsidr >> 13) & ((1 << 15) - 1));
// associativity - 1
register unsigned numways = ((ccsidr >> 3) & ((1 << 10) - 1));
// linesize
register unsigned linesizel2 = (ccsidr >> 0) & ((1 << 3) - 1);
if (DEBUG)
printf("linesizel2: %d numways: %d numsets: %d\n",
linesizel2, numways + 1, numsets + 1);
register int shiftways = __builtin_clz(numways);
register int shiftset = linesizel2 + 4;
if (DEBUG)
printf("shiftways: %d shiftset: %d\n", shiftways, shiftset);
unsigned int cnt = 0;
for (register int w = numways; w >= 0; --w)
for (register int s = numsets; s >= 0; --s)
{
register unsigned long v = (w << shiftways) | (s << shiftset);
if (!DEBUG)
// invalidate num/way
asm volatile("mcr p15, 0, %0, c7, c6, 2" : : "r" (v));
if (DEBUG)
printf("w=%d s=%d: %08lx\n", w, s, v);
if (DEBUG)
cnt++;
}
asm volatile("isb");
asm volatile("dsb");
asm volatile("@ End:");
if (DEBUG)
printf("cnt: %d\n", cnt);
}

Some files were not shown because too many files have changed in this diff Show More