blob: 83f349eab9a90ca51873cf04db7b0949ab67782f [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
Stefan Taunerc65b8552013-09-12 15:48:39 +000040
41#if !defined (__NetBSD__) && !defined (__DragonFly__)
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +000042#include <pci/pci.h>
Stefan Taunerc65b8552013-09-12 15:48:39 +000043#else
44#include <pciutils/pci.h>
45#endif
46
Carl-Daniel Hailfinger72376832010-06-25 13:18:48 +000047#undef index
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +000048#endif
49
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000050#if defined (__i386__) || defined (__x86_64__)
51
52/* All x86 is little-endian. */
53#define __FLASHROM_LITTLE_ENDIAN__ 1
54
55#elif defined (__mips) || defined (__mips__) || defined (_mips) || defined (mips)
56
57/* MIPS can be either endian. */
58#if defined (__MIPSEL) || defined (__MIPSEL__) || defined (_MIPSEL) || defined (MIPSEL)
59#define __FLASHROM_LITTLE_ENDIAN__ 1
60#elif defined (__MIPSEB) || defined (__MIPSEB__) || defined (_MIPSEB) || defined (MIPSEB)
61#define __FLASHROM_BIG_ENDIAN__ 1
62#endif
63
64#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__)
65
66/* PowerPC can be either endian. */
67#if defined (_BIG_ENDIAN) || defined (__BIG_ENDIAN__)
68#define __FLASHROM_BIG_ENDIAN__ 1
69/* Error checking in case some weird header has #defines for LE as well. */
70#if defined (_LITTLE_ENDIAN) || defined (__LITTLE_ENDIAN__)
71#error Conflicting endianness #define
72#endif
73#else
74#error Little-endian PowerPC #defines are unknown
75#endif
76
David Hendricksb286da72012-02-13 00:35:35 +000077#elif defined (__arm__)
78#if defined (__ARMEL__)
79#define __FLASHROM_LITTLE_ENDIAN__ 1
80#else
81#error Big-endian ARM #defines are unknown
82#endif
83
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000084#endif
85
86#if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
87/* Nonstandard libc-specific macros for determining endianness. */
88#if defined(__GLIBC__)
89#include <endian.h>
90#if BYTE_ORDER == LITTLE_ENDIAN
91#define __FLASHROM_LITTLE_ENDIAN__ 1
92#elif BYTE_ORDER == BIG_ENDIAN
93#define __FLASHROM_BIG_ENDIAN__ 1
94#endif
95#endif
96#endif
97
98#if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
99#error Unable to determine endianness. Please add support for your arch or libc.
100#endif
101
102#define ___constant_swab8(x) ((uint8_t) ( \
103 (((uint8_t)(x) & (uint8_t)0xffU))))
104
105#define ___constant_swab16(x) ((uint16_t) ( \
106 (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
107 (((uint16_t)(x) & (uint16_t)0xff00U) >> 8)))
108
109#define ___constant_swab32(x) ((uint32_t) ( \
110 (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
111 (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
112 (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
113 (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
114
115#define ___constant_swab64(x) ((uint64_t) ( \
116 (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
117 (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
118 (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
119 (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
120 (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
121 (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
122 (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
123 (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
124
125#if defined (__FLASHROM_BIG_ENDIAN__)
126
127#define cpu_to_le(bits) \
128static inline uint##bits##_t cpu_to_le##bits(uint##bits##_t val) \
129{ \
130 return ___constant_swab##bits(val); \
131}
132
133cpu_to_le(8)
134cpu_to_le(16)
135cpu_to_le(32)
136cpu_to_le(64)
137
138#define cpu_to_be8
139#define cpu_to_be16
140#define cpu_to_be32
141#define cpu_to_be64
142
143#elif defined (__FLASHROM_LITTLE_ENDIAN__)
144
145#define cpu_to_be(bits) \
146static inline uint##bits##_t cpu_to_be##bits(uint##bits##_t val) \
147{ \
148 return ___constant_swab##bits(val); \
149}
150
151cpu_to_be(8)
152cpu_to_be(16)
153cpu_to_be(32)
154cpu_to_be(64)
155
156#define cpu_to_le8
157#define cpu_to_le16
158#define cpu_to_le32
159#define cpu_to_le64
160
161#else
162
163#error Could not determine endianness.
164
165#endif
166
167#define be_to_cpu8 cpu_to_be8
168#define be_to_cpu16 cpu_to_be16
169#define be_to_cpu32 cpu_to_be32
170#define be_to_cpu64 cpu_to_be64
171#define le_to_cpu8 cpu_to_le8
172#define le_to_cpu16 cpu_to_le16
173#define le_to_cpu32 cpu_to_le32
174#define le_to_cpu64 cpu_to_le64
175
Carl-Daniel Hailfinger41bea032010-07-29 13:17:37 +0000176#if NEED_PCI == 1
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000177#if defined (__i386__) || defined (__x86_64__)
178
179#define __FLASHROM_HAVE_OUTB__ 1
180
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000181/* for iopl and outb under Solaris */
182#if defined (__sun) && (defined(__i386) || defined(__amd64))
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000183#include <sys/sysi86.h>
184#include <sys/psw.h>
185#include <asm/sunddi.h>
186#endif
187
Carl-Daniel Hailfinger0d974e72010-07-17 12:54:09 +0000188/* Clarification about OUTB/OUTW/OUTL argument order:
189 * OUT[BWL](val, port)
190 */
191
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000192#if defined(__FreeBSD__) || defined(__DragonFly__)
Carl-Daniel Hailfingera5eecda2012-02-25 22:50:21 +0000193 /* Note that Debian/kFreeBSD (FreeBSD kernel with glibc) has conflicting
194 * out[bwl] definitions in machine/cpufunc.h and sys/io.h at least in some
195 * versions. Use machine/cpufunc.h only for plain FreeBSD/DragonFlyBSD.
196 */
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000197 #include <machine/cpufunc.h>
Michael Karchere7f32092010-01-12 15:36:24 +0000198 #define OUTB(x, y) do { u_int outb_tmp = (y); outb(outb_tmp, (x)); } while (0)
199 #define OUTW(x, y) do { u_int outw_tmp = (y); outw(outw_tmp, (x)); } while (0)
200 #define OUTL(x, y) do { u_int outl_tmp = (y); outl(outl_tmp, (x)); } while (0)
201 #define INB(x) __extension__ ({ u_int inb_tmp = (x); inb(inb_tmp); })
202 #define INW(x) __extension__ ({ u_int inw_tmp = (x); inw(inw_tmp); })
203 #define INL(x) __extension__ ({ u_int inl_tmp = (x); inl(inl_tmp); })
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000204#else
Carl-Daniel Hailfinger60d9bd22012-08-09 23:34:41 +0000205#if defined(__MACH__) && defined(__APPLE__)
Carl-Daniel Hailfingerf992c192010-10-06 23:16:10 +0000206 /* Header is part of the DirectHW library. */
Stefan Reinauer83704c52011-03-18 22:00:15 +0000207 #include <DirectHW/DirectHW.h>
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000208#endif
209#if defined (__sun) && (defined(__i386) || defined(__amd64))
210 /* Note different order for outb */
211 #define OUTB(x,y) outb(y, x)
212 #define OUTW(x,y) outw(y, x)
213 #define OUTL(x,y) outl(y, x)
214 #define INB inb
215 #define INW inw
216 #define INL inl
217#else
Rudolf Marek03ae5c12010-03-16 23:59:19 +0000218
219#ifdef __DJGPP__
220
221#include <pc.h>
222
223 #define OUTB(x,y) outportb(y, x)
224 #define OUTW(x,y) outportw(y, x)
225 #define OUTL(x,y) outportl(y, x)
226
227 #define INB inportb
228 #define INW inportw
229 #define INL inportl
230
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000231#else
Carl-Daniel Hailfingera5eecda2012-02-25 22:50:21 +0000232 /* This is the usual glibc interface. */
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000233 #define OUTB outb
234 #define OUTW outw
235 #define OUTL outl
236 #define INB inb
237 #define INW inw
238 #define INL inl
Rudolf Marek03ae5c12010-03-16 23:59:19 +0000239
240#endif
241
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000242#endif
243#endif
244
Carl-Daniel Hailfingerb63b0672010-07-02 17:12:50 +0000245#if defined(__NetBSD__) || defined (__OpenBSD__)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000246 #if defined(__i386__) || defined(__x86_64__)
247 #include <sys/types.h>
248 #include <machine/sysarch.h>
Stefan Tauner0554ca52013-07-25 22:54:25 +0000249 #if defined(__NetBSD__)
250 #if defined(__i386__)
251 #define iopl i386_iopl
252 #elif defined(__x86_64__)
253 #define iopl x86_64_iopl
254 #endif
255 #elif defined (__OpenBSD__)
256 #if defined(__i386__)
257 #define iopl i386_iopl
258 #elif defined(__amd64__)
259 #define iopl amd64_iopl
260 #endif
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000261 #endif
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000262
Uwe Hermann43959702010-03-13 17:28:29 +0000263static inline void outb(uint8_t value, uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000264{
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000265 __asm__ volatile ("outb %b0,%w1": :"a" (value), "Nd" (port));
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000266}
267
Uwe Hermann43959702010-03-13 17:28:29 +0000268static inline uint8_t inb(uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000269{
270 uint8_t value;
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000271 __asm__ volatile ("inb %w1,%0":"=a" (value):"Nd" (port));
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000272 return value;
273}
274
Uwe Hermann43959702010-03-13 17:28:29 +0000275static inline void outw(uint16_t value, uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000276{
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000277 __asm__ volatile ("outw %w0,%w1": :"a" (value), "Nd" (port));
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000278}
279
Uwe Hermann43959702010-03-13 17:28:29 +0000280static inline uint16_t inw(uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000281{
282 uint16_t value;
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000283 __asm__ volatile ("inw %w1,%0":"=a" (value):"Nd" (port));
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000284 return value;
285}
286
Uwe Hermann43959702010-03-13 17:28:29 +0000287static inline void outl(uint32_t value, uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000288{
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000289 __asm__ volatile ("outl %0,%w1": :"a" (value), "Nd" (port));
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000290}
291
Uwe Hermann43959702010-03-13 17:28:29 +0000292static inline uint32_t inl(uint16_t port)
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000293{
294 uint32_t value;
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000295 __asm__ volatile ("inl %1,%0":"=a" (value):"Nd" (port));
Jonathan A. Kollasch3646c8f2010-01-08 21:18:08 +0000296 return value;
297}
298 #endif
299#endif
300
Carl-Daniel Hailfinger60d9bd22012-08-09 23:34:41 +0000301#if !(defined(__MACH__) && defined(__APPLE__)) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) && !defined(__DragonFly__) && !defined(__LIBPAYLOAD__)
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000302typedef struct { uint32_t hi, lo; } msr_t;
303msr_t rdmsr(int addr);
304int wrmsr(int addr, msr_t msr);
305#endif
Carl-Daniel Hailfingera5eecda2012-02-25 22:50:21 +0000306#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000307/* FreeBSD already has conflicting definitions for wrmsr/rdmsr. */
308#undef rdmsr
309#undef wrmsr
310#define rdmsr freebsd_rdmsr
311#define wrmsr freebsd_wrmsr
312typedef struct { uint32_t hi, lo; } msr_t;
313msr_t freebsd_rdmsr(int addr);
314int freebsd_wrmsr(int addr, msr_t msr);
315#endif
Patrick Georgia9095a92010-09-30 17:03:32 +0000316#if defined(__LIBPAYLOAD__)
317#include <arch/io.h>
318#include <arch/msr.h>
319typedef struct { uint32_t hi, lo; } msr_t;
320msr_t libpayload_rdmsr(int addr);
321int libpayload_wrmsr(int addr, msr_t msr);
322#undef rdmsr
323#define rdmsr libpayload_rdmsr
324#define wrmsr libpayload_wrmsr
325#endif
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000326
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000327#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__)
328
329/* PCI port I/O is not yet implemented on PowerPC. */
330
331#elif defined (__mips) || defined (__mips__) || defined (_mips) || defined (mips)
332
333/* PCI port I/O is not yet implemented on MIPS. */
334
David Hendricksb286da72012-02-13 00:35:35 +0000335#elif defined(__arm__)
336
337/* Non memory mapped I/O is not supported on ARM. */
338
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000339#else
340
341#error Unknown architecture, please check if it supports PCI port IO.
342
343#endif
Carl-Daniel Hailfinger41bea032010-07-29 13:17:37 +0000344#endif
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000345
Carl-Daniel Hailfinger5d5c0722009-12-14 03:32:24 +0000346#endif /* !__HWACCESS_H__ */