1261268Sjhb/*-
2261268Sjhb * Copyright (c) 2014 Advanced Computing Technologies LLC
3261268Sjhb * Written by: John H. Baldwin <jhb@FreeBSD.org>
4261268Sjhb * All rights reserved.
5261268Sjhb *
6261268Sjhb * Redistribution and use in source and binary forms, with or without
7261268Sjhb * modification, are permitted provided that the following conditions
8261268Sjhb * are met:
9261268Sjhb * 1. Redistributions of source code must retain the above copyright
10261268Sjhb *    notice, this list of conditions and the following disclaimer.
11261268Sjhb * 2. Redistributions in binary form must reproduce the above copyright
12261268Sjhb *    notice, this list of conditions and the following disclaimer in the
13261268Sjhb *    documentation and/or other materials provided with the distribution.
14261268Sjhb *
15261268Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16261268Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17261268Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18261268Sjhb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19261268Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20261268Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21261268Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22261268Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23261268Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24261268Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25261268Sjhb * SUCH DAMAGE.
26261268Sjhb */
27261268Sjhb
28261268Sjhb#include <sys/cdefs.h>
29261268Sjhb__FBSDID("$FreeBSD$");
30261268Sjhb
31261268Sjhb#include <sys/types.h>
32261268Sjhb
33261268Sjhb#include <machine/vmm.h>
34261268Sjhb#include <vmmapi.h>
35261268Sjhb
36261268Sjhb#include "ioapic.h"
37261268Sjhb
38261268Sjhb/*
39261268Sjhb * Assign PCI INTx interrupts to I/O APIC pins in a round-robin
40261268Sjhb * fashion.  Note that we have no idea what the HPET is using, but the
41261268Sjhb * HPET is also programmable whereas this is intended for hardwired
42261268Sjhb * PCI interrupts.
43261268Sjhb *
44261268Sjhb * This assumes a single I/O APIC where pins >= 16 are permitted for
45261268Sjhb * PCI devices.
46261268Sjhb */
47261268Sjhbstatic int pci_pins;
48261268Sjhb
49261268Sjhbvoid
50261268Sjhbioapic_init(struct vmctx *ctx)
51261268Sjhb{
52261268Sjhb
53261268Sjhb	if (vm_ioapic_pincount(ctx, &pci_pins) < 0) {
54261268Sjhb		pci_pins = 0;
55261268Sjhb		return;
56261268Sjhb	}
57261268Sjhb
58261268Sjhb	/* Ignore the first 16 pins. */
59261268Sjhb	if (pci_pins <= 16) {
60261268Sjhb		pci_pins = 0;
61261268Sjhb		return;
62261268Sjhb	}
63261268Sjhb	pci_pins -= 16;
64261268Sjhb}
65261268Sjhb
66261268Sjhbint
67261268Sjhbioapic_pci_alloc_irq(void)
68261268Sjhb{
69261268Sjhb	static int last_pin;
70261268Sjhb
71261268Sjhb	if (pci_pins == 0)
72261268Sjhb		return (-1);
73261268Sjhb	return (16 + (last_pin++ % pci_pins));
74261268Sjhb}
75