ioapic.c revision 261268
1246057Sganbold/*-
2266337Sian * Copyright (c) 2014 Advanced Computing Technologies LLC
3246057Sganbold * Written by: John H. Baldwin <jhb@FreeBSD.org>
4246057Sganbold * All rights reserved.
5246057Sganbold *
6246057Sganbold * Redistribution and use in source and binary forms, with or without
7246057Sganbold * modification, are permitted provided that the following conditions
8246057Sganbold * are met:
9246057Sganbold * 1. Redistributions of source code must retain the above copyright
10246057Sganbold *    notice, this list of conditions and the following disclaimer.
11246057Sganbold * 2. Redistributions in binary form must reproduce the above copyright
12246057Sganbold *    notice, this list of conditions and the following disclaimer in the
13246057Sganbold *    documentation and/or other materials provided with the distribution.
14246057Sganbold *
15246057Sganbold * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16246057Sganbold * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17246057Sganbold * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18246057Sganbold * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19246057Sganbold * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20246057Sganbold * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21246057Sganbold * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22246057Sganbold * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23246057Sganbold * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24246057Sganbold * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25246057Sganbold * SUCH DAMAGE.
26246057Sganbold */
27246057Sganbold
28246057Sganbold#include <sys/cdefs.h>
29246057Sganbold__FBSDID("$FreeBSD: head/usr.sbin/bhyve/ioapic.c 261268 2014-01-29 14:56:48Z jhb $");
30246057Sganbold
31246057Sganbold#include <sys/types.h>
32246057Sganbold
33246057Sganbold#include <machine/vmm.h>
34246057Sganbold#include <vmmapi.h>
35246057Sganbold
36246057Sganbold#include "ioapic.h"
37246057Sganbold
38246057Sganbold/*
39246057Sganbold * Assign PCI INTx interrupts to I/O APIC pins in a round-robin
40246057Sganbold * fashion.  Note that we have no idea what the HPET is using, but the
41246057Sganbold * HPET is also programmable whereas this is intended for hardwired
42246057Sganbold * PCI interrupts.
43246375Sganbold *
44246057Sganbold * This assumes a single I/O APIC where pins >= 16 are permitted for
45246057Sganbold * PCI devices.
46246057Sganbold */
47246057Sganboldstatic int pci_pins;
48246057Sganbold
49246057Sganboldvoid
50246057Sganboldioapic_init(struct vmctx *ctx)
51246057Sganbold{
52246057Sganbold
53246057Sganbold	if (vm_ioapic_pincount(ctx, &pci_pins) < 0) {
54246057Sganbold		pci_pins = 0;
55246057Sganbold		return;
56246057Sganbold	}
57246057Sganbold
58246057Sganbold	/* Ignore the first 16 pins. */
59246057Sganbold	if (pci_pins <= 16) {
60246057Sganbold		pci_pins = 0;
61246057Sganbold		return;
62246375Sganbold	}
63246375Sganbold	pci_pins -= 16;
64246057Sganbold}
65246057Sganbold
66246057Sganboldint
67246057Sganboldioapic_pci_alloc_irq(void)
68246057Sganbold{
69246057Sganbold	static int last_pin;
70246057Sganbold
71246057Sganbold	if (pci_pins == 0)
72246057Sganbold		return (-1);
73246057Sganbold	return (16 + (last_pin++ % pci_pins));
74246057Sganbold}
75246057Sganbold