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@secunet.com Acked-by: Stefan Reinauer stefan.reinauer@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@llnl.gov dave_peterson@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@llnl.gov dave_peterson@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