direct-io.hg

view xen/arch/powerpc/powerpc64/ppc970.c @ 11487:4fdf5151b187

[POWERPC] merge with xen-unstable.hg
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author hollisb@localhost
date Mon Sep 18 12:48:56 2006 -0500 (2006-09-18)
parents bc349d862a5d
children a817acb39386
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, 2006
17 *
18 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
19 * Jimi Xenidis <jimix@watson.ibm.com>
20 */
22 #include <xen/config.h>
23 #include <xen/types.h>
24 #include <xen/mm.h>
25 #include <xen/sched.h>
26 #include <xen/lib.h>
27 #include <asm/time.h>
28 #include <asm/current.h>
29 #include <asm/powerpc64/procarea.h>
30 #include <asm/powerpc64/processor.h>
31 #include <asm/powerpc64/ppc970-hid.h>
33 #undef SERIALIZE
35 struct rma_settings {
36 int order;
37 int rmlr_0;
38 int rmlr_1_2;
39 };
41 static struct rma_settings rma_orders[] = {
42 { .order = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /* 64 MB */
43 { .order = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */
44 { .order = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */
45 { .order = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /* 1 GB */
46 { .order = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /* 16 GB */
47 { .order = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */
48 };
50 static uint log_large_page_sizes[] = {
51 4 + 20, /* (1 << 4) == 16M */
52 };
54 static struct rma_settings *cpu_find_rma(unsigned int order)
55 {
56 int i;
57 for (i = 0; i < ARRAY_SIZE(rma_orders); i++) {
58 if (rma_orders[i].order == order)
59 return &rma_orders[i];
60 }
61 return NULL;
62 }
64 unsigned int cpu_default_rma_order_pages(void)
65 {
66 return rma_orders[0].order - PAGE_SHIFT;
67 }
69 int cpu_rma_valid(unsigned int log)
70 {
71 return cpu_find_rma(log) != NULL;
72 }
74 unsigned int cpu_large_page_orders(uint *sizes, uint max)
75 {
76 uint i = 0;
78 while (i < max && i < ARRAY_SIZE(log_large_page_sizes)) {
79 sizes[i] = log_large_page_sizes[i] - PAGE_SHIFT;
80 ++i;
81 }
83 return i;
84 }
86 unsigned int cpu_extent_order(void)
87 {
88 return log_large_page_sizes[0] - PAGE_SHIFT;
89 }
91 static u64 cpu0_hids[6];
92 static u64 cpu0_hior;
94 void cpu_initialize(int cpuid)
95 {
96 ulong r1, r2;
97 union hid0 hid0;
98 union hid1 hid1;
99 union hid4 hid4;
100 union hid5 hid5;
102 __asm__ __volatile__ ("mr %0, 1" : "=r" (r1));
103 __asm__ __volatile__ ("mr %0, 2" : "=r" (r2));
105 if (cpuid == 0) {
106 /* we can assume that these are sane to start with. We
107 * _do_not_ store the results in case we want to mess with them
108 * on a per-cpu basis later. */
109 cpu0_hids[0] = mfhid0();
110 cpu0_hids[1] = mfhid1();
111 cpu0_hids[4] = mfhid4();
112 cpu0_hids[5] = mfhid5();
113 cpu0_hior = 0;
114 }
116 hid0.word = cpu0_hids[0];
117 hid1.word = cpu0_hids[1];
118 hid4.word = cpu0_hids[4];
119 hid5.word = cpu0_hids[5];
121 /* This is SMP safe because the compiler must use r13 for it. */
122 parea = global_cpu_table[cpuid];
123 ASSERT(parea != NULL);
125 mthsprg0((ulong)parea); /* now ready for exceptions */
127 /* Set decrementers for 1 second to keep them out of the way during
128 * intialization. */
129 /* XXX make tickless */
130 mtdec(timebase_freq);
131 mthdec(timebase_freq);
133 hid0.bits.nap = 1; /* NAP */
134 hid0.bits.dpm = 1; /* Dynamic Power Management */
135 hid0.bits.nhr = 0; /* ! Not Hard Reset */
136 hid0.bits.hdice_en = 1; /* enable HDEC */
137 hid0.bits.en_therm = 0; /* ! Enable ext thermal ints */
138 /* onlu debug Xen should do this */
139 hid0.bits.en_attn = 1; /* Enable attn instruction */
141 #ifdef SERIALIZE
142 hid0.bits.one_ppc = 1;
143 hid0.bits.isync_sc = 1;
144 hid0.bits.inorder = 1;
145 /* may not want these */
146 hid0.bits.do_single = 1;
147 hid0.bits.ser-gp = 1;
148 #endif
150 printk("CPU #%d: Hello World! SP = %lx TOC = %lx HID0 = %lx\n",
151 smp_processor_id(), r1, r2, hid0.word);
153 mthid0(hid0.word);
155 hid1.bits.bht_pm = 7; /* branch history table prediction mode */
156 hid1.bits.en_ls = 1; /* enable link stack */
158 hid1.bits.en_cc = 1; /* enable count cache */
159 hid1.bits.en_ic = 1; /* enable inst cache */
161 hid1.bits.pf_mode = 2; /* prefetch mode */
163 hid1.bits.en_if_cach = 1; /* i-fetch cacheability control */
164 hid1.bits.en_ic_rec = 1; /* i-cache parity error recovery */
165 hid1.bits.en_id_rec = 1; /* i-dir parity error recovery */
166 hid1.bits.en_er_rec = 1; /* i-ERAT parity error recovery */
168 hid1.bits.en_sp_itw = 1; /* En speculative tablewalks */
169 mthid1(hid1.word);
171 /* no changes to hid4 but we want to make sure that secondaries
172 * are sane */
173 hid4.bits.lg_pg_dis = 0; /* make sure we enable large pages */
174 mthid4(hid4.word);
176 hid5.bits.DCBZ_size = 0; /* make dcbz size 32 bytes */
177 hid5.bits.DCBZ32_ill = 0; /* make dzbz 32byte illeagal */
178 mthid5(hid5.word);
180 #ifdef DUMP_HIDS
181 printk("hid0 0x%016lx\n"
182 "hid1 0x%016lx\n"
183 "hid4 0x%016lx\n"
184 "hid5 0x%016lx\n",
185 mfhid0(), mfhid1(), mfhid4(), mfhid5());
186 #endif
188 mthior(cpu0_hior);
190 /* for good luck */
191 __asm__ __volatile__("isync; slbia; isync" : : : "memory");
192 }
194 void cpu_init_vcpu(struct vcpu *v)
195 {
196 struct domain *d = v->domain;
197 union hid4 hid4;
198 struct rma_settings *rma_settings;
200 hid4.word = mfhid4();
202 hid4.bits.lpes_0 = 0; /* external exceptions set MSR_HV=1 */
203 hid4.bits.lpes_1 = 1; /* RMA applies */
205 hid4.bits.rmor_0_15 = page_to_maddr(d->arch.rma_page) >> 26;
207 hid4.bits.lpid_0_1 = d->domain_id & 3;
208 hid4.bits.lpid_2_5 = (d->domain_id >> 2) & 0xf;
210 rma_settings = cpu_find_rma(d->arch.rma_order + PAGE_SHIFT);
211 ASSERT(rma_settings != NULL);
212 hid4.bits.rmlr_0 = rma_settings->rmlr_0;
213 hid4.bits.rmlr_1_2 = rma_settings->rmlr_1_2;
215 v->arch.cpu.hid4.word = hid4.word;
216 }
218 void save_cpu_sprs(struct vcpu *v)
219 {
220 /* HID4 is initialized with a per-domain value at domain creation time, and
221 * does not change after that. */
222 }
224 void load_cpu_sprs(struct vcpu *v)
225 {
226 mthid4(v->arch.cpu.hid4.word);
227 }