Revision 34933c8c
b/hw/arm_sysctl.c | ||
---|---|---|
27 | 27 |
uint32_t resetlevel; |
28 | 28 |
uint32_t proc_id; |
29 | 29 |
uint32_t sys_mci; |
30 |
uint32_t sys_cfgdata; |
|
31 |
uint32_t sys_cfgctrl; |
|
32 |
uint32_t sys_cfgstat; |
|
30 | 33 |
} arm_sysctl_state; |
31 | 34 |
|
32 | 35 |
static const VMStateDescription vmstate_arm_sysctl = { |
33 | 36 |
.name = "realview_sysctl", |
34 |
.version_id = 1,
|
|
37 |
.version_id = 2,
|
|
35 | 38 |
.minimum_version_id = 1, |
36 | 39 |
.fields = (VMStateField[]) { |
37 | 40 |
VMSTATE_UINT32(leds, arm_sysctl_state), |
... | ... | |
41 | 44 |
VMSTATE_UINT32(flags, arm_sysctl_state), |
42 | 45 |
VMSTATE_UINT32(nvflags, arm_sysctl_state), |
43 | 46 |
VMSTATE_UINT32(resetlevel, arm_sysctl_state), |
47 |
VMSTATE_UINT32_V(sys_mci, arm_sysctl_state, 2), |
|
48 |
VMSTATE_UINT32_V(sys_cfgdata, arm_sysctl_state, 2), |
|
49 |
VMSTATE_UINT32_V(sys_cfgctrl, arm_sysctl_state, 2), |
|
50 |
VMSTATE_UINT32_V(sys_cfgstat, arm_sysctl_state, 2), |
|
44 | 51 |
VMSTATE_END_OF_LIST() |
45 | 52 |
} |
46 | 53 |
}; |
... | ... | |
53 | 60 |
#define BOARD_ID_EB 0x140 |
54 | 61 |
#define BOARD_ID_PBA8 0x178 |
55 | 62 |
#define BOARD_ID_PBX 0x182 |
63 |
#define BOARD_ID_VEXPRESS 0x190 |
|
56 | 64 |
|
57 | 65 |
static int board_id(arm_sysctl_state *s) |
58 | 66 |
{ |
... | ... | |
104 | 112 |
case 0x38: /* NVFLAGS */ |
105 | 113 |
return s->nvflags; |
106 | 114 |
case 0x40: /* RESETCTL */ |
115 |
if (board_id(s) == BOARD_ID_VEXPRESS) { |
|
116 |
/* reserved: RAZ/WI */ |
|
117 |
return 0; |
|
118 |
} |
|
107 | 119 |
return s->resetlevel; |
108 | 120 |
case 0x44: /* PCICTL */ |
109 | 121 |
return 1; |
... | ... | |
142 | 154 |
case 0xcc: /* SYS_TEST_OSC3 */ |
143 | 155 |
case 0xd0: /* SYS_TEST_OSC4 */ |
144 | 156 |
return 0; |
157 |
case 0xa0: /* SYS_CFGDATA */ |
|
158 |
if (board_id(s) != BOARD_ID_VEXPRESS) { |
|
159 |
goto bad_reg; |
|
160 |
} |
|
161 |
return s->sys_cfgdata; |
|
162 |
case 0xa4: /* SYS_CFGCTRL */ |
|
163 |
if (board_id(s) != BOARD_ID_VEXPRESS) { |
|
164 |
goto bad_reg; |
|
165 |
} |
|
166 |
return s->sys_cfgctrl; |
|
167 |
case 0xa8: /* SYS_CFGSTAT */ |
|
168 |
if (board_id(s) != BOARD_ID_VEXPRESS) { |
|
169 |
goto bad_reg; |
|
170 |
} |
|
171 |
return s->sys_cfgstat; |
|
145 | 172 |
default: |
173 |
bad_reg: |
|
146 | 174 |
printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset); |
147 | 175 |
return 0; |
148 | 176 |
} |
... | ... | |
190 | 218 |
s->nvflags &= ~val; |
191 | 219 |
break; |
192 | 220 |
case 0x40: /* RESETCTL */ |
221 |
if (board_id(s) == BOARD_ID_VEXPRESS) { |
|
222 |
/* reserved: RAZ/WI */ |
|
223 |
break; |
|
224 |
} |
|
193 | 225 |
if (s->lockval == LOCK_VALUE) { |
194 | 226 |
s->resetlevel = val; |
195 | 227 |
if (val & 0x100) |
... | ... | |
216 | 248 |
case 0x98: /* OSCRESET3 */ |
217 | 249 |
case 0x9c: /* OSCRESET4 */ |
218 | 250 |
break; |
251 |
case 0xa0: /* SYS_CFGDATA */ |
|
252 |
if (board_id(s) != BOARD_ID_VEXPRESS) { |
|
253 |
goto bad_reg; |
|
254 |
} |
|
255 |
s->sys_cfgdata = val; |
|
256 |
return; |
|
257 |
case 0xa4: /* SYS_CFGCTRL */ |
|
258 |
if (board_id(s) != BOARD_ID_VEXPRESS) { |
|
259 |
goto bad_reg; |
|
260 |
} |
|
261 |
s->sys_cfgctrl = val & ~(3 << 18); |
|
262 |
s->sys_cfgstat = 1; /* complete */ |
|
263 |
switch (s->sys_cfgctrl) { |
|
264 |
case 0xc0800000: /* SYS_CFG_SHUTDOWN to motherboard */ |
|
265 |
qemu_system_shutdown_request(); |
|
266 |
break; |
|
267 |
case 0xc0900000: /* SYS_CFG_REBOOT to motherboard */ |
|
268 |
qemu_system_reset_request(); |
|
269 |
break; |
|
270 |
default: |
|
271 |
s->sys_cfgstat |= 2; /* error */ |
|
272 |
} |
|
273 |
return; |
|
274 |
case 0xa8: /* SYS_CFGSTAT */ |
|
275 |
if (board_id(s) != BOARD_ID_VEXPRESS) { |
|
276 |
goto bad_reg; |
|
277 |
} |
|
278 |
s->sys_cfgstat = val & 3; |
|
279 |
return; |
|
219 | 280 |
default: |
281 |
bad_reg: |
|
220 | 282 |
printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset); |
221 | 283 |
return; |
222 | 284 |
} |
Also available in: Unified diff