-
Notifications
You must be signed in to change notification settings - Fork 8
/
mmiodev_MemoryStickController.c
executable file
·158 lines (119 loc) · 3.39 KB
/
mmiodev_MemoryStickController.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//(c) uARM project https://github.com/uARM-Palm/uARM [email protected]
#include "mmiodev_MemoryStickController.h"
#include <string.h>
#include <stdlib.h>
#include "util.h"
#define MS_CONTROLLER_SIZE 0x400
struct MemoryStickController {
uint16_t systemReg;
//not sure
uint16_t reg_0, reg_40, reg_50, reg_2c0, reg_2d0, reg_2e0, reg_2f0;
//some sort of flags. w1c i think
uint16_t reg_188, reg_180;
//seems to be command results (64 bits in 2 32-bit regs)
uint32_t reply_lo_2f0, reply_hi_2f8;
};
//reg 0x08 seems to be "system register" top 16 bits (IP calls it system reg 0x18)
static bool msCtrlrPrvMemAccessF(void* userData, uint32_t pa, uint_fast8_t size, bool write, void* buf)
{
struct MemoryStickController *msc = (struct MemoryStickController*)userData;
uint32_t val = 0;
bool ret = true;
pa %= MS_CONTROLLER_SIZE;
if (size == 4 && !write && (pa == 0x2f0 || pa == 0x2f8)) {
*(uint32_t*)buf = (pa == 0x2f0) ? msc->reply_lo_2f0 : msc->reply_hi_2f8;
fprintf(stderr, "MSC %c [%04lx] == 0x%08lx\n", (char)(write ? 'W' : 'R'), (unsigned long)pa, (unsigned long)*(uint32_t*)buf);
return true;
}
if (size != 2) {
fprintf(stderr, "%s: Unexpected %s of %u bytes to 0x%08lx\n", __func__, write ? "write" : "read", size, (unsigned long)pa);
return false;
}
if (write)
val = *(uint16_t*)buf;
switch (pa) {
case 0x00:
if (write)
msc->reg_0 = val;
else
val = msc->reg_0;
break;
case 0x08: //system reg top 16 bits?
if (write)
msc->systemReg = (msc->systemReg & 0x8a00) | (val & 0x75ff);
//XXX: writing 0x0800 clears XINT too
else
val = msc->systemReg;
break;
case 0x40:
if (write)
msc->reg_40 = val;
else
val = msc->reg_40;
break;
case 0x50:
if (write)
msc->reg_50 = val;
else
val = msc->reg_50;
break;
case 0x180:
if (write)
msc->reg_180 &=~ val;
else
val = msc->reg_180;
break;
case 0x188:
if (write)
msc->reg_188 &=~ val;
else
val = msc->reg_188;
break;
case 0x2c0:
if (write)
msc->reg_2c0 = val;
else
val = msc->reg_2c0;
break;
case 0x2d0:
if (write)
msc->reg_2d0 = val &~ 1;
else
val = msc->reg_2d0;
break;
case 0x2e0: //some sort of command, assembled from 2 bytes in 3452MGLib@7f0
if (write)
msc->reg_2e0 = val;
else
val = msc->reg_2e0;
break;
case 0x2f0:
if (write)
msc->reg_2f0 = val;
else
val = msc->reg_2f0;
break;
default:
fprintf(stderr, "unknown reg 0x%08lx\n", (unsigned long)pa);
ret = false;
break;
}
if (ret)
fprintf(stderr, "MSC %c [%04lx] == 0x%04lx\n", (char)(write ? 'W' : 'R'), (unsigned long)pa, (unsigned long)val);
else
fprintf(stderr, "MSC %c [%04lx] FAILED\n", (char)(write ? 'W' : 'R'), (unsigned long)pa);
if (!write)
*(uint16_t*)buf = val;
return ret;
}
struct MemoryStickController* msCtrlrInit(struct ArmMem *physMem, uint32_t baseAddr)
{
struct MemoryStickController *msc = (struct MemoryStickController*)malloc(sizeof(*msc));
if (!msc)
ERR("cannot alloc MSC");
memset(msc, 0, sizeof (*msc));
msc->systemReg = 0x4455;
if (!memRegionAdd(physMem, baseAddr, MS_CONTROLLER_SIZE, msCtrlrPrvMemAccessF, msc))
ERR("cannot add MSC to MEM\n");
return msc;
}