From 1e916e076640c133dd32d69804325db02f1707be Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Fri, 28 Jan 2011 07:54:11 +0000 Subject: Move CMOS handling into separate files in accessors Signed-off-by: Patrick Georgi Acked-by: Stefan Reinauer git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6313 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- util/nvramtool/accessors/cmos-hw-unix.c | 122 ++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 util/nvramtool/accessors/cmos-hw-unix.c (limited to 'util/nvramtool/accessors/cmos-hw-unix.c') diff --git a/util/nvramtool/accessors/cmos-hw-unix.c b/util/nvramtool/accessors/cmos-hw-unix.c new file mode 100644 index 0000000000..06855d72df --- /dev/null +++ b/util/nvramtool/accessors/cmos-hw-unix.c @@ -0,0 +1,122 @@ +#include +#include "cmos_lowlevel.h" + +#if defined(__FreeBSD__) +#include +#include +#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 +#endif +#if (defined(__MACH__) && defined(__APPLE__)) +#include +#endif +#define OUTB outb +#define OUTW outw +#define OUTL outl +#define INB inb +#define INW inw +#define INL inl +#endif + +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); + +/* 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); +} + + +/**************************************************************************** + * 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 + * 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. + ****************************************************************************/ +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 +} + +cmos_access_t cmos_hal = { + .init = cmos_hal_init, + .read = cmos_hal_read, + .write = cmos_hal_write, + .set_iopl = cmos_set_iopl, +}; + -- cgit v1.2.3