xref: /freebsd/usr.sbin/bhyve/pci_hostbridge.c (revision 1d386b48a555f61cb7325543adbbb5c3f3407a66)
1366f6083SPeter Grehan /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
4366f6083SPeter Grehan  * Copyright (c) 2011 NetApp, Inc.
5366f6083SPeter Grehan  * All rights reserved.
6366f6083SPeter Grehan  *
7366f6083SPeter Grehan  * Redistribution and use in source and binary forms, with or without
8366f6083SPeter Grehan  * modification, are permitted provided that the following conditions
9366f6083SPeter Grehan  * are met:
10366f6083SPeter Grehan  * 1. Redistributions of source code must retain the above copyright
11366f6083SPeter Grehan  *    notice, this list of conditions and the following disclaimer.
12366f6083SPeter Grehan  * 2. Redistributions in binary form must reproduce the above copyright
13366f6083SPeter Grehan  *    notice, this list of conditions and the following disclaimer in the
14366f6083SPeter Grehan  *    documentation and/or other materials provided with the distribution.
15366f6083SPeter Grehan  *
16366f6083SPeter Grehan  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17366f6083SPeter Grehan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18366f6083SPeter Grehan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19366f6083SPeter Grehan  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20366f6083SPeter Grehan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21366f6083SPeter Grehan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22366f6083SPeter Grehan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23366f6083SPeter Grehan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24366f6083SPeter Grehan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25366f6083SPeter Grehan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26366f6083SPeter Grehan  * SUCH DAMAGE.
27366f6083SPeter Grehan  */
28366f6083SPeter Grehan 
29366f6083SPeter Grehan #include <sys/cdefs.h>
30b72e06b1SCorvin Köhne #include <err.h>
31621b5090SJohn Baldwin #include <stdlib.h>
32621b5090SJohn Baldwin 
33621b5090SJohn Baldwin #include "config.h"
34366f6083SPeter Grehan #include "pci_emul.h"
35366f6083SPeter Grehan 
36366f6083SPeter Grehan static int
pci_hostbridge_init(struct pci_devinst * pi,nvlist_t * nvl)376a284cacSJohn Baldwin pci_hostbridge_init(struct pci_devinst *pi, nvlist_t *nvl)
38366f6083SPeter Grehan {
39621b5090SJohn Baldwin 	const char *value;
40621b5090SJohn Baldwin 	u_int vendor, device;
41621b5090SJohn Baldwin 
42621b5090SJohn Baldwin 	vendor = 0x1275;	/* NetApp */
43621b5090SJohn Baldwin 	device = 0x1275;	/* NetApp */
44621b5090SJohn Baldwin 
45621b5090SJohn Baldwin 	value = get_config_value_node(nvl, "vendor");
46621b5090SJohn Baldwin 	if (value != NULL)
47621b5090SJohn Baldwin 		vendor = strtol(value, NULL, 0);
48b72e06b1SCorvin Köhne 	else
49b72e06b1SCorvin Köhne 		vendor = pci_config_read_reg(NULL, nvl, PCIR_VENDOR, 2, vendor);
509f40a3beSJohn Baldwin 	value = get_config_value_node(nvl, "devid");
51621b5090SJohn Baldwin 	if (value != NULL)
52621b5090SJohn Baldwin 		device = strtol(value, NULL, 0);
53b72e06b1SCorvin Köhne 	else
54b72e06b1SCorvin Köhne 		device = pci_config_read_reg(NULL, nvl, PCIR_DEVICE, 2, device);
55366f6083SPeter Grehan 
56366f6083SPeter Grehan 	/* config space */
57621b5090SJohn Baldwin 	pci_set_cfgdata16(pi, PCIR_VENDOR, vendor);
58621b5090SJohn Baldwin 	pci_set_cfgdata16(pi, PCIR_DEVICE, device);
59a0df62cdSTycho Nightingale 	pci_set_cfgdata8(pi, PCIR_HDRTYPE, PCIM_HDRTYPE_NORMAL);
60366f6083SPeter Grehan 	pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE);
61366f6083SPeter Grehan 	pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_HOST);
62366f6083SPeter Grehan 
6374f80b23SNeel Natu 	pci_emul_add_pciecap(pi, PCIEM_TYPE_ROOT_PORT);
6474f80b23SNeel Natu 
65366f6083SPeter Grehan 	return (0);
66366f6083SPeter Grehan }
67366f6083SPeter Grehan 
68062b878fSPeter Grehan static int
pci_amd_hostbridge_legacy_config(nvlist_t * nvl,const char * opts __unused)6998d920d9SMark Johnston pci_amd_hostbridge_legacy_config(nvlist_t *nvl, const char *opts __unused)
70062b878fSPeter Grehan {
71b72e06b1SCorvin Köhne 	nvlist_t *pci_regs;
72b72e06b1SCorvin Köhne 
73b72e06b1SCorvin Köhne 	pci_regs = create_relative_config_node(nvl, "pcireg");
74b72e06b1SCorvin Köhne 	if (pci_regs == NULL) {
75b72e06b1SCorvin Köhne 		warnx("amd_hostbridge: failed to create pciregs node");
76b72e06b1SCorvin Köhne 		return (-1);
77b72e06b1SCorvin Köhne 	}
78b72e06b1SCorvin Köhne 
79b72e06b1SCorvin Köhne 	set_config_value_node(pci_regs, "vendor", "0x1022"); /* AMD */
80b72e06b1SCorvin Köhne 	set_config_value_node(pci_regs, "device", "0x7432"); /* made up */
81062b878fSPeter Grehan 
82062b878fSPeter Grehan 	return (0);
83062b878fSPeter Grehan }
84062b878fSPeter Grehan 
85*6f7d2cf8SVitaliy Gusev #ifdef BHYVE_SNAPSHOT
86*6f7d2cf8SVitaliy Gusev static int
pci_de_snapshot(struct vm_snapshot_meta * meta __unused)87*6f7d2cf8SVitaliy Gusev pci_de_snapshot(struct vm_snapshot_meta *meta __unused)
88*6f7d2cf8SVitaliy Gusev {
89*6f7d2cf8SVitaliy Gusev 	return (0);
90*6f7d2cf8SVitaliy Gusev }
91*6f7d2cf8SVitaliy Gusev #endif
92*6f7d2cf8SVitaliy Gusev 
9337045dfaSMark Johnston static const struct pci_devemu pci_de_amd_hostbridge = {
94062b878fSPeter Grehan 	.pe_emu = "amd_hostbridge",
95621b5090SJohn Baldwin 	.pe_legacy_config = pci_amd_hostbridge_legacy_config,
96621b5090SJohn Baldwin 	.pe_alias = "hostbridge",
97062b878fSPeter Grehan };
98062b878fSPeter Grehan PCI_EMUL_SET(pci_de_amd_hostbridge);
99062b878fSPeter Grehan 
10037045dfaSMark Johnston static const struct pci_devemu pci_de_hostbridge = {
101366f6083SPeter Grehan 	.pe_emu = "hostbridge",
102366f6083SPeter Grehan 	.pe_init = pci_hostbridge_init,
103*6f7d2cf8SVitaliy Gusev #ifdef BHYVE_SNAPSHOT
104*6f7d2cf8SVitaliy Gusev 	.pe_snapshot =	pci_de_snapshot,
105*6f7d2cf8SVitaliy Gusev #endif
106366f6083SPeter Grehan };
107366f6083SPeter Grehan PCI_EMUL_SET(pci_de_hostbridge);
108