lint/checkpatch: Add __aligned to the list of attribute notes
[coreboot2.git] / util / nvramtool / accessors / cmos-hw-unix.c
blob101f0348f2352837095beecc202a9871c31f202a
1 #include <assert.h>
2 #include "cmos_lowlevel.h"
4 #if defined(__FreeBSD__)
5 #include <sys/types.h>
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); })
13 #else
14 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
15 #include <sys/io.h>
16 #endif
17 #if (defined(__MACH__) && defined(__APPLE__))
18 #include <DirectHW/DirectHW.h>
19 #endif
20 #if defined(__NetBSD__) || defined(__OpenBSD__)
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)
31 uint8_t value;
32 asm volatile ("inb %w1,%0":"=a" (value):"Nd" (port));
33 return value;
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)
43 uint16_t value;
44 asm volatile ("inw %w1,%0":"=a" (value):"Nd" (port));
45 return value;
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)
55 uint32_t value;
56 asm volatile ("inl %1,%0":"=a" (value):"Nd" (port));
57 return value;
59 #endif
60 #ifdef __x86_64__
61 #ifdef __OpenBSD__
62 #define iopl amd64_iopl
63 #else
64 #define iopl x86_64_iopl
65 #endif
66 #endif
67 #ifdef __i386__
68 #define iopl i386_iopl
69 #endif
70 #endif
71 #define OUTB outb
72 #define OUTW outw
73 #define OUTL outl
74 #define INB inb
75 #define INW inw
76 #define INL inl
77 #endif
79 static void cmos_hal_init(void* data);
80 static unsigned char cmos_hal_read(unsigned addr);
81 static void cmos_hal_write(unsigned addr, unsigned char value);
82 static void cmos_set_iopl(int level);
84 #if defined(__i386__) || defined(__x86_64__)
86 /* no need to initialize anything */
87 static void cmos_hal_init(__attribute__((unused)) void *data)
91 static unsigned char cmos_hal_read(unsigned index)
93 unsigned short port_0, port_1;
95 assert(!verify_cmos_byte_index(index));
97 if (index < 128) {
98 port_0 = 0x70;
99 port_1 = 0x71;
100 } else {
101 port_0 = 0x72;
102 port_1 = 0x73;
105 OUTB(index, port_0);
106 return INB(port_1);
109 static void cmos_hal_write(unsigned index, unsigned char value)
111 unsigned short port_0, port_1;
113 assert(!verify_cmos_byte_index(index));
115 if (index < 128) {
116 port_0 = 0x70;
117 port_1 = 0x71;
118 } else {
119 port_0 = 0x72;
120 port_1 = 0x73;
123 OUTB(index, port_0);
124 OUTB(value, port_1);
128 /****************************************************************************
129 * cmos_set_iopl
131 * Set the I/O privilege level of the executing process. Root privileges are
132 * required for performing this action. A sufficient I/O privilege level
133 * allows the process to access x86 I/O address space and to disable/reenable
134 * interrupts while executing in user space. Messing with the I/O privilege
135 * level is therefore somewhat dangerous.
136 ****************************************************************************/
137 static void cmos_set_iopl(int level)
139 #if defined(__FreeBSD__)
140 static int io_fd = -1;
141 #endif
143 assert((level >= 0) && (level <= 3));
145 #if defined(__FreeBSD__)
146 if (level == 0) {
147 if (io_fd != -1) {
148 close(io_fd);
149 io_fd = -1;
151 } else {
152 if (io_fd == -1) {
153 io_fd = open("/dev/io", O_RDWR);
154 if (io_fd < 0) {
155 perror("/dev/io");
156 exit(1);
160 #else
161 if (iopl(level)) {
162 fprintf(stderr, "%s: iopl() system call failed. "
163 "You must be root to do this.\n", prog_name);
164 exit(1);
166 #endif
169 #else
171 /* no need to initialize anything */
172 static void cmos_hal_init(__attribute__((unused)) void *data)
174 return;
177 static unsigned char cmos_hal_read(__attribute__((unused)) unsigned index)
179 return;
182 static void cmos_hal_write(__attribute__((unused)) unsigned index,
183 __attribute__((unused)) unsigned char value)
185 return;
188 static void cmos_set_iopl(__attribute__((unused)) int level)
190 return;
193 #endif
195 cmos_access_t cmos_hal = {
196 .init = cmos_hal_init,
197 .read = cmos_hal_read,
198 .write = cmos_hal_write,
199 .set_iopl = cmos_set_iopl,