more specs.
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@846 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
a05b6ddb15
commit
fd958cea68
|
@ -0,0 +1,266 @@
|
|||
RFC for the chip specification architecture
|
||||
|
||||
\begin{abstract}
|
||||
At the end of this document is the original message that motivated the
|
||||
change.
|
||||
\end{abstract}
|
||||
|
||||
\section{Scope}
|
||||
This document defines how LinuxBIOS programmers can specify chips that
|
||||
are used, specified, and initalized. The current scope is for superio
|
||||
chips, but the architecture should allow for specification of other chips such
|
||||
as southbridges. Multiple chips of same or different type are supported.
|
||||
|
||||
\section{Goals}
|
||||
The goals of the new chip architecture are these:
|
||||
\begin{itemize}
|
||||
\item seperate implementation details from specification in the Config file
|
||||
(translation: no more C code in Config files)
|
||||
\item make the specification easier for people to use and understand
|
||||
\item remove private details of a given chip to the chip file as much
|
||||
as possible
|
||||
\item allow unique register-set-specifiers for each chip
|
||||
\end{itemize}
|
||||
|
||||
\section{Specification in the Config file}
|
||||
The specification looks like this:
|
||||
\begin{verbatim}
|
||||
chip <name> [path=<path>] ["<configuration>"]
|
||||
\end{verbatim}
|
||||
The name is in the standard LinuxBIOS form of type/vendor/name, e.g.
|
||||
"southbridge/intel/piix4e" or "superio/ITE/it8671f". The class of the
|
||||
chip is derived from the first pathname component of the name, and the chip
|
||||
configuration is derived from the following components.
|
||||
|
||||
The path defines the access mechanism to the chip.
|
||||
It is optional. If present, it overrides the default path to the chip.
|
||||
|
||||
The configuration defines chip-specific configuration details, and is also
|
||||
optional. Note that an empty configuration will leave the chip with
|
||||
no enabled resources. This may be desirable in some cases.
|
||||
|
||||
\section{Results of specifying a chip}
|
||||
|
||||
When one or more chips are specified, the data about the chips
|
||||
is saved until the entire file is parsed. At this point, the config tool
|
||||
creates a file in the build directory called chip.c This file contains
|
||||
a common struct containing information about
|
||||
each individual chip and an array of pointers to these structures.
|
||||
|
||||
For each chip, there are two structures. The structures contain control
|
||||
information for the chip, and register initialization information. The
|
||||
names of the structures are derived by ``flattening'' the chip name,
|
||||
as in the current linuxbios. For example, superio/ITE/xyz uses
|
||||
two structs, one called superio_ITE_xyz_control and one called
|
||||
superio_ITE_xyz_init. The control struct is initialized from the
|
||||
chip name and path information, and has a pointer to the
|
||||
config struct. The config struct is initialized from the quote string
|
||||
|
||||
\begin{verbatim}
|
||||
From rminnich@lanl.gov Fri May 16 10:34:13 2003
|
||||
Date: Tue, 13 May 2003 08:11:46 -0600 (MDT)
|
||||
From: ron minnich <rminnich@lanl.gov>
|
||||
To: linuxbios@clustermatic.org
|
||||
Subject: RFC:new superio proposal
|
||||
|
||||
Abstract:
|
||||
The superio architecture for linuxbios has worked for the last 2
|
||||
years but is being stretched to the limit by the changes in superio chips.
|
||||
The architecture depended on superio resources being relatively constant
|
||||
between chips, but this assumption no longer holds. In this document we
|
||||
propose several alternatives and solicit comments.
|
||||
|
||||
Overview:
|
||||
The superio architecture in linuxbios was developed over time, and
|
||||
modified as circumstances required. In the beginning it was relatively
|
||||
simple and assumed only one superio per mainboard. The latest version
|
||||
allows an arbitrary number of superios per mainboard, and allows complete
|
||||
specification of the superio base I/O address along with the specification
|
||||
of reasonable default valures for both the base I/O address and the
|
||||
superio parameters such as serial enable, baud rate, and so on.
|
||||
|
||||
Specification of superio control parameters is done by a configuration
|
||||
line such as:
|
||||
|
||||
nsuperio sis/950 com1={1} floppy=1 lpt=1
|
||||
|
||||
This fragment sets the superio type to sis/950; sets com1, floppy, and lpt
|
||||
to enabled; and leaves the defaults to com1 (baud rate, etc.) to the
|
||||
default values.
|
||||
|
||||
While it is not obvious, these configuration parameters are fragments of a
|
||||
C initializer. The initializers are used to build a statically initialized
|
||||
structure of this type:
|
||||
|
||||
struct superio {
|
||||
struct superio_control *super; // the ops for the device.
|
||||
unsigned int port; // if non-zero, overrides the default port
|
||||
// com ports. This is not done as an array (yet).
|
||||
// We think it's easier to set up from python if it is not an
|
||||
// array.
|
||||
struct com_ports com1, com2, com3, com4;
|
||||
// DMA, if it exists.
|
||||
struct lpt_ports lpt1, lpt2;
|
||||
/* flags for each device type. Unsigned int. */
|
||||
// low order bit ALWAYS means enable. Next bit means to enable
|
||||
// LPT is in transition, so we leave this here for the moment.
|
||||
// The winbond chips really stretched the way this works.
|
||||
// so many functions!
|
||||
unsigned int ide, floppy, lpt;
|
||||
unsigned int keyboard, cir, game;
|
||||
unsigned int gpio1, gpio2, gpio3;
|
||||
unsigned int acpi,hwmonitor;
|
||||
};
|
||||
|
||||
These structures are, in turn, created and statically initialized by a
|
||||
config-tool-generated structure that defines all the superios. This file
|
||||
is called nsuperio.c, is created for each mainboard you build, only
|
||||
appears in the build directory, and looks like this:
|
||||
|
||||
===
|
||||
extern struct superio_control superio_winbond_w83627hf_control;
|
||||
|
||||
struct superio superio_winbond_w83627hf= {
|
||||
&superio_winbond_w83627hf_control,
|
||||
.com1={1}, .com2={1}, .floppy=1, .lpt=1, .keyboard=1, .hwmonitor=1};
|
||||
|
||||
struct superio *all_superio[] = {&superio_winbond_w83627hf,
|
||||
};
|
||||
|
||||
unsigned long nsuperio = 1;
|
||||
===
|
||||
|
||||
This example shows a board with one superio (nsuperio). The superio
|
||||
consists of a winbond w83627hf, with com1, com2, floppy, lpt, keyboard,
|
||||
and hwmonitor enabled. Note that this structure also allows for
|
||||
over-riding the default superio base, although that capability is rarely
|
||||
used.
|
||||
|
||||
The control structure is used to define how to access the superio for
|
||||
purposes of control. It looks like this:
|
||||
===
|
||||
struct superio_control {
|
||||
void (*pre_pci_init)(struct superio *s);
|
||||
void (*init)(struct superio *s);
|
||||
void (*finishup)(struct superio *s);
|
||||
unsigned int defaultport; /* the defaultport. Can be overridden
|
||||
* by commands in config
|
||||
*/
|
||||
// This is the print name for debugging
|
||||
char *name;
|
||||
};
|
||||
===
|
||||
|
||||
There are three methods for stages of hardwaremain. First is pre_pci_init
|
||||
(for chips like the acer southbridge that require you to enable some
|
||||
resources BEFORE pci scan); init, called during the 'middle' phase of
|
||||
hardwaremain; and finishup, called before the payload is loaded.
|
||||
|
||||
This approach was inspired by and borrows heavily on the Plan 9 kernel
|
||||
configuration tools.
|
||||
|
||||
The problem:
|
||||
|
||||
When the first version of the superio structure came out it was much
|
||||
smaller. It has grown and in the limit this structure is the union of all
|
||||
possibly superio chips. Obviously, in the long term, this is not
|
||||
practical: we can not anticipate all possible superio chips for all time.
|
||||
|
||||
The common PC BIOS solution to this type of problem is to continue with
|
||||
binary structures but add version numbers to them, so that all code that
|
||||
uses a given structure has to check the version number. Personally, I find
|
||||
this grotesque and would rather not work this way.
|
||||
|
||||
Using textual strings for configuration is something I find far more
|
||||
attractive. Plan 9 has shown that this approach has no real limits and
|
||||
suffices for configuration tasks. The Linux kernel does more limited use
|
||||
of strings for configuration, but still depends on them. Strings are
|
||||
easier to read and work with than binary structures, and more important, a
|
||||
lot easier to deal with when things start going wrong.
|
||||
|
||||
The proposed solution:
|
||||
|
||||
What follows are three possible ideas for specifying superio resources and
|
||||
their settings.
|
||||
|
||||
A common part of the new idea is to eliminate the common superio
|
||||
structure, due to the many variations in chips, and make it invisible
|
||||
outside a given superio source file -- the superio structure is now
|
||||
private to a given superio. Thus, sis/950/superio.c would contain its own
|
||||
superio structure definitions, and also might contain more than once
|
||||
instance of these structures (consider a board with 2 sis 950 chips).
|
||||
|
||||
The control structure would change as follows:
|
||||
struct superio_control {
|
||||
int (*create)(struct superio *s);
|
||||
void (*pre_pci_init)(struct superio *s);
|
||||
void (*init)(struct superio *s);
|
||||
void (*finishup)(struct superio *s);
|
||||
unsigned int defaultport; /* the defaultport. Can be overridden
|
||||
* by commands in config
|
||||
*/
|
||||
// This is the print name for debugging
|
||||
char *name;
|
||||
};
|
||||
|
||||
I.e. we add a new function for creating the superio.
|
||||
|
||||
Communication of superio settings from linuxbios to the superio would be
|
||||
via textual strings. The superio structure becomes this:
|
||||
|
||||
struct superio {
|
||||
struct superio_control *super; // the ops for the device.
|
||||
unsigned int port; // if non-zero, overrides the default port
|
||||
struct configuration *config;
|
||||
};
|
||||
|
||||
|
||||
So now the question becomes, what is the configuration structure?
|
||||
There are several choices. The simplest, from my point of view, are
|
||||
keyword-value pairs:
|
||||
struct configuration {
|
||||
const char *keyword;
|
||||
const char *value;
|
||||
};
|
||||
|
||||
These get filled in by the config tool as before. The linuxbios libary can
|
||||
then provide a generic parsing function for the superios to use.
|
||||
|
||||
The remaining question is how should the superio command look in
|
||||
freebios2?
|
||||
|
||||
superio sis/950 "com1=115200,8n1 lpt=1 com2=9600"
|
||||
|
||||
or
|
||||
|
||||
superio sis/950 "com1baud=115200 lpt=1 com1chars=8n1"
|
||||
|
||||
or
|
||||
|
||||
superio sis/950 ((com1 115200 8n1) (lpt 1))
|
||||
|
||||
So, my questions:
|
||||
|
||||
1. Does this new scheme look workable. If not, what needs to change?
|
||||
2. What should the 'struct configuration' be? does keyword/value work?
|
||||
3. what should the superio command look like?
|
||||
|
||||
Comments welcome.
|
||||
|
||||
I'd like to adopt this "RFC" approach for freebios2 as much as we can.
|
||||
There was a lot of give-and-take in the early days of linuxbios about
|
||||
structure and it proved useful. There's a lot that will start happening in
|
||||
freebios2 now, and we need to try to make sure it will work for everyone.
|
||||
|
||||
Those of you who are doing mainboards, please look at freebios2 and see
|
||||
how it looks for you. There's a lot of good work that has been done (not
|
||||
by me so far, thanks Eric and Stefan), and more that needs to be done.
|
||||
Consider trying out romcc as an "assembly code killer". See how it fits
|
||||
together and if you can work with it or need changes. Bring comments back
|
||||
to this list.
|
||||
|
||||
thanks
|
||||
|
||||
ron
|
||||
|
||||
\end{verbatim}
|
|
@ -0,0 +1,276 @@
|
|||
New config language for LinuxBIOS
|
||||
|
||||
\begin{abstract}
|
||||
We describe the new configuration language for LinuxBIOS.
|
||||
\end{abstract}
|
||||
|
||||
\section{Scope}
|
||||
This document defines the new configuration language for LinuxBIOS.
|
||||
|
||||
\section{Goals}
|
||||
The goals of the new language are these:
|
||||
\begin{itemize}
|
||||
\item Simplified Makefiles so people can see what is set
|
||||
\item Move from the regular-expression-based language to something
|
||||
a bit more comprehensible and flexible
|
||||
\item make the specification easier for people to use and understand
|
||||
\item allow unique register-set-specifiers for each chip
|
||||
\end{itemize}
|
||||
|
||||
\section{Language}
|
||||
Here is the new language. It is very similar to the old one, differing
|
||||
in only a few respects. It borrows heavily from Greg Watson's suggestions.
|
||||
|
||||
I am presenting it in a pseudo-BNF in the hopes it will be easier. Things
|
||||
in '' are keywords; things in ``'' are strings in the actual text.
|
||||
\begin{verbatim}
|
||||
#exprs are composed of factor or factor + factor etc.
|
||||
expr ::= factor ( ``+'' factor | ``-'' factor | )*
|
||||
#factors are term or term * term or term / term or ...
|
||||
factor ::= term ( ``*'' term | ``/'' term | ... )*
|
||||
#
|
||||
unary-op ::= ``!'' ID
|
||||
# term is a number, hexnumber, ID, unary-op, or a full-blown expression
|
||||
term ::= NUM | XNUM | ID | unary-op | ``(`` expr ``)''
|
||||
|
||||
# Option command. Can be an expression or quote-string.
|
||||
# Options are used in the config tool itself (in expressions and 'if')
|
||||
# and are also passed to the C compiler when building linuxbios.
|
||||
# It is an error to have two option commands in a file.
|
||||
# It is an error to have an option command after the ID has been used
|
||||
# in an expression (i.e. 'set after used' is an error)
|
||||
option ::= 'option' ID '=' (``value'' | term)
|
||||
|
||||
# Default command. The ID is set to this value if no option command
|
||||
# is scanned.
|
||||
# Multiple defaults for an ID will produce warning, but not errors.
|
||||
# It is OK to scan a default command after use of an ID.
|
||||
# Options always over-ride defaults.
|
||||
default ::= 'default' ID '=' (``value'' | term)
|
||||
|
||||
# the mainboard, southbridge, northbridge commands
|
||||
# cause sourcing of Config.lb files as in the old config tool
|
||||
# as parts are sourced, a device tree is built. The structure
|
||||
# of the tree is determined by the structure of the components
|
||||
# as they are specified. To attach a superio to a southbridge, for
|
||||
# example, one would do this:
|
||||
# southbridge acer/5432
|
||||
# superio NSC/123
|
||||
# end
|
||||
# end
|
||||
# the tool generates static initializers for this hierarchy.
|
||||
|
||||
# add C code to the current component (motherboard, etc. )
|
||||
# to initialise the component-INDEPENDENT structure members
|
||||
init ::= 'init' ``CODE''
|
||||
|
||||
# add C code to the current component (motherboard, etc. )
|
||||
# to initialise the component-DEPENDENT structure members
|
||||
register ::= 'register' ``CODE''
|
||||
|
||||
|
||||
# mainboard command
|
||||
# statements in this block will set variables controlling the mainboard,
|
||||
# and will also place components (northbridge etc.) in the device tree
|
||||
# under this mainboard
|
||||
mainboard ::= 'mainboard' PATH (statements)* 'end'
|
||||
|
||||
# standard linuxbios commands
|
||||
southbridge ::= 'southbridge' PATH (statemnts)* 'end'
|
||||
northbridge ::= 'northbridge' PATH (statemnts)* 'end'
|
||||
superio ::= 'superio PATH (statemnts)* 'end'
|
||||
cpu ::= 'cpu' PATH (statemnts)* 'end'
|
||||
arch ::= 'arch' PATH (statemnts)* 'end'
|
||||
|
||||
# files for building linuxbios
|
||||
# include a file in crt0.S
|
||||
mainboardinit ::= 'mainboardinit' PATH
|
||||
|
||||
# object file
|
||||
object ::= 'object' PATH
|
||||
# driver objects are just built into the image in a different way
|
||||
driver ::= 'driver' PATH
|
||||
|
||||
# Use the Config.lb file in the PATH
|
||||
dir ::= 'dir' PATH
|
||||
|
||||
# add a file to the set of ldscript files
|
||||
ldscript ::= 'ldscript' PATH
|
||||
|
||||
# dependencies or actions for the makerule command
|
||||
dep ::= 'dep' ``dependency-string''
|
||||
act ::= 'act' ``actions''
|
||||
depsacts ::= (dep | act)*
|
||||
# set up a makerule
|
||||
#
|
||||
makerule ::= 'makerule' PATH depsacts
|
||||
|
||||
#defines for use in makefiles only
|
||||
# note usable in the config tool, not passed to cc
|
||||
makedefine ::= 'makedefine' ``RAWTEXT''
|
||||
|
||||
# add an action to an existing make rule
|
||||
addaction ::= 'addaction' PATH ``ACTION''
|
||||
|
||||
# statements
|
||||
statement ::=
|
||||
option
|
||||
| default
|
||||
| cpu
|
||||
| arch
|
||||
| northbridge
|
||||
| southbridge
|
||||
| superio
|
||||
| object
|
||||
| driver
|
||||
| mainboardinit
|
||||
| makerule
|
||||
| makedefine
|
||||
| addaction
|
||||
| init
|
||||
| register
|
||||
| iif
|
||||
| dir
|
||||
| ldscript
|
||||
|
||||
statements ::= (statement)*
|
||||
|
||||
# target directory specification
|
||||
target ::= 'target' PATH
|
||||
|
||||
# and the whole thing
|
||||
board ::= target (option)* mainboard
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
A sample file:
|
||||
|
||||
\begin{verbatim}
|
||||
target x
|
||||
|
||||
# over-ride the default rom size in the mainboard file
|
||||
option ROM_SIZE=0x100000
|
||||
mainboard amd/solo
|
||||
end
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
Sample mainboard file
|
||||
\begin{verbatim}
|
||||
#
|
||||
###
|
||||
### Set all of the defaults for an x86 architecture
|
||||
###
|
||||
arch i386 end
|
||||
cpu k8 end
|
||||
#
|
||||
option DEBUG=1
|
||||
default USE_FALLBACK_IMAGE=1
|
||||
option A=(1+2)
|
||||
option B=0xa
|
||||
#
|
||||
###
|
||||
### Build our 16 bit and 32 bit linuxBIOS entry code
|
||||
###
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
ldscript cpu/i386/entry32.lds
|
||||
#
|
||||
###
|
||||
### Build our reset vector (This is where linuxBIOS is entered)
|
||||
###
|
||||
if USE_FALLBACK_IMAGE
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
end
|
||||
|
||||
if USE_NORMAL_IMAGE
|
||||
mainboardinit cpu/i386/reset32.inc
|
||||
ldscript cpu/i386/reset32.lds
|
||||
end
|
||||
.
|
||||
.
|
||||
.
|
||||
if USE_FALLBACK_IMAGE mainboardinit arch/i386/lib/noop_failover.inc end
|
||||
#
|
||||
###
|
||||
### Romcc output
|
||||
###
|
||||
#makerule ./failover.E dep "$(MAINBOARD)/failover.c" act "$(CPP) -I$(TOP)/src $(CPPFLAGS) $(MAINBOARD)/failover.c > ./failever.E"
|
||||
#makerule ./failover.inc dep "./romcc ./failover.E" act "./romcc -O ./failover.E > failover.inc"
|
||||
#mainboardinit ./failover.inc
|
||||
makerule ./auto.E dep "$(MAINBOARD)/auto.c" act "$(CPP) -I$(TOP)/src -$(ROMCCPPFLAGS) $(CPPFLAGS) $(MAINBOARD)/auto.c > ./auto.E"
|
||||
makerule ./auto.inc dep "./romcc ./auto.E" act "./romcc -O ./auto.E > auto.inc"
|
||||
mainboardinit ./auto.inc
|
||||
#
|
||||
###
|
||||
### Setup RAM
|
||||
###
|
||||
mainboardinit ram/ramtest.inc
|
||||
mainboardinit southbridge/amd/amd8111/smbus.inc
|
||||
mainboardinit sdram/generic_dump_spd.inc
|
||||
#
|
||||
###
|
||||
### Include the secondary Configuration files
|
||||
###
|
||||
northbridge amd/amdk8
|
||||
end
|
||||
southbridge amd/amd8111
|
||||
end
|
||||
#mainboardinit arch/i386/smp/secondary.inc
|
||||
superio NSC/pc87360
|
||||
register "com1={1} com2={0} floppy=1 lpt=1 keyboard=1"
|
||||
end
|
||||
dir /pc80
|
||||
##dir /src/superio/winbond/w83627hf
|
||||
cpu p5 end
|
||||
cpu p6 end
|
||||
cpu k7 end
|
||||
cpu k8 end
|
||||
#
|
||||
###
|
||||
### Build the objects we have code for in this directory.
|
||||
###
|
||||
##object mainboard.o
|
||||
driver mainboard.o
|
||||
object static_devices.o
|
||||
if HAVE_MP_TABLE object mptable.o end
|
||||
if HAVE_PIRQ_TABLE object irq_tables.o end
|
||||
### Location of the DIMM EEPROMS on the SMBUS
|
||||
### This is fixed into a narrow range by the DIMM package standard.
|
||||
###
|
||||
option SMBUS_MEM_DEVICE_START=(0xa << 3)
|
||||
option SMBUS_MEM_DEVICE_END=(SMBUS_MEM_DEVICE_START +1)
|
||||
option SMBUS_MEM_DEVICE_INC=1
|
||||
#
|
||||
### The linuxBIOS bootloader.
|
||||
###
|
||||
option PAYLOAD_SIZE = (ROM_SECTION_SIZE - ROM_IMAGE_SIZE)
|
||||
option CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
|
||||
#
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
I've found the output of the new tool to be easier to
|
||||
handle. Makefile.settings looks like this, for example:
|
||||
\begin{verbatim}
|
||||
TOP:=/home/rminnich/src/yapps2/freebios2
|
||||
TARGET_DIR:=x
|
||||
export MAINBOARD:=/home/rminnich/src/yapps2/freebios2/src/mainboard/amd/solo
|
||||
export ARCH:=i386
|
||||
export _RAMBASE:=0x4000
|
||||
export ROM_IMAGE_SIZE:=65535
|
||||
export PAYLOAD_SIZE:=131073
|
||||
export MAX_CPUS:=1
|
||||
export HEAP_SIZE:=8192
|
||||
export STACK_SIZE:=8192
|
||||
export MEMORY_HOLE:=0
|
||||
export LINUXBIOS_VERSION:=1.1.0
|
||||
export CC:=$(CROSS_COMPILE)gcc
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
In other words, instead of expressions, we see the values. It's easier to
|
||||
deal with.
|
||||
|
Loading…
Reference in New Issue