This repository was archived by the owner on Jan 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMmio.java
More file actions
353 lines (322 loc) · 12.2 KB
/
Copy pathMmio.java
File metadata and controls
353 lines (322 loc) · 12.2 KB
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
/*
* Copyright (c) Steven P. Goldsmith. All rights reserved.
*/
package com.codeferm.periphery;
import static com.codeferm.periphery.Common.MAX_CHAR_ARRAY_LEN;
import static com.codeferm.periphery.Common.jString;
import static com.codeferm.periphery.Common.memMove;
import static org.fusesource.hawtjni.runtime.FieldFlag.CONSTANT;
import org.fusesource.hawtjni.runtime.JniClass;
import org.fusesource.hawtjni.runtime.JniField;
import org.fusesource.hawtjni.runtime.JniMethod;
import org.fusesource.hawtjni.runtime.Library;
import static org.fusesource.hawtjni.runtime.MethodFlag.CONSTANT_INITIALIZER;
/**
* c-periphery MMIO wrapper functions for the Linux userspace /dev/mem device.
*
* @author Steven P. Goldsmith
* @version 1.0.0
* @since 1.0.0
*/
@JniClass
public class Mmio implements AutoCloseable {
/**
* Function was successful.
*/
public static final int MMIO_SUCCESS = 0;
/**
* java-periphery library.
*/
private static final Library LIBRARY = new Library("java-periphery", Mmio.class);
/**
* MMIO handle.
*/
final private long handle;
/**
* Load library.
*/
static {
LIBRARY.load();
init();
}
/**
* Load constants.
*/
@JniMethod(flags = {CONSTANT_INITIALIZER})
private static native void init();
/**
* Error constants.
*/
@JniField(flags = {CONSTANT})
public static int MMIO_ERROR_ARG;
@JniField(flags = {CONSTANT})
public static int MMIO_ERROR_OPEN;
@JniField(flags = {CONSTANT})
public static int MMIO_ERROR_CLOSE;
/**
* Map the region of physical memory at the specified base address with the specified size.
*
* @param base Doesn't need be aligned to a page boundary.
* @param size Doesn't need be aligned to a page boundary.
*/
public Mmio(final long base, final long size) {
// Allocate handle
handle = mmioNew();
if (handle == 0) {
throw new RuntimeException("Handle cannot be NULL");
}
// Open device
if (mmioOpen(handle, base, size) != MMIO_SUCCESS) {
// Free handle before throwing exception
mmioFree(handle);
throw new RuntimeException(mmioErrMessage(handle));
}
}
/**
* Map the region of physical memory at the specified base address and size, using the specified memory character device. This
* open function can be used with sandboxed memory character devices, e.g. /dev/gpiomem.
*
* @param base Doesn't need be aligned to a page boundary.
* @param size Doesn't need be aligned to a page boundary.
* @param path MMIO path /dev/mem, /dev/gpiomem, etc.
*/
public Mmio(final long base, final long size, final String path) {
// Allocate handle
handle = mmioNew();
if (handle == 0) {
throw new RuntimeException("Handle cannot be NULL");
}
// Open device
if (mmioOpenAdvanced(handle, base, size, path) != MMIO_SUCCESS) {
// Free handle before throwing exception
mmioFree(handle);
throw new RuntimeException(mmioErrMessage(handle));
}
}
/**
* Close and free handle.
*/
@Override
public void close() {
mmioClose(handle);
mmioFree(handle);
}
/**
* Handle accessor.
*
* @return Handle.
*/
public long getHandle() {
return handle;
}
/**
* Allocate a MMIO handle. Returns a valid handle on success, or NULL on failure.
*
* @return A valid handle on success, or NULL on failure.
*/
@JniMethod(accessor = "mmio_new")
public static final native long mmioNew();
/**
* Map the region of physical memory at the specified base address with the specified size.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param base Doesn't need be aligned to a page boundary.
* @param size Doesn't need be aligned to a page boundary.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_open")
public static native int mmioOpen(long mmio, long base, long size);
/**
* Map the region of physical memory at the specified base address with the specified size.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param base Doesn't need be aligned to a page boundary.
* @param size Doesn't need be aligned to a page boundary.
* @param path MMIO path /dev/mem, /dev/gpiomem, etc.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_open_advanced")
public static native int mmioOpenAdvanced(long mmio, long base, long size, final String path);
/**
* Return the pointer to the mapped physical memory.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @return Pointer to the mapped physical memory.
*/
@JniMethod(accessor = "mmio_ptr")
public static final native long mmioPtr(long mmio);
/**
* Read 32-bits from mapped physical memory, starting at the specified byte offset, relative to the base address the MMIO handle
* was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param offset Starting offset.
* @param value Read memory.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_read32")
public static final native int mmioRead32(long mmio, long offset, int[] value);
/**
* Read 16-bits from mapped physical memory, starting at the specified byte offset, relative to the base address the MMIO handle
* was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param offset Starting offset.
* @param value Read memory.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_read16")
public static final native int mmioRead16(long mmio, long offset, short[] value);
/**
* Read 8-bits from mapped physical memory, starting at the specified byte offset, relative to the base address the MMIO handle
* was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param offset Starting offset.
* @param value Read memory.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_read8")
public static final native int mmioRead8(long mmio, long offset, byte[] value);
/**
* Read array of bytes from mapped physical memory, starting at the specified byte offset, relative to the base address the MMIO
* handle was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param offset Starting offset.
* @param buf Array of bytes read.
* @param len Amount to read.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_read")
public static final native int mmioRead(long mmio, long offset, byte[] buf, long len);
/**
* Write 32-bits to mapped physical memory, starting at the specified byte offset, relative to the base address the MMIO handle
* was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param offset Starting offset.
* @param value Value to write.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_write32")
public static final native int mmioWrite32(long mmio, long offset, int value);
/**
* Write 16-bits to mapped physical memory, starting at the specified byte offset, relative to the base address the MMIO handle
* was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param offset Starting offset.
* @param value Value to write.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_write16")
public static final native int mmioWrite16(long mmio, long offset, short value);
/**
* Write 8-bits to mapped physical memory, starting at the specified byte offset, relative to the base address the MMIO handle
* was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param offset Starting offset.
* @param value Value to write.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_write8")
public static final native int mmioWrite8(long mmio, long offset, byte value);
/**
* Write array of bytes to mapped physical memory, starting at the specified byte offset, relative to the base address the MMIO
* handle was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param offset Starting offset.
* @param buf Array of bytes write.
* @param len Amount to write.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_write")
public static final native int mmioWrite(long mmio, long offset, byte[] buf, long len);
/**
* Unmap mapped physical memory.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_close")
public static native int mmioClose(long mmio);
/**
* Free a MMIO handle.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
*/
@JniMethod(accessor = "mmio_free")
public static native void mmioFree(long mmio);
/**
* Return the base address the MMIO handle was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @return Base address.
*/
@JniMethod(accessor = "mmio_base")
public static final native long mmioBase(long mmio);
/**
* Return the base address the MMIO handle was opened with.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @return Base address.
*/
@JniMethod(accessor = "mmio_size")
public static final native long mmioSize(long mmio);
/**
*
* Return a string representation of the MMIO handle.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @param str String representation of the MMIO handle.
* @param len Length of char array.
* @return 0 on success, or a negative MMIO error code on failure.
*/
@JniMethod(accessor = "mmio_tostring")
public static native int mmioToString(long mmio, byte[] str, long len);
/**
* Return a string representation of the MMIO handle. Wraps native method and simplifies.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @return MMIO handle as String.
*/
public static String mmioToString(long mmio) {
var str = new byte[MAX_CHAR_ARRAY_LEN];
if (mmioToString(mmio, str, str.length) < 0) {
throw new RuntimeException(mmioErrMessage(mmio));
}
return jString(str);
}
/**
* Return the libc errno of the last failure that occurred.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @return libc errno.
*/
@JniMethod(accessor = "mmio_errno")
public static native int mmioErrNo(long mmio);
/**
* Return a human readable error message pointer of the last failure that occurred.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @return Error message pointer.
*/
@JniMethod(accessor = "mmio_errmsg")
public static native long mmioErrMsg(long mmio);
/**
* Return a human readable error message of the last failure that occurred. Converts const char * returned by mmio_errmsg to a
* Java String.
*
* @param mmio Valid pointer to an allocated MMIO handle structure.
* @return Error message.
*/
public static String mmioErrMessage(long mmio) {
var ptr = mmioErrMsg(mmio);
var str = new byte[MAX_CHAR_ARRAY_LEN];
memMove(str, ptr, str.length);
return jString(str);
}
}