Xisop: Dropping LyX, exported tex and updated pdf
authorMatthew Mondor <mmondor@pulsar-zone.net>
Mon, 2 Dec 2019 07:07:48 +0000 (07:07 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Mon, 2 Dec 2019 07:07:48 +0000 (07:07 +0000)
Xisop/doc/.gitignore [new file with mode: 0644]
Xisop/doc/xisop.pdf
Xisop/doc/xisop.tex [new file with mode: 0644]

diff --git a/Xisop/doc/.gitignore b/Xisop/doc/.gitignore
new file mode 100644 (file)
index 0000000..9fee574
--- /dev/null
@@ -0,0 +1,3 @@
+*.log
+*.toc
+*.aux
index 802887a..dc2ec7d 100644 (file)
Binary files a/Xisop/doc/xisop.pdf and b/Xisop/doc/xisop.pdf differ
diff --git a/Xisop/doc/xisop.tex b/Xisop/doc/xisop.tex
new file mode 100644 (file)
index 0000000..9ed9261
--- /dev/null
@@ -0,0 +1,3432 @@
+%% LyX 2.1.2.2 created this file.  For more info, see http://www.lyx.org/.
+%% Do not edit unless you really know what you are doing.
+\documentclass[english]{article}
+\usepackage[latin9]{inputenc}
+\usepackage[letterpaper]{geometry}
+\geometry{verbose,tmargin=0.5in,bmargin=0.5in}
+
+\makeatletter
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
+\providecommand{\LyX}{L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
+\newenvironment{lyxlist}[1]
+{\begin{list}{}
+{\settowidth{\labelwidth}{#1}
+ \setlength{\leftmargin}{\labelwidth}
+ \addtolength{\leftmargin}{\labelsep}
+ \renewcommand{\makelabel}[1]{##1\hfil}}}
+{\end{list}}
+
+\makeatother
+
+\usepackage{babel}
+\begin{document}
+
+\title{Xisop kernel development notes}
+
+
+\author{Copyright (c) 2001-2003, Matthew Mondor\\
+All rights reserved.}
+
+\maketitle
+\newpage{}
+
+\tableofcontents{}
+
+\newpage{}
+
+
+\section{General development notes}
+
+Before attempting to write software for Xisop to expand it's funtionality,
+or before porting Xisop to a new architecture, it is recommended to
+carefully read this manual entirely. It attempts to answer all questions
+one could have about it's organization and build process, as well
+as style and conventions one must follow for code consistancy with
+the rest of the project.
+
+
+\subsection{Development software used}
+
+To develop Xisop, the GNU GCC suite of compiler, assembler, linker
+and binutils software was chosen. The main reasons for this consists
+of cost savings, and portability. GCC has support for many different
+CPU types was a main factor. Moreover, the AT\&T assembly syntax allows
+to somewhat obtain some consistency.
+
+An effort was made to try to not support GCC-specific functions however,
+for portability reasons. For instance, the various \emph{\_spl}{*}\emph{()}
+functions are implemented as macros around a separate assembly function,
+located in the assembler \emph{.s} files, rather than embedded inside
+the C code using inline assembly directives. (\emph{XXX} \emph{actually
+they may be fixed to be GCC-dependent soon heh}).
+
+A choice was made to not use GNU or BSD make. Instead, \emph{/bin/sh}
+is assumed to exist. This usually consists of a POSIX compliant shell,
+on GNU systems (and Linux) the \emph{bash} shell usually emulates
+it's behavior and \emph{/bin/sh} then consists of a symbolic link
+to \emph{/bin/bash}. On BSD systems only POSIX 1003.2 and 1003.2a
+functionality is usually present in their \emph{/bin/sh}, which is
+what Xisop build scripts are making use of. As such, \emph{bash} is
+therefore not a requirement.
+
+This document is written and maintained using \LyX{}. The UAE (Amiga
+emulator) and Bochs (i386 emulator) utilities were useful to develop
+the current ports. The original host development system consists of
+an i386 compatible system running NetBSD 1.6\_STABLE. This operating
+system is ideal for programming and cross compiling. The current Xisop
+building system was tuned to the NetBSD 1.6.1 toolchain. To compile
+the amiga port, for instance, you only should need to use the build.sh
+script to build the suite of netbsdelf-m68k tools. Using the Xisop
+``\emph{./make.sh -t amiga}'' command should then build the amiga
+target.
+
+The software was written using the VIm editor, with \emph{ts=8}, \emph{sw=4}
+and \emph{cindent}.
+
+If you compile your own gcc with your intended compiling target, you
+simply need to change a file to tell the locations of the various
+building tools. See the section about ``the build process'' later
+on for more information.
+
+
+\subsection{Xisop compatibility with other systems, and where it fits best}
+
+
+\subsubsection{UNIX, POSIX, BSD, Linux}
+
+Xisop is definitely not POSIX, although it's functions are simpler
+than POSIX is, requireing a small learning curve only to use. It was
+not designed as a general-purpose operating system to replace Unix
+and provide all it's capabilities. It's an entity of it's own, simpler
+and smaller, mostly made to suit the requirements of restricted embedded
+systems. To implement most POSIX requirements a larger system is required,
+which generally also results in slower code. For instance, Xisop addresses
+ports and tasks as addresses, rather than IDs. This solves the problem
+of allocation and reuse of process IDs.
+
+A Xisop task also is lightweight compared to a UNIX-style process.
+Moreover, the need for more custom user signals than POSIX environment
+provides made it unsuitable to reserve almost all 32 signals to reserved
+semantics. The concept of file descriptors and select()/poll() is
+also different. However, SIGPOLL signal was reserved in Xisop for
+the implementation of message-based signals and events using a single
+message port and signal. This can be used when there can be a large
+number of entities a task may be monitoring, and the user signals
+would not be appropriate. It would be possible to work a system out
+using this facility for the 32 standard Unix signals if the need existed.
+
+Although it would be possible to implement POSIX compatibility libraries,
+it was not a main goal in Xisop development.
+
+
+\subsubsection{Memory and process protection}
+
+Xisop was not designed to support Memory Management Unit (MMU) coprocessors
+and provide page-grained memory protection. This helped to implement
+message passing in a very efficient manner, only passing pointers
+around, and reduced considerably kernel size. Moreover, it allows
+to provide most user-access system functions in a shared library,
+reducing considerably the amount of system calls an application needs
+to make (accessed through traps). The number of traps being reduced,
+the preemtive scheduler is less clobbered. Calling functions of a
+shared library happen entirely in the caller's task allocated CPU
+time slice, which means that the kernel load is not affected. Not
+requireing MMU is also an advantage with Xisop, as it can run with
+a single MC68000L8 for instance, and a little RAM.
+
+However, we all know that without appropriate memory protection, Xisop
+cannot efficiently protect the kernel from user tasks, which can take
+full control on the system at any time. Clean interfaces were however
+implemented, which internally perform various sanity checking to ensure
+the validity of the supplied objects and arguments, so that common
+software bugs do not automatically corrupt memory and the system.
+Xisop knows the difference between a valid task, port, device handle,
+etc, and invalid ones. It also knows when to not attempt to free memory
+if a wrong pointer is supplied, since \emph{mnode\_t} nodes are also
+validated using a unique magic cookie. Such steps permit to minimize
+system crashes in the event of a software bug.
+
+The kernel comports special macros to aid in realizing object validity
+sceals and dependancies checking, which are defined in \textless{}\emph{common/kernel/object.h}\textgreater{}:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~OBJECT\_VALIDATE(objptr,~objtype)}}] Sets the \emph{objptr}-\textgreater{}object\_magic
+field to \emph{objtype}. This type corresponds to one of the \emph{OBJECT\_}{*}
+names which are defined in the same headerfile.
+\item [{\emph{void~OBJECT\_INVALIDATE(objptr)}}] Sets the \emph{objptr}-\textgreater{}object\_magic
+field to 0.
+\item [{\emph{void~OBJECT\_REGISTER(objptr)}}] Registers \emph{objptr}
+object by setting the \emph{objptr}-\textgreater{}object\_id field
+to a unique number. This number will be used for matching when verifying
+for proper dependancy link. Only objects which may be required as
+dependancy to others need to use this.
+\item [{\emph{void~OBJECT\_SETDEP(objptr,~depobjptr)}}] Associates \emph{objptr}
+object as requireing the \emph{depobjptr} object as dependancy for
+proper function. What this does is internally set \emph{objptr}-\textgreater{}objdep\_magic
+to \emph{depobjptr}-\textgreater{}magic and \emph{objptr}-\textgreater{}objdep\_id
+to \emph{depobjptr}-\textgreater{}object\_id. As a result, it becomes
+possible to refuse to perform operations related to this object if
+the dependancy link ever dies.
+\item [{\emph{bool~OBJECT\_VALID(objptr,~objtype)}}] First verifies if
+objptr is non-NULL, and then evaluates if the object associated with
+\emph{objptr} truely corresponds to \emph{objtype} (\emph{objptr}
+!= NULL \&\& \emph{objptr}-\textgreater{}object\_magic == \emph{objtype}).
+This consists of the reason why the various \emph{OBJECT\_}{*} definitions
+in the headerfile should consist of unique values which are unlikely
+to occur randomly. Returns TRUE on success, or FALSE otherwise.
+\item [{\emph{bool~OBJECT\_DEPENDS(objptr,~depobjptr)}}] Verifies the
+integrity of a dependancy link, which was previously linked using
+\emph{OBJECT\_SETDEP()} on \emph{objptr}. This in fact makes sure
+that the object it should relate to (\emph{depobjptr}) is still valid,
+and consists of the same one (\emph{depobjptr} != NULL \&\& \emph{depobjptr}-\textgreater{}object\_magic
+== \emph{objptr}-\textgreater{}objdep\_magic \&\& \emph{depobjptr}-\textgreater{}object\_id
+== \emph{objptr}-\textgreater{}objdep\_id). Returns TRUE on success,
+or FALSE otherwise.
+\end{lyxlist}
+Obviously, the structure of an object only requires to hold the fields
+which are required for the functionality it requires according to
+these macros. Those fields are all expected to be of type \emph{u\_int32\_t}.
+This system allows relatively lightweight validity checking of object
+credentials, without the need for memory protection. The kernel uses
+them wherever needed for safety. Using this system also allows to
+use efficient dynamic memory allocation techniques (\emph{pool\_t}
+functions) to create and destroy critical system objects, and reference
+can be made using pointers through the system, rather than using less
+efficient or fixed-sized arrays and object ID allocation. Programming
+using these macros also yields in a clean interface to result in consistant,
+clean C code.
+
+
+\subsubsection{Multitasking}
+
+While Xisop provides preemptive multitasking (more information provided
+in the next section), it can be disabled by user applications if need
+be. This means that Xisop can be used to create single-tasking applications
+where a multitasking environment is not wanted, while still taking
+advantage of the abstraction of CPU and hardware access Xisop allows.
+This for instance allows games to be written almost entirely in C,
+and be independent of an operating system such as Windows or AmigaOS,
+using Xisop instead. Such a small game can be booted from a single
+floppy, which would comport all necessary components of the game,
+including Xisop itself. Disabling multitasking also allows direct
+access to the hardware resources by the main application, in a safe
+manner. When multitasking is enabled, such safe access to hardware
+resources is also provided, although using the \emph{device} concept
+is required to remain multitasking friendly and access those. More
+information about Xisop devices is given later on.
+
+This means that multitasking was provided as a useful optional facility
+rather than to force limits over the applications. It is great to
+develop some kinds of systems using multitasking, while some other
+applications are much better without it. This was an important consideration
+when designing Xisop. Whether multitasking is enabled or disabled,
+the public interrupt facilities interface works as expected. More
+information is provided on this interface in a later section.
+
+
+\subsubsection{AmigaOS}
+
+Although some ideas were admitedly borrowed from the Amiga Operating
+System, the compatibility stops there. The AmigaOS headerfiles, although
+publically available, or source code (which is unavailable publically)
+were not used as a reference to write it, nor can Xisop run AmigaOS
+native object files and binaries. Xisop is a clean-room kernel implementation,
+written from scratch and uses it's own set of ideas and conventions,
+which are described in this document.
+
+The Xisop signals, message ports, devices and handlers concepts were
+however borrowed from AmigaOS, as it was a great proof of feasibility
+using a very simple underlaying structure. The interface and internals
+do not behave identically but anyone who programmed using the AmigaOS
+inter-task communication and synchronization features will feel at
+ease with Xisop.
+
+
+\subsubsection{Where Xisop fits best}
+
+The best application Xisop suits for consists of an embedded system,
+dedicated to provide specific services or tasks, running with low-cost
+hardware and restricted physical memory. There are however a wide
+range of applications which fit in this category, cell phones, microwave
+ovens, PDAs, clocks, industrial microcontrollers or event loggers,
+alarm systems, etc. An example of low-cost hardware Xisop runs great
+on is a Motorola MC68000L8 microprocessor based board with a restricted
+512 kilobytes of memory, and an RS-232 interface with UART controler
+chip. Xisop can also be used to develop games on 32-bit consoles or
+arcade hardware.
+
+Xisop consists of a nice component when simplifying hardware design
+of a project, where a simple CPU unit, little RAM and Xisop-based
+software can provide the tasks of more complex hardware-only solutions.
+This also implies that the simpler hardware may then be reused, since
+it now basically consists of a general purpose programmable system
+rather than single-purpose hardware units which can only serve for
+a single project.
+
+It does not consist of a full multipurpose operating system but rather
+of a collection of primitives to aid a C programmer to write his applications
+on a variety of hardware, and benefit from memory management including
+support for runtime dynamic memory addition and removal, as well as
+multiple memory types, inter-task communication primitives, a fair
+number of user signals, abstracted interrupt facilities, and a microkernel
+design allowing to add future functionality modularized as userspace
+tasks, shared libraries, devices and handlers.
+
+It's weak license (BSDL-style) makes it especially suitable for commercial
+embedded applications when a technical team can build a custom application,
+where royalties for use, or redistribution of custom changes in the
+code are not required. An effort is provided to make the CPU-specific
+interface abstract so that most of the code can be written in C, for
+code clarity, consistency, development speed and ease. The assembly
+code is restricted to the minimum, and always consists of a backend
+to use C. The same is true for architecture-specific assembly low-level
+code. Those sections are described later on.
+
+As such, very little time is generally required to port the basics
+of Xisop to a new architecture (other 32-bit ones, at least). Engineers
+can then develop custom low-cost hardware and a programmer can write
+most of the software for it using C and Xisop rather than having to
+write all of it in assembly, or starting from nothing and having to
+re-invent the assembly to C support primitives.
+
+Very low cost hardware helps when many units are being deployed. However,
+in the cases where the hardware costs are higher (i.e. microprosessor
+with MMU support and 8 or more megabytes of memory), Xisop may seem
+too rudimentary, but there are then alternatives such as NetBSD which
+can be ported quite fast (when required, as it already consists of
+the most portable OS), and POSIX functionalities, with full unix features,
+networking, protected memory, etc all become available. It is also
+released under the BSD unrestrictive license and is available at \emph{http://www.netbsd.org}.
+
+
+\subsection{Xisop coding standards}
+
+
+\subsubsection{Licencing issues and censorship}
+
+All code which is to be publically released within the standard Xisop
+distribution should be licensed under a BSD-style license, and should
+not be released under the GNU Public License (GPL) or GNU Lesser Public
+License (LGPL). It however is obvious that companion packages be released
+and distributed separately with the Xisop main archive, as long as
+it be clearly isolated and labeled as such, so that it can easily
+be stripped when code under such strict a license is not wanted within
+a project. It is allowed for authors to include their advertizing
+clause as wanted in the BSD license advertizing at the top of their
+files. A main file can then easily be created using a script of advertizement
+clauses and related files whcih one can append in the documentation
+of a commercial or closed source product using Xisop.
+
+This allows anyone to use Xisop for open source or closed source projects
+as wanted. Although it is encouraged to publically donate the new
+processor and architecture specific modules one develops, as well
+as machine-independent new modules of interest for inclusion into
+the main Xisop tree, released under BSD license, noone is obliged
+to do so. This also allows the main tree to not become too tainted
+with alot of code everyone develops which does not serve the other
+Xisop users much and mostly bloat the project. The mirokernel design
+easy allows third party supplied libraries, devices and handlers to
+be developed, and these may also be closed source, and commercial.
+There of course is no problem to release such optional kernel-independent
+modules under one of the GNU licenses.
+
+If you port Xisop to a new processor or architecture, and are willing
+to contribute the code to the tree, I suggest that the source be obtained
+via CVS from the main Xisop source repository, and that \emph{cvs
+diff -u} be used to create a patch. This patch should be sent via
+email to Matthew Modor, at \emph{mmondor@gobot.ca}. I then will attempt
+to merge it into the main Xisop CVS tree, after performing basic sanity
+checking on the code, and fixing required bugs if possible (if any).
+I may also reply back if there is any reason why the changes cannot
+be applied, in which case I could help to make it conform with the
+requirements.
+
+
+\subsubsection{Standard data types and when to use them}
+
+Xisop uses a defined set of data types in it's kernel, and attempts
+to remain consistant when using them for code clarity and obviousness.
+The following C standard data types are used:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{char}}] The standard C character type, used for C strings
+only in Xisop. \emph{int8\_t} and \emph{u\_int8\_t} should be used
+for other byte-related types.
+\item [{\emph{char~{*}}}] Obvious, also only used in direct relation with
+C strings.
+\item [{\emph{void}}] When a function returns nothing, or has no arguments,
+for both prototype and function declaration.
+\item [{\emph{void~{*}}}] This consists as usual, of a pointer to an abstract
+type, and is used where required.
+\item [{\emph{int}}] This is used as a convenient format for various return
+codes and variables where bit-size is not a concern, or should match
+the one which is assumed for the processor (although it is highly
+recommended to use the various defined types below for these).
+\end{lyxlist}
+The other standard C data types are replaced by the following ones,
+which are defined in the Xisop machine-independent \textless{}\emph{common/types.h\textgreater{}}
+headerfile:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{bool}}] Corresponds to \emph{int}, but specifically denotes
+that this variable is used for boolean operations and conditionals
+for code clarity it may only hold TRUE (1) or FALSE (0) values.
+\item [{\emph{int8\_t}}] Is used everywhere byte-sized signed elements
+are explicitely required, from -127 to +128, except for strings where
+the standard C \emph{char} type should be used.
+\item [{\emph{u\_int8\_t}}] Should be used where unsigned byte-sized elements
+are required, for 0-255 values.
+\item [{\emph{int16\_t}}] Is the data type used for 16-bit signed integers
+values, -32768 to +32767.
+\item [{\emph{u\_int16\_t}}] The unsigned 16-bit value data type which
+can old 0 to 65535.
+\item [{\emph{int32\_t}}] For use with 32-bit signed data types
+\item [{\emph{u\_int32\_t}}] 32-bit unsigned data type
+\item [{\emph{int64\_t}}] signed 64-bit data type (usually typedef with
+\emph{long long})
+\item [{\emph{u\_int64\_t}}] unsigned 64-bit data type. It is to be noted
+that operations on 64-bit objects is generally slow as it requires
+multiple instructions on 32-bit architectures. Currently, no 64-bit
+data types are beign used anymore, the few ones which used it were
+converted to use 32-bit ones instead.
+\item [{\emph{size\_t}}] Used to represent a size in bytes, this in fact
+is equivalent to \emph{u\_int32\_t}. \emph{size\_t} should not be
+used to represent arbitary types amounts, but byte amounts only (corresponding
+to a number of \emph{char}, \emph{u\_int8\_t} or \emph{int8\_t} types).
+\item [{\emph{ssize\_t}}] Purpose is the same as for \emph{size\_t}, but
+this can hold -1 for error.
+\end{lyxlist}
+And other frequently used standard Xisop types, which are still defined
+in \textless{}\emph{common/types.h}\textgreater{}, but have their
+corresponding structures defined at their respective locations (mentionned
+in parentheses):
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{node\_t}}] A doubly linked list node to be used in \emph{list\_t}
+type lists. (common/kernlib/list.h)
+\item [{\emph{list\_t}}] A doubly linked list (common/kernlib/list.h)
+\item [{\emph{mchunk\_t}}] A chunk of contiguous memory pages, part of
+a \emph{ppool\_t} (common/kernel/memory.h)
+\item [{\emph{page\_t}}] A physical memory page, or a number of contiguous
+physical memory pages, holding the necessary information for freeing
+back. (common/kernel/memory.h)
+\item [{\emph{ppool\_t}}] A system pool of pages, that is, what other pools
+allocate pages from. (common/kernel/memory.h)
+\item [{\emph{pool\_t}}] A efficient fixed sized objects (\emph{pnode\_t})
+memory pool with internal statistical page cacheing, which can optionally
+dynamically grow and shrink, or be static in size (common/kernel/memory.h)
+\item [{\emph{pnode\_t}}] A pool object node, which must prefix any pool
+object. This type internally begins with a \emph{node\_t} and can
+therefore be used directly for queuing in \emph{list\_t}. (common/kernel/memory.h)
+\item [{\emph{mpool\_t}}] A multiple \emph{pool\_t} memory pool used to
+serve multiple sized blocks requests. Of various memory types. Bocks
+which are too large are rounded at page boundaries. (common/kernel/memory.h)
+\item [{\emph{mnode\_t}}] Internally used by the \emph{mpool\_t} related
+allocation primitives (common/kernel/memory.h)
+\item [{\emph{facility\_t}}] A public interrupt facility which the port-specific
+code initializes calling the common \emph{facility\_init()} function.
+(common/kernel/exception.h)
+\item [{\emph{hook\_t}}] An interrupt, trap or exception code vector attached
+to a \emph{facility\_t}. (common/kernel/exception.h)
+\item [{\emph{hookid\_t}}] An \emph{hook\_t} ID, internally a \emph{u\_int32\_t},
+which is guarranteed to be unique for the facility it belongs to.
+(common/kernel/exception.h)
+\item [{\emph{task\_t}}] Task structure (common/kernel/task.h)
+\item [{\emph{priority\_t}}] A task priority number (common/kernel/task.h)
+\item [{\emph{signum\_t}}] Signal number (common/kernel/signal.h)
+\item [{\emph{sigmask\_t}}] Signal mask which can represent one or more
+\emph{signum\_t}. (common/kernel/signal.h)
+\item [{\emph{port\_t}}] Message port (common/kernel/port.h)
+\item [{\emph{message\_t}}] A message header structure which comports the
+glue to queue messages in \emph{port\_t} (common/kernel/port.h)
+\item [{\emph{device\_t}}] An open device handler (common/kernel/device.h)
+\item [{\emph{devicenode\_t}}] A linked device hook (common/kernel/device.h)
+\item [{\emph{iorequest\_t}}] An I/O request message type used for \emph{device\_t}
+requests (common/kernel/device.h)
+\item [{\emph{fifo8\_t}}] An 8-bit elements FIFO buffer. \emph{fifo}{*}\emph{\_t}
+types are implemented as a fixed bytes buffer once initialized, rather
+than using linked lists. It is possible to easily create new \emph{fifo}{*}\emph{\_t}
+types of arbitrary object sizes using a macro. (common/kernlib/fifo.h)
+\item [{\emph{fifo16\_t}}] A 16-bit elements FIFO buffer (common/kernlib/fifo.h)
+\item [{\emph{fifo32\_t}}] A 32-bit elements FIFO buffer (common/kernlib/fifo.h)
+\item [{\emph{lifo8\_t}}] A 8-bit elements LIFO buffer. \emph{lifo}{*}\emph{\_t}
+types operate like stacks, and are internally implemented as a fixed
+bytes buffer once initialized, rather than using linked lists. A macro
+is provided to easily create new types of \emph{lifo}{*}\emph{\_t}
+for objects of arbitrary size. (common/kernlib/lifo.h)
+\item [{\emph{lifo16\_t}}] A 16-bit elements LIFO buffer (common/kernlib/lifo.h)
+\item [{\emph{lifo32\_t}}] A 32-bit elements LIFO buffer (common/kernlib/lifo.h)
+\item [{\emph{hashtable\_t}}] A hash lookup table (common/kernlib/hash.h)
+\item [{\emph{hashnode\_t}}] A hash lookup table node (common/kernlib/hash.h\textgreater{}
+\end{lyxlist}
+And here are the processor and architecture specific opaque data types
+they provide:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{\_ipl\_t}}] Abstract Interrupt Priority Level type, associated
+with the \emph{\_spl}n\emph{()} and \emph{\_splx()} functions. (processor/support.h)
+\item [{\emph{\_ctx\_t}}] Abstract processor-specific supplied context
+handle, associated to \emph{\_ctx\_init()} function which is used
+by \emph{task\_alloc()} and internal kernel context switching. (processor/support.h)
+\item [{\emph{\_lock\_t}}] Abstract processor-specific supplied atomic
+simple lock handle. Associated to the \emph{\_lock\_}{*}\emph{()}
+functions. (processor/support.h)
+\item [{\emph{\_rlock\_t}}] An abstract atomic recursive lock handle (needs
+to be unlocked the same number of times it was locked to free the
+\emph{\_rlock\_t}). Associated to the \emph{\_rlock\_}{*}\emph{()}
+functions. (processor/support.h)
+\item [{\emph{XXX}}] The 64-bit related types are currently unused. On
+most processors the GCC compiler requires additional libraries to
+support these, which are currently not part of Xisop. There however
+exist such implementations fully written in C, like the one used on
+BSD systems which would not be hard to include if it was necessary.
+An effort was made to also not include software which requires the
+use of floating point, for code size and efficiency.
+\end{lyxlist}
+
+\subsubsection{Programming style and conventions}
+
+It is a fact that consistency is a must for readibility, especially
+in an open source project which many others may need to modify to
+suit their particular needs. The following programming conventions
+are used, and are defined for assembly and C code.
+
+
+\paragraph{Function names}
+
+All functions which are not behaving identically to ANSI-C or POSIX
+or other widely standarized ones, but have the same name should have
+their name prefixed by an underscore ('\_'). Others which behave exactly
+like the standards should have the same name the standard expects.
+Other functions which have nothing in common with standard names should
+not be prefixed by underscores, except for the defined processor and
+port-specific functions, which names should also begin with an underscore.
+Of course, if a hardware-specific function is provided as a replacement
+to a common portable one for performance considerations, it obviously
+should bear the same name, however.
+
+
+\paragraph{Formatting}
+
+Line termination should consist of ``\textbackslash{}n'' (linefeed,
+as is used on Amiga and Unix), rather than ``\textbackslash{}r\textbackslash{}n''
+which is used on MS-DOS and Windows for text file storage. Other than
+tab (``\textbackslash{}t'') and linefeed (``\textbackslash{}n''),
+no other control characters should be found within the source files.
+Moreover, every line of the source files should not exceed 79 characters.
+
+
+\paragraph{C language sections}
+
+It is important that C files be using the standard eight (8) tab size
+for real tabs. However, the software tab should consist of four (4)
+characters. Tabs should be used where 8 space tabs are needed, and
+spaces used to fill the 4 character tabs. When using the VIm editor,
+these should be used: \emph{ts=8}, \emph{sw=4}, and \emph{cindent}.
+This allows the files to be printable using text file viewers properly
+at all times, and to also be printable as-is on most printers. \emph{XXX}
+Add settings for emacs
+\begin{itemize}
+\item C program suffix should consist of lower case \emph{.c}
+\item C headerfiles should use the lower case suffix \emph{.h}
+\item ANSI-C programming norms should be observed as much as possible.
+\item ANSI convention for function arguments specification rather than K\&R.
+\item BSD programming style used rather than GNU style, especially for opening
+and closing braces convention. This corresponds to the formatting
+performed using GNU indent program with the following parameters:
+\emph{gindent -kr -ncs \textless{}file\textgreater{}.c}
+\item Functions and global variables which are specific to the current module
+should be declared \emph{static}, and their prototypes should be in
+a private headerfile or in the current C source file, not in a public
+headerfile which is included by any other C source module.
+\item Macros and variables directly refering to hardware architecture-specific
+registers should use the \emph{volatile} keyword.
+\item Every function must have a corresponding prototype, defined either
+at the top of the current C file (if static) or in a corresponding
+headerfile (public ones).
+\item For kernel code, the conventions should be followed about the choice
+of variable types to use (described in the previous section).
+\item No C++ or other language should be used within the kernel code. Of
+course there is no such restriction for any user program.
+\item Code should obviously be commented as required for clarity, but \emph{``/{*}''}
+and \emph{``{*}/''} C-style delimited comments only are allowed,
+not \emph{``//''} C++ ones.
+\item Code should not invoke general purpose memory allocation routines
+when a special fast access pool was provided already to allocate and
+free these types of items. Where appropriate, the general kernel objects
+pool system should be expanded when a new object is frequently allocated
+and freed, rather than using the general purpose management functions.
+These obviously should be common, machine-independent objects (which
+can possibly use machine-specific definitions, if they become standard
+and documented in this document so all ports provide them). See the
+memory management section later on for more information.
+\item General purpose libraries supplied in \emph{src/common/kernlib/} should
+normally have each function implemented as a separate C file into
+the library's directory. During the build process they will get compiled
+independently, and then archived together using \emph{ar}. \emph{ranlib}
+will then be executed on the archive. This ensures that unused functions
+do not be included into the end kernel result, reducing kernel size
+considerably when full multipurpose libraries are used (such as complete
+string libraries).
+\end{itemize}
+
+\paragraph{Assembly sections}
+
+For assembly sections, the AT\&T style should be observed, and the
+assembly should not be embedded into the C code using inline assembly
+routines. Often a library requireing both assembly and C will at build
+time assemble it's assembly section file (\emph{.s}), compile it's
+C part (\emph{.c}), and link the two together into an object file
+(\emph{.o}) using the \emph{-r} linker switch, which then gets linked
+with the kernel. In other situations one may want to instead compile
+all modules to objects (\emph{.o}), create an \emph{ar} archive (\emph{.a}),
+run \emph{ranlib} on it, and link it to the kernel (in which case
+all unused functionality which was isolated into it's own module does
+not get included by the linker, reducing kernel size). This applies
+to both processor-specific and architecture-specific backends. The
+rest is written in C. It is encouraged to write most of the architecture-specific
+boot loader code in C and provide a companion assembly file to interface
+and call the C loader main function. This minimizes assembly code,
+and C is more consistant and readable, it can be more suitable to
+sometimes write tricky sections like relocators, etc.
+
+The assembly sections should ensure to be reeintrant, that is, using
+the stack to save registers rather than using temporary registers
+to save other registers, and using the stack as well for temporary
+variables for which registers cannot be used, rather than static memory
+locations. These are usually indended to be called from C, and because
+of the way Xisop shared libraries work, is a main reason to follow
+these directives. An assembly section which is known to execute uninterruptably
+may at it's discretion use static memory if needed.
+\begin{itemize}
+\item Assembly files should have the following lowercase suffix: \emph{.s}
+\item Tabulation should be set to use real tabs (not spaces), with a standard
+tab width of 8.
+\item Assembler opcodes should be located after the first tab.
+\item Operands should be located after the second tabulation.
+\item Where more than an operand is required and are separated by a comma,
+a space is required after the comma.
+\item Opcode names should be lowercase, and must match those shown by objdump
+when dissassembling. This allows consistancy between all code for
+a particular processor. Although this may sound tidious at first,
+it is not as hard as it sounds to learn the specific mnemonic names
+objdump displays, with some little practice. Adventages results in
+consistency, where it also becomes possible to locate specific instructions
+in the code with regular expressions, etc.
+\item \emph{.equ} and \emph{=} directives, if any, should be located at
+the top of the assembly file.
+\item \emph{.globl} directives to declare public functions should also be
+located at the top of the file.
+\item All code should be within the \emph{.text} section, along with any
+static memory variables if need be (although use of these is discouraged,
+except for instance in the kernel loader bootblock where they can
+be useful, or in special context code where one knows what he's doing
+rather than only using the stack).
+\item A comment on a line or two should be placed before each function,
+especially the ones which are intended to be called from C, along
+with the C prototype.
+\item Other comments should be found along the code where required for obviousness.
+\item Obviously, registers which a function modifies should be saved in
+the stack, and restored upon function return, except (if any) the
+register corresponding to the return code expected in C for that processor.
+\item Interrupt, trap and exception assembly sections should normally save
+all registers which are commonly used for the particular processor,
+and restore them before returning. It is wrong to assume that C compiled
+functions always save all registers they modify other than the expected
+result register. This was learned from experience using GCC.
+\end{itemize}
+
+\subsection{Xisop scheduler and inter-task communication}
+
+
+\subsubsection{The multitasking scheduler}
+
+The scheduler currently allows to set priorities for each task, between
+-128 and 127. It is preemptive and will make sure to allow other tasks
+to run even when a particular task hugs the CPU by not going to sleep.
+A task can be in two main states: running, and sleeping.
+
+When a task sleeps, it has a mask of signals that will awake it as
+soon as possible if it receives any signal it waits for, and leaves
+more opportunities for other tasks to execute their shores when it
+is sleeping. When a task runs, it usually executes it's shores and
+goes back to sleep for the next event to process, when running in
+a multitasking system. However, if it does not return to sleep fast
+enough, the scheduler preemtive nature will suspend it and allow other
+tasks to also get a fair CPU time share, depending on the priority
+of the running tasks, unless the task has disabled scheduling, in
+which case it will remain running until it decides to delegate control
+to the system again.
+
+The task priority controls the speed and frequency at which a running
+task awakes, or runs. What the scheduler does is assign a set of credits
+to all tasks in the run queue, according to their priority one another.
+Then using round-robin at each scheduler round, the task with the
+highest amount of credits is given some CPU time, and a credit is
+taken out from it. If a task expired it's credits, it is no longer
+given a round, until all other tasks also expired their credits. When
+this happens, all tasks are given credits according to their priority
+again. Some care is taken to not constantly give a turn to the last
+task even if it has more credits, to allow to make the best out of
+Xisop asynchroneous facilities, but such a high priority task will
+have more turns within the run still, observing it's relative priority
+to the others.
+
+When a task goes to sleep, it is immediately taken out of the run
+queue and will not be awaken until a signal it awaits for is received.
+When it does, it will be moved in the running queue as fast as possible,
+at which point the time elapsing before it can act to the signal is
+directly dependent on the priority of the task related to the other
+ready to run tasks. However, when the task is moved in the run queue,
+it is immediately given it's credits at the maximum it's priority
+permits, thus increasing the chances it can answer in a fast manner
+among the other tasks in the run queue, which may already have been
+there before, and elapsed their credits.
+
+This means that if all tasks run with the default priority of 0, they
+all get a fair share of the CPU, and are naturally awaking very fast
+when one get a signal. In the case where one of the tasks remains
+running, the speed of signal responsiveness will ususally consist
+of the frequency of the scheduler. This frequency is usually configurable,
+and depends on the capacity of the timers available for the particular
+architecture (and of course on CPU speed).
+
+In the case where the scheduler detects that all tasks are sleeping,
+it attempts to reduce it's CPU usage by calling the \emph{\_idle()}
+processor-specific function, which will only awaken the scheduler
+again when the next interrupt, trap or exception occurs. It is possible
+in Xisop to have dead locked tasks, if they decide to wait for no
+signals, or if they wait for a signal to occur which never does.
+
+Following are described all functions which are related to tasks and
+scheduler, or which are useful to synchronize resources, other than
+the \emph{signal\_t} and \emph{port\_t} based systems, which are described
+in a further section.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{task\_t~{*}task\_alloc(int~({*}start)(void~{*},~void~{*}),}}] \emph{void~{*}res,~void~{*}args,~priority\_t~priority,~size\_t~stacksize,~u\_int8\_t~flags)}
+Allocates a task which can then be started or freed back. \emph{start}
+specifies the entry point function, \emph{res} an optional pointer
+to a buffer for results which the task may need to use or NULL, and
+\emph{args} an optional pointer to a buffer which may be used by the
+task to obtain it's argument, or NULL. When \emph{start} is called,
+\emph{res} is passed as the first argument and \emph{args} as the
+second one. \emph{priority} consists of the task initial running priority
+which may be in the range of -128 to 127, 0 being the normal running
+priority. \emph{stacksize} specifies the size of the stack in bytes
+which should be dedicated to the task, a common size being 4096 bytes.
+\emph{flags} may be 0, or ORed \emph{TS\_}{*} flags which are defined
+in \textless{}\emph{src/common/kernel/task.h}\textgreater{}. The task
+is not yet launched by Xisop. If the \emph{TS\_SHARED} flag is supplied,
+this task will use the \emph{mpool\_t} of it's parent (the current
+task which allocates it). This means that all memory allocated by
+one of the tasks sharing a memory pool is inherently shared. One task
+ending will not cause the allocated regions to be freed unless explicitely
+freed. When all tasks shareing a memory pool exit, all allocated memory
+by any of them is automatically freed back. This feature can be used
+when memory should inherently be shared among the tasks, or when memory
+resources are very scarce. However, unlike using Xisop messages which
+provide synchronization to share arbitrary memory regions among tasks,
+implicit synchronization should be used by the tasks when accessing
+the same shared memory locations which they should access concurrently.
+For this, \emph{rwlock\_t} and \emph{\_lock\_t} based systems can
+be used, or a custom system based around Xisop signals and/or messages.
+\item [{\emph{task\_t~{*}task\_free(task\_t~{*}task)}}] Allows to free
+\emph{task} which was previously allocated by \emph{task\_alloc()}.
+Only tasks which have been allocated but which have not been launched
+may be freed using this function, or it internally does nothing. NULL
+is returned. The kernel automatically frees tasks which have been
+launched when they exit. When a task is freed, all the resources it
+allocated using standard Xisop functions are automatically freed back
+to the system as well. The exception is when the task was setup with
+the \emph{TS\_SHARED} flag, where the memory is only freed when all
+tasks sharing that memory pool ended. This does not affect message
+ports, signals, devices, libraries or handlers, however, which are
+released by each task, always, as they exit.
+\item [{\emph{bool~task\_start(task\_t~{*}task)}}] Launches \emph{task}
+which should have previously been allocated using \emph{task\_alloc()}.
+The task is moved to the ready queue and will start executing as soon
+as the current task yields calling \emph{\_yield()} or is preempted
+by the scheduler. The delay for it to actually execute also depends
+on the relative priority of the tasks on the ready queue and their
+current credits. If synchronization is needed with it's startup, signals
+or messages can be used. TRUE is returned on success, or FALSE if
+the task is invalid, or was already launched.
+\item [{\emph{bool~task\_end(task\_t~{*}task)}}] Immediately forces termination
+of the specified \emph{task}, which may consist of the current task,
+or of another task. The task is cleanly freed as if it exited itself.
+Can also be used on a task which is locked on the waiting queue, perhaps
+waiting for events it will never receive. When a task ends and needs
+to be freed, it is moved in a queue for a dedicated task called the
+reaper, which chores consist of freeing all resources related to each
+task and the tasks themselves on it's own scheduler CPU time slices.
+Other tasks and the kernel are then releaved from that work. When
+a task ends it will soon automatically be freed by Xisop, and the
+resources it allocated are automatically freed as well.
+\item [{\emph{void~\_yield(task\_t~{*}task)}}] Permits a currently running
+task to immediately yield control back to the scheduler to allow other
+tasks to have an immediate opportunity to execute, rather than leaving
+the preemtive scheduler interrupt it. The task is not moved to the
+wait queue, and will have an opportunity to resume again very soon.
+\emph{task} consists of a suggestion to which task to delegate control
+to, which should also currently be in the ready queue. When \emph{task}
+is invalid or NULL, the scheduler is left to decide which task to
+execute next.
+\item [{\emph{void~task\_sleep(task\_t~{*}task,~u\_int32\_t~flags,~task\_t~{*}yield)}}] Allows
+to immediately switch the specified task (which may also be the currently
+running task) to the waiting queue. The task will be unable to execute
+again until it is specifically moved back again on the ready queue
+by calling \emph{task\_wakeup()} on it with at least one of the same
+bits in \emph{flags}. This can be useful when custom interrupt attached
+code hooks need to synchronize tasks and such and that signals and
+message ports are not desired. If the task being put to sleep consists
+of the current task, \emph{yield} can specify another optional ready
+task to run immediately, if non-NULL.
+\item [{\emph{bool~task\_wakeup(task\_t~{*}task,~u\_int32\_t~flags)}}] Immediately
+awakes the specified task if it currently is sleeping in the waiting
+queue. This is normally used after a \emph{task\_sleep()} call was
+made on the task. However, it is possible to use this function to
+wake a task which is waiting for a signal as well if \emph{TSF\_SIGNAL}
+flag is specified. This is normally used by custom interrupt hooks
+which need to synchronize tasks, when they cannot use signals or message
+ports. They then can share a \emph{fifo\_t} buffer, or custom \emph{list\_t}
+queue, with the wanted tasks and cause them to awake and sleep at
+will for instance. The task is only awaken if at least one bit supplied
+in \emph{flags} matches one of the bits of the \emph{flags} which
+were used at \emph{task\_sleep()}. TRUE is returned if the task could
+be awaken, or FALSE if the flags do not permit to awake it or another
+problem occurs.
+\end{lyxlist}
+The current sleeping flags are described as follows (as defined in
+\textless{}\emph{src/common/kernel/scheduler.h}\textgreater{}) :
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{TSF\_KERNEL}}] Kernel-reserved, used by the task reaper for
+instance.
+\item [{\emph{TSF\_SIGNAL}}] Task is waiting for the reception of at least
+of one of the signal bits in \emph{task\_t-\textgreater{}sigwait}.
+Internally used bu the signal subsystem.
+\item [{\emph{TSF\_CUSTOM}}] As the name implies, may be used by user tasks.
+\end{lyxlist}
+Here are then described the scheduler control functions:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{priority\_t~task\_getpriority(task\_t~{*}task)}}] Obtains
+the current running priority level of \emph{task}.
+\item [{\emph{priority\_t~task\_setpriority(task\_t~{*}task,~priority\_t~p)}}] Permits
+to change the running priority of \emph{task} to \emph{p}. Returned
+is the previous priority of \emph{task} which could be used to restore
+it.
+\item [{\emph{void~sched\_disable(void)}}] Allows to disable the preemptive
+scheduler, which will only be re-enabled when a corresponding number
+of \emph{sched\_enable()} have been called, as the scheduler lock
+consists of a recursive \emph{\_rlock\_t}. It is important to not
+call \emph{yield()}, \emph{port\_wait(), port\_send(), signal\_send()}
+or \emph{signal\_wait()} when the scheduler is disabled, because it
+would prevent the task from ever being awaken again. Obviously, this
+call should be used with care, if any.
+\item [{\emph{void~sched\_enable(void)}}] Re-enables the scheduler if
+the same number of instances of this function matched with the previous
+\emph{sched\_disable()} calls.
+\end{lyxlist}
+
+\subsubsection{Locks and synchronization primitives}
+
+Other synchronization systems such as signals and message ports are
+later described in a next section. However, these are also very useful
+synchronization primitives which Xisop provides to both kernelspace
+and userspace software:
+
+
+\paragraph{Exclusive access locks}
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_lock\_init(\_lock\_t~{*}lock)}}] Initializes an
+exclusive access a lock. This has to be used before using other functions
+\emph{lock}.
+\item [{\emph{void~\_lock\_acquire(\_lock\_t~{*}lock)}}] This function
+is not multitasking-friendly in that the current task loops in an
+endless loop until exclusive obtention of the \emph{\_lock\_t} is
+acquired. Tasks should normally use \emph{lock\_acquire()} instead.
+\item [{\emph{void~\_lock\_release(\_lock\_t~{*}lock)}}] Immediately
+releases the exclusive \emph{\_lock\_t} \emph{lock} to allow another
+locker to obtain it.
+\item [{\emph{bool~\_lock\_try(\_lock\_t~{*}lock)}}] Attempts to exclusively
+acquire \emph{lock}, but returns immediately with FALSE if it cannot.
+TRUE is returned on success.
+\item [{\emph{bool~\_lock\_available(\_lock\_t~{*}lock)}}] Returns TRUE
+if there currently are no locker on \emph{lock}, but does not attempt
+to lock it. It is unsafe to attempt to implement \emph{\_lock\_try()}
+using this function, obviously.
+\item [{\emph{void~lock\_acquire(\_lock\_t~{*}lock)}}] Similarily to
+\emph{\_lock\_acquire()}, locks execution of the current task until
+\emph{lock} is exclusively obtained. This function is however better
+according to multitasking as it immediately yields CPU time to allow
+the current locker to free it as soon as possible for the current
+task to own it.
+\item [{\emph{void~lock\_release(\_lock\_t~{*}lock)}}] Identical to \emph{\_lock\_release()},
+made to match \emph{lock\_acquire()} for consistency.
+\end{lyxlist}
+
+\paragraph{Recursive locks}
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_rlock\_init(\_rlock\_t~{*}lock)}}] Initializes a
+recursive lock of type \emph{\_rlock\_t}. This needs to be performed
+before calling other recursive lock operations on \emph{lock}. Recursive
+locks are different from exclusive locks in that there can be any
+number of concurrent lockers at the same time. They are usually used
+for systems which execute at intervals, like the Xisop scheduler and
+interrupt facilities which also make use of this system. They can
+then make sure to be the only locker before performing their critical
+work. This way arbitrary tasks may disable the facilities safely by
+locking the lock, and unlocking it when they are done with their critical
+section.
+\item [{\emph{void~\_rlock\_acquire(\_rlock\_t~{*}lock)}}] Locks recusively
+the \emph{lock} \emph{\_rlock\_t}. This basically atomically increases
+the lockers counter of the lock, and never fails. It always returns
+immediately.
+\item [{\emph{void~\_rlock\_release(\_rlock\_t~{*}lock)}}] Releases the
+\emph{lock} \emph{\_rlock\_t}. Note that the same number of release
+operations must be performed on \emph{lock} for it to become available
+again. This only atomically decreases the lockers counter of the lock,
+and returns immediately.
+\item [{\emph{bool~\_rlock\_trylock(\_rlock\_t~{*}lock)}}] If the lock
+is free/available, that is, no current lockers exist on \emph{lock},
+this function atomically locks it and returns TRUE immediately. Otherwise
+it returns FALSE and returns immediately, in which case the lock is
+left in it's original state before the call. This can be very useful
+for an event-driven system which needs to make sure that the lock
+is free to perform it's tasks, but also needs to prevent it's own
+recursion. Obviously, if it returned TRUE, \emph{\_rlock\_release()}
+is expected to be called when done.
+\item [{\emph{bool~\_rlock\_available(\_rlock\_t~{*}lock)}}] Returns
+FALSE if there are any lockers on \emph{lock}, or TRUE if the lock
+is currently free from any lockers. This however only performs the
+check, and does not change the lock state. It is unsafe to use this
+function along with \emph{\_rlock\_acquire()} to implement a \emph{\_rlock\_trylock()}
+replacement as it would not be atomic.
+\end{lyxlist}
+
+\paragraph{Read/Write locks}
+
+These locks internally consist of a combination of exclusive and recursive
+locks. They are ideal for instance to protect synchronization of resources
+where multiple readers are allowed but that exclusive access is required
+for write operations. There currently is provided no way to upgrade
+a currently held shared access lock to an exclusive lock, or to downgrade
+an exclusively held lock to a shared access lock, other than releasing
+the lock and re-locking it. However, if this proves necessary in the
+future, we shall implement these features. These locks are especially
+adequate to protect resources which are frequently accessed in read-only
+mode, but which occasionally need to be updated, which obviously requires
+write/exclusive access, which is the case with several Xisop system
+lists, and these locks are then used by the involved kernel functions
+as well.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~rwlock\_init(rwlock\_t~{*}lock)}}] Initializes \emph{lock},
+which is necessary before using any other \emph{rwlock\_}{*}\emph{()}
+function on it.
+\item [{\emph{void~rwlock\_acquire(rwlock\_t~{*}lock,~bool~exclusive)}}] Locks
+the current task until the \emph{lock} \emph{rwlock\_t} can be exclusively
+accessed (for read and/or writing access) if \emph{exclusive} is TRUE,
+or until a shared recursive access is obtained (for read-only access)
+if \emph{exclusive} is FALSE. Is multitasking-safe.
+\item [{\emph{void~rwlock\_release(rwlock\_t~{*}lock)}}] Releases the
+access on \emph{lock} which was obtained using \emph{rwlock\_acquire()}
+or \emph{rwlock\_try()}. Whether this access was exclusive or shared
+is internally remembered.
+\item [{\emph{bool~rwlock\_try(rwlock\_t~{*}lock,~bool~exclusive)}}] Very
+similar to \emph{rwlock\_acquire()} but always immediately returns
+with FALSE if the access cannot be obtained immediately. TRUE is returned
+with the lock held on success.
+\item [{\emph{void~rwlock\_upgrade(rwlock\_t~{*}lock)}}] Permits to upgrade
+an already obtained shared lock to an exclusive lock. The current
+task may sleep as required until all shared lockers free their lock.
+The caller \emph{MUST} already be holding the lock in shared mode.
+This function is most useful for operations such as check-and-modify,
+when read-only access is generally required to a resource, but that
+under certain conditions write access is needed to modify the resource
+after the check.
+\item [{\emph{void~rwlock\_downgrade(rwlock\_t~{*}lock)}}] Conversely
+to \emph{rwlock\_upgrade()}, allows to downgrade an already obtained
+exclusive lock to a shared lock. The caller \emph{MUST} already be
+holding this lock in exclusive mode. The usefulness of this function
+is questionable. Although provided, the kernel does not use it.
+\end{lyxlist}
+
+\paragraph{System lists access}
+
+Several system lists require internal \emph{rwlock\_t} for synchronization
+against corruption. In \textless{}\emph{common/kernel/main.h}\textgreater{}
+are defined several macros which can be used to access those securely
+by kernel functions. The \emph{enum systables} specifies various system
+lists which can be accessed using these methods, called \emph{SYSTABLE\_}{*}.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~SYSTABLE\_RLOCK(enum~systables~table)}}] Locks the
+\emph{rwlock\_t} of the specified \emph{table}, in shared mode (read-only
+access).
+\item [{\emph{void~SYSTABLE\_WLOCK(enum~systables~table)}}] Locks the
+\emph{rwlock\_t} of the specified \emph{table}, in exclusive mode
+(read/write access).
+\item [{\emph{void~SYSTABLE\_UNLOCK(enum~systables~table)}}] Unlocks
+the \emph{rwlock\_t} of the specified \emph{table}, which should have
+previously been locked using \emph{SYSTABLE\_RLOCK()} or \emph{SYSTABLE\_WLOCK()}.
+\item [{\emph{void~SYSTABLE\_UPGRADE(enum~systables~table)}}] Allows
+a caller which \emph{MUST} hold a shared read-only access lock (after
+using \emph{SYSTABLE\_RLOCK()}) to upgrade the lock to exclusive mode.
+\item [{\emph{hashtable\_t~{*}SYSTABLE(enum~systables~table)}}] Returns
+the \emph{hashtable\_t} pointer associated with the system list \emph{table}.
+Obviously, this should only be used when the lock is held, and should
+only be used for the access corresponding to the currently obtained
+lock type.
+\end{lyxlist}
+The following two functions, as opposed to macros, are implemented
+as C functions and perform boundary checking on the arguments, as
+they are provided for user tasks rather than for the kernel, for which
+the previous macros were designed:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{hashtable\_t~{*}systable\_lock(u\_int32\_t~systable,~bool~exclusive)}}] Attempts
+to lock access to the system list \emph{systable}, in exclusive or
+shared mode. A pointer to the \emph{hashtable\_t} is returned on success,
+or NULL otherwise. As usual, shared locks should be obtained when
+read-only access is performed on a list, but an exclusive lock is
+required if there is any need to modify a system list.
+\item [{\emph{void~systable\_unlock(u\_int32\_t~systable)}}] Unlocks
+a previously held lock for \emph{systable}, which should have previously
+been obtained using \emph{systable\_lock()}.
+\item [{\emph{void~systable\_upgrade(u\_int32\_t~systable)}}] Upgrades
+a previously held lock for systable in shared mode to exclusive mode.
+The lock \emph{MUST} previously be obtained in shared mode.
+\end{lyxlist}
+
+\subsubsection{Signals}
+
+Very few signals are reserved by the system, SIGTERM and SIGPOLL,
+respectively. As Xisop currently supports 32 different signals per
+task, this results in 30 user signals the applications programmer
+may play with. Signals are internally implemented as bits, and are
+not reliably queued, which means that although a task will always
+know that a particular signal was received, it cannot know if it occured
+more than once before it had the chance to process it. It ressembles
+alot to a hardware bus line, which can be activated by the other end,
+although our capacity to monitor a single signal state is dependent
+on the rate at which we run.
+
+Note that sending a SIGTERM signal to a task does not force it to
+exit. It merely consists of a request to exit to the task, and the
+task may ignore it or respect it.
+
+\emph{XXX 32 is no longer a fixed value now that signum\_t and sigmask\_t
+are abstracted and could be set by the port-specific code.}
+
+Message ports are used when the need for reliable event queuing is
+met. The signals merely allow a task to sleep and be awaken on specified
+events, like a message arriving on a port, which internally uses a
+signal bit.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{signum\_t~signal\_alloc(void)}}] Attempts to allocate an
+available signal bit from the current task. Returns the signal number
+allocated, or -1 if no more signals available.
+\item [{\emph{void~signal\_free(sigmask\_t~sigmask)}}] Frees all specified
+signals in \emph{sigmask}, which should previously have been obtained
+using \emph{signal\_alloc()}. If reserved signals are part of the
+supplied \emph{sigmask}, those are ignored.
+\item [{\emph{sigmask\_t~signal\_wait(sigmask\_t~sigmask,~task\_t~{*}task)}}] Suspends
+the current task until at least one of the supplied signals in \emph{sigmask},
+or a system reserved signal occurs. Returned is the mask of signals
+we received which caused an awakening. Multitasking-friendly applications
+usually spend most of their time suspended by this call, and are awakening
+to perform their operations asynchroneously, and go back to sleep
+as soon as possible, to allow other tasks to also respond and execute
+efficienty. However, because of the nature of the preemptive scheduler,
+a task which remains in running state will not prevent others from
+executing. \emph{task}, which may be NULL, optionally specifies which
+task should be favored as a suggestion to the scheduler, which allows
+to implement cooperative tasks more efficiently. The current task
+is guaranteed to awake at the occurance of the specified signals,
+but will not be able to determine how many occurances of each signal
+occurred as no queueing is performed.
+\item [{\emph{void~signal\_send(task\_t~{*}task,~sigmask\_t~sigmask)}}] Atomically
+sends the supplied signals in \emph{sigmask} to the specified \emph{task}.
+The task, if suspended waiting for signals, is awaken if a signal
+it waits for is included in \emph{sigmask}, and will have a chance
+to run. The delay elapsing between \emph{signal\_send()} and the task
+being able to process the signal depends on three factors:
+
+\begin{itemize}
+\item The speed at which the current task returns to sleep (using \emph{yield()},
+\emph{port\_wait()} or \emph{signal\_wait()}).
+\item If it does not return to sleep, the current task will continue running
+until it is preempted by the scheduler, which is dependent on the
+scheduler timer interrupt frequency.
+\item The priority of the tasks in the ready queue, that is, which are currently
+awake. This factor takes place after the other end was awaken, and
+before it gets an opportunity to actually execute.
+\end{itemize}
+\item [{\emph{sigmask\_t~SIGMASK(signum\_t~signum)}}] Consists of a useful
+macro to convert a signal number (\emph{signum\_t}) to a signal mask
+(\emph{sigmask\_t}). Those may then be ORed together (using C '\textbar{}'
+bitwise operator character) to represent multiple signals.
+\end{lyxlist}
+
+\subsubsection{Message ports}
+
+In the UNIX world, this is called Inter Process Communication (IPC).
+In the case of Xisop, we communicate between light-weight tasks, rather
+than between full fledged processes, using signals, datagram messages
+and connectionless, unidirectional ports. The Xisop port functions
+internally operate using signal primitives and message queues (in
+FIFO order). These are safe to call from userspace as well as kernelspace
+tasks. However, it is not safe to transfer messages among ports in
+an interrupt handler context without using \emph{\_splhigh()} for
+synchronization. \emph{XXX}
+
+A Xisop message consists of an arbitrary sized object prefixed with
+a \emph{message\_t} structure, which is internally used for message
+queueing and replying information. Because the message is internally
+``moved'' by only swapping pointers efficiently, memory copy operations
+are minimized. However, this also means that the original creator
+of the message, as well as the other end to which the message is passed,
+are responsible to synchronize operations properly among eachother
+on the message memory area (more information on this below). The \emph{message\_t}
+header starts with a \emph{pnode\_t} internally, which means that
+the user can use \emph{pool\_t} primitives to efficiently and arbitrarily
+create and destroy messages. It also means that at their discretion
+the ends are able to internally queue the message in custom \emph{list\_t}
+lists when necessary (after \emph{port\_get()}, and taking care to
+unlink it before \emph{port\_send()}/\emph{port\_reply()}, obviously).
+
+Some care was made when implementing Xisop message ports to take in
+consideration tasks and or ports which may be destroyed before a message
+is replied back by the other end, or for cases where a public port
+address, after being obtained once, becomes invalid as the public
+service dies. Instead of implementing a higher overhead or less versatile
+unique port ID allocation, validation and lookup system, or using
+expensive string operations with a \emph{hashtable\_t} using \emph{hashtable\_lookup()}
+for every message send, the following techniques were implemented:
+\begin{itemize}
+\item A special magic cookie is set on a valid, existing port. This means
+that when attempting to perform any operation on a \emph{port\_t}
+pointer which does not resolve to an actual, currently valid port,
+operation is refused to take place. When a message port is destroyed,
+that magic number is reset to zero, which renders it unusable.
+\item Because an efficient \emph{pool\_t} is used to allocate and free back
+\emph{port\_t} objects, it would be possible for an intended reply
+port to be destroyed, and for another port, belonging to any task,
+to be created at the same address. To solve this issue, each port
+also comports an internal unique ID. When a message is sent to a port,
+from which a reply is expected, the \emph{message\_t} is made to remember
+both the reply \emph{port\_t} address and unique ID. When attempting
+to reply, the \emph{port\_t} validity is performed as usual via the
+magic number, and the unique ID is then evaluated for a match. This
+way, a reply message will never be queued back on an unexpected port,
+or to a nonexisting one which may just have died.
+\item The unique ID supplied to a port only consists of an unsigned 32-bit
+integer, which is obtained from a global shared counter, which is
+incremented and used whenever required. This means that the odds of
+another \emph{port\_t} using the same address and ID within the delay
+of a send/reply are probably always none.
+\item Using this method prevented restrictions on the maximum number of
+ports and tasks which can exist in Xisop. The overhead is also smaller
+than having to run through an array looking for an empty slot, and
+having to re-allocate the memory area to dynamically grow or shrink
+it, because without MMU support alot of memory copying would be required
+for those operations. Using a \emph{pool\_t} then is ideal for speed.
+Using a relatively fast lookup hash table would require a lookup to
+be performed before every message send, which was considered suboptimal
+when designing Xisop. Although \emph{port\_find()} uses this, it would
+have been absurd to need to perform this lookup before sending any
+message. Especially considering that locking must be used when accessing
+the system hash table for synchronization.
+\end{itemize}
+Usually, the tasks should be written to be reliable and to synchronize
+well within eachother. However, with these precautions, supported
+by well written applications, the \emph{port\_t} system is always
+very reliable and predictable. Here are described the functions:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{port\_t~{*}port\_create(const~char~{*}name)}}] Allows
+to create a message port on the current task. This internally also
+needs to allocate a signal bit using \emph{signal\_alloc()}, which
+is associated to the \emph{port\_t} for the \emph{port\_wait()} internals.
+NULL is returned on failure, or a pointer to the new \emph{port\_t}
+on success. \emph{name} is optional and should be NULL if the port
+does not need to be advertized to the whole system. If other tasks
+need to find our port by name, then \emph{name} will be usable with
+\emph{port\_find()} to locate it, and listing the system public ports
+would advertize it as well. Ports are generally private, except for
+special public services. The length of \emph{name} will be truncated
+to 32 characters if it is longer. If a public port is created, but
+that another public port bears the same name alerady, the operation
+fails. The port name is case-sensitive. If the task exists without
+closing it's ports, they are automatically destroyed by the kernel.
+\item [{\emph{port\_t~{*}port\_destroy(port\_t~{*}port)}}] Destroys a
+message port of the current process, which was created using \emph{port\_create()}.
+The internally allocated signal bit and memory are released back to
+the system. If any queued messages exist, the queue is lost, but the
+\emph{message\_t} objects are untouched, as they remain the responsibility
+of the application who created them. NULL is returned.
+\item [{\emph{port\_t~{*}port\_find(const~char~{*}name)}}] Allows to
+locate a public message port by name. If the port can be found, it's
+address is returned. NULL is returned otherwise. Because this needs
+to lookup through a system's public ports hash table it needs to lock
+it internally using a \emph{rwlock\_t} in shared access mode. The
+port name is case-sensitive.
+\item [{\emph{bool~port\_send(port\_t~{*}port,~port\_t~{*}replyport,~message\_t~{*}message)}}] Queues
+the supplied \emph{message\_t} to the specified \emph{port\_t} in
+FIFO order, and internally \emph{send\_signal()} the associated process
+with the internal port signal. This means that the other process could
+be sleeping using \emph{signal\_wait()} or \emph{port\_wait()} and
+will be awakened so that it may process the message. The supplied
+message then becomes owned by the other end, and should be left alone
+by the current task until a reply be obtained from the other side
+on the \emph{message\_t}'s \emph{replyport}. This \emph{port\_send()}
+and \emph{port\_reply()} mechanism serves for synchronization. This
+means that normally, \emph{replyport} is supplied the address of a
+local \emph{port\_t} used to receive results from the task we send
+messages to via it's own \emph{port\_t}. TRUE is returned on success,
+or FALSE if the message could not be delivered (in which case the
+supplied \emph{port\_t} address is probably invalid and a \emph{port\_find()}
+operation can be used again to attempt to locate the port, if it consists
+of a public port which should exist).
+\item [{\emph{message\_t~{*}port\_get(port\_t~{*}port)}}] If at least
+one message is available in the specified \emph{port\_t}, the first
+one is unqueued from it in FIFO order and the address to it is returned.
+Otherwise, NULL is returned.
+\item [{\emph{bool~port\_reply(message\_t~{*}msg)}}] Sends back the supplied
+\emph{message\_t} to the reply \emph{port\_t} of the task that previously
+sent it to us. This port corresponds to the \emph{replyport} argument
+that was used at \emph{port\_send()}. Normally, the other end waits
+until we are done with the message, and we use this function to notify
+that it can safely continue to do whatever it wants with the \emph{message\_t}
+data. TRUE is returned on success, or FALSE if no \emph{replyport}
+was set for the \emph{message\_t}, or that the reply port is no longer
+valid.
+\item [{\emph{port\_t~{*}port\_wait(port\_t~{*}{*}ports,~u\_int32\_t~num,~task\_t~{*}task)}}] Suspends
+the current task until a message is received through one of the supplied
+port(s) specified in the array of \emph{port\_t} pointers \emph{ports}.
+\emph{num} specifies the number of \emph{port\_t} pointers supplied
+in the ports array. \emph{task} specifies a suggestion preference
+of which task to switch to, or NULL to let the scheduler choose. Returned
+is the pointer to the \emph{port\_t} which received the message, or
+NULL if a reserved signal was the awakening cause. If one of the ports
+already has queued messages the task will not be set to sleep and
+the aforementionned port will be returned immediately. If it is necessary
+to monitor other signals as well as port message arrivals, it is advised
+to manually assemble the \emph{sigmask\_t} from all monitored signals,
+including the ones associated to the monitored ports, and to use \emph{signal\_wait()}
+instead. Evaluating the resulting \emph{sigmask\_t} will permit to
+know which ports received messages, if any. Use of the \emph{PORT\_SIGMASK()}
+macro will then be useful.
+\item [{\emph{bool~port\_flush(port\_t~{*}port)}}] Unqueues all pending
+messages in the supplied \emph{port\_t}, if any. This can be useful
+to discard unused \emph{port\_reply()} results which are obtained
+where no result codes are needed, rather than using a \emph{while()}
+loop of \emph{port\_get()} statements. Also useful before destroying
+ports when desired. Returns TRUE on success, or FALSE if the port
+is invalid. Should obviously not be used on other tasks' ports, only
+ours.
+\item [{\emph{sigmask\_t~PORT\_SIGMASK(port\_t~{*}port)}}] Is useful
+when it is necessary to know which signal bit is associated with a
+particular port. The returned \emph{sigmask\_t} can be ORed with the
+other masks to provide to \emph{signal\_wait()}. This way, it is possible
+for a task to monitor the state of other signals while at the same
+time monitoring message ports for events. This macro, just like \emph{SIGMASK()},
+should be used instead of expressions such as \emph{(1L \textless{}\textless{}
+n)} both for code obviousness and backwards compatibility, because
+the number of available signals could eventually grow.
+\end{lyxlist}
+
+\subsubsection{The special SIGPOLL signal and the poll port}
+
+\emph{XXX needs to be rethinked and re-written :)}
+
+As there only are 30 user signals, and that a message port is usually
+associated with a signal, it may be useful to assign more than one
+message port to a single signal, or process more than one event using
+a single signal and message port.
+
+The SIGPOLL signal is reserved for just that, and each task always
+has a message port associated with this signal. Through this port
+can be sent various type of messages for more than one event the task
+may want to be awakened for. This provides message multiplexing, while
+the method for multiple message ports using the same signal would
+provide port multiplexing. The reason why message multiplexing was
+chosen as a standard in Xisop was because it requires less resources.
+The more ports there are on the system, the larger the system ports
+pool grows and it will never shrink for considerations described in
+the previous subsection. \emph{XXX}
+
+This special system-reserved port can be used to transfer reliable
+signals, possibly emulating POSIX semantics, or to transfer many other
+types of events a task may all be waiting for. It also is useful to
+have a high number of concurrently opened high-level files, and implement
+filedescriptors. A special set of functions is provided by Xisop machine-independent
+layer to transfer messages through this port, and to evaluate the
+type of event that originated the message, along with message size.
+Because unlike for standard message ports where messages of a fixed
+size are usually transfered, the message size changes here, depending
+on the event type and message.
+
+\emph{XXX}
+
+
+\subsection{Xisop memory management system}
+
+Xisop provides three types of memory management primitives for the
+kernel. These are provided by the Xisop machine-independent layer.
+It also provides distinction between the various types of memory,
+when an architecture has more than one (i.e. Amiga CHIP and FAST RAM,
+peripheral memory, etc). Special care was used to prevent the memory
+management system from having to disable interrupts (which may be
+very useful when the \emph{\_FACILITY\_SCHEDTIMER} consists of the
+only timing source for an architecture and needs to be as reliable
+as possible). A \emph{\_lock\_t} is internally used by the system
+page primitives to sychronize access to the system page pools. This
+also avoids having to export them as system calls via traps.
+
+
+\subsubsection{Page primitives}
+
+The first level system consists of page allocation and freeing. The
+page size is dependent on architecture when MMU is concerned, however
+within Xisop which provides it's own memory management, a page is
+typically 4096 bytes. Primitives are provided to allocate a single
+page, or number of physically contiguous pages, and to free back one
+page, or a number of contiguous pages. At system initialization, the
+page pools are initiated to provide access to the physical memory
+areas, and are classified by memory type. There are a few functions
+also defined by Xisop which allow to add physical memory areas to
+the page pools, and specify their type, so that the architecture-dependent
+initialization code be simpler, and also that at runtime it be possible
+to attach new RAM which was mapped from external devices, possibly
+hot-pluggable ones such as PCMCIA memory cards, etc. Here are described
+the dynamic memory linking functions. Note that these functions internally
+use a \emph{\_lock\_t} which is acquired to access the system pages
+pools. This means that they are generally safe to call anytime, but
+from interrupt handler context. \emph{XXX}
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{mchunk\_t~{*}mchunk\_init(void~{*}mem,~size\_t~size)}}] Internally
+prepares the supplied memory block to pages which can later be linked
+into the system. The internal control structures are setup in hidden
+data which will not be added into the public pages. This is dependent
+on \emph{\_PAGE\_SIZE}, which should be defined by the port-specific
+\textless{}\emph{port/support.h}\textgreater{} headerfile. NULL is
+returned if the supplied memory area was too small to be split into
+pages and to store the necessary control data. Otherwise, a pointer
+to the \emph{mchunk\_t} is provided. After using this call, the memory
+area should never be manipulated anymore, other than using other Xisop
+standard calls, unless it is known that the area is not linked into
+the system pages. The supplied memory is expected to be physical contiguous
+memory.
+\item [{\emph{bool~mchunk\_attach(int~memtype,~mchunk\_t~{*}mchunk)}}] Allows
+to link an \emph{mchunk\_t} which was previously prepared using \emph{mchunk\_init()},
+to the system \emph{ppool\_t} associated with the specified memory
+type. After this is performed, it is possible to allocate memory pages
+from this memory chunk until it be unlinked using \emph{mchunk\_detach()}.
+This depends on \emph{\_MEM\_MAX}, which is defined by the port specific
+\textless{}\emph{port/support.h}\textgreater{} headerfile. TRUE is
+normally returned, unless the chunk is seen to already have been attached,
+or that the supplied memory type is invalid, in which case FALSE is
+returned. It is possible to setup and append as many \emph{mchunk\_t}
+as wanted. For instance, the port-specific code which sets up the
+kernel pages for available memory may need to call \emph{mchunk\_init()}
+and \emph{mchunk\_attach()} multiple times, one for each contiguous
+memory block. It is safe to call this function to attach new memory
+at system runtime, anytime.
+\item [{\emph{bool~mchunk\_detach(int~memtype,~mchunk\_t~{*}mchunk)}}] Permits
+to safely detach from the system an \emph{mchunk\_t} which previously
+was attached using \emph{mchunk\_attach()}. TRUE is returned on success,
+or FALSE if the memory type is invalid, if the supplied \emph{mchunk\_t}
+was not currently attached, or if any memory from that \emph{mchunk\_t}
+is still currently allocated, in which case the chunk is not unliked.
+\end{lyxlist}
+The first level of allocation primitives allow to allocate and free
+one or multiple contiguous pages of physical memory to and from the
+system pools (\emph{ppool\_t} of each memory type). Internally, the
+list of linked \emph{mchunk\_t} for a memory type is ran through.
+These functions also acquire the system pools safety lock while working
+on the system memory pools:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{page\_t~{*}pages\_alloc(int~memtype,~u\_int32\_t~many,~bool~zero)}}] Allocates
+\emph{many} contiguous memory pages of \emph{\_PAGE\_SIZE} bytes,
+of the supplied \emph{memtype}, which can be \emph{\_MEM\_ANY} in
+which case all memory types are tried sequencially, favoring the first
+memory type to the last. A \emph{page\_t} pointer is returned which
+can be used to access the memory area via \emph{page\_t-\textgreater{}address},
+or to free back the memory using \emph{pages\_free()}. NULL is returned
+if not enough memory can be found to satisfy the request. If \emph{zero}
+is TRUE and pages could be allocated, the memory area is zeroed using
+\emph{pageclr()}.
+\item [{\emph{bool~pages\_free(page\_t~{*}pages)}}] Releases to the system
+one or more contiguous memory pages which previously were allocated
+using \emph{pages\_alloc()}. TRUE is returned on success, or FALSE
+if the supplied pointer was NULL, or if the \emph{page\_t} was already
+freed back.
+\end{lyxlist}
+
+\subsubsection{Simple object pool primitives}
+
+The second level consists of a pool of fixed sized entities, the \emph{pool\_t}.
+A pool can be pre-allocated once, with a fixed maximum number of elements,
+setup to grow automatically when new elements are needed, internally
+allocating and preparing new pages as required, and can optionally
+also shrink smaller automatically, releasing back to the system the
+unused pages. When a pool is about to shrink, it evaluates statistics
+about the number of pages the pool normally holds on average, so that
+primitives to free the page are not called too often unnecessarily.
+Such pages are buffered by the pool for future use, if they are expected
+to be reclaimed back soon. Using these functions is more efficient
+in speed and memory than using page allocation primitives, calls to
+which it attempts to minimize, while filling each page of memory with
+the most objects possible.
+
+A C structure should be defined for the type of object which is to
+be allocated, and the first element of that structure should consist
+of a \emph{pnode\_t} element. These functions, unlike page allocation
+ones, do not synchronize if multiple tasks or interrupt handlers share
+a \emph{pool\_t}. The caller should therefore provide synchronization
+whenever necessary. However, if the \emph{pool\_t} allocates or frees
+system pages, the \emph{pages\_alloc()} and \emph{pages\_free()} functions
+are used which internally use synchronization to ensure that the system
+pools do not corrupt. These functions are mostly for kernel use. If
+used from userspace, these pools will not be automatically freed back
+to the system unless the tasks specifically destroys them before exiting.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{bool~pool\_init(pool\_t~{*}p,}}] \emph{u\_int32\_t~stepp,
+u\_int32\_t~minp, u\_int32\_t~maxp, size\_t~nodesize, int~memtype)}
+Initializes the supplied \emph{pool\_t} object \emph{p} to be used
+to allocate objects of \emph{nodesize} length (size which should include
+the \emph{pnode\_t} element). This size should be equal or smaller
+than \emph{\_PAGE\_SIZE} {*} \emph{stepp} / 2. \emph{stepp} specifies
+how many contiguous pages should be allocated and freed at once using
+\emph{pages\_}{*}\emph{()} primitives, when required. If \emph{stepp}
+appears too small to fit a useful number of nodes in a \emph{page\_t},
+it will be automatically grown until it reaches a maximum of 8, after
+which FALSE will be returned for failure (although there is no such
+limit for the \emph{stepp} argument itself when manually set high
+enough). Each \emph{page\_t} is then internally split into objects.
+\emph{minp} tells the minimum number of \emph{page\_t} which should
+always remain into the \emph{pool\_t}, or 0 if it is allowed to shrink
+totally when it needs no memory. The pool will initially allocate
+those at initialization, and it will never shrink smaller during it's
+lifetime, if non-zero. \emph{maxp} similarily specifies the maximum
+number of \emph{page\_t} which the \emph{pool\_t} should eventually
+grow to, or 0 for no limit. For instance, using \emph{minp} and \emph{maxp}
+of 0 allows the pool\_t to dynamically grow and shrink as necessary
+and it could eventually use all available RAM. Using a \emph{minp}
+and \emph{maxp} of 2 ensures that at least two \emph{page\_t} be initially
+allocated, which will never be freed back unless the \emph{pool\_t}
+is destroyed, and also tells that the pool should never allocate more
+pages. This can be useful in interrupt context or some situations
+where we do not want the system pool pages to be accessed. A fixed
+number of maximum object nodes will be available to allocate and free
+efficiently then. \emph{memtype} specifies the memory type which this
+pool will use to allocate the pages. It is invalid to specify \emph{\_MEM\_ANY}
+here. TRUE is returned on success, or FALSE on failure (invalid memory
+type or not enough available memory).
+\item [{\emph{bool~pool\_destroy(pool\_t~{*}pool)}}] Frees all memory
+currently being used by the specified \emph{pool\_t} and destroys
+the pool object, which can no longer be used by pool object allocation
+primitives unless it is re-initialized. Any currently allocated objects
+from the \emph{pool\_t} become invalid immediately and should therefore
+not be accessed anymore, they get freed as well. TRUE is returned
+on success, or FALSE if the supplied \emph{pool\_t} was not previously
+initialized successfully.
+\item [{\emph{pnode\_t~{*}pool\_alloc(pool\_t~{*}pool,~bool~zero)}}] Attempts
+to allocate a single object from the specified \emph{pool\_t}. The
+object size depends on the \emph{nodesize} parameter which was supplied
+at \emph{pool\_init()}. A pointer to the object is returned on success,
+or NULL if not enough memory is available, either for the \emph{pool\_t},
+if \emph{maxp} was non-zero, or system memory.
+\item [{\emph{pnode\_t~{*}pool\_free(pnode\_t~{*}node)}}] Releases the
+specified object \emph{node} which was previously allocated using
+\emph{pool\_alloc()}, back to the \emph{pool\_t} it belongs to. NULL
+is returned.
+\end{lyxlist}
+
+\subsubsection{General purpose memory pools}
+
+The third level memory management system, working with \emph{mpool\_t},
+consists of a number of \emph{pool\_t}, adapted to serve most byte
+requirement requests, through more standard malloc() and free() like
+functions. For a system with a \emph{\_PAGE\_SIZE} of 4096, \emph{\_MPOOLSTEP}
+of 1 and \emph{\_MPOOLS} of 7 and \emph{\_MPOOLSTART} of 16, there
+are 7 \emph{pool\_t}, deserved to serve element sized as closely possible
+to the requested number of bytes (smallest nodesize 16 + sizeof(mnode\_t)),
+and a \emph{list\_t} designed to hold \emph{page\_t} pointers to satisfy
+larger requests, which get rounded on page boundaries. An \emph{mpool\_t}
+is capable of serving requests for various memory types, including
+\emph{\_MEM\_ANY}, where the first memory types are privileged over
+the last ones. Like their \emph{pool\_t} counterparts, these functions
+do not perform any special synchronization which may be necessary
+if an \emph{mpool\_t} was shared among several tasks. Here are the
+functions related to the \emph{mpool\_t}:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{bool~mpool\_init(mpool\_t~{*}mpool)}}] Initializes an \emph{mpool\_t}
+to accept allocation requests. TRUE is returned on success, or FALSE
+if there is a problem initializing the \emph{pool\_t} elements, or
+if the supplied \emph{mpool} pointer is NULL. This function is dependent
+on the port-specific \emph{\_MPOOLS}, \emph{\_MPOOLSTEP, \_MPOOLSTART}
+and the \emph{enum \_memtypes} holding \emph{\_MEM\_MAX} which should
+have been defined in \textless{}\emph{port/support.h}\textgreater{}.
+\emph{\_MPOOLS} specifies the number of \emph{pool\_t} objects, \emph{\_MPOOLSTEP}
+the \emph{stepp} argument to \emph{pool\_init()}, \emph{\_MPOOLSTART}
+the maximum bytesize request for the first \emph{pool\_t}, and \emph{\_MEM\_MAX}
+the number of memory types supplied by the system. See the port-dependent
+section for more information on how to set these.
+\item [{\emph{bool~mpool\_destroy(mpool\_t~{*}mpool)}}] Frees all memory
+currently associated with the specified \emph{mpool\_t}, which should
+have previously been initialized by \emph{mpool\_init()}, and disables
+the \emph{mpool\_t}. Any pointers to memory which were obtained via
+\emph{\_malloc()} using this pool become invalid. No more requests
+will be allowed on this \emph{mpool\_t} unless re-initialized using
+\emph{mpool\_init()}. TRUE is returned, or FALSE if the \emph{mpool\_t}
+was already destroyed, or that the supplied pointer is NULL. It is
+also possible for this function to return FALSE without error, in
+the case where at least another task shares this \emph{mpool\_t}.
+(See the \emph{TS\_SHARED} flag to \emph{task\_alloc()}).
+\item [{\emph{void~{*}\_malloc(mpool\_t~{*}mpool,~int~memtype,~size\_t~size,~bool~zero)}}] Attempts
+to allocate the requested \emph{size} contiguous bytes from the supplied
+\emph{mpool}, using memory of type \emph{memtype}. \_MEM\_ANY is valid,
+and will cause any available memory type to be returned. A pointer
+is returned to a memory area holding the number of bytes that were
+requested, or NULL if there is not enough memory to satisfy the request,
+or if the parameters are wrong. If \emph{zero} is TRUE, the memory
+area is cleared with 0x00 bytes. Automatic synchronization is performed
+if the \emph{mpool\_t} is shared by more than one task.
+\item [{\emph{void~{*}\_free(void~{*}mem)}}] Frees back the memory to
+which the supplied \emph{mem} points, to where it belongs. NULL is
+returned. Automatic synchronization is performed if the \emph{mpool\_t}
+is shared by more than one task.
+\end{lyxlist}
+
+\paragraph{Kernel code}
+
+Here are variants which can be used by kernel functions. Note that
+the kernel can use all the above previously mentionned functions as
+well, however for consistency it is good to use the following where
+appropriate. All of these, contrary to the previously described primitives,
+internally use exclusive locks as necessary to ensure the integrity
+of the system pools, so that disabling the scheduler is unnecessary:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~{*}\_kmalloc(int~memtype,~size\_t~size,~bool~zero)}}] Allocates
+general-purpose memory from the kernel memory pool, which should be
+released using \emph{kfree()}. When a task uses this function the
+memory is not restored to the system automatically when it exists.
+Special syncronization is used internally so that it is safe to use
+by multiple tasks.
+\item [{\emph{void~{*}\_kfree(void~{*}mem)}}] Frees back to the kernel
+memory pools memory which has previously been allocated by \emph{kmalloc()}.
+Internal special synchronization is used.
+\item [{\emph{void~{*}TMALLOC(int~memtype,~size\_t~size)}}] Equivalent
+to calling \emph{kmalloc(memtype, size, FALSE);}
+\item [{\emph{void~{*}TCMALLOC(int~memtype,~int~number,~size\_t~size)}}] Equivalent
+to calling \emph{kmalloc(memtype, number {*} size, TRUE);}
+\item [{\emph{void~{*}MALLOC(size\_t~size)}}] Identical to calling \emph{kmalloc(\_MEM\_ANY,
+size, FALSE);}
+\item [{\emph{void~{*}CMALLOC(int~number,~size\_t~size)}}] Like calling
+\emph{\_kmalloc(\_MEM\_ANY, number {*} size, TRUE);}
+\item [{\emph{void~{*}FREE(void~{*}mem)}}] Equivalent to \emph{\_kfree(mem);}
+but made to match all above macros.
+\item [{\emph{void~{*}kmalloc(size\_t~size)}}] Like \emph{MALLOC()} but
+implemented as an ANSI-C compliant function.
+\item [{\emph{void~kfree(void~{*}mem)}}] Counterpart to \emph{kmalloc()}.
+\item [{\emph{pnode\_t~{*}spool\_alloc(u\_int32\_t~pool)}}] Allows to
+efficiently allocate a frequently used kernel object for which a special
+system pool exists. \emph{pool} may consist of one of the \emph{POOL\_}{*}
+names which are defined in the \emph{enum \_syspools} in \textless{}\emph{src/kernel/memory.h}\textgreater{}.
+Automatic synchronization is performed.
+\item [{\emph{pnode\_t~{*}spools\_free(u\_int32\_t~pool,~pnode\_t~{*}node)}}] Made
+to free a system object which was previously allocated using \emph{spool\_alloc()}.
+Automatic synchronization is performed.
+\end{lyxlist}
+
+\paragraph{User space tasks}
+
+The following can be called by user tasks to allocate memory using
+their own memory pool, which is automatically released back to the
+system when they exit. They behave identically to the standard ANSI-C
+functions bearing the same name. They are implemented as functions
+rather than macros, for inclusion into the Xisop shared library. These
+are also safe to use in the case where more than one tasks are sharing
+an \emph{mpool\_t} (see the \emph{TS\_SHARED} flag to \emph{task\_alloc()}).
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~{*}malloc(size\_t~size)}}] Behaves identically to
+the standard ANSI-C \emph{malloc()}.
+\item [{\emph{void~{*}calloc(int~number,~size\_t~size)}}] Identical
+to ANSI-C \emph{calloc()} semantics.
+\item [{\emph{void~{*}realloc(void~{*}ptr,~size\_t~size)}}] Like ANSI-C
+\emph{realloc()} semantics. Note that like the standard, the returned
+pointer can point to a new memory area, in which case the previous
+contents will have been copied over. The use of this function is generally
+discouraged against generally more efficient dynamic allocation techniques
+using linked lists. It is however provided for compatibility with
+ANSI-C.
+\item [{\emph{void~free(void~{*}ptr)}}] Again like the ANSI-C \emph{free()}
+function. Note that this function can also free memory which has been
+allocated using \emph{tmalloc()} and \emph{tcmalloc()}.
+\end{lyxlist}
+ANSI-C however has no concept of multiple memory types, and as such
+\emph{tmalloc()} had to be included. \emph{free()} can be used to
+free back memory which they allocate still:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~{*}tmalloc(int~memtype,~size\_t~size)}}] Like \emph{malloc()}
+but allows to specify a Xisop port-dependent memory type.
+\item [{\emph{void~{*}tcmalloc(int~memtype,~int~number,~size\_t~size)}}] Like
+\emph{calloc()}, but can also be told the type of memory wanted.
+\end{lyxlist}
+
+\subsubsection{A note about absolute memory allocation}
+
+Xisop does not provide an allocation function which can be told the
+absolute memory location area desired. There are several reasons for
+this which this section attempts to explain.
+
+Xisop provides the necessary inter-task communications tools to prevent
+the need of using absolute memory addresses for rendez-vous among
+tasks. Moreover, it has the concept of devices, which can be left
+the task to perform synchronization among tasks which need to share
+a specific resource. Additionally, Xisop does not setup the MMU in
+a way to prevent user tasks from accessing any memory.
+
+This means that if absolute memory locations need to be reserved by
+the system, they normally should not be included into the general
+purpose memory pools. A user device task can then specifically handle
+those locations as necessary and provide multitasking-friendly access
+to them.
+
+For instance, the video memory should not be attached to the system
+memory pools by the port-specific code. Instead, a device task should
+be written and provided to allow safe access to the video hardware,
+and basic console support. Optionally, a handler can be provided,
+which even allows a higher abstraction to access the device. For instance,
+the device could supply basic resource allocation and access primitives,
+while the handler could support vt100 emulation over the device.
+
+In the case of a single-tasking application being developped around
+Xisop, once the scheduler is disabled there is no need for any special
+handling to access the wanted memory regions. The memory allocator
+is no longer necessary to use, even.
+
+Another consideration to realize is that if for instance video memory
+was part of the system memory pools, it could automatically be allocated
+by another task which was only requesting some memory. If we had support
+for reserved pages, then there would be no point in allocating them,
+also. Only general-purpose memory should be attached into the system.
+There exists the possibility of reserving a specific memory type for
+some memory however, if there is a need for specific regions to only
+be used by certain applications but that general purpose management
+primitives are still desired.
+
+Other than the Xisop message port system which allows tasks to share
+and synchronize arbitrary memory regions, it is possible for several
+tasks to inherently share a common memory pool, using the \emph{TS\_SHARED}
+flag to \emph{task\_alloc()}. This can in some circumstances be used
+if the memory resources are quite scarce (many tasks which only allocate
+few but various sized memory blocks of different memory types can
+waste quite a large amount of pages. Using the same pool would then
+permit the same pages to be used among the tasks for their similar
+allocation needs. Their allocated blocks generally consist of a page
+which is split in equally sized blocks). Moreover, in such a setup,
+one task which allocates a block of memory does not implicitly free
+it on exit, if other tasks are still running sharing the memory. Those
+blocks need to be explicitely freed unless all tasks exit to really
+be released back to the system. Moreover, special synchronization
+must be used by the tasks if they want to access the same memory addresses.
+This is usually done using an \emph{rwlock\_t}, or disabling the scheduler
+temporarily.
+
+
+\subsection{Xisop public interrupt abstraction facilities}
+
+To allow Xisop architecture-specific devices to attach interrupt handler
+hooks, and for portable code to make use of a few basic interrupt
+facilities like timers, it is a good idea to provide a few access
+functions to allow this. The idea is to provide a facility which allows
+the kernel code, or userspace tasks, to run a piece of code once,
+a certain number of times, or indefinitely, as part of the low-level
+interrupt handling code. It thus should be possible to add and delete
+their code handlers from each of the wanted interrupt handlers. To
+provide this multi-purpose facility, the following system was developed,
+and almost entirely consists of portable common code.
+
+
+\subsubsection{Internals}
+
+The following structure is defined in \textless{}\emph{common/kernel/exception.h}\textgreater{}:
+\begin{quote}
+\emph{typedef struct \_int\_hook \{}\\
+\emph{~~~~pnode\_t node; }\\
+\emph{~~~~hookid\_t id;}\\
+\emph{~~~~u\_int32\_t skipcount, runcount;}\\
+\emph{~~~~void ({*}code)(hookid\_t, int, void {*}); }\\
+\emph{~~~~void {*}data;}\\
+\emph{\} hook\_t;}
+\end{quote}
+Where \emph{node} is used for internal linking, \emph{id} consists
+of a unique ID for this facility, \emph{skipcount} of the number of
+times this handler will execute before calling the \emph{code} hook,
+\emph{runcount} of the number of times the hook \emph{code} will be
+called before it gets automatically deleted, or 0 if it should execute
+everytime this interrupt occurs. \emph{void~({*}code)(hookid\_t,
+int, void~{*})} consists of the C function to invoke when the event
+occurs. The abstracted arguments \emph{void} pointer may serve any
+purpose the application wants. \emph{void~{*}data} pointer to abstract
+user-defined data will be passed as argument to the called function.
+The \emph{hookid\_t} argument will consist of the ID of the \emph{hook\_t}
+into the facility which caused the call, and is made to be unique.
+The supplied \emph{int} argument may be useless, or can serve to determine
+the origin of the interrupt, somewhat like the \emph{hookid\_t}, but
+will use a facility-specific semantics, which could include a key
+being pressed in the case of a keyboard interrupt, etc. The kernel
+uses an efficient memory \emph{pool\_t} to internally allocate and
+free these automatically when hooks are attached and detached from
+facilities.
+
+The following machine-independent function is also provided so that
+the port-specific code (from assembly or C) may easily order an execution
+of all attached hooks on a facility. The hook ids are made to be unique
+so that it is safe for the one who attached a hook to try to delete
+it, assuming that if it exists in the list, it cannot be any other
+hook supplied by other code (even if it expired and another hook replaced
+it internally). This consists of an interface for the port, not of
+the general user interface to the facilities:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~facility\_exechooks(u\_int32\_t~facility,~int~origin)}}] executes
+all attached code hooks of the specified \emph{facility}, sequencially
+(if any). This means that for each existing hook, the corresponding
+function is called if it's \emph{skipcount} is 0, or \emph{skipcount}
+is simply decreased by 1 otherwise. When the hook is to be called,
+it is passed the corresponding user data pointer (which can be NULL)
+to it, the \emph{hookid\_t} id for the hook, and \emph{origin} into
+the \emph{int} argument. The hook is then evaluated for expiration
+if \emph{runcount} was non-zero at insertion with \emph{hook\_attach()},
+and automatically destroyed if it expires. The caller should normally
+disable the interrupt associated with the facility temporarily before
+calling this function, however the associated \emph{facility\_t} internally
+uses an \emph{\_rlock\_t} to prevent self-recursion, lock which is
+also used by \emph{hook\_attach()} and \emph{hook\_detach()} for safety.
+This function is made for the port-specific code to call when the
+interrupt this facility is concerned with occurs. This function is
+dependent on \emph{\_FACILITY\_MAX} and the \emph{enum \_facilities}
+which are port-specific in \textless{}\emph{port/support.h}\textgreater{}.
+\item [{\emph{void~facilities\_init(void)}}] is provided to ease initialization
+of the system facility arrays from the port-specific code. This function
+depends on the port-specific \emph{\_FACILITY\_MAX} and the \emph{enum
+\_facilities} defined in \textless{}\emph{port/support.h}\textgreater{}.
+More informaton on port-specific initialization is provided in a next
+chapter.
+\end{lyxlist}
+Decision was made to provide the above functions even though their
+functionality is simple for a few reasons. It prevents code duplication
+among ports, minimises assembly sections in machine-dependent sections,
+and they are known to work, providing the required functionality.
+Being abstracted, their internals may change over time affecting all
+ports simultaneously without requireing changes in the machine-specific
+sections. Moreover, they use an internal memory \emph{pool\_t} per
+\emph{facility\_t} for efficiency. Once initialized, those will never
+need to query the system page primitives, and are thus very efficient,
+as well as safe to use from interrupt context without special handling.
+
+Because these facilities are transparent to the Xisop microkernel
+itself, and are provided by port-specific code, although driven by
+common portable code, the interrupt sources are not required to internally
+correspond to actual hardware interrupts. The port-specific code is
+free to provide the wanted interrupt sources and facilities in the
+manner it wishes. As such they can be used for various hardware and
+sotfware event types.
+
+
+\subsubsection{User interface}
+
+Here is now described the kernel user interface to manipulate custom
+interrupt hooks on the provided facilities. These are also machine-independent.
+They were implemented around \emph{\_rlock\_t} and \emph{pool\_t}
+primitives in a way to make it possible for userland to access their
+functionality without the need for system call traps.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{hookid\_t~hook\_attach(u\_int32\_t~facility,}}] \emph{u\_int32\_t~skipcount,
+u\_int32\_t~runcount, void~({*}code)(hookid\_t,~int,~void~{*}),
+void~{*}data)} Allows to append or insert a user supplied code hook
+to the wanted interrupt facility. The \emph{facility} argument specifies
+what type of exception, trap or interrupt is wanted, and is port-specific.
+An example would be \emph{\_FACILITY\_VBLANK}. \emph{code} specifies
+which function to call as the user hook handler, which should never
+be NULL. \emph{data} points to an optional user data block which will
+be passed back when calling the function handler, and can be NULL.
+The argument of type \emph{hookid\_t} which will be passed will consist
+of the unique ID representing this \emph{hook\_t} into the \emph{facility},
+while the \emph{int} argument, which is facility-specific, could serve
+to determine the origin of the event if the facility serves several.
+The return value is 0 in the case of an error (unknown public facility),
+or a unique ID which can be used to eventually delete that particular
+hook. This is required to not correspond to the hook function address,
+since multiple hooks may call the same function if wanted. This ID
+is always unique to this facility. It is safe to attach a code hook
+function which can expire and then attempt to remove it using the
+supplied \emph{hookid\_t}. If it expired and another hook now uses
+the same \emph{hook\_t} address, it's \emph{hookid\_t} will still
+be different. The semantics of \emph{skipcount} and \emph{runcount}
+are explained in the internals above.
+\item [{\emph{bool~hook\_detach(u\_int32\_t~facility,~hookid\_t~id)}}] Permits
+to remove a user supplied hook on the wanted \emph{facility}, with
+the specfied \emph{id}. Returns TRUE if it could find and delete the
+hook, or FALSE if the hook did not exist, or no longer does (it may
+have expired).
+\item [{\emph{void~facility\_disable(u\_int32\_t~facility)}}] Disables
+all hooks of the specified facility temporarily. They cannot expire
+during the period they are suspended, and none will be executed, even
+when the interrupt source occurs. It does not disable the interrupt
+source. This system is recursive, in that the exact same number of
+calls to \emph{facility\_enable()} must be made to re-enable the facility.
+Note that it is safe to attach and detach hooks from a facility at
+any time, and that this function is only provided as a feature.
+\item [{\emph{void~facility\_enable(u\_int32\_t~facility)}}] Re-enables
+the specified facility which was previously suspended using \emph{facility\_disable()},
+if the \emph{facility\_t} internal \emph{\_rlock\_t} reaches 0 (that
+is all previous calls to \emph{facility\_disable()} were matched by
+a \emph{facility\_disable()}).
+\end{lyxlist}
+
+\subsubsection{Common facilities}
+
+Not all ports have all these facilities, and some may provide more.
+However, this consists of a guide so that facilities which are intended
+to provide the same functionality on the various architectures bear
+the same name.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{\_FACILITY\_SCHEDTIMER}}] This is the only facility which
+must be available on all ports. It usually executes at intervals governed
+by \emph{\_SCHEDTIMER\_HZ}, a frequency defined in instances per second
+(hertz), which is defined in \textless{}\emph{port/support.h}\textgreater{}.
+Systems which only comport one hardware timer source will at least
+always have this timer facility available for multiple uses, although
+internally used by the scheduler. Disabling the scheduler does not
+disable the timer facility, as the scheduler lock consists of an \emph{\_rlock\_t}.
+\item [{\emph{\_FACILITY\_KEYBOARD}}] As the name implies, this facility
+is concerned with keyboard key presses. The key code is usually returned
+in the \emph{int} argument when calling the attached hooks.
+\item [{\emph{\_FACILITY\_VBLANK}}] This facility is very useful for graphic-oriented
+software which need to synchronize operations with the video refresh
+rate. The frequency of a vertical blank interrupt varies with the
+underlaying hardware, but usually consists of 50Hz for PAL (europe)
+and 60Hz for NTSC (american) systems. This is very useful to implement
+double buffering, and can also be used to synchronize audio events
+like music and sound effects with animations.
+\item [{\emph{\_FACILITY\_TRAP}{*}}] These type of facilities can be directly
+tied to user traps which may remain available, and associated to a
+related \emph{\_cause()} function to allow user tasks to both attach
+handlers to receive those events and call \emph{\_cause()} to trigger
+such events. However, because of the Xisop \emph{sys\_custom()} system
+call, the use of such facilities become questionable. \emph{XXX}
+\item [{\emph{\_FACILITY\_FLOPPYSYNC}}] Triggered when a floppy drive notifies
+that it found the sync code of a track.
+\item [{\emph{\_FACILITY\_FLOPPYBLOCK}}] Triggered when the floppy drive
+finished reading a requested block to memory.
+\item [{\emph{\_FACILITY\_AUDIO}}] Notification that an audio channel finished
+playing a sample, or starts looping back the supplied sample buffer
+again.
+\item [{\emph{\_FACILITY\_BLITTERREADY}}] Notification by a parallel hardware
+blitter that it is done with the requested operations and may now
+be ordered new instructions again.
+\item [{\emph{\_FACILITY\_COPPER}}] A hardware raster parrallel blitter
+originated interrupt
+\item [{\emph{\_FACILITY\_SERIAL}}] A generic serial interrupt
+\item [{\emph{\_FACILITY\_SERIALRBF}}] A serial Read Buffer Full interrupt
+\item [{\emph{\_FACILITY\_SERIALTBE}}] A serial Transmit Buffer Empty interrupt
+\end{lyxlist}
+Many other types of facilities may exist, although what should be
+taken as an example consists of the clear names that they are given,
+which directly reference to their origin as much as possible, while
+attempting to avoid cryptic names such as KBD for keyboard, etc. Where
+required, the label can be long enough as long as it remains meaningful.
+
+
+\subsection{Kernel statistics}
+
+The \emph{src/common/kernel/statistic.}(\emph{c}\textbar{}\emph{h})
+module defines primitives for statistic counters.
+
+\emph{XXX}
+
+
+\subsection{Xisop binaries and executables}
+
+The Xisop kernel currently has no ELF or a.out relocatable executable
+loader, and no custom format was implemented, which would require
+a GCC ld BFD backend to be written. This means that at current time,
+all the shared libraries, devices, handlers and user tasks need to
+be started by the kernel at startup. This is easily done however,
+but prevents the microkernel from using all it's features of attaching
+required components at runtime as wanted, although it was designed
+to eventually be able to do so efficiently. It however currently allows
+Xisop to be useable in embedded systems which have defined components,
+like for monolithic kernels.
+
+
+\subsection{Xisop devices}
+
+Xisop devices generally consist of a medium-level backend to hardware-assisted
+services, such as keyboard input, tty output, RS-232 communication,
+etc. As such, they are generally architecture-dependent. Of course,
+machine-independent devices may be written as wanted, where the high-level
+handler interface is considered unadequate and that shared access
+to some kind of ressource is wanted, however.
+
+The Xisop devices are implemented around the message port system.
+There were two main reasons which determined this decision compared
+to using a shared library type system. First, the message receiving
+responsiveness and speed can be determined by the task priority, which
+allows the administrator to decide which devices and tasks to prioritize
+over others. Secondly, the message passing system already provides
+reliable FIFO queuing, and each message/request can be replied to
+when wanted, allowing a device to easily serve resources in a multitasking-friendly,
+asynchroneous manner to the simultaneous requesters.
+
+A device is thus implemented by a task, which decides to attach a
+system device node and then takes the responsibility to serve the
+expected requests. Each task may only attach one device to the system
+lists, and has to specify the device name and version which are used
+for other tasks to open the device. This means that a device name
+may have several simultaneous versions running on the system.
+
+Of course, there are cases where only a single device may control
+a specific hardware resource for instance, and in this case the versionning
+system becomes less useful, in which case version 0 is usually used.
+However, the version may still be useful if the various versions of
+the device had changes to the user interface. In this case, using
+the version is still useful, as opening using the wrong version (the
+one a task expects) will at least always fail cleanly with an error,
+rather than leaving the task to open a device which does not act as
+expected when sending requests.
+
+
+\subsubsection{User interface}
+
+Here are described the device interface functions. Let's first present
+the functions which are intended for client tasks to access device
+server ones:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{device\_t~{*}device\_open(const~char~{*}name,~u\_int32\_t~version,~u\_int32\_t~unit)}}] Allows
+the task to open the unit number \emph{unit} of device \emph{name}
+of version \emph{version}. NULL is returned on failure, which can
+occur because of lack of memory, or if the specified device name of
+the specified version does not exist. Otherwise, a \emph{device\_t}
+handle pointer is returned, which may then be used at \emph{iorequest\_init()}.
+Device names are case-sensitive. If the task exists and that open
+devices have not been explicitely closed, the kernel automatically
+closes them.
+\item [{\emph{device\_t~{*}device\_close(device\_t~{*}handle)}}] Closes
+a device handle which previously was opened using \emph{device\_open()}.
+Always returns NULL. Any \emph{iorequest\_t} associated to this \emph{device\_t}
+may not be used anymore, as it becomes invalid, unless it be reinitialized
+again using \emph{iorequest\_init()} using a new \emph{device\_t}
+handle.
+\item [{\emph{bool~iorequest\_init(iorequest\_t~{*}message,~device\_t~{*}handle,~port\_t~{*}replyport)}}] Initializes
+an \emph{iorequest\_t} \emph{message}, which is necessary to use other
+\emph{iorequest\_}{*}\emph{()} functions to perform device requests.
+\emph{handle} specifies the \emph{device\_t} which will serve requests
+for this message during future requests, and \emph{replyport} of a
+generally \emph{iorequest\_t}-specific private port which was previously
+created, through which request result messages will be sent back to
+us by the device. The \emph{iorequest\_t} buffer is the responsibility
+of the task, just like \emph{port\_t} \emph{message\_t} are. Returns
+TRUE on success, or FALSE on failure (invalid arguments or out of
+memory). The device may optionally internally allocate device-specific
+additional data which will then attach to the \emph{iorequest\_t}.
+These will however be allocated on the current task's memory pool,
+and are therefore released automatically if the task exists.
+\item [{\emph{bool~iorequest\_destroy(iorequest\_t~{*}message)}}] Invalidates
+the \emph{iorequest\_t} \emph{message} which was previously initialized
+using \emph{iorequest\_init()}. As devices may internally allocate
+device-specific additional data and attach it to an \emph{iorequest\_t}
+at initialization, a task should call this function when it no longer
+needs the \emph{iorequest\_t}. Of course, if the task exists, the
+resources are automatically released back to the system, however.
+\item [{\emph{bool~iorequest\_sync(iorequest\_t~{*}message)}}] Permits
+to send a synchroneous request to a device, via \emph{message}. This
+means that the task is suspended until the request completes. The
+reply result is also automatically extracted from the reply port associated
+to the \emph{iorequest\_t}. Before sending a request, some fields
+of the \emph{iorequest\_t} message should be set. When it completes,
+the result fields will have been set. Both can have device-dependent
+semantics, although there is generally a standard, which is described
+in the internals section. Returns TRUE if the request could be sent,
+or FALSE if there was an internal problem (invalid \emph{message},
+or no longer existing device).
+\item [{\emph{bool~iorequest\_async(iorequest\_t~{*}message)}}] Very
+similar to \emph{iorequest\_sync()}, but permits to launch the request
+without waiting until it completes, performing an asynchroneous request.
+Upon completion, the device will internally \emph{port\_reply()} into
+the reply port associated with \emph{message}, and the task is then
+responsible for extracting the reply message from the reply port.
+This allows to launch several asynchroneous requests and to monitor
+signals or ports to detect when they occur. For instance, a task may
+launch an asynchroneous request to read one character, and when the
+request completes, specifying that data exists to read. It can then
+send synchroneous requests to read larger blocks until no more data
+is available, in which case it may then again send an asynchroneous
+request and resume normal activity. TRUE is returned if the request
+could be launched, or FALSE if it failed (invalid \emph{message} or
+no longer existing device).
+\item [{\emph{bool~iorequest\_abort(iorequest\_t~{*}message)}}] If \emph{message}
+currently consists of an asynchroneous request which was made using
+\emph{iorequest\_async()} and is still pending, an abort request is
+sent to cancel it. Like usual, the device will reply still as soon
+as the request could be aborted, and the task becomes responsible
+to unlink the reply message from the reply port associated with \emph{message}.
+TRUE is returned on success, or FALSE if \emph{message} does not consist
+of a currently pending asynchroneous request.
+\item [{\emph{bool~iorequest\_wait(iorequest\_t~{*}message)}}] Waits
+until a currently pending (or aborted which not yet replied) asynchoneous
+request terminates, and automatically unlinks the reply message received
+through the reply port of \emph{message}. This can especially be useful
+after an \emph{iorequest\_abort()}. Returns TRUE on success, or FALSE
+if \emph{message} is not currently a pending (or aborted which did
+not yet return) asynchroneous request.
+\item [{\emph{bool~iorequest\_pending(iorequest\_t~{*}message)}}] Returns
+TRUE if \emph{message} currently consists of an asynchroneously pending
+request, or FALSE otherwise.
+\item [{\emph{bool~iorequest\_aborted(iorequest\_t~{*}message)}}] Returns
+TRUE if \emph{message} consists of a request which just completed,
+but which was an asynchroneous request and was aborted.
+\end{lyxlist}
+These utility functions, although performing the most basic Xisop
+device operations, are provided to minimize code duplication, for
+very simple synchroneous I/O. Normally, tasks will address requests
+using \emph{iorequest\_sync()} and \emph{iorequest\_async()} as needed,
+but this can be useful to have:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{ssize\_t~device\_read(iorequest\_t~{*}req,~void~{*}buf,~size\_t~len)}}] Similarily
+to unix \emph{read()}, reads at most \emph{len} bytes of data from
+the opened device and unit associated with \emph{req} into \emph{buf},
+and returns the number of actually read bytes, or -1 on error. The
+current task is suspended until the operation completes, since \emph{iorequest\_sync()}
+is internally used.
+\item [{\emph{ssize\_t~device\_write(iorequest\_t~{*}req,~void~{*}buf,~size\_t~len)}}] Like
+unix \emph{write()}, writes at most \emph{len} bytes of data from
+\emph{buf}, to the opened device and unit associated with \emph{req},
+and returns the number of actually written bytes, or -1 on error.
+The current task is suspended until the operation completes as it
+internally uses \emph{iorequest\_sync()}.
+\end{lyxlist}
+
+\subsubsection{Device server interface}
+
+Here follows functions which are only useful to device server tasks
+to call:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{bool~device\_attach(const~char~{*}name,}}] \emph{u\_int32\_t~version,
+port\_t~{*}port, void~({*}clean)(void), bool~({*}open)(void~{*}{*},~u\_int32\_t),
+void~({*}close)(void~{*},~u\_int32\_t), void~{*}({*}iorinit)(void),
+void~({*}iordestroy)(void~{*}), u\_int8\_t~flags)}\\
+Allows the current task to become a system device. \emph{name} consists
+of the unique case-sensitive device name to assign to the system device
+node, which will be required to use at \emph{device\_open()}, and
+will be truncated to 32 characters if longer. \emph{version} specifies
+the version number to use, which will also need to match at \emph{device\_open()},
+for this device name. \emph{port} consists of the device server's
+private port, through which requests should be sent. \emph{flags}
+consists of one or combination of \emph{DNF\_}{*} flags described
+in the header file, like \emph{DNF\_RESIDENT} which tells Xisop to
+never cause the device task to exit if there exist no more client
+open instances. The various function pointers which must be supplied
+are explained below:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~({*}clean)(void)}}] is a function which the device
+task can provide for Xisop to call when no more client open instances
+exist for this device, unless the device is resident (and \emph{flags}
+comported \emph{DNF\_RESIDENT} at device creation). This function
+is responsible to restore the hardware which this device may have
+been serving to a consistant and known state. It will also be called
+automatically by Xisop when the task exits normally. Note that \emph{clean()}
+should not comport any special function to cause the task to end.
+Xisop will send a \emph{SIGTERM} signal when the task should do so.
+If the task exits by itself, \emph{clean()} will be called automatically
+nevertheless. Because this function may be called under the context
+of any other task, it should not expect to execute under the device's
+task memory pool (and therefore should normally not call allocation
+functions). It is possible to specify NULL for this function if the
+device has no need for any special cleanup function.
+\item [{\emph{bool~({*}open)(void~{*}{*}udata,~u\_int32\_t~unit)}}] All
+devices are required to provide this function. It's purpose is to
+validate if \emph{unit} can be opened (some devices limit the number
+of open instances of a unit, to protect their resources), and to optionally
+allocate any needed device-specific data which it may need to attach
+to \emph{device\_t} nodes. \emph{open()} is called at each \emph{device\_open()}
+function instance called on this device. It is expected to return
+FALSE if it refuses to open the specified \emph{unit} or if it cannot
+allocate any required resources, or TRUE on success. If the task allocates
+data which is needed to be attached to the \emph{device\_t} handle,
+it should supply the address of the allocated data block into the
+supplied \emph{udata}. It should set NULL there otherwise. Although
+the device may at it's discretion maintain counters on the number
+of currently opened units, etc, Xisop will automatically send a SIGTERM
+to the device task if it is non-resident and that there exist no more
+openers. Note that this function is called under the context of the
+task which calls \emph{device\_open()}. As such, the memory allocations,
+such as the optional \emph{udata} block will be automatically freed
+when the other task ends, not ours. For this reason, the function
+can use \emph{malloc()} and companions safely, but should not use
+lower-level Xisop kernel allocation primitives.
+\item [{\emph{void~({*}close)(void~{*}udata,~u\_int32\_t~unit)}}] This
+function is also required for all device tasks to provide, and is
+called by \emph{device\_close()} on a \emph{device\_t} handle which
+was previously associated to this task by \emph{device\_open()}. The
+function is responsible for calling \emph{free()} on the supplied
+\emph{udata} pointer if needed, and to perform the necessary device-specific
+cleanup required when a device handle closes. \emph{unit} specifies
+the unit which was opened by this handle.
+\item [{\emph{void~{*}({*}iorinit)(void)}}] Devices may optionally provide
+this function to allocate \emph{iorequest\_t} message specific data
+which it might need, very similarily to \emph{open()} which can attach
+data to a \emph{device\_t} handle. NULL can be supplied if there is
+no need for \emph{iorequest\_t} specific extention data. This function
+is called under the context of the task calling \emph{iorequest\_init()}
+and as such no Xisop low-level allocation functions should be called.
+The function may allocate the data block with \emph{malloc()}, initialize
+it and return a pointer to it, or NULL on failure (out of memory).
+\item [{\emph{void~(iordestroy)(void~{*}udata)}}] May also be supplied
+NULL if NULL was supplied for \emph{iorinit()}. Otherwise, this function
+is responsible to \emph{free()} the supplied \emph{udata}, which corresponds
+to a block of memory which was returned by a previous \emph{iorinit()}
+call.
+\end{lyxlist}
+\item [{\emph{bool~iorequest\_satisfy(iorequest\_t~{*}message,~bool~result)}}] Is
+a useful utility function to set the main request success result code
+and reply to the task that it has completed.
+\end{lyxlist}
+Various macros of interest may be used by device tasks:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~{*}DEVICEHANDLE\_UDATA(device\_t~{*}handle)}}] Returns
+the \emph{udata} pointer associated with the supplied \emph{device\_t}
+\emph{handle}.
+\item [{\emph{void~{*}IOREQUEST\_UDATA(iorequest\_t~{*}message)}}] Returns
+the \emph{udata} pointer associated with the supplied \emph{iorequest\_t
+message}.
+\end{lyxlist}
+
+\subsubsection{Internals}
+
+This system based upon the Xisop message ports system and the previously
+described functions permit to open or provide devices, and to communicate
+requests from the client-side and completion from the server-side,
+through a special message, the \emph{iorequest\_t}.
+
+\emph{XXX}
+
+
+\subsection{Xisop handlers}
+
+Handlers provide a higher-level abstraction to devices or resources.
+It should be noted that unlike devices, these are implemented in the
+form of a standard shared library format. This means that devices
+are usually a nice abstraction to mount handlers on, as devices naturally
+perform the queuing, etc. \emph{XXX}
+
+
+\subsection{Xisop shared libraries}
+
+The concept of Xisop shared libraries is both very simple, and unusual.
+It is important that all functions a library provides publically be
+reentrant. Opening a library basically obtains the pointer to a structure
+which is necessary to access it's function pointers. As such, only
+one resident copy is required for all applications, and new applications
+can ``attach'' the libraries they need as required. The system keeps
+track of how many times it is currently being open by various tasks,
+and can therefore know when the library should be expunged from memory.
+Obviously, when a library is requested which is not currently in RAM,
+it should be loaded in the system from disk.
+
+Each library may have concurrent versions on the same system, in memory
+and on disk. When an application requests access to a library, it
+optionally specifies the expected version, without which the latest
+is assumed. This way, it is possible for the administrator to get
+rid of the obsolete libraries but only after making sure that no applications
+require them anymore. While software is being developped, it becomes
+possible to have concurrent versions of applications each using their
+respectively related material.
+
+\emph{XXX}
+
+
+\subsubsection{The Xisop library}
+
+\emph{XXX}
+
+
+\subsection{Xisop system calls}
+
+System calls are different than normal functions in that they allow
+userspace tasks to execute instructions which are normally only allowed
+to call in supervisor mode, or in kernel space. Moreover, system calls
+are currently uninterruptible in Xisop, which means that the task
+is guaranteed to not be preempted while executing a system call function,
+until it returned. These are internally implemented using processor
+traps, by the port-specific code. However, the system call functions
+themselves are portable and part of the Xisop common code. Because
+Xisop does not use MMU facilities, system calls are very fast to execute
+compared to on unix systems. Xisop design attempts to require the
+less of these possible however, because they also disable the scheduler
+when executing.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{struct~xisop\_root~{*}sys\_getroot(void)}}] Permits a task
+to obtain the address of the main Xisop control structure, where system
+lists are stored. Obviously, if a task uses this information in any
+way, it has to be careful not to disrupt Xisop activities. It is recommended
+to disable the scheduler and/or interrupts where required to access
+the information which that structure provides. It is made for people
+who know Xisop inside out only.
+\item [{\emph{void~sys\_int\_disable(void)}}] This internally calls \emph{\_splhigh()}
+which ensures to mask all interrupts, including that of the preemptive
+scheduler. Precautions should be made about the calls used similarly
+to when disabling the scheduler. However, this call permits a task
+to completely take control over Xisop.
+\item [{\emph{void~sys\_int\_enable(void)}}] Internally calling \emph{\_spl0()},
+this re-enables all interrupts. \emph{XXX} heh actually, can the \emph{\_syscall()}
+trap actually occur after a \emph{sys\_int\_disable()}? Will need
+to check this out.
+\item [{\emph{void~sys\_idle(void)}}] Permits to suspend the processor
+until the next trap, interrupt or exception occurs. This internally
+calls the \emph{\_idle()} processor-specific function. This is mostly
+used by Xisop \emph{main()} which is returned control to when no tasks
+are currently on the ready queue.
+\item [{\emph{void~sys\_custom(void~{*}res,~void~({*}func)(void~{*},~void~{*}),~void~{*}args)}}] A
+very special system call, allows user tasks to execute arbitrary code
+in supervisor mode, uninterruptibly (scheduler will not preempt, but
+interrupts can still take place). \emph{func} specifies the function
+to call, which will be passed \emph{res} as the first argument and
+\emph{args} as the second argument, which can be used by the function
+to acquire parameters and return results. \emph{res} and \emph{args}
+can be NULL when they are not needed. Because Xisop attempts to be
+more useful to the programmer than to secure the kernel against userland,
+this was beleived to be a very useful function, where user tasks can
+create their custom system calls as required.
+\end{lyxlist}
+
+\subsection{Xisop general programming interfaces}
+
+In an attempt to keep the code unified and clean, multipurpose interfaces
+were provided.
+
+
+\subsubsection{Byte alignment macros}
+
+In \emph{\textless{}common/types.h\textgreater{}} the following macros
+are provided for byte alignment.
+
+These macros permit object size related byte alignment:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{size\_t~OALIGN\_CEIL(size\_t~v,~o)}}] \emph{o}-aligns
+\emph{v}. This macro rounds \emph{v} to the nearest larger unit as
+required. \emph{o} should be any native C or custom structure type,
+to which \emph{v} should be aligned relative to. \emph{v} is not modified,
+the new value is returned.
+\item [{\emph{size\_t~OALIGN\_FLOOR(size\_t~v,~o)}}] \emph{o}-aligns
+\emph{v}. Unlike \emph{OALIGN\_CEIL()} this macro rounds to the nearest
+smaller unit as required.
+\end{lyxlist}
+And these macros permit byte size related alignment:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{size\_t~BALIGN\_CEIL(size\_t~v,~size\_t~s)}}] This macro
+aligns \emph{v} to the nearest larger unit relative to \emph{s} size
+as required. \emph{v} is not modified, the new value is returned.
+\item [{\emph{size\_t~BALIGN\_FLOOR(size\_t~v,~size\_t~s)}}] Very similar
+to \emph{BALIGN\_CEIL()}, but rounds \emph{v} to the nearest smaller
+unit relative to \emph{s} size as required.
+\end{lyxlist}
+
+\subsubsection{Byte order manipulation macros}
+
+In \emph{\textless{}common/types.h\textgreater{}} the following macros
+are provided for byte order/endian conversions. These are most useful
+for network Remote Procedure Call implementations, as well as for
+binary file formats which can be in network order so that multiple
+architectures may easily use the same file format. Depending on the
+native host byte order (the \emph{\_ARCH\_BIG\_ENDIAN} and \emph{\_ARCH\_LITTLE\_ENDIAN}
+definitions defined by processor-specific code), these will perform
+no action where no conversion is necessary. The network order should
+be used for transferring over networks or writing to binary files,
+and actually corresponds to the native host byte order on big endian
+architectures.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{u\_int16\_t~BYTEORDER\_NETWORK16(u\_int16\_t)}}] Converts
+the specified 16-bit word to network order for sending through the
+network or writing to a binary file.
+\item [{\emph{u\_int16\_t~BYTEORDER\_HOST16(u\_int16\_t)}}] Converts the
+specified network order 16-bit word to native host order after reading
+from a binary file or receiving through the network.
+\item [{\emph{u\_int32\_t~BYTEORDER\_NETWORK32(u\_int32\_t)}}] Converts
+the specified 32-bit word to network order for sending through the
+network or writing to a binary file.
+\item [{\emph{u\_int32\_t~BYTEORDER\_HOST32(u\_int32\_t)}}] Converts the
+specified network order 32-bit word to native host order after reading
+from a binary file or receiving through the network.
+\end{lyxlist}
+
+\subsubsection{Doubly linked lists}
+
+These macros, as well as the \emph{list\_t} and \emph{node\_t} types
+are defined in \emph{\textless{}common/types.h\textgreater{}} and
+\emph{\textless{}common/kernlib/list.h\textgreater{}}.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~DLIST\_INIT(list\_t~{*}list)}}]~
+\item [{\emph{void~DLIST\_APPEND(list\_t~{*}list,~node\_t~{*}node)}}]~
+\item [{\emph{void~DLIST\_INSERT(list\_t~{*}list,~node\_t~{*}node)}}]~
+\item [{\emph{void~DLIST\_INSERTAT(list\_t~{*}list,~node\_t~{*}atnode,~node\_t~{*}node)}}]~
+\item [{\emph{void~DLIST\_SWAP(list~t~{*}dstlist,~list\_t~{*}srclist,~node\_t~{*}srcnode,~bool~insert)}}]~
+\item [{\emph{void~DLIST\_UNLINK(list\_t~{*}list,~node\_t~{*}node)}}]~
+\item [{\emph{u\_int32\_t~DLIST\_NODES(list\_t~{*}list)}}]~
+\item [{\emph{node\_t~{*}DLIST\_TOP(list\_t~{*}list)}}]~
+\item [{\emph{node\_t~{*}DLIST\_BOTTOM(list\_t~{*}list)}}]~
+\item [{\emph{node\_t~{*}DLIST\_NEXT(node\_t~{*}node)}}]~
+\item [{\emph{node\_t~{*}DLIST\_PREV(node\_t~{*}node)}}]~
+\item [{\emph{void~DLIST\_FOREACH(list\_t~{*}list,~node\_t~{*}iterator)}}]~
+\end{lyxlist}
+\emph{XXX}
+
+
+\subsubsection{Hash based fast lookup tables}
+
+The prototypes and types for these are defined in \emph{\textless{}common/types.h\textgreater{}}
+and \emph{\textless{}common/kernlib/hash.h\textgreater{}}.
+
+\emph{XXX}
+
+
+\subsubsection{FIFO (First In, First Out) buffers}
+
+These macros as well as the default FIFO types are defined in \emph{\textless{}common/types.h\textgreater{}}
+and \emph{\textless{}common/kernlib/fifo.h\textgreater{}}.
+
+\emph{XXX}
+
+
+\subsubsection{LIFO (Last In, First Out / Stack) buffers}
+
+These macros as well as the default LIFO types are defined in \emph{\textless{}common/types.h\textgreater{}}
+and \emph{\textless{}common/kernlib/lifo.h\textgreater{}}.
+
+\emph{XXX}
+
+
+\subsection{Xisop source tree organization}
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{doc/}}] This directory holds this file, as well as various
+notes of interest
+\item [{\emph{src/}}] Where all source resides
+\item [{\emph{src/common/}}] All machine-independent Xisop source
+\item [{\emph{src/common/kernel/}}] Xisop kernel main code
+\item [{\emph{src/common/kernlib/}}] Xisop kernel main machine-independent
+libraries
+\item [{\emph{src/common/library/}}] Xisop machine-independent shared libraries
+\item [{\emph{src/common/device/}}] Xisop machine-independent devices
+\item [{\emph{src/common/handler/}}] Xisop machine-independent handlers
+\item [{\emph{src/common/task/}}] Xisop machine-independent resident tasks
+\item [{\emph{src/processors/}}] Holds all processor-specific code
+\item [{\emph{src/processors/m68k/}}] The Motorola m68k support (MC68000L8/L10)
+\item [{\emph{src/processors/m68k/kernlib/}}] m68k specific replacement
+functions for wanted standard machine-independent kernlib ones (optional)
+\item [{\emph{src/ports/}}] Holds all port-specific code, including boot
+loaders
+\item [{\emph{src/ports/amiga/}}] The Amiga port of Xisop code resides
+here
+\item [{\emph{src/ports/amiga/kernlib/}}] Amiga-specific replacement functions
+for wanted standard machine-independent kernlib ones (optional)
+\item [{\emph{src/ports/amiga/boot/}}] The Amiga-specific code to generate
+a bootable kernel
+\item [{\emph{src/ports/amiga/library/}}] Amiga-specific shared libraries
+(optional)
+\item [{\emph{src/ports/amiga/device/}}] Amiga-specific devices (optional)
+\item [{\emph{src/ports/amiga/handler/}}] Amiga-specific handlers (optional)
+\item [{\emph{src/ports/amiga/task/}}] Amiga-specific resident tasks (optional)
+\end{lyxlist}
+
+\subsection{The build process}
+
+Here is described the way the Xisop source is built to create a binary
+kernel image. \emph{/bin/sh} is also assumed to exist for the building
+process. The convention for the script names are as follows:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{src/generic\_makedefs.sh}}] contains various sh functions
+and variables assigned to local utilities which are required by all
+\emph{clean.sh} scripts, and the main \emph{src/make.sh} script. Those
+scripts \emph{source} this file to obtain the common information.
+\item [{\emph{src/makedefs.sh}}] consists of a symbolic link to \emph{port/makedefs.sh},
+which contains the configuration information required to build the
+for the target port system. The paths to the various useful utilities
+are assigned to shell variables. If functions need to be supplied
+for other build scripts, they also should be defined here. This file
+is sourced (included) by all other build scripts. They all should
+use the variables supplied by this file when accessing the cross-compile
+or local utilities.
+\item [{\emph{src/make.sh}}] allows to fully compile the kernel to result
+in a kernel image. Requires the target port name to be specified,
+as it also sets up required symbolic links.
+\item [{\emph{src/clean.sh}}] cleans the source tree, that is, deletes
+all files which may have been created by the build process.
+\item [{{*}\emph{/make.sh}}] The various sections described below will
+need such a script which should perform the necessary steps to compile
+the section. These \emph{source} src/\emph{makedefs.sh} to know which
+commands to invoke and access useful \emph{/bin/sh} macros..
+\item [{{*}\emph{/clean.sh}}] The sections also need such a script which
+is expected to delete all files which the \emph{make.sh} script counterpart
+creates. These \emph{source} \emph{src/generic\_makedefs.sh}.
+\end{lyxlist}
+
+\paragraph{Cleaning the whole source tree}
+
+The \emph{src/clean.sh} script ensures to clean the whole source tree
+by calling the \emph{clean.sh} script for each section, including
+all ports and processors. The invoker is expected to be in the \emph{src/}
+directory.
+
+
+\paragraph{Building the system}
+
+The \emph{src/make.sh} script builds the entire system. The main steps
+performed to compile the system are described as follows, in order.
+
+
+\subsubsection{Preliminary building process setup}
+
+The \emph{src/processor,} \emph{src/port} and \emph{src/makedefs.sh}
+symbolic links should point to their corresponding \emph{src/processors/\textless{}directory\textgreater{}}
+and \emph{src/ports/\textless{}directory\textgreater{}} and \emph{src/ports/\textless{}directory\textgreater{}/makedefs.sh}.
+These are setup depending on the target system for which Xisop is
+being built. Each of these (port and processor sections) supplies
+a \emph{support.h} headerfile which should be sufficient for the rest
+of the kernel code to access the functionality of the hardware specific
+code they provide. Moreover, each of them will after building provide
+\emph{ar} archives (\emph{.a} files) into their respective \emph{ar/}
+directory, resulting from their various object files, which will be
+sufficient to link with the rest of the kernel code to achieve the
+end result. The \emph{src/make.sh} script creates these symbolic links
+when supplied with a valid \emph{target} (using the \emph{-t} parameter).
+
+\emph{src/make.sh} also ensures to set the \emph{\$SRCDIR} environment
+variable to the absolute path to the current directory (\emph{src/}),
+which should be used by other build scripts when compiling modules
+so that \emph{\#include} directives in the source can locate the file
+using \emph{-I} parameter, etc.
+
+
+\subsubsection{Building the processor-specific support code}
+
+Control is delegated to \emph{src/processor}/\emph{make.sh}. This
+is expected to assemble and compile the various sections it comports
+to binary objects independently (\emph{.o}) using \emph{-c} parameter
+to \emph{gcc} command, and to then archive them as \emph{ar} archives
+into the \emph{src/processor/ar} directory using the \emph{ar} and
+\emph{ranlib} commands. This final object will be linked with the
+kernel code by another section of the build process. It is to be noted
+that it will be linked before the general common machine-independent
+kernel library, so that it is possible to provide processor-specific
+replacements to standard low-level functions, such as \emph{memcpy()},
+\emph{memset()}, etc. These could however be overriden by the port-specific
+support code. When control is given to \emph{make.sh} of this section,
+the current directory will have been changed as well so that it is
+safe to access the section files relatively to the current (section)
+directory.
+
+
+\subsubsection{Building the port-specific support code}
+
+Control is given to \emph{src/port/make.sh} to compile this section,
+and very similarly to the processor-specific section, the goal is
+to generate one or more \emph{ar} archive in the \emph{src/port/ar}
+directory. \emph{src/port/support.h} will also contain all necessary
+information for the rest of the kernel code to use the port-specific
+support. This code will be linked with the global kernel before s\emph{rc/processor/ar/{*}.a},
+which means that it is possible to provide port-specific standard
+functions overriding the processor-specific ones, as well as kernel
+machine-independent common ones. This could allow for instance to
+provide \emph{memcpy()} and \emph{memset()} functions using specialized
+data moving hardware such as blitters, etc. It is however recommended
+that libraries be built in a way to not force the whole library to
+be included into the final kernel if only a few of the functions were
+necessary. To do this, a library could consists of a directory, with
+all functions isolated in their own \emph{.c} file. The \emph{ar}
+archive then results in a bunch of very small \emph{.o} files which
+will be ignored by the linker when unrequired. It is important to
+also run \emph{ranlib} on the \emph{ar} archive.
+
+\emph{XXX} \emph{Hmm I should find a nice way to define the resident
+libraries, devices and handlers, both common and port-specific ones.
+Also, which tasks should be initially started, etc. Actually, resident
+devices and handlers, being tasks, would just need to be included
+in the tasks to start, I guess...}
+
+\emph{XXX This next paragraph is currently invalid.}
+
+The \emph{ar/{*}.a} result should also include \emph{\_init\_libraries()},
+\emph{\_init\_devices()} and \emph{\_init\_handlers()} functions,
+which should as required attach the wanted shared libraries, devices
+and handlers in the kernel by calling their init function. These also
+should initialize machine-independent ones. If there are port-dependent
+ones, their code should be located into the \emph{library/}, \emph{device/}
+and \emph{handler/} directories in \emph{src/port/}.
+
+
+\subsubsection{Building the machine-independent main Xisop code}
+
+The \emph{src/common/kernlib/} directory comports a directory for
+each internal kernel library, which each contain functions isolated
+into a single file each. These are built separately as object modules,
+and are archived using \emph{ar} and \emph{ranlib} into \emph{src/common/kernlib/ar}
+directory. The reason for this is that it allows the resulting kernel
+image to be smaller when not all of the functions of a particular
+library are used. If all string functions were located into the same
+\emph{string.c} file for instance, all of the string functions would
+automatically be linked within the result even if only two string
+functions were actually used, for instance.
+
+The \emph{src/common/kernel/} and \emph{src/common/kernlib/} sections
+containing only portable C code are compiled, and their modules archived
+with \emph{ar} and \emph{ranlib}, to \emph{src/common/kernel/ar/{*}.a}
+and \emph{src/common/kernlib/ar/{*}.a} files. At current time, \emph{src/common/library/},
+\emph{src/common/device/} and \emph{src/common/handler/} sections
+are all compiled and archived together as \emph{src/common/ar/{*}.a}.
+\emph{XXX This last statement is false as nothing is done for libraries,
+devices and handlers at current time..}
+
+
+\subsubsection{Linking the final kernel}
+
+\emph{src/common/kernel/kernel}.\emph{a}, \emph{src/port/support.}a,
+\emph{src/processor/support.a}, \emph{src/common/kernlib/kernlib.a}
+and \emph{src/common/shared.a} are linked together, in that order,
+into the ELF relocatable \emph{src/xisop.o} file (using \emph{-r}
+option to ld). This allows processor-specific libraries to replace
+\emph{common/kernlib} functions, and port-specific ones to override
+both processor-specific and common ones.
+
+
+\subsubsection{Linking the final kernel and building the bootable Xisop result}
+
+After building both the machine dependent and independent sections
+described above, the control is then left to \emph{src/port/boot/make.sh},
+after changing to the \emph{src/port/boot directory}. The role of
+this final script is to complete the linking and building process.
+Here is what currently happens:
+
+As a general rule, image\_script.ld file in that directory comports
+the necessary information to statically link monolithically the whole
+kernel as a binary image. Here is an excerpt of what \emph{src/ports/amiga/boot/make.sh}
+does:
+\begin{itemize}
+\item show \$C\_COMPC -I\$SRCDIR init.c
+\item A=`\$L\_LS ../../../common/kernel/ar/{*}.a ../ar/{*}.a ../../../processor/ar/{*}.a
+../.. /../common/kernlib/ar/{*}.a`
+\item show \$C\_LD -nostdlib -e \_start -Ttext 0x005f8000 -o image.o init.o
+\$A
+\item show \$C\_LD -T image\_script.ld -nostdlib -o image.bin init.o \$A
+\item ...
+\end{itemize}
+The first operation compiles it's initialization code, which provides
+the \emph{\_start} entrypoint, which eventually calls Xisop \emph{main()}.
+Then is compiled a list of the various \emph{ar} archives which should
+be linked. The order of these archives is important, as it permits
+the processor-specific code to override the common code, and the port-specific
+code to override the processor specific and common code.
+
+Then follows the linking process, which is done two time. The first
+instance creates \emph{image.o} which can then be viewed and disassembled
+using the \emph{objdump} utility. This is mostly used for debugging
+so that at runtime in the emulator it is possible to stop the emulation
+process and fall into the debugger, which then discloses the current
+executing address. That same address in image.o disassembly should
+match, and this is where it can be handy.
+
+The second linking command creates the binary Xisop kernel image using
+the \emph{image\_script.ld} linker script, to result in \emph{image.bin}.
+This is the actual image, which expects to be loaded into memory at
+the address 0x005f8000, and jumped to. (See the \emph{image\_script.ld}
+and \emph{make.sh} scripts for more information).
+
+The script then proceeds to compile the disk boot loader (floppy in
+this case), which is located into the \emph{bootf/} directory. It
+then compiles the tools which are needed to assemble the result and
+fix the bootblock checksum using the the local compiler (not the cross
+compiler, although the same compiler could be used for both local
+and cross, if the target and the build system are the same). It finally
+uses those tools to create the final xisop.adf floppy image, and advertizes
+the location of this file to the user.
+
+Those last steps are very port-specific and are best done by someone
+with a good amount of experience for the particular port to ensure
+that it works right. It is important to advertize the location of
+the final result to the user at the very end.
+
+\newpage{}
+
+
+\section{Hardware specific development notes}
+
+This chapter describes which hardware specific sections are required
+to support Xisop. They in fact provide the low-level glue which all
+the machine-independent common code replies on. As such, they should
+be small, effective, and as efficient and stable as possible. They
+should be well tested before releasing an official new Xisop port.
+
+To aid in having a well organized source tree, and to prevent code
+duplication, hence enhancing stability with time, the processor-specific
+and port-specific sections have been separated into two. Several ports
+may then take advantage of the same processor-specific code, such
+as atomic locking primitives, which are known to work well, which
+helps alot to speed up development.
+
+
+\subsection{Microprocessor specific notes}
+
+
+\subsubsection{Required backend functions and support}
+
+Each processor is different but it is great to abstract most CPU-specific
+functions into a standard set. The headerfile which will be invoked
+by the common machine-independent parts of the kernel to acquire support
+for the hardware specific functions is \emph{processor/support.h},
+where \emph{processor} will consist of a symbolic link to the actual
+\emph{processor} directory in use in the \emph{processors} directory.
+Although the general organization of the processor specific code is
+implementation dependent, it is important that \emph{support.h} loads
+support for all necessary functions and data types which are processor-specific,
+and that \emph{ar/{*}.a} be the only necessary modules to link with
+the rest of the kernel.
+
+It is allowed if desired to also supply processor specific functions
+to replace some of the common machine-independent ones, which may
+be desired for speed at occasions. When this is done, the functions
+should behave identically as expected, should bear the same names,
+and no prototypes should be provided for them in \emph{support.h}.
+The processor-specific code will be linked to the final kernel before
+the common libraries and those functions will replace the machine-independent
+ones then. These functions could be for instance: \emph{memcmp()},
+\emph{memcpy()}, \emph{memset()}, etc.
+
+Here are the various recommended functions which each CPU should support,
+and make public to the rest of the kernel, at a minimum:
+
+
+\paragraph{Context manipulation}
+
+The \emph{\_ctx\_t} structure should be defined by the CPU-specific
+support headerfile and should be used as an abstract type representing
+all required information to save or restore a context, thus all registers,
+status register (SR), stack pointer (SP), and program counter (PC).
+The load and save context code sections are generally port-specific
+are called from an interrupt, and as needed some care will be taken
+to save the user stack pointer (USP) rather than the supervisor stack
+pointer (SSP), as their purpose consist of task switching.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_ctx\_init(\_ctx\_t~{*}context,~u\_int32\_t~{*}stack,~size\_t~stacksize,~void~{*}start)}}] Allows
+to create a new CPU context. On some systems the stack grows downwards
+while upwards on others. For this reason, the \emph{stacksize} argument
+is used which permits to set the stack pointer as required, because
+\emph{stack} should be a pointer to the top of the stack. \emph{start}
+is a function pointer to the code to execute (stack startup address).
+Usually, SP and PC are set accordingly in \emph{context}, SR set to
+the current one, and other registers zeroed. In some cases it may
+be good to also ensure to turn off the supervisor bit from SR in the
+context, because user tasks are expected to run in userstate processor
+mode.
+\end{lyxlist}
+
+\paragraph{Simple lock support}
+
+\emph{\_lock\_t} should also be defined for abstraction, and help
+to perform various synchronization tasks. These need not be symetric
+multiprocessor (SMP) safe, but they should at least be atomic for
+the current processor. Atomic in the sense that test-and-set must
+be performed at once to acquire a lock. If a processor does not allow
+to make this atomic, it is possible to provide these by the port-specific
+code, in which case it could disable interrupts (at least the scheduler
+interrupt) before performing it's tasks, so that operations seem atomic
+in a multitasking environment. These lock primitives should not be
+nestled or recursive, they are intended for exclusive access.
+
+In any case, all following lock primitives should be callable by normal
+user tasks, which means that when required a trap can be used internally
+to swich to supervisor mode if the processor requires to perform privileged
+instructions to achieve the expected atomic behavior, both for \emph{\_lock\_t}
+and \emph{\_rlock\_t} primitives. Fortunately, they can usually be
+implemented properly using normal instructions.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_lock\_init(\_lock\_t~{*}lock)}}] Permits to initialize
+a \emph{\_lock\_t} entity as required for future operations on this
+\emph{lock}.
+\item [{\emph{void~\_lock\_acquire(\_lock\_t~{*}lock)}}] Allows to obtain
+exclusive access on the supplied \emph{lock}, or wait looping indefinitely
+until the lock could be obtained, in order to obtain it as fast as
+possible. It is important that this operation be atomic so that in
+the event of scheduled context switching race conditions do not occur.
+\item [{\emph{void~\_lock\_release(\_lock\_t~{*}lock)}}] Should free
+the specified \emph{lock}, which will enable any other requester to
+acquire the lock to obtain it. This operation also should be atomic.
+\item [{\emph{bool~\_lock\_try(\_lock\_t~{*}lock)}}] Attempts to obtain
+exclusive access to \emph{lock}, returning TRUE/1 if it could obtain
+it immediately, or FALSE/0 if the lock is already being held, in which
+case it also returns immediately. It is important that this be implemented
+atomically, in a single test-and-set instruction.
+\item [{\emph{bool~\_lock\_available(\_lock\_t~{*}lock)}}] Verifies if
+\emph{lock} is available. This is not to be used to implement \emph{\_lock\_try()},
+it is used in situations where we only want to make sure that no lockers
+currently own the lock, but that we still do not want to obtain it
+ourselves. An example of this is where a lock is used as an ON/OFF
+switch, which can be implemented using this mechanism, without disabling
+the event which needs to access a resource, which may serve other
+functions but will skip executing the critical code if the scheduler
+lock is held. This is usually best implemented using recursive \emph{\_rlock\_t}
+however, which will be described below.
+\end{lyxlist}
+The following locking primitives are different in that a lock may
+be locked by any number of lockers, but has to be unlocked the same
+number of times for the lock to become free again. These are called
+recursive locks. A useful example consists of the scheduler which
+wants to ensure that no task disabled the scheduler temporarily before
+performing a context switch. It then evaluates the lock using \emph{\_rlock\_available()},
+or \emph{\_rlock\_try()} if it needs to prevent recursion, and only
+performs the switch if it is (and hence the lock counter equals to
+0, or 1). It is recommended that the \emph{\_rlock\_t} type consist
+of an \emph{int32\_t} (signed), but the processor-specific code is
+left to define it differently if need be.
+
+Although for several architectures C code can also be used to implement
+these, it is a good idea to implement them in assembly because there
+is no guarantee that the compiler will always use atomic increase
+and decrease operations (GCC 2.95.3 at least seems to not always do
+so for m68k with C macros, it often loads the value from the lock
+counter, increase it during other processing and posts back the new
+value over the counter, instead of always generating an atomic increment
+instruction which m68k is well capable of). Moreover, for some other
+architectures the use of an internal \emph{\_lock\_t} or \emph{\_splhigh()}
+may be required to implement these properly, and if there are privileged
+instructions required to implement these, a trap may be needed.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_rlock\_init(\_rlock\_t~{*}rlock)}}] Initializes
+\emph{rlock} to 0. This normally is rarely done except at system initialization,
+or lock creation.
+\item [{\emph{void~\_rlock\_acquire(\_rlock\_t~{*}rlock)}}] Atomically
+increases the \emph{rlock} counter by one.
+\item [{\emph{void~\_rlock\_release(\_rlock\_t~{*}rlock)}}] Atomically
+decreases the \emph{rlock} counter by one. There is no need to perform
+any check against 0 in this function.
+\item [{\emph{void~\_rlock\_try(\_rlock\_t~{*}rlock)}}] Permits to atomically
+increase the \emph{rlock} counter by one, and returns TRUE if the
+caller consists of the only locker (in which case the lock counter
+should now be 1). If the counter is higher, it means that more than
+one locker exists and the function is then expected to decrease the
+counter atomically again, and return FALSE. This allows exclusive
+access to a recursive lock. This function is both used by the scheduler
+and public interrupt facility systems. Because they want to make sure
+that noone holds the lock when they execute their critical tasks,
+and that they also need to lock it to prevent potential self-recursion,
+this call is a great facility to use.
+\item [{\emph{void~\_rlock\_available(\_rlock\_t~{*}rlock)}}] Returns
+TRUE if the \emph{rlock} counter equals to 0, or FALSE otherwise (in
+which case there at least remains one current locker). This function
+is provided for callers which do not need to prevent possible recursion,
+but only need to make sure that the lock is currently free. Following
+\emph{\_rlock\_available()} with \emph{\_rlock\_acquire()} is not
+safe, and \emph{\_rlock\_try()} should be used instead when this is
+desired.
+\end{lyxlist}
+
+\paragraph{Byte order conversion support}
+
+The processor-specific code needs to \#define \emph{\_ARCH\_BIG\_ENDIAN}
+or \emph{\_ARCH\_LITTLE\_ENDIAN} in their \emph{support.h} depending
+on their native byte order. These will be used at a higher level in
+the libraries for the endian-conversion functions between network
+(big endian) and host order (big or little endian). These are most
+useful when saving a binary file format which needs to be loadable
+by another processor of another endian order as well as in the implementation
+of networking based Remote Procedure Calls, etc. Moreover, the two
+following functions should be provided:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{u\_int16\_t~\_bswap16(u\_int16\_t)}}] Swaps the order of
+the two bytes held in the supplied 16-bit word and returns the result.
+For instance, 0x1234 becomes 0x3412.
+\item [{\emph{u\_int32\_t~\_bswap32(u\_int32\_t)}}] Reverses the order
+of the four bytes held in the supplied 32-bit word and returns the
+result. For instance, 0x12345678 becomes 0x78563412.
+\end{lyxlist}
+
+\paragraph{String library optimizations support}
+
+Note that the following are not necessary to consider if a specially
+optimized library functions for string and memory are implemented
+in assembly for the architecture.
+
+Every other architecture should \emph{\#define} the architecture-specific
+\emph{\_\_ARCH\_INT\_BITS} macro, which should be set to the native
+word size used by the particular processor for int, using the compiler.
+This should be expressed in bits, not in bytes. The most common value
+is 32, but it can vary.
+
+It is also important to \emph{\#define} the \emph{\_ARCH\_LOWCACHE}
+macro (with no value), if it is beleived that loop unrolling is of
+no benefit. This can be the case on architectures with very low instruction
+caches, or ones which are using none. If loop unrolling is wanted,
+this should not be defined.
+
+The \emph{\_ARCH\_USEINDEXING} macro also should be \emph{\#defined}
+with no value if it is beleived that the compiler generates better
+code for this particular processor when using indexed instructions
+rather than many post-increment/pre-decrement pointer based instructions.
+For instance, the i386 processor has no such special support, and
+using indexing can generate better code using GCC2. For m68k, it is
+usually better not to use indexing. Note that this is only taken in
+consideration if \emph{\_ARCH\_LOWCACHE} is not defined, as it only
+affects loop unrolling of the C string and memory library.
+
+These definitions are expected to be found in the \emph{support.h}
+file for every particular processor.
+
+
+\paragraph{CPU-saving}
+
+On CPUs which support this, it is very useful to not hug the processor
+constantly in a loop where the only event that is awaited for consists
+of an interrupt. On microprocessors which do not provide such a feature,
+it is safe to just make this function do nothing.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_idle(void)}}] Suspends execution of instructions
+by the current processor until the next interrupt, trap or exception
+occurs.
+\end{lyxlist}
+
+\paragraph{Interrupt level control}
+
+Most microprocessors support several interrupt levels, where the higher
+the level the better precedence of execution over others. Manipulating
+the interrupt priority level (IPL) using Set Priority Level functions
+becomes useful for critical code sections which need to disable all
+interrupts at the specified level and under. Although port-specific
+code attempts to provide it's own finer grained interrupt control
+code when considered required, these should be available. The \emph{\_ipl\_t}
+type itself is left to be defined with \emph{typedef} by the processor-specific
+code to the best variable type to hold the processor IPL state.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{\_ipl\_t~\_spl}n\emph{(void)}}] Immediately sets the current
+priority level to the one specified by \emph{n}. Thus, functions such
+as \emph{\_spl0()}, \emph{\_spl1()}, \emph{\_spl2()}, etc should be
+provided, for each interrupt level. \emph{\_spl0()} should enable
+all interrupt levels to occur. The returned value serves to eventually
+restore the previous interrupt level using \emph{\_splx()}, and is
+an abstract type defined by the processor-specific code.
+\item [{\emph{\_ipl\_t~\_splhigh(void)}}] Usually a macro to the highest
+\emph{\_spl}n\emph{()} function, it disables all interrupts by setting
+the highest priority level, thus masking all interrupts.
+\item [{\emph{void~\_splx(\_ipl\_t~state)}}] Permits to restore the previous
+interrupt priority level which was active before a call to an \emph{\_spl}{*}\emph{()}
+function was made, using the state value which was supplied by them.
+\end{lyxlist}
+
+\subsubsection{m68k}
+
+The Motorola MC68000L8 and MC68000L10 processors were the first to
+run Xisop. No support for MMU is present, such memory management units
+usually come on other external circuits for this processor, and there
+are various types. As Xisop does not need MMU, those processors were
+an ideal target. Although internally built as 16-bit processors, these
+processors behave as 32-bit ones from the programming point of view.
+It is also expected to run the same (or with minor modifications to
+disable their MMU) on the other processors of the 680x0 family, which
+are fully 32-bit. The assembly code observes the following rules to
+properly work with GCC compiled C modules:
+\begin{itemize}
+\item Stack pointer consists of A7/SP and frame pointer of A6/FP. In supervisor
+mode, the user stack pointer consists of USP and specialized instructions
+need to be used to access and manipulate it.
+\item Registers A0 and D0 serve the special purpose of return code for functions.
+Where the C code expects A0 or D0 to be used depends on the function
+prototype as seen from C. Functions expected to return a pointer should
+do so in A0, and D0 is used for other integer values. Assembly functions
+expected to be called from C must have a C function prototype defined
+in a headerfile which the C code must include.
+\item Assembly functions save all the registers they modify, and restore
+them before returning. As such, functions returning nothing (void)
+are expected to never return with a different register state. However,
+this is not always true of GCC generated code. Of course, the D0 register
+in the case of integer returning functions, and A0 for pointer returning
+ones should as expected modify the corresponding register as well.
+Registers to be saved are pushed on the stack, which grows upwards.
+\item Because there are various registers which GCC generated code modifies
+without always saving, exception handlers save all general purpose
+registers A0-A6 and D0-D7 registers, and restore them before returning
+with RTE. It was a false assumption to previously only backup A0 and
+D0 which are used as function return codes, and many problems occurred
+back then with this attempt.
+\item When an assembly function calls a C function, it needs to push the
+arguments in the stack, growing upwards, in reverse order, before
+calling it. After the C function returned, the stack pointer should
+be updated by additioning the number of bytes that were pushed. In
+the case where 16-bit or 8-bit values are passed as arguments, GCC
+still expects a stack entry of 32-bit size.
+\item An assembly function expected to be called from C must obtain the
+arguments (if any) from the stack. These are ordered growing downwards,
+as they were inserted in reverse order in the stack, growing upwards.
+Obviously, when registers are temporarily saved on the stack to preserve
+their state and restore them before returning, the offset at which
+these parameters are found on the stack changes, and the code has
+to account for this.
+\item The \emph{\_ctx\_t} manipulation functions had to be implemented as
+follows: \emph{\_ctx\_init()} can be called from usermode and only
+creates a context with zero registers, etc. However, \emph{\_yield()}
+had to be implemented using a trap to execute in supervisor mode,
+and the scheduler preemptive interrupt also executes in supervisor
+mode. Both save the current context to \emph{root-\textgreater{}curctx},
+call \emph{schedule()} and load back the context from \emph{root-\textgreater{}curctx},
+as expected. They need to use privileged instructions to change SR
+(status register) and USP (user stack pointer), because SR/A7 becomes
+the SSP (supervisor stack pointer) when in supervisor mode. To make
+sure to respect the PC (program counter) address of the contexts,
+they are manipulated on the supervisor stack (SSP), where the m68k
+saves them when jumping to the exception handler. As such, RTE (return
+from exception) automatically jumps where it should for the current
+context. The offset to the SR 16-bit register is usually \%sp@ and
+the one for PC 32-bit one in \%sp@(2) when initially intering the
+trap or interrupt exception. This offset has to be recalculated as
+registers are being saved on the stack, of course.
+\end{itemize}
+Other m68k specific notes about aspects which had to be taken in consideration:
+\begin{itemize}
+\item At kernel initialization, room for the supervisor stack pointer needs
+to be setup, and the Supervisor Stack Pointer (SSP/A7) should be set
+properly. To do this it is necessary to go in supervisor mode, and
+then set the A7 register to the right address. The way this must be
+done depends on the architecture. Because at bootup ROM code may have
+taken control already and one must use it's own facilities to obtain
+supervisor privileges.
+\item Dropping to user state from supervisor state to call Xisop \emph{main()}
+is rather simple. 1024 bytes are taken from the current SSP (A7),
+and assigned to the USP. The supervisor bit in SR is then unset, and
+a jump to \emph{main()} is made. The function is very tiny and only
+ensures to launch the various initial tasks, then waits forever in
+a loop using \emph{\_idle()} calls via \emph{sys\_idle()}. It corresponds
+to the \emph{\_scontext} \emph{\_ctx\_t} in \emph{root-\textgreater{}curctx}
+when no tasks are on the ready queue. Such a small stack buffer is
+then safe.
+\item Using GCC 2.95.3, -O2 and -fomit-frame-pointer compilation directives
+seem to generate both well optimized and small m68k code. I however
+noted that using -fno-function-cse was also required with -O2, without
+which the resulting code crashed. -m68000 was used to generate true
+MC68000 code (no support for 020+ specific instructions which wouldn't
+run on a plain 68000).
+\item Although m68k is very good to produce position-independent code, the
+default output GCC produces still comports instructions using direct
+addressing, except when -fpic is used, in which case additional symbols,
+with a .got table need to also be in the code, even if m68k generally
+doesn't require these for position-independent code (it has all the
+relative addressing instructions required for large memory model).
+As the only solution I found to properly relocate the code upon loading
+would be to write an ELF or a.out loader, which isn't done yet, the
+kernel code is loaded at a specific location, defined before compilation.
+A GCC ld BFD backend will need to be written, or an ELF loader, to
+allow to relocate the kernel, as well as file executable binaries.
+\item The \emph{\_spl}n\emph{()} and \emph{\_splhigh()} functions were implemented
+as macros, calling the assembly \emph{\_spl()} function which takes
+a 16-bit argument (the new SR to apply). \emph{\_splx()} assembly
+functions restores the previous SR. As SR is 16-bit, the \emph{\_ipl\_t}
+type was defined as an \emph{u\_int16\_t} internally. This allowed
+to generate very compact code for the eight interrupt priority level
+control functions which m68k required.
+\item The \emph{\_lock\_}{*}\emph{()} functions were implemented using the
+TAS instruction for atomicity, and the \emph{\_lock\_t} data type
+was internally defined as an \emph{u\_int8\_t}.
+\item The \emph{\_rlock}{*}\emph{()} functions could be implemented without
+the use of an internal \emph{\_lock\_t} to guarrantee atomicity, because
+the m68k processor is capable of addition and substraction on a 32-bit
+value in a single instruction. An \emph{\_rlock\_t} consists of a
+\emph{int32\_t} for this architecture.
+\item Before the port-specific code calls Xisop \emph{main()}, it is necessary
+to switch back to user processor mode. The \emph{\_usermode()} function
+was implemented for this and added to the m68k set of processor-specific
+functions, which allows to create a 1024 bytes user stack from the
+current supervisor stack, switches to usermode, and jumps to the specified
+function.
+\end{itemize}
+
+\subsection{Port specific notes}
+
+
+\subsubsection{Required backend and support functions}
+
+Each architecture needs a specific initialization section, such as
+setting up exceptions, interrupts and memory. Although this can also
+be CPU-specific, the various architectures using the same processor
+would most likely still need these to be different. They are thus
+considered as port-specific low-level backend support. Similarly to
+the processor-specific support code, \emph{support.h} and \emph{ar/{*}.a}
+are the main targets that should be provided to allow the rest of
+the kernel to use it, as it will include \emph{port/support.h} and
+will link in \emph{port/ar/}{*}.\emph{a}, where \emph{port} consists
+of a symbolic link to the actual \emph{ports/\textless{}name\textgreater{}}
+directory.
+
+It is allowed if desired to also supply port specific functions to
+replace some of the common machine-independent ones, which may be
+desired for speed at occasions. When this is done, the functions should
+behave identically as expected, should bear the same names, and no
+prototypes should be provided for them in \emph{support.h}. The port-specific
+\emph{ar/{*}.a} modules will be linked before the processor-specific
+and Xisop common libraries and those functions will replace them if
+they are supplied. These functions could be for instance: \emph{memcmp()},
+\emph{memcpy()}, \emph{memset()}, etc.
+
+After the kernel was built, using both common, processor and port
+code, control is left again to the port specific code which should
+handle boot support; This can be creating a floppy image, etc. See
+the section on the building process for more information.
+
+It is important that the port-specific code provides the \emph{\_start}
+entry point. This code should then set the processor in supervisor
+mode where required, setup the supervisor mode stack pointer, disable
+interrupts and perform initialization of the various systems described
+below. Afterwards, it should switch back to userstate processor mode,
+and leave control to the Xisop \emph{main()} function, which will
+not return. That \emph{\_start} entry point is where the boot kernel
+loader needs to jump to.
+
+
+\paragraph{Memory initialization and requirements}
+
+The port-specific \emph{support.h} should define C enumerators (enum)
+and definitions (\#define) for the machine-independent Xisop memory
+code. It is recommended to also read the section on Xisop memory management
+for more information. The port-specific requirements are explained
+as follows:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{\#define~\_PAGE\_SIZE~\textless{}value\textgreater{}}}] The
+memory management system needs to know the amount of bytes in which
+to split pages. On operating systems which support Memory Management
+Units (MMU), this is required to match the page size which the hardware
+requires. In the case of Xisop, it is safe to use any reasonable multiple
+of 16 bytes here. A common \emph{\_PAGE\_SIZE} is 4096 bytes. On systems
+with very low memory it may be useful to use 1024, or even 256. This
+value is used by the page memory allocation primitives.
+\end{lyxlist}
+The \emph{mpool\_t}, a multi-purpose memory pool which allows management
+primitives such as \emph{\_malloc()} and \emph{\_free()}, requires
+specific definitions:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{\#define~\_MPOOLS~\textless{}value\textgreater{}}}] This
+is the number of internal \emph{pool\_t} which are necessary to initialize
+for an \emph{mpool\_t}, to be able to use these efficient pools when
+dealing with byte requirements which are too small to be rounded at
+page boundaries.
+\item [{\emph{\#define~\_MPOOLSTART~\textless{}value\textgreater{}}}] The
+smallest amount of bytes which an \emph{mpool\_t} can allocate, which
+is multiplied by two for each consecutive \emph{pool\_t} initialized
+for the \emph{mpool\_t} at \emph{mpool\_init()}.
+\item [{\emph{\#define~\_MPOOLSTEP~\textless{}value\textgreater{}}}] The
+number of physical \emph{\_PAGE\_SIZE} bytes pages into a \emph{page\_t}
+for every \emph{pool\_t} of an \emph{mpool\_t}.
+\end{lyxlist}
+To explain better the previous definitions, what the \emph{mpool\_init()}
+function actually does is iterate \emph{\_MPOOLS} times to initialize
+the \emph{pool\_t} objects, setting the first \emph{pool\_t} to allocate
+units of \emph{\_MPOOLSTART} bytes, the second \emph{\_MPOOLSTART}
+{*} 2, and continueing to iterate multiplying the unit size by two
+until \emph{\_MPOOLS} number of \emph{pool\_t} were initialized. Larger
+unit sizes which cannot be handled by the \emph{pool\_t} will be rounded
+at page boundaries. \emph{\_MPOOLSTEP} simply consists of the \emph{stepp}
+argument to \emph{pool\_init()}. As such, all the definitions above
+intimately correlate to eachother, and are quite versatile to match
+various requirements an architecture may need.
+
+For a system with a \emph{\_PAGE\_SIZE} of 4096 bytes, an \emph{\_MPOOLSTART}
+of 16 and \emph{\_MPOOLSTEP} of 1, 7 consists of an ideal value for
+\emph{\_MPOOLS}. On a system with a fair amount of memory, if it is
+wanted to minimize calls to the page management primitives even more,
+it is possible to set a larger \emph{\_MPOOLSTEP} and raise \emph{\_MPOOLS}
+accordingly, while keeping the same underlaying \emph{\_PAGE\_SIZE}.
+Basically \emph{\_MPOOLS} should be set just below the \emph{pool\_init()}
+breaking point, where it returns FALSE because \emph{sizeof(mnode\_t)}
+plus the current \emph{\_MPOOLSTART} multiple consist of too large
+objects to fit into a \emph{pool\_t} page (which in turn depends on
+\emph{\_MPOOLSTEP} which changes the \emph{page\_t} size for a \emph{pool\_t}).
+
+It is recommended to read the source for \emph{mpool\_init()} which
+is located in \emph{src/common/kernel/memory.c} for a better understanding,
+as well as the documentation on Xisop memory management primitives.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{enum~\_memtypes}}] This enumeration should define the various
+memory types the architecture provides, in preference order when \emph{\_MEM\_ANY}
+is used (-1) when calling the allocation primitives. The enumeration
+should set \emph{\_MEM\_}{*} names, the first one corresponding to
+0, and the last element should consist of \emph{\_MEM\_MAX}, corresponding
+to the number of memory types the system provides. Not all architectures
+provide more than a single memory type, under which case \emph{\_MEM\_ALL}
+will correspond to 0 and \emph{\_MEM\_MAX} to 1, respectively.
+\end{lyxlist}
+Other than defining these requirements in it's \emph{support.h} headerfile,
+the port-specific initialization code is responsible for attaching
+the available physical memory pages to the system pools, before initializing
+the public interrupt facilities. This is done by first calling the
+\emph{memory\_init()} machine-independent function. Then, the \emph{mchunk\_init()}
+and \emph{mchunk\_attach()} functions which are documented in the
+Xisop memory management section are normally called once for each
+contiguous memory area which is to be used as general purpose memory.
+The video memory, or other special memory sections should not be included
+in the system memory pools. It is important to perform this step before
+continuing on with the next initialization sections. The \emph{mchunk\_init()}
+and \emph{mchunk\_attach()} functions are described in detail in the
+Xisop memory management section.
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~memory\_init(void})}] This function is only called
+once by the port-specific initialization code before starting to attach
+memory chunks to the system pools. After this function executes, it
+becomes possible to use the \emph{mchunk\_init()} and \emph{mchunk\_attach()}
+functions to attach contiguous memory regions to the system page pools.
+\end{lyxlist}
+
+\paragraph{Exceptions initialization and public interrupt facilities}
+
+It is recommended to maintain an \emph{\_interrupt\_depth} variable
+or recursive lock, which each trap or interrupt handler should increase
+at startup and decrease before returning, which can be used for the
+scheduler interrupt to determine if it should call \emph{schedule()}
+or not. As the scheduler timer interrupt would also raise it at startup,
+it can then mask interrupts and evaluate if it equals 1 afterwards,
+in which case it is sure to have the right to perform a context switch.
+This permits to make system calls uninterruptible for the time of
+their execution and to protect the scheduler from performing context
+switches while an interrupt handler is executing, which at occasions
+could result in recursivity and context corruption. As an effort is
+made to minimize the number of system call traps required during normal
+Xisop function, the preemptive nature of the scheduler is not bothered
+by having uninterruptible system calls, unless a task voluntarily
+abuses \emph{sys\_custom()}, which is by all meals legal if one wants
+to.
+
+Obviously, most exception handlers are responsible to return with
+the registers unchanged, and as such should normally save all general-purpose
+registers on the stack at startup, and return them before returning.
+This is especially true if C functions are to be called from the interrupt
+handler, where unexpected registers may be tempered with.
+
+After setting up the memory, the public interrupt facilities can be
+defined to the system and their internal handler vectors setup. Usually,
+\emph{facilities\_init()} will be called before vectors are initialized,
+or if not possible, dummy do-nothing vectors can be installed, and
+can then be setup definitely after calling f\emph{acilities\_init()},
+when it becomes safe.
+
+This function call depends on the \emph{enum \_facilities} C enumerator
+which should be defined in the port specific \emph{support.h} headerfile.
+This enumerator defines each facility in the form of \emph{\_FACILITY\_}{*},
+where {*} consists of the name of the facility. The first entry should
+evaluate to 0, and the last one to the total number of facilities
+(\emph{\_FACILITY\_MAX}). The various interrupt handlers need to internally
+call \emph{facility\_exechooks()} on the facility they are serving
+for the public facilities to become alive. At it's discretion, the
+handler may temporarily disable the interrupt source when calling
+the function, but \emph{facility\_exechooks()} internally performs
+recursion prevention and makes sure to not execute the hooks if a
+hook is currently being inserted or removed, using an \emph{\_rlock\_t}
+for each facility internally.
+
+There only is at least one facility which is required for all ports
+to provide. This facility should be named \emph{\_FACILITY\_SCHEDTIMER},
+and should call the hooks at \emph{\_SCHEDTIMER\_HZ} frequency, which
+should also be defined by the port-specific \emph{support.h}. This
+way, simple time-based Xisop applications can work portably on all
+ports. This facility should correspond to the timer interrupt which
+the port chose to use for the preemptive scheduler timer. This facility
+does not interfere with the scheduler activities; it is called when
+the interrupt occurs even if the scheduler \emph{rlock\_t} is set
+(\emph{schedule()} handles the scheduler locked/disabled case already).
+Generally, the scheduler interrupt handler works as follows:
+\begin{itemize}
+\item Increase the global \emph{\_interrupt\_depth} variable like for all
+handlers
+\item Temporarily disable the interrupt source (by raising the IPL using
+\emph{\_spl}{*}\emph{()} or otherwise) to prevent any possible recursion
+or other interruption.
+\item Save the current user CPU context to the \emph{root-\textgreater{}curctx
+\_ctx\_t}
+\item Execute the facility hooks using \emph{facility\_exechooks(\_FACILITY\_SCHEDTIMER)}
+\item Verify if the \emph{\_interrupt\_depth} variable equals to 1. If so,
+call \emph{schedule(NULL)}, which may or may not change the \emph{root-\textgreater{}curctx}
+backed up context pointer and \emph{root-\textgreater{}curtask}
+\item Load back the CPU context from the new \emph{root-\textgreater{}curctx}
+(which possibly can be the same, but this must not be assumed)
+\item Re-enable the scheduler interrupt source
+\item Decrease the global \emph{\_interrupt\_depth} variable like for other
+handlers
+\item Return from interrupt handler while ensuring to jump to the PC of
+the new context. Generally, the address to return to is backed up
+into the supervisor stack, which needs to be modified for this. That
+address within the supervisor stack pointer is where context save
+and load operations obtain and set the Program Counter address.
+\end{itemize}
+Because of the context load/save operations, and return address hack,
+the scheduler interrupt handler is usually implemented entirely in
+assembly (although it calls the \emph{schedule()} and \emph{facility\_exechooks()}
+C functions).
+
+The other facilities, which are optional and can be provided by the
+port-specific code will often be implemented as a mix of assembly
+and C code and will similarily at least:
+\begin{itemize}
+\item increase global \emph{\_interrupt\_depth} and optionally disable interrupt
+source
+\item save registers
+\item perform any additional wanted operation
+\item call \emph{facility\_exechooks()} on their facility
+\item restore registers
+\item re-enable the interrupt source if it was temporarily disabled, and
+decrease global \emph{\_interrupt\_depth}
+\item return
+\end{itemize}
+The facility public interface and \emph{facility\_exechooks()} are
+described in more details in the Xisop public facilities section.
+
+
+\paragraph{System trap triggers and handlers initialization}
+
+It is important for the port-specific code to define the \emph{\_syscall()}
+and \emph{\_yield()} functions. The role of the system call trap handler
+is to serve system call functions uninterruptibly, internally calling
+\emph{\_scatch()} Xisop common function with the requested arguments.
+Here is described the trigger, which function should be supplied by
+the port-dependent code:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_syscall(u\_int32\_t~function,~void~{*}res,~void~{*}args)}}] Internally
+places the supplied parameters into a static buffer or in registers,
+and generate a processor trap interrupt. It is safe to save the registers
+we modify on the stack, and restore them from the stack after the
+trap returns, and then return ourselves, because nor \emph{\_yield()}
+nor context switching are implemented via syscalls. Although the understanding
+of the arguments is not necessary at this point, \emph{function} specifies
+the syscall number which is to be performed, \emph{res} a pointer
+to eventual results expected from that system call (or NULL), and
+\emph{args} optional arguments which need to be passed to the system
+call (or NULL). Although this function is also highly processor-specific,
+the choice of the trap vector to implement system calls is left to
+the port writer, and as such this function as well.
+\end{lyxlist}
+The other end, consisting of the system call trap handler, is responsible
+for the following:
+\begin{itemize}
+\item Increment \emph{\_interrupt\_depth} global variable
+\item Save all general purpose registers
+\item Read arguments supplied by \emph{\_syscall()} from the static buffer
+or registers, and insert them on the stack as C arguments, then call
+\emph{\_scatch()} C function. Fix the stack pointer to forget the
+pushed stack arguments.
+\item Restore general purpose registers we saved
+\item Decrement \emph{\_interrupt\_depth} global variable
+\item Return
+\end{itemize}
+The \emph{\_scatch()} function (which is defined in \emph{src/common/kernel/syscall.c})
+is responsible for performing the necessary sanity checking on the
+arguments, and does not need to be provided by the machine-specific
+code:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_scatch(u\_int32\_t~function,~void~{*}results,~void~{*}arguments)}}] Consists
+of the heart of the syscall trap. \emph{function} specifies the requested
+syscall function number which was called. These are standard and are
+described in the ``System Calls'' section. \emph{results} consists
+of a pointer to the block of memory which will be modified to store
+the syscall results by this \emph{function}. It can be NULL. \emph{arguments}
+similarly specifies the location of the arguments expected for this
+\emph{function}, or NULL. This function refuses to perform any call
+if the supplied \emph{function} is invalid (out of bounds).
+\end{lyxlist}
+After setting up the \emph{\_syscall()} trap vector, the interrupts
+can remain disabled/masked still, like since the beginning. More information
+on the generic user system calls interface is provided in the Xisop
+system calls section.
+
+Another requirement that the port-specific code must satisfy consists
+of the \emph{\_yield()} internal function:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{\_yield(task\_t~{*}task)}}] permits the current task to
+immediately perform a context switch to another task, in fact preempting
+itself. \emph{task} is an optional preference of which task to switch
+to, or NULL, which parameter should be passed when the trap handler
+internally calls \emph{schedule()}. This is usually implemented in
+the form of a trap like for \emph{\_syscall()}, which sets the supplied
+argument in a static buffer to prevent modifying a register (it is
+unsafe to save registers on the stack as we most likely won't be the
+next task to return from the trap). The backend trap handler acts
+as follows:\end{lyxlist}
+\begin{itemize}
+\item Increase the global \emph{\_interrupt\_depth} variable like for all
+handlers
+\item Temporarily disable all interrupt sources (by raising the IPL using
+\emph{\_splhigh()} or equivalent to prevent any possible interruption,
+but without modifying registers, which can be saved and restored safely
+before performing the next steps
+\item Save the current user CPU context to the \emph{root-\textgreater{}curctx
+\_ctx\_t}
+\item Insert the supplied argument from the static buffer in the stack as
+a C argument
+\item Call \emph{schedule()}, which may or may not change the \emph{root-\textgreater{}curctx}
+backed up context pointer and \emph{root-\textgreater{}curtask}
+\item Adjust stack pointer to forget the passed argument
+\item Load back the CPU context from the new \emph{root-\textgreater{}curctx}
+(which possibly can be the same, but this must not be assumed)
+\item Re-enable interrupts calling \emph{\_spl0()} or performing equivalent
+taking care not to modify registers. Using the stack is now safe.
+(remember that the old level obtained from \emph{\_splhigh()} cannot
+be obtained back unless saved to a static buffer, in which case it
+can be restored properly. Saving it on the stack is also safe if the
+context switching function only modified the user stack pointer and
+the supervisor stack pointer consists of the active stack during the
+trap).
+\item Decrease the global \emph{\_interrupt\_depth} variable like for other
+handlers
+\item Return from interrupt handler while ensuring to jump to the PC of
+the new context. Generally, the address to return to is backed up
+into the supervisor stack, which needs to be modified for this. That
+address within the supervisor stack pointer is where context save
+and load operations obtain and set the Program Counter address.
+\end{itemize}
+
+\paragraph{Suggestions}
+
+The rest of the port-specific code internals which it needs to perform
+are left to the implementor, as long as they suit well the purpose.
+However, a few suggestions are made which can help to keep some consistency
+among the various ports, in their choice of function names for instance.
+This example attempts to restrict the assembly code to the minimum,
+while calling C functions as much as possible to handle most exception
+code.
+
+It is generally a good idea for hardware interrupts to provide one
+separate assembly handler per interrupt level, to prevent the C code
+from having to perform unnecessary additional conditional instructions
+to evaluate the level, as it already usually needs to detect the source.
+For other general-purpose trap vectors, it is allowed to provide support
+to execute a single C function for all of them, passing in an argument
+the required information on the trap vector number. This however would
+be less desireable than having a different facility for each, if their
+frequency was high and a large number of hooks were attached, because
+they then would obviously all run often, evaluating one by one if
+they are interested in the trap. Suggestion names for various common
+facility types are shown in the Xisop public interrupt facilities
+section.
+
+It is to be noted that the timer interrupt chosen to be used as the
+preemptive scheduler one is special as it needs to perform context
+switching, often also implying stack pointer access and modifications.
+This handler is therefore usually fully written in assembly, as previously
+demonstrated. As a general rule, the role of the exception vectors
+is to call a C function which can then handle the event.
+
+Here are various C functions which can be called by the machine language
+backend to exceptions, traps and interrupts:
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_icatch}n\emph{(void)}}] For every hardware interrupt
+level, une such C function can be called. For interrupt level 3, \emph{icatch3()}
+would be called, for instance. It is possible to pass parameters if
+required to detect the interrupt source in the C functions.
+\item [{\emph{void~\_tcatch(int~vector)}}] This C function can be called
+for all software traps which occur that do not correspond to the syscall
+or yield trap vectors. \emph{vector} argument specifies the number
+of the trap vector.
+\item [{\emph{void~\_ecatch(int~vector)}}] A C function called when an
+hardware exception is generated, such as bus error, division by zero,
+etc. It is recommended that the code processing these do not hang
+or crash the system permanently if high-reliability is required. \emph{vector}
+consists of the exception vector, or reason which caused it, and \emph{stack}
+points as usual to the retrurn from exception address on the stack.
+Although this is CPU-specific, port-specific exception handling code
+may be provided.
+\end{lyxlist}
+
+\paragraph{Port-specific system shared libraries to attach and system tasks
+to launch}
+
+Although Xisop has a few common portable system libraries and tasks
+which it initializes at startup, it is ideal for the port-specific
+section to be able to describe which other tasks should be launched,
+and their parameters such as priority level, stack size, etc. To do
+this the port-specific code needs to provide the \emph{\_port\_init()}
+function which the Xisop init task will invoke and which then can
+use the required flexibility. It should be noted that as the init
+task only has a 4096 bytes stack, this function is expected to at
+least create a task with a larger stack if it needs to before performing
+it's own initialization if it overuses the stack. The kernel expects
+the current state to remain the same when the function returns (apart
+of course from the new libraries and tasks which may now exist and
+be resident).
+\begin{lyxlist}{00.00.0000}
+\item [{\emph{void~\_port\_init(void)}}] Port-specific function who's
+purpose is to attach the wanted port-specific libraries, and to launch
+the wanted port-specific tasks. This function is called by the Xisop
+\emph{init} task which runs with a stack of 4096 bytes, and runs in
+userstate mode like normal tasks.
+\end{lyxlist}
+
+\paragraph{Last steps of the port-specific initialization code}
+
+After switching to supervisor mode, setting up memory, system call
+and yield traps, as well as scheduler timer interrupt, and initializing
+the public interrupt facilities, port-specific initialization code
+is then complete, and it now should execute the following steps:
+\begin{itemize}
+\item Call the machine-independent \emph{xisop\_init()} function, which
+sets up various internal structures and disables the scheduler, and
+then internally calls \emph{\_spl0()} as interrupts finally become
+safe to enable.
+\item Call the famous Xisop machine-independent \emph{main()} function which
+is expected to never return. If the processor currently runs into
+supervisor mode, it is necessary to drop to usermode before calling
+\emph{main()}. The role of this function is to enable the scheduler,
+launch the Xisop \emph{init} task, which in turn will make sure to
+launch the \emph{task reaper} task, and call the port-dependent \emph{\_port\_init()}
+function which then can also attach and launch the wanted resources.\\
+Note that the \emph{main()} function with it's current stack becomes
+the initial context that the scheduler always switches to when there
+remains no tasks in the ready queue to run. As such, after launching
+the init task, it loops forever calling \emph{sys\_idle()} system
+call which internall calls processor-specific \emph{\_idle()}, which
+permits the processor to stop spinning until the next interrupt or
+trap event occurs.
+\end{itemize}
+
+\subsubsection{Amiga}
+\begin{itemize}
+\item The Amiga port uses the \emph{processors/m68k} processor-specific
+code.
+\item In addition to the m68k \emph{\_spl}{*}\emph{()} functions, the amiga
+low level library also supplies \emph{aspl}{*}\emph{()} functions
+using INTENA control register for finer grained control to disable
+certain interrupts for a period of time. For instance, \emph{asplvblank()}
+disables the vertical blank interrupt, \emph{asplsched()} disables
+the scheduler, etc. \emph{asplx()} is used to restore the previous
+state, as usual. For \emph{asplsched()}, a \emph{\_lock\_t} is used
+to turn the scheduler ON/OFF, so that the timer interrupt it ties
+to still can execute other code if required. \emph{XXX}
+\item The chosen \emph{\_syscall()} trap vector was 0.
+\item The chosen \emph{\_yield()} trap vector was 1.
+\item The Amiga has four multi-purpose timers in it's two CIA chips. The
+use Xisop currently makes of them is as follows: CIA-A TimerA is reserved
+for keyboard timing, which is a hardware requirement. CIA-B Timer
+A is used by the Xisop scheduler, which generates high-level hardware
+interrupts of high priority (IPL 6). The B timers and TOD counters
+are unused and remain available for devices and user code for each
+CIA.
+\item The two memory page pools (\emph{ppool\_t}) initialized at startup
+by \emph{\_init\_memory()} consist of one for CHIP RAM, and another
+one for FAST RAM. The \emph{enum \_memtypes} as such set \emph{\_MEM\_FAST}
+to 0 and \emph{\_MEM\_CHIP} to 1, FAST memory being the prefered if
+\emph{\_MEM\_ANY} is used. Currently, the addresses mapped in the
+standard distribution are 0x - 0x for CHIP (enhanced 2 megabytes agnus
+chip (fatter)), and 0x00200000-0x00600000 for FAST (usual 4 first
+megabytes of ZorroII memory found on A2000). This currently needs
+to be modified in the code itself as the booting process currently
+does not detect the available RAM amounts. The provided UAE Amiga
+Emulator configuration file which is configured as such can be located
+in the \emph{src/ports/amiga/boot} directory. \emph{XXX}
+\item To setup the initial supervisor stack, the AmigaOS SuperState() exec.library
+call must be used to gain supervisor privileges. The SSP/A7 register
+can then be set to the proper location. To do this a special function
+is provided in assembly by the Amiga support library, \emph{void~\_supervisor(u\_int32\_t~{*}sp,~size\_t~ssize~void
+({*}func)(void))} which allows to set the new entry point function
+and stack. To the provided \emph{stack} pointer will be additionned
+the supplied stack size \emph{ssize} automatically because of the
+stack which grows upwards. The supplied function \emph{func} is then
+given control to. This function is expected to never return.\end{itemize}
+
+\end{document}