1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/machsystm.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/cpu.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/intreg.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/machcpuvar.h> 33*7c478bd9Sstevel@tonic-gate #include <vm/hat_sfmmu.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/error.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/hypervisor_api.h> 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate /* 38*7c478bd9Sstevel@tonic-gate * XXX needs to be set by some algorithm that derives this 39*7c478bd9Sstevel@tonic-gate * from the partition description 40*7c478bd9Sstevel@tonic-gate */ 41*7c478bd9Sstevel@tonic-gate int cpu_q_entries = 128; 42*7c478bd9Sstevel@tonic-gate int dev_q_entries = 128; 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * Once the partition description if finallized 46*7c478bd9Sstevel@tonic-gate * cpu_q_entries and dev_q_entries will be set 47*7c478bd9Sstevel@tonic-gate * and be garaunteed to be two's power multiples. 48*7c478bd9Sstevel@tonic-gate */ 49*7c478bd9Sstevel@tonic-gate #define INTR_CPU_Q 0x3c 50*7c478bd9Sstevel@tonic-gate #define INTR_DEV_Q 0x3d 51*7c478bd9Sstevel@tonic-gate #define INTR_REPORT_SIZE 64 52*7c478bd9Sstevel@tonic-gate #define INTR_CPU_Q_SIZE (cpu_q_entries * INTR_REPORT_SIZE) 53*7c478bd9Sstevel@tonic-gate #define INTR_DEV_Q_SIZE (dev_q_entries * INTR_REPORT_SIZE) 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* 56*7c478bd9Sstevel@tonic-gate * XXX - This needs to be rewritten with prom calls to 57*7c478bd9Sstevel@tonic-gate * let OBP know the queues are allocated 58*7c478bd9Sstevel@tonic-gate */ 59*7c478bd9Sstevel@tonic-gate void 60*7c478bd9Sstevel@tonic-gate cpu_intrq_register(struct cpu *cpu) 61*7c478bd9Sstevel@tonic-gate { 62*7c478bd9Sstevel@tonic-gate struct machcpu *mcpup = &cpu->cpu_m; 63*7c478bd9Sstevel@tonic-gate uint64_t ret; 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate ret = hv_cpu_qconf(INTR_CPU_Q, mcpup->cpu_q_base_pa, cpu_q_entries); 66*7c478bd9Sstevel@tonic-gate if (ret != H_EOK) 67*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: cpu_mondo queue configuration " 68*7c478bd9Sstevel@tonic-gate "failed, error %lu", cpu->cpu_id, ret); 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate ret = hv_cpu_qconf(INTR_DEV_Q, mcpup->dev_q_base_pa, dev_q_entries); 71*7c478bd9Sstevel@tonic-gate if (ret != H_EOK) 72*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: dev_mondo queue configuration " 73*7c478bd9Sstevel@tonic-gate "failed, error %lu", cpu->cpu_id, ret); 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate ret = hv_cpu_qconf(CPU_RQ, mcpup->cpu_rq_base_pa, CPU_RQ_ENTRIES); 76*7c478bd9Sstevel@tonic-gate if (ret != H_EOK) 77*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: resumable error queue configuration " 78*7c478bd9Sstevel@tonic-gate "failed, error %lu", cpu->cpu_id, ret); 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate ret = hv_cpu_qconf(CPU_NRQ, mcpup->cpu_nrq_base_pa, 81*7c478bd9Sstevel@tonic-gate CPU_NRQ_ENTRIES); 82*7c478bd9Sstevel@tonic-gate if (ret != H_EOK) 83*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: non-resumable error queue " 84*7c478bd9Sstevel@tonic-gate "configuration failed, error %lu", cpu->cpu_id, ret); 85*7c478bd9Sstevel@tonic-gate } 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate void 88*7c478bd9Sstevel@tonic-gate cpu_intrq_setup(struct cpu *cpu) 89*7c478bd9Sstevel@tonic-gate { 90*7c478bd9Sstevel@tonic-gate struct machcpu *mcpup = &cpu->cpu_m; 91*7c478bd9Sstevel@tonic-gate int cpu_list_size; 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /* 94*7c478bd9Sstevel@tonic-gate * Allocate mondo data for xcalls. 95*7c478bd9Sstevel@tonic-gate */ 96*7c478bd9Sstevel@tonic-gate mcpup->mondo_data = contig_mem_alloc(INTR_REPORT_SIZE); 97*7c478bd9Sstevel@tonic-gate if (mcpup->mondo_data == NULL) 98*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: cpu mondo_data allocation failed", 99*7c478bd9Sstevel@tonic-gate cpu->cpu_id); 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate /* 102*7c478bd9Sstevel@tonic-gate * Allocate a percpu list of NCPU for xcalls 103*7c478bd9Sstevel@tonic-gate */ 104*7c478bd9Sstevel@tonic-gate cpu_list_size = NCPU * sizeof (uint16_t); 105*7c478bd9Sstevel@tonic-gate if (cpu_list_size < INTR_REPORT_SIZE) 106*7c478bd9Sstevel@tonic-gate cpu_list_size = INTR_REPORT_SIZE; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate mcpup->cpu_list = contig_mem_alloc(cpu_list_size); 109*7c478bd9Sstevel@tonic-gate if (mcpup->mondo_data == NULL) 110*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: cpu mondo_data allocation failed", 111*7c478bd9Sstevel@tonic-gate cpu->cpu_id); 112*7c478bd9Sstevel@tonic-gate mcpup->cpu_list_ra = va_to_pa(mcpup->cpu_list); 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * va_to_pa() is too expensive to call for every crosscall 116*7c478bd9Sstevel@tonic-gate * so we do it here at init time and save it in machcpu. 117*7c478bd9Sstevel@tonic-gate */ 118*7c478bd9Sstevel@tonic-gate mcpup->mondo_data_ra = va_to_pa(mcpup->mondo_data); 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate /* 121*7c478bd9Sstevel@tonic-gate * Allocate sun4v interrupt and error queues. 122*7c478bd9Sstevel@tonic-gate */ 123*7c478bd9Sstevel@tonic-gate mcpup->cpu_q_va = contig_mem_alloc(INTR_CPU_Q_SIZE); 124*7c478bd9Sstevel@tonic-gate if (mcpup->cpu_q_va == NULL) 125*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: cpu intrq allocation failed", 126*7c478bd9Sstevel@tonic-gate cpu->cpu_id); 127*7c478bd9Sstevel@tonic-gate mcpup->cpu_q_base_pa = va_to_pa(mcpup->cpu_q_va); 128*7c478bd9Sstevel@tonic-gate mcpup->cpu_q_size = INTR_CPU_Q_SIZE; 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate mcpup->dev_q_va = contig_mem_alloc(INTR_DEV_Q_SIZE); 131*7c478bd9Sstevel@tonic-gate if (mcpup->dev_q_va == NULL) 132*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: dev intrq allocation failed", 133*7c478bd9Sstevel@tonic-gate cpu->cpu_id); 134*7c478bd9Sstevel@tonic-gate mcpup->dev_q_base_pa = va_to_pa(mcpup->dev_q_va); 135*7c478bd9Sstevel@tonic-gate mcpup->dev_q_size = INTR_DEV_Q_SIZE; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate /* Allocate resumable queue and its kernel buffer */ 138*7c478bd9Sstevel@tonic-gate mcpup->cpu_rq_va = contig_mem_alloc(2 * CPU_RQ_SIZE); 139*7c478bd9Sstevel@tonic-gate if (mcpup->cpu_rq_va == NULL) 140*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: resumable queue allocation failed", 141*7c478bd9Sstevel@tonic-gate cpu->cpu_id); 142*7c478bd9Sstevel@tonic-gate mcpup->cpu_rq_base_pa = va_to_pa(mcpup->cpu_rq_va); 143*7c478bd9Sstevel@tonic-gate mcpup->cpu_rq_size = CPU_RQ_SIZE; 144*7c478bd9Sstevel@tonic-gate /* zero out the memory */ 145*7c478bd9Sstevel@tonic-gate bzero(mcpup->cpu_rq_va, 2 * CPU_RQ_SIZE); 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate /* Allocate nonresumable queue here */ 148*7c478bd9Sstevel@tonic-gate mcpup->cpu_nrq_va = contig_mem_alloc(2 * CPU_NRQ_SIZE); 149*7c478bd9Sstevel@tonic-gate if (mcpup->cpu_nrq_va == NULL) 150*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "cpu%d: nonresumable queue " 151*7c478bd9Sstevel@tonic-gate "allocation failed", cpu->cpu_id); 152*7c478bd9Sstevel@tonic-gate mcpup->cpu_nrq_base_pa = va_to_pa(mcpup->cpu_nrq_va); 153*7c478bd9Sstevel@tonic-gate mcpup->cpu_nrq_size = CPU_NRQ_SIZE; 154*7c478bd9Sstevel@tonic-gate /* zero out the memory */ 155*7c478bd9Sstevel@tonic-gate bzero(mcpup->cpu_nrq_va, 2 * CPU_NRQ_SIZE); 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate } 158