2 #include "cmos_lowlevel.h"
4 #if defined(__FreeBSD__)
6 #include <machine/cpufunc.h>
7 #define OUTB(x, y) do { u_int tmp = (y); outb(tmp, (x)); } while (0)
8 #define OUTW(x, y) do { u_int tmp = (y); outw(tmp, (x)); } while (0)
9 #define OUTL(x, y) do { u_int tmp = (y); outl(tmp, (x)); } while (0)
10 #define INB(x) __extension__ ({ u_int tmp = (x); inb(tmp); })
11 #define INW(x) __extension__ ({ u_int tmp = (x); inw(tmp); })
12 #define INL(x) __extension__ ({ u_int tmp = (x); inl(tmp); })
14 #if defined(__GLIBC__)
17 #if (defined(__MACH__) && defined(__APPLE__))
18 #include <DirectHW/DirectHW.h>
20 #if defined(__NetBSD__)
21 #if defined(__i386__) || defined(__x86_64__)
22 #include <machine/sysarch.h>
24 static inline void outb(uint8_t value, uint16_t port)
26 asm volatile ("outb %b0,%w1": :"a" (value), "Nd" (port));
29 static inline uint8_t inb(uint16_t port)
32 asm volatile ("inb %w1,%0":"=a" (value):"Nd" (port));
36 static inline void outw(uint16_t value, uint16_t port)
38 asm volatile ("outw %w0,%w1": :"a" (value), "Nd" (port));
41 static inline uint16_t inw(uint16_t port)
44 asm volatile ("inw %w1,%0":"=a" (value):"Nd" (port));
48 static inline void outl(uint32_t value, uint16_t port)
50 asm volatile ("outl %0,%w1": :"a" (value), "Nd" (port));
53 static inline uint32_t inl(uint16_t port)
56 asm volatile ("inl %1,%0":"=a" (value):"Nd" (port));
61 #define iopl x86_64_iopl
64 #define iopl i386_iopl
75 static void cmos_hal_init(void* data);
76 static unsigned char cmos_hal_read(unsigned addr);
77 static void cmos_hal_write(unsigned addr, unsigned char value);
78 static void cmos_set_iopl(int level);
80 /* no need to initialize anything */
81 static void cmos_hal_init(__attribute__((unused)) void *data)
85 static unsigned char cmos_hal_read(unsigned index)
87 unsigned short port_0, port_1;
89 assert(!verify_cmos_byte_index(index));
103 static void cmos_hal_write(unsigned index, unsigned char value)
105 unsigned short port_0, port_1;
107 assert(!verify_cmos_byte_index(index));
122 /****************************************************************************
125 * Set the I/O privilege level of the executing process. Root privileges are
126 * required for performing this action. A sufficient I/O privilege level
127 * allows the process to access x86 I/O address space and to disable/reenable
128 * interrupts while executing in user space. Messing with the I/O privilege
129 * level is therefore somewhat dangerous.
130 ****************************************************************************/
131 static void cmos_set_iopl(int level)
133 #if defined(__FreeBSD__)
134 static int io_fd = -1;
137 assert((level >= 0) && (level <= 3));
139 #if defined(__FreeBSD__)
147 io_fd = open("/dev/io", O_RDWR);
156 fprintf(stderr, "%s: iopl() system call failed. "
157 "You must be root to do this.\n", prog_name);
163 cmos_access_t cmos_hal = {
164 .init = cmos_hal_init,
165 .read = cmos_hal_read,
166 .write = cmos_hal_write,
167 .set_iopl = cmos_set_iopl,