Print this page
5255 uts shouldn't open-code ISP2
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/sun4v/os/intrq.c
+++ new/usr/src/uts/sun4v/os/intrq.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 +#include <sys/sysmacros.h>
26 27 #include <sys/machsystm.h>
27 28 #include <sys/cpu.h>
28 29 #include <sys/intreg.h>
29 30 #include <sys/machcpuvar.h>
30 31 #include <vm/hat_sfmmu.h>
31 32 #include <sys/error.h>
32 33 #include <sys/hypervisor_api.h>
33 34
34 35 void
35 36 cpu_intrq_register(struct cpu *cpu)
36 37 {
37 38 struct machcpu *mcpup = &cpu->cpu_m;
38 39 uint64_t ret;
39 40
40 41 ret = hv_cpu_qconf(INTR_CPU_Q, mcpup->cpu_q_base_pa, cpu_q_entries);
41 42 if (ret != H_EOK)
42 43 cmn_err(CE_PANIC, "cpu%d: cpu_mondo queue configuration "
43 44 "failed, error %lu", cpu->cpu_id, ret);
44 45
45 46 ret = hv_cpu_qconf(INTR_DEV_Q, mcpup->dev_q_base_pa, dev_q_entries);
46 47 if (ret != H_EOK)
47 48 cmn_err(CE_PANIC, "cpu%d: dev_mondo queue configuration "
48 49 "failed, error %lu", cpu->cpu_id, ret);
49 50
50 51 ret = hv_cpu_qconf(CPU_RQ, mcpup->cpu_rq_base_pa, cpu_rq_entries);
51 52 if (ret != H_EOK)
52 53 cmn_err(CE_PANIC, "cpu%d: resumable error queue configuration "
53 54 "failed, error %lu", cpu->cpu_id, ret);
54 55
55 56 ret = hv_cpu_qconf(CPU_NRQ, mcpup->cpu_nrq_base_pa, cpu_nrq_entries);
56 57 if (ret != H_EOK)
57 58 cmn_err(CE_PANIC, "cpu%d: non-resumable error queue "
58 59 "configuration failed, error %lu", cpu->cpu_id, ret);
59 60 }
60 61
61 62 int
62 63 cpu_intrq_setup(struct cpu *cpu)
63 64 {
64 65 struct machcpu *mcpup = &cpu->cpu_m;
65 66 size_t size;
66 67
67 68 /*
68 69 * This routine will return with an error return if any
69 70 * contig_mem_alloc() fails. It is expected that the caller will
70 71 * call cpu_intrq_cleanup() (or cleanup_cpu_common() which will).
71 72 * That will cleanly free only those blocks that were alloc'd.
72 73 */
73 74
74 75 /*
75 76 * Allocate mondo data for xcalls.
76 77 */
77 78 mcpup->mondo_data = contig_mem_alloc(INTR_REPORT_SIZE);
78 79
79 80 if (mcpup->mondo_data == NULL) {
80 81 cmn_err(CE_NOTE, "cpu%d: cpu mondo_data allocation failed",
81 82 cpu->cpu_id);
82 83 return (ENOMEM);
83 84 }
84 85 /*
85 86 * va_to_pa() is too expensive to call for every crosscall
86 87 * so we do it here at init time and save it in machcpu.
87 88 */
88 89 mcpup->mondo_data_ra = va_to_pa(mcpup->mondo_data);
89 90
90 91 /*
↓ open down ↓ |
55 lines elided |
↑ open up ↑ |
91 92 * Allocate a per-cpu list of ncpu_guest_max for xcalls
92 93 */
93 94 size = ncpu_guest_max * sizeof (uint16_t);
94 95 if (size < INTR_REPORT_SIZE)
95 96 size = INTR_REPORT_SIZE;
96 97
97 98 /*
98 99 * contig_mem_alloc() requires size to be a power of 2.
99 100 * Increase size to a power of 2 if necessary.
100 101 */
101 - if ((size & (size - 1)) != 0) {
102 + if (!ISP2(size)) {
102 103 size = 1 << highbit(size);
103 104 }
104 105
105 106 mcpup->cpu_list = contig_mem_alloc(size);
106 107
107 108 if (mcpup->cpu_list == NULL) {
108 109 cmn_err(CE_NOTE, "cpu%d: cpu cpu_list allocation failed",
109 110 cpu->cpu_id);
110 111 return (ENOMEM);
111 112 }
112 113 mcpup->cpu_list_ra = va_to_pa(mcpup->cpu_list);
113 114
114 115 /*
115 116 * Allocate sun4v interrupt and error queues.
116 117 */
117 118 size = cpu_q_entries * INTR_REPORT_SIZE;
118 119
119 120 mcpup->cpu_q_va = contig_mem_alloc(size);
120 121
121 122 if (mcpup->cpu_q_va == NULL) {
122 123 cmn_err(CE_NOTE, "cpu%d: cpu intrq allocation failed",
123 124 cpu->cpu_id);
124 125 return (ENOMEM);
125 126 }
126 127 mcpup->cpu_q_base_pa = va_to_pa(mcpup->cpu_q_va);
127 128 mcpup->cpu_q_size = size;
128 129
129 130 /*
130 131 * Allocate device queues
131 132 */
132 133 size = dev_q_entries * INTR_REPORT_SIZE;
133 134
134 135 mcpup->dev_q_va = contig_mem_alloc(size);
135 136
136 137 if (mcpup->dev_q_va == NULL) {
137 138 cmn_err(CE_NOTE, "cpu%d: dev intrq allocation failed",
138 139 cpu->cpu_id);
139 140 return (ENOMEM);
140 141 }
141 142 mcpup->dev_q_base_pa = va_to_pa(mcpup->dev_q_va);
142 143 mcpup->dev_q_size = size;
143 144
144 145 /*
145 146 * Allocate resumable queue and its kernel buffer
146 147 */
147 148 size = cpu_rq_entries * Q_ENTRY_SIZE;
148 149
149 150 mcpup->cpu_rq_va = contig_mem_alloc(2 * size);
150 151
151 152 if (mcpup->cpu_rq_va == NULL) {
152 153 cmn_err(CE_NOTE, "cpu%d: resumable queue allocation failed",
153 154 cpu->cpu_id);
154 155 return (ENOMEM);
155 156 }
156 157 mcpup->cpu_rq_base_pa = va_to_pa(mcpup->cpu_rq_va);
157 158 mcpup->cpu_rq_size = size;
158 159 /* zero out the memory */
159 160 bzero(mcpup->cpu_rq_va, 2 * size);
160 161
161 162 /*
162 163 * Allocate non-resumable queues
163 164 */
164 165 size = cpu_nrq_entries * Q_ENTRY_SIZE;
165 166
166 167 mcpup->cpu_nrq_va = contig_mem_alloc(2 * size);
167 168
168 169 if (mcpup->cpu_nrq_va == NULL) {
169 170 cmn_err(CE_NOTE, "cpu%d: nonresumable queue allocation failed",
170 171 cpu->cpu_id);
171 172 return (ENOMEM);
172 173 }
173 174 mcpup->cpu_nrq_base_pa = va_to_pa(mcpup->cpu_nrq_va);
174 175 mcpup->cpu_nrq_size = size;
175 176 /* zero out the memory */
176 177 bzero(mcpup->cpu_nrq_va, 2 * size);
177 178
178 179 return (0);
179 180 }
180 181
181 182 void
182 183 cpu_intrq_cleanup(struct cpu *cpu)
183 184 {
184 185 struct machcpu *mcpup = &cpu->cpu_m;
185 186 int cpu_list_size;
186 187 uint64_t cpu_q_size;
187 188 uint64_t dev_q_size;
188 189 uint64_t cpu_rq_size;
189 190 uint64_t cpu_nrq_size;
190 191
191 192 /*
192 193 * Free mondo data for xcalls.
193 194 */
194 195 if (mcpup->mondo_data) {
195 196 contig_mem_free(mcpup->mondo_data, INTR_REPORT_SIZE);
196 197 mcpup->mondo_data = NULL;
197 198 mcpup->mondo_data_ra = NULL;
198 199 }
199 200
200 201 /*
↓ open down ↓ |
89 lines elided |
↑ open up ↑ |
201 202 * Free per-cpu list of ncpu_guest_max for xcalls
202 203 */
203 204 cpu_list_size = ncpu_guest_max * sizeof (uint16_t);
204 205 if (cpu_list_size < INTR_REPORT_SIZE)
205 206 cpu_list_size = INTR_REPORT_SIZE;
206 207
207 208 /*
208 209 * contig_mem_alloc() requires size to be a power of 2.
209 210 * Increase size to a power of 2 if necessary.
210 211 */
211 - if ((cpu_list_size & (cpu_list_size - 1)) != 0) {
212 + if (!ISP2(cpu_list_size)) {
212 213 cpu_list_size = 1 << highbit(cpu_list_size);
213 214 }
214 215
215 216 if (mcpup->cpu_list) {
216 217 contig_mem_free(mcpup->cpu_list, cpu_list_size);
217 218 mcpup->cpu_list = NULL;
218 219 mcpup->cpu_list_ra = NULL;
219 220 }
220 221
221 222 /*
222 223 * Free sun4v interrupt and error queues.
223 224 */
224 225 if (mcpup->cpu_q_va) {
225 226 cpu_q_size = cpu_q_entries * INTR_REPORT_SIZE;
226 227 contig_mem_free(mcpup->cpu_q_va, cpu_q_size);
227 228 mcpup->cpu_q_va = NULL;
228 229 mcpup->cpu_q_base_pa = NULL;
229 230 mcpup->cpu_q_size = 0;
230 231 }
231 232
232 233 if (mcpup->dev_q_va) {
233 234 dev_q_size = dev_q_entries * INTR_REPORT_SIZE;
234 235 contig_mem_free(mcpup->dev_q_va, dev_q_size);
235 236 mcpup->dev_q_va = NULL;
236 237 mcpup->dev_q_base_pa = NULL;
237 238 mcpup->dev_q_size = 0;
238 239 }
239 240
240 241 if (mcpup->cpu_rq_va) {
241 242 cpu_rq_size = cpu_rq_entries * Q_ENTRY_SIZE;
242 243 contig_mem_free(mcpup->cpu_rq_va, 2 * cpu_rq_size);
243 244 mcpup->cpu_rq_va = NULL;
244 245 mcpup->cpu_rq_base_pa = NULL;
245 246 mcpup->cpu_rq_size = 0;
246 247 }
247 248
248 249 if (mcpup->cpu_nrq_va) {
249 250 cpu_nrq_size = cpu_nrq_entries * Q_ENTRY_SIZE;
250 251 contig_mem_free(mcpup->cpu_nrq_va, 2 * cpu_nrq_size);
251 252 mcpup->cpu_nrq_va = NULL;
252 253 mcpup->cpu_nrq_base_pa = NULL;
253 254 mcpup->cpu_nrq_size = 0;
254 255 }
255 256 }
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX