direct-io.hg

view xen/arch/powerpc/powerpc64/domain.c @ 11498:464acece0dad

[POWERPC][XEN] Clear SLB entries on boot and other cleanups

This patch clears and SLB entries that might have been left behind by
Firmware and also cleans up the Save and Restore of the segments.

Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Thu Sep 07 02:21:17 2006 -0400 (2006-09-07)
parents b82a8107cae6
children 29b02d929b7e
line source
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Copyright (C) IBM Corp. 2005
17 *
18 * Authors: Jimi Xenidis <jimix@watson.ibm.com>
19 */
21 #include <xen/config.h>
22 #include <xen/lib.h>
23 #include <xen/sched.h>
24 #include <xen/mm.h>
25 #include <asm/current.h>
27 void save_sprs(struct vcpu *v)
28 {
29 v->arch.timebase = mftb();
31 v->arch.sprg[0] = mfsprg0();
32 v->arch.sprg[1] = mfsprg1();
33 v->arch.sprg[2] = mfsprg2();
34 v->arch.sprg[3] = mfsprg3();
36 v->arch.dar = mfdar();
37 v->arch.dsisr = mfdsisr();
39 save_cpu_sprs(v);
40 }
42 void load_sprs(struct vcpu *v)
43 {
44 ulong timebase_delta;
46 mtsprg0(v->arch.sprg[0]);
47 mtsprg1(v->arch.sprg[1]);
48 mtsprg2(v->arch.sprg[2]);
49 mtsprg3(v->arch.sprg[3]);
50 mtdar(v->arch.dar);
51 mtdsisr(v->arch.dsisr);
53 load_cpu_sprs(v);
55 /* adjust the DEC value to account for cycles while not
56 * running this OS */
57 timebase_delta = mftb() - v->arch.timebase;
58 if (timebase_delta > v->arch.dec)
59 v->arch.dec = 0;
60 else
61 v->arch.dec -= timebase_delta;
62 }
64 /* XXX evaluate all isyncs in segment code */
66 void flush_segments(void)
67 {
68 struct slb_entry slb0;
69 ulong zero = 0;
71 __asm__ __volatile__(
72 "slbmfev %0,%2\n"
73 "slbmfee %1,%2\n"
74 :"=&r"(slb0.slb_vsid), "=&r"(slb0.slb_esid)
75 :"r"(zero)
76 :"memory");
78 /* we manually have to invalidate SLB[0] since slbia doesn't. */
79 /* XXX name magic constants! */
80 if (slb0.slb_esid & SLB_ESID_VALID) {
81 ulong rb;
82 ulong class;
84 class = !!(slb0.slb_vsid & SLB_ESID_CLASS);
85 rb = slb0.slb_esid & SLB_ESID_MASK;
86 rb |= class << SLBIE_CLASS_LOG;
88 slbie(rb);
89 }
90 slbia();
91 }
93 void save_segments(struct vcpu *v)
94 {
95 struct slb_entry *slb_entry = v->arch.slb_entries;
96 int i;
98 /* save all extra SLBs */
99 for (i = 0; i < NUM_SLB_ENTRIES; i++) {
100 ulong vsid;
101 ulong esid;
103 __asm__ __volatile__(
104 "slbmfev %0,%2\n"
105 "slbmfee %1,%2\n"
106 :"=&r"(vsid), "=&r"(esid)
107 :"r"(i)
108 :"memory");
110 /* FIXME: should we bother to save invalid entries? */
111 slb_entry[i].slb_vsid = vsid;
112 slb_entry[i].slb_esid = esid;
113 #ifdef SLB_DEBUG
114 if (vsid != 0) {
115 printf("%s: DOM[0x%x]: S%02d: 0x%016lx 0x%016lx\n",
116 __func__, v->domain->domain_id, i, vsid, esid);
117 }
118 #endif
119 }
121 flush_segments();
122 }
124 void load_segments(struct vcpu *v)
125 {
126 struct slb_entry *slb_entry = v->arch.slb_entries;
127 int i;
129 /* restore all extra SLBs */
130 for (i = 0; i < NUM_SLB_ENTRIES; i++) {
131 ulong vsid = slb_entry[i].slb_vsid;
132 ulong esid = slb_entry[i].slb_esid;
134 /* FIXME: should we bother to restore invalid entries */
135 /* stuff in the index here */
136 esid &= ~SLBMTE_ENTRY_MASK;
137 esid |= i;
139 __asm__ __volatile__(
140 "isync\n"
141 "slbmte %0,%1\n"
142 "isync\n"
143 :
144 :"r" (vsid), "r"(esid)
145 :"memory");
147 #ifdef SLB_DEBUG
148 if (vsid != 0) {
149 printf("%s: DOM[0x%x]: R%02d: 0x%016lx 0x%016lx\n",
150 __func__, v->domain->domain_id, i, vsid, esid);
151 }
152 #endif
153 }
154 }
156 void dump_segments(int valid)
157 {
158 int i;
160 printk("Dump %s SLB entries:\n", valid ? "VALID" : "ALL");
162 /* save all extra SLBs */
163 for (i = 0; i < NUM_SLB_ENTRIES; i++) {
164 ulong vsid;
165 ulong esid;
167 __asm__ __volatile__(
168 "slbmfev %0,%2\n"
169 "slbmfee %1,%2\n"
170 :"=&r"(vsid), "=&r"(esid)
171 :"r"(i)
172 :"memory");
174 if (valid && !(esid & SLB_ESID_VALID))
175 continue;
176 printf("S%02d: 0x%016lx 0x%016lx\n", i, vsid, esid);
177 }
178 }