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