loader: remove shouting from ORB's variable name
[hvf.git] / cp / guest / reset.c
blobccacc2362ed419f056d3d3c60a678b5f50914eda
1 /*
2 * (C) Copyright 2007-2010 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * This file is released under the GPLv2. See the COPYING file for more
5 * details.
6 */
8 #include <directory.h>
9 #include <sched.h>
10 #include <dat.h>
11 #include <vcpu.h>
12 #include <vdevice.h>
14 #define RESET_CPU 0x000001
15 #define SET_ESA390 0x000002
16 #define RESET_PSW 0x000004
17 #define RESET_PREFIX 0x000008
18 #define RESET_CPU_TIMER 0x000010
19 #define RESET_CLK_COMP 0x000020
20 #define RESET_TOD_PROG_REG 0x000040
21 #define RESET_CR 0x000080
22 #define RESET_BREAK_EV_ADDR 0x000100
23 #define RESET_FPCR 0x000200
24 #define RESET_AR 0x000400
25 #define RESET_GPR 0x000800
26 #define RESET_FPR 0x001000
27 #define RESET_STORAGE_KEYS 0x002000
28 #define RESET_STORAGE 0x004000
29 #define RESET_NONVOL_STORAGE 0x008000
30 #define RESET_EXPANDED_STORAGE 0x010000
31 #define RESET_TOD 0x020000
32 #define RESET_TOD_STEER 0x040000
33 #define RESET_FLOATING_INTERRUPTIONS 0x080000
34 #define RESET_IO 0x100000
35 #define RESET_PLO_LOCKS 0x200000
36 #define __RESET_PLO_LOCKS_PRESERVE 0x400000
37 #define RESET_PLO_LOCKS_PRESERVE (RESET_PLO_LOCKS | \
38 __RESET_PLO_LOCKS_PRESERVE)
41 * These define all the different ways of reseting the system...to save us
42 * typing later on :)
44 #define SUBSYSTEM_RESET_FLAGS (RESET_FLOATING_INTERRUPTIONS | RESET_IO)
45 #define CPU_RESET_FLAGS (RESET_CPU)
46 #define INIT_CPU_RESET_FLAGS (RESET_CPU | SET_ESA390 | RESET_PSW | \
47 RESET_PREFIX | RESET_CPU_TIMER | \
48 RESET_CLK_COMP | RESET_TOD_PROG_REG | \
49 RESET_CR | RESET_BREAK_EV_ADDR | \
50 RESET_FPCR)
51 #define CLEAR_RESET_FLAGS (RESET_CPU | SET_ESA390 | RESET_PSW | \
52 RESET_PREFIX | RESET_CPU_TIMER | \
53 RESET_CLK_COMP | RESET_TOD_PROG_REG | \
54 RESET_CR | RESET_BREAK_EV_ADDR | RESET_FPCR | \
55 RESET_AR | RESET_GPR | RESET_FPR | \
56 RESET_STORAGE_KEYS | RESET_STORAGE | \
57 RESET_NONVOL_STORAGE | RESET_PLO_LOCKS | \
58 RESET_FLOATING_INTERRUPTIONS | RESET_IO)
59 #define POWER_ON_RESET_FLAGS (RESET_CPU | SET_ESA390 | RESET_PSW | \
60 RESET_PREFIX | RESET_CPU_TIMER | \
61 RESET_CLK_COMP | RESET_TOD_PROG_REG | \
62 RESET_CR | RESET_BREAK_EV_ADDR | RESET_FPCR | \
63 RESET_AR | RESET_GPR | RESET_FPR | \
64 RESET_STORAGE_KEYS | RESET_STORAGE | \
65 RESET_EXPANDED_STORAGE | RESET_TOD | \
66 RESET_TOD_STEER | RESET_PLO_LOCKS_PRESERVE | \
67 RESET_FLOATING_INTERRUPTIONS | RESET_IO)
70 * Reset TODO:
71 * - handle Captured-z/Architecture-PSW register
73 static void __perform_cpu_reset(struct virt_sys *sys, int flags)
75 struct virt_cpu *cpu = sys->cpu;
77 if (flags & RESET_CPU) {
78 if (flags & SET_ESA390) {
79 FIXME("set the arch mode to ESA/390");
82 FIXME("clear interruptions (PROG, SVC, local EXT, MCHECK)");
84 * FIXME: clear interruptions:
85 * - PROG
86 * - SVC
87 * - local EXT (floating EXT are NOT cleared)
88 * - MCHECK (floating are NOT cleared)
91 cpu->state = GUEST_STOPPED;
94 if (flags & RESET_PSW)
95 memset(&cpu->sie_cb.gpsw, 0, sizeof(struct psw));
97 if (flags & RESET_PREFIX)
98 cpu->sie_cb.prefix = 0;
100 if (flags & RESET_CPU_TIMER) {
101 FIXME("");
104 if (flags & RESET_CLK_COMP) {
105 FIXME("");
108 if (flags & RESET_TOD_PROG_REG) {
109 FIXME("");
112 if (flags & RESET_CR) {
113 memset(cpu->sie_cb.gcr, 0, 16*sizeof(u64));
114 cpu->sie_cb.gcr[0] = 0xE0UL;
115 cpu->sie_cb.gcr[14] = 0xC2000000UL;
118 if (flags & RESET_BREAK_EV_ADDR) {
119 FIXME("initialize to 0x1");
122 if (flags & RESET_FPCR)
123 cpu->regs.fpcr = 0;
125 if (flags & RESET_AR)
126 memset(cpu->regs.ar, 0, 16*sizeof(u32));
128 if (flags & RESET_GPR)
129 memset(cpu->regs.gpr, 0, 16*sizeof(u64));
131 if (flags & RESET_FPR)
132 memset(cpu->regs.fpr, 0, 16*sizeof(u64));
134 if (flags & RESET_STORAGE_KEYS) {
137 if (flags & RESET_STORAGE) {
138 struct page *p;
140 list_for_each_entry(p, &sys->guest_pages, guest)
141 memset(page_to_addr(p), 0, PAGE_SIZE);
144 if (flags & RESET_NONVOL_STORAGE) {
147 if (flags & RESET_EXPANDED_STORAGE) {
150 if (flags & RESET_TOD) {
153 if (flags & RESET_TOD_STEER) {
156 if (flags & RESET_PLO_LOCKS) {
157 FIXME("if RESET_PLO_LOCKS_PRESERVE is set, don't reset locks...");
159 * TODO: if RESET_PLO_LOCKS_PRESERVE is set, don't reset
160 * locks held by powered on CPUS
165 static void __perform_noncpu_reset(struct virt_sys *sys, int flags)
167 struct virt_device *vdev;
168 int i;
170 if (flags & RESET_FLOATING_INTERRUPTIONS) {
173 if (flags & RESET_IO) {
174 for_each_vdev(sys, vdev) {
175 FIXME("wait for I/O to complete?");
176 mutex_lock(&vdev->lock);
178 /* set to zero */
179 vdev->pmcw.interrupt_param = 0;
180 vdev->pmcw.isc = 0;
181 vdev->pmcw.e = 0;
182 vdev->pmcw.lm = 0;
183 vdev->pmcw.mm = 0;
184 vdev->pmcw.d = 0;
185 vdev->pmcw.pnom = 0;
186 vdev->pmcw.lpum = 0;
187 vdev->pmcw.mbi = 0;
188 vdev->pmcw.f = 0;
189 vdev->pmcw.x = 0;
190 vdev->pmcw.s = 0;
192 /* set to one */
193 vdev->pmcw.pom = 0xff;
195 /* defined by the install - HVF hardcoded */
196 vdev->pmcw.t = 0;
197 vdev->pmcw.lpm = 0x80;
198 vdev->pmcw.pim = 0x80;
199 vdev->pmcw.pam = 0x80;
200 for(i=0; i<8; i++)
201 vdev->pmcw.chpid[i] = 0;
203 memset(&vdev->scsw, 0, sizeof(struct scsw));
204 mutex_unlock(&vdev->lock);
209 /**************/
211 void guest_power_on_reset(struct virt_sys *sys)
213 __perform_cpu_reset(sys, POWER_ON_RESET_FLAGS);
214 __perform_noncpu_reset(sys, POWER_ON_RESET_FLAGS);
217 void guest_system_reset_normal(struct virt_sys *sys)
219 __perform_cpu_reset(sys, CPU_RESET_FLAGS);
222 * TODO: once we have SMP guests, all other cpus should get a
223 * CPU_RESET_FLAGS as well.
226 __perform_noncpu_reset(sys, SUBSYSTEM_RESET_FLAGS);
229 void guest_system_reset_clear(struct virt_sys *sys)
231 __perform_cpu_reset(sys, CLEAR_RESET_FLAGS);
234 * TODO: once we have SMP guests, all other cpus should get a
235 * CLEAR_RESET_FLAGS as well.
238 __perform_noncpu_reset(sys, CLEAR_RESET_FLAGS);
241 void guest_load_normal(struct virt_sys *sys)
243 __perform_cpu_reset(sys, INIT_CPU_RESET_FLAGS);
246 * TODO: once we have SMP guests, all other cpus should get a
247 * CPU_RESET_FLAGS.
250 __perform_noncpu_reset(sys, SUBSYSTEM_RESET_FLAGS);
253 void guest_load_clear(struct virt_sys *sys)
255 __perform_cpu_reset(sys, CLEAR_RESET_FLAGS);
258 * TODO: once we have SMP guests, all other cpus should get a
259 * CLEAR_RESET_FLAGS as well.
262 __perform_noncpu_reset(sys, CLEAR_RESET_FLAGS);