1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#include <sys/types.h>
28#include <sys/cmn_err.h>
29#include <sys/errno.h>
30#include <sys/systm.h>
31#include <sys/sunddi.h>
32#include <sys/pci_cfgspace.h>
33#include <sys/pci.h>
34#include <sys/pcie.h>
35#include <vm/seg_kmem.h>
36#include <sys/mman.h>
37#include <sys/cpu_module.h>
38#include "intel_nhm.h"
39
40static ddi_acc_handle_t dev_pci_hdl[MAX_CPU_NODES][CPU_PCI_DEVS][CPU_PCI_FUNCS];
41
42void
43nhm_pci_cfg_setup(dev_info_t *dip)
44{
45	pci_regspec_t reg;
46	int i, j, k;
47
48	reg.pci_phys_mid = 0;
49	reg.pci_phys_low = 0;
50	reg.pci_size_hi = 0;
51	reg.pci_size_low = PCIE_CONF_HDR_SIZE; /* overriden in pciex */
52	for (i = 0; i < MAX_CPU_NODES; i++) {
53		for (j = 0; j < CPU_PCI_DEVS; j++) {
54			for (k = 0; k < CPU_PCI_FUNCS; k++) {
55				reg.pci_phys_hi = ((SOCKET_BUS(i))
56				    << PCI_REG_BUS_SHIFT) +
57				    (j << PCI_REG_DEV_SHIFT) +
58				    (k << PCI_REG_FUNC_SHIFT);
59				if (ddi_prop_update_int_array(
60				    DDI_MAJOR_T_UNKNOWN, dip, "reg",
61				    (int *)&reg, sizeof (reg)/sizeof (int)) !=
62				    DDI_PROP_SUCCESS)
63					cmn_err(CE_WARN, "nhm_pci_cfg_setup: "
64					    "cannot create reg property");
65
66				if (pci_config_setup(dip,
67				    &dev_pci_hdl[i][j][k]) != DDI_SUCCESS)
68					cmn_err(CE_WARN, "intel_nhm: "
69					    "pci_config_setup failed");
70			}
71		}
72	}
73	ddi_prop_remove_all(dip);
74}
75
76void
77nhm_pci_cfg_free()
78{
79	int i, j, k;
80
81	for (i = 0; i < MAX_CPU_NODES; i++) {
82		for (j = 0; j < CPU_PCI_DEVS; j++) {
83			for (k = 0; k < CPU_PCI_FUNCS; k++) {
84				pci_config_teardown(&dev_pci_hdl[i][j][k]);
85			}
86		}
87	}
88}
89
90static ddi_acc_handle_t
91nhm_get_hdl(int bus, int dev, int func)
92{
93	ddi_acc_handle_t hdl;
94	int slot;
95
96	if (bus >= SOCKET_BUS(MAX_CPU_NODES) && bus <= SOCKET_BUS(0) &&
97	    dev < CPU_PCI_DEVS && func < CPU_PCI_FUNCS) {
98		slot = SOCKET_BUS(0) - bus;
99		ASSERT(slot >= 0 && slot < MAX_CPU_NODES);
100		hdl = dev_pci_hdl[slot][dev][func];
101	} else {
102		hdl = 0;
103	}
104	return (hdl);
105}
106
107uint8_t
108nhm_pci_getb(int bus, int dev, int func, int reg, int *interpose)
109{
110	ddi_acc_handle_t hdl;
111
112	hdl = nhm_get_hdl(bus, dev, func);
113	return (cmi_pci_getb(bus, dev, func, reg, interpose, hdl));
114}
115
116uint16_t
117nhm_pci_getw(int bus, int dev, int func, int reg, int *interpose)
118{
119	ddi_acc_handle_t hdl;
120
121	hdl = nhm_get_hdl(bus, dev, func);
122	return (cmi_pci_getw(bus, dev, func, reg, interpose, hdl));
123}
124
125uint32_t
126nhm_pci_getl(int bus, int dev, int func, int reg, int *interpose)
127{
128	ddi_acc_handle_t hdl;
129
130	hdl = nhm_get_hdl(bus, dev, func);
131	return (cmi_pci_getl(bus, dev, func, reg, interpose, hdl));
132}
133
134void
135nhm_pci_putb(int bus, int dev, int func, int reg, uint8_t val)
136{
137	ddi_acc_handle_t hdl;
138
139	hdl = nhm_get_hdl(bus, dev, func);
140	cmi_pci_putb(bus, dev, func, reg, hdl, val);
141}
142
143void
144nhm_pci_putw(int bus, int dev, int func, int reg, uint16_t val)
145{
146	ddi_acc_handle_t hdl;
147
148	hdl = nhm_get_hdl(bus, dev, func);
149	cmi_pci_putw(bus, dev, func, reg, hdl, val);
150}
151
152void
153nhm_pci_putl(int bus, int dev, int func, int reg, uint32_t val)
154{
155	ddi_acc_handle_t hdl;
156
157	hdl = nhm_get_hdl(bus, dev, func);
158	cmi_pci_putl(bus, dev, func, reg, hdl, val);
159}
160