-
Notifications
You must be signed in to change notification settings - Fork 8
/
RAM.c
executable file
·142 lines (103 loc) · 3.51 KB
/
RAM.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
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
//(c) uARM project https://github.com/uARM-Palm/uARM [email protected]
#include <string.h>
#include <stdlib.h>
#include "endian.h"
#include "util.h"
#include "mem.h"
#include "RAM.h"
struct ArmRam {
uint32_t adr;
uint32_t sz;
uint32_t* buf;
};
static bool ramAccessF(void* userData, uint32_t pa, uint_fast8_t size, bool write, void* bufP)
{
struct ArmRam *ram = (struct ArmRam*)userData;
uint8_t *addr = (uint8_t*)ram->buf;
pa -= ram->adr;
if (pa >= ram->sz)
return false;
addr += pa;
if (write) {
switch (size) {
case 1:
*((uint8_t*)addr) = *(uint8_t*)bufP; //our memory system is little-endian
break;
case 2:
*((uint16_t*)addr) = htole16(*(uint16_t*)bufP); //our memory system is little-endian
break;
case 4:
*((uint32_t*)addr) = htole32(*(uint32_t*)bufP);
break;
case 8:
*((uint32_t*)(addr + 0)) = htole32(((uint32_t*)bufP)[0]);
*((uint32_t*)(addr + 4)) = htole32(((uint32_t*)bufP)[1]);
break;
case 32:
*((uint32_t*)(addr + 0)) = htole32(((uint32_t*)bufP)[0]);
*((uint32_t*)(addr + 4)) = htole32(((uint32_t*)bufP)[1]);
*((uint32_t*)(addr + 8)) = htole32(((uint32_t*)bufP)[2]);
*((uint32_t*)(addr + 12)) = htole32(((uint32_t*)bufP)[3]);
*((uint32_t*)(addr + 16)) = htole32(((uint32_t*)bufP)[4]);
*((uint32_t*)(addr + 20)) = htole32(((uint32_t*)bufP)[5]);
*((uint32_t*)(addr + 24)) = htole32(((uint32_t*)bufP)[6]);
*((uint32_t*)(addr + 28)) = htole32(((uint32_t*)bufP)[7]);
break;
default:
return false;
}
}
else {
switch (size) {
case 1:
*(uint8_t*)bufP = *((uint8_t*)addr);
break;
case 2:
*(uint16_t*)bufP = le16toh(*((uint16_t*)addr));
break;
case 4:
*(uint32_t*)bufP = le32toh(*((uint32_t*)addr));
break;
case 64:
((uint32_t*)bufP)[ 8] = le32toh(*((uint32_t*)(addr + 32)));
((uint32_t*)bufP)[ 9] = le32toh(*((uint32_t*)(addr + 36)));
((uint32_t*)bufP)[10] = le32toh(*((uint32_t*)(addr + 40)));
((uint32_t*)bufP)[11] = le32toh(*((uint32_t*)(addr + 44)));
((uint32_t*)bufP)[12] = le32toh(*((uint32_t*)(addr + 48)));
((uint32_t*)bufP)[13] = le32toh(*((uint32_t*)(addr + 52)));
((uint32_t*)bufP)[14] = le32toh(*((uint32_t*)(addr + 56)));
((uint32_t*)bufP)[15] = le32toh(*((uint32_t*)(addr + 60)));
//fallthrough
case 32:
((uint32_t*)bufP)[4] = le32toh(*((uint32_t*)(addr + 16)));
((uint32_t*)bufP)[5] = le32toh(*((uint32_t*)(addr + 20)));
((uint32_t*)bufP)[6] = le32toh(*((uint32_t*)(addr + 24)));
((uint32_t*)bufP)[7] = le32toh(*((uint32_t*)(addr + 28)));
//fallthrough
case 16:
((uint32_t*)bufP)[2] = le32toh(*((uint32_t*)(addr + 8)));
((uint32_t*)bufP)[3] = le32toh(*((uint32_t*)(addr + 12)));
//fallthrough
case 8:
((uint32_t*)bufP)[0] = le32toh(*((uint32_t*)(addr + 0)));
((uint32_t*)bufP)[1] = le32toh(*((uint32_t*)(addr + 4)));
break;
default:
return false;
}
}
return true;
}
struct ArmRam* ramInit(struct ArmMem *mem, uint32_t adr, uint32_t sz, uint32_t* buf)
{
struct ArmRam *ram = (struct ArmRam*)malloc(sizeof(*ram));
if (!ram)
ERR("cannot alloc RAM at 0x%08x", adr);
memset(ram, 0, sizeof (*ram));
ram->adr = adr;
ram->sz = sz;
ram->buf = buf;
if (!memRegionAdd(mem, adr, sz, ramAccessF, ram))
ERR("cannot add RAM at 0x%08x to MEM\n", adr);
return ram;
}