source: trunk/hwaccess.h @ 1507

Revision 1507, 9.4 KB checked in by hailfinger, 3 months ago (diff)

Support Debian/kFreeBSD

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@…>
Tested-by: Robert Millan <rmh@…>
Tested-by: Uwe Hermann <uwe@…>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@…>

Line 
1/*
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
18 */
19
20/*
21 * Header file for hardware access and OS abstraction. Included from flash.h.
22 */
23
24#ifndef __HWACCESS_H__
25#define __HWACCESS_H__ 1
26
27#if defined (__i386__) || defined (__x86_64__)
28#if defined(__GLIBC__)
29#include <sys/io.h>
30#endif
31#endif
32
33#if NEED_PCI == 1
34/*
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
40#include <pci/pci.h>
41#undef index
42#endif
43
44#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#elif defined (__arm__)
72#if defined (__ARMEL__)
73#define __FLASHROM_LITTLE_ENDIAN__ 1
74#else
75#error Big-endian ARM #defines are unknown
76#endif
77
78#endif
79
80#if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
81/* Nonstandard libc-specific macros for determining endianness. */
82#if defined(__GLIBC__)
83#include <endian.h>
84#if BYTE_ORDER == LITTLE_ENDIAN
85#define __FLASHROM_LITTLE_ENDIAN__ 1
86#elif BYTE_ORDER == BIG_ENDIAN
87#define __FLASHROM_BIG_ENDIAN__ 1
88#endif
89#endif
90#endif
91
92#if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
93#error Unable to determine endianness. Please add support for your arch or libc.
94#endif
95
96#define ___constant_swab8(x) ((uint8_t) (                               \
97        (((uint8_t)(x) & (uint8_t)0xffU))))
98
99#define ___constant_swab16(x) ((uint16_t) (                             \
100        (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) |                    \
101        (((uint16_t)(x) & (uint16_t)0xff00U) >> 8)))
102
103#define ___constant_swab32(x) ((uint32_t) (                             \
104        (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) |              \
105        (((uint32_t)(x) & (uint32_t)0x0000ff00UL) <<  8) |              \
106        (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >>  8) |              \
107        (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
108
109#define ___constant_swab64(x) ((uint64_t) (                             \
110        (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) |     \
111        (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) |     \
112        (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) |     \
113        (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) <<  8) |     \
114        (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >>  8) |     \
115        (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) |     \
116        (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) |     \
117        (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
118
119#if defined (__FLASHROM_BIG_ENDIAN__)
120
121#define cpu_to_le(bits)                                                 \
122static inline uint##bits##_t cpu_to_le##bits(uint##bits##_t val)        \
123{                                                                       \
124        return ___constant_swab##bits(val);                             \
125}
126
127cpu_to_le(8)
128cpu_to_le(16)
129cpu_to_le(32)
130cpu_to_le(64)
131
132#define cpu_to_be8
133#define cpu_to_be16
134#define cpu_to_be32
135#define cpu_to_be64
136
137#elif defined (__FLASHROM_LITTLE_ENDIAN__)
138
139#define cpu_to_be(bits)                                                 \
140static inline uint##bits##_t cpu_to_be##bits(uint##bits##_t val)        \
141{                                                                       \
142        return ___constant_swab##bits(val);                             \
143}
144
145cpu_to_be(8)
146cpu_to_be(16)
147cpu_to_be(32)
148cpu_to_be(64)
149
150#define cpu_to_le8
151#define cpu_to_le16
152#define cpu_to_le32
153#define cpu_to_le64
154
155#else
156
157#error Could not determine endianness.
158
159#endif
160
161#define be_to_cpu8 cpu_to_be8
162#define be_to_cpu16 cpu_to_be16
163#define be_to_cpu32 cpu_to_be32
164#define be_to_cpu64 cpu_to_be64
165#define le_to_cpu8 cpu_to_le8
166#define le_to_cpu16 cpu_to_le16
167#define le_to_cpu32 cpu_to_le32
168#define le_to_cpu64 cpu_to_le64
169
170#if NEED_PCI == 1
171#if defined (__i386__) || defined (__x86_64__)
172
173#define __FLASHROM_HAVE_OUTB__ 1
174
175/* for iopl and outb under Solaris */
176#if defined (__sun) && (defined(__i386) || defined(__amd64))
177#include <strings.h>
178#include <sys/sysi86.h>
179#include <sys/psw.h>
180#include <asm/sunddi.h>
181#endif
182
183#if (defined(__MACH__) && defined(__APPLE__))
184#define __DARWIN__
185#endif
186
187/* Clarification about OUTB/OUTW/OUTL argument order:
188 * OUT[BWL](val, port)
189 */
190
191#if defined(__FreeBSD__) || defined(__DragonFly__)
192  /* Note that Debian/kFreeBSD (FreeBSD kernel with glibc) has conflicting
193   * out[bwl] definitions in machine/cpufunc.h and sys/io.h at least in some
194   * versions. Use machine/cpufunc.h only for plain FreeBSD/DragonFlyBSD.
195   */
196  #include <machine/cpufunc.h>
197  #define off64_t off_t
198  #define lseek64 lseek
199  #define OUTB(x, y) do { u_int outb_tmp = (y); outb(outb_tmp, (x)); } while (0)
200  #define OUTW(x, y) do { u_int outw_tmp = (y); outw(outw_tmp, (x)); } while (0)
201  #define OUTL(x, y) do { u_int outl_tmp = (y); outl(outl_tmp, (x)); } while (0)
202  #define INB(x) __extension__ ({ u_int inb_tmp = (x); inb(inb_tmp); })
203  #define INW(x) __extension__ ({ u_int inw_tmp = (x); inw(inw_tmp); })
204  #define INL(x) __extension__ ({ u_int inl_tmp = (x); inl(inl_tmp); })
205#else
206#if defined(__DARWIN__)
207    /* Header is part of the DirectHW library. */
208    #include <DirectHW/DirectHW.h>
209    #define off64_t off_t
210    #define lseek64 lseek
211#endif
212#if defined (__sun) && (defined(__i386) || defined(__amd64))
213  /* Note different order for outb */
214  #define OUTB(x,y) outb(y, x)
215  #define OUTW(x,y) outw(y, x)
216  #define OUTL(x,y) outl(y, x)
217  #define INB  inb
218  #define INW  inw
219  #define INL  inl
220#else
221
222#ifdef __DJGPP__
223
224#include <pc.h>
225
226  #define OUTB(x,y) outportb(y, x)
227  #define OUTW(x,y) outportw(y, x)
228  #define OUTL(x,y) outportl(y, x)
229
230  #define INB  inportb
231  #define INW  inportw
232  #define INL  inportl
233
234#else
235  /* This is the usual glibc interface. */
236  #define OUTB outb
237  #define OUTW outw
238  #define OUTL outl
239  #define INB  inb
240  #define INW  inw
241  #define INL  inl
242
243#endif
244
245#endif
246#endif
247
248#if defined(__NetBSD__) || defined (__OpenBSD__)
249  #define off64_t off_t
250  #define lseek64 lseek
251  #if defined(__i386__) || defined(__x86_64__)
252    #include <sys/types.h>
253    #include <machine/sysarch.h>
254#if defined(__NetBSD__)
255    #if defined(__i386__)
256      #define iopl i386_iopl
257    #elif defined(__x86_64__)
258      #define iopl x86_64_iopl
259    #endif
260#elif defined (__OpenBSD__)
261    #if defined(__i386__)
262      #define iopl i386_iopl
263    #elif defined(__amd64__)
264      #define iopl amd64_iopl
265    #endif
266#endif
267
268static inline void outb(uint8_t value, uint16_t port)
269{
270        asm volatile ("outb %b0,%w1": :"a" (value), "Nd" (port));
271}
272
273static inline uint8_t inb(uint16_t port)
274{
275        uint8_t value;
276        asm volatile ("inb %w1,%0":"=a" (value):"Nd" (port));
277        return value;
278}
279
280static inline void outw(uint16_t value, uint16_t port)
281{
282        asm volatile ("outw %w0,%w1": :"a" (value), "Nd" (port));
283}
284
285static inline uint16_t inw(uint16_t port)
286{
287        uint16_t value;
288        asm volatile ("inw %w1,%0":"=a" (value):"Nd" (port));
289        return value;
290}
291
292static inline void outl(uint32_t value, uint16_t port)
293{
294        asm volatile ("outl %0,%w1": :"a" (value), "Nd" (port));
295}
296
297static inline uint32_t inl(uint16_t port)
298{
299        uint32_t value;
300        asm volatile ("inl %1,%0":"=a" (value):"Nd" (port));
301        return value;
302}
303  #endif
304#endif
305
306#if !defined(__DARWIN__) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) && !defined(__DragonFly__) && !defined(__LIBPAYLOAD__)
307typedef struct { uint32_t hi, lo; } msr_t;
308msr_t rdmsr(int addr);
309int wrmsr(int addr, msr_t msr);
310#endif
311#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
312/* FreeBSD already has conflicting definitions for wrmsr/rdmsr. */
313#undef rdmsr
314#undef wrmsr
315#define rdmsr freebsd_rdmsr
316#define wrmsr freebsd_wrmsr
317typedef struct { uint32_t hi, lo; } msr_t;
318msr_t freebsd_rdmsr(int addr);
319int freebsd_wrmsr(int addr, msr_t msr);
320#endif
321#if defined(__LIBPAYLOAD__)
322#include <arch/io.h>
323#include <arch/msr.h>
324typedef struct { uint32_t hi, lo; } msr_t;
325msr_t libpayload_rdmsr(int addr);
326int libpayload_wrmsr(int addr, msr_t msr);
327#undef rdmsr
328#define rdmsr libpayload_rdmsr
329#define wrmsr libpayload_wrmsr
330#endif
331
332#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__)
333
334/* PCI port I/O is not yet implemented on PowerPC. */
335
336#elif defined (__mips) || defined (__mips__) || defined (_mips) || defined (mips)
337
338/* PCI port I/O is not yet implemented on MIPS. */
339
340#elif defined(__arm__)
341
342/* Non memory mapped I/O is not supported on ARM. */
343
344#else
345
346#error Unknown architecture, please check if it supports PCI port IO.
347
348#endif
349#endif
350
351#endif /* !__HWACCESS_H__ */
Note: See TracBrowser for help on using the repository browser.