blob: eea36521e8cc1f9153c8c672441f18052e4b2f66 [file] [log] [blame]
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +00001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2009 Carl-Daniel Hailfinger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Uwe Hermann43959702010-03-13 17:28:29 +000018 */
19
20/*
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +000021 * Header file for hardware access and OS abstraction. Included from flash.h.
22 */
23
24#ifndef __HWACCESS_H__
25#define __HWACCESS_H__ 1
26
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000027#if defined (__i386__) || defined (__x86_64__)
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +000028#if defined(__GLIBC__)
29#include <sys/io.h>
30#endif
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000031#endif
32
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +000033#if NEED_PCI == 1
Carl-Daniel Hailfinger72376832010-06-25 13:18:48 +000034/*
35 * libpci headers use the variable name "index" which triggers shadowing
36 * warnings on systems which have the index() function in a default #include
37 * or as builtin.
38 */
39#define index shadow_workaround_index
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +000040#include <pci/pci.h>
Carl-Daniel Hailfinger72376832010-06-25 13:18:48 +000041#undef index
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +000042#endif
43
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000044#if defined (__i386__) || defined (__x86_64__)
45
46/* All x86 is little-endian. */
47#define __FLASHROM_LITTLE_ENDIAN__ 1
48
49#elif defined (__mips) || defined (__mips__) || defined (_mips) || defined (mips)
50
51/* MIPS can be either endian. */
52#if defined (__MIPSEL) || defined (__MIPSEL__) || defined (_MIPSEL) || defined (MIPSEL)
53#define __FLASHROM_LITTLE_ENDIAN__ 1
54#elif defined (__MIPSEB) || defined (__MIPSEB__) || defined (_MIPSEB) || defined (MIPSEB)
55#define __FLASHROM_BIG_ENDIAN__ 1
56#endif
57
58#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__)
59
60/* PowerPC can be either endian. */
61#if defined (_BIG_ENDIAN) || defined (__BIG_ENDIAN__)
62#define __FLASHROM_BIG_ENDIAN__ 1
63/* Error checking in case some weird header has #defines for LE as well. */
64#if defined (_LITTLE_ENDIAN) || defined (__LITTLE_ENDIAN__)
65#error Conflicting endianness #define
66#endif
67#else
68#error Little-endian PowerPC #defines are unknown
69#endif
70
71#endif
72
73#if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
74/* Nonstandard libc-specific macros for determining endianness. */
75#if defined(__GLIBC__)
76#include <endian.h>
77#if BYTE_ORDER == LITTLE_ENDIAN
78#define __FLASHROM_LITTLE_ENDIAN__ 1
79#elif BYTE_ORDER == BIG_ENDIAN
80#define __FLASHROM_BIG_ENDIAN__ 1
81#endif
82#endif
83#endif
84
85#if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
86#error Unable to determine endianness. Please add support for your arch or libc.
87#endif
88
89#define ___constant_swab8(x) ((uint8_t) ( \
90 (((uint8_t)(x) & (uint8_t)0xffU))))
91
92#define ___constant_swab16(x) ((uint16_t) ( \
93 (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
94 (((uint16_t)(x) & (uint16_t)0xff00U) >> 8)))
95
96#define ___constant_swab32(x) ((uint32_t) ( \
97 (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
98 (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
99 (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
100 (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
101
102#define ___constant_swab64(x) ((uint64_t) ( \
103 (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
104 (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
105 (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
106 (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
107 (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
108 (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
109 (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
110 (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
111
112#if defined (__FLASHROM_BIG_ENDIAN__)
113
114#define cpu_to_le(bits) \
115static inline uint##bits##_t cpu_to_le##bits(uint##bits##_t val) \
116{ \
117 return ___constant_swab##bits(val); \
118}
119
120cpu_to_le(8)
121cpu_to_le(16)
122cpu_to_le(32)
123cpu_to_le(64)
124
125#define cpu_to_be8
126#define cpu_to_be16
127#define cpu_to_be32
128#define cpu_to_be64
129
130#elif defined (__FLASHROM_LITTLE_ENDIAN__)
131
132#define cpu_to_be(bits) \
133static inline uint##bits##_t cpu_to_be##bits(uint##bits##_t val) \
134{ \
135 return ___constant_swab##bits(val); \
136}
137
138cpu_to_be(8)
139cpu_to_be(16)
140cpu_to_be(32)
141cpu_to_be(64)
142
143#define cpu_to_le8
144#define cpu_to_le16
145#define cpu_to_le32
146#define cpu_to_le64
147
148#else
149
150#error Could not determine endianness.
151
152#endif
153
154#define be_to_cpu8 cpu_to_be8
155#define be_to_cpu16 cpu_to_be16
156#define be_to_cpu32 cpu_to_be32
157#define be_to_cpu64 cpu_to_be64
158#define le_to_cpu8 cpu_to_le8
159#define le_to_cpu16 cpu_to_le16
160#define le_to_cpu32 cpu_to_le32
161#define le_to_cpu64 cpu_to_le64
162
Carl-Daniel Hailfinger41bea032010-07-29 13:17:37 +0000163#if NEED_PCI == 1
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000164#if defined (__i386__) || defined (__x86_64__)
165
166#define __FLASHROM_HAVE_OUTB__ 1
167
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000168/* for iopl and outb under Solaris */
169#if defined (__sun) && (defined(__i386) || defined(__amd64))
170#include <strings.h>
171#include <sys/sysi86.h>
172#include <sys/psw.h>
173#include <asm/sunddi.h>
174#endif
175
176#if (defined(__MACH__) && defined(__APPLE__))
177#define __DARWIN__
178#endif
179
Carl-Daniel Hailfinger0d974e72010-07-17 12:54:09 +0000180/* Clarification about OUTB/OUTW/OUTL argument order:
181 * OUT[BWL](val, port)
182 */
183
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000184#if defined(__FreeBSD__) || defined(__DragonFly__)
185 #include <machine/cpufunc.h>
186 #define off64_t off_t
187 #define lseek64 lseek
Michael Karchere7f32092010-01-12 15:36:24 +0000188 #define OUTB(x, y) do { u_int outb_tmp = (y); outb(outb_tmp, (x)); } while (0)
189 #define OUTW(x, y) do { u_int outw_tmp = (y); outw(outw_tmp, (x)); } while (0)
190 #define OUTL(x, y) do { u_int outl_tmp = (y); outl(outl_tmp, (x)); } while (0)
191 #define INB(x) __extension__ ({ u_int inb_tmp = (x); inb(inb_tmp); })
192 #define INW(x) __extension__ ({ u_int inw_tmp = (x); inw(inw_tmp); })
193 #define INL(x) __extension__ ({ u_int inl_tmp = (x); inl(inl_tmp); })
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000194#else
195#if defined(__DARWIN__)
Carl-Daniel Hailfingerf992c192010-10-06 23:16:10 +0000196 /* Header is part of the DirectHW library. */
Stefan Reinauer83704c52011-03-18 22:00:15 +0000197 #include <DirectHW/DirectHW.h>
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000198 #define off64_t off_t
199 #define lseek64 lseek
200#endif
201#if defined (__sun) && (defined(__i386) || defined(__amd64))
202 /* Note different order for outb */
203 #define OUTB(x,y) outb(y, x)
204 #define OUTW(x,y) outw(y, x)
205 #define OUTL(x,y) outl(y, x)
206 #define INB inb
207 #define INW inw
208 #define INL inl
209#else
Rudolf Marek03ae5c12010-03-16 23:59:19 +0000210
211#ifdef __DJGPP__
212
213#include <pc.h>
214
215 #define OUTB(x,y) outportb(y, x)
216 #define OUTW(x,y) outportw(y, x)
217 #define OUTL(x,y) outportl(y, x)
218
219 #define INB inportb
220 #define INW inportw
221 #define INL inportl
222
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000223#else
Rudolf Marek03ae5c12010-03-16 23:59:19 +0000224
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000225 #define OUTB outb
226 #define OUTW outw
227 #define OUTL outl
228 #define INB inb
229 #define INW inw
230 #define INL inl
Rudolf Marek03ae5c12010-03-16 23:59:19 +0000231
232#endif
233
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000234#endif
235#endif
236
Carl-Daniel Hailfingerb63b0672010-07-02 17:12:50 +0000237#if defined(__NetBSD__) || defined (__OpenBSD__)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000238 #define off64_t off_t
239 #define lseek64 lseek
240 #if defined(__i386__) || defined(__x86_64__)
241 #include <sys/types.h>
242 #include <machine/sysarch.h>
Carl-Daniel Hailfingerb63b0672010-07-02 17:12:50 +0000243#if defined(__NetBSD__)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000244 #if defined(__i386__)
245 #define iopl i386_iopl
246 #elif defined(__x86_64__)
247 #define iopl x86_64_iopl
248 #endif
Carl-Daniel Hailfingerb63b0672010-07-02 17:12:50 +0000249#elif defined (__OpenBSD__)
250 #if defined(__i386__)
251 #define iopl i386_iopl
252 #elif defined(__amd64__)
253 #define iopl amd64_iopl
254 #endif
255#endif
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000256
Uwe Hermann43959702010-03-13 17:28:29 +0000257static inline void outb(uint8_t value, uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000258{
259 asm volatile ("outb %b0,%w1": :"a" (value), "Nd" (port));
260}
261
Uwe Hermann43959702010-03-13 17:28:29 +0000262static inline uint8_t inb(uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000263{
264 uint8_t value;
265 asm volatile ("inb %w1,%0":"=a" (value):"Nd" (port));
266 return value;
267}
268
Uwe Hermann43959702010-03-13 17:28:29 +0000269static inline void outw(uint16_t value, uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000270{
271 asm volatile ("outw %w0,%w1": :"a" (value), "Nd" (port));
272}
273
Uwe Hermann43959702010-03-13 17:28:29 +0000274static inline uint16_t inw(uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000275{
276 uint16_t value;
277 asm volatile ("inw %w1,%0":"=a" (value):"Nd" (port));
278 return value;
279}
280
Uwe Hermann43959702010-03-13 17:28:29 +0000281static inline void outl(uint32_t value, uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000282{
283 asm volatile ("outl %0,%w1": :"a" (value), "Nd" (port));
284}
285
Uwe Hermann43959702010-03-13 17:28:29 +0000286static inline uint32_t inl(uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000287{
288 uint32_t value;
289 asm volatile ("inl %1,%0":"=a" (value):"Nd" (port));
290 return value;
291}
292 #endif
293#endif
294
Patrick Georgia9095a92010-09-30 17:03:32 +0000295#if !defined(__DARWIN__) && !defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__LIBPAYLOAD__)
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000296typedef struct { uint32_t hi, lo; } msr_t;
297msr_t rdmsr(int addr);
298int wrmsr(int addr, msr_t msr);
299#endif
300#if defined(__FreeBSD__) || defined(__DragonFly__)
301/* FreeBSD already has conflicting definitions for wrmsr/rdmsr. */
302#undef rdmsr
303#undef wrmsr
304#define rdmsr freebsd_rdmsr
305#define wrmsr freebsd_wrmsr
306typedef struct { uint32_t hi, lo; } msr_t;
307msr_t freebsd_rdmsr(int addr);
308int freebsd_wrmsr(int addr, msr_t msr);
309#endif
Patrick Georgia9095a92010-09-30 17:03:32 +0000310#if defined(__LIBPAYLOAD__)
311#include <arch/io.h>
312#include <arch/msr.h>
313typedef struct { uint32_t hi, lo; } msr_t;
314msr_t libpayload_rdmsr(int addr);
315int libpayload_wrmsr(int addr, msr_t msr);
316#undef rdmsr
317#define rdmsr libpayload_rdmsr
318#define wrmsr libpayload_wrmsr
319#endif
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000320
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000321#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__)
322
323/* PCI port I/O is not yet implemented on PowerPC. */
324
325#elif defined (__mips) || defined (__mips__) || defined (_mips) || defined (mips)
326
327/* PCI port I/O is not yet implemented on MIPS. */
328
329#else
330
331#error Unknown architecture, please check if it supports PCI port IO.
332
333#endif
Carl-Daniel Hailfinger41bea032010-07-29 13:17:37 +0000334#endif
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000335
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000336#endif /* !__HWACCESS_H__ */