[coreboot] [commit] r6313 - in trunk/util/nvramtool: . accessors
repository service
svn at coreboot.org
Fri Jan 28 08:54:11 CET 2011
Author: oxygene
Date: Fri Jan 28 08:54:11 2011
New Revision: 6313
URL: https://tracker.coreboot.org/trac/coreboot/changeset/6313
Log:
Move CMOS handling into separate files in accessors
Signed-off-by: Patrick Georgi <patrick.georgi at secunet.com>
Acked-by: Stefan Reinauer <stefan.reinauer at coreboot.org>
Added:
trunk/util/nvramtool/accessors/cmos-hw-unix.c
- copied, changed from r6311, trunk/util/nvramtool/cmos_lowlevel.c
trunk/util/nvramtool/accessors/cmos-mem.c
- copied, changed from r6311, trunk/util/nvramtool/cmos_lowlevel.c
Modified:
trunk/util/nvramtool/Makefile
trunk/util/nvramtool/cmos_lowlevel.c
trunk/util/nvramtool/cmos_lowlevel.h
trunk/util/nvramtool/common.h
Modified: trunk/util/nvramtool/Makefile
==============================================================================
--- trunk/util/nvramtool/Makefile Fri Jan 28 08:50:33 2011 (r6312)
+++ trunk/util/nvramtool/Makefile Fri Jan 28 08:54:11 2011 (r6313)
@@ -31,7 +31,7 @@
OBJS = cmos_lowlevel.o cmos_ops.o common.o compute_ip_checksum.o \
hexdump.o input_file.o layout.o accessors/layout-text.o lbtable.o \
- reg_expr.o cbfs.o
+ reg_expr.o cbfs.o accessors/cmos-hw-unix.o accessors/cmos-mem.o
OBJS += $(CLI_OBJS)
Copied and modified: trunk/util/nvramtool/accessors/cmos-hw-unix.c (from r6311, trunk/util/nvramtool/cmos_lowlevel.c)
==============================================================================
--- trunk/util/nvramtool/cmos_lowlevel.c Fri Jan 28 08:47:35 2011 (r6311, copy source)
+++ trunk/util/nvramtool/accessors/cmos-hw-unix.c Fri Jan 28 08:54:11 2011 (r6313)
@@ -1,76 +1,35 @@
-/*****************************************************************************\
- * cmos_lowlevel.c
- *****************************************************************************
- * Copyright (C) 2002-2005 The Regents of the University of California.
- * Produced at the Lawrence Livermore National Laboratory.
- * Written by David S. Peterson <dsp at llnl.gov> <dave_peterson at pobox.com>.
- * UCRL-CODE-2003-012
- * All rights reserved.
- *
- * This file is part of nvramtool, a utility for reading/writing coreboot
- * parameters and displaying information from the coreboot table.
- * For details, see http://coreboot.org/nvramtool.
- *
- * 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.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-\*****************************************************************************/
+#include <assert.h>
+#include "cmos_lowlevel.h"
#if defined(__FreeBSD__)
-#include <fcntl.h>
-#include <unistd.h>
+#include <sys/types.h>
+#include <machine/cpufunc.h>
+#define OUTB(x, y) do { u_int tmp = (y); outb(tmp, (x)); } while (0)
+#define OUTW(x, y) do { u_int tmp = (y); outw(tmp, (x)); } while (0)
+#define OUTL(x, y) do { u_int tmp = (y); outl(tmp, (x)); } while (0)
+#define INB(x) __extension__ ({ u_int tmp = (x); inb(tmp); })
+#define INW(x) __extension__ ({ u_int tmp = (x); inw(tmp); })
+#define INL(x) __extension__ ({ u_int tmp = (x); inl(tmp); })
+#else
+#if defined(__GLIBC__)
+#include <sys/io.h>
+#endif
+#if (defined(__MACH__) && defined(__APPLE__))
+#include <DirectIO/darwinio.h>
+#endif
+#define OUTB outb
+#define OUTW outw
+#define OUTL outl
+#define INB inb
+#define INW inw
+#define INL inl
#endif
-
-#include "common.h"
-#include "cmos_lowlevel.h"
-
-/* Hardware Abstraction Layer: lowlevel byte-wise write access */
-
-typedef struct {
- void (*init)(void* data);
- unsigned char (*read)(unsigned addr);
- void (*write)(unsigned addr, unsigned char value);
- void (*set_iopl)(int level);
-} cmos_access_t;
static void cmos_hal_init(void* data);
static unsigned char cmos_hal_read(unsigned addr);
static void cmos_hal_write(unsigned addr, unsigned char value);
static void cmos_set_iopl(int level);
-static cmos_access_t cmos_hal = {
- .init = cmos_hal_init,
- .read = cmos_hal_read,
- .write = cmos_hal_write,
- .set_iopl = cmos_set_iopl,
-};
-
-static void mem_hal_init(void* data);
-static unsigned char mem_hal_read(unsigned addr);
-static void mem_hal_write(unsigned addr, unsigned char value);
-static void mem_set_iopl(int level);
-
-static cmos_access_t memory_hal = {
- .init = mem_hal_init,
- .read = mem_hal_read,
- .write = mem_hal_write,
- .set_iopl = mem_set_iopl,
-};
-
-static cmos_access_t *current_access = &cmos_hal;
-
/* no need to initialize anything */
static void cmos_hal_init(__attribute__((unused)) void *data)
{
@@ -112,235 +71,9 @@
OUTB(value, port_1);
}
-static unsigned char* mem_hal_data = (unsigned char*)-1;
-static void mem_hal_init(void *data)
-{
- mem_hal_data = data;
-}
-
-static unsigned char mem_hal_read(unsigned index)
-{
- assert(mem_hal_data != (unsigned char*)-1);
- return mem_hal_data[index];
-}
-
-static void mem_hal_write(unsigned index, unsigned char value)
-{
- assert(mem_hal_data != (unsigned char*)-1);
- mem_hal_data[index] = value;
-}
-
-void select_hal(hal_t hal, void *data)
-{
- switch(hal) {
- case HAL_CMOS:
- current_access = &cmos_hal;
- break;
- case HAL_MEMORY:
- current_access = &memory_hal;
- break;
- }
- current_access->init(data);
-}
-
-/* Bit-level access */
-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 += ((unsigned long long)(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(const cmos_entry_t * e)
-{
- cmos_bit_op_location_t where;
- unsigned bit = e->bit, length = e->length;
- unsigned next_bit, bits_left, nr_bits;
- unsigned long long result = 0;
- unsigned char value;
-
- assert(!verify_cmos_op(bit, length, e->config));
- result = 0;
-
- if (e->config == CMOS_ENTRY_STRING) {
- char *newstring = calloc(1, (length + 7) / 8);
- unsigned usize = (8 * sizeof(unsigned long long));
-
- if (!newstring) {
- out_of_memory();
- }
-
- 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 > usize ? usize : bits_left, &where);
- value = cmos_read_bits(&where, nr_bits);
- put_bits(value, next_bit % usize, nr_bits,
- &((unsigned long long *)newstring)[next_bit /
- usize]);
- result = (unsigned long)newstring;
- }
- } else {
- 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(const cmos_entry_t * e, unsigned long long value)
-{
- cmos_bit_op_location_t where;
- unsigned bit = e->bit, length = e->length;
- unsigned next_bit, bits_left, nr_bits;
-
- assert(!verify_cmos_op(bit, length, e->config));
-
- if (e->config == CMOS_ENTRY_STRING) {
- unsigned long long *data =
- (unsigned long long *)(unsigned long)value;
- unsigned usize = (8 * sizeof(unsigned long long));
-
- 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 > usize ? usize : bits_left,
- &where);
- value = data[next_bit / usize];
- cmos_write_bits(&where, nr_bits,
- get_bits(value, next_bit % usize, nr_bits));
- }
- } else {
- 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)
-{
- return current_access->read(index);
-}
-
-/****************************************************************************
- * 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)
-{
- current_access->write(index, value);
-}
-
-/****************************************************************************
- * 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
+ * cmos_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
@@ -348,11 +81,6 @@
* interrupts while executing in user space. Messing with the I/O privilege
* level is therefore somewhat dangerous.
****************************************************************************/
-void set_iopl(int level)
-{
- current_access->set_iopl(level);
-}
-
static void cmos_set_iopl(int level)
{
#if defined(__FreeBSD__)
@@ -385,84 +113,10 @@
#endif
}
-static void mem_set_iopl(__attribute__ ((unused)) int level)
-{
-}
-
-/****************************************************************************
- * 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, cmos_entry_config_t config)
-{
- 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 (config == CMOS_ENTRY_STRING)
- return OK;
-
- 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;
- }
+cmos_access_t cmos_hal = {
+ .init = cmos_hal_init,
+ .read = cmos_hal_read,
+ .write = cmos_hal_write,
+ .set_iopl = cmos_set_iopl,
+};
- 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);
-}
Copied and modified: trunk/util/nvramtool/accessors/cmos-mem.c (from r6311, trunk/util/nvramtool/cmos_lowlevel.c)
==============================================================================
--- trunk/util/nvramtool/cmos_lowlevel.c Fri Jan 28 08:47:35 2011 (r6311, copy source)
+++ trunk/util/nvramtool/accessors/cmos-mem.c Fri Jan 28 08:54:11 2011 (r6313)
@@ -1,117 +1,11 @@
-/*****************************************************************************\
- * cmos_lowlevel.c
- *****************************************************************************
- * Copyright (C) 2002-2005 The Regents of the University of California.
- * Produced at the Lawrence Livermore National Laboratory.
- * Written by David S. Peterson <dsp at llnl.gov> <dave_peterson at pobox.com>.
- * UCRL-CODE-2003-012
- * All rights reserved.
- *
- * This file is part of nvramtool, a utility for reading/writing coreboot
- * parameters and displaying information from the coreboot table.
- * For details, see http://coreboot.org/nvramtool.
- *
- * 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.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-\*****************************************************************************/
-
-#if defined(__FreeBSD__)
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#include "common.h"
+#include <assert.h>
#include "cmos_lowlevel.h"
-/* Hardware Abstraction Layer: lowlevel byte-wise write access */
-
-typedef struct {
- void (*init)(void* data);
- unsigned char (*read)(unsigned addr);
- void (*write)(unsigned addr, unsigned char value);
- void (*set_iopl)(int level);
-} cmos_access_t;
-
-static void cmos_hal_init(void* data);
-static unsigned char cmos_hal_read(unsigned addr);
-static void cmos_hal_write(unsigned addr, unsigned char value);
-static void cmos_set_iopl(int level);
-
-static cmos_access_t cmos_hal = {
- .init = cmos_hal_init,
- .read = cmos_hal_read,
- .write = cmos_hal_write,
- .set_iopl = cmos_set_iopl,
-};
-
static void mem_hal_init(void* data);
static unsigned char mem_hal_read(unsigned addr);
static void mem_hal_write(unsigned addr, unsigned char value);
static void mem_set_iopl(int level);
-static cmos_access_t memory_hal = {
- .init = mem_hal_init,
- .read = mem_hal_read,
- .write = mem_hal_write,
- .set_iopl = mem_set_iopl,
-};
-
-static cmos_access_t *current_access = &cmos_hal;
-
-/* no need to initialize anything */
-static void cmos_hal_init(__attribute__((unused)) void *data)
-{
-}
-
-static unsigned char cmos_hal_read(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);
-}
-
-static void cmos_hal_write(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);
-}
-
static unsigned char* mem_hal_data = (unsigned char*)-1;
static void mem_hal_init(void *data)
{
@@ -130,339 +24,14 @@
mem_hal_data[index] = value;
}
-void select_hal(hal_t hal, void *data)
-{
- switch(hal) {
- case HAL_CMOS:
- current_access = &cmos_hal;
- break;
- case HAL_MEMORY:
- current_access = &memory_hal;
- break;
- }
- current_access->init(data);
-}
-
-/* Bit-level access */
-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 += ((unsigned long long)(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(const cmos_entry_t * e)
-{
- cmos_bit_op_location_t where;
- unsigned bit = e->bit, length = e->length;
- unsigned next_bit, bits_left, nr_bits;
- unsigned long long result = 0;
- unsigned char value;
-
- assert(!verify_cmos_op(bit, length, e->config));
- result = 0;
-
- if (e->config == CMOS_ENTRY_STRING) {
- char *newstring = calloc(1, (length + 7) / 8);
- unsigned usize = (8 * sizeof(unsigned long long));
-
- if (!newstring) {
- out_of_memory();
- }
-
- 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 > usize ? usize : bits_left, &where);
- value = cmos_read_bits(&where, nr_bits);
- put_bits(value, next_bit % usize, nr_bits,
- &((unsigned long long *)newstring)[next_bit /
- usize]);
- result = (unsigned long)newstring;
- }
- } else {
- 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(const cmos_entry_t * e, unsigned long long value)
-{
- cmos_bit_op_location_t where;
- unsigned bit = e->bit, length = e->length;
- unsigned next_bit, bits_left, nr_bits;
-
- assert(!verify_cmos_op(bit, length, e->config));
-
- if (e->config == CMOS_ENTRY_STRING) {
- unsigned long long *data =
- (unsigned long long *)(unsigned long)value;
- unsigned usize = (8 * sizeof(unsigned long long));
-
- 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 > usize ? usize : bits_left,
- &where);
- value = data[next_bit / usize];
- cmos_write_bits(&where, nr_bits,
- get_bits(value, next_bit % usize, nr_bits));
- }
- } else {
- 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)
-{
- return current_access->read(index);
-}
-
-/****************************************************************************
- * 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)
-{
- current_access->write(index, value);
-}
-
-/****************************************************************************
- * 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)
-{
- current_access->set_iopl(level);
-}
-
-static void cmos_set_iopl(int level)
-{
-#if defined(__FreeBSD__)
- static int io_fd = -1;
-#endif
-
- assert((level >= 0) && (level <= 3));
-
-#if defined(__FreeBSD__)
- if (level == 0) {
- if (io_fd != -1) {
- close(io_fd);
- io_fd = -1;
- }
- } else {
- if (io_fd == -1) {
- io_fd = open("/dev/io", O_RDWR);
- if (io_fd < 0) {
- perror("/dev/io");
- exit(1);
- }
- }
- }
-#else
- if (iopl(level)) {
- fprintf(stderr, "%s: iopl() system call failed. "
- "You must be root to do this.\n", prog_name);
- exit(1);
- }
-#endif
-}
-
static void mem_set_iopl(__attribute__ ((unused)) int level)
{
}
-/****************************************************************************
- * 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, cmos_entry_config_t config)
-{
- 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 (config == CMOS_ENTRY_STRING)
- return OK;
-
- 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;
- }
+cmos_access_t memory_hal = {
+ .init = mem_hal_init,
+ .read = mem_hal_read,
+ .write = mem_hal_write,
+ .set_iopl = mem_set_iopl,
+};
- 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);
-}
Modified: trunk/util/nvramtool/cmos_lowlevel.c
==============================================================================
--- trunk/util/nvramtool/cmos_lowlevel.c Fri Jan 28 08:50:33 2011 (r6312)
+++ trunk/util/nvramtool/cmos_lowlevel.c Fri Jan 28 08:54:11 2011 (r6313)
@@ -38,98 +38,9 @@
/* Hardware Abstraction Layer: lowlevel byte-wise write access */
-typedef struct {
- void (*init)(void* data);
- unsigned char (*read)(unsigned addr);
- void (*write)(unsigned addr, unsigned char value);
- void (*set_iopl)(int level);
-} cmos_access_t;
-
-static void cmos_hal_init(void* data);
-static unsigned char cmos_hal_read(unsigned addr);
-static void cmos_hal_write(unsigned addr, unsigned char value);
-static void cmos_set_iopl(int level);
-
-static cmos_access_t cmos_hal = {
- .init = cmos_hal_init,
- .read = cmos_hal_read,
- .write = cmos_hal_write,
- .set_iopl = cmos_set_iopl,
-};
-
-static void mem_hal_init(void* data);
-static unsigned char mem_hal_read(unsigned addr);
-static void mem_hal_write(unsigned addr, unsigned char value);
-static void mem_set_iopl(int level);
-
-static cmos_access_t memory_hal = {
- .init = mem_hal_init,
- .read = mem_hal_read,
- .write = mem_hal_write,
- .set_iopl = mem_set_iopl,
-};
-
+extern cmos_access_t cmos_hal, memory_hal;
static cmos_access_t *current_access = &cmos_hal;
-/* no need to initialize anything */
-static void cmos_hal_init(__attribute__((unused)) void *data)
-{
-}
-
-static unsigned char cmos_hal_read(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);
-}
-
-static void cmos_hal_write(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);
-}
-
-static unsigned char* mem_hal_data = (unsigned char*)-1;
-static void mem_hal_init(void *data)
-{
- mem_hal_data = data;
-}
-
-static unsigned char mem_hal_read(unsigned index)
-{
- assert(mem_hal_data != (unsigned char*)-1);
- return mem_hal_data[index];
-}
-
-static void mem_hal_write(unsigned index, unsigned char value)
-{
- assert(mem_hal_data != (unsigned char*)-1);
- mem_hal_data[index] = value;
-}
-
void select_hal(hal_t hal, void *data)
{
switch(hal) {
@@ -353,42 +264,6 @@
current_access->set_iopl(level);
}
-static void cmos_set_iopl(int level)
-{
-#if defined(__FreeBSD__)
- static int io_fd = -1;
-#endif
-
- assert((level >= 0) && (level <= 3));
-
-#if defined(__FreeBSD__)
- if (level == 0) {
- if (io_fd != -1) {
- close(io_fd);
- io_fd = -1;
- }
- } else {
- if (io_fd == -1) {
- io_fd = open("/dev/io", O_RDWR);
- if (io_fd < 0) {
- perror("/dev/io");
- exit(1);
- }
- }
- }
-#else
- if (iopl(level)) {
- fprintf(stderr, "%s: iopl() system call failed. "
- "You must be root to do this.\n", prog_name);
- exit(1);
- }
-#endif
-}
-
-static void mem_set_iopl(__attribute__ ((unused)) int level)
-{
-}
-
/****************************************************************************
* verify_cmos_op
*
Modified: trunk/util/nvramtool/cmos_lowlevel.h
==============================================================================
--- trunk/util/nvramtool/cmos_lowlevel.h Fri Jan 28 08:50:33 2011 (r6312)
+++ trunk/util/nvramtool/cmos_lowlevel.h Fri Jan 28 08:54:11 2011 (r6313)
@@ -34,6 +34,13 @@
#include "common.h"
#include "layout.h"
+typedef struct {
+ void (*init)(void* data);
+ unsigned char (*read)(unsigned addr);
+ void (*write)(unsigned addr, unsigned char value);
+ void (*set_iopl)(int level);
+} cmos_access_t;
+
typedef enum { HAL_CMOS, HAL_MEMORY } hal_t;
void select_hal(hal_t hal, void *data);
Modified: trunk/util/nvramtool/common.h
==============================================================================
--- trunk/util/nvramtool/common.h Fri Jan 28 08:50:33 2011 (r6312)
+++ trunk/util/nvramtool/common.h Fri Jan 28 08:54:11 2011 (r6313)
@@ -43,30 +43,6 @@
#include <string.h>
#include <ctype.h>
-#if defined(__FreeBSD__)
-#include <sys/types.h>
-#include <machine/cpufunc.h>
-#define OUTB(x, y) do { u_int tmp = (y); outb(tmp, (x)); } while (0)
-#define OUTW(x, y) do { u_int tmp = (y); outw(tmp, (x)); } while (0)
-#define OUTL(x, y) do { u_int tmp = (y); outl(tmp, (x)); } while (0)
-#define INB(x) __extension__ ({ u_int tmp = (x); inb(tmp); })
-#define INW(x) __extension__ ({ u_int tmp = (x); inw(tmp); })
-#define INL(x) __extension__ ({ u_int tmp = (x); inl(tmp); })
-#else
-#if defined(__GLIBC__)
-#include <sys/io.h>
-#endif
-#if (defined(__MACH__) && defined(__APPLE__))
-#include <DirectIO/darwinio.h>
-#endif
-#define OUTB outb
-#define OUTW outw
-#define OUTL outl
-#define INB inb
-#define INW inw
-#define INL inl
-#endif
-
#define FALSE 0
#define TRUE 1
More information about the coreboot
mailing list