xref: /onnv-gate/usr/src/uts/sun4v/os/intrq.c (revision 1991:f29baf5bf770)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*1991Sheppo  * Common Development and Distribution License (the "License").
6*1991Sheppo  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*1991Sheppo 
220Sstevel@tonic-gate /*
231342Sae112802  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/machsystm.h>
300Sstevel@tonic-gate #include <sys/cpu.h>
310Sstevel@tonic-gate #include <sys/intreg.h>
320Sstevel@tonic-gate #include <sys/machcpuvar.h>
330Sstevel@tonic-gate #include <vm/hat_sfmmu.h>
340Sstevel@tonic-gate #include <sys/error.h>
350Sstevel@tonic-gate #include <sys/hypervisor_api.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate void
380Sstevel@tonic-gate cpu_intrq_register(struct cpu *cpu)
390Sstevel@tonic-gate {
400Sstevel@tonic-gate 	struct machcpu *mcpup = &cpu->cpu_m;
410Sstevel@tonic-gate 	uint64_t ret;
420Sstevel@tonic-gate 
430Sstevel@tonic-gate 	ret = hv_cpu_qconf(INTR_CPU_Q, mcpup->cpu_q_base_pa, cpu_q_entries);
440Sstevel@tonic-gate 	if (ret != H_EOK)
450Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: cpu_mondo queue configuration "
460Sstevel@tonic-gate 		    "failed, error %lu", cpu->cpu_id, ret);
470Sstevel@tonic-gate 
480Sstevel@tonic-gate 	ret = hv_cpu_qconf(INTR_DEV_Q, mcpup->dev_q_base_pa, dev_q_entries);
490Sstevel@tonic-gate 	if (ret != H_EOK)
500Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: dev_mondo queue configuration "
510Sstevel@tonic-gate 		    "failed, error %lu", cpu->cpu_id, ret);
520Sstevel@tonic-gate 
53*1991Sheppo 	ret = hv_cpu_qconf(CPU_RQ, mcpup->cpu_rq_base_pa, cpu_rq_entries);
540Sstevel@tonic-gate 	if (ret != H_EOK)
550Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: resumable error queue configuration "
560Sstevel@tonic-gate 		    "failed, error %lu", cpu->cpu_id, ret);
570Sstevel@tonic-gate 
58*1991Sheppo 	ret = hv_cpu_qconf(CPU_NRQ, mcpup->cpu_nrq_base_pa, cpu_nrq_entries);
590Sstevel@tonic-gate 	if (ret != H_EOK)
600Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: non-resumable error queue "
610Sstevel@tonic-gate 		    "configuration failed, error %lu", cpu->cpu_id, ret);
620Sstevel@tonic-gate }
630Sstevel@tonic-gate 
640Sstevel@tonic-gate void
650Sstevel@tonic-gate cpu_intrq_setup(struct cpu *cpu)
660Sstevel@tonic-gate {
670Sstevel@tonic-gate 	struct machcpu *mcpup = &cpu->cpu_m;
680Sstevel@tonic-gate 	int cpu_list_size;
69*1991Sheppo 	uint64_t cpu_q_size;
70*1991Sheppo 	uint64_t dev_q_size;
71*1991Sheppo 	uint64_t cpu_rq_size;
72*1991Sheppo 	uint64_t cpu_nrq_size;
730Sstevel@tonic-gate 
740Sstevel@tonic-gate 	/*
750Sstevel@tonic-gate 	 * Allocate mondo data for xcalls.
760Sstevel@tonic-gate 	 */
770Sstevel@tonic-gate 	mcpup->mondo_data = contig_mem_alloc(INTR_REPORT_SIZE);
780Sstevel@tonic-gate 	if (mcpup->mondo_data == NULL)
790Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: cpu mondo_data allocation failed",
800Sstevel@tonic-gate 		    cpu->cpu_id);
810Sstevel@tonic-gate 
820Sstevel@tonic-gate 	/*
830Sstevel@tonic-gate 	 *  Allocate a percpu list of NCPU for xcalls
840Sstevel@tonic-gate 	 */
850Sstevel@tonic-gate 	cpu_list_size = NCPU * sizeof (uint16_t);
860Sstevel@tonic-gate 	if (cpu_list_size < INTR_REPORT_SIZE)
870Sstevel@tonic-gate 		cpu_list_size = INTR_REPORT_SIZE;
880Sstevel@tonic-gate 
890Sstevel@tonic-gate 	mcpup->cpu_list = contig_mem_alloc(cpu_list_size);
901342Sae112802 	if (mcpup->cpu_list == NULL)
911342Sae112802 		cmn_err(CE_PANIC, "cpu%d: cpu cpu_list allocation failed",
920Sstevel@tonic-gate 		    cpu->cpu_id);
930Sstevel@tonic-gate 	mcpup->cpu_list_ra = va_to_pa(mcpup->cpu_list);
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	/*
960Sstevel@tonic-gate 	 * va_to_pa() is too expensive to call for every crosscall
970Sstevel@tonic-gate 	 * so we do it here at init time and save it in machcpu.
980Sstevel@tonic-gate 	 */
990Sstevel@tonic-gate 	mcpup->mondo_data_ra = va_to_pa(mcpup->mondo_data);
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 	/*
1020Sstevel@tonic-gate 	 * Allocate sun4v interrupt and error queues.
1030Sstevel@tonic-gate 	 */
104*1991Sheppo 	cpu_q_size = cpu_q_entries * INTR_REPORT_SIZE;
105*1991Sheppo 	mcpup->cpu_q_va = contig_mem_alloc(cpu_q_size);
1060Sstevel@tonic-gate 	if (mcpup->cpu_q_va == NULL)
1070Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: cpu intrq allocation failed",
1080Sstevel@tonic-gate 		    cpu->cpu_id);
1090Sstevel@tonic-gate 	mcpup->cpu_q_base_pa = va_to_pa(mcpup->cpu_q_va);
110*1991Sheppo 	mcpup->cpu_q_size =  cpu_q_size;
1110Sstevel@tonic-gate 
112*1991Sheppo 	dev_q_size = dev_q_entries * INTR_REPORT_SIZE;
113*1991Sheppo 	mcpup->dev_q_va = contig_mem_alloc(dev_q_size);
1140Sstevel@tonic-gate 	if (mcpup->dev_q_va == NULL)
1150Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: dev intrq allocation failed",
1160Sstevel@tonic-gate 		    cpu->cpu_id);
1170Sstevel@tonic-gate 	mcpup->dev_q_base_pa = va_to_pa(mcpup->dev_q_va);
118*1991Sheppo 	mcpup->dev_q_size =  dev_q_size;
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	/* Allocate resumable queue and its kernel buffer */
121*1991Sheppo 	cpu_rq_size = cpu_rq_entries * Q_ENTRY_SIZE;
122*1991Sheppo 	mcpup->cpu_rq_va = contig_mem_alloc(2 * cpu_rq_size);
1230Sstevel@tonic-gate 	if (mcpup->cpu_rq_va == NULL)
1240Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: resumable queue allocation failed",
1250Sstevel@tonic-gate 		    cpu->cpu_id);
1260Sstevel@tonic-gate 	mcpup->cpu_rq_base_pa = va_to_pa(mcpup->cpu_rq_va);
127*1991Sheppo 	mcpup->cpu_rq_size = cpu_rq_size;
1280Sstevel@tonic-gate 	/* zero out the memory */
129*1991Sheppo 	bzero(mcpup->cpu_rq_va, 2 * cpu_rq_size);
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	/* Allocate nonresumable queue here */
132*1991Sheppo 	cpu_nrq_size = cpu_nrq_entries * Q_ENTRY_SIZE;
133*1991Sheppo 	mcpup->cpu_nrq_va = contig_mem_alloc(2 * cpu_nrq_size);
1340Sstevel@tonic-gate 	if (mcpup->cpu_nrq_va == NULL)
1350Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: nonresumable queue "
1360Sstevel@tonic-gate 		    "allocation failed", cpu->cpu_id);
1370Sstevel@tonic-gate 	mcpup->cpu_nrq_base_pa = va_to_pa(mcpup->cpu_nrq_va);
138*1991Sheppo 	mcpup->cpu_nrq_size = cpu_nrq_size;
1390Sstevel@tonic-gate 	/* zero out the memory */
140*1991Sheppo 	bzero(mcpup->cpu_nrq_va, 2 * cpu_nrq_size);
141*1991Sheppo }
142*1991Sheppo 
143*1991Sheppo void
144*1991Sheppo cpu_intrq_cleanup(struct cpu *cpu)
145*1991Sheppo {
146*1991Sheppo 	struct machcpu *mcpup = &cpu->cpu_m;
147*1991Sheppo 	int cpu_list_size;
148*1991Sheppo 	uint64_t cpu_q_size;
149*1991Sheppo 	uint64_t dev_q_size;
150*1991Sheppo 	uint64_t cpu_rq_size;
151*1991Sheppo 	uint64_t cpu_nrq_size;
152*1991Sheppo 
153*1991Sheppo 	/*
154*1991Sheppo 	 * Free mondo data for xcalls.
155*1991Sheppo 	 */
156*1991Sheppo 	if (mcpup->mondo_data) {
157*1991Sheppo 		contig_mem_free(mcpup->mondo_data, INTR_REPORT_SIZE);
158*1991Sheppo 		mcpup->mondo_data = NULL;
159*1991Sheppo 		mcpup->mondo_data_ra = NULL;
160*1991Sheppo 	}
161*1991Sheppo 
162*1991Sheppo 	/*
163*1991Sheppo 	 *  Free percpu list of NCPU for xcalls
164*1991Sheppo 	 */
165*1991Sheppo 	cpu_list_size = NCPU * sizeof (uint16_t);
166*1991Sheppo 	if (cpu_list_size < INTR_REPORT_SIZE)
167*1991Sheppo 		cpu_list_size = INTR_REPORT_SIZE;
168*1991Sheppo 
169*1991Sheppo 	if (mcpup->cpu_list) {
170*1991Sheppo 		contig_mem_free(mcpup->cpu_list, cpu_list_size);
171*1991Sheppo 		mcpup->cpu_list = NULL;
172*1991Sheppo 		mcpup->cpu_list_ra = NULL;
173*1991Sheppo 	}
1740Sstevel@tonic-gate 
175*1991Sheppo 	/*
176*1991Sheppo 	 * Free sun4v interrupt and error queues.
177*1991Sheppo 	 */
178*1991Sheppo 	if (mcpup->cpu_q_va) {
179*1991Sheppo 		cpu_q_size = cpu_q_entries * INTR_REPORT_SIZE;
180*1991Sheppo 		contig_mem_free(mcpup->cpu_q_va, cpu_q_size);
181*1991Sheppo 		mcpup->cpu_q_va = NULL;
182*1991Sheppo 		mcpup->cpu_q_base_pa = NULL;
183*1991Sheppo 		mcpup->cpu_q_size = 0;
184*1991Sheppo 	}
185*1991Sheppo 
186*1991Sheppo 	if (mcpup->dev_q_va) {
187*1991Sheppo 		dev_q_size = dev_q_entries * INTR_REPORT_SIZE;
188*1991Sheppo 		contig_mem_free(mcpup->dev_q_va, dev_q_size);
189*1991Sheppo 		mcpup->dev_q_va = NULL;
190*1991Sheppo 		mcpup->dev_q_base_pa = NULL;
191*1991Sheppo 		mcpup->dev_q_size = 0;
192*1991Sheppo 	}
193*1991Sheppo 
194*1991Sheppo 	if (mcpup->cpu_rq_va) {
195*1991Sheppo 		cpu_rq_size = cpu_rq_entries * Q_ENTRY_SIZE;
196*1991Sheppo 		contig_mem_free(mcpup->cpu_rq_va, 2 * cpu_rq_size);
197*1991Sheppo 		mcpup->cpu_rq_va = NULL;
198*1991Sheppo 		mcpup->cpu_rq_base_pa = NULL;
199*1991Sheppo 		mcpup->cpu_rq_size = 0;
200*1991Sheppo 	}
201*1991Sheppo 
202*1991Sheppo 	if (mcpup->cpu_nrq_va) {
203*1991Sheppo 		cpu_nrq_size = cpu_nrq_entries * Q_ENTRY_SIZE;
204*1991Sheppo 		contig_mem_free(mcpup->cpu_nrq_va, 2 * cpu_nrq_size);
205*1991Sheppo 		mcpup->cpu_nrq_va = NULL;
206*1991Sheppo 		mcpup->cpu_nrq_base_pa = NULL;
207*1991Sheppo 		mcpup->cpu_nrq_size = 0;
208*1991Sheppo 	}
2090Sstevel@tonic-gate }
210