forked from uARM-Palm/uARM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmem.c
executable file
·99 lines (66 loc) · 2.03 KB
/
mem.c
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
//(c) uARM project https://github.com/uARM-Palm/uARM [email protected]
#include <string.h>
#include <stdlib.h>
#include "util.h"
#include "mem.h"
#define NUM_MEM_REGIONS 128
struct ArmMemRegion {
uint32_t pa;
uint32_t sz;
ArmMemAccessF aF;
void* uD;
};
struct ArmMem {
struct ArmMemRegion regions[NUM_MEM_REGIONS];
};
struct ArmMem *memInit(void)
{
struct ArmMem *mem = (struct ArmMem*)malloc(sizeof(*mem));
if (!mem)
ERR("cannot alloc MEM");
memset(mem, 0, sizeof (*mem));
return mem;
}
void memDeinit(struct ArmMem *mem)
{
(void)mem;
}
bool memRegionAdd(struct ArmMem *mem, uint32_t pa, uint32_t sz, ArmMemAccessF aF, void* uD)
{
uint_fast8_t i;
//check for intersection with another region
for (i = 0; i < NUM_MEM_REGIONS; i++) {
if (!mem->regions[i].sz)
continue;
if ((mem->regions[i].pa <= pa && mem->regions[i].pa + mem->regions[i].sz > pa) || (pa <= mem->regions[i].pa && pa + sz > mem->regions[i].pa))
return false; //intersection -> fail
}
//find a free region and put it there
for (i = 0; i < NUM_MEM_REGIONS; i++) {
if (mem->regions[i].sz == 0) {
mem->regions[i].pa = pa;
mem->regions[i].sz = sz;
mem->regions[i].aF = aF;
mem->regions[i].uD = uD;
return true;
}
}
//fail miserably
return false;
}
bool memAccess(struct ArmMem *mem, uint32_t addr, uint_fast8_t size, uint_fast8_t accessType, void* buf)
{
bool ret = false, wantWrite = !!(accessType &~ MEM_ACCCESS_FLAG_NOERROR);
uint_fast8_t i;
for (i = 0; i < NUM_MEM_REGIONS; i++) {
if (mem->regions[i].pa <= addr && mem->regions[i].pa + mem->regions[i].sz > addr) {
ret = mem->regions[i].aF(mem->regions[i].uD, addr, size, wantWrite, buf);
break;
}
}
if (!ret && !(accessType & MEM_ACCCESS_FLAG_NOERROR)) {
fprintf(stderr, "Memory %s of %u bytes to PA 0x%08lx fails\n", wantWrite ? "write" : "read", size, (unsigned long)addr);
while(1); //make debugging easier
}
return ret;
}