Signed-off-by: Stefan Reinauer <stepan@coresystems.de>

Acked-by: Jordan Crouse <jordan.crouse@amd.com>


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2736 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Stefan Reinauer 2007-07-12 16:35:42 +00:00 committed by Stefan Reinauer
parent 6cf687783b
commit 6540ae5ea0
31 changed files with 6733 additions and 0 deletions

339
util/lxbios/COPYING Normal file
View File

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

132
util/lxbios/ChangeLog Normal file
View File

@ -0,0 +1,132 @@
Mon Jan 23 16:00:00 PST 2006 David S. Peterson (dsp@llnl.gov)
Version 2.0.1
* Postpone most sanity checking of CMOS layout information until right
before a CMOS read or write operation is attempted. This fixes a
problem discovered by Stefan Reinauer in which lxbios was failing on
Opteron due to the existence of a "user_data" parameter that is 256
bits long. In general, postponing the sanity checks will make
lxbios more adaptable to changes in how LinuxBIOS stores CMOS
parameters.
* Merge fix from Stefan Reinauer that makes hex dumps look a bit
nicer.
* Merge fix from Stefan Reinauer that allows lxbios to access CMOS
memory beyond the first 128 bytes.
Fri Dec 16 14:30:00 PST 2005 David S. Peterson (dsp@llnl.gov)
Version 2.0.0
* Added the following options:
-Y
Write CMOS layout information to standard output.
-b OUTPUT_FILE
Write the contents of CMOS memory to a binary file.
-B INPUT_FILE
Read binary data from file and write it to CMOS memory.
-x
Show a hex dump of all CMOS data.
-X DUMPFILE
Read binary data from a CMOS dumpfile and show a hex dump of
the data.
Thanks to Stefan Reinauer for suggesting the ideas for the "-Y",
"-b OUTPUT_FILE", and "-B INPUT_FILE" options.
* Added support for reading/writing CMOS parameters between 1 and 64
bits in size that are not necessarily aligned on byte boundaries.
* Reworked much of the code, cleaning up some ugly parts.
* Made a number of minor improvements.
Wed Nov 30 16:30:00 PST 2005 David S. Peterson (dsp@llnl.gov)
Version 1.4.0
* Merge patch from Stefan Reinauer <stepan@openbios.org> that makes
lxbios recognize the LB_TAG_OPTION_CHECKSUM entry placed in the
LinuxBIOS table by newer versions of LinuxBIOS.
* Tweak formatting of code to facilitate merging future patches.
* Minor code cleanup.
Fri Jun 25 18:30:00 PDT 2004 David S. Peterson (dsp@llnl.gov)
Version 1.3.2.
* Changed default_is_printable_fn to avoid problems displaying hex
dumps.
Thu Jun 10 14:00:00 PDT 2004 David S. Peterson (dsp@llnl.gov)
Version 1.3.1.
* Minor code cleanup.
Fri Mar 7 18:00:00 PST 2003 David S. Peterson (dsp@llnl.gov)
Version 1.3.0.
* Added -y option that tells lxbios to get CMOS layout information
from a file instead of from the CMOS option table.
* Modified command syntax so that -r flag is required for reading a
single CMOS parameter.
* Fixed bug where CMOS checksum was being displayed with bytes
reversed.
Thu Dec 5 14:30:00 PST 2002 David S. Peterson (dsp@llnl.gov)
Version 1.2.3.
* Fixed bug where checksum was not being updated after changing CMOS
parameter values.
* Added code to verify checksum when reading CMOS parameters.
* Modified program so that check_sum parameter is treated differently
from other CMOS parameters. Now, -c option must be used to
read/write check_sum parameter.
Thu Nov 14 15:15:00 PST 2002 David S. Peterson (dsp@llnl.gov)
Version 1.2.2.
* Shortened output of usage message.
Mon Nov 11 18:00:00 PST 2002 David S. Peterson (dsp@llnl.gov)
Version 1.2.1.
* Fixed typo in man page.
Mon Nov 11 10:00:00 PST 2002 David S. Peterson (dsp@llnl.gov)
Version 1.2.0.
* Added hex dump stuff.
Fri Nov 8 17:00:00 PST 2002 David S. Peterson (dsp@llnl.gov)
Version 1.1.0.
* Added -l option for displaying entries from LinuxBIOS table.
* Added -d option for low-level dump of LinuxBIOS table.
* Improved code that searches for LinuxBIOS table.
Wed Nov 6 09:30:00 PST 2002 David S. Peterson (dsp@llnl.gov)
Version 1.0.0.

70
util/lxbios/DISCLAIMER Normal file
View File

@ -0,0 +1,70 @@
####################################################################
# $Id: DISCLAIMER,v 1.1.1.1 2005/12/02 22:35:19 dsp_llnl Exp $
####################################################################
Copyright (C) 2002 The Regents of the University of California.
Produced at the Lawrence Livermore National Laboratory.
Written by David S. Peterson <dsp@llnl.gov>.
UCRL-CODE-2003-012
All rights reserved.
This file is part of lxbios, a utility for reading/writing LinuxBIOS
parameters and displaying information from the LinuxBIOS table.
For details, see <http://www.llnl.gov/linux/lxbios/>.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License (as published by the
Free Software Foundation) version 2, dated June 1991.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
conditions of the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
This work was produced at the University of California, Lawrence Livermore
National Laboratory (UC LLNL) under contract no. W-7405-ENG-48 (Contract 48)
between the U.S. Department of Energy (DOE) and The Regents of the
University of California (University) for the operation of UC LLNL.
The rights of the Federal Government are reserved under Contract 48 subject
to the restrictions agreed upon by the DOE and University as allowed under
DOE Acquisition Letter 97-1.
#############################################################################
OUR NOTICE AND TERMS AND CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE
Our Preamble Notice
-------------------
A. This notice is required to be provided under our contract with the U.S.
Department of Energy (DOE). This work was produced at the University of
California, Lawrence Livermore National Laboratory under Contract No.
W-7405-ENG-48 with the DOE.
B. Neither the United States Government nor the University of California nor
any of their employees, makes any warranty, express or implied, or
assumes any liability or responsibility for the accuracy, completeness,
or usefulness of any information, apparatus, product, or process
disclosed, or represents that its use would not infringe privately-owned
rights.
C. Also, reference herein to any specific commercial products, process, or
services by trade name, trademark, manufacturer or otherwise does not
necessarily constitute or imply its endorsement, recommendation, or
favoring by the United States Government or the University of California.
The views and opinions of authors expressed herein do not necessarily
state or reflect those of the United States Government or the University
of California, and shall not be used for advertising or product
endorsement purposes. The precise terms and conditions for copying,
distribution and modification follows.
GNU Terms and Conditions for Copying, Distribution, and Modification
--------------------------------------------------------------------
The precise terms and conditions of the GNU General Public License
(version 2, dated June 1991) are contained in the file COPYING which is
included in this software distribution.

28
util/lxbios/Makefile Normal file
View File

@ -0,0 +1,28 @@
# $Id: Makefile,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
PROJECT = lxbios
CC = gcc
CFLAGS = -O2 -W -Wall
LDFLAGS =
OBJS = common.o compute_ip_checksum.o hexdump.o cmos_lowlevel.o \
reg_expr.o layout.o layout_file.o lbtable.o cmos_ops.o input_file.o \
opts.o lxbios.o
HEADERS = common.h ip_checksum.h linuxbios_tables.h hexdump.h \
cmos_lowlevel.h reg_expr.h layout.h layout_file.h lbtable.h \
cmos_ops.h input_file.h opts.h
all: lxbios man
lxbios: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
man: lxbios.1.gz
$(OBJS): $(HEADERS)
lxbios.1.gz: lxbios.1
gzip -c --best lxbios.1 > lxbios.1.gz
clean:
rm -f *.o lxbios lxbios.1.gz

21
util/lxbios/README Normal file
View File

@ -0,0 +1,21 @@
$Id: README,v 1.3 2006/01/24 00:25:39 dsp_llnl Exp $
Summary of Operation
--------------------
lxbios is a utility for reading/writing LinuxBIOS parameters and
displaying information from the LinuxBIOS table. It is intended for x86-based
systems (both 32-bit and 64-bit) that use LinuxBIOS.
The LinuxBIOS table resides in low physical memory, and may be accessed
through the /dev/mem interface. It is created at boot time by LinuxBIOS, and
contains various system information such as the type of mainboard in use. It
specifies locations in the CMOS (nonvolatile RAM) where the LinuxBIOS
parameters are stored.
For information about LinuxBIOS, see http://www.linuxbios.org/.
Ideas for Future Improvements
-----------------------------
1. Move the core functionality of this program into a shared library.
2. Consider adding options for displaying other BIOS-provided information
such as the MP table, ACPI table, PCI IRQ routing table, etc.

299
util/lxbios/cmos_lowlevel.c Normal file
View File

@ -0,0 +1,299 @@
/*****************************************************************************\
* cmos_lowlevel.c
* $Id: cmos_lowlevel.c,v 1.3 2006/01/24 00:25:39 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include <sys/io.h>
#include "common.h"
#include "cmos_lowlevel.h"
typedef struct
{ unsigned byte_index;
unsigned bit_offset;
}
cmos_bit_op_location_t;
static unsigned cmos_bit_op_strategy (unsigned bit, unsigned bits_left,
cmos_bit_op_location_t *where);
static unsigned char cmos_read_bits (const cmos_bit_op_location_t *where,
unsigned nr_bits);
static void cmos_write_bits (const cmos_bit_op_location_t *where,
unsigned nr_bits, unsigned char value);
static unsigned char get_bits (unsigned long long value, unsigned bit,
unsigned nr_bits);
static void put_bits (unsigned char value, unsigned bit, unsigned nr_bits,
unsigned long long *result);
/****************************************************************************
* get_bits
*
* Extract a value 'nr_bits' bits wide starting at bit position 'bit' from
* 'value' and return the result. It is assumed that 'nr_bits' is at most 8.
****************************************************************************/
static inline unsigned char get_bits (unsigned long long value, unsigned bit,
unsigned nr_bits)
{ return (value >> bit) & ((unsigned char) ((1 << nr_bits) - 1)); }
/****************************************************************************
* put_bits
*
* Extract the low order 'nr_bits' bits from 'value' and store them in the
* value pointed to by 'result' starting at bit position 'bit'. The bit
* positions in 'result' where the result is stored are assumed to be
* initially zero.
****************************************************************************/
static inline void put_bits (unsigned char value, unsigned bit,
unsigned nr_bits, unsigned long long *result)
{ *result += (value & ((unsigned char) ((1 << nr_bits) - 1))) << bit; }
/****************************************************************************
* cmos_read
*
* Read value from nonvolatile RAM at position given by 'bit' and 'length'
* and return this value. The I/O privilege level of the currently executing
* process must be set appropriately.
****************************************************************************/
unsigned long long cmos_read (unsigned bit, unsigned length)
{ cmos_bit_op_location_t where;
unsigned next_bit, bits_left, nr_bits;
unsigned long long result;
unsigned char value;
assert(!verify_cmos_op(bit, length));
result = 0;
for (next_bit = 0, bits_left = length;
bits_left;
next_bit += nr_bits, bits_left -= nr_bits)
{ nr_bits = cmos_bit_op_strategy(bit + next_bit, bits_left, &where);
value = cmos_read_bits(&where, nr_bits);
put_bits(value, next_bit, nr_bits, &result);
}
return result;
}
/****************************************************************************
* cmos_write
*
* Write 'data' to nonvolatile RAM at position given by 'bit' and 'length'.
* The I/O privilege level of the currently executing process must be set
* appropriately.
****************************************************************************/
void cmos_write (unsigned bit, unsigned length, unsigned long long value)
{ cmos_bit_op_location_t where;
unsigned next_bit, bits_left, nr_bits;
assert(!verify_cmos_op(bit, length));
for (next_bit = 0, bits_left = length;
bits_left;
next_bit += nr_bits, bits_left -= nr_bits)
{ nr_bits = cmos_bit_op_strategy(bit + next_bit, bits_left, &where);
cmos_write_bits(&where, nr_bits, get_bits(value, next_bit, nr_bits));
}
}
/****************************************************************************
* cmos_read_byte
*
* Read a byte from nonvolatile RAM at a position given by 'index' and return
* the result. An 'index' value of 0 represents the first byte of
* nonvolatile RAM.
*
* Note: the first 14 bytes of nonvolatile RAM provide an interface to the
* real time clock.
****************************************************************************/
unsigned char cmos_read_byte (unsigned index)
{ unsigned short port_0, port_1;
assert(!verify_cmos_byte_index(index));
if (index < 128)
{ port_0 = 0x70;
port_1 = 0x71;
}
else
{ port_0 = 0x72;
port_1 = 0x73;
}
outb(index, port_0);
return inb(port_1);
}
/****************************************************************************
* cmos_write_byte
*
* Write 'value' to nonvolatile RAM at a position given by 'index'. An
* 'index' of 0 represents the first byte of nonvolatile RAM.
*
* Note: the first 14 bytes of nonvolatile RAM provide an interface to the
* real time clock. Writing to any of these bytes will therefore
* affect its functioning.
****************************************************************************/
void cmos_write_byte (unsigned index, unsigned char value)
{ unsigned short port_0, port_1;
assert(!verify_cmos_byte_index(index));
if (index < 128)
{ port_0 = 0x70;
port_1 = 0x71;
}
else
{ port_0 = 0x72;
port_1 = 0x73;
}
outb(index, port_0);
outb(value, port_1);
}
/****************************************************************************
* cmos_read_all
*
* Read all contents of CMOS memory into array 'data'. The first 14 bytes of
* 'data' are set to zero since this corresponds to the real time clock area.
****************************************************************************/
void cmos_read_all (unsigned char data[])
{ unsigned i;
for (i = 0; i < CMOS_RTC_AREA_SIZE; i++)
data[i] = 0;
for (; i < CMOS_SIZE; i++)
data[i] = cmos_read_byte(i);
}
/****************************************************************************
* cmos_write_all
*
* Update all of CMOS memory with the contents of array 'data'. The first 14
* bytes of 'data' are ignored since this corresponds to the real time clock
* area.
****************************************************************************/
void cmos_write_all (unsigned char data[])
{ unsigned i;
for (i = CMOS_RTC_AREA_SIZE; i < CMOS_SIZE; i++)
cmos_write_byte(i, data[i]);
}
/****************************************************************************
* set_iopl
*
* Set the I/O privilege level of the executing process. Root privileges are
* required for performing this action. A sufficient I/O privilege level
* allows the process to access x86 I/O address space and to disable/reenable
* interrupts while executing in user space. Messing with the I/O privilege
* level is therefore somewhat dangerous.
****************************************************************************/
void set_iopl (int level)
{ assert((level >= 0) && (level <= 3));
if (iopl(level))
{ fprintf(stderr,
"%s: iopl() system call failed. You must be root to do "
"this.\n",
prog_name);
exit(1);
}
}
/****************************************************************************
* verify_cmos_op
*
* 'bit' represents a bit position in the nonvolatile RAM. The first bit
* (i.e. the lowest order bit of the first byte) of nonvolatile RAM is
* labeled as bit 0. 'length' represents the width in bits of a value we
* wish to read or write. Perform sanity checking on 'bit' and 'length'. If
* no problems were encountered, return OK. Else return an error code.
****************************************************************************/
int verify_cmos_op (unsigned bit, unsigned length)
{ if ((bit >= (8 * CMOS_SIZE)) || ((bit + length) > (8 * CMOS_SIZE)))
return CMOS_AREA_OUT_OF_RANGE;
if (bit < (8 * CMOS_RTC_AREA_SIZE))
return CMOS_AREA_OVERLAPS_RTC;
if (length > (8 * sizeof(unsigned long long)))
return CMOS_AREA_TOO_WIDE;
return OK;
}
/****************************************************************************
* cmos_bit_op_strategy
*
* Helper function used by cmos_read() and cmos_write() to determine which
* bits to read or write next.
****************************************************************************/
static unsigned cmos_bit_op_strategy (unsigned bit, unsigned bits_left,
cmos_bit_op_location_t *where)
{ unsigned max_bits;
where->byte_index = bit >> 3;
where->bit_offset = bit & 0x07;
max_bits = 8 - where->bit_offset;
return (bits_left > max_bits) ? max_bits : bits_left;
}
/****************************************************************************
* cmos_read_bits
*
* Read a chunk of bits from a byte location within CMOS memory. Return the
* value represented by the chunk of bits.
****************************************************************************/
static unsigned char cmos_read_bits (const cmos_bit_op_location_t *where,
unsigned nr_bits)
{ return (cmos_read_byte(where->byte_index) >> where->bit_offset) &
((unsigned char) ((1 << nr_bits) - 1));
}
/****************************************************************************
* cmos_write_bits
*
* Write a chunk of bits (the low order 'nr_bits' bits of 'value') to an area
* within a particular byte of CMOS memory.
****************************************************************************/
static void cmos_write_bits (const cmos_bit_op_location_t *where,
unsigned nr_bits, unsigned char value)
{ unsigned char n, mask;
if (nr_bits == 8)
{ cmos_write_byte(where->byte_index, value);
return;
}
n = cmos_read_byte(where->byte_index);
mask = ((unsigned char) ((1 << nr_bits) - 1)) << where->bit_offset;
n = (n & ~mask) + ((value << where->bit_offset) & mask);
cmos_write_byte(where->byte_index, n);
}

View File

@ -0,0 +1,62 @@
/*****************************************************************************\
* cmos_lowlevel.h
* $Id: cmos_lowlevel.h,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef LXBIOS_CMOS_LOWLEVEL_H
#define LXBIOS_CMOS_LOWLEVEL_H
#include "common.h"
#define CMOS_AREA_OUT_OF_RANGE (CMOS_RESULT_START + 0)
#define CMOS_AREA_OVERLAPS_RTC (CMOS_RESULT_START + 1)
#define CMOS_AREA_TOO_WIDE (CMOS_RESULT_START + 2)
unsigned long long cmos_read (unsigned bit, unsigned length);
void cmos_write (unsigned bit, unsigned length, unsigned long long value);
unsigned char cmos_read_byte (unsigned index);
void cmos_write_byte (unsigned index, unsigned char value);
void cmos_read_all (unsigned char data[]);
void cmos_write_all (unsigned char data[]);
void set_iopl (int level);
int verify_cmos_op (unsigned bit, unsigned length);
#define CMOS_SIZE 256 /* size of CMOS memory in bytes */
#define CMOS_RTC_AREA_SIZE 14 /* first 14 bytes control real time clock */
/****************************************************************************
* verify_cmos_byte_index
*
* Return 1 if 'index' does NOT specify a valid CMOS memory location. Else
* return 0.
****************************************************************************/
static inline int verify_cmos_byte_index (unsigned index)
{ return (index < CMOS_RTC_AREA_SIZE) || (index >= CMOS_SIZE); }
#endif /* LXBIOS_CMOS_LOWLEVEL_H */

221
util/lxbios/cmos_ops.c Normal file
View File

@ -0,0 +1,221 @@
/*****************************************************************************\
* cmos_ops.c
* $Id: cmos_ops.c,v 1.3 2006/01/24 00:25:40 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include "common.h"
#include "cmos_ops.h"
#include "cmos_lowlevel.h"
static int prepare_cmos_op_common (const cmos_entry_t *e);
/****************************************************************************
* prepare_cmos_op_common
*
* Perform a few checks common to both reads and writes.
****************************************************************************/
static int prepare_cmos_op_common (const cmos_entry_t *e)
{ int result;
if (e->config == CMOS_ENTRY_RESERVED)
/* Access to reserved parameters is not permitted. */
return CMOS_OP_RESERVED;
if ((result = verify_cmos_op(e->bit, e->length)) != OK)
return result;
assert(e->length > 0);
return OK;
}
/****************************************************************************
* prepare_cmos_read
*
* The caller wishes to read a CMOS parameter represented by 'e'. Perform
* sanity checking on 'e'. If a problem was found with e, return an error
* code. Else return OK.
****************************************************************************/
int prepare_cmos_read (const cmos_entry_t *e)
{ int result;
if ((result = prepare_cmos_op_common(e)) != OK)
return result;
switch (e->config)
{ case CMOS_ENTRY_ENUM:
case CMOS_ENTRY_HEX:
break;
default:
BUG();
}
return OK;
}
/****************************************************************************
* prepare_cmos_write
*
* The caller wishes to set a CMOS parameter represented by 'e' to a value
* whose string representation is stored in 'value_str'. Perform sanity
* checking on 'value_str'. On error, return an error code. Else store the
* numeric equivalent of 'value_str' in '*value' and return OK.
****************************************************************************/
int prepare_cmos_write (const cmos_entry_t *e, const char value_str[],
unsigned long long *value)
{ const cmos_enum_t *q;
unsigned long long out;
const char *p;
int negative, result, found_one;
if ((result = prepare_cmos_op_common(e)) != OK)
return result;
switch (e->config)
{ case CMOS_ENTRY_ENUM:
/* Make sure the user's input corresponds to a valid option. */
for (q = first_cmos_enum_id(e->config_id), found_one = 0;
q != NULL;
q = next_cmos_enum_id(q))
{ found_one = 1;
if (!strncmp(q->text, value_str, CMOS_MAX_TEXT_LENGTH))
break;
}
if (!found_one)
return CMOS_OP_NO_MATCHING_ENUM;
if (q == NULL)
return CMOS_OP_BAD_ENUM_VALUE;
out = q->value;
break;
case CMOS_ENTRY_HEX:
/* See if the first character of 'value_str' (excluding any initial
* whitespace) is a minus sign.
*/
for (p = value_str; isspace(*p); p++);
negative = (*p == '-');
out = strtoull(value_str, (char **) &p, 0);
if (*p)
return CMOS_OP_INVALID_INT;
/* If we get this far, the user specified a valid integer. However
* we do not currently support the use of negative numbers as CMOS
* parameter values.
*/
if (negative)
return CMOS_OP_NEGATIVE_INT;
break;
default:
BUG();
}
if ((e->length < (8 * sizeof(*value))) &&
(out >= (1ull << e->length)))
return CMOS_OP_VALUE_TOO_WIDE;
*value = out;
return OK;
}
/****************************************************************************
* cmos_checksum_read
*
* Read the checksum for the LinuxBIOS parameters stored in CMOS and return
* this value.
****************************************************************************/
uint16_t cmos_checksum_read (void)
{ uint16_t lo, hi;
/* The checksum is stored in a big-endian format. */
hi = cmos_read_byte(cmos_checksum_index);
lo = cmos_read_byte(cmos_checksum_index + 1);
return (hi << 8) + lo;
}
/****************************************************************************
* cmos_checksum_write
*
* Set the checksum for the LinuxBIOS parameters stored in CMOS to
* 'checksum'.
****************************************************************************/
void cmos_checksum_write (uint16_t checksum)
{ unsigned char lo, hi;
/* The checksum is stored in a big-endian format. */
hi = (unsigned char) (checksum >> 8);
lo = (unsigned char) (checksum & 0x00ff);
cmos_write_byte(cmos_checksum_index, hi);
cmos_write_byte(cmos_checksum_index + 1, lo);
}
/****************************************************************************
* cmos_checksum_compute
*
* Compute a checksum for the LinuxBIOS parameter values currently stored in
* CMOS and return this checksum.
****************************************************************************/
uint16_t cmos_checksum_compute (void)
{ unsigned i, sum;
sum = 0;
for (i = cmos_checksum_start; i <= cmos_checksum_end; i++)
sum += cmos_read_byte(i);
return ~((uint16_t) (sum & 0xffff));
}
/****************************************************************************
* cmos_checksum_verify
*
* Verify that the LinuxBIOS CMOS checksum is valid. If checksum is not
* valid then print warning message and exit.
****************************************************************************/
void cmos_checksum_verify (void)
{ uint16_t computed, actual;
set_iopl(3);
computed = cmos_checksum_compute();
actual = cmos_checksum_read();
set_iopl(0);
if (computed != actual)
{ fprintf(stderr, "%s: Warning: LinuxBIOS CMOS checksum is bad.\n",
prog_name);
exit(1);
}
}

53
util/lxbios/cmos_ops.h Normal file
View File

@ -0,0 +1,53 @@
/*****************************************************************************\
* cmos_ops.h
* $Id: cmos_ops.h,v 1.3 2006/01/24 00:25:40 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef LXBIOS_CMOS_OPS_H
#define LXBIOS_CMOS_OPS_H
#include "common.h"
#include "layout.h"
#define CMOS_OP_BAD_ENUM_VALUE (CMOS_OP_RESULT_START + 0)
#define CMOS_OP_NEGATIVE_INT (CMOS_OP_RESULT_START + 1)
#define CMOS_OP_INVALID_INT (CMOS_OP_RESULT_START + 2)
#define CMOS_OP_RESERVED (CMOS_OP_RESULT_START + 3)
#define CMOS_OP_VALUE_TOO_WIDE (CMOS_OP_RESULT_START + 4)
#define CMOS_OP_NO_MATCHING_ENUM (CMOS_OP_RESULT_START + 5)
int prepare_cmos_read (const cmos_entry_t *e);
int prepare_cmos_write (const cmos_entry_t *e, const char value_str[],
unsigned long long *value);
uint16_t cmos_checksum_read (void);
void cmos_checksum_write (uint16_t checksum);
uint16_t cmos_checksum_compute (void);
void cmos_checksum_verify (void);
#endif /* LXBIOS_CMOS_OPS_H */

106
util/lxbios/common.c Normal file
View File

@ -0,0 +1,106 @@
/*****************************************************************************\
* common.c
* $Id: common.c,v 1.3 2006/01/24 00:25:40 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include "common.h"
/* basename of this program, as reported by argv[0] */
const char prog_name[] = "lxbios";
/* version of this program */
const char prog_version[] = "2.0.1";
/****************************************************************************
* get_line_from_file
*
* Get a line of input from file 'f'. Store result in 'line' which is an
* array of 'line_buf_size' bytes.
****************************************************************************/
int get_line_from_file (FILE *f, char line[], int line_buf_size)
{ if (fgets(line, line_buf_size, f) == NULL)
return LINE_EOF;
/* If the file contains a line that is too long, then it's best to let the
* user know right away rather than passing back a truncated result that
* will lead to problems later on.
*/
return (strlen(line) == ((size_t) (line_buf_size - 1))) ?
LINE_TOO_LONG : OK;
}
/****************************************************************************
* out_of_memory
*
* We ran out of memory. Print an error message and die.
****************************************************************************/
void out_of_memory (void)
{ fprintf(stderr, "%s: Out of memory.\n", prog_name);
exit(1);
}
/****************************************************************************
* usage
*
* Write a usage message to 'outfile'. If 'outfile' is 'stderr' then exit
* with a value of 1. Otherwise exit with a value of 0.
****************************************************************************/
void usage (FILE *outfile)
{ fprintf(outfile,
"Usage: %s [-y LAYOUT_FILE | -t] PARAMETER ...\n\n"
" Read/write LinuxBIOS parameters or show info from "
"LinuxBIOS table.\n\n"
" -y LAYOUT_FILE: Use CMOS layout specified by "
"LAYOUT_FILE.\n"
" -t: Use CMOS layout specified by CMOS option "
"table.\n"
" [-n] -r NAME: Show parameter NAME. If -n is given, "
"show value only.\n"
" -e NAME: Show all possible values for parameter "
"NAME.\n"
" -a: Show names and values for all "
"parameters.\n"
" -w NAME=VALUE: Set parameter NAME to VALUE.\n"
" -p INPUT_FILE: Set parameters according to INPUT_FILE.\n"
" -i: Same as -p but file contents taken from "
"standard input.\n"
" -c [VALUE]: Show CMOS checksum or set checksum to "
"VALUE.\n"
" -l [ARG]: Show LinuxBIOS table info for ARG, or "
"all ARG choices.\n"
" -d: Show low-level dump of LinuxBIOS table.\n"
" -Y: Show CMOS layout info.\n"
" -b OUTPUT_FILE: Dump CMOS memory contents to file.\n"
" -B INPUT_FILE: Write file contents to CMOS memory.\n"
" -x: Show hex dump of CMOS memory.\n"
" -X DUMPFILE: Show hex dump of CMOS dumpfile.\n"
" -v: Show version info for this program.\n"
" -h: Show this message.\n", prog_name);
exit(outfile == stderr);
}

72
util/lxbios/common.h Normal file
View File

@ -0,0 +1,72 @@
/*****************************************************************************\
* common.h
* $Id: common.h,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef LXBIOS_COMMON_H
#define LXBIOS_COMMON_H
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define FALSE 0
#define TRUE 1
#define BUG() assert(0)
#define COMMON_RESULT_START 0x10000
#define LAYOUT_RESULT_START 0x20000
#define CMOS_RESULT_START 0x30000
#define CMOS_OP_RESULT_START 0x40000
#define OK 0 /* 0 is used universally to indicate success. */
#define LINE_EOF (COMMON_RESULT_START + 0)
#define LINE_TOO_LONG (COMMON_RESULT_START + 1)
/* basename of this program, as reported by argv[0] */
extern const char prog_name[];
/* version of this program */
extern const char prog_version[];
int get_line_from_file (FILE *f, char line[], int line_buf_size);
void out_of_memory (void);
void usage (FILE *outfile);
#endif /* LXBIOS_COMMON_H */

View File

@ -0,0 +1,44 @@
/*****************************************************************************\
* compute_ip_checksum.c
* $Id: compute_ip_checksum.c,v 1.1.1.1 2005/12/02 22:35:19 dsp_llnl Exp $
\*****************************************************************************/
#include <stdint.h>
#include "ip_checksum.h"
/* Note: The contents of this file were borrowed from the LinuxBIOS source
* code which may be obtained from http://www.linuxbios.org.
* Specifically, this code was obtained from LinuxBIOS version 1.0.0.8.
*/
unsigned long compute_ip_checksum(void *addr, unsigned long length)
{
uint8_t *ptr;
volatile union {
uint8_t byte[2];
uint16_t word;
} value;
unsigned long sum;
unsigned long i;
/* In the most straight forward way possible,
* compute an ip style checksum.
*/
sum = 0;
ptr = addr;
for(i = 0; i < length; i++) {
unsigned long value;
value = ptr[i];
if (i & 1) {
value <<= 8;
}
/* Add the new value */
sum += value;
/* Wrap around the carry */
if (sum > 0xFFFF) {
sum = (sum + (sum >> 16)) & 0xFFFF;
}
}
value.byte[0] = sum & 0xff;
value.byte[1] = (sum >> 8) & 0xff;
return (~value.word) & 0xFFFF;
}

248
util/lxbios/hexdump.c Normal file
View File

@ -0,0 +1,248 @@
/*****************************************************************************\
* hexdump.c
* $Id: hexdump.c,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
\*****************************************************************************/
#include "hexdump.h"
/* hexdump.c
*
* Copyright (C) 2002
* David S. Peterson. All rights reserved.
*
* Author: David S. Peterson <dave_peterson@pobox.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions, and the entire permission notice, including
* the following disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the entire permission notice,
* including the following disclaimer in the documentation and/or other
* materials provided with the distribution.
* 3. The name(s) of the author(s) may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* ALTERNATIVELY, this product may be distributed under the terms of the GNU
* General Public License, in which case the provisions of the GPL are
* required INSTEAD OF the above restrictions. (This clause is necessary due
* to a potential bad interaction between the GPL and the restrictions
* contained in a BSD-style copyright.)
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
static void addrprint (FILE *outfile, uint64_t address, int width);
static void hexprint (FILE *outfile, unsigned char byte);
static void charprint (FILE *outfile, unsigned char byte,
unsigned char nonprintable,
is_printable_fn_t is_printable_fn);
/*--------------------------------------------------------------------------
* hexdump
*
* Write a hex dump of 'mem' to 'outfile'.
*
* parameters:
* mem: a pointer to the memory to display
* bytes: the number of bytes of data to display
* addrprint_start: The address to associate with the first byte of
* data. For instance, a value of 0 indicates that the
* first byte displayed should be labeled as byte 0.
* outfile: The place where the hex dump should be written.
* For instance, stdout or stderr may be passed here.
* format: A structure specifying how the hex dump should be
* formatted.
*--------------------------------------------------------------------------*/
void hexdump (const void *mem, int bytes, uint64_t addrprint_start,
FILE *outfile, const hexdump_format_t *format)
{ int bytes_left, index, i;
const unsigned char *p;
is_printable_fn_t is_printable_fn;
/* Quietly return if the caller asks us to do something unreasonable. */
if ((format->bytes_per_line <= 0) || (bytes < 0))
return;
is_printable_fn = format->is_printable_fn;
if (is_printable_fn == NULL)
is_printable_fn = default_is_printable_fn;
p = (const unsigned char *) mem;
index = 0;
/* Each iteration handles one full line of output. When loop terminates,
* the number of remaining bytes to display (if any) will not be enough to
* fill an entire line.
*/
for (bytes_left = bytes;
bytes_left >= format->bytes_per_line;
bytes_left -= format->bytes_per_line)
{ /* print start address for current line */
fprintf(outfile, format->indent);
addrprint(outfile, addrprint_start + index, format->addrprint_width);
fprintf(outfile, format->sep1);
/* display the bytes in hex */
for (i = 0; ; )
{ hexprint(outfile, p[index++]);
if (++i >= format->bytes_per_line)
break;
fprintf(outfile, format->sep2);
}
index -= format->bytes_per_line;
fprintf(outfile, format->sep3);
/* display the bytes as characters */
for (i = 0; i < format->bytes_per_line; i++)
charprint(outfile, p[index++], format->nonprintable,
is_printable_fn);
fprintf(outfile, "\n");
}
if (bytes_left == 0)
return;
/* print start address for last line */
fprintf(outfile, format->indent);
addrprint(outfile, addrprint_start + index, format->addrprint_width);
fprintf(outfile, format->sep1);
/* display bytes for last line in hex */
for (i = 0; i < bytes_left; i++)
{ hexprint(outfile, p[index++]);
fprintf(outfile, format->sep2);
}
index -= bytes_left;
/* pad the rest of the hex byte area with spaces */
for (; ; )
{ fprintf(outfile, " ");
if (++i >= format->bytes_per_line)
break;
fprintf(outfile, format->sep2);
}
fprintf(outfile, format->sep3);
/* display bytes for last line as characters */
for (i = 0; i < bytes_left; i++)
charprint(outfile, p[index++], format->nonprintable, is_printable_fn);
/* pad the rest of the character area with spaces */
for (; i < format->bytes_per_line; i++)
fprintf(outfile, " ");
fprintf(outfile, "\n");
}
/*--------------------------------------------------------------------------
* default_is_printable_fn
*
* Determine whether the input character is printable. The proper behavior
* for this type of function may be system-dependent. This function takes a
* conservative approach. If it is not adequate for your purposes, you can
* write your own.
*
* parameters:
* c: the input character
*
* return value:
* Return 1 if the input character is printable. Otherwise return 0.
*--------------------------------------------------------------------------*/
int default_is_printable_fn (unsigned char c)
{ return (c >= 0x20) && (c <= 0x7e); }
/*--------------------------------------------------------------------------
* addrprint
*
* Display an address as a hexadecimal number.
*
* parameters:
* outfile: the place where the output should be written
* address: the address to display
* width: The number of bytes wide the address should be displayed as.
* Must be a value from 1 to 8.
*--------------------------------------------------------------------------*/
static void addrprint (FILE *outfile, uint64_t address, int width)
{ char s[17];
int i;
/* force the user's input to be valid */
if (width < 1)
width = 1;
else if (width > 8)
width = 8;
/* convert address to string */
sprintf(s, "%016llx", (unsigned long long) address);
/* write it out, with colons separating consecutive 16-bit chunks of the
* address
*/
for (i = 16 - (2 * width); ; )
{ fprintf(outfile, "%c", s[i]);
if (++i >= 16)
break;
if ((i % 4) == 0)
fprintf(outfile, ":");
}
}
/*--------------------------------------------------------------------------
* hexprint
*
* Display a byte as a two digit hex value.
*
* parameters:
* outfile: the place where the output should be written
* byte: the byte to display
*--------------------------------------------------------------------------*/
static void hexprint (FILE *outfile, unsigned char byte)
{ static const char tbl[] =
{ '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
fprintf(outfile, "%c%c", tbl[byte >> 4], tbl[byte & 0x0f]);
}
/*--------------------------------------------------------------------------
* charprint
*
* Display a byte as its character representation.
*
* parameters:
* outfile: the place where the output should be written
* byte: the byte to display
* nonprintable: a substitute character to display if the byte
* represents a nonprintable character
* is_printable_fn: a function that returns a boolean value indicating
* whether a given character is printable
*--------------------------------------------------------------------------*/
static void charprint (FILE *outfile, unsigned char byte,
unsigned char nonprintable,
is_printable_fn_t is_printable_fn)
{ fprintf(outfile, "%c", is_printable_fn(byte) ? byte : nonprintable); }

132
util/lxbios/hexdump.h Normal file
View File

@ -0,0 +1,132 @@
/*****************************************************************************\
* hexdump.h
* $Id: hexdump.h,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
\*****************************************************************************/
#ifndef _HEXDUMP_H
#define _HEXDUMP_H
/* hexdump.h
*
* Copyright (C) 2002
* David S. Peterson. All rights reserved.
*
* Author: David S. Peterson <dave_peterson@pobox.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions, and the entire permission notice, including
* the following disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the entire permission notice,
* including the following disclaimer in the documentation and/or other
* materials provided with the distribution.
* 3. The name(s) of the author(s) may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* ALTERNATIVELY, this product may be distributed under the terms of the GNU
* General Public License, in which case the provisions of the GPL are
* required INSTEAD OF the above restrictions. (This clause is necessary due
* to a potential bad interaction between the GPL and the restrictions
* contained in a BSD-style copyright.)
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
#include <sys/types.h>
#include <stdio.h>
typedef int (*is_printable_fn_t) (unsigned char c);
/*--------------------------------------------------------------------------
* hexdump_format_t
*
* This specifies how the output of the 'hexdump' function should look.
*
* fields:
* bytes_per_line: the number of data bytes to display per line of
* output
* addrprint_width: Each line of output begins with the address of the
* first data byte displayed on that line. This
* specifies the number of bytes wide the address
* should be displayed as. This value must be from 1
* to 8.
* indent: This is a string to display at the start of each
* output line. Its purpose is to indent the output.
* sep1: This is a string to display between the address and
* the bytes of data displayed in hex. It serves as a
* separator.
* sep2: This is a string to display between individual hex
* values. It serves as a separator.
* sep3: This is a string to display between the bytes of
* data in hex and the bytes of data displayed as
* characters. It serves as a separator.
* nonprintable: This is a substitute character to display in place
* of nonprintable characters.
* is_printable_fn: This is a user-supplied function that takes a byte
* value as input and returns a boolean value
* indicating whether the corresponding character is
* printable. A value of NULL will cause
* default_is_printable_fn to be used.
*--------------------------------------------------------------------------*/
typedef struct
{ int bytes_per_line;
int addrprint_width;
const char *indent;
const char *sep1;
const char *sep2;
const char *sep3;
unsigned char nonprintable;
is_printable_fn_t is_printable_fn;
}
hexdump_format_t;
/*--------------------------------------------------------------------------
* hexdump
*
* Write a hex dump of 'mem' to 'outfile'.
*
* parameters:
* mem: a pointer to the memory to display
* bytes: the number of bytes of data to display
* addrprint_start: The address to associate with the first byte of
* data. For instance, a value of 0 indicates that the
* first byte displayed should be labeled as byte 0.
* outfile: The place where the hex dump should be written.
* For instance, stdout or stderr may be passed here.
* format: A structure specifying how the hex dump should be
* formatted.
*--------------------------------------------------------------------------*/
void hexdump (const void *mem, int bytes, uint64_t addrprint_start,
FILE *outfile, const hexdump_format_t *format);
/*--------------------------------------------------------------------------
* default_is_printable_fn
*
* Determine whether the input character is printable. The proper behavior
* for this type of function may be system-dependent. This function appears
* to work well on a Linux system. However, if it is not adequate for your
* purposes, you can write your own.
*
* parameters:
* c: the input character
*
* return value:
* Return 1 if the input character is printable. Otherwise return 0.
*--------------------------------------------------------------------------*/
int default_is_printable_fn (unsigned char c);
#endif /* _HEXDUMP_H */

280
util/lxbios/input_file.c Normal file
View File

@ -0,0 +1,280 @@
/*****************************************************************************\
* input_file.c
* $Id: input_file.c,v 1.3 2006/01/24 00:25:40 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include "common.h"
#include "input_file.h"
#include "layout.h"
#include "cmos_ops.h"
#include "cmos_lowlevel.h"
#include "reg_expr.h"
static int get_input_file_line (FILE *f, char line[], int line_buf_size);
static unsigned long long try_prepare_cmos_write (const cmos_entry_t *e,
const char value_str[]);
/* matches either a blank line or a comment line */
static const char blank_or_comment_regex[] =
/* a blank line */
"(^[[:space:]]+$)"
"|" /* or ... */
/* a line consisting of: optional whitespace followed by */
"(^[[:space:]]*"
/* a '#' character and optionally, additional characters */
"#.*$)";
/* matches an assignment line */
const char assignment_regex[] =
/* optional whitespace */
"^[[:space:]]*"
/* followed by a LinuxBIOS parameter name */
"([^[:space:]]+)"
/* followed by optional whitespace */
"[[:space:]]*"
/* followed by an '=' character */
"="
/* followed by optional whitespace */
"[[:space:]]*"
/* followed by a value that may contain embedded whitespace */
"([^[:space:]]+([[:space:]]+[^[:space:]]+)*)+"
/* followed by optional whitespace */
"[[:space:]]*$";
static int line_num;
/****************************************************************************
* process_input_file
*
* Read the contents of file 'f' and return a pointer to a list of pending
* write operations. Perform sanity checking on all write operations and
* exit with an error message if there is a problem.
****************************************************************************/
cmos_write_t * process_input_file (FILE *f)
{
static const int LINE_BUF_SIZE = 256;
static const size_t N_MATCHES = 4;
char line[LINE_BUF_SIZE];
const char *name, *value;
cmos_write_t *list, *item, **p;
regex_t blank_or_comment, assignment;
regmatch_t match[N_MATCHES];
const cmos_entry_t *e;
list = NULL;
p = &list;
compile_reg_exprs(REG_EXTENDED | REG_NEWLINE, 2, blank_or_comment_regex,
&blank_or_comment, assignment_regex, &assignment);
/* each iteration processes one line from input file */
for (line_num = 1;
get_input_file_line(f, line, LINE_BUF_SIZE) == OK;
line_num++)
{ /* skip comments and blank lines */
if (!regexec(&blank_or_comment, line, 0, NULL, 0))
continue;
/* Is this a valid assignment line? If not, then it's a syntax
* error.
*/
if (regexec(&assignment, line, N_MATCHES, match, 0))
{ fprintf(stderr, "%s: Syntax error on line %d of input file.\n",
prog_name, line_num);
exit(1);
}
/* OK, we found an assignment. Break the line into substrings
* representing the lefthand and righthand sides of the assignment.
*/
line[match[1].rm_eo] = '\0';
line[match[2].rm_eo] = '\0';
name = &line[match[1].rm_so];
value = &line[match[2].rm_so];
/* now look up the LinuxBIOS parameter name */
if (is_checksum_name(name) || (e = find_cmos_entry(name)) == NULL)
{ fprintf(stderr, "%s: Error on line %d of input file: CMOS parameter "
"%s not found.\n", prog_name, line_num, name);
exit(1);
}
/* At this point, we figure out what numeric value needs to be written
* to which location. At the same time, we perform sanity checking on
* the write operation.
*/
if ((item = (cmos_write_t *) malloc(sizeof(*item))) == NULL)
out_of_memory();
item->bit = e->bit;
item->length = e->length;
item->value = try_prepare_cmos_write(e, value);
/* Append write operation to pending write list. */
item->next = NULL;
*p = item;
p = &item->next;
}
free_reg_exprs(2, &blank_or_comment, &assignment);
return list;
}
/****************************************************************************
* do_cmos_writes
*
* 'list' is a linked list of pending CMOS write operations that have passed
* all sanity checks. Perform all write operations, destroying the list as
* we go.
****************************************************************************/
void do_cmos_writes (cmos_write_t *list)
{ cmos_write_t *item;
set_iopl(3);
while (list != NULL)
{ item = list;
list = item->next;
cmos_write(item->bit, item->length, item->value);
free(item);
}
cmos_checksum_write(cmos_checksum_compute());
set_iopl(0);
}
/****************************************************************************
* get_input_file_line
*
* Get a line of input from file 'f'. Store result in 'line' which is an
* array of 'line_buf_size' bytes. Return OK on success or an error code on
* error.
****************************************************************************/
static int get_input_file_line (FILE *f, char line[], int line_buf_size)
{ switch (get_line_from_file(f, line, line_buf_size))
{ case OK:
return OK;
case LINE_EOF:
return LINE_EOF;
case LINE_TOO_LONG:
fprintf(stderr, "%s: Error on line %d of input file: Maximum line "
"length exceeded. Max is %d characters.\n", prog_name,
line_num, line_buf_size - 2);
break;
default:
BUG();
}
exit(1);
return 1; /* keep compiler happy */
}
/****************************************************************************
* try_prepare_cmos_write
*
* Attempt to convert 'value_str' to an integer representation for storage in
* CMOS memory. On success, return the converted value. On error, exit with
* an error message.
****************************************************************************/
static unsigned long long try_prepare_cmos_write (const cmos_entry_t *e,
const char value_str[])
{ unsigned long long value;
switch (prepare_cmos_write(e, value_str, &value))
{ case OK:
return value;
case CMOS_OP_BAD_ENUM_VALUE:
fprintf(stderr, "%s: Error on line %d of input file: Bad value for "
"parameter %s.", prog_name, line_num, e->name);
break;
case CMOS_OP_NEGATIVE_INT:
fprintf(stderr, "%s: Error on line %d of input file: This program "
"does not support assignment of negative numbers to "
"LinuxBIOS parameters.", prog_name, line_num);
break;
case CMOS_OP_INVALID_INT:
fprintf(stderr, "%s: Error on line %d of input file: %s is not a "
"valid integer.", prog_name, line_num, value_str);
break;
case CMOS_OP_RESERVED:
fprintf(stderr, "%s: Error on line %d of input file: Can not modify "
"reserved LinuxBIOS parameter %s.", prog_name, line_num,
e->name);
break;
case CMOS_OP_VALUE_TOO_WIDE:
fprintf(stderr, "%s: Error on line %d of input file: Can not write "
"value %s to CMOS parameter %s that is only %d bits wide.",
prog_name, line_num, value_str, e->name, e->length);
break;
case CMOS_OP_NO_MATCHING_ENUM:
fprintf(stderr, "%s: LinuxBIOS parameter %s has no matching enums.",
prog_name, e->name);
break;
case CMOS_AREA_OUT_OF_RANGE:
fprintf(stderr, "%s: The CMOS area specified by the layout info for "
"LinuxBIOS parameter %s is out of range.", prog_name,
e->name);
break;
case CMOS_AREA_OVERLAPS_RTC:
fprintf(stderr, "%s: The CMOS area specified by the layout info for "
"LinuxBIOS parameter %s overlaps the realtime clock area.",
prog_name, e->name);
break;
case CMOS_AREA_TOO_WIDE:
fprintf(stderr, "%s: The CMOS area specified by the layout info for "
"LinuxBIOS parameter %s is too wide.",
prog_name, e->name);
break;
default:
fprintf(stderr,
"%s: Unknown error encountered while attempting to modify "
"LinuxBIOS parameter %s.", prog_name, e->name);
break;
}
fprintf(stderr, " No CMOS writes performed.\n");
exit(1);
return 0; /* keep compiler happy */
}

56
util/lxbios/input_file.h Normal file
View File

@ -0,0 +1,56 @@
/*****************************************************************************\
* input_file.h
* $Id: input_file.h,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef LXBIOS_INPUT_FILE_H
#define LXBIOS_INPUT_FILE_H
#include "common.h"
typedef struct cmos_write_t cmos_write_t;
/* This represents a pending CMOS write operation. When changing multiple
* CMOS parameter values, we first represent the changes as a list of pending
* write operations. This allows us to sanity check all write operations
* before any of them are performed.
*/
struct cmos_write_t
{ unsigned bit;
unsigned length;
unsigned long long value;
cmos_write_t *next;
};
cmos_write_t * process_input_file (FILE *f);
void do_cmos_writes (cmos_write_t *list);
extern const char assignment_regex[];
#endif /* LXBIOS_INPUT_FILE_H */

16
util/lxbios/ip_checksum.h Normal file
View File

@ -0,0 +1,16 @@
/*****************************************************************************\
* ip_checksum.h
* $Id: ip_checksum.h,v 1.1.1.1 2005/12/02 22:35:19 dsp_llnl Exp $
\*****************************************************************************/
#ifndef IP_CHECKSUM_H
#define IP_CHECKSUM_H
/* Note: The contents of this file were borrowed from the LinuxBIOS source
* code which may be obtained from http://www.linuxbios.org.
* Specifically, this code was obtained from LinuxBIOS version 1.0.0.8.
*/
unsigned long compute_ip_checksum(void *addr, unsigned long length);
#endif /* IP_CHECKSUM_H */

513
util/lxbios/layout.c Normal file
View File

@ -0,0 +1,513 @@
/*****************************************************************************\
* layout.c
* $Id: layout.c,v 1.2 2006/01/24 00:25:40 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include "common.h"
#include "layout.h"
#include "cmos_lowlevel.h"
typedef struct cmos_entry_item_t cmos_entry_item_t;
struct cmos_entry_item_t
{ cmos_entry_t item;
cmos_entry_item_t *next;
};
typedef struct cmos_enum_item_t cmos_enum_item_t;
struct cmos_enum_item_t
{ cmos_enum_t item;
cmos_enum_item_t *next;
};
static void default_cmos_layout_get_fn (void);
static int areas_overlap (unsigned area_0_start, unsigned area_0_length,
unsigned area_1_start, unsigned area_1_length);
static int entries_overlap (const cmos_entry_t *p, const cmos_entry_t *q);
static const cmos_enum_item_t * find_first_cmos_enum_id (unsigned config_id);
const char checksum_param_name[] = "check_sum";
/* Newer versions of LinuxBIOS store the 3 pieces of information below in the
* LinuxBIOS table so we don't have to rely on hardcoded values.
*/
/* This is the offset from the start of CMOS of the first byte that the
* checksum is calculated over.
*/
#define CMOS_CHECKSUM_START 49
/* This is the offset from the start of CMOS of the last byte that the
* checksum is calculated over.
*/
#define CMOS_CHECKSUM_END 125
/* This is the offset from the start of CMOS where the LinuxBIOS checksum is
* stored.
*/
#define CMOS_CHECKSUM_INDEX 126
/* index of first byte of checksummed area */
unsigned cmos_checksum_start = CMOS_CHECKSUM_START;
/* index of last byte of checksummed area */
unsigned cmos_checksum_end = CMOS_CHECKSUM_END;
/* index of first byte of CMOS checksum (a big-endian 16-bit value) */
unsigned cmos_checksum_index = CMOS_CHECKSUM_INDEX;
/* List is sorted in ascending order according to 'bit' field in
* cmos_entry_t.
*/
static cmos_entry_item_t *cmos_entry_list = NULL;
/* List is sorted in ascending order: first by 'config_id' and then by
* 'value'.
*/
static cmos_enum_item_t *cmos_enum_list = NULL;
static cmos_layout_get_fn_t cmos_layout_get_fn = default_cmos_layout_get_fn;
/****************************************************************************
* entries_overlap
*
* Return 1 if cmos entries 'p' and 'q' overlap. Else return 0.
****************************************************************************/
static inline int entries_overlap (const cmos_entry_t *p,
const cmos_entry_t *q)
{ return areas_overlap(p->bit, p->length, q->bit, q->length); }
/****************************************************************************
* cmos_entry_to_const_item
*
* Return a pointer to the cmos_entry_item_t that 'p' is embedded within.
****************************************************************************/
static inline const cmos_entry_item_t * cmos_entry_to_const_item
(const cmos_entry_t *p)
{ static const cmos_entry_t *pos = &((cmos_entry_item_t *) 0)->item;
unsigned long offset, address;
offset = (unsigned long) pos;
address = ((unsigned long) p) - offset;
return (const cmos_entry_item_t *) address;
}
/****************************************************************************
* cmos_enum_to_const_item
*
* Return a pointer to the cmos_enum_item_t that 'p' is embedded within.
****************************************************************************/
static inline const cmos_enum_item_t * cmos_enum_to_const_item
(const cmos_enum_t *p)
{ static const cmos_enum_t *pos = &((cmos_enum_item_t *) 0)->item;
unsigned long offset, address;
offset = (unsigned long) pos;
address = ((unsigned long) p) - offset;
return (const cmos_enum_item_t *) address;
}
/****************************************************************************
* register_cmos_layout_get_fn
*
* Set 'fn' as the function that will be called to retrieve CMOS layout
* information.
****************************************************************************/
void register_cmos_layout_get_fn (cmos_layout_get_fn_t fn)
{ cmos_layout_get_fn = fn; }
/****************************************************************************
* get_cmos_layout
*
* Retrieve CMOS layout information and store it in our internal repository.
****************************************************************************/
void get_cmos_layout (void)
{ cmos_layout_get_fn(); }
/****************************************************************************
* add_cmos_entry
*
* Attempt to add CMOS entry 'e' to our internal repository of layout
* information. Return OK on success or an error code on failure. If
* operation fails because 'e' overlaps an existing CMOS entry, '*conflict'
* will be set to point to the overlapping entry.
****************************************************************************/
int add_cmos_entry (const cmos_entry_t *e, const cmos_entry_t **conflict)
{ cmos_entry_item_t *item, *prev, *new_entry;
*conflict = NULL;
if (e->length < 1)
return LAYOUT_ENTRY_BAD_LENGTH;
if ((new_entry = (cmos_entry_item_t *) malloc(sizeof(*new_entry))) == NULL)
out_of_memory();
new_entry->item = *e;
if (cmos_entry_list == NULL)
{ new_entry->next = NULL;
cmos_entry_list = new_entry;
return OK;
}
/* Find place in list to insert new entry. List is sorted in ascending
* order.
*/
for (item = cmos_entry_list, prev = NULL;
(item != NULL) && (item->item.bit < e->bit);
prev = item, item = item->next);
if (prev == NULL)
{ if (entries_overlap(e, &cmos_entry_list->item))
{ *conflict = &cmos_entry_list->item;
goto fail;
}
new_entry->next = cmos_entry_list;
cmos_entry_list = new_entry;
return OK;
}
if (entries_overlap(&prev->item, e))
{ *conflict = &prev->item;
goto fail;
}
if ((item != NULL) && entries_overlap(e, &item->item))
{ *conflict = &item->item;
goto fail;
}
new_entry->next = item;
prev->next = new_entry;
return OK;
fail:
free(new_entry);
return LAYOUT_ENTRY_OVERLAP;
}
/****************************************************************************
* find_cmos_entry
*
* Search for a CMOS entry whose name is 'name'. Return pointer to matching
* entry or NULL if entry not found.
****************************************************************************/
const cmos_entry_t * find_cmos_entry (const char name[])
{ cmos_entry_item_t *item;
for (item = cmos_entry_list; item != NULL; item = item->next)
{ if (!strcmp(item->item.name, name))
return &item->item;
}
return NULL;
}
/****************************************************************************
* first_cmos_entry
*
* Return a pointer to the first CMOS entry in our list or NULL if list is
* empty.
****************************************************************************/
const cmos_entry_t * first_cmos_entry (void)
{ return (cmos_entry_list == NULL) ? NULL : &cmos_entry_list->item; }
/****************************************************************************
* next_cmos_entry
*
* Return a pointer to next entry in list after 'last' or NULL if no more
* entries.
****************************************************************************/
const cmos_entry_t * next_cmos_entry (const cmos_entry_t *last)
{ const cmos_entry_item_t *last_item, *next_item;
last_item = cmos_entry_to_const_item(last);
next_item = last_item->next;
return (next_item == NULL) ? NULL : &next_item->item;
}
/****************************************************************************
* add_cmos_enum
*
* Attempt to add CMOS enum 'e' to our internal repository of layout
* information. Return OK on success or an error code on failure.
****************************************************************************/
int add_cmos_enum (const cmos_enum_t *e)
{ cmos_enum_item_t *item, *prev, *new_enum;
if ((new_enum = (cmos_enum_item_t *) malloc(sizeof(*new_enum))) == NULL)
out_of_memory();
new_enum->item = *e;
if (cmos_enum_list == NULL)
{ new_enum->next = NULL;
cmos_enum_list = new_enum;
return OK;
}
/* The list of enums is sorted in ascending order, first by 'config_id' and
* then by 'value'. Look for the first enum whose 'config_id' field
* matches 'e'.
*/
for (item = cmos_enum_list, prev = NULL;
(item != NULL) && (item->item.config_id < e->config_id);
prev = item, item = item->next);
if (item == NULL)
{ new_enum->next = NULL;
prev->next = new_enum;
return OK;
}
if (item->item.config_id > e->config_id)
{ new_enum->next = item;
if (prev == NULL)
cmos_enum_list = new_enum;
else
prev->next = new_enum;
return OK;
}
/* List already contains at least one enum whose 'config_id' matches 'e'.
* Now find proper place to insert 'e' based on 'value'.
*/
while (item->item.value < e->value)
{ prev = item;
item = item->next;
if ((item == NULL) || (item->item.config_id != e->config_id))
{ new_enum->next = item;
prev->next = new_enum;
return OK;
}
}
if (item->item.value == e->value)
{ free(new_enum);
return LAYOUT_DUPLICATE_ENUM;
}
new_enum->next = item;
if (prev == NULL)
cmos_enum_list = new_enum;
else
prev->next = new_enum;
return OK;
}
/****************************************************************************
* find_cmos_enum
*
* Search for an enum that matches 'config_id' and 'value'. If found, return
* a pointer to the mathcing enum. Else return NULL.
****************************************************************************/
const cmos_enum_t * find_cmos_enum (unsigned config_id,
unsigned long long value)
{ const cmos_enum_item_t *item;
if ((item = find_first_cmos_enum_id(config_id)) == NULL)
return NULL;
while (item->item.value < value)
{ item = item->next;
if ((item == NULL) || (item->item.config_id != config_id))
return NULL;
}
return (item->item.value == value) ? &item->item : NULL;
}
/****************************************************************************
* first_cmos_enum
*
* Return a pointer to the first CMOS enum in our list or NULL if list is
* empty.
****************************************************************************/
const cmos_enum_t * first_cmos_enum (void)
{ return (cmos_enum_list == NULL) ? NULL : &cmos_enum_list->item; }
/****************************************************************************
* next_cmos_enum
*
* Return a pointer to next enum in list after 'last' or NULL if no more
* enums.
****************************************************************************/
const cmos_enum_t * next_cmos_enum (const cmos_enum_t *last)
{ const cmos_enum_item_t *last_item, *next_item;
last_item = cmos_enum_to_const_item(last);
next_item = last_item->next;
return (next_item == NULL) ? NULL : &next_item->item;
}
/****************************************************************************
* first_cmos_enum_id
*
* Return a pointer to the first CMOS enum in our list that matches
* 'config_id' or NULL if there are no matching enums.
****************************************************************************/
const cmos_enum_t * first_cmos_enum_id (unsigned config_id)
{ const cmos_enum_item_t *item;
item = find_first_cmos_enum_id(config_id);
return (item == NULL) ? NULL : &item->item;
}
/****************************************************************************
* next_cmos_enum_id
*
* Return a pointer to next enum in list after 'last' that matches the
* 'config_id' field of 'last' or NULL if there are no more matching enums.
****************************************************************************/
const cmos_enum_t * next_cmos_enum_id (const cmos_enum_t *last)
{ const cmos_enum_item_t *item;
item = cmos_enum_to_const_item(last)->next;
return ((item == NULL) || (item->item.config_id != last->config_id)) ?
NULL : &item->item;
}
/****************************************************************************
* is_checksum_name
*
* Return 1 if 'name' matches the name of the parameter representing the CMOS
* checksum. Else return 0.
****************************************************************************/
int is_checksum_name (const char name[])
{ return !strcmp(name, checksum_param_name); }
/****************************************************************************
* checksum_layout_to_bytes
*
* On entry, '*layout' contains checksum-related layout information expressed
* in bits. Perform sanity checking on the information and convert it from
* bit positions to byte positions. Return OK on success or an error code if
* a sanity check fails.
****************************************************************************/
int checksum_layout_to_bytes (cmos_checksum_layout_t *layout)
{ unsigned start, end, index;
start = layout->summed_area_start;
end = layout->summed_area_end;
index = layout->checksum_at;
if (start % 8)
return LAYOUT_SUMMED_AREA_START_NOT_ALIGNED;
if ((end % 8) != 7)
return LAYOUT_SUMMED_AREA_END_NOT_ALIGNED;
if (index % 8)
return LAYOUT_CHECKSUM_LOCATION_NOT_ALIGNED;
if (end <= start)
return LAYOUT_INVALID_SUMMED_AREA;
/* Convert bit positions to byte positions. */
start /= 8;
end /= 8; /* equivalent to "end = ((end - 7) / 8)" */
index /= 8;
if (verify_cmos_byte_index(start) || verify_cmos_byte_index(end))
return LAYOUT_SUMMED_AREA_OUT_OF_RANGE;
if (verify_cmos_byte_index(index))
return LAYOUT_CHECKSUM_LOCATION_OUT_OF_RANGE;
/* checksum occupies 16 bits */
if (areas_overlap(start, end - start + 1, index, index + 1))
return LAYOUT_CHECKSUM_OVERLAPS_SUMMED_AREA;
layout->summed_area_start = start;
layout->summed_area_end = end;
layout->checksum_at = index;
return OK;
}
/****************************************************************************
* checksum_layout_to_bits
*
* On entry, '*layout' contains checksum-related layout information expressed
* in bytes. Convert this information to bit positions.
****************************************************************************/
void checksum_layout_to_bits (cmos_checksum_layout_t *layout)
{ layout->summed_area_start *= 8;
layout->summed_area_end = (layout->summed_area_end * 8) + 7;
layout->checksum_at *= 8;
}
/****************************************************************************
* default_cmos_layout_get_fn
*
* If this function is ever called, it means that an appropriate callback for
* obtaining CMOS layout information was not set before attempting to
* retrieve layout information.
****************************************************************************/
static void default_cmos_layout_get_fn (void)
{ BUG(); }
/****************************************************************************
* areas_overlap
*
* Return 1 if the two given areas overlap. Else return 0.
****************************************************************************/
static int areas_overlap (unsigned area_0_start, unsigned area_0_length,
unsigned area_1_start, unsigned area_1_length)
{ unsigned area_0_end, area_1_end;
area_0_end = area_0_start + area_0_length - 1;
area_1_end = area_1_start + area_1_length - 1;
return ((area_1_start <= area_0_end) && (area_0_start <= area_1_end));
}
/****************************************************************************
* find_first_cmos_enum_id
*
* Return a pointer to the first item in our list of enums that matches
* 'config_id'. Return NULL if there is no matching enum.
****************************************************************************/
static const cmos_enum_item_t * find_first_cmos_enum_id (unsigned config_id)
{ cmos_enum_item_t *item;
for (item = cmos_enum_list;
(item != NULL) && (item->item.config_id < config_id);
item = item->next);
return ((item == NULL) || (item->item.config_id > config_id)) ?
NULL : item;
}

114
util/lxbios/layout.h Normal file
View File

@ -0,0 +1,114 @@
/*****************************************************************************\
* layout.h
* $Id: layout.h,v 1.2 2006/01/24 00:25:40 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef LXBIOS_LAYOUT_H
#define LXBIOS_LAYOUT_H
#include "common.h"
#include "linuxbios_tables.h"
#define LAYOUT_ENTRY_OVERLAP (LAYOUT_RESULT_START + 0)
#define LAYOUT_ENTRY_BAD_LENGTH (LAYOUT_RESULT_START + 1)
#define LAYOUT_DUPLICATE_ENUM (LAYOUT_RESULT_START + 2)
#define LAYOUT_SUMMED_AREA_START_NOT_ALIGNED (LAYOUT_RESULT_START + 3)
#define LAYOUT_SUMMED_AREA_END_NOT_ALIGNED (LAYOUT_RESULT_START + 4)
#define LAYOUT_CHECKSUM_LOCATION_NOT_ALIGNED (LAYOUT_RESULT_START + 5)
#define LAYOUT_INVALID_SUMMED_AREA (LAYOUT_RESULT_START + 6)
#define LAYOUT_CHECKSUM_OVERLAPS_SUMMED_AREA (LAYOUT_RESULT_START + 7)
#define LAYOUT_SUMMED_AREA_OUT_OF_RANGE (LAYOUT_RESULT_START + 8)
#define LAYOUT_CHECKSUM_LOCATION_OUT_OF_RANGE (LAYOUT_RESULT_START + 9)
typedef enum
{ CMOS_ENTRY_ENUM,
CMOS_ENTRY_HEX,
CMOS_ENTRY_RESERVED
}
cmos_entry_config_t;
/* This represents a CMOS parameter. */
typedef struct
{ unsigned bit;
unsigned length;
cmos_entry_config_t config;
unsigned config_id;
char name[CMOS_MAX_NAME_LENGTH];
}
cmos_entry_t;
/* This represents a possible value for a CMOS parameter of type
* CMOS_ENTRY_ENUM.
*/
typedef struct
{ unsigned config_id;
unsigned long long value;
char text[CMOS_MAX_TEXT_LENGTH];
}
cmos_enum_t;
/* This represents the location of the CMOS checksum and the area over which
* it is computed. Depending on the context, the values may be represented as
* either bit positions or byte positions.
*/
typedef struct
{ unsigned summed_area_start; /* first checksummed location */
unsigned summed_area_end; /* last checksummed location */
unsigned checksum_at; /* location of checksum */
}
cmos_checksum_layout_t;
extern const char checksum_param_name[];
extern unsigned cmos_checksum_start;
extern unsigned cmos_checksum_end;
extern unsigned cmos_checksum_index;
typedef void (*cmos_layout_get_fn_t) (void);
void register_cmos_layout_get_fn (cmos_layout_get_fn_t fn);
void get_cmos_layout (void);
int add_cmos_entry (const cmos_entry_t *e, const cmos_entry_t **conflict);
const cmos_entry_t * find_cmos_entry (const char name[]);
const cmos_entry_t * first_cmos_entry (void);
const cmos_entry_t * next_cmos_entry (const cmos_entry_t *last);
int add_cmos_enum (const cmos_enum_t *e);
const cmos_enum_t * find_cmos_enum (unsigned config_id,
unsigned long long value);
const cmos_enum_t * first_cmos_enum (void);
const cmos_enum_t * next_cmos_enum (const cmos_enum_t *last);
const cmos_enum_t * first_cmos_enum_id (unsigned config_id);
const cmos_enum_t * next_cmos_enum_id (const cmos_enum_t *last);
int is_checksum_name (const char name[]);
int checksum_layout_to_bytes (cmos_checksum_layout_t *layout);
void checksum_layout_to_bits (cmos_checksum_layout_t *layout);
#endif /* LXBIOS_LAYOUT_H */

848
util/lxbios/layout_file.c Normal file
View File

@ -0,0 +1,848 @@
/*****************************************************************************\
* layout_file.c
* $Id: layout_file.c,v 1.3 2006/01/24 00:25:40 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include "common.h"
#include "layout_file.h"
#include "layout.h"
#include "cmos_lowlevel.h"
#include "reg_expr.h"
static void process_layout_file (FILE *f);
static void skip_past_start (FILE *f);
static int process_entry (FILE *f, int skip_add);
static int process_enum (FILE *f, int skip_add);
static void process_checksum_info (FILE *f);
static void skip_remaining_lines (FILE *f);
static void create_entry (cmos_entry_t *cmos_entry,
const char start_bit_str[], const char length_str[],
const char config_str[], const char config_id_str[],
const char name_str[]);
static void try_add_layout_file_entry (const cmos_entry_t *cmos_entry);
static void create_enum (cmos_enum_t *cmos_enum, const char id_str[],
const char value_str[], const char text_str[]);
static void try_add_cmos_enum (const cmos_enum_t *cmos_enum);
static void set_checksum_info (const char start_str[], const char end_str[],
const char index_str[]);
static char cmos_entry_char_value (cmos_entry_config_t config);
static int get_layout_file_line (FILE *f, char line[], int line_buf_size);
static unsigned string_to_unsigned (const char str[], const char str_name[]);
static unsigned long string_to_unsigned_long (const char str[],
const char str_name[]);
static unsigned long do_string_to_unsigned_long (const char str[],
const char str_name[],
const char blurb[]);
/* matches either a blank line or a comment line */
static const char blank_or_comment_regex[] =
/* a blank line */
"(^[[:space:]]+$)"
"|" /* or ... */
/* a line consisting of: optional whitespace followed by */
"(^[[:space:]]*"
/* a '#' character and optionally, additional characters */
"#.*$)";
static regex_t blank_or_comment_expr;
/* matches the line in a CMOS layout file indicating the start of the
* "entries" section.
*/
static const char start_entries_regex[] =
/* optional whitespace */
"^[[:space:]]*"
/* followed by "entries" */
"entries"
/* followed by optional whitespace */
"[[:space:]]*$";
static regex_t start_entries_expr;
/* matches the line in a CMOS layout file indicating the start of the
* "enumerations" section
*/
static const char start_enums_regex[] =
/* optional whitespace */
"^[[:space:]]*"
/* followed by "enumerations" */
"enumerations"
/* followed by optional whitespace */
"[[:space:]]*$";
static regex_t start_enums_expr;
/* matches the line in a CMOS layout file indicating the start of the
* "checksums" section
*/
static const char start_checksums_regex[] =
/* optional whitespace */
"^[[:space:]]*"
/* followed by "checksums" */
"checksums"
/* followed by optional whitespace */
"[[:space:]]*$";
static regex_t start_checksums_expr;
/* matches a line in a CMOS layout file specifying a CMOS entry */
static const char entries_line_regex[] =
/* optional whitespace */
"^[[:space:]]*"
/* followed by a chunk of nonwhitespace for start-bit field */
"([^[:space:]]+)"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for length field */
"([^[:space:]]+)"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for config field */
"([^[:space:]]+)"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for config-ID field */
"([^[:space:]]+)"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for name field */
"([^[:space:]]+)"
/* followed by optional whitespace */
"[[:space:]]*$";
static regex_t entries_line_expr;
/* matches a line in a CMOS layout file specifying a CMOS enumeration */
static const char enums_line_regex[] =
/* optional whitespace */
"^[[:space:]]*"
/* followed by a chunk of nonwhitespace for ID field */
"([^[:space:]]+)"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for value field */
"([^[:space:]]+)"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for text field */
"([^[:space:]]+)"
/* followed by optional whitespace */
"[[:space:]]*$";
static regex_t enums_line_expr;
/* matches the line in a CMOS layout file specifying CMOS checksum
* information
*/
static const char checksum_line_regex[] =
/* optional whitespace */
"^[[:space:]]*"
/* followed by "checksum" */
"checksum"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for first bit of summed area */
"([^[:space:]]+)"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for last bit of summed area */
"([^[:space:]]+)"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for checksum location bit */
"([^[:space:]]+)"
/* followed by optional whitespace */
"[[:space:]]*$";
static regex_t checksum_line_expr;
static const int LINE_BUF_SIZE = 256;
static int line_num;
static const char *layout_filename = NULL;
/****************************************************************************
* set_layout_filename
*
* Set the name of the file we will obtain CMOS layout information from.
****************************************************************************/
void set_layout_filename (const char filename[])
{ layout_filename = filename; }
/****************************************************************************
* get_layout_from_file
*
* Read CMOS layout information from the user-specified CMOS layout file.
****************************************************************************/
void get_layout_from_file (void)
{ FILE *f;
assert(layout_filename != NULL);
if ((f = fopen(layout_filename, "r")) == NULL)
{ fprintf(stderr, "%s: Can not open CMOS layout file %s for reading: "
"%s\n", prog_name, layout_filename, strerror(errno));
exit(1);
}
process_layout_file(f);
fclose(f);
}
/****************************************************************************
* write_cmos_layout
*
* Write CMOS layout information to file 'f'. The output is written in the
* format that CMOS layout files adhere to.
****************************************************************************/
void write_cmos_layout (FILE *f)
{ const cmos_entry_t *cmos_entry;
const cmos_enum_t *cmos_enum;
cmos_checksum_layout_t layout;
fprintf(f, "entries\n");
for (cmos_entry = first_cmos_entry();
cmos_entry != NULL;
cmos_entry = next_cmos_entry(cmos_entry))
fprintf(f, "%u %u %c %u %s\n", cmos_entry->bit, cmos_entry->length,
cmos_entry_char_value(cmos_entry->config),
cmos_entry->config_id, cmos_entry->name);
fprintf(f, "\nenumerations\n");
for (cmos_enum = first_cmos_enum();
cmos_enum != NULL;
cmos_enum = next_cmos_enum(cmos_enum))
fprintf(f, "%u %llu %s\n", cmos_enum->config_id, cmos_enum->value,
cmos_enum->text);
layout.summed_area_start = cmos_checksum_start;
layout.summed_area_end = cmos_checksum_end;
layout.checksum_at = cmos_checksum_index;
checksum_layout_to_bits(&layout);
fprintf(f, "\nchecksums\nchecksum %u %u %u\n", layout.summed_area_start,
layout.summed_area_end, layout.checksum_at);
}
/****************************************************************************
* process_layout_file
*
* Read CMOS layout information from file 'f' and add it to our internal
* repository.
****************************************************************************/
static void process_layout_file (FILE *f)
{ compile_reg_exprs(REG_EXTENDED | REG_NEWLINE, 7,
blank_or_comment_regex, &blank_or_comment_expr,
start_entries_regex, &start_entries_expr,
entries_line_regex, &entries_line_expr,
start_enums_regex, &start_enums_expr,
enums_line_regex, &enums_line_expr,
start_checksums_regex, &start_checksums_expr,
checksum_line_regex, &checksum_line_expr);
line_num = 1;
skip_past_start(f);
/* Skip past all entries. We will process these later when we make a
* second pass through the file.
*/
while (!process_entry(f, 1));
/* Process all enums, adding them to our internal repository as we go. */
if (process_enum(f, 0))
{ fprintf(stderr, "%s: Error: CMOS layout file contains no "
"enumerations.\n", prog_name);
exit(1);
}
while (!process_enum(f, 0));
/* Go back to start of file. */
line_num = 1;
fseek(f, 0, SEEK_SET);
skip_past_start(f);
/* Process all entries, adding them to the repository as we go. We must
* add the entries after the enums, even though they appear in the layout
* file before the enums. This is because the entries are sanity checked
* against the enums as they are added.
*/
if (process_entry(f, 0))
{ fprintf(stderr, "%s: Error: CMOS layout file contains no entries.\n",
prog_name);
exit(1);
}
while (!process_entry(f, 0));
/* Skip past all enums. They have already been processed. */
while (!process_enum(f, 1));
/* Process CMOS checksum info. */
process_checksum_info(f);
/* See if there are any lines left to process. If so, verify that they are
* all either blank lines or comments.
*/
skip_remaining_lines(f);
free_reg_exprs(7, &blank_or_comment_expr, &start_entries_expr,
&entries_line_expr, &start_enums_expr,
&enums_line_expr, &start_checksums_expr,
&checksum_line_expr);
}
/****************************************************************************
* skip_past_start
*
* Skip past the line that marks the start of the "entries" section.
****************************************************************************/
static void skip_past_start (FILE *f)
{ char line[LINE_BUF_SIZE];
for (; ; line_num++)
{ if (get_layout_file_line(f, line, LINE_BUF_SIZE))
{ fprintf(stderr,
"%s: \"entries\" line not found in CMOS layout file.\n",
prog_name);
exit(1);
}
if (!regexec(&blank_or_comment_expr, line, 0, NULL, 0))
continue;
if (!regexec(&start_entries_expr, line, 0, NULL, 0))
break;
fprintf(stderr, "%s: Syntax error on line %d of CMOS layout file. "
"\"entries\" line expected.\n", prog_name, line_num);
exit(1);
}
line_num++;
}
/****************************************************************************
* process_entry
*
* Get an entry from "entries" section of file and add it to our repository
* of layout information. Return 0 if an entry was found and processed.
* Return 1 if there are no more entries.
****************************************************************************/
static int process_entry (FILE *f, int skip_add)
{ static const size_t N_MATCHES = 6;
char line[LINE_BUF_SIZE];
regmatch_t match[N_MATCHES];
cmos_entry_t cmos_entry;
int result;
result = 1;
for (; ; line_num++)
{ if (get_layout_file_line(f, line, LINE_BUF_SIZE))
{ fprintf(stderr,
"%s: Unexpected end of CMOS layout file reached while "
"reading \"entries\" section.\n", prog_name);
exit(1);
}
if (!regexec(&blank_or_comment_expr, line, 0, NULL, 0))
continue;
if (regexec(&entries_line_expr, line, N_MATCHES, match, 0))
{ if (regexec(&start_enums_expr, line, 0, NULL, 0))
{ fprintf(stderr, "%s: Syntax error on line %d of CMOS layout "
"file.\n", prog_name, line_num);
exit(1);
}
break; /* start of enumerations reached: no more entries */
}
result = 0; /* next layout entry found */
if (skip_add)
break;
line[match[1].rm_eo] = '\0';
line[match[2].rm_eo] = '\0';
line[match[3].rm_eo] = '\0';
line[match[4].rm_eo] = '\0';
line[match[5].rm_eo] = '\0';
create_entry(&cmos_entry, &line[match[1].rm_so], &line[match[2].rm_so],
&line[match[3].rm_so], &line[match[4].rm_so],
&line[match[5].rm_so]);
try_add_layout_file_entry(&cmos_entry);
break;
}
line_num++;
return result;
}
/****************************************************************************
* process_enum
*
* Get an enuneration from "enumerations" section of file and add it to our
* repository of layout information. Return 0 if an enumeration was found
* and processed. Return 1 if there are no more enumerations.
****************************************************************************/
static int process_enum (FILE *f, int skip_add)
{ static const size_t N_MATCHES = 4;
char line[LINE_BUF_SIZE];
regmatch_t match[N_MATCHES];
cmos_enum_t cmos_enum;
int result;
result = 1;
for (; ; line_num++)
{ if (get_layout_file_line(f, line, LINE_BUF_SIZE))
{ fprintf(stderr,
"%s: Unexpected end of CMOS layout file reached while "
"reading \"enumerations\" section.\n", prog_name);
exit(1);
}
if (!regexec(&blank_or_comment_expr, line, 0, NULL, 0))
continue;
if (regexec(&enums_line_expr, line, N_MATCHES, match, 0))
{ if (regexec(&start_checksums_expr, line, 0, NULL, 0))
{ fprintf(stderr, "%s: Syntax error on line %d of CMOS layout "
"file.\n", prog_name, line_num);
exit(1);
}
break; /* start of checksums reached: no more enumerations */
}
result = 0; /* next layout enumeration found */
if (skip_add)
break;
line[match[1].rm_eo] = '\0';
line[match[2].rm_eo] = '\0';
line[match[3].rm_eo] = '\0';
create_enum(&cmos_enum, &line[match[1].rm_so], &line[match[2].rm_so],
&line[match[3].rm_so]);
try_add_cmos_enum(&cmos_enum);
break;
}
line_num++;
return result;
}
/****************************************************************************
* process_checksum_info
*
* Get line conatining CMOS checksum information.
****************************************************************************/
static void process_checksum_info (FILE *f)
{ static const size_t N_MATCHES = 4;
char line[LINE_BUF_SIZE];
regmatch_t match[N_MATCHES];
for (; ; line_num++)
{ if (get_layout_file_line(f, line, LINE_BUF_SIZE))
{ fprintf(stderr,
"%s: Unexpected end of CMOS layout file reached while "
"reading \"checksums\" section.\n", prog_name);
exit(1);
}
if (!regexec(&blank_or_comment_expr, line, 0, NULL, 0))
continue;
if (regexec(&checksum_line_expr, line, N_MATCHES, match, 0))
{ fprintf(stderr, "%s: Syntax error on line %d of CMOS layout "
"file. \"checksum\" line expected.\n", prog_name,
line_num);
exit(1);
}
/* checksum line found */
line[match[1].rm_eo] = '\0';
line[match[2].rm_eo] = '\0';
line[match[3].rm_eo] = '\0';
set_checksum_info(&line[match[1].rm_so], &line[match[2].rm_so],
&line[match[3].rm_so]);
break;
}
}
/****************************************************************************
* skip_remaining_lines
*
* Get any remaining lines of unprocessed input. Complain if we find a line
* that contains anything other than comments and whitespace.
****************************************************************************/
static void skip_remaining_lines (FILE *f)
{ char line[LINE_BUF_SIZE];
for (line_num++;
get_layout_file_line(f, line, LINE_BUF_SIZE) == OK;
line_num++)
{ if (regexec(&blank_or_comment_expr, line, 0, NULL, 0))
{ fprintf(stderr, "%s: Syntax error on line %d of CMOS layout file: "
"Only comments and/or whitespace allowed after "
"\"checksum\" line.\n", prog_name, line_num);
exit(1);
}
}
}
/****************************************************************************
* create_entry
*
* Create a CMOS entry structure representing the given information. Perform
* sanity checking on input parameters.
****************************************************************************/
static void create_entry (cmos_entry_t *cmos_entry,
const char start_bit_str[], const char length_str[],
const char config_str[], const char config_id_str[],
const char name_str[])
{ cmos_entry->bit = string_to_unsigned(start_bit_str, "start-bit");
cmos_entry->length = string_to_unsigned(length_str, "length");
if (config_str[1] != '\0')
goto bad_config_str;
switch (config_str[0])
{ case 'e':
cmos_entry->config = CMOS_ENTRY_ENUM;
break;
case 'h':
cmos_entry->config = CMOS_ENTRY_HEX;
break;
case 'r':
cmos_entry->config = CMOS_ENTRY_RESERVED;
break;
default:
goto bad_config_str;
}
cmos_entry->config_id = string_to_unsigned(config_id_str, "config-ID");
if (strlen(name_str) >= CMOS_MAX_NAME_LENGTH)
{ fprintf(stderr, "%s: Error on line %d of CMOS layout file: name too "
"long (max length is %d).\n", prog_name, line_num,
CMOS_MAX_NAME_LENGTH - 1);
exit(1);
}
strcpy(cmos_entry->name, name_str);
return;
bad_config_str:
fprintf(stderr, "%s: Error on line %d of CMOS layout file: 'e', 'h', or "
"'r' expected for config value.\n", prog_name, line_num);
exit(1);
}
/****************************************************************************
* try_add_layout_file_entry
*
* Attempt to add the given CMOS entry to our internal repository. Exit with
* an error message on failure.
****************************************************************************/
static void try_add_layout_file_entry (const cmos_entry_t *cmos_entry)
{ const cmos_entry_t *conflict;
switch (add_cmos_entry(cmos_entry, &conflict))
{ case OK:
return;
case CMOS_AREA_OUT_OF_RANGE:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. Area "
"covered by entry %s is out of range.\n", prog_name,
line_num, cmos_entry->name);
break;
case CMOS_AREA_TOO_WIDE:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. Area "
"covered by entry %s is too wide.\n", prog_name, line_num,
cmos_entry->name);
break;
case LAYOUT_ENTRY_OVERLAP:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. Layouts "
"overlap for entries %s and %s.\n", prog_name, line_num,
cmos_entry->name, conflict->name);
break;
case LAYOUT_ENTRY_BAD_LENGTH:
/* Silently ignore entries with zero length. Although this should
* never happen in practice, we should handle the case in a
* reasonable manner just to be safe.
*/
return;
default:
BUG();
}
exit(1);
}
/****************************************************************************
* create_enum
*
* Create a CMOS enumeration structure representing the given information.
* Perform sanity checking on input parameters.
****************************************************************************/
static void create_enum (cmos_enum_t *cmos_enum, const char id_str[],
const char value_str[], const char text_str[])
{ cmos_enum->config_id = string_to_unsigned(id_str, "ID");
cmos_enum->value = string_to_unsigned_long(value_str, "value");
if (strlen(text_str) >= CMOS_MAX_TEXT_LENGTH)
{ fprintf(stderr, "%s: Error on line %d of CMOS layout file: text too "
"long (max length is %d).\n", prog_name, line_num,
CMOS_MAX_TEXT_LENGTH - 1);
exit(1);
}
strcpy(cmos_enum->text, text_str);
}
/****************************************************************************
* try_add_cmos_enum
*
* Attempt to add the given CMOS enum to our internal repository. Exit with
* an error message on failure.
****************************************************************************/
static void try_add_cmos_enum (const cmos_enum_t *cmos_enum)
{ switch (add_cmos_enum(cmos_enum))
{ case OK:
return;
case LAYOUT_DUPLICATE_ENUM:
fprintf(stderr, "%s: Error on line %d of CMOS layout file: "
"Enumeration found with duplicate ID/value combination.\n",
prog_name, line_num);
break;
default:
BUG();
}
exit(1);
}
/****************************************************************************
* set_checksum_info
*
* Set CMOS checksum information according to input parameters and perform
* sanity checking on input parameters.
****************************************************************************/
static void set_checksum_info (const char start_str[], const char end_str[],
const char index_str[])
{ cmos_checksum_layout_t layout;
/* These are bit positions that we want to convert to byte positions. */
layout.summed_area_start =
string_to_unsigned(start_str, "CMOS checksummed area start");
layout.summed_area_end =
string_to_unsigned(end_str, "CMOS checksummed area end");
layout.checksum_at =
string_to_unsigned(index_str, "CMOS checksum location");
switch (checksum_layout_to_bytes(&layout))
{ case OK:
break;
case LAYOUT_SUMMED_AREA_START_NOT_ALIGNED:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. CMOS "
"checksummed area start is not byte-aligned.\n", prog_name,
line_num);
goto fail;
case LAYOUT_SUMMED_AREA_END_NOT_ALIGNED:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. CMOS "
"checksummed area end is not byte-aligned.\n", prog_name,
line_num);
goto fail;
case LAYOUT_CHECKSUM_LOCATION_NOT_ALIGNED:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. CMOS "
"checksum location is not byte-aligned.\n", prog_name,
line_num);
goto fail;
case LAYOUT_INVALID_SUMMED_AREA:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. CMOS "
"checksummed area end must be greater than CMOS checksummed "
"area start.\n", prog_name, line_num);
goto fail;
case LAYOUT_CHECKSUM_OVERLAPS_SUMMED_AREA:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. CMOS "
"checksum overlaps checksummed area.\n", prog_name,
line_num);
goto fail;
case LAYOUT_SUMMED_AREA_OUT_OF_RANGE:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. CMOS "
"checksummed area out of range.\n", prog_name, line_num);
goto fail;
case LAYOUT_CHECKSUM_LOCATION_OUT_OF_RANGE:
fprintf(stderr, "%s: Error on line %d of CMOS layout file. CMOS "
"checksum location out of range.\n", prog_name, line_num);
goto fail;
default:
BUG();
}
cmos_checksum_start = layout.summed_area_start;
cmos_checksum_end = layout.summed_area_end;
cmos_checksum_index = layout.checksum_at;
return;
fail:
exit(1);
}
/****************************************************************************
* cmos_entry_char_value
*
* Return the character representation of 'config'.
****************************************************************************/
static char cmos_entry_char_value (cmos_entry_config_t config)
{ switch (config)
{ case CMOS_ENTRY_ENUM:
return 'e';
case CMOS_ENTRY_HEX:
return 'h';
case CMOS_ENTRY_RESERVED:
return 'r';
default:
BUG();
}
return 0; /* not reached */
}
/****************************************************************************
* get_layout_file_line
*
* Get a line of input from file 'f'. Store result in 'line' which is an
* array of 'line_buf_size' bytes. Return OK on success or an error code on
* failure.
****************************************************************************/
static int get_layout_file_line (FILE *f, char line[], int line_buf_size)
{ switch (get_line_from_file(f, line, line_buf_size))
{ case OK:
return OK;
case LINE_EOF:
return LINE_EOF;
case LINE_TOO_LONG:
fprintf(stderr, "%s: Error on line %d of CMOS layout file: Maximum "
"line length exceeded. Max is %d characters.\n", prog_name,
line_num, line_buf_size - 2);
break;
}
exit(1);
return 1; /* keep compiler happy */
}
/****************************************************************************
* string_to_unsigned
*
* Convert the string 'str' to an unsigned and return the result.
****************************************************************************/
static unsigned string_to_unsigned (const char str[], const char str_name[])
{ unsigned long n;
unsigned z;
n = do_string_to_unsigned_long(str, str_name, "");
if ((z = (unsigned) n) != n)
{ /* This could happen on an architecture in which sizeof(unsigned) <
* sizeof(unsigned long).
*/
fprintf(stderr, "%s: Error on line %d of CMOS layout file: %s value is "
"out of range.\n", prog_name, line_num, str_name);
exit(1);
}
return z;
}
/****************************************************************************
* string_to_unsigned_long
*
* Convert the string 'str' to an unsigned long and return the result.
****************************************************************************/
static unsigned long string_to_unsigned_long (const char str[],
const char str_name[])
{ return do_string_to_unsigned_long(str, str_name, " long"); }
/****************************************************************************
* do_string_to_unsigned_long
*
* Convert the string 'str' to an unsigned long and return the result. Exit
* with an appropriate error message on failure.
****************************************************************************/
static unsigned long do_string_to_unsigned_long (const char str[],
const char str_name[],
const char blurb[])
{ unsigned long n;
char *p;
n = strtoul(str, &p, 0);
if (*p != '\0')
{ fprintf(stderr, "%s: Error on line %d of CMOS layout file: %s is not a "
"valid unsigned%s integer.\n", prog_name,
line_num, str_name, blurb);
exit(1);
}
return n;
}

42
util/lxbios/layout_file.h Normal file
View File

@ -0,0 +1,42 @@
/*****************************************************************************\
* layout_file.h
* $Id: layout_file.h,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef LXBIOS_LAYOUT_FILE_H
#define LXBIOS_LAYOUT_FILE_H
#include "common.h"
#include "linuxbios_tables.h"
void set_layout_filename (const char filename[]);
void get_layout_from_file (void);
void write_cmos_layout (FILE *f);
#endif /* LXBIOS_LAYOUT_FILE_H */

1270
util/lxbios/lbtable.c Normal file

File diff suppressed because it is too large Load Diff

43
util/lxbios/lbtable.h Normal file
View File

@ -0,0 +1,43 @@
/*****************************************************************************\
* lbtable.h
* $Id: lbtable.h,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef LXBIOS_LBTABLE_H
#define LXBIOS_LBTABLE_H
#include "common.h"
void get_lbtable (void);
void get_layout_from_cmos_table (void);
void dump_lbtable (void);
void list_lbtable_choices (void);
void list_lbtable_item (const char item[]);
#endif /* LXBIOS_LBTABLE_H */

View File

@ -0,0 +1,226 @@
/*****************************************************************************\
* linuxbios_tables.h
* $Id: linuxbios_tables.h,v 1.1.1.1 2005/12/02 22:35:19 dsp_llnl Exp $
\*****************************************************************************/
#ifndef LINUXBIOS_TABLES_H
#define LINUXBIOS_TABLES_H
#include <stdint.h>
/* Note: The contents of this file were borrowed from the LinuxBIOS source
* code which may be obtained from http://www.linuxbios.org/.
* Specifically, this code was obtained from LinuxBIOS version 1.1.8.
*/
/* The linuxbios table information is for conveying information
* from the firmware to the loaded OS image. Primarily this
* is expected to be information that cannot be discovered by
* other means, such as quering the hardware directly.
*
* All of the information should be Position Independent Data.
* That is it should be safe to relocated any of the information
* without it's meaning/correctnes changing. For table that
* can reasonably be used on multiple architectures the data
* size should be fixed. This should ease the transition between
* 32 bit and 64 bit architectures etc.
*
* The completeness test for the information in this table is:
* - Can all of the hardware be detected?
* - Are the per motherboard constants available?
* - Is there enough to allow a kernel to run that was written before
* a particular motherboard is constructed? (Assuming the kernel
* has drivers for all of the hardware but it does not have
* assumptions on how the hardware is connected together).
*
* With this test it should be straight forward to determine if a
* table entry is required or not. This should remove much of the
* long term compatibility burden as table entries which are
* irrelevant or have been replaced by better alternatives may be
* dropped. Of course it is polite and expidite to include extra
* table entries and be backwards compatible, but it is not required.
*/
/* Since LinuxBIOS is usually compiled 32bit, gcc will align 64bit
* types to 32bit boundaries. If the LinuxBIOS table is dumped on a
* 64bit system, a uint64_t would be aligned to 64bit boundaries,
* breaking the table format.
*
* lb_uint64 will keep 64bit LinuxBIOS table values aligned to 32bit
* to ensure compatibility. They can be accessed with the two functions
* below: unpack_lb64() and pack_lb64()
*
* See also: util/lbtdump/lbtdump.c
*/
struct lb_uint64 {
uint32_t lo;
uint32_t hi;
};
static inline uint64_t unpack_lb64(struct lb_uint64 value)
{
uint64_t result;
result = value.hi;
result = (result << 32) + value.lo;
return result;
}
static inline struct lb_uint64 pack_lb64(uint64_t value)
{
struct lb_uint64 result;
result.lo = (value >> 0) & 0xffffffff;
result.hi = (value >> 32) & 0xffffffff;
return result;
}
struct lb_header
{
uint8_t signature[4]; /* LBIO */
uint32_t header_bytes;
uint32_t header_checksum;
uint32_t table_bytes;
uint32_t table_checksum;
uint32_t table_entries;
};
/* Every entry in the boot enviroment list will correspond to a boot
* info record. Encoding both type and size. The type is obviously
* so you can tell what it is. The size allows you to skip that
* boot enviroment record if you don't know what it easy. This allows
* forward compatibility with records not yet defined.
*/
struct lb_record {
uint32_t tag; /* tag ID */
uint32_t size; /* size of record (in bytes) */
};
#define LB_TAG_UNUSED 0x0000
#define LB_TAG_MEMORY 0x0001
struct lb_memory_range {
struct lb_uint64 start;
struct lb_uint64 size;
uint32_t type;
#define LB_MEM_RAM 1 /* Memory anyone can use */
#define LB_MEM_RESERVED 2 /* Don't use this memory region */
#define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */
};
struct lb_memory {
uint32_t tag;
uint32_t size;
struct lb_memory_range map[0];
};
#define LB_TAG_HWRPB 0x0002
struct lb_hwrpb {
uint32_t tag;
uint32_t size;
uint64_t hwrpb;
};
#define LB_TAG_MAINBOARD 0x0003
struct lb_mainboard {
uint32_t tag;
uint32_t size;
uint8_t vendor_idx;
uint8_t part_number_idx;
uint8_t strings[0];
};
#define LB_TAG_VERSION 0x0004
#define LB_TAG_EXTRA_VERSION 0x0005
#define LB_TAG_BUILD 0x0006
#define LB_TAG_COMPILE_TIME 0x0007
#define LB_TAG_COMPILE_BY 0x0008
#define LB_TAG_COMPILE_HOST 0x0009
#define LB_TAG_COMPILE_DOMAIN 0x000a
#define LB_TAG_COMPILER 0x000b
#define LB_TAG_LINKER 0x000c
#define LB_TAG_ASSEMBLER 0x000d
struct lb_string {
uint32_t tag;
uint32_t size;
uint8_t string[0];
};
/* The following structures are for the cmos definitions table */
#define LB_TAG_CMOS_OPTION_TABLE 200
/* cmos header record */
struct cmos_option_table {
uint32_t tag; /* CMOS definitions table type */
uint32_t size; /* size of the entire table */
uint32_t header_length; /* length of header */
};
/* cmos entry record
This record is variable length. The name field may be
shorter than CMOS_MAX_NAME_LENGTH. The entry may start
anywhere in the byte, but can not span bytes unless it
starts at the beginning of the byte and the length is
fills complete bytes.
*/
#define LB_TAG_OPTION 201
struct cmos_entries {
uint32_t tag; /* entry type */
uint32_t size; /* length of this record */
uint32_t bit; /* starting bit from start of image */
uint32_t length; /* length of field in bits */
uint32_t config; /* e=enumeration, h=hex, r=reserved */
uint32_t config_id; /* a number linking to an enumeration record */
#define CMOS_MAX_NAME_LENGTH 32
uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name of entry in ascii,
variable length int aligned */
};
/* cmos enumerations record
This record is variable length. The text field may be
shorter than CMOS_MAX_TEXT_LENGTH.
*/
#define LB_TAG_OPTION_ENUM 202
struct cmos_enums {
uint32_t tag; /* enumeration type */
uint32_t size; /* length of this record */
uint32_t config_id; /* a number identifying the config id */
uint32_t value; /* the value associated with the text */
#define CMOS_MAX_TEXT_LENGTH 32
uint8_t text[CMOS_MAX_TEXT_LENGTH]; /* enum description in ascii,
variable length int aligned */
};
/* cmos defaults record
This record contains default settings for the cmos ram.
*/
#define LB_TAG_OPTION_DEFAULTS 203
struct cmos_defaults {
uint32_t tag; /* default type */
uint32_t size; /* length of this record */
uint32_t name_length; /* length of the following name field */
uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name identifying the default */
#define CMOS_IMAGE_BUFFER_SIZE 128
uint8_t default_set[CMOS_IMAGE_BUFFER_SIZE]; /* default settings */
};
#define LB_TAG_OPTION_CHECKSUM 204
struct cmos_checksum {
uint32_t tag;
uint32_t size;
/* In practice everything is byte aligned, but things are measured
* in bits to be consistent.
*/
uint32_t range_start; /* First bit that is checksummed (byte aligned) */
uint32_t range_end; /* Last bit that is checksummed (byte aligned) */
uint32_t location; /* First bit of the checksum (byte aligned) */
uint32_t type; /* Checksum algorithm that is used */
#define CHECKSUM_NONE 0
#define CHECKSUM_PCBIOS 1
};
#endif /* LINUXBIOS_TABLES_H */

255
util/lxbios/lxbios.1 Normal file
View File

@ -0,0 +1,255 @@
.\"***************************************************************************\
.\" lxbios.1
.\" $Id: lxbios.1,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
.\"***************************************************************************
.\" Copyright (C) 2002, 2003 The Regents of the University of California.
.\" Produced at the Lawrence Livermore National Laboratory.
.\" Written by David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
.\" UCRL-CODE-2003-012
.\" All rights reserved.
.\"
.\" This file is part of lxbios, a utility for reading/writing LinuxBIOS
.\" parameters and displaying information from the LinuxBIOS table.
.\" For details, see <http://www.llnl.gov/linux/lxbios/>.
.\"
.\" Please also read the file DISCLAIMER which is included in this software
.\" distribution.
.\"
.\" This program is free software; you can redistribute it and/or modify it
.\" under the terms of the GNU General Public License (as published by the
.\" Free Software Foundation) version 2, dated June 1991.
.\"
.\" This program is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
.\" conditions of the GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public License along
.\" with this program; if not, write to the Free Software Foundation, Inc.,
.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
.\"***************************************************************************/
.TH LXBIOS 1 "December 2005" Linux
.SH NAME
lxbios \- read/write LinuxBIOS-related information
.SH SYNOPSIS
.B "lxbios [OPTS] [-n] -r NAME"
.br
.B "lxbios [OPTS] -e NAME"
.br
.B "lxbios [OPTS] -a"
.br
.B "lxbios [OPTS] -w NAME=VALUE"
.br
.B "lxbios [OPTS] -p INPUT_FILE"
.br
.B "lxbios [OPTS] -i"
.br
.B "lxbios [OPTS] -c [VALUE]"
.br
.B "lxbios [OPTS] -l [ARG]"
.br
.B "lxbios [OPTS] -d"
.br
.B "lxbios [OPTS] -Y"
.br
.B "lxbios [OPTS] -b OUTPUT_FILE"
.br
.B "lxbios [OPTS] -B INPUT_FILE"
.br
.B "lxbios [OPTS] -x"
.br
.B "lxbios [OPTS] -X DUMPFILE"
.br
.B "lxbios [OPTS] -v"
.br
.B "lxbios [OPTS] -h"
.SH DESCRIPTION
.B "lxbios"
is a utility for reading/writing LinuxBIOS parameters and displaying
information from the LinuxBIOS table.
The LinuxBIOS table resides in low physical memory. It is created at boot
time by LinuxBIOS, and contains various system information such as the type
of mainboard in use. It specifies locations in the CMOS (nonvolatile RAM)
where the LinuxBIOS parameters are stored.
This program is intended for x86-based systems that use LinuxBIOS. For
information about LinuxBIOS, see
.br
http://www.linuxbios.org/.
.SH PARAMETERS
.TP
.B "[-n] -r NAME"
Show the value of the LinuxBIOS parameter given by
.B "NAME."
If
.B "-n"
is specified, show only the value. Otherwise show both parameter name and
value.
.TP
.B "-e NAME"
Show all possible values for parameter given by
.B "NAME."
.TP
.B "-a"
Show the names and values for all LinuxBIOS parameters.
.TP
.B "-w NAME=VALUE"
Assign
.B "VALUE"
to LinuxBIOS parameter given by
.B "NAME."
.TP
.B "-p INPUT_FILE"
Assign values to LinuxBIOS parameters according to the contents of
.B "INPUT_FILE."
The format of this file is described below.
.TP
.B "-i"
This is similar to the
.B "-p"
option, except that the contents of the input file are taken from standard
input.
.TP
.B "-c [VALUE]"
If
.B "VALUE"
is present then set the CMOS checksum for the LinuxBIOS parameters to
.B "VALUE."
Otherwise, show the checksum value.
.TP
.B "-l [ARG]"
If
.B "ARG"
is present then show information from the LinuxBIOS table as specified by
.B "ARG."
Otherwise show all possible values for
.B "ARG."
.TP
.B "-d"
Do a low-level dump of the LinuxBIOS table.
.TP
.B "-Y"
Write CMOS layout information to standard output. If redirected to a file,
the layout information may be used as input for the
.B "'-y LAYOUT_FILE'"
option (see below).
.TP
.B "-b OUTPUT_FILE"
Write the contents of CMOS memory to the binary file
.B "OUTPUT_FILE."
The first 14 bytes of
.B "OUTPUT_FILE"
do not contain actual CMOS data, and are always written as zeros. This is
because the first 14 bytes of the CMOS area do not contain CMOS memory. These
bytes are involved with the functioning of the real time clock.
.TP
.B "-B INPUT_FILE"
Read binary data from
.B "INPUT_FILE"
and write the data to CMOS memory. The first 14 bytes of
.B "INPUT_FILE"
are skipped and data is written to CMOS starting at the 15th byte of the CMOS
area. This is because the first 14 bytes of the CMOS area do not contain CMOS
memory. These bytes are involved with the functioning of the real time clock.
.TP
.B "-x"
Show a hex dump of all CMOS data. The first 14 bytes of the dump do not
contain actual CMOS data, and are always shown as zeros. This is because the
first 14 bytes of the CMOS area do not contain CMOS memory. These bytes are
involved with the functioning of the real time clock.
.TP
.B "-X DUMPFILE"
Read binary data from
.B "DUMPFILE"
(presumably a CMOS dumpfile created using the
.B "-b OUTPUT_FILE"
option) and show a hex dump of the data.
.TP
.B "-v"
Show version information for this program.
.TP
.B "-h"
Show a help message for this program.
.SH "OPTIONS"
In all cases above,
.B "[OPTS]"
evaluates to the following:
.B " [-y LAYOUT_FILE | -t]"
The
.B "'-y LAYOUT_FILE'"
option tells lxbios to obtain CMOS layout information from the contents of
.B "LAYOUT_FILE."
Likewise, the
.B "'-t'"
option tells lxbios to obtain CMOS layout information from the CMOS option
table (contained within the LinuxBIOS table). If neither option is
specified, the CMOS option table is used by default.
.B "LAYOUT_FILE"
follows the format of the
.B "cmos.layout"
files provided by LinuxBIOS.
If the LinuxBIOS installed on your system was built without specifying
.B "HAVE_OPTION_TABLE,"
then the LinuxBIOS table will not contain a CMOS option table. In this case,
the
.B "'-y LAYOUT_FILE'"
option must be used.
These two options are silently ignored when used in combination with other
options (such as
.B "-h,"
for instance) for which they are not applicable.
.SH FILE FORMAT
For the
.B "-p"
option,
.B "INPUT_FILE"
must consist of a sequence of lines such that each line is either a blank
line, a comment, or an assignment. A blank line consists only of zero or
more whitespace characters (spaces and tabs). A comment is constructed as
follows:
.B " [ws]#[text]"
Here,
.B "[ws]"
indicates optional whitespace characters and
.B "[text]"
indicates optional text. Blank lines and comments are both ignored. An
assignment is constructed as follows:
.B " [ws]NAME[ws]=[ws]VALUE[ws]"
Here,
.B "NAME"
is the name of a LinuxBIOS parameter and
.B "VALUE"
is the value that will be assigned to
.B "NAME."
.B "VALUE"
is allowed to contain whitespace characters, but it must begin and end with
nonwhitespace characters. Note that each comment must appear on a line by
itself. If you attempt to add a comment to the end of an assignment, then the
comment will be interpreted as part of
.B "VALUE."
It is useful to observe that the output produced by both the
.B "-a"
and the
.B "'[-n] NAME'"
options (without
.B "-n"
specified) adheres to this file format.
.SH BUGS
This program does not implement any type of synchronization to ensure that
different processes don't stomp on each other when trying to access the
nonvolatile RAM simultaneously. Therefore, corruption of the BIOS parameter
values may occur if multiple instances of this program are executed
concurrently.
.SH AUTHORS
David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>
.br
Stefan Reinauer <stepan@openbios.org>

754
util/lxbios/lxbios.c Normal file
View File

@ -0,0 +1,754 @@
/*****************************************************************************\
* lxbios.c
* $Id: lxbios.c,v 1.3 2006/01/24 00:25:40 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include "common.h"
#include "opts.h"
#include "lbtable.h"
#include "layout.h"
#include "layout_file.h"
#include "input_file.h"
#include "cmos_ops.h"
#include "cmos_lowlevel.h"
#include "reg_expr.h"
#include "hexdump.h"
typedef void (*op_fn_t) (void);
static void op_show_version (void);
static void op_show_usage (void);
static void op_lbtable_show_info (void);
static void op_lbtable_dump (void);
static void op_show_param_values (void);
static void op_cmos_show_one_param (void);
static void op_cmos_show_all_params (void);
static void op_cmos_set_one_param (void);
static void op_cmos_set_params_stdin (void);
static void op_cmos_set_params_file (void);
static void op_cmos_checksum (void);
static void op_show_layout (void);
static void op_write_cmos_dump (void);
static void op_read_cmos_dump (void);
static void op_show_cmos_hex_dump (void);
static void op_show_cmos_dumpfile (void);
static int list_one_param (const char name[], int show_name);
static int list_all_params (void);
static void list_param_enums (const char name[]);
static void set_one_param (const char name[], const char value[]);
static void set_params (FILE *f);
static void parse_assignment (char arg[], const char **name,
const char **value);
static int list_cmos_entry (const cmos_entry_t *e, int show_name);
static uint16_t convert_checksum_value (const char value[]);
static const op_fn_t op_fns[] =
{ op_show_version,
op_show_usage,
op_lbtable_show_info,
op_lbtable_dump,
op_show_param_values,
op_cmos_show_one_param,
op_cmos_show_all_params,
op_cmos_set_one_param,
op_cmos_set_params_stdin,
op_cmos_set_params_file,
op_cmos_checksum,
op_show_layout,
op_write_cmos_dump,
op_read_cmos_dump,
op_show_cmos_hex_dump,
op_show_cmos_dumpfile
};
static const hexdump_format_t cmos_dump_format =
{ 16, 2, "", " | ", " ", " | ", '.', NULL };
/****************************************************************************
* main
****************************************************************************/
int main (int argc, char *argv[])
{ cmos_layout_get_fn_t fn;
parse_lxbios_args(argc, argv);
if (lxbios_op_modifiers[LXBIOS_MOD_USE_CMOS_LAYOUT_FILE].found)
{ set_layout_filename(
lxbios_op_modifiers[LXBIOS_MOD_USE_CMOS_LAYOUT_FILE].param);
fn = get_layout_from_file;
}
else
fn = get_layout_from_cmos_table;
register_cmos_layout_get_fn(fn);
op_fns[lxbios_op.op]();
return 0;
}
/****************************************************************************
* op_show_version
*
* -v
*
* Show version information for this program.
****************************************************************************/
static void op_show_version (void)
{ printf("This is %s version %s.\n", prog_name, prog_version); }
/****************************************************************************
* op_show_usage
*
* -h
*
* Show a usage message for this program.
****************************************************************************/
static void op_show_usage (void)
{ usage(stdout); }
/****************************************************************************
* op_lbtable_show_info
*
* -l [ARG]
*
* If ARG is present, show LinuxBIOS table information specified by ARG.
* Else show all possible values for ARG.
****************************************************************************/
static void op_lbtable_show_info (void)
{ if (lxbios_op.param == NULL)
list_lbtable_choices();
else
{ get_lbtable();
list_lbtable_item(lxbios_op.param);
}
}
/****************************************************************************
* op_lbtable_dump
*
* -d
*
* Do low-level dump of LinuxBIOS table.
****************************************************************************/
static void op_lbtable_dump (void)
{ get_lbtable();
dump_lbtable();
}
/****************************************************************************
* op_show_param_values
*
* -e NAME option
*
* Show all possible values for parameter NAME.
****************************************************************************/
static void op_show_param_values (void)
{ get_cmos_layout();
list_param_enums(lxbios_op.param);
}
/****************************************************************************
* op_cmos_show_one_param
*
* [-n] -r NAME
*
* Show parameter NAME. If -n is specified, show value only. Else show name
* and value.
****************************************************************************/
static void op_cmos_show_one_param (void)
{ int result;
get_cmos_layout();
result = list_one_param(lxbios_op.param,
!lxbios_op_modifiers[LXBIOS_MOD_SHOW_VALUE_ONLY].found);
cmos_checksum_verify();
if (result)
exit(1);
}
/****************************************************************************
* op_cmos_show_all_params
*
* -a
*
* Show names and values for all parameters.
****************************************************************************/
static void op_cmos_show_all_params (void)
{ int result;
get_cmos_layout();
result = list_all_params();
cmos_checksum_verify();
if (result)
exit(1);
}
/****************************************************************************
* op_cmos_set_one_param
*
* -w NAME=VALUE
*
* Set parameter NAME to VALUE.
****************************************************************************/
static void op_cmos_set_one_param (void)
{ const char *name, *value;
get_cmos_layout();
/* Separate 'NAME=VALUE' syntax into two strings representing NAME and
* VALUE.
*/
parse_assignment(lxbios_op.param, &name, &value);
set_one_param(name, value);
}
/****************************************************************************
* op_cmos_set_params_stdin
*
* -i
*
* Set parameters according to standard input.
****************************************************************************/
static void op_cmos_set_params_stdin (void)
{ get_cmos_layout();
set_params(stdin);
}
/****************************************************************************
* op_cmos_set_params_file
*
* -p INPUT_FILE
*
* Set parameters according to INPUT_FILE.
****************************************************************************/
static void op_cmos_set_params_file (void)
{ FILE *f;
if ((f = fopen(lxbios_op.param, "r")) == NULL)
{ fprintf(stderr, "%s: Can not open file %s for reading: %s\n",
prog_name, lxbios_op.param, strerror(errno));
exit(1);
}
get_cmos_layout();
set_params(f);
fclose(f);
}
/****************************************************************************
* op_cmos_checksum
*
* -c [VALUE]
*
* If VALUE is present, set LinuxBIOS CMOS checksum to VALUE. Else show
* checksum value.
****************************************************************************/
static void op_cmos_checksum (void)
{ uint16_t checksum;
get_cmos_layout();
if (lxbios_op.param == NULL)
{ set_iopl(3);
checksum = cmos_checksum_read();
set_iopl(0);
printf("0x%x\n", checksum);
}
else
{ checksum = convert_checksum_value(lxbios_op.param);
set_iopl(3);
cmos_checksum_write(checksum);
set_iopl(0);
}
}
/****************************************************************************
* op_show_layout
*
* -Y
*
* Write CMOS layout information to standard output.
****************************************************************************/
static void op_show_layout (void)
{ get_cmos_layout();
write_cmos_layout(stdout);
}
/****************************************************************************
* op_write_cmos_dump
*
* -b OUTPUT_FILE
*
* Write the contents of CMOS memory to a binary file.
****************************************************************************/
static void op_write_cmos_dump (void)
{ unsigned char data[CMOS_SIZE];
FILE *f;
if ((f = fopen(lxbios_op.param, "w")) == NULL)
{ fprintf(stderr, "%s: Can not open file %s for writing: %s\n",
prog_name, lxbios_op.param, strerror(errno));
exit(1);
}
set_iopl(3);
cmos_read_all(data);
set_iopl(0);
if (fwrite(data, 1, CMOS_SIZE, f) != CMOS_SIZE)
{ fprintf(stderr, "%s: Error writing CMOS data to file %s: %s\n",
prog_name, lxbios_op.param, strerror(errno));
exit(1);
}
fclose(f);
}
/****************************************************************************
* op_read_cmos_dump
*
* -B INPUT_FILE
*
* Read binary data from a file and write the data to CMOS memory.
****************************************************************************/
static void op_read_cmos_dump (void)
{ unsigned char data[CMOS_SIZE];
size_t nr_bytes;
FILE *f;
if ((f = fopen(lxbios_op.param, "r")) == NULL)
{ fprintf(stderr, "%s: Can not open file %s for reading: %s\n",
prog_name, lxbios_op.param, strerror(errno));
exit(1);
}
if ((nr_bytes = fread(data, 1, CMOS_SIZE, f)) != CMOS_SIZE)
{ fprintf(stderr, "%s: Error: Only able to read %d bytes of CMOS data "
"from file %s. CMOS data is unchanged.\n", prog_name,
(int) nr_bytes, lxbios_op.param);
exit(1);
}
fclose(f);
set_iopl(3);
cmos_write_all(data);
set_iopl(0);
}
/****************************************************************************
* op_show_cmos_hex_dump
*
* -x
*
* Write a hex dump of CMOS memory to standard output.
****************************************************************************/
static void op_show_cmos_hex_dump (void)
{ unsigned char data[CMOS_SIZE];
set_iopl(3);
cmos_read_all(data);
set_iopl(0);
hexdump(data, CMOS_SIZE, 0, stdout, &cmos_dump_format);
}
/****************************************************************************
* op_show_cmos_dumpfile
*
* -X DUMP_FILE
*
* Read binary data from a file (presumably a CMOS dump file) and display a
* hex dump of the CMOS data from the file.
****************************************************************************/
static void op_show_cmos_dumpfile (void)
{ unsigned char data[CMOS_SIZE];
size_t nr_bytes;
FILE *f;
if ((f = fopen(lxbios_op.param, "r")) == NULL)
{ fprintf(stderr, "%s: Can not open file %s for reading: %s\n",
prog_name, lxbios_op.param, strerror(errno));
exit(1);
}
nr_bytes = fread(data, 1, CMOS_SIZE, f);
fclose(f);
hexdump(data, nr_bytes, 0, stdout, &cmos_dump_format);
}
/****************************************************************************
* list_one_param
*
* Attempt to list one CMOS parameter given by 'name'. 'show_name' is a
* boolean value indicating whether the parameter name should be displayed
* along with its value. Return 1 if error was encountered. Else return OK.
****************************************************************************/
static int list_one_param (const char name[], int show_name)
{ const cmos_entry_t *e;
if (is_checksum_name(name) || ((e = find_cmos_entry(name)) == NULL))
{ fprintf(stderr, "%s: CMOS parameter %s not found.\n", prog_name, name);
exit(1);
}
if (e->config == CMOS_ENTRY_RESERVED)
{ fprintf(stderr, "%s: Parameter %s is reserved.\n", prog_name, name);
exit(1);
}
return (list_cmos_entry(e, show_name) != 0);
}
/****************************************************************************
* list_all_params
*
* Attempt to list all CMOS parameters. Return 1 if error was encountered.
* Else return OK.
****************************************************************************/
static int list_all_params (void)
{ const cmos_entry_t *e;
int result;
result = OK;
for (e = first_cmos_entry(); e != NULL; e = next_cmos_entry(e))
{ if ((e->config == CMOS_ENTRY_RESERVED) || is_checksum_name(e->name))
continue;
if (list_cmos_entry(e, TRUE))
result = 1;
}
return result;
}
/****************************************************************************
* list_param_enums
*
* List all possible values for CMOS parameter given by 'name'.
****************************************************************************/
static void list_param_enums (const char name[])
{ const cmos_entry_t *e;
const cmos_enum_t *p;
if (is_checksum_name(name) || (e = find_cmos_entry(name)) == NULL)
{ fprintf(stderr, "%s: CMOS parameter %s not found.\n", prog_name, name);
exit(1);
}
switch (e->config)
{ case CMOS_ENTRY_ENUM:
for (p = first_cmos_enum_id(e->config_id);
p != NULL;
p = next_cmos_enum_id(p))
printf("%s\n", p->text);
break;
case CMOS_ENTRY_HEX:
printf("Parameter %s requires a %u-bit unsigned integer.\n", name,
e->length);
break;
case CMOS_ENTRY_RESERVED:
printf("Parameter %s is reserved.\n", name);
break;
default:
BUG();
}
}
/****************************************************************************
* set_one_param
*
* Set the CMOS parameter given by 'name' to 'value'. The 'name' parameter
* is case-sensitive. If we are setting an enum parameter, then 'value' is
* interpreted as a case-sensitive string that must match the option name
* exactly. If we are setting a 'hex' parameter, then 'value' is treated as
* a string representation of an unsigned integer that may be specified in
* decimal, hex, or octal.
****************************************************************************/
static void set_one_param (const char name[], const char value[])
{ const cmos_entry_t *e;
unsigned long long n;
if (is_checksum_name(name) || (e = find_cmos_entry(name)) == NULL)
{ fprintf(stderr, "%s: CMOS parameter %s not found.", prog_name, name);
exit(1);
}
switch (prepare_cmos_write(e, value, &n))
{ case OK:
break;
case CMOS_OP_BAD_ENUM_VALUE:
fprintf(stderr, "%s: Bad value for parameter %s.", prog_name, name);
goto fail;
case CMOS_OP_NEGATIVE_INT:
fprintf(stderr,
"%s: This program does not support assignment of negative "
"numbers to LinuxBIOS parameters.", prog_name);
goto fail;
case CMOS_OP_INVALID_INT:
fprintf(stderr, "%s: %s is not a valid integer.", prog_name, value);
goto fail;
case CMOS_OP_RESERVED:
fprintf(stderr,
"%s: Can not modify reserved LinuxBIOS parameter %s.",
prog_name, name);
goto fail;
case CMOS_OP_VALUE_TOO_WIDE:
fprintf(stderr,
"%s: Can not write value %s to CMOS parameter %s that is "
"only %d bits wide.", prog_name, value, name, e->length);
goto fail;
case CMOS_OP_NO_MATCHING_ENUM:
fprintf(stderr,
"%s: LinuxBIOS parameter %s has no matching enums.",
prog_name, name);
goto fail;
case CMOS_AREA_OUT_OF_RANGE:
fprintf(stderr,
"%s: The CMOS area specified by the layout info for "
"LinuxBIOS parameter %s is out of range.", prog_name, name);
goto fail;
case CMOS_AREA_OVERLAPS_RTC:
fprintf(stderr,
"%s: The CMOS area specified by the layout info for "
"LinuxBIOS parameter %s overlaps the realtime clock area.",
prog_name, name);
goto fail;
case CMOS_AREA_TOO_WIDE:
fprintf(stderr,
"%s: The CMOS area specified by the layout info for "
"LinuxBIOS parameter %s is too wide.",
prog_name, name);
goto fail;
default:
fprintf(stderr,
"%s: Unknown error encountered while attempting to modify "
"LinuxBIOS parameter %s.", prog_name, name);
goto fail;
}
/* write the value to nonvolatile RAM */
set_iopl(3);
cmos_write(e->bit, e->length, n);
cmos_checksum_write(cmos_checksum_compute());
set_iopl(0);
return;
fail:
fprintf(stderr, " CMOS write not performed.\n");
exit(1);
}
/****************************************************************************
* set_params
*
* Set LinuxBIOS parameters according to the contents of file 'f'.
****************************************************************************/
static void set_params (FILE *f)
{ /* First process the input file. Then perform writes only if there were
* no problems processing the input. Either all values will be written
* successfully or no values will be written.
*/
do_cmos_writes(process_input_file(f));
}
/****************************************************************************
* parse_assignment
*
* Parse the string 'arg' (which supposedly represents an assignment) into a
* NAME and a VALUE. If 'arg' does not conform to the proper assignment
* syntax, exit with a usage message. Otherwise, on return, 'arg' is broken
* into substrings representing NAME and VALUE, and *name and *value are set
* to point to these two substrings.
****************************************************************************/
static void parse_assignment (char arg[], const char **name,
const char **value)
{ static const size_t N_MATCHES = 4;
regmatch_t match[N_MATCHES];
regex_t assignment;
compile_reg_exprs(REG_EXTENDED | REG_NEWLINE, 1, assignment_regex,
&assignment);
/* Does 'arg' conform to proper assignment syntax? If not, exit with a
* usage message.
*/
if (regexec(&assignment, arg, N_MATCHES, match, 0))
usage(stderr);
/* Ok, we found a valid assignment. Break it into two strings
* representing NAME and VALUE.
*/
arg[match[1].rm_eo] = '\0';
arg[match[2].rm_eo] = '\0';
*name = &arg[match[1].rm_so];
*value = &arg[match[2].rm_so];
free_reg_exprs(1, &assignment);
}
/****************************************************************************
* list_cmos_entry
*
* Attempt to list the CMOS entry represented by 'e'. 'show_name' is a
* boolean value indicating whether the parameter name should be displayed
* along with its value. On success, return OK. On error, print an error
* message and return 1.
****************************************************************************/
static int list_cmos_entry (const cmos_entry_t *e, int show_name)
{ const cmos_enum_t *p;
unsigned long long value;
/* sanity check CMOS entry */
switch (prepare_cmos_read(e))
{ case OK:
break;
case CMOS_OP_RESERVED:
BUG();
case CMOS_AREA_OUT_OF_RANGE:
fprintf(stderr, "%s: Can not read LinuxBIOS parameter %s because "
"layout info specifies out of range CMOS area.\n", prog_name,
e->name);
return 1;
case CMOS_AREA_OVERLAPS_RTC:
fprintf(stderr, "%s: Can not read LinuxBIOS parameter %s because "
"layout info specifies CMOS area that overlaps realtime "
"clock area.\n", prog_name, e->name);
return 1;
case CMOS_AREA_TOO_WIDE:
fprintf(stderr, "%s: Can not read LinuxBIOS parameter %s because "
"layout info specifies CMOS area that is too wide.\n",
prog_name, e->name);
return 1;
default:
fprintf(stderr, "%s: Unknown error encountered while attempting to "
"read LinuxBIOS parameter %s\n", prog_name, e->name);
return 1;
}
/* read the value from CMOS */
set_iopl(3);
value = cmos_read(e->bit, e->length);
set_iopl(0);
/* display the value */
switch (e->config)
{ case CMOS_ENTRY_ENUM:
if ((p = find_cmos_enum(e->config_id, value)) == NULL)
{ if (show_name)
printf("# Bad value -> %s = 0x%llx\n", e->name, value);
else
printf("Bad value -> 0x%llx\n", value);
}
else
{ if (show_name)
printf("%s = %s\n", e->name, p->text);
else
printf("%s\n", p->text);
}
break;
case CMOS_ENTRY_HEX:
if (show_name)
printf("%s = 0x%llx\n", e->name, value);
else
printf("0x%llx\n", value);
break;
case CMOS_ENTRY_RESERVED:
default:
BUG();
}
return OK;
}
/****************************************************************************
* convert_checksum_value
*
* 'value' is the string representation of a checksum value that the user
* wishes to set using the -c option. Convert the string to a 16-bit
* unsigned integer and return the result. Exit with an error message if
* 'value' is invalid.
****************************************************************************/
static uint16_t convert_checksum_value (const char value[])
{ unsigned long n;
const char *p;
uint16_t result;
int negative;
for (p = value; isspace(*p); p++);
negative = (*p == '-');
n = strtoul(value, (char **) &p, 0);
if (*p)
{ fprintf(stderr, "%s: Checksum value %s is not a valid integer.\n",
prog_name, value);
exit(1);
}
if (negative)
{ fprintf(stderr,
"%s: Checksum must be an unsigned integer.\n", prog_name);
exit(1);
}
result = (uint16_t) n;
if (result != n)
{ fprintf(stderr,
"%s: Checksum value must fit within 16 bits.\n", prog_name);
exit(1);
}
return result;
}

50
util/lxbios/lxbios.spec Normal file
View File

@ -0,0 +1,50 @@
##
# $Id: lxbios.spec,v 1.3 2006/01/24 00:25:40 dsp_llnl Exp $
##
Name: lxbios
Version: 2.0.1
Release: 0
Summary: LinuxBIOS utility program
Group: System Environment/Base
License: GPL
Provides: lxbios
BuildRoot: %{_tmppath}/%{name}-%{version}
Source0: %{name}-%{version}.tgz
%description
lxbios is a utility for reading/writing LinuxBIOS parameters and displaying
information from the LinuxBIOS table.
At boot time, LinuxBIOS places a table (known as the LinuxBIOS table) in low
physical memory. The contents of this table are preserved even after
LinuxBIOS transfers control to the kernel and the kernel initializes itself.
The LinuxBIOS table contains various system information such as the type of
mainboard in use. It also specifies locations in the CMOS (nonvolatile RAM)
where the LinuxBIOS parameters are stored.
%prep
%setup -n %{name}-%{version}
%build
make
%install
rm -rf "$RPM_BUILD_ROOT"
mkdir -p "$RPM_BUILD_ROOT/usr/bin"
mkdir -p "$RPM_BUILD_ROOT/usr/man/man1"
cp lxbios "$RPM_BUILD_ROOT/usr/bin"
cp lxbios.1.gz $RPM_BUILD_ROOT/usr/man/man1
%clean
rm -rf "$RPM_BUILD_ROOT"
%files
%defattr(-,root,root,0755)
%doc ChangeLog README
%doc README
/usr/bin/lxbios
/usr/man/man1/lxbios.1.gz

232
util/lxbios/opts.c Normal file
View File

@ -0,0 +1,232 @@
/*****************************************************************************\
* opts.c
* $Id: opts.c,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include "common.h"
#include "opts.h"
lxbios_op_info_t lxbios_op;
lxbios_op_modifier_info_t lxbios_op_modifiers[LXBIOS_NUM_OP_MODIFIERS];
static char * handle_optional_arg (int argc, char *argv[]);
static void register_op (int *op_found, lxbios_op_t op, char op_param[]);
static void register_op_modifier (lxbios_op_modifier_t mod, char mod_param[]);
static void resolve_op_modifiers (void);
static void sanity_check_args (void);
static const char getopt_string[] = "-ab:B:c::de:hil::np:r:tvw:xX:y:Y";
/****************************************************************************
* parse_lxbios_args
*
* Parse command line arguments.
****************************************************************************/
void parse_lxbios_args (int argc, char *argv[])
{ lxbios_op_modifier_info_t *mod_info;
int i, op_found;
char c;
for (i = 0, mod_info = lxbios_op_modifiers;
i < LXBIOS_NUM_OP_MODIFIERS;
i++, mod_info++)
{ mod_info->found = FALSE;
mod_info->found_seq = 0;
mod_info->param = NULL;
}
op_found = FALSE;
opterr = 0;
do
{ switch (c = getopt(argc, argv, getopt_string))
{ case 'a':
register_op(&op_found, LXBIOS_OP_CMOS_SHOW_ALL_PARAMS, NULL);
break;
case 'b':
register_op(&op_found, LXBIOS_OP_WRITE_CMOS_DUMP, optarg);
break;
case 'B':
register_op(&op_found, LXBIOS_OP_READ_CMOS_DUMP, optarg);
break;
case 'c':
register_op(&op_found, LXBIOS_OP_CMOS_CHECKSUM,
handle_optional_arg(argc, argv));
break;
case 'd':
register_op(&op_found, LXBIOS_OP_LBTABLE_DUMP, NULL);
break;
case 'e':
register_op(&op_found, LXBIOS_OP_SHOW_PARAM_VALUES, optarg);
break;
case 'h':
register_op(&op_found, LXBIOS_OP_SHOW_USAGE, NULL);
break;
case 'i':
register_op(&op_found, LXBIOS_OP_CMOS_SET_PARAMS_STDIN, NULL);
break;
case 'l':
register_op(&op_found, LXBIOS_OP_LBTABLE_SHOW_INFO,
handle_optional_arg(argc, argv));
break;
case 'n':
register_op_modifier(LXBIOS_MOD_SHOW_VALUE_ONLY, NULL);
break;
case 'p':
register_op(&op_found, LXBIOS_OP_CMOS_SET_PARAMS_FILE, optarg);
break;
case 'r':
register_op(&op_found, LXBIOS_OP_CMOS_SHOW_ONE_PARAM, optarg);
break;
case 't':
register_op_modifier(LXBIOS_MOD_USE_CMOS_OPT_TABLE, NULL);
break;
case 'v':
register_op(&op_found, LXBIOS_OP_SHOW_VERSION, NULL);
break;
case 'w':
register_op(&op_found, LXBIOS_OP_CMOS_SET_ONE_PARAM, optarg);
break;
case 'x':
register_op(&op_found, LXBIOS_OP_SHOW_CMOS_HEX_DUMP, NULL);
break;
case 'X':
register_op(&op_found, LXBIOS_OP_SHOW_CMOS_DUMPFILE, optarg);
break;
case 'y':
register_op_modifier(LXBIOS_MOD_USE_CMOS_LAYOUT_FILE, optarg);
break;
case 'Y':
register_op(&op_found, LXBIOS_OP_SHOW_LAYOUT, NULL);
break;
case -1: /* no more command line args */
break;
case '?': /* unknown option found */
case 1: /* nonoption command line arg found */
default:
usage(stderr);
break;
}
}
while (c != -1);
if (!op_found)
usage(stderr);
resolve_op_modifiers();
sanity_check_args();
}
/****************************************************************************
* handle_optional_arg
*
* Handle a command line option with an optional argument.
****************************************************************************/
static char * handle_optional_arg (int argc, char *argv[])
{ char *arg;
if (optarg != NULL)
{ /* optional arg is present and arg was specified as "-zarg" (with no
* whitespace between "z" and "arg"), where -z is the option and "arg"
* is the value of the optional arg
*/
return optarg;
}
if ((argv[optind] == NULL) || (argv[optind][0] == '-'))
return NULL;
arg = argv[optind]; /* optional arg is present */
/* This call to getopt yields the optional arg we just found, which we want
* to skip.
*/
getopt(argc, argv, getopt_string);
return arg;
}
/****************************************************************************
* register_op
*
* Store the user's selection of which operation this program should perform.
****************************************************************************/
static void register_op (int *op_found, lxbios_op_t op, char op_param[])
{ if (*op_found && (op != lxbios_op.op))
usage(stderr);
*op_found = TRUE;
lxbios_op.op = op;
lxbios_op.param = op_param;
}
/****************************************************************************
* register_op_modifier
*
* Store information regarding an optional argument specified in addition to
* the user's selection of which operation this program should perform.
****************************************************************************/
static void register_op_modifier (lxbios_op_modifier_t mod, char mod_param[])
{ static int found_seq = 0;
lxbios_op_modifier_info_t *mod_info;
mod_info = &lxbios_op_modifiers[mod];
mod_info->found = TRUE;
mod_info->found_seq = ++found_seq;
mod_info->param = mod_param;
}
/****************************************************************************
* resolve_op_modifiers
*
* If the user specifies multiple arguments that conflict with each other,
* the last specified argument overrides previous conflicting arguments.
****************************************************************************/
static void resolve_op_modifiers (void)
{ if (lxbios_op_modifiers[LXBIOS_MOD_USE_CMOS_LAYOUT_FILE].found &&
lxbios_op_modifiers[LXBIOS_MOD_USE_CMOS_OPT_TABLE].found)
{ if (lxbios_op_modifiers[LXBIOS_MOD_USE_CMOS_LAYOUT_FILE].found_seq >
lxbios_op_modifiers[LXBIOS_MOD_USE_CMOS_OPT_TABLE].found_seq)
lxbios_op_modifiers[LXBIOS_MOD_USE_CMOS_OPT_TABLE].found = FALSE;
else
lxbios_op_modifiers[LXBIOS_MOD_USE_CMOS_LAYOUT_FILE].found = FALSE;
}
}
/****************************************************************************
* sanity_check_args
*
* Perform sanity checking on command line arguments.
****************************************************************************/
static void sanity_check_args (void)
{ if ((lxbios_op_modifiers[LXBIOS_MOD_SHOW_VALUE_ONLY].found) &&
(lxbios_op.op != LXBIOS_OP_CMOS_SHOW_ONE_PARAM))
usage(stderr);
}

84
util/lxbios/opts.h Normal file
View File

@ -0,0 +1,84 @@
/*****************************************************************************\
* opts.h
* $Id: opts.h,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef LXBIOS_OPTS_H
#define LXBIOS_OPTS_H
#include "common.h"
typedef enum
{ LXBIOS_OP_SHOW_VERSION = 0,
LXBIOS_OP_SHOW_USAGE,
LXBIOS_OP_LBTABLE_SHOW_INFO,
LXBIOS_OP_LBTABLE_DUMP,
LXBIOS_OP_SHOW_PARAM_VALUES,
LXBIOS_OP_CMOS_SHOW_ONE_PARAM,
LXBIOS_OP_CMOS_SHOW_ALL_PARAMS,
LXBIOS_OP_CMOS_SET_ONE_PARAM,
LXBIOS_OP_CMOS_SET_PARAMS_STDIN,
LXBIOS_OP_CMOS_SET_PARAMS_FILE,
LXBIOS_OP_CMOS_CHECKSUM,
LXBIOS_OP_SHOW_LAYOUT,
LXBIOS_OP_WRITE_CMOS_DUMP,
LXBIOS_OP_READ_CMOS_DUMP,
LXBIOS_OP_SHOW_CMOS_HEX_DUMP,
LXBIOS_OP_SHOW_CMOS_DUMPFILE
}
lxbios_op_t;
typedef struct
{ lxbios_op_t op;
char *param;
}
lxbios_op_info_t;
typedef enum
{ LXBIOS_MOD_SHOW_VALUE_ONLY = 0,
LXBIOS_MOD_USE_CMOS_LAYOUT_FILE,
LXBIOS_MOD_USE_CMOS_OPT_TABLE,
LXBIOS_NUM_OP_MODIFIERS /* must always be last */
}
lxbios_op_modifier_t;
typedef struct
{ int found;
int found_seq;
char *param;
}
lxbios_op_modifier_info_t;
extern lxbios_op_info_t lxbios_op;
extern lxbios_op_modifier_info_t lxbios_op_modifiers[];
void parse_lxbios_args (int argc, char *argv[]);
#endif /* LXBIOS_OPTS_H */

81
util/lxbios/reg_expr.c Normal file
View File

@ -0,0 +1,81 @@
/*****************************************************************************\
* reg_expr.c
* $Id: reg_expr.c,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include <stdarg.h>
#include "common.h"
#include "reg_expr.h"
/****************************************************************************
* compile_reg_exprs
*
* Compile a bunch of regular expressions.
****************************************************************************/
void compile_reg_exprs (int cflags, int num_exprs,
/* const char *expr1, regex_t *reg1, */ ...)
{ static const size_t ERROR_BUF_SIZE = 256;
char error_msg[ERROR_BUF_SIZE];
va_list ap;
regex_t *reg;
const char *expr;
int i, result;
va_start(ap, num_exprs);
for (i = 0; i < num_exprs; i++)
{ expr = va_arg(ap, const char *);
reg = va_arg(ap, regex_t *);
if ((result = regcomp(reg, expr, cflags)) != 0)
{ regerror(result, reg, error_msg, ERROR_BUF_SIZE);
fprintf(stderr, "%s: %s\n", prog_name, error_msg);
exit(1);
}
}
va_end(ap);
}
/****************************************************************************
* free_reg_exprs
*
* Destroy a bunch of previously compiled regular expressions.
****************************************************************************/
void free_reg_exprs (int num_exprs, /* regex_t *reg1, */ ...)
{ va_list ap;
int i;
va_start(ap, num_exprs);
for (i = 0; i < num_exprs; i++)
regfree(va_arg(ap, regex_t *));
va_end(ap);
}

42
util/lxbios/reg_expr.h Normal file
View File

@ -0,0 +1,42 @@
/*****************************************************************************\
* reg_expr.h
* $Id: reg_expr.h,v 1.2 2005/12/16 22:45:49 dsp_llnl Exp $
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of lxbios, a utility for reading/writing LinuxBIOS
* parameters and displaying information from the LinuxBIOS table.
* For details, see <http://www.llnl.gov/linux/lxbios/>.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef LXBIOS_REG_EXPR_H
#define LXBIOS_REG_EXPR_H
#include <regex.h>
#include "common.h"
void compile_reg_exprs (int cflags, int num_exprs,
/* const char *expr1, regex_t *reg1, */ ...);
void free_reg_exprs (int num_exprs, /* regex_t *reg1, */ ...);
#endif /* LXBIOS_REG_EXPR_H */