intrq.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
152N/A/*
152N/A * CDDL HEADER START
152N/A *
152N/A * The contents of this file are subject to the terms of the
152N/A * Common Development and Distribution License, Version 1.0 only
152N/A * (the "License"). You may not use this file except in compliance
152N/A * with the License.
152N/A *
152N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
152N/A * or http://www.opensolaris.org/os/licensing.
152N/A * See the License for the specific language governing permissions
152N/A * and limitations under the License.
152N/A *
152N/A * When distributing Covered Code, include this CDDL HEADER in each
152N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152N/A * If applicable, add the following below this CDDL HEADER, with the
152N/A * fields enclosed by brackets "[]" replaced with your own identifying
152N/A * information: Portions Copyright [yyyy] [name of copyright owner]
873N/A *
152N/A * CDDL HEADER END
152N/A */
152N/A/*
152N/A * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
152N/A * Use is subject to license terms.
781N/A */
152N/A
152N/A#pragma ident "%Z%%M% %I% %E% SMI"
2086N/A
152N/A#include <sys/machsystm.h>
152N/A#include <sys/cpu.h>
152N/A#include <sys/intreg.h>
152N/A#include <sys/machcpuvar.h>
152N/A#include <vm/hat_sfmmu.h>
1795N/A#include <sys/error.h>
1795N/A#include <sys/hypervisor_api.h>
152N/A
152N/A/*
152N/A * XXX needs to be set by some algorithm that derives this
152N/A * from the partition description
152N/A */
361N/Aint cpu_q_entries = 128;
152N/Aint dev_q_entries = 128;
152N/A
421N/A/*
152N/A * Once the partition description if finallized
152N/A * cpu_q_entries and dev_q_entries will be set
152N/A * and be garaunteed to be two's power multiples.
152N/A */
338N/A#define INTR_CPU_Q 0x3c
152N/A#define INTR_DEV_Q 0x3d
152N/A#define INTR_REPORT_SIZE 64
152N/A#define INTR_CPU_Q_SIZE (cpu_q_entries * INTR_REPORT_SIZE)
1177N/A#define INTR_DEV_Q_SIZE (dev_q_entries * INTR_REPORT_SIZE)
152N/A
152N/A/*
152N/A * XXX - This needs to be rewritten with prom calls to
1795N/A * let OBP know the queues are allocated
152N/A */
1177N/Avoid
152N/Acpu_intrq_register(struct cpu *cpu)
152N/A{
152N/A struct machcpu *mcpup = &cpu->cpu_m;
152N/A uint64_t ret;
152N/A
152N/A ret = hv_cpu_qconf(INTR_CPU_Q, mcpup->cpu_q_base_pa, cpu_q_entries);
152N/A if (ret != H_EOK)
152N/A cmn_err(CE_PANIC, "cpu%d: cpu_mondo queue configuration "
152N/A "failed, error %lu", cpu->cpu_id, ret);
152N/A
152N/A ret = hv_cpu_qconf(INTR_DEV_Q, mcpup->dev_q_base_pa, dev_q_entries);
152N/A if (ret != H_EOK)
2086N/A cmn_err(CE_PANIC, "cpu%d: dev_mondo queue configuration "
152N/A "failed, error %lu", cpu->cpu_id, ret);
1060N/A
152N/A ret = hv_cpu_qconf(CPU_RQ, mcpup->cpu_rq_base_pa, CPU_RQ_ENTRIES);
152N/A if (ret != H_EOK)
152N/A cmn_err(CE_PANIC, "cpu%d: resumable error queue configuration "
152N/A "failed, error %lu", cpu->cpu_id, ret);
152N/A
152N/A ret = hv_cpu_qconf(CPU_NRQ, mcpup->cpu_nrq_base_pa,
152N/A CPU_NRQ_ENTRIES);
152N/A if (ret != H_EOK)
152N/A cmn_err(CE_PANIC, "cpu%d: non-resumable error queue "
152N/A "configuration failed, error %lu", cpu->cpu_id, ret);
152N/A}
152N/A
152N/Avoid
152N/Acpu_intrq_setup(struct cpu *cpu)
152N/A{
152N/A struct machcpu *mcpup = &cpu->cpu_m;
152N/A int cpu_list_size;
152N/A
152N/A /*
152N/A * Allocate mondo data for xcalls.
868N/A */
152N/A mcpup->mondo_data = contig_mem_alloc(INTR_REPORT_SIZE);
152N/A if (mcpup->mondo_data == NULL)
152N/A cmn_err(CE_PANIC, "cpu%d: cpu mondo_data allocation failed",
152N/A cpu->cpu_id);
152N/A
152N/A /*
152N/A * Allocate a percpu list of NCPU for xcalls
152N/A */
152N/A cpu_list_size = NCPU * sizeof (uint16_t);
152N/A if (cpu_list_size < INTR_REPORT_SIZE)
152N/A cpu_list_size = INTR_REPORT_SIZE;
152N/A
152N/A mcpup->cpu_list = contig_mem_alloc(cpu_list_size);
152N/A if (mcpup->mondo_data == NULL)
152N/A cmn_err(CE_PANIC, "cpu%d: cpu mondo_data allocation failed",
152N/A cpu->cpu_id);
152N/A mcpup->cpu_list_ra = va_to_pa(mcpup->cpu_list);
152N/A
152N/A /*
152N/A * va_to_pa() is too expensive to call for every crosscall
152N/A * so we do it here at init time and save it in machcpu.
152N/A */
152N/A mcpup->mondo_data_ra = va_to_pa(mcpup->mondo_data);
152N/A
152N/A /*
152N/A * Allocate sun4v interrupt and error queues.
152N/A */
152N/A mcpup->cpu_q_va = contig_mem_alloc(INTR_CPU_Q_SIZE);
152N/A if (mcpup->cpu_q_va == NULL)
152N/A cmn_err(CE_PANIC, "cpu%d: cpu intrq allocation failed",
152N/A cpu->cpu_id);
152N/A mcpup->cpu_q_base_pa = va_to_pa(mcpup->cpu_q_va);
2086N/A mcpup->cpu_q_size = INTR_CPU_Q_SIZE;
152N/A
152N/A mcpup->dev_q_va = contig_mem_alloc(INTR_DEV_Q_SIZE);
152N/A if (mcpup->dev_q_va == NULL)
509N/A cmn_err(CE_PANIC, "cpu%d: dev intrq allocation failed",
509N/A cpu->cpu_id);
509N/A mcpup->dev_q_base_pa = va_to_pa(mcpup->dev_q_va);
509N/A mcpup->dev_q_size = INTR_DEV_Q_SIZE;
152N/A
152N/A /* Allocate resumable queue and its kernel buffer */
152N/A mcpup->cpu_rq_va = contig_mem_alloc(2 * CPU_RQ_SIZE);
152N/A if (mcpup->cpu_rq_va == NULL)
152N/A cmn_err(CE_PANIC, "cpu%d: resumable queue allocation failed",
152N/A cpu->cpu_id);
152N/A mcpup->cpu_rq_base_pa = va_to_pa(mcpup->cpu_rq_va);
152N/A mcpup->cpu_rq_size = CPU_RQ_SIZE;
152N/A /* zero out the memory */
152N/A bzero(mcpup->cpu_rq_va, 2 * CPU_RQ_SIZE);
152N/A
152N/A /* Allocate nonresumable queue here */
152N/A mcpup->cpu_nrq_va = contig_mem_alloc(2 * CPU_NRQ_SIZE);
152N/A if (mcpup->cpu_nrq_va == NULL)
152N/A cmn_err(CE_PANIC, "cpu%d: nonresumable queue "
152N/A "allocation failed", cpu->cpu_id);
2086N/A mcpup->cpu_nrq_base_pa = va_to_pa(mcpup->cpu_nrq_va);
152N/A mcpup->cpu_nrq_size = CPU_NRQ_SIZE;
152N/A /* zero out the memory */
152N/A bzero(mcpup->cpu_nrq_va, 2 * CPU_NRQ_SIZE);
152N/A
152N/A}
152N/A