CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/packages/bsp/sunxi-temp/mod_mmio.h
Views: 3959
1
#include <sys/mman.h>
2
#include <sys/types.h>
3
#include <sys/stat.h>
4
#include <errno.h>
5
#include <fcntl.h>
6
#include <unistd.h>
7
#include <string.h>
8
#include <stdlib.h>
9
#include <stdio.h>
10
#include <time.h>
11
#include <math.h>
12
#include <stdint.h>
13
14
struct mmio {
15
unsigned long iobase; /* getpagesize() aligned, see mmap(2) */
16
unsigned long offset; /* additional offset from iobase */
17
unsigned long range; /* N * uint32_t read/write ops. */
18
19
void *iomem;
20
size_t iosize;
21
int kmem; /* 0 - /dev/mem, 1 - /dev/kmem */
22
};
23
24
void sysDelay_us(uint16_t us)
25
{
26
struct timespec usec;
27
usec.tv_sec = 0;
28
usec.tv_nsec = us*1000;
29
nanosleep(&usec,NULL);
30
}
31
32
void sysDelay_ms(uint16_t ms)
33
{
34
struct timespec msec;
35
msec.tv_sec = 0;
36
msec.tv_nsec = ms*1000000;
37
nanosleep(&msec,NULL);
38
}
39
40
static inline uint32_t readl(void *ptr)
41
{
42
uint32_t *data = ptr;
43
return *data;
44
}
45
46
static inline void writel(uint32_t value, void *ptr)
47
{
48
uint32_t *data = ptr;
49
*data = value;
50
}
51
52
uint32_t mmio_readl(const struct mmio *io, unsigned int offset)
53
{
54
void *addr;
55
56
addr = io->iomem + io->offset + offset;
57
58
return readl(addr);
59
}
60
61
void mmio_writel(const struct mmio *io, unsigned int offset, uint32_t value)
62
{
63
void *addr;
64
65
addr = io->iomem + io->offset + offset;
66
writel(value, addr);
67
}
68
69
static void mmio_normalize(struct mmio *mo)
70
{
71
int npages = 0;
72
73
mo->iobase += mo->offset;
74
mo->offset = mo->iobase & (getpagesize() - 1);
75
mo->iobase = mo->iobase & ~(getpagesize() - 1);
76
77
npages += (mo->range * sizeof(uint32_t)) / getpagesize();
78
npages += 1;
79
mo->iosize = npages * getpagesize();
80
}
81
82
static void mmio_init(struct mmio *mo)
83
{
84
char *device;
85
int iofd;
86
87
if (!mo->kmem)
88
device = "/dev/mem";
89
else
90
device = "/dev/kmem";
91
92
iofd = open(device, O_RDWR);
93
if (iofd < 0)
94
{
95
//ie_errno("open() failed");
96
printf("open failed\n");
97
exit(-1);
98
// TODO:
99
}
100
101
mo->iomem = mmap(NULL, mo->iosize,
102
PROT_READ|PROT_WRITE,
103
MAP_SHARED,
104
iofd, mo->iobase);
105
106
if (mo->iomem == MAP_FAILED)
107
{
108
printf("can't map\n");
109
exit(-1);
110
//die_errno("can't map @ %0lX", mo->iobase);
111
}
112
113
close(iofd);
114
}
115
116
int mmio_map(struct mmio *io, unsigned long base, size_t length)
117
{
118
memset(io, 0, sizeof(*io));
119
120
io->iobase = base;
121
io->offset = 0;
122
io->range = length;
123
124
mmio_normalize(io);
125
mmio_init(io);
126
127
return 0;
128
}
129
130
void mmio_unmap(struct mmio *io)
131
{
132
if (munmap(io->iomem, io->iosize))
133
{
134
exit(-1);
135
//die_errno("can't unmap @ %lX", io->iobase);
136
}
137
138
memset(io, 0, sizeof(*io));
139
}
140
141
unsigned long mmio_read(unsigned long iobase)
142
{
143
struct mmio io;
144
uint32_t rdata;
145
146
mmio_map(&io, iobase, 0);
147
rdata = mmio_readl(&io, 0);
148
mmio_unmap(&io);
149
return rdata;
150
}
151
152
unsigned long mmio_write(unsigned long iobase, unsigned long data2)
153
{
154
struct mmio io;
155
uint32_t data;
156
157
mmio_map(&io, iobase, 0);
158
mmio_writel(&io, 0, data2);
159
data = mmio_readl(&io, 0);
160
mmio_unmap(&io);
161
if (data != data2)
162
return -1;
163
else
164
return 0;
165
}
166
167
unsigned long mmio_write2(unsigned long iobase, unsigned long data2)
168
{
169
struct mmio io;
170
uint32_t data;
171
172
mmio_map(&io, iobase, 0);
173
mmio_writel(&io, 0, data2);
174
data = mmio_readl(&io, 0);
175
mmio_unmap(&io);
176
if (data != data2)
177
return -1;
178
else
179
return 0;
180
}
181
182
void * mmiof_init(unsigned long iobase)
183
{
184
struct mmio io1;
185
unsigned long offset;
186
// unsigned long iobase;
187
unsigned long range;
188
size_t iosize;
189
void *iomem;
190
// mmio_map(&io1, 0x18040000, 0);
191
192
//memset(io1, 0, sizeof(*io1));
193
194
// iobase = 0x18040000;
195
//offset = 0;
196
range = 0;
197
198
// mmio_normalize(&io1);
199
int npages = 0;
200
201
//iobase += offset;
202
offset = iobase & (getpagesize() - 1);
203
iobase = iobase & ~(getpagesize() - 1);
204
205
npages += (range * sizeof(uint32_t)) / getpagesize();
206
npages += 1;
207
iosize = npages * getpagesize();
208
209
//mmio_init(&io1);
210
char *device;
211
int iofd;
212
213
device = "/dev/mem";
214
//device = "/dev/kmem";
215
216
iofd = open(device, O_RDWR);
217
if (iofd < 0)
218
{
219
//ie_errno("open() failed");
220
printf("open failed\n");
221
exit(-1);
222
// TODO:
223
}
224
225
iomem = mmap(NULL, iosize, PROT_READ|PROT_WRITE, MAP_SHARED, iofd, iobase);
226
227
if (iomem == MAP_FAILED)
228
{
229
printf("can't map\n");
230
exit(-1);
231
//die_errno("can't map @ %0lX", mo->iobase);
232
}
233
234
close(iofd);
235
return iomem;
236
237
}
238
239
unsigned long mmiof_read(void * iomem, unsigned long offset)
240
{
241
void *addr;
242
addr = iomem + offset;
243
unsigned long read_data = readl(addr);
244
return read_data;
245
}
246
247
void mmiof_write(void * iomem, unsigned long offset, unsigned long value)
248
{
249
void *addr;
250
addr = iomem + offset;
251
uint32_t *data = addr;
252
*data = value;
253
}
254
255
void mmiof_close(void * iomem)
256
{
257
if (munmap(iomem, 4096))
258
{
259
exit(-1);
260
//die_errno("can't unmap @ %lX", io->iobase);
261
}
262
}
263
264
265