summaryrefslogtreecommitdiff
path: root/roms/openbios/include/arch/sparc32/io.h
blob: 2241bb4dcb4ce56002a6b91d2ecfafc25f48a294 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#ifndef _ASM_IO_H
#define _ASM_IO_H

#include "asm/types.h"

extern unsigned int va_shift; // Set in entry.S

// Defined in ldscript
extern char _start, _data, _stack, _estack, _end, _vmem, _evmem, _iomem;

// XXX check use and merge
#define phys_to_virt(phys) ((void *) ((unsigned long) (phys)))
#define virt_to_phys(virt) ((unsigned long) (virt))

#ifndef BOOTSTRAP

#ifndef _IO_BASE
#define _IO_BASE	0
#endif

/*
 * The insw/outsw/insl/outsl macros don't do byte-swapping.
 * They are only used in practice for transferring buffers which
 * are arrays of bytes, and byte-swapping is not appropriate in
 * that case.  - paulus
 */
#define insw(port, buf, ns)	_insw_ns((uint16_t *)((port)+_IO_BASE), (buf), (ns))
#define outsw(port, buf, ns)	_outsw_ns((uint16_t *)((port)+_IO_BASE), (buf), (ns))

#define inb(port)		in_8((uint8_t *)((port)+_IO_BASE))
#define outb(val, port)		out_8((uint8_t *)((port)+_IO_BASE), (val))
#define inw(port)		in_le16((uint16_t *)((port)+_IO_BASE))
#define outw(val, port)		out_le16((uint16_t *)((port)+_IO_BASE), (val))
#define inl(port)		in_le32((uint32_t *)((port)+_IO_BASE))
#define outl(val, port)		out_le32((uint32_t *)((port)+_IO_BASE), (val))

/*
 * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
 */
static inline int in_8(volatile unsigned char *addr)
{
    int ret;

    __asm__ __volatile__("ldub [%1], %0\n\t"
                         "stbar\n\t"
                         :"=r"(ret):"r"(addr):"memory");

    return ret;
}

static inline void out_8(volatile unsigned char *addr, int val)
{
    __asm__ __volatile__("stb %0, [%1]\n\t"
                         "stbar\n\t"
                         : : "r"(val), "r"(addr):"memory");
}

static inline int in_le16(volatile unsigned short *addr)
{
    int ret;

    // XXX
    __asm__ __volatile__("lduh [%1], %0\n\t"
                         "stbar\n\t"
                         :"=r"(ret):"r"(addr):"memory");

    return ret;
}

static inline int in_be16(volatile unsigned short *addr)
{
    int ret;

    __asm__ __volatile__("lduh [%1], %0\n\t"
                         "stbar\n\t"
                         :"=r"(ret):"r"(addr):"memory");

    return ret;
}

static inline void out_le16(volatile unsigned short *addr, int val)
{
    // XXX
    __asm__ __volatile__("sth %0, [%1]\n\t"
                         "stbar\n\t"
                         : : "r"(val), "r"(addr):"memory");
}

static inline void out_be16(volatile unsigned short *addr, int val)
{
    __asm__ __volatile__("sth %0, [%1]\n\t"
                         "stbar\n\t"
                         : : "r"(val), "r"(addr):"memory");
}

static inline unsigned in_le32(volatile unsigned *addr)
{
    unsigned ret;

    // XXX
    __asm__ __volatile__("ld [%1], %0\n\t"
                         "stbar\n\t"
                         :"=r"(ret):"r"(addr):"memory");

    return ret;
}

static inline unsigned in_be32(volatile unsigned *addr)
{
    unsigned ret;

    __asm__ __volatile__("ld [%1], %0\n\t"
                         "stbar\n\t"
                         :"=r"(ret):"r"(addr):"memory");

    return ret;
}

static inline void out_le32(volatile unsigned *addr, int val)
{
    // XXX
    __asm__ __volatile__("st %0, [%1]\n\t"
                         "stbar\n\t"
                         : : "r"(val), "r"(addr):"memory");
}

static inline void out_be32(volatile unsigned *addr, int val)
{
    __asm__ __volatile__("st %0, [%1]\n\t"
                         "stbar\n\t"
                         : : "r"(val), "r"(addr):"memory");
}

static inline void _insw_ns(volatile uint16_t * port, void *buf, int ns)
{
	uint16_t *b = (uint16_t *) buf;

	while (ns > 0) {
		*b++ = in_le16(port);
		ns--;
	}
}

static inline void _outsw_ns(volatile uint16_t * port, const void *buf,
			     int ns)
{
	uint16_t *b = (uint16_t *) buf;

	while (ns > 0) {
		out_le16(port, *b++);
		ns--;
	}
}

static inline void _insw(volatile uint16_t * port, void *buf, int ns)
{
	uint16_t *b = (uint16_t *) buf;

	while (ns > 0) {
		*b++ = in_be16(port);
		ns--;
	}
}

static inline void _outsw(volatile uint16_t * port, const void *buf,
			  int ns)
{
	uint16_t *b = (uint16_t *) buf;

	while (ns > 0) {
		out_be16(port, *b++);
		ns--;
	}
}
#else /* BOOTSTRAP */
#ifdef FCOMPILER
#define inb(reg) ((u8)0xff)
#define inw(reg) ((u16)0xffff)
#define inl(reg) ((u32)0xffffffff)
#define outb(reg, val) do{} while(0)
#define outw(reg, val) do{} while(0)
#define outl(reg, val) do{} while(0)
#else
extern u8 inb(u32 reg);
extern u16 inw(u32 reg);
extern u32 inl(u32 reg);
extern void insw(u32 reg, void *addr, unsigned long count);
extern void outb(u32 reg, u8 val);
extern void outw(u32 reg, u16 val);
extern void outl(u32 reg, u32 val);
extern void outsw(u32 reg, const void *addr, unsigned long count);
#endif
#endif
#endif /* _ASM_IO_H */