diff options
-rw-r--r-- | documentation/RFC/chip.tex | 266 | ||||
-rw-r--r-- | documentation/RFC/config.tex | 276 |
2 files changed, 542 insertions, 0 deletions
diff --git a/documentation/RFC/chip.tex b/documentation/RFC/chip.tex new file mode 100644 index 0000000000..58a50853df --- /dev/null +++ b/documentation/RFC/chip.tex @@ -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} diff --git a/documentation/RFC/config.tex b/documentation/RFC/config.tex new file mode 100644 index 0000000000..1190c8daa9 --- /dev/null +++ b/documentation/RFC/config.tex @@ -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. + |