Add string support to nvramtool.
To add a string to your cmos.layout, you need to specify type 's': #start len type unused name 416 512 s 0 boot_devices With this patch you can do $ nvramtool -w boot_devices="(hd0,0);(hd2,1);(hd3)" And FILO will attempt to load a menu.lst from any of these devices in that order. The patch is not exactly pretty, but a cleaner solution might have resulted in a complete rewrite of the tool, which I did not want. Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Joseph Smith <joe@settoplinux.org> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3613 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
committed by
Stefan Reinauer
parent
830b17d3e3
commit
a67aab7083
@@ -1,6 +1,5 @@
|
||||
/*****************************************************************************\
|
||||
* cmos_lowlevel.c
|
||||
* $Id$
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2002-2005 The Regents of the University of California.
|
||||
* Produced at the Lawrence Livermore National Laboratory.
|
||||
@@ -70,7 +69,7 @@ static inline unsigned char get_bits (unsigned long long value, unsigned bit,
|
||||
****************************************************************************/
|
||||
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; }
|
||||
{ *result += ((unsigned long long)(value & ((unsigned char) ((1 << nr_bits) - 1)))) << bit; }
|
||||
|
||||
/****************************************************************************
|
||||
* cmos_read
|
||||
@@ -79,21 +78,39 @@ static inline void put_bits (unsigned char value, unsigned bit,
|
||||
* 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)
|
||||
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;
|
||||
unsigned long long result = 0;
|
||||
unsigned char value;
|
||||
|
||||
assert(!verify_cmos_op(bit, length));
|
||||
assert(!verify_cmos_op(bit, length, e->config));
|
||||
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);
|
||||
if (e->config == CMOS_ENTRY_STRING)
|
||||
{ char *newstring = malloc((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;
|
||||
@@ -106,17 +123,32 @@ unsigned long long cmos_read (unsigned bit, unsigned 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)
|
||||
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));
|
||||
assert(!verify_cmos_op(bit, length, e->config));
|
||||
|
||||
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));
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,13 +268,16 @@ void set_iopl (int level)
|
||||
* 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)
|
||||
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;
|
||||
|
||||
|
Reference in New Issue
Block a user