source: trunk/packages/xen-common/xen-common/xen/arch/powerpc/powerpc64/domain.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 4.4 KB
Line 
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 */
20
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>
26
27void save_sprs(struct vcpu *v)
28{
29    v->arch.timebase = mftb();
30
31    v->arch.sprg[0] = mfsprg0();
32    v->arch.sprg[1] = mfsprg1();
33    v->arch.sprg[2] = mfsprg2();
34    v->arch.sprg[3] = mfsprg3();
35
36    v->arch.dar = mfdar();
37    v->arch.dsisr = mfdsisr();
38
39    save_cpu_sprs(v);
40}
41
42void load_sprs(struct vcpu *v)
43{
44    ulong timebase_delta;
45
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);
52
53    load_cpu_sprs(v);
54
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}
63
64/* XXX evaluate all isyncs in segment code */
65
66void flush_segments(void)
67{
68    struct slb_entry slb0;
69    ulong zero = 0;
70
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");
77
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;
83
84        class = !!(slb0.slb_vsid & SLB_ESID_CLASS);
85        rb = slb0.slb_esid & SLB_ESID_MASK;
86        rb |= class << SLBIE_CLASS_LOG;
87
88        slbie(rb);
89    }
90    slbia();
91}
92
93void save_segments(struct vcpu *v)
94{
95    struct slb_entry *slb_entry = v->arch.slb_entries;
96    int i;
97
98    /* save all extra SLBs */
99    for (i = 0; i < NUM_SLB_ENTRIES; i++) {
100        ulong vsid;
101        ulong esid;
102
103        __asm__ __volatile__(
104                "slbmfev %0,%2\n"
105                "slbmfee %1,%2\n"
106                :"=&r"(vsid), "=&r"(esid)
107                :"r"(i)
108                :"memory");
109
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            printk("%s: DOM[0x%x]: S%02d: 0x%016lx 0x%016lx\n",
116                    __func__, v->domain->domain_id, i, vsid, esid);
117        }
118#endif
119    }
120
121    flush_segments();
122}
123
124void load_segments(struct vcpu *v)
125{
126    struct slb_entry *slb_entry = v->arch.slb_entries;
127    int i;
128
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;
133
134        /* FIXME: should we bother to restore invalid entries */
135        /* stuff in the index here */
136        esid &= ~SLBMTE_ENTRY_MASK;
137        esid |= i;
138
139        __asm__ __volatile__(
140                "isync\n"
141                "slbmte %0,%1\n"
142                "isync\n"
143                :
144                :"r" (vsid), "r"(esid)
145                :"memory");
146
147#ifdef SLB_DEBUG
148        if (vsid != 0) {
149            printk("%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}
155
156void dump_segments(int valid)
157{
158    int i;
159
160    printk("Dump %s SLB entries:\n", valid ? "VALID" : "ALL");
161
162    /* save all extra SLBs */
163    for (i = 0; i < NUM_SLB_ENTRIES; i++) {
164        ulong vsid;
165        ulong esid;
166
167        __asm__ __volatile__(
168                "slbmfev %0,%2\n"
169                "slbmfee %1,%2\n"
170                :"=&r"(vsid), "=&r"(esid)
171                :"r"(i)
172                :"memory");
173
174        if (valid && !(esid & SLB_ESID_VALID))
175            continue;
176        printk("S%02d: 0x%016lx 0x%016lx\n", i, vsid, esid);
177    }
178}
Note: See TracBrowser for help on using the repository browser.