xref: /titanic_41/usr/src/uts/sun4v/os/intrq.c (revision 1ae0874509b6811fdde1dfd46f0d93fd09867a3f)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*1ae08745Sheppo  * Common Development and Distribution License (the "License").
6*1ae08745Sheppo  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*1ae08745Sheppo 
227c478bd9Sstevel@tonic-gate /*
2322defd95Sae112802  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/machsystm.h>
307c478bd9Sstevel@tonic-gate #include <sys/cpu.h>
317c478bd9Sstevel@tonic-gate #include <sys/intreg.h>
327c478bd9Sstevel@tonic-gate #include <sys/machcpuvar.h>
337c478bd9Sstevel@tonic-gate #include <vm/hat_sfmmu.h>
347c478bd9Sstevel@tonic-gate #include <sys/error.h>
357c478bd9Sstevel@tonic-gate #include <sys/hypervisor_api.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate void
387c478bd9Sstevel@tonic-gate cpu_intrq_register(struct cpu *cpu)
397c478bd9Sstevel@tonic-gate {
407c478bd9Sstevel@tonic-gate 	struct machcpu *mcpup = &cpu->cpu_m;
417c478bd9Sstevel@tonic-gate 	uint64_t ret;
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate 	ret = hv_cpu_qconf(INTR_CPU_Q, mcpup->cpu_q_base_pa, cpu_q_entries);
447c478bd9Sstevel@tonic-gate 	if (ret != H_EOK)
457c478bd9Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: cpu_mondo queue configuration "
467c478bd9Sstevel@tonic-gate 		    "failed, error %lu", cpu->cpu_id, ret);
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate 	ret = hv_cpu_qconf(INTR_DEV_Q, mcpup->dev_q_base_pa, dev_q_entries);
497c478bd9Sstevel@tonic-gate 	if (ret != H_EOK)
507c478bd9Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: dev_mondo queue configuration "
517c478bd9Sstevel@tonic-gate 		    "failed, error %lu", cpu->cpu_id, ret);
527c478bd9Sstevel@tonic-gate 
53*1ae08745Sheppo 	ret = hv_cpu_qconf(CPU_RQ, mcpup->cpu_rq_base_pa, cpu_rq_entries);
547c478bd9Sstevel@tonic-gate 	if (ret != H_EOK)
557c478bd9Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: resumable error queue configuration "
567c478bd9Sstevel@tonic-gate 		    "failed, error %lu", cpu->cpu_id, ret);
577c478bd9Sstevel@tonic-gate 
58*1ae08745Sheppo 	ret = hv_cpu_qconf(CPU_NRQ, mcpup->cpu_nrq_base_pa, cpu_nrq_entries);
597c478bd9Sstevel@tonic-gate 	if (ret != H_EOK)
607c478bd9Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: non-resumable error queue "
617c478bd9Sstevel@tonic-gate 		    "configuration failed, error %lu", cpu->cpu_id, ret);
627c478bd9Sstevel@tonic-gate }
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate void
657c478bd9Sstevel@tonic-gate cpu_intrq_setup(struct cpu *cpu)
667c478bd9Sstevel@tonic-gate {
677c478bd9Sstevel@tonic-gate 	struct machcpu *mcpup = &cpu->cpu_m;
687c478bd9Sstevel@tonic-gate 	int cpu_list_size;
69*1ae08745Sheppo 	uint64_t cpu_q_size;
70*1ae08745Sheppo 	uint64_t dev_q_size;
71*1ae08745Sheppo 	uint64_t cpu_rq_size;
72*1ae08745Sheppo 	uint64_t cpu_nrq_size;
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate 	/*
757c478bd9Sstevel@tonic-gate 	 * Allocate mondo data for xcalls.
767c478bd9Sstevel@tonic-gate 	 */
777c478bd9Sstevel@tonic-gate 	mcpup->mondo_data = contig_mem_alloc(INTR_REPORT_SIZE);
787c478bd9Sstevel@tonic-gate 	if (mcpup->mondo_data == NULL)
797c478bd9Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: cpu mondo_data allocation failed",
807c478bd9Sstevel@tonic-gate 		    cpu->cpu_id);
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	/*
837c478bd9Sstevel@tonic-gate 	 *  Allocate a percpu list of NCPU for xcalls
847c478bd9Sstevel@tonic-gate 	 */
857c478bd9Sstevel@tonic-gate 	cpu_list_size = NCPU * sizeof (uint16_t);
867c478bd9Sstevel@tonic-gate 	if (cpu_list_size < INTR_REPORT_SIZE)
877c478bd9Sstevel@tonic-gate 		cpu_list_size = INTR_REPORT_SIZE;
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	mcpup->cpu_list = contig_mem_alloc(cpu_list_size);
9022defd95Sae112802 	if (mcpup->cpu_list == NULL)
9122defd95Sae112802 		cmn_err(CE_PANIC, "cpu%d: cpu cpu_list allocation failed",
927c478bd9Sstevel@tonic-gate 		    cpu->cpu_id);
937c478bd9Sstevel@tonic-gate 	mcpup->cpu_list_ra = va_to_pa(mcpup->cpu_list);
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	/*
967c478bd9Sstevel@tonic-gate 	 * va_to_pa() is too expensive to call for every crosscall
977c478bd9Sstevel@tonic-gate 	 * so we do it here at init time and save it in machcpu.
987c478bd9Sstevel@tonic-gate 	 */
997c478bd9Sstevel@tonic-gate 	mcpup->mondo_data_ra = va_to_pa(mcpup->mondo_data);
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	/*
1027c478bd9Sstevel@tonic-gate 	 * Allocate sun4v interrupt and error queues.
1037c478bd9Sstevel@tonic-gate 	 */
104*1ae08745Sheppo 	cpu_q_size = cpu_q_entries * INTR_REPORT_SIZE;
105*1ae08745Sheppo 	mcpup->cpu_q_va = contig_mem_alloc(cpu_q_size);
1067c478bd9Sstevel@tonic-gate 	if (mcpup->cpu_q_va == NULL)
1077c478bd9Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: cpu intrq allocation failed",
1087c478bd9Sstevel@tonic-gate 		    cpu->cpu_id);
1097c478bd9Sstevel@tonic-gate 	mcpup->cpu_q_base_pa = va_to_pa(mcpup->cpu_q_va);
110*1ae08745Sheppo 	mcpup->cpu_q_size =  cpu_q_size;
1117c478bd9Sstevel@tonic-gate 
112*1ae08745Sheppo 	dev_q_size = dev_q_entries * INTR_REPORT_SIZE;
113*1ae08745Sheppo 	mcpup->dev_q_va = contig_mem_alloc(dev_q_size);
1147c478bd9Sstevel@tonic-gate 	if (mcpup->dev_q_va == NULL)
1157c478bd9Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: dev intrq allocation failed",
1167c478bd9Sstevel@tonic-gate 		    cpu->cpu_id);
1177c478bd9Sstevel@tonic-gate 	mcpup->dev_q_base_pa = va_to_pa(mcpup->dev_q_va);
118*1ae08745Sheppo 	mcpup->dev_q_size =  dev_q_size;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	/* Allocate resumable queue and its kernel buffer */
121*1ae08745Sheppo 	cpu_rq_size = cpu_rq_entries * Q_ENTRY_SIZE;
122*1ae08745Sheppo 	mcpup->cpu_rq_va = contig_mem_alloc(2 * cpu_rq_size);
1237c478bd9Sstevel@tonic-gate 	if (mcpup->cpu_rq_va == NULL)
1247c478bd9Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: resumable queue allocation failed",
1257c478bd9Sstevel@tonic-gate 		    cpu->cpu_id);
1267c478bd9Sstevel@tonic-gate 	mcpup->cpu_rq_base_pa = va_to_pa(mcpup->cpu_rq_va);
127*1ae08745Sheppo 	mcpup->cpu_rq_size = cpu_rq_size;
1287c478bd9Sstevel@tonic-gate 	/* zero out the memory */
129*1ae08745Sheppo 	bzero(mcpup->cpu_rq_va, 2 * cpu_rq_size);
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	/* Allocate nonresumable queue here */
132*1ae08745Sheppo 	cpu_nrq_size = cpu_nrq_entries * Q_ENTRY_SIZE;
133*1ae08745Sheppo 	mcpup->cpu_nrq_va = contig_mem_alloc(2 * cpu_nrq_size);
1347c478bd9Sstevel@tonic-gate 	if (mcpup->cpu_nrq_va == NULL)
1357c478bd9Sstevel@tonic-gate 		cmn_err(CE_PANIC, "cpu%d: nonresumable queue "
1367c478bd9Sstevel@tonic-gate 		    "allocation failed", cpu->cpu_id);
1377c478bd9Sstevel@tonic-gate 	mcpup->cpu_nrq_base_pa = va_to_pa(mcpup->cpu_nrq_va);
138*1ae08745Sheppo 	mcpup->cpu_nrq_size = cpu_nrq_size;
1397c478bd9Sstevel@tonic-gate 	/* zero out the memory */
140*1ae08745Sheppo 	bzero(mcpup->cpu_nrq_va, 2 * cpu_nrq_size);
141*1ae08745Sheppo }
1427c478bd9Sstevel@tonic-gate 
143*1ae08745Sheppo void
144*1ae08745Sheppo cpu_intrq_cleanup(struct cpu *cpu)
145*1ae08745Sheppo {
146*1ae08745Sheppo 	struct machcpu *mcpup = &cpu->cpu_m;
147*1ae08745Sheppo 	int cpu_list_size;
148*1ae08745Sheppo 	uint64_t cpu_q_size;
149*1ae08745Sheppo 	uint64_t dev_q_size;
150*1ae08745Sheppo 	uint64_t cpu_rq_size;
151*1ae08745Sheppo 	uint64_t cpu_nrq_size;
152*1ae08745Sheppo 
153*1ae08745Sheppo 	/*
154*1ae08745Sheppo 	 * Free mondo data for xcalls.
155*1ae08745Sheppo 	 */
156*1ae08745Sheppo 	if (mcpup->mondo_data) {
157*1ae08745Sheppo 		contig_mem_free(mcpup->mondo_data, INTR_REPORT_SIZE);
158*1ae08745Sheppo 		mcpup->mondo_data = NULL;
159*1ae08745Sheppo 		mcpup->mondo_data_ra = NULL;
160*1ae08745Sheppo 	}
161*1ae08745Sheppo 
162*1ae08745Sheppo 	/*
163*1ae08745Sheppo 	 *  Free percpu list of NCPU for xcalls
164*1ae08745Sheppo 	 */
165*1ae08745Sheppo 	cpu_list_size = NCPU * sizeof (uint16_t);
166*1ae08745Sheppo 	if (cpu_list_size < INTR_REPORT_SIZE)
167*1ae08745Sheppo 		cpu_list_size = INTR_REPORT_SIZE;
168*1ae08745Sheppo 
169*1ae08745Sheppo 	if (mcpup->cpu_list) {
170*1ae08745Sheppo 		contig_mem_free(mcpup->cpu_list, cpu_list_size);
171*1ae08745Sheppo 		mcpup->cpu_list = NULL;
172*1ae08745Sheppo 		mcpup->cpu_list_ra = NULL;
173*1ae08745Sheppo 	}
174*1ae08745Sheppo 
175*1ae08745Sheppo 	/*
176*1ae08745Sheppo 	 * Free sun4v interrupt and error queues.
177*1ae08745Sheppo 	 */
178*1ae08745Sheppo 	if (mcpup->cpu_q_va) {
179*1ae08745Sheppo 		cpu_q_size = cpu_q_entries * INTR_REPORT_SIZE;
180*1ae08745Sheppo 		contig_mem_free(mcpup->cpu_q_va, cpu_q_size);
181*1ae08745Sheppo 		mcpup->cpu_q_va = NULL;
182*1ae08745Sheppo 		mcpup->cpu_q_base_pa = NULL;
183*1ae08745Sheppo 		mcpup->cpu_q_size = 0;
184*1ae08745Sheppo 	}
185*1ae08745Sheppo 
186*1ae08745Sheppo 	if (mcpup->dev_q_va) {
187*1ae08745Sheppo 		dev_q_size = dev_q_entries * INTR_REPORT_SIZE;
188*1ae08745Sheppo 		contig_mem_free(mcpup->dev_q_va, dev_q_size);
189*1ae08745Sheppo 		mcpup->dev_q_va = NULL;
190*1ae08745Sheppo 		mcpup->dev_q_base_pa = NULL;
191*1ae08745Sheppo 		mcpup->dev_q_size = 0;
192*1ae08745Sheppo 	}
193*1ae08745Sheppo 
194*1ae08745Sheppo 	if (mcpup->cpu_rq_va) {
195*1ae08745Sheppo 		cpu_rq_size = cpu_rq_entries * Q_ENTRY_SIZE;
196*1ae08745Sheppo 		contig_mem_free(mcpup->cpu_rq_va, 2 * cpu_rq_size);
197*1ae08745Sheppo 		mcpup->cpu_rq_va = NULL;
198*1ae08745Sheppo 		mcpup->cpu_rq_base_pa = NULL;
199*1ae08745Sheppo 		mcpup->cpu_rq_size = 0;
200*1ae08745Sheppo 	}
201*1ae08745Sheppo 
202*1ae08745Sheppo 	if (mcpup->cpu_nrq_va) {
203*1ae08745Sheppo 		cpu_nrq_size = cpu_nrq_entries * Q_ENTRY_SIZE;
204*1ae08745Sheppo 		contig_mem_free(mcpup->cpu_nrq_va, 2 * cpu_nrq_size);
205*1ae08745Sheppo 		mcpup->cpu_nrq_va = NULL;
206*1ae08745Sheppo 		mcpup->cpu_nrq_base_pa = NULL;
207*1ae08745Sheppo 		mcpup->cpu_nrq_size = 0;
208*1ae08745Sheppo 	}
2097c478bd9Sstevel@tonic-gate }
210