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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/pci_cfgacc.h>
27 
28 #define	PCI_CFGACC_FILLREQ(r, d, b, o, s, w, v)				\
29 	{(r).rcdip = (d); (r).bdf = (b); (r).offset = (o);		\
30 	(r).size = (s); (r).write = w; (r).ioacc = B_FALSE; 		\
31 	VAL64(&(r)) = (v); }
32 
33 /*
34  * Common interfaces for accessing pci config space
35  */
36 
37 /*
38  * This pointer should be initialized before using, here doesn't check it.
39  * For x86:
40  * 	initialized at the end of pci_check();
41  * For Sparc:
42  *  initialized in the px_attach().
43  */
44 void (*pci_cfgacc_acc_p)(pci_cfgacc_req_t *req);
45 
46 uint8_t
pci_cfgacc_get8(dev_info_t * rcdip,uint16_t bdf,uint16_t off)47 pci_cfgacc_get8(dev_info_t *rcdip, uint16_t bdf, uint16_t off)
48 {
49 	pci_cfgacc_req_t req;
50 
51 	PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 1, B_FALSE, 0);
52 	(*pci_cfgacc_acc_p)(&req);
53 	return (VAL8(&req));
54 }
55 
56 void
pci_cfgacc_put8(dev_info_t * rcdip,uint16_t bdf,uint16_t off,uint8_t data)57 pci_cfgacc_put8(dev_info_t *rcdip, uint16_t bdf, uint16_t off, uint8_t data)
58 {
59 	pci_cfgacc_req_t req;
60 
61 	PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 1, B_TRUE, data);
62 	(*pci_cfgacc_acc_p)(&req);
63 }
64 
65 uint16_t
pci_cfgacc_get16(dev_info_t * rcdip,uint16_t bdf,uint16_t off)66 pci_cfgacc_get16(dev_info_t *rcdip, uint16_t bdf, uint16_t off)
67 {
68 	pci_cfgacc_req_t req;
69 
70 	PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 2, B_FALSE, 0);
71 	(*pci_cfgacc_acc_p)(&req);
72 	return (VAL16(&req));
73 }
74 
75 void
pci_cfgacc_put16(dev_info_t * rcdip,uint16_t bdf,uint16_t off,uint16_t data)76 pci_cfgacc_put16(dev_info_t *rcdip, uint16_t bdf, uint16_t off, uint16_t data)
77 {
78 	pci_cfgacc_req_t req;
79 
80 	PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 2, B_TRUE, data);
81 	(*pci_cfgacc_acc_p)(&req);
82 }
83 
84 uint32_t
pci_cfgacc_get32(dev_info_t * rcdip,uint16_t bdf,uint16_t off)85 pci_cfgacc_get32(dev_info_t *rcdip, uint16_t bdf, uint16_t off)
86 {
87 	pci_cfgacc_req_t req;
88 
89 	PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 4, B_FALSE, 0);
90 	(*pci_cfgacc_acc_p)(&req);
91 	return (VAL32(&req));
92 }
93 
94 void
pci_cfgacc_put32(dev_info_t * rcdip,uint16_t bdf,uint16_t off,uint32_t data)95 pci_cfgacc_put32(dev_info_t *rcdip, uint16_t bdf, uint16_t off, uint32_t data)
96 {
97 	pci_cfgacc_req_t req;
98 
99 	PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 4, B_TRUE, data);
100 	(*pci_cfgacc_acc_p)(&req);
101 }
102 
103 uint64_t
pci_cfgacc_get64(dev_info_t * rcdip,uint16_t bdf,uint16_t off)104 pci_cfgacc_get64(dev_info_t *rcdip, uint16_t bdf, uint16_t off)
105 {
106 	pci_cfgacc_req_t req;
107 
108 	PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 8, B_FALSE, 0);
109 	(*pci_cfgacc_acc_p)(&req);
110 	return (VAL64(&req));
111 }
112 
113 void
pci_cfgacc_put64(dev_info_t * rcdip,uint16_t bdf,uint16_t off,uint64_t data)114 pci_cfgacc_put64(dev_info_t *rcdip, uint16_t bdf, uint16_t off, uint64_t data)
115 {
116 	pci_cfgacc_req_t req;
117 
118 	PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 8, B_TRUE, data);
119 	(*pci_cfgacc_acc_p)(&req);
120 }
121