1:
2:
3:
4:
5:
6:
7:
8:
9:
10: #include "hw.h"
11: #include "primecell.h"
12: #include "sysemu.h"
13:
14: #define LOCK_VALUE 0xa05f
15:
16: typedef struct {
17: uint32_t base;
18: uint32_t sys_id;
19: uint32_t leds;
20: uint16_t lockval;
21: uint32_t cfgdata1;
22: uint32_t cfgdata2;
23: uint32_t flags;
24: uint32_t nvflags;
25: uint32_t resetlevel;
26: } arm_sysctl_state;
27:
28: static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
29: {
30: arm_sysctl_state *s = (arm_sysctl_state *)opaque;
31:
32: offset -= s->base;
33: switch (offset) {
34: case 0x00:
35: return s->sys_id;
36: case 0x04:
37:
38:
39: return 0;
40: case 0x08:
41: return s->leds;
42: case 0x20:
43: return s->lockval;
44: case 0x0c:
45: case 0x10:
46: case 0x14:
47: case 0x18:
48: case 0x1c:
49: case 0x24:
50:
51: return 0;
52: case 0x28:
53: return s->cfgdata1;
54: case 0x2c:
55: return s->cfgdata2;
56: case 0x30:
57: return s->flags;
58: case 0x38:
59: return s->nvflags;
60: case 0x40:
61: return s->resetlevel;
62: case 0x44:
63: return 1;
64: case 0x48:
65: return 0;
66: case 0x4c:
67: return 0;
68: case 0x50:
69: return 0x1000;
70: case 0x54:
71: return 0;
72: case 0x58:
73: return 0;
74: case 0x5c:
75:
76: return 0;
77: case 0x60:
78: return 0;
79: case 0x84:
80:
81: return 0x02000000;
82: case 0x88:
83: return 0xff000000;
84: case 0x64:
85: case 0x68:
86: case 0x6c:
87: case 0x70:
88: case 0x74:
89: case 0x80:
90: case 0x8c:
91: case 0x90:
92: case 0x94:
93: case 0x98:
94: case 0x9c:
95: case 0xc0:
96: case 0xc4:
97: case 0xc8:
98: case 0xcc:
99: case 0xd0:
100: return 0;
101: default:
102: printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset);
103: return 0;
104: }
105: }
106:
107: static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
108: uint32_t val)
109: {
110: arm_sysctl_state *s = (arm_sysctl_state *)opaque;
111: offset -= s->base;
112:
113: switch (offset) {
114: case 0x08:
115: s->leds = val;
116: case 0x0c:
117: case 0x10:
118: case 0x14:
119: case 0x18:
120: case 0x1c:
121:
122: break;
123: case 0x20:
124: if (val == LOCK_VALUE)
125: s->lockval = val;
126: else
127: s->lockval = val & 0x7fff;
128: break;
129: case 0x28:
130:
131: s->cfgdata1 = val;
132: break;
133: case 0x2c:
134:
135: s->cfgdata2 = val;
136: break;
137: case 0x30:
138: s->flags |= val;
139: break;
140: case 0x34:
141: s->flags &= ~val;
142: break;
143: case 0x38:
144: s->nvflags |= val;
145: break;
146: case 0x3c:
147: s->nvflags &= ~val;
148: break;
149: case 0x40:
150: if (s->lockval == LOCK_VALUE) {
151: s->resetlevel = val;
152: if (val & 0x100)
153: qemu_system_reset_request ();
154: }
155: break;
156: case 0x44:
157:
158: break;
159: case 0x4c:
160: case 0x50:
161: case 0x54:
162: case 0x64:
163: case 0x68:
164: case 0x6c:
165: case 0x70:
166: case 0x74:
167: case 0x80:
168: case 0x84:
169: case 0x88:
170: case 0x8c:
171: case 0x90:
172: case 0x94:
173: case 0x98:
174: case 0x9c:
175: break;
176: default:
177: printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset);
178: return;
179: }
180: }
181:
182: static CPUReadMemoryFunc *arm_sysctl_readfn[] = {
183: arm_sysctl_read,
184: arm_sysctl_read,
185: arm_sysctl_read
186: };
187:
188: static CPUWriteMemoryFunc *arm_sysctl_writefn[] = {
189: arm_sysctl_write,
190: arm_sysctl_write,
191: arm_sysctl_write
192: };
193:
194: void arm_sysctl_init(uint32_t base, uint32_t sys_id)
195: {
196: arm_sysctl_state *s;
197: int iomemtype;
198:
199: s = (arm_sysctl_state *)qemu_mallocz(sizeof(arm_sysctl_state));
200: if (!s)
201: return;
202: s->base = base;
203: s->sys_id = sys_id;
204:
205:
206: s->flags = 3;
207: iomemtype = cpu_register_io_memory(0, arm_sysctl_readfn,
208: arm_sysctl_writefn, s);
209: cpu_register_physical_memory(base, 0x00001000, iomemtype);
210:
211: }
212: