%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Copyright (c) 2011-2013, ETH Zurich.
% All rights reserved.
%
% This file is distributed under the terms in the attached LICENSE file.
% If you do not find this file, copies can be found by writing to:
% ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\documentclass[a4paper,11pt,twoside]{report}
\usepackage{bftn}
\usepackage{calc}
\usepackage{verbatim}
\usepackage{xspace}
\usepackage{pifont}
\usepackage{textcomp}
\usepackage{amsmath}
\usepackage{multirow}

\title{Mackerel User Guide}
\author{Barrelfish project}
% \date{\today}		% Uncomment (if needed) - date is automatic
\tnnumber{2}
\tnkey{Mackerel}

\begin{document}
\maketitle			% Uncomment for final draft

\begin{versionhistory}
\vhEntry{1.2}{31.05.2010}{TR}{Initial version under new formatting}
\vhEntry{1.3}{15.08.2011}{TR}{Added support for imports and new
  command-line options}
\vhEntry{1.4}{09.12.2011}{TR}{New mapping for constants}
\vhEntry{1.5}{11.03.2013}{TR}{Added quick reference, corrected errors,
  and clarified field insertions}
\end{versionhistory}

% \intro{Abstract}		% Insert abstract here
% \intro{Acknowledgements}	% Uncomment (if needed) for acknowledgements
\tableofcontents		% Uncomment (if needed) for final draft
% \listoffigures		% Uncomment (if needed) for final draft
% \listoftables			% Uncomment (if needed) for final draft
\cleardoublepage
\setcounter{secnumdepth}{2}

\newcommand{\fnname}[1]{\textit{\texttt{#1}}}%
\newcommand{\datatype}[1]{\textit{\texttt{#1}}}%
\newcommand{\varname}[1]{\texttt{#1}}%
\newcommand{\keywname}[1]{\textbf{\texttt{#1}}}%
\newcommand{\tabindent}{\hspace*{3ex}}%
\newcommand{\Mac}{Mackerel\xspace}


%-------INTRODUCTION 


\chapter{Introduction and Usage} 

\Mac is a domain-specific language used to describe hardware devices
and the in-memory formats of registers and data structures like
descriptor lists, page-table entries, etc.   

The \Mac language itself is designed to be easy to transcribe into
from a hardware data book or similar description - most of the
constructs correspond to the kinds of concepts one finds in hardware
descriptions. 

A feature of the \Mac language is that, while traditional comments in
\Mac specifications are allowed, explanatory text in English is
included as part of a \Mac specification itself, and used to generate
debugging code which explains the meaning of register values. 

 Typically, it takes as input a specification written in the
Mackerel language and outputs a C header file consisting of a large
number of C inline function definitions to access and manipulate
registers and in-memory data structures, format them for printing in
human-readable form, etc.  

The \Mac compiler is written in Haskell using the Parsec parsing
library.  A quick roadmap of the source code files is provided in
Chapter \ref{chap:sourcetree}. 

To manually invoke \Mac, run:

\verb~> mackerel --shift-driver -c devFile.dev -o devFile.h~

This will translate a device file into a single C header file containing all
relevant functions for accessing the device, as described in
Chapter~\ref{chap:shiftdriver}. 

If you wish to use the (deprecated) bitfield-based back-end instead,
you can use:

\verb~> mackerel --bitfield-driver -c devFile.dev -o devFile.h~

This backend should not be used for new code, as it is not portable
across compilers.  It is described in
Chapter~\ref{chap:bitfielddriver}. 

\section{Command-line options}

The complete list of comand-line options supported by the current
Mackerel compiler is as follows:
\begin{itemize}
\item \texttt{-c} \textit{filename} or
  \texttt{--input-file=}\textit{filename}: This option is mandatory
  and specifies the pathname to be read.  This pathname must specify
  the file: the main input file will not be searched for along the
  search path. 

\item \texttt{-I} \textit{dir} or \texttt{--include-dir}
  \textit{dir}: this option can be supplied multiple times and
  specifies the search path for imported files. 

\item \texttt{-v} or \texttt{--verbose}: Increases the verbosity level
  of the compiler.

\item \texttt{-o} \textit{filename} or \texttt{--output-file}
  \textit{filename}: this option, if supplied, specifies the name of
  the C header file which will be written by the compiler.  If not
  given, the filename will be derived from the input filename by
  removing all the directory components (i.e. it will reside in the
  current working directory) and appending \texttt{.h}.

\item \texttt{-S} or \texttt{shift-driver}: Specifies the shift driver
  backend; this is the default. 

\item \texttt{-B} or \texttt{bitfield-driver}: Specifies the bitfield
  driver backend; this is deprecated.  Furthermore, imports are
  (deliberately) not supported by the bitfield driver.  If multiple
  \texttt{-S} and \texttt{-B} options are specified, the last one
  determines the compiler output. 

\end{itemize}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\chapter{Lexical Conventions}\label{chap:lexical}
The following convention has been adopted for Mackerel. It is similar to
the convention opted by modern day programming languages like C and Java.\\

\begin{description}
\item[Whitespace:]  As in C and Java, \Mac considers sequences of
  space, newline, tab, and carriage return characters to be
  whitespace.  Whitespace is generally not significant. 

\item[Comments:] \Mac supports C-style comments.  Single line comments
  start with \texttt{//} and continue until the end of the line.
  Multiline comments are enclosed between \texttt{/*} and \texttt{*/};
  anything inbetween is ignored and treated as white space.

\item[Identifiers:] Valid \Mac identifiers are sequences of numbers
  (0-9), letters (a-z, A-Z) and the underscore character ``\texttt{\_}''.  They
  must start with a letter or ``\texttt{\_}''.  
  \begin{align*}
    identifier & \rightarrow ( letter \mid \_ ) (letter \mid digit \mid \_)^{\textrm{*}} \\
    letter & \rightarrow (\textsf{A \ldots Z} \mid  \textsf{a \ldots z})\\
    digit & \rightarrow (\textsf{0 \ldots 9})
\end{align*}

  Note that a single underscore ``\texttt{\_}'' by itself is a special,
  ``don't care'' or anonymous identifier which is treated differently
  inside the language. 
  
\item[Integer Literals:] A \Mac integer literal is a sequence of
  digits, optionally preceded by a radix specifier.  As in C, decimal (base 10)
  literals have no specifier and hexadecimal literals start with
  \texttt{0x}.  Binary literals start with \texttt{0b}. 

  In addition, as a special case the string \texttt{1s} can be used to
  indicate an integer which is composed entirely of binary 1's. 

\begin{align*}
digit & \rightarrow (\textsf{0 \ldots 9})^{\textrm{1}}\\
hexadecimal & \rightarrow (\textsf{0x})(\textsf{0 \ldots 9} \mid \textsf{A \ldots F} \mid \textsf{a \ldots f})^{\textrm{1}}\\
binary & \rightarrow (\textsf{0b})(\textsf{0, 1})^{\textrm{1}}\\
allones & \rightarrow \textsf{1s}\\
\end{align*}


\item[Reserved words:] The following are reserved words in \Mac:
\begin{alltt}
  \begin{tabbing}
xxxxxxxxx \= xxxxxxxxx \= xxxxxxxxx \= xxxxxxxxx \= xxxxxxxxx \= xxxxxxxxx \kill
addr \> also \> bytewise \> constants \> datatype \> device \\
io \> lsbfirst \> many \> msbfirst \> pci \> regarray  \\
register \> regtype \> space \> stepwise \> type \> valuewise \\
import 
  \end{tabbing}
\end{alltt}

\item[Special characters:] The following characters are used as operators,
  separators, terminators or other special purposes in \Mac:
\begin{alltt}

  \{ \} [ ] ( ) + - * / ; , . _ = 

\end{alltt}

\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Declarations}\label{chap:declarations}

A \Mac source file must consist of zero or more \textit{import}
declarations, followed by a single \textit{device
  specification}, which itself consists of further specifications of
registers, register types, etc. 

\section{Imports}\label{sec:imports}

An import declaration makes the definitions in a different device file
available in the current device definition, as described below.  The
syntax of an import declaration is as follows:

\begin{syntax}
import \synit{device};
\end{syntax}

\begin{description}
\item[device] is the name of a device from which to import
  definitions.  
\end{description}

The \Mac compiler will search for a file with the appropriate name and
parse this at the same time as the main file, along with this file's
imports, and so on.  Cyclic dependencies between device files will not
cause errors, but at present are unlikely to result in C header files
which will successfully compile. 

\section{Devices}\label{sec:devices}

A device declaration in \Mac specifies a particular type of hardware
device (such as an ioAPIC or a particular Ethernet controller).   The
syntax is as follows:

\begin{syntax}
device \synit{name} [lsbfirst|msbfirst] ( \synit{args} ) "\synit{description}"
\verb+{+
  \synit{declaration};
  \ldots
\verb+}+;
\end{syntax}

\begin{description}
\item[name] is an identifier for the device type, and will be used to
  generate identifiers in the target language (typically C).  
  The name of the name of the device \emph{must} correspond to the
  filename of the file, including case sensitivity: for example, 
  the file \texttt{xapic.dev} will define a device type
  of name \texttt{xapic}. 

\item[lsbfirst or msbfirst] optionally specifies the \emph{bit order}
  of the declarations 
  inside the device file; if specified, it must be \texttt{lsbfirst}
  (the default) or \texttt{msbfirst}.  

  Note that this does not say \emph{anything} about the endianness of
  the hardware device, or the host platform, or the execution
  environment.  It simply says which order the bitfields in particular
  registers are listed in the declarations which follow --
  least-significant bits first or most-sigificant bits first. 

  The reason for this feature is that \Mac specifications are
  typically transcribed from chip datasheets, and while these are
  generally unambiguous there is no clear convention on which order to
  list a hardware register bitfields in a datasheet.   This feature 
  means that the \Mac specification can more closely resemble to text
  in the datasheet.  

  When transcribing a datasheet into a \Mac specification, if the
  fields in a register or register type are listed starting with the
  one which includes bit 0, specify \texttt{lsbfirst}.   If the fields
  are listed starting with the one which includes the high bit in the
  register, specify \texttt{msbfirst}.  In both cases type the fields
  in the order they are printed in the datasheet. 

\item[args] are the arguments that specify how to access the device.
  They are treated as base addresses in one of several \emph{address
    spaces} supported by \Mac (see Section~\ref{sec:spaces}
  below).  Typical devices have a single base address in either memory
  or I/O space, though some device types (of which only one instance
  ever exists, and at a fixed address) have no arguments, and others
  may have more if they have multiple register sets which can appear
  at different addresses.   

  The arguments will become arguments to the function that intializes
  the struct used to represent the device in \Mac-generated C.
  They are also used within the device declaration to specify the
  locations of individual registers or groups of registers. 

  Arguments are declared in C-style type notation as either of type
  \texttt{address} (in memory space) or \texttt{io} (in I/O
  space).  By convention a single device argument is named
  \texttt{base}. 

\item [description] is a string literal in double quotes, which
  describes the device type being specified, for example \texttt{"AC97
  Baseline Audio"}. 

\end{description}

After the description string follows in curly brackets a series of
declarations which specify details of the device hardware.   Each
declaration must be one of the following:

\begin{itemize}

  \item A \texttt{space} declaration, describing a device-specific
    address space for registers in addition to the built-in address
    spaces. 
  
  \item A \texttt{constants} list, analogous to a C enumeration type

  \item A \texttt{register} declaration, describing a particular
    hardware register or group of registers
    
  \item A \texttt{regtype} definition, giving the type and format of
    other hardware register values. 

\end{itemize}

\section{Address spaces}\label{sec:spaces}

Registers defined in a \Mac file
reside at specified addresses in an \emph{address space} (unless they
are specified as \texttt{noaddr}, see Section~\ref{sec:registers}). 

There are currently 3 built-in address spaces that \Mac understands,
and addresses in these spaces require both a base and an offset.  Base 
values are given as an arguments to the device specification, and so
each device argument must be declared as being of one of the following
types: 

\begin{description}

\item[addr]: Physical memory, for memory-mapped I/O.  Register
  locations in physical address space are given as offsets relative to
  a base address which is an argument to the device definition. 

\item[io]: I/O port space, for \texttt{ia32} machines.  An I/O address
  is a 16-bit port number, and register locations in I/O port space
  are given as offsets relative to a base address which is an argument
  to the device definition.   

\item[pci]: PCI Configuration space.  A PCI configuration space
  address is a 4-tuple of \textit{(bus, device, function, offset)}, however,
  \Mac only deals in integer offsets from an opaque ``base'' address,
  allowing for different addressing schemes depending on hardware.  

\end{description}

In addition, \Mac allows the specification of per-device address
spaces.  This feature can express a variety of hardware features, for
example processor model-specific registers, co-processor registers, 
device registers that must be accessed indirectly through another
index registers, etc.  

The syntax for defining a new address space is:

\begin{syntax}
space \synit{name}(\synit{index}) bytewise|valuewise|stepwise(\textit{step})|registerwise
          "\synit{description}"; 
\end{syntax}

\begin{description}
\item[name] is an identifier for the address space, and is used in
  register declarations instead of a builtin space such as
  \texttt{addr} or \texttt{io}. 

\item [index] is an identifier for the argument giving the address for
  the registers

\item [bytewise, valuewise or registerwise] defines how registers in the new
  space are addressed.  Bytewise addresses are like conventional
  memory addresses, for example two adjacent 32-bit registers in a
  bytewise-addressed space will have offsets that differ by 4.  All
  the built-in address spaces (\texttt{addr}, \texttt{pci}, and
  \texttt{io}) are bytewise-addressed. 

  In contrast, registers in a valuewise-addressed space are indexed by
  a simple integer regardless of size, meaning that two adjacent
  32-bit registers will have addresses that differ only by 1.
  A good example of a valuewise address space is the set of ia32
  model-specific registers (MSRs). 

  If neither of these is sufficient, \texttt{stepwise} allows you to
  explicitly specify how many bytes are occupied by each address in
  the address space.  \texttt{bytewise} is therefore a synonym for
  \texttt{stepwise(1)}, but \texttt{stepwise(4)} might be useful for
  devices (such as some IOAPICs) where registers are indexed by 32-bit
  values but can be accessed as 64-bit quantities. 

  Alternatively, \texttt{registerwise} gives more freedom by calling a
  custom function to access each register. For a 32-bit register \texttt{R} in the
  registerwise address space \texttt{S}, the read and write functions are
  declared as follows:
%
  \begin{syntax}
uint32_t __DN(S_read_32_R)(void);
void __DN(S_write_32_R)(uint32_t _regval);
  \end{syntax}


\item [``description''] is a string literal in double quotes, which
  describes the constant type being specified, for example
  \texttt{"PHY control registers"}. 

\end{description}

Register addresses in user-defined address spaces are always given
simply as offsets, since the base is implicit in the device
definition.  

\Mac files cannot currently say how registers in a particular space
are accessed; this functionality must be provided externally by the
programmer (typically by short inline functions).  

Here is how ia32 MSRs are defined: 

\begin{example}
space msr valuewise "Model-specific Registers";
register platform\_id ro msr(0x17) "Platform ID" \verb+{+
    \_	50;
    id	3 "platform id";
    \_	11;
\verb+}+;
\ldots
\end{example}

As a second example, here is a set of space declarations (and
associated index and data registers) from the legacy PC real-time
clock (RTC) definition: 

\begin{example}
space std(idx) valuewise "Standard register space";
register ndx rw io(base, 0x70) "Standard index" 
             type(uint8);
register target rw io(base, 0x71) "Standard target" 
             type(uint8);
regarray standard rw std(0x00)[256] type(uint8);

space ext(idx) valuewise "Extended register space"; 
register endx rw io(base, 0x72) "Extended index" 
             type(uint8);
register etarget rw io(base, 0x73) "Extended target''
             type(uint8);
regarray extended rw std(0x00)[256] type(uint8);
\end{example}

\section{Constants}\label{sec:constants}

A \texttt{constant} declaration defines a series of related values,
for example, the possible values of a given register field.  Each
constant type consists of an identifier for the type, a textual
description, and a series of possible values.   Each value in turn
consists of an identifier for the value, the numerical value itself,
and a textual description of its meaning. 

The syntax is:

\begin{syntax}
constants \synit{name} [width( \synit{width} )] "\synit{description}" \verb+{+ 
   \synit{name\(\sb{1}\)} = \synit{value\(\sb{1}\)} ["\synit{description\(\sb{1}\)}"] ;
   \ldots
\verb+}+; 
\end{syntax}


\begin{description}
\item[name] is an identifier for the constant type, and will be used to
  generate identifiers in the target language (typically C).  The
  scope of this identifier is the enclosing device specification.  

\item[width] is optional, and specifies the width of the constant
  value in bits.  This is useful, for example, when the type is used
  as the type of a register. 

\item [``description''] is a string literal in double quotes, which
  describes the constant type being specified, for example
  \texttt{"Vector delivery mode"}. 
\end{description}

Each constant value is given as follows:

\begin{description}

\item[name$_i$] is an identifier for the particular value of the
  constant type.  The scope of this identifier is the enclosing
  constant declaration, not the device declaration as a whole.

\item[value$_i$] is an expression giving the corresponding numerical
  value.  This will usually be a literal like \texttt{0b1101} or
  \texttt{0xf}, though it can potentially be any arithmetic expression
  supported by \Mac. 

\item[``description$_i$''] is an optional string literal in double
  quotes, which describes the meaning of the value being specified,
  for example \texttt{"Lowest priority"}.  If not specified, it
  defaults to the identifier name$_i$. 

\end{description}

Here is a complete example of a constants declaration, taken from the
xAPIC definition: 

\begin{example}
constants vdm "Vector delivery mode" \verb+{+
       fixed   = 0b000 "Fixed";
       lowest  = 0b001 "Lowest priority";
       smi     = 0b010 "SMI";
       nmi     = 0b100 "NMI";
       init    = 0b101 "INIT";
       startup = 0b110 "Start Up";
       extint  = 0b111 "ExtINT";
\verb+}+;
\end{example}

Note that the collection of constant values does not have to be
complete or contiguous. 

\section{Register types}\label{sec:regtypes}

A \texttt{regtype} declaration defines a data type corresponding to the
format of one or more registers; it can be thought of as a translation
of the bitfield descriptions typically found in data sheets.   A
\texttt{regtype} doesn't define any particular hardware registers
(see \texttt{register} declarations below), merely a data type for
representing their contents. 
The syntax is as follows:

\begin{syntax}
regtype \synit{name} ["\synit{description}"] \verb+{+
   \synit{fieldname}\(\sb{1}\) \synit{width} [type(\synit{fieldtype})] [\synit{attr}] ["\synit{description}"];
   \ldots
\verb+}+;
\end{syntax}

\begin{description}

\item[name] is an identifier for the register type.  Its scope is the
  enclosing device declaration. 

\item[description] is an optional string in double quotes, giving a
  description of the register type, for example \texttt{"LVT
    monitor"}.   If not present, it defaults to the identifier.  

\end{description}

The field descriptions declare the individual bitfields which make up
the register type.  The order in which these are given is determined
by the \texttt{lsbfirst} or \texttt{msbfirst} declaration in the
\texttt{device} specification: if \texttt{lsbfirst}, the first field
given starts at bit 0, etc.

\begin{description}

\item[fieldname] is an identifier for the bit field.  It can be
  given as an underscore (\texttt{\_}) to indicate ``don't care'' or
  ``reserved'' fields, in which case the field is
  assumed to have an attributed of \texttt{rsvd} (see below), and no
  description is needed. 

\item[width] is an integer giving the width of the field in bits. 

\item[fieldtype] is an optional identifier giving the type of this field.
  This must be either the identifier of a \texttt{constants} declaration
  somewhere in the enclosing \texttt{device} declaration, for example
  \texttt{type(vdm)}, or a qualified name of the form
  \textit{device}\texttt{.}\textit{constdef}, where \textit{device} is
  the name of a device definition previously imported. 

\item[attr] is an optional field
  attribute.  See section~\ref{sec:fieldattrs} for more information. 

\item[description] is an optional string in double quotes, giving a
  description of the field, for example \texttt{"Logical APIC ID"}. 
  If not present, it defaults to the identifier.  

\end{description}

% feature from old version:
% There is another variation for defining the bit-width for register layout in
% bit-fields, called {\it location based width}, besides {\it normal mode}. It
% may be more error prone and tiresome process for the user, to manually
% calculate the bit width. Mackerel can do this for users. To automate the
% process of calculating bit-width, user can specify exact register layout and
% Mackerel will put appropriate bit-width. User just has to put bit location
% it into (), to distuinguish it from normal mode.
% 
% \verb+(startbit - endbit)+
% 
% A number 8 in field declaration, in normal mode, represents 8 bits but (8)
% represents single bit. Like wise, (9-11) (which are starting and ending
% location of that particular field) represents 3 bits in register layout. By
% using this mode of specifying the register layout, user can copy bit location
% as it is from the hardware specificaion to dev file avoiding any confusions.


Here is a complete example of a \texttt{regtype} declaration, taken from the
xAPIC definition: 
\begin{example}
  regtype lvt_lint "LVT Int" \verb+{+
    vector\verb+    +8 "Vector";
    dlv_mode\verb+  +4 type(vdm) "Delivery mode";
    _\verb+         +1;
    status\verb+    +1 "Delivery status";
    pinpol\verb+    +1 "Pin polarity";
    rirr\verb+      +1 "Remote IRR";
    trig_mode\verb+ +1 "Trigger mode";
    mask\verb+      +1 "Mask";
    _\verb+         +15;
  \verb+}+;
\end{example}

\section{Registers}\label{sec:registers}

A \texttt{register} declaration defines a particular hardware register
on the device.  

\begin{syntax}
register \synit{name} [\synit{attr}] [also] 
             \{ noaddr | \synit{space}( \synit{address} ) \} ["\synit{description}"] \synit{type} ;
\end{syntax}

\begin{description}

\item[name] is an identifier for the register.  Its scope is the
  enclosing \texttt{device} declaration. 

\item[attr] is an (optional) attribute.  See
  Section~\ref{sec:fieldattrs} for more information.

\item[space] gives the address space of this register
  (e.g. \texttt{addr}, \texttt{io}, \texttt{pci}, or a per-device
  user-defined address space).

\item[address] gives the address of the register in the address
  space.  For builtin address spaces this is given as a
  comma-separated pair of \textit{(base, offset)} where \textit{base}
  is a device argument of the correct type and \textit{offset} is an
  integer-valued \Mac expression.   For user-defined address spaces,
  the address is a single \Mac integer expression giving the register
  index.  

  By default, it is an error to specify more than one
  register at the same location, or at locations which overlap.  By
  preceding the address specifier with the \texttt{also} keyword, you
  can allow registers to coexist at the same location. 

\item[noaddr] is an alternative to the address space definition, and
  is used for registers which have no address (or, alternatively, an
  implicit address).  A good example of this kind of register is a
  coprocessor register which requires custom assembler instructions to
  read and write.  Mackerel generates slightly different access code
  for this type of register, specified later in this document, and
  requires the developer to supply the raw register access functions. 

\item[description] is an optional string in double quotes, giving a
  description of the register, for example \texttt{"Error status"}. 
  If not present, it defaults to the name identifier.  

\item[type] gives the format of the register.  It can consist of
  \texttt{type(}\textit{name}\texttt{)}, where \textit{name} is
  either:
  \begin{itemize}
  \item the identifier of a register type previously declared with a
    \texttt{regtype} declaration;
  \item the identifier of a constants type previously declared with a
    \texttt{constants} declaration which included an explicit
    \texttt{width()} specifier;
  \item one of the built in register types \texttt{uint8},
    \texttt{uint16}, \texttt{uint32}, or \texttt{uint64}; or
  \item a qualified name of the form
    \textit{device}\texttt{.}\textit{type}, where \textit{device}
    is the name of a device definition previously imported.  
  \end{itemize}

  Alternatively, the type can be given as a sequence of fields in
  braces, exactly as in a \texttt{regtype} declaration.  In effect,
  this latter form defines both a register type and a register at the
  same time, with the same name. 

\end{description}

Here are some examples of \texttt{register} definitions:

\begin{example}
  register dfr rw at (base, 0x00e0) "Destination Format" \{
    _           28 mb1;
    model       4 type(model_type) "Model";
  \};
\end{example}
\begin{example}
  register apr ro at (base, 0x0090) "Arbitration priority" type(priority);
\end{example}
\begin{example}
  register isr0 ro at (base, 0x0100) "ISR bits 0-31" type(uint32);
\end{example}
\begin{example}
  register cr4 noaddr "Control register 4" \{
    _           49 mbz;
    smxe        1 "SMX enable";
    vmxe        1 "VMX enable";
    _           2 mbz;
    osxmmexcpt  1 "OS support for unmasked SIMD FP exceptions";
    osfxsr      1 "OS support for FXSAVE and FXRSTOR instructions";
    pce         1 "Performance-monitoring counter enable";
    pge         1 "Page global enable";
    mce         1 "Machine-check enable";
    pae         1 "Physical address extensions";
    pse         1 "Page size extensions";
    de          1 "Debugging extensions";
    tsd         1 "Time stamp disable";
    pvi         1 "Protected-mode virtual interrupts";
    vme         1 "Virtual 8086 mode extensions";
  \};
\end{example}



\section{Register Arrays}\label{sec:regarrays}

A \texttt{regarray} declaration defines an array of hardware registers
on the device, all of which have the same type and attributes. 

\begin{syntax}
regarray \synit{name} [\synit{attr}] [also] 
             \synit{space}( \synit{address} ) ["\synit{description}"] \synit{type} ;
\end{syntax}

All fields are as for register declarations, except: 

\begin{description}

\item[address] gives the address of the registers which form the array
  in the address space.  This is given as for a single
  \texttt{register} declaration, followed by an array specifier in
  square brackets.  

  There are three forms of array specifier. The simplest looks like
  this:
  \begin{example}
    regarray ier ro addr(base, 0x0480) [ 8 ] 
                 "IER" type(uint32);
  \end{example}
  This specifies a contiguous array of 8 32-bit registers starting at
  \texttt{base + 0x0480}.  This example therefore occupies 32 bytes of
  IO space.  Alternatively: 
  \begin{example}
    regarray ier ro addr(base, 0x0480) [ 8; 0x10 ] 
                 "IER" type(uint32);
  \end{example}
  This second example specifies 8 32-bit registers, which occur every 16 bytes,
  starting at \texttt{base + 0x0480}.  Finally, one can explicitly
  list the individual locations for the array (note: the back-end does
  not yet generate correct code for this case):
  \begin{example}
    regarray ier ro addr(base, 0x0480) [ 0, 0x10, 0x18 ] 
                 "IER" type(uint32);
  \end{example}
  This third example specifies 3 32-bit registers, at offsets of
  \texttt{0x480}, \texttt{0x490}, and \texttt{0x498} from
  \texttt{base}. 

\end{description}

\section{Data types}\label{sec:datatypes}

A \texttt{datatype} declaration defines a data type corresponding to the
format of a structure in memory; it can be used to represent in-memory
hardware-defined datastructures like page table entries or DMA
descriptors. 

The syntax is as follows:

\begin{syntax}
datatype \synit{name} [lsbfirst|msbfirst (\synit{wordsize})] ["\synit{descr}"] \verb+{+
   \synit{fieldname}\(\sb{1}\) \synit{width} [type(\synit{fieldtype})] [\synit{attr}] ["\synit{description}"];
   \ldots
\verb+}+;
\end{syntax}

\begin{description}

\item[name] is an identifier for the data type.  Its scope is the
  enclosing device declaration. 

\item[lsbfirst or msbfirst] together with a (required) word size
  specify how the fields in the specification are ordered.  This is
  described in more detail below. 

\item[description] is an optional string in double quotes, giving a
  description of the register type, for example \texttt{"LVT
    monitor"}.   If not present, it defaults to the identifier.  

\end{description}

The field descriptions declare the individual bitfields which make up
the data type.  

The order in which these are given is determined
by the \texttt{lsbfirst} or \texttt{msbfirst} declaration.  Data
structures in memory are sometimes listed in data books as a sequence
of words, each of which is formatted into bit fields.  In order for
authors of device specifications to easily translate these
descriptions into Mackerel, one can specify the ``word size'' used in
the description along with the order in which bit fields within a
word are listed.  For example, ``\texttt{msbfirst(32)}'' means that
the bit fields are to be grouped into words of 32 bits each, and
within each word the fields are listed most-significant-bit (i.e. the
field containing bit 31) first.  On an Intel architecture machine,
this will cause the resulting C declaration to be derived by taking
the first set of fields whose width adds up to 32, reversing their
order in the struct declaration, then the next group, etc. 

Specifying a word size of 0 will cause the entire set of fields to be
reordered (if necessary) in one go.  If no bit order and word size are
specified, the default is that of the device itself, with a word size
of 0. 

\begin{description}

\item[fieldname] is an identifier for the bit field.  It can be
  given as an underscore (\texttt{\_}) to indicate ``don't care'' or
  ``reserved'' fields, in which case the field is
  assumed to have an attributed of \texttt{rsvd} (see below), and no
  description is needed. 

\item[width] is an integer giving the width of the field in bits. 

\item[fieldtype] is an optional identifier giving the type of this field.
  This must be the identifier of a \texttt{constants} declaration
  somewhere in the enclosing \texttt{device} declaration, for example
  \texttt{type(vdm)}. 

\item[attr] is an optional field
  attribute.  See section~\ref{sec:fieldattrs} for more information.
  The only field attributes allowed for data types are \texttt{rsvd},
  \texttt{mbz}, \texttt{mb1}, or \texttt{rw}.  ``Don't care'' fields
  default to \texttt{rsvd}; others default to \texttt{rw}. 

\item[description] is an optional string in double quotes, giving a
  description of the field, for example \texttt{"Command header"}. 
  If not present, it defaults to the identifier.  

\end{description}

Here is a complete example of a \texttt{regtype} declaration, taken from the
a SATA AHCI port definition: 
\begin{example}
  datatype cls msbfirst(32) "Command list structure" \verb+{+
      prdtl\verb+ +16 "Physical region descriptor table length";
      pmp\verb+   +4  "Port multiplier port";
      \_\verb+     +1;
      c\verb+     +1 "Clear busy upon R\_OK";
      b\verb+     +1 "BIST";
      r\verb+     +1 "Reset";
      p\verb+     +1 "Prefetchable";
      w\verb+     +1 "Write";
      a\verb+     +1 "ATAPI";
      cfl\verb+   +5 "Command FIS length";
      prdbc\verb+ +32 "Physical region descriptor byte count";
      ctba\verb+  +32 "Command table descriptor base addr";
      ctbau\verb+ +32 "Command table descriptor base addr upper";
      \_\verb+     +32;
      \_\verb+     +32;
      \_\verb+     +32;
      \_\verb+     +32;
  \verb+}+;
\end{example}

\section{Field and register attributes}\label{sec:fieldattrs}

This section lists the various attributes that can be applied to
register fields or entire registers.  Some of these values can only be
applied to register fields, and not to entire registers.   Some of
these attributes are functionally equivalent from the point of view of
client code generated by \Mac, but the aim is to facilitate typing in
information from data sheets. 

\begin{description}

\item[rw] Read/write.  The value is readable and writable.  This is
  the default. 

\item[ro] Read-only.  The value is readable, but not writeable.  No
  code will be generated to handle writes to this value. 

\item[wo] Write-only.  The value is writable, but not readable.  No
  code will be generated to handle reads from this value, but
  generated code may keep a ``shadow'' copy of the last value written
  to aid in debugging. 

\item[rc] Read to clear.  The value is readable, but not writeable,
  and a read operation will clear the value (this is sometimes seen
  with statistical count registers, for example).  Driver code
  generated for registers will behave as if the register was
  \textbf{ro}, so care must be taken if extra reads are inserted.  In
  particular, remember that printing the value of the register in
  debugging code will clear it. 

\item[rwzc] Read/write zero to clear. The value is readable. A write of 0
  clears (sets to 0) the corresponding bit, and a write of 1 has no effect.

\item[rw1c] Read/write one to clear.  The value is readable. A write of 1
  clears (sets to 0) the corresponding bit, and a write of 0 has no
  effect. 

\item[rwc] Read/write clear.  A synonmym for \textbf{rw1c}.

\item[ros] Read-only sticky.  Value is readable and not writeable.  In
  Intel nomenclature, the bits can only be reset with a power cycle;
  in \Mac this attribute is simply a synonym for \texttt{ro}. 

\item[rw1cs] Read and write one to clear and sticky.  In Intel
  nomenclature, this is equivalent to \texttt{rwc} but bits can only
  be reset on a power cycle.  

\item[rwcs] Read, write to clear and sticky.  A synonym for \textbf{rw1cs}.

\item[rwo] Read/write once. Can be written to precisely once after
  reset, and thereafter is read-only. 

\item[rws] Read/write and sticky.  Software can read and write to this
  bit, but the bit can only be reset after a power cycle. 

\item[rsvd] Reserved.  \Mac generates code to allow clients to read
  reserved bits, but when writing a register value, code generated by \Mac
  will ensure the bit values are preserved, if necessary by performing
  a read before the write. 

\item[mbz] Must be zero.  \Mac will generate no code to read the
  value, but will ensure that it is always written as 0. 

\item[mb1] Must be one.  \Mac will  generate no code to read the
  value, but will ensure that it is always written as 1. 

\end{description}

Register attributes can be \texttt{rw}, \texttt{ro}, or \texttt{wo},
and provide a default attribute for each field of the register.  If
no attributes at all are specified, \texttt{rw} is assumed, except in
the case of an anonymous register field (denoted by an underscore
``\texttt{\_}''), which defaults to 
\texttt{rsvd} regardless of the register attribute.  The motivation for
this design choice is that unused fields of registers are frequently
``reserved'' rather than ``don't care''.  The default behaviour will
therefore result in potential inefficiency (due to reading the value
before writing it), but never incorrect behaviour (due to writing the
wrong values to a reserved field).
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{C mapping for device drivers}\label{chap:shiftdriver}

For each device specification, \Mac generates a single C header file
giving all the necessary definitions and declarations.   While
developers are not expected to look at this file in normal use, it is
designed to be fairly readable to curious humans, and is worth
examining to understand what \Mac is generating (and to find bugs in
\Mac). 

The file for a device called, say, \texttt{apic} is conventionally named
\texttt{apic\_dev.h}, and in Barrelfish is usually found in
the \texttt{dev} subdirectory of the main include directory; thus a C
file would include it with:

\begin{alltt}
#include <dev/apic\_dev.h>
\end{alltt}

This chapter will describe the contents of this header file. 

\section{Preamble}

The header file is protected by the customary macro to ensure that it
is only included once - for example, for a device called \texttt{DEV} this is
``\texttt{\_\_DEV\_H}''. 

The file includes only one other header file: \texttt{mackerel.h}.
This latter header file includes declarations for the low-level read
and write functions that \Mac code requires, and some other
preprocessor macros to ensure correct C code generation.   


%% \Mac prefixes all declarations in the file with the
%% name of the file plus an underscore (``\texttt{DEV\_}'').  However, for
%% most (though not all) declarations this prefix can be overridden by
%% defining the macro ``\texttt{DEV\_PREFIX}'' before including the file. 

%% This is at first sight a little confusing.  Suppose we have a device
%% called \texttt{pc16550d\_uart}.   By default, any declaration
%% \texttt{foo} in \Mac file will correspond to
%% \texttt{pc16550d\_uart\_foo} in the header file. 

%% If, however, we include a line:

%% \begin{quote}
%%  \texttt{\#define pc16550d\_uart\_PREFIX uart}
%% \end{quote}

%% -- before including the header file, that declaration is likely to now
%% be \texttt{uart\_foo}. 

In the rest of this chapter, we'll use ``\texttt{DN\_}'' as the
device prefix that cannot be redefined in this manner, and ``\texttt{DP\_}''
as device prefix that can. 

\section{Device-level declarations}

For the device, \Mac generates: 

\begin{enumerate}

\item a C structure type to represent what it knows about the
  device, called \texttt{DN\_t}.  To access a device from C via \Mac,
  you first need to declare one of these, and then call a function
  (see below) to initialize it. 
  
  The struct contains fields which correspond to each of the arguments
  which define the addresses of the device, plus a ``shadow'' copy of
  every register on the device which has at least one write-only field -
  this is used to keep track of the last value written to the register. 

\item The initialization function \texttt{DN\_initialize}.  For a
  device type with an argment of ``\texttt{io base}'', the
  initialization function looks like:

  \begin{quote}
    \texttt{void DN\_initialize( DN\_t *\_dev, mackerel\_io\_t base );}
  \end{quote}
  
  The idiom for accessing a device at IO address \texttt{ia} would be:
  
  \begin{quote}
    \texttt{DN\_t dev;}\\
    \texttt{DN\_initialize( \&dev, ia );}\\
    \ldots\\
    \textit{code to access registers via \texttt{dev}}
  \end{quote}

\item An enumeration declaration \texttt{enum
  DN\_initials}, with a field \texttt{DN\_REG\_initial} for each
  register \texttt{REG} defined in the device.  Currently, all these
  enumeration fields are set to \texttt{0x00}, and are used inside the
  generated initialization function to initialize any shadow copies of
  registers in the device struct.  
  
\item An \texttt{snprintf}-like function to
  pretty-print \emph{all} the register contents of the device, with prototype:
  \begin{quote}
    \texttt{int DN\_pr(char *s, size\_t sz, DN\_t *v);}
  \end{quote}
  For a complex device, this is a lot of information, and may require a
  large buffer to fully capture.  This is also potentially a large
  function to inline.  It will result in reads from all readable device
  registers, including ``read to clear'' (\textbf{rc}) registers and
  fields.  For write-only registers, this function will print the shadow
  copy of the register maintained in the device structure, which holds
  the last value written to the register (or 0 if the register has not
  been written since the initialization function was called).  The
  output identifies which values are ``real'' and which are shadow
  copies, includes descriptions of all register fields, and translates
  symbolic values into their names and descriptions. 
\end{enumerate}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Constants}

For a constants declaration of type \texttt{CNSTS}, having fields
\texttt{FIELD1} and \texttt{FIELD2}, \Mac will generate the following:

\begin{enumerate}

\item A type definition which defines type \texttt{DP\_CNSTS\_t} to be
  an unsigned integer type (e.g.\ \texttt{uint8\_t} or
  \texttt{uint64\_t}).  The type is the smallest such type large
  enough to hold the largest value in the constants declaration, or
  (if the width is explicitly given) the smallest such type wider than
  the given width. 

\item A set of CPP macro definitions \texttt{DP\_FIELD1} and
  \texttt{DP\_FIELD2}, each of which expands to a C expression
  consisting of the field value cast to type \texttt{DP\_CNSTS\_t}.  

  If the field value is specified as \texttt{1s}, the macro will
  expand to the C value \texttt{-1LL} cast to type
  \texttt{DP\_CNSTS\_t}.  

  Note that the field names are not prefixed by the constants name,
  only the device prefix. 

  The motivation for using CPP macros (rather than C enumerations, as
  in an earlier version of Mackerel) is that \texttt{enum} types are
  only the size of C \texttt{int}s, whereas Mackerel can specify
  values in \texttt{constants} declarations which are larger than
  this (such as 64-bit values). 

  The motivation for not using constant unsigned integer declarations
  is that macros allow us to only generate a header file, without
  cluttering up the data segment with multiple copies of constants if
  the generated header file is included more than once. 
      
\item A function which takes an argument of type \texttt{DP\_CNSTS\_t}
  and returns a pointer to a string containing the description of the
  field value, or NULL if the argument does not correspond to a field
  value:
  \begin{quote}
    \texttt{char *DP\_CNSTS\_describe(DP\_CNSTS\_t e);}
  \end{quote}
  Note that this function can also simply be used as a test of whether
  the value is valid. 

\item An \texttt{snprintf}-like function to pretty-print values of
  type \texttt{DP\_CNSTS\_t}, with prototype:
  \begin{quote}
    \texttt{int DP\_CNSTS\_prtval(char *s, size\_t sz, DP\_CNSTS\_t e);}
  \end{quote}

\end{enumerate}

\section{Register types}\label{sec:c-regtype}. 

For a \texttt{regtype} declaration \texttt{REGTYPE}, \Mac will
generate the following: 

\begin{enumerate}

\item A type definition \texttt{DP\_REGTYPE\_t}, which is an unsigned
  integer of the same size as the register. 

\item A CPP macro \texttt{DP\_REGTYPE\_default}, which is an integer
  literal giving the ``default'' value for the register type.  Note
  that since this is a macro, the prefix of the name cannot be
  overridden using the trick mentioned above. 

\item An \texttt{snprintf}-like function to pretty-print values of the
  register type, with prototype:
  \begin{quote}
    \texttt{int DP\_REGTYPE\_prtval(char *s, size\_t sz, DP\_REGTYPE\_t v);}
  \end{quote}

\item For every field \texttt{FLD} (of type \texttt{FLDTYPE\_t}) of the
  register type, a function to insert a value into that field of a value
  of type \texttt{DP\_REGTYPE\_t}: 
  \begin{quote}
    \texttt{DP\_REGTYPE\_t DP\_REGTYPE\_FLD\_insert(DP\_REGTYPE\_t r, FLDTYPE\_t val );}
  \end{quote}
  Note that this insertion is \textit{not} in place, in contrast to
  the function generated for \texttt{datatype} declarations (see
  below).  Instead, this it returns a new value of the register type
  with the specified field modified, and so is intended to be used in
  a ``functional'' style. 

\item For every field \texttt{FLD} (of type \texttt{FLDTYPE\_t}) of the
  register type, a function to extract a single field from a value
  of type \texttt{DP\_REGTYPE\_t}: 
  \begin{quote}
    \texttt{FLDTYPE\_t DP\_REGTYPE\_FLD\_extract(DP\_REGTYPE\_t r);}
  \end{quote}

\end{enumerate}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Data types}\label{sec:c-datatype}. 

For a \texttt{datatype} declaration
\texttt{DATATYPE}, \Mac will generate the following:

\begin{enumerate}

\item A type definition \texttt{DP\_DATATYPE\_t}, which is of type
  \texttt{uint8\_t *}.  This is the canonical way to refer to values
  of the datatype in memory. 

\item A \texttt{static const size\_t DP\_DATATYPE\_size}, which is the
  size in bytes of the data type.  This should be used in place of
  \texttt{sizeof(DP\_DATATYPE\_t)}, which will the wrong result in
  general. 

\item A type definition \texttt{DP\_DATATYPE\_array\_t}, which is of type
  \texttt{uint8\_t[sz]}, where \texttt{sz} is the size in bytes of the
  datatype.  This should be used sparingly, for example to allocate a
  value of the datatype on the stack. 

\item An \texttt{snprintf}-like function to pretty-print values of the
  datatype, with prototype:
  \begin{quote}
    \texttt{int DP\_DATATYPE\_prtval(char *s, size\_t sz, DP\_DATATYPE\_t v);}
  \end{quote}

\item For every field \texttt{FLD} (of type \texttt{FLDTYPE\_t}) of the
  datatype, a function to insert a value into that field of a value
  of type \texttt{DP\_DATATYPE\_t}: 
  \begin{quote}
    \texttt{void DP\_DATATYPE\_FLD\_insert(DP\_DATATYPE\_t r, FLDTYPE\_t val );}
  \end{quote}
  Note that this insertion is \textit{in place}, in contrast to the
  ``functional'' style used for register types. 

\item For every field \texttt{FLD} (of type \texttt{FLDTYPE\_t}) of the
  datatype, a function to extract a single field from a value
  of type \texttt{DP\_DATATYPE\_t}: 
  \begin{quote}
    \texttt{FLDTYPE\_t DP\_DATATYPE\_FLD\_extract(DP\_DATATYPE\_t r);}
  \end{quote}

\end{enumerate}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Registers}

For a register \texttt{REG} that defines its own type, \Mac defines
a register type with the same name and generates the declarations
defined in section~\ref{sec:c-regtype}. 

For each register \texttt{REG} with type \texttt{REGTYPE}, \Mac will
generate some of the following:

\begin{enumerate}

\item If the register has fields which are readable, a function to
  read the contents of the register:
  \begin{quote}
    \texttt{DP\_REGTYPE\_t DP\_REG\_rd( DN\_t *dev );}
  \end{quote}

\item If the register address is not given as \texttt{noaddr}, a function to
  read the raw contents of the register:
  \begin{quote}
    \texttt{DP\_REGTYPE\_t DP\_REG\_rawrd( DN\_t *dev );}
  \end{quote}
  On the other hand, if the register address is given as
  \texttt{noaddr}, the developer is required to supply this function
  herself -- Mackerel-generated code will use it to access the
  register. 

\item If the register has fields which are writeable, a function to
  write the contents of the register:
  \begin{quote}
    \texttt{void DP\_REG\_wr( DN\_t *dev, DP\_REGTYPE\_t val );}
  \end{quote}
  Note that this is \emph{not} a simple write of the value: any fields
  which must be 1 or 0 are set accordingly, and reserved fields are
  read from the register before writing back the value.  Therefore,
  this function will only write the bit fields of \texttt{val} which
  are meaningful to write according to the register specification.
  However, this function will not perform a read from the register
  unless the register contains reserved fields. 

\item If the register address is not given as \texttt{noaddr}, a function to
  write raw values to the register:
  \begin{quote}
    \texttt{DP\_REGTYPE\_t DP\_REG\_rawwr( DN\_t *dev, DP\_REGTYPE\_t val );}
  \end{quote}
  This function is potentially dangerous, since it makes no guarantees
  that certain fields of the register are set to zero or one, or
  preserves the contents of reserved fields.  Use with caution. 

  On the other hand, if the register address is given as
  \texttt{noaddr}, the developer is required to supply this function
  herself -- Mackerel-generated code will use it to access the
  register.  Again, in this case, the function should not try to
  preserve fields, since Mackerel will make sure that the
  ``sanitized'' register and field writing functions will do this
  correctly. 

\item For every readable field \texttt{FLD} (of type \texttt{FLDTYPE})
  of the register, a function to read just that single field from the
  register: 
  \begin{quote}
    \texttt{FLDTYPE DP\_REG\_FLD\_rdf( DN\_t *dev );}
  \end{quote}

\item For every writeable field \texttt{FLD} of the register, a function to
  write just that single field to the register:
  \begin{quote}
    \texttt{void DP\_REG\_FLD\_wrf( DN\_t *dev, \texttt{FLDTYPE} val );}
  \end{quote}
  
  These functions should be used with care.  It is of
  course impossible to write only one field, hence a complete write to
  the register will occur.  Furthermore, the values of the other
  read/writeable or reserved register fields will be determined first
  by doing a hidden read from the register.   Any write-only 
  fields will then be initialized from the shadow copy.  Any ``must be
  zero'' or ``must be 1'' fields will be set to their respective values.  

\item For every write-only field \texttt{FLD} (of type \texttt{FLDTYPE})
  of the register, a function to read just that single field from the
  shadow copy of the register contents: 
  \begin{quote}
    \texttt{FLDTYPE DP\_REG\_FLD\_rd\_shadow( DN\_t *dev );}
  \end{quote}
  
\item An \texttt{snprintf}-like function to pretty-print the
  current value of the register, or its shadow copy if the register is
  not readable, with prototype:
  \begin{quote}
    \texttt{int DP\_REG\_pr( char *s, size\_t sz, DN\_t *dev );}
  \end{quote}

\end{enumerate}

\section{Register Arrays}\label{sec:c-regarray}

For a register array \texttt{RARR} that defines its own type, \Mac defines
a register type with the same name and generates the declarations
defined in section~\ref{sec:c-regtype}. 

For each register array \texttt{RARR} with type \texttt{REGTYPE}, \Mac will
generate some of the following:

\begin{enumerate}

\item A CPP macro \texttt{DP\_DATATYPE\_size}, which is an integer
  literal cast to a \texttt{size\_t} giving the length in bytes of the
  data type. 

\item If the register array has fields which are readable, a function to
  read the contents of a register:
  \begin{quote}
    \texttt{DP\_REGTYPE\_t DP\_REG\_rd( DN\_t *dev, int i );}
  \end{quote}

\item If the register array has fields which are writeable, a function to
  write the contents of a register:
  \begin{quote}
    \texttt{void DP\_REG\_wr( DN\_t *dev, int i, DP\_REGTYPE\_t val );}
  \end{quote}
  Note that this is \emph{not} a simple write of the value: any fields
  which must be 1 or 0 are set accordingly, and reserved fields are
  read from the register before writing back the value.  Therefore,
  this function will only write the bit fields of \texttt{val} which
  are meaningful to write according to the register specification.
  However, this function will not perform a read from the register
  unless the register contains reserved fields. 

\item For every readable field \texttt{FLD} (of type \texttt{FLDTYPE})
  of the register array, a function to read just that single field
  from a register: 
  \begin{quote}
    \texttt{FLDTYPE DP\_REG\_FLD\_rdf( DN\_t *dev, int i );}
  \end{quote}

\item For every writeable field \texttt{FLD} of the register array, a
  function to write just that single field to a register:
  \begin{quote}
    \texttt{void DP\_REG\_FLD\_wrf( DN\_t *dev, int i, \texttt{FLDTYPE} val );}
  \end{quote}
  
  These functions should be used with care.  It is of
  course impossible to write only one field, hence a complete write to
  the register will occur.  Furthermore, the values of the other
  read/writeable or reserved register fields will be determined first
  by doing a hidden read from the register.   Any write-only 
  fields will then be initialized from the shadow copy.  Any ``must be
  zero'' or ``must be 1'' fields will be set to their respective values.  

\item For every write-only field \texttt{FLD} (of type \texttt{FLDTYPE})
  of the register array, a function to read just that single field from the
  shadow copy of a register's contents: 
  \begin{quote}
    \texttt{FLDTYPE DP\_REG\_FLD\_rd\_shadow( DN\_t *dev );}
  \end{quote}
  
\item An \texttt{snprintf}-like function to pretty-print the
  current value of one register in the array, or its shadow copy
  if the field is write-only, with prototype:
  \begin{quote}
    \texttt{int DP\_REG\_pri( char *s, size\_t sz, DN\_t *dev, int i );}
  \end{quote}
  
\item An \texttt{snprintf}-like function to pretty-print the
  current value of all registers in the array, or their shadow copies
  if the field is write-only, with prototype:
  \begin{quote}
    \texttt{int DP\_REG\_pr( char *s, size\_t sz, DN\_t *dev );}
  \end{quote}

\end{enumerate}

\section{Address spaces}\label{sec:c-spaces}

It is the responsibility of the programmer to supply functions to
access registers in user-defined address spaces (though it's common to
call \Mac{}-generated code in turn to do this).   The register access
code generated by \Mac for a 32-bit wide register declared in an
address space \texttt{SPACE} will call the following function for a
read:
  \begin{quote}
    \texttt{uint32\_t DP\_SPACE\_read\_32( DN\_t *dev, size\_t offset );}
  \end{quote}
-- and the following function for a write:
  \begin{quote}
    \texttt{void DP\_SPACE\_write\_32( DN\_t *dev, size\_t offset,
      uint32\_t value );}
  \end{quote}

These functions must be supplied by the programmer in a file named
\texttt{DP\_spaces.h}, which is included by the generated header file
\emph{if and only if} the device specification defines new address
spaces.  Note that only one header file is required, rather than one
for each user-defined address space.

Since the device is passed as an argument, the functions can access
any device fields (including device arguments and shadow copies of
write-only registers) 

They are not
declared anywhere in the generated header file, which means that not
all the read/write functions for an 
address space need to be supplied, only the ones actually used.
Furthermore, these can be declared to be \texttt{static inline}, or
\texttt{extern}, etc.\ according to taste.

\section{Overall header file structure}

The generated header file is not too difficult to read, and doing so
can be useful for debugging purposes.  The declarations emitted by
\Mac occur in the file in the following order (to minimise the need
for forward declarations):

\begin{enumerate}
\item Preamble, naturally.
\item Type, print, and check declarations for each ``constants''
  clause.
\item Type, union, and print declarations for each register type
  (including implicit types). 
\item The device structure, and its initialization function.
\item Read, write, and print functions for each register
\item The device print function. 
\end{enumerate}

In addition, comments in the generated file are intended to help you
find the relevant declarations quickly if you need to. 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Bitfield C mapping for device drivers}\label{chap:bitfielddriver} 

\section*{Important}
This appendix contains the deprecated C mapping which uses bitfield
structures to represent registers.  This back end should not be used,
since it is not portable across architectures and does not guarantee
that register accesses will be of the same size as the register, which
breaks some architectures (such as Rock Creek).   It is included here
to help understand legacy code.  Such code should be converted as soon
as possible. 

For each device specification, \Mac generates a single C header file
giving all the necessary definitions and declarations.   While
developers are not expected to look at this file in normal use, it is
designed to be fairly readable to curious humans, and is worth
examining to understand what \Mac is generating (and to find bugs in
\Mac). 

This chapter will describe the contents of this header file. 

\section{Preamble}

The header file is protected by the customary macro to ensure that it
is only included once - for example, for a device called \texttt{DEV} this is
``\texttt{\_\_DEV\_H}''. 

The file includes only one other header file: \texttt{mackerel.h}.
This latter header file includes declarations for the low-level read
and write functions that \Mac code requires, and some other
preprocessor macros to ensure correct C code generation.   

\Mac prefixes all declarations in the file with the
name of the file plus an underscore (``\texttt{DEV\_}''). 


%%  However, for
%% most (though not all) declarations this prefix can be overridden by
%% defining the macro ``\texttt{DEV\_PREFIX}'' before including the file. 

%% This is at first sight a little confusing.  Suppose we have a device
%% called \texttt{pc16550d\_uart}.   By default, any declaration
%% \texttt{foo} in \Mac file will correspond to
%% \texttt{pc16550d\_uart\_foo} in the header file. 

%% If, however, we include a line:

%% \begin{quote}
%%  \texttt{\#define pc16550d\_uart\_PREFIX uart}
%% \end{quote}

%% -- before including the header file, that declaration is likely to now
%% be \texttt{uart\_foo}. 

In the rest of this chapter, we'll use ``\texttt{DN\_}'' as the
device prefix that cannot be redefined in this manner, and ``\texttt{DP\_}''
as device prefix that can. 

\section{Device-level declarations}

\Mac provides a C structure type to represent what it knows about the
device, called \texttt{DN\_t}.  To access a device from C via \Mac,
you first need to declare one of these, and the call a function to
initialize it. 

The initialize function is called \texttt{DN\_initialize}.  For a
device type with an argment of ``\texttt{io base}'', the
initialization function looks like:

\begin{quote}
\texttt{void DN\_initialize( DN\_t *\_dev, mackerel\_io\_t base );}
\end{quote}

The idiom for accessing a device at IO address \texttt{ia} would be:

\begin{quote}
  \texttt{DN\_t dev;}\\
  \texttt{DN\_initialize( \&dev, ia );}\\
  \ldots\\
  \textit{code to access registers via \texttt{dev}}
\end{quote}

In addition, \Mac generates an \texttt{snprintf}-like function to
pretty-print \emph{all} the register contents of the device, with prototype:
\begin{quote}
  \texttt{int DN\_pr(char *s, size\_t sz, DP\_CNSTS\_t v);}
\end{quote}
For a complex device, this is a lot of information, and may require a
large buffer to fully capture.  This is also potentially a large
function to inline.  It will result in reads from all readable device
registers, including ``read to clear'' (\textbf{rc}) registers and
fields.  For write-only registers, this function will print the shadow
copy of the register maintained in the device structure, which holds
the last value written to the register (or 0 if the register has not
been written since the initialization function was called).  The
output identifies which values are ``real'' and which are shadow
copies, includes descriptions of all register fields, and translates
symbolic values into their names and descriptions. 

\section{Constants}

For a constants declaration of type \texttt{CNSTS}, having fields
\texttt{FIELD1} and \texttt{FIELD2}, \Mac will generate the following:

\begin{enumerate}

\item An enumeration type \texttt{DP\_CNSTS\_t} with fields
  \texttt{DP\_FIELD1} and \texttt{DP\_FIELD2}.  Note that the field
  names are not prefixed by the enumeration name, only the device
  prefix. 

\item An \texttt{snprintf}-like function to pretty-print values of the
  enumeration, with prototype:
  \begin{quote}
    \texttt{int DP\_CNSTS\_prt(char *s, size\_t sz, DP\_CNSTS\_t e);}
  \end{quote}
      
\item A function which returns 1 if an enumeration value is valid, 0
  if otherwise:
  \begin{quote}
    \texttt{int DP\_CNSTS\_chk(DP\_CNSTS\_t e);}
  \end{quote}

\end{enumerate}

\section{Register types}\label{sec:old:c-regtype}. 

For a \texttt{regtype} declaration \texttt{REGTYPE}, \Mac will generate the following:

\begin{enumerate}

\item A bitfield structure type \texttt{DP\_REGTYPE\_t}, whose field
  names are those of the fields specified in the \Mac file, with no
  prefix, and whose physical layout corresponds to the hardware
  register type.

\item A union type \texttt{DP\_REGTYPE\_un}, whose members are the
  bitfield struct above (as ``\texttt{val}'') and the smallest
  enclosing unsigned integer type (as ``\texttt{raw}''),. 

\item An \texttt{snprintf}-like function to pretty-print values of the
  register type, with prototype:
  \begin{quote}
    \texttt{int DP\_REGTYPE\_prtval(char *s, size\_t sz, DP\_CNSTS\_t v);}
  \end{quote}

\end{enumerate}

This functionality is being replaced by one based on shifts and masks,
rather than using bitfields, which have portability issues. 
For a \texttt{regtype} declaration \texttt{REGTYPE}, \Mac will soon
generate the following: 

\begin{enumerate}

\item A type definition \texttt{DP\_REGTYPE\_t} which is an unsigned
  integer of the same size as the register. 

\item For every field \texttt{FLD} (of type \texttt{FLDTYPE}) of the
  register type, a function to insert a value into that field of a value
  of type \texttt{DP\_REGTYPE\_t}: 
  \begin{quote}
    \texttt{DP\_REGTYPE\_t DP\_REGTYPE\_FLD\_ins(DP\_REGTYPE\_t r, FLD\_TYPE val );}
  \end{quote}

\item For every field \texttt{FLD} (of type \texttt{FLDTYPE}) of the
  register type, a function to extract a single field from a value
  of type \texttt{DP\_REGTYPE\_t}: 
  \begin{quote}
    \texttt{FLDTYPE DP\_REGTYPE\_FLD\_ext(DP\_REGTYPE\_t r);}
  \end{quote}

\end{enumerate}

\section{Data types}\label{sec:old:c-datatype}. 

For a \texttt{datatype} declaration
\texttt{DATATYPE}, \Mac will generate the following:

\begin{enumerate}

\item A bitfield structure type \texttt{DP\_DATATYPE\_t}, whose field
  names are those of the fields specified in the \Mac file, with no
  prefix, and whose physical layout corresponds to the hardware data type.

\item An \texttt{snprintf}-like function to pretty-print values of the
  data type, with prototype:
  \begin{quote}
    \texttt{int DP\_DATATYPE\_prtval(char *s, size\_t sz, DP\_CNSTS\_t v);}
  \end{quote}

\end{enumerate}

\section{Registers}

For a register \texttt{REG} that defines its own type, \Mac defines
a register type with the same name and generates the declarations
defined in section~\ref{sec:old:c-regtype}. 

For each register \texttt{REG} with type \texttt{REGTYPE}, \Mac will
generate some of the following:

\begin{enumerate}

\item If the register has fields which are readable, a function to
  read a ``raw'' (integer) value from the register:
  \begin{quote}
    \texttt{uint$x$\_t DP\_REG\_rd\_raw( DN\_t *dev );}
  \end{quote}
  -- where \texttt{uint$x$\_t} is a standard C unsigned integer type
  with a fixed size, such as \texttt{uint32\_t}., 

\item If the register has fields which are readable, a function to
  read a bitfield value from the register:
  \begin{quote}
    \texttt{DP\_REGTYPE\_t  DP\_REG\_rd( DN\_t *dev );}
  \end{quote}

\item If the register has fields which are not readable, a function to
  read a bitfield value from a saved copy of the last value written to
  the register using this device struct:
  \begin{quote}
    \texttt{DP\_REGTYPE\_t  DP\_REG\_rd\_shadow( DN\_t *dev );}
  \end{quote}

\item If the register has fields which are writeable, a function to
  write a ``raw'' (integer) value to the register:
  \begin{quote}
    \texttt{void DP\_REG\_wr\_raw( DN\_t *dev, uint$x$\_t val );}
  \end{quote}
  -- where \texttt{uint$x$\_t} is smallest suitable standard C
  unsigned integer type with a fixed size, such as
  \texttt{uint32\_t}.

\item If the register has fields which are writeable, a function to
  write a bitfield value to the register:
  \begin{quote}
    \texttt{void DP\_REG\_wr( DN\_t *dev, DP\_REGTYPE val );}
  \end{quote}
  
  Unlike the raw write function, this will (only if necessary) perform
  a read first from the register to ensure that ``reserved'' fields
  will be written back with their correct values.  It will also force
  any ``must be zero'' or ``must be 1'' fields to be their respective 
  values.  

\item For every writeable field \texttt{FLD} of the register, a function to
  write just that single field to the register:
  \begin{quote}
    \texttt{void DP\_REG\_FLD\_wrf( DN\_t *dev, \texttt{uint$x$\_t} val );}
  \end{quote}
  -- where \texttt{uint$x$\_t} is smallest suitable standard C
  unsigned integer type with a fixed size, such as
  \texttt{uint8\_t}. 
  
  These functions should be used with care.  It is of
  course impossible to write only one field, hence a complete write to
  the register will occur.  Furthermore, the values of the other
  read/writeable or reserved register fields will be determined first
  by doing a hidden read from the register.   Any write-only 
  fields will then be initialized from the shadow copy.  Any ``must be
  zero'' or ``must be 1'' fields will be set to their respective values.  
  
\item An \texttt{snprintf}-like function to pretty-print the
  current value of the register, or its shadow copy if the register is
  not readable, with prototype:
  \begin{quote}
    \texttt{int DP\_REG\_pr( char *s, size\_t sz, DN\_t *dev );}
  \end{quote}

\end{enumerate}

\section{Register Arrays}\label{sec:old:c-regarray}

For a register array \texttt{RARR} that defines its own type, \Mac defines
a register type with the same name and generates the declarations
defined in section~\ref{sec:old:c-regtype}. 

For each register array \texttt{RARR} with type \texttt{REGTYPE}, \Mac will
generate some of the following:

\begin{enumerate}

\item A static constant giving the length of the array (42 in this example):
  \begin{quote}
    \texttt{static const int DP\_RARR\_length = 0x26;}
  \end{quote}

\item If the registers have fields which are readable, a function to
  read a ``raw'' (integer) value from a register:
  \begin{quote}
    \texttt{uint$x$\_t DP\_RARR\_rd\_raw( DN\_t *dev, int i );}
  \end{quote}
  -- where \texttt{uint$x$\_t} is a standard C unsigned integer type
  with a fixed size, such as \texttt{uint32\_t}, and \texttt{i} is an
  index into the array.

\item If the registers have fields which are readable, a function to
  read a bitfield value from a register:
  \begin{quote}
    \texttt{DP\_REGTYPE\_t  DP\_RARR\_rd( DN\_t *dev, int i );}
  \end{quote}

\item If the registers have fields which are not readable, a function to
  read a bitfield value from a saved copy of the last value written to
  each register using this device struct:
  \begin{quote}
    \texttt{DP\_REGTYPE\_t  DP\_RARR\_rd\_shadow( DN\_t *dev, int i );}
  \end{quote}

\item If the registers have fields which are writeable, a function to
  write a ``raw'' (integer) value to a register:
  \begin{quote}
    \texttt{void DP\_RARRG\_wr\_raw( DN\_t *dev, int i,  uint$x$\_t val );}
  \end{quote}
  -- where \texttt{uint$x$\_t} is smallest suitable standard C
  unsigned integer type with a fixed size, such as
  \texttt{uint32\_t}.

\item If the registers have fields which are writeable, a function to
  write a bitfield value to a register:
  \begin{quote}
    \texttt{void DP\_RARR\_wr( DN\_t *dev, int i,  DP\_REGTYPE val );}
  \end{quote}
  -- where \texttt{uint$x$\_t} is smallest suitable standard C
  unsigned integer type with a fixed size, such as
  \texttt{uint32\_t}. 
  
  Unlike the raw write function, this will (only if necessary) perform
  a read first from the register to ensure that ``reserved'' fields
  will be written back with their correct values.  It will also force
  any ``must be zero'' or ``must be 1'' fields to be their respective 
  values.  
  
\item An \texttt{snprintf}-like function to pretty-print the
  current value of one element of the array, or its shadow copy if the
  register is not readable, with prototype:
  \begin{quote}
    \texttt{int DP\_RARR\_pri( char *s, size\_t sz, DN\_t *dev, int i );}
  \end{quote}
  
\item An \texttt{snprintf}-like function to pretty-print the
  entire register array, or its shadow copies if the registers in the
  array are not readable, with prototype:
  \begin{quote}
    \texttt{int DP\_RARR\_pr( char *s, size\_t sz, DN\_t *dev );}
  \end{quote}

\end{enumerate}

\section{Address spaces}\label{sec:old:c-spaces}

It is the responsibility of the programmer to supply functions to
access registers in user-defined address spaces (though it's common to
call \Mac{}-generated code in turn to do this).   The register access
code generated by \Mac for a 32-bit wide register declared in an
address space \texttt{SPACE} will call the following function for a
read:
  \begin{quote}
    \texttt{uint32\_t DP\_SPACE\_read\_32( DN\_t *dev, size\_t offset );}
  \end{quote}
-- and the following function for a write:
  \begin{quote}
    \texttt{void DP\_SPACE\_write\_32( DN\_t *dev, size\_t offset,
      uint32\_t value );}
  \end{quote}

These functions must be supplied by the programmer in a file named
\texttt{DP\_spaces.h}, which is included by the generated header file
\emph{if and only if} the device specification defines new address
spaces.  Note that only one header file is required, rather than one
for each user-defined address space.

Since the device is passed as an argument, the functions can access
any device fields (including device arguments and shadow copies of
write-only registers) 

They are not
declared anywhere in the generated header file, which means that not
all the read/write functions for an 
address space need to be supplied, only the ones actually used.
Furthermore, these can be declared to be \texttt{static inline}, or
\texttt{extern}, etc.\ according to taste.

\section{Overall header file structure}

The generated header file is not too difficult to read, and doing so
can be useful for debugging purposes.  The declarations emitted by
\Mac occur in the file in the following order (to minimise the need
for forward declarations):

\begin{enumerate}
\item Preamble, naturally.
\item Type, print, and check declarations for each ``constants''
  clause.
\item Type, union, and print declarations for each register type
  (including implicit types). 
\item The device structure, and its initialization function.
\item Read, write, and print functions for each register
\item The device print function. 
\end{enumerate}

In addition, comments in the generated file are intended to help you
find the relevant declarations quickly if you need to. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Migrating from the bit-field based version of Mackerel}
\label{chap:migrating}

Previous versions of Mackerel generated a C API by defining packed C
bitfield structs for register types.  This version of Mackerel avoids
this in favor of masks and shifts, hidden behind inline functions.
This chapter gives some hints for migrating code written using the old
Mackerel to the new version. 

\begin{itemize}

\item The initialize function for a device structure remains the same. 

\item \texttt{DEV\_REG\_wr\_raw()} and \texttt{DEV\_REG\_rd\_raw()}
  functions should be replaced with \texttt{DEV\_REG\_wr()} and
  \texttt{DEV\_REG\_rd()} with the same arguments.  

\item The following code to set individual register fields:

\begin{verbatim}
    //deassert PHY_RESET
    {
        e1000_ctrl_t c = e1000_ctrl_rd(d);
        c.phy_rst = 0;
        e1000_ctrl_wr(d, c);
        e1000_status_t s = e1000_status_rd(d);
        s.phyra = 0;
        e1000_status_wr(d, s);
    }
\end{verbatim}

 -- must be replaced with:

\begin{verbatim}
    //deassert PHY_RESET
    e1000_ctrl_phy_rst_wrf(d, 0);
    e1000_status_phyra_wrf(d, 0);
\end{verbatim}

\item The following code to read individual register fields:

\begin{verbatim}
    speed = e1000_status_rd(d).speed;
\end{verbatim}

 -- must be replaced by: 

\begin{verbatim}
    speed = e1000_status_speed_rdf(d);
\end{verbatim}

\item The following code to access a field from a register:

\begin{verbatim}
    // test LAN ID to see if we need to modify the MAC from EEPROM
    {
        e1000_status_t s = e1000_status_rd(d);
        if (s.lan_id == e1000_lan_b) {
            mac_word2 ^= e1000_lan_b_mask;
        }
    }
\end{verbatim}

  -- must be replaced by:

\begin{verbatim}
    // test LAN ID to see if we need to modify the MAC from EEPROM
    {
        e1000_status_t s = e1000_status_rd(d);
        if (e1000_status_lan_id_extract(s) == e1000_lan_b) {
            mac_word2 ^= e1000_lan_b_mask;
        }
    }
\end{verbatim}

\item The following idiom for setting fields using struct literals:

\begin{verbatim}
    e1000_rxdctl_wr(d, 0, (e1000_rxdctl_t){ .gran=1, .wthresh=1 } );
\end{verbatim}

 -- should be replaced by:

\begin{verbatim}
    e1000_rxdctl_t tmp = e1000_rxdctl_default;
    tmp = e1000_rxdctl_gran_insert(tmp,1);
    tmp = e1000_rxdctl_wthresh_insert(tmp,1);
    e1000_rxdctl_wr(d, 0, tmp);
\end{verbatim}
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Source code structure}\label{chap:sourcetree}

The \Mac source directory contains the files listed below.

\begin{description}

\item[Attr.hs] Dealing with register field attributes.
\item[BitFieldDriver.hs] Old code generator for device drivers using
  bitfields, deprecated.
\item[CAbsSyntax.hs] Contains combinators for rendering C code.
\item[CSyntax.hs] Old-style C combinators, deprecated.
\item[Checks.hs] Compile-time checks.
\item[Dev.hs] Overall device representation.
\item[Fields.hs] Representing register fields.
\item[MackerelParser.hs] ParSec parser for language.
\item[Main.hs] Top level file, which is used to run \Mac.
\item[Poly.hs] Polynomial arithmetic for compile-time expression
  reduction (currently unused)
\item[RegisterTable.hs] Representing registers and register arrays.
\item[ShiftDriver.hs] Code generator for device drivers using shifts and masks.
\item[Space.hs] Representing address spaces.
\item[TypeName.hs] Data type for scoping type names when importing.
\item[TypeTable.hs] Representing register, data, and constants types.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Quick reference}\label{chap:quickref}

In the following quick reference, the following identifiers are used
as examples, assuming a Mackerel file named \texttt{dev1.dev}: 

\begin{description}
\item[dev1] A device definition.\\
\item[const1] A constants definition.
\item[cval1] One value of the constants definition.\\
\item[rtype2] A register type definition.
\item[field2] A field in the above register type.
\item[ftype2] The type of this field.\\
\item[dtype3] A data type definition.
\item[field3] A field in the above data type.
\item[ftype3] The type of this field.\\
\item[reg4] A register definition with its own type.
\item[rtype4] Type of the above register.
\item[field4] A field in the above register.
\item[ftype4] The type of this field.\\
\item[array5] A register array.
\item[field5] A field in the elements of the above array.
\item[ftype5] The type of this field.
\end{description}

\clearpage
\section*{Quick list of Mackerel C declarations:}
{\footnotesize
\begin{tabular}{|l|l|}
\hline 
\textbf{C declaration} & \textbf{Description} \\ \hline 
\multicolumn{2}{|l|}{Device declarations} \\ \hline
\texttt{struct dev1\_t} & Device structure \\ 
\texttt{typedef dev1\_t} & Device type defintion (as above) \\ 
\texttt{enum dev1\_initials} & Initial register values \\
\texttt{void dev1\_initialize( dev1\_t *dev, ... )} & Initialization \\
\texttt{int dev1\_pr( char *s, size\_t sz, device\_t *v )} & Print \\
\hline

\multicolumn{2}{|l|}{Constants declarations} \\ \hline
\texttt{typedef dev1\_const1\_t} & Integer type \\
\texttt{\#define dev1\_cval1} & Macro giving integer value \\
\texttt{char *dev1\_const1\_describe( dev1\_const1\_t e )} & Description \\
\texttt{int dev1\_const1\_prtval( char *s, size\_t sz,
  dev1\_const1\_t e )} & Print \\
\texttt{int dev1\_const1\_chk( dev1\_const1\_t e)} & Check value \\
\hline

\multicolumn{2}{|l|}{Register type declarations} \\ \hline
\texttt{typedef dev1\_rtype2\_t} & Type defintion \\
\texttt{\#define dev1\_rtype2\_default} & Default value \\
\texttt{int dev1\_rtype2\_prtval( char *s, size\_t sz,
  dev1\_rtype2\_t v )} & Print \\
\texttt{dev1\_rtype2\_t dev1\_rtype2\_field2\_insert( dev1\_rtype2\_t r, ftype2\_t val )} & Insert a field value \\
\texttt{ftype2\_t dev1\_rtype2\_field2\_extract( dev1\_rtype2\_t r )} & Extract field value\\
\hline

\multicolumn{2}{|l|}{Datatype declarations} \\ \hline
\texttt{typedef dev1\_dtype3\_t} & Pointer to datatype \\
\texttt{const size\_t dev1\_dtype3\_size} & Size \\
\texttt{typedef dev1\_dtype3\_array\_t} & Byte array of the same size \\
\texttt{int dev1\_dtype3\_prtval( char *s, size t sz, dev1\_dtype3\_t
  v )} & Print \\
\texttt{void dev1\_dtype3\_field3\_insert( dev1\_dtype3\_t r, ftype3\_t val )} & Insert field \\
\texttt{ftype3\_t dev1\_dtype3\_field3\_extract( dev1\_dtype3\_t r )} & Extract field \\
\hline

\multicolumn{2}{|l|}{Register declarations} \\ \hline
\texttt{dev1\_rtype4\_t dev1\_reg4\_rd( dev1\_t *dev )} & Read register \\
\texttt{dev1\_rtype4\_t dev1\_reg4\_rawrd( dev1\_t *dev )} & Raw read \\
\texttt{void dev1\_reg4\_wr( dev1\_t *dev, dev1\_rtype4\_t val )} & Write register \\
\texttt{void dev1\_reg4\_rawwr( dev1\_t *dev, dev1\_rtype4\_t val )} & Raw write \\
\texttt{ftype4\_t dev1\_reg4\_field4\_rdf( dev1\_t *dev )} & Read field \\
\texttt{void dev1\_reg4\_field4\_wrf( dev1\_t *dev, ftype4 val )} & Write field \\
\texttt{ftype4\_t dev1\_reg4\_field4\_rd\_shaddow( dev1\_t *dev )} & Read shadow \\
\texttt{int dev1\_reg4\_pr( char *s, size\_t sz, dev1\_t *dev )} & Print \\
\hline

\multicolumn{2}{|l|}{Register array declarations} \\ \hline
\texttt{const int dev1\_array5\_length} & Num. registers \\
\texttt{dev1\_rtype5\_t dev1\_reg5\_rd( dev1\_t *dev, int i )} & Read register \\
\texttt{dev1\_rtype5\_t dev1\_reg5\_rawrd( dev1\_t *dev, int i )} & Raw read \\
\texttt{void dev1\_reg5\_wr( dev1\_t *dev, int i, dev1\_rtype5\_t val )} & Write register \\
\texttt{void dev1\_reg5\_rawwr( dev1\_t *dev, int i, dev1\_rtype5\_t val )} & Raw write \\

\texttt{ftype5\_t dev1\_reg5\_field5\_rdf( dev1\_t *dev, int i )} & Read field \\
\texttt{void dev1\_reg5\_field5\_wrf( dev1\_t *dev, int i, ftype5 val )} & Write field \\
\texttt{ftype5\_t dev1\_reg5\_field5\_rd\_shaddow( dev1\_t *dev, int i
  )} & Read shadow \\
\texttt{int dev1\_reg5\_pri( char *s, size\_t sz, dev1\_t *dev, int i )} & Print \\
\texttt{int dev1\_reg5\_pr( char *s, size\_t sz, dev1\_t *dev )} &
Print array \\
\hline

\multicolumn{2}{|l|}{Space access functions} \\ \hline
\texttt{uint\textit{x}\_t dev1\_space6\_read\_\textit{x}(
    dev1\_t *dev, size\_t offset )} & Read a value \\
\texttt{void dev1\_space6\_write\textit{x}(
    dev1\_t *dev, size\_t offset, uint\textit{x}\_t value )} & Write a
    value \\
\hline

\end{tabular}}

\end{document}
