pci.c revision 1.6 1 1.6 riastrad /* $NetBSD: pci.c,v 1.6 2022/02/16 23:49:26 riastradh Exp $ */
2 1.1 sakamoto
3 1.5 kiyohara /*
4 1.5 kiyohara * Copyright (C) 1995-1997 Gary Thomas (gdt (at) linuxppc.org)
5 1.1 sakamoto * All rights reserved.
6 1.1 sakamoto *
7 1.5 kiyohara * Adapted from a program by:
8 1.5 kiyohara * Steve Sellgren
9 1.5 kiyohara * San Francisco Indigo Company
10 1.5 kiyohara * sfindigo!sellgren (at) uunet.uu.net
11 1.5 kiyohara * Adapted for Moto boxes by:
12 1.5 kiyohara * Pat Kane & Mark Scott, 1996
13 1.5 kiyohara * Fixed for IBM/PowerStack II Pat Kane 1997
14 1.1 sakamoto *
15 1.1 sakamoto * Redistribution and use in source and binary forms, with or without
16 1.1 sakamoto * modification, are permitted provided that the following conditions
17 1.1 sakamoto * are met:
18 1.1 sakamoto * 1. Redistributions of source code must retain the above copyright
19 1.1 sakamoto * notice, this list of conditions and the following disclaimer.
20 1.1 sakamoto * 2. Redistributions in binary form must reproduce the above copyright
21 1.1 sakamoto * notice, this list of conditions and the following disclaimer in the
22 1.1 sakamoto * documentation and/or other materials provided with the distribution.
23 1.1 sakamoto * 3. All advertising materials mentioning features or use of this software
24 1.1 sakamoto * must display the following acknowledgement:
25 1.5 kiyohara * This product includes software developed by Gary Thomas.
26 1.5 kiyohara * 4. The name of the author may not be used to endorse or promote products
27 1.5 kiyohara * derived from this software without specific prior written permission.
28 1.1 sakamoto *
29 1.5 kiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
30 1.5 kiyohara * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
31 1.5 kiyohara * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32 1.5 kiyohara * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
33 1.5 kiyohara * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
34 1.5 kiyohara * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 1.5 kiyohara * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 1.5 kiyohara * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 1.5 kiyohara * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 1.5 kiyohara * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 1.1 sakamoto */
40 1.1 sakamoto
41 1.5 kiyohara #include <lib/libsa/stand.h>
42 1.5 kiyohara #include <sys/bswap.h>
43 1.1 sakamoto #include <dev/pci/pcireg.h>
44 1.5 kiyohara #include "boot.h"
45 1.1 sakamoto
46 1.5 kiyohara #define NSLOTS 5
47 1.5 kiyohara #define NPCIREGS 10
48 1.1 sakamoto
49 1.5 kiyohara
50 1.5 kiyohara /*
51 1.5 kiyohara * should use devfunc number/indirect method to be totally safe on
52 1.5 kiyohara * all machines, this works for now on 3 slot Moto boxes
53 1.5 kiyohara */
54 1.5 kiyohara
55 1.5 kiyohara #define PCI_CONFIG_SPACE_BASE 0x80800000
56 1.5 kiyohara #define PCI_CONFIG_SPACE(d, f) \
57 1.5 kiyohara (u_long *)(PCI_CONFIG_SPACE_BASE | (1 << (d)) | ((f) << 8))
58 1.5 kiyohara
59 1.5 kiyohara struct PCI_ConfigInfo {
60 1.5 kiyohara u_long *config_addr;
61 1.5 kiyohara u_long regs[NPCIREGS];
62 1.5 kiyohara } PCI_slots [NSLOTS] = {
63 1.5 kiyohara { PCI_CONFIG_SPACE(11, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
64 1.5 kiyohara { PCI_CONFIG_SPACE(12, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
65 1.5 kiyohara { PCI_CONFIG_SPACE(13, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
66 1.5 kiyohara { PCI_CONFIG_SPACE(14, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
67 1.5 kiyohara { PCI_CONFIG_SPACE(15, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
68 1.5 kiyohara };
69 1.5 kiyohara
70 1.5 kiyohara
71 1.5 kiyohara #define DEVID (PCI_ID_REG >> 2)
72 1.5 kiyohara #define CMD (PCI_COMMAND_STATUS_REG >> 2)
73 1.5 kiyohara #define CLASS (PCI_CLASS_REG >> 2)
74 1.5 kiyohara #define BAR_BASE (PCI_MAPREG_START >> 2)
75 1.5 kiyohara
76 1.5 kiyohara /*
77 1.5 kiyohara * The following code modifies the PCI Command register
78 1.5 kiyohara * to enable memory and I/O accesses.
79 1.5 kiyohara */
80 1.5 kiyohara void
81 1.5 kiyohara enablePCI(int slot, int io, int mem, int master)
82 1.5 kiyohara {
83 1.5 kiyohara volatile u_char *ppci;
84 1.5 kiyohara u_char enable = 0;
85 1.5 kiyohara
86 1.5 kiyohara if (io)
87 1.5 kiyohara enable |= PCI_COMMAND_IO_ENABLE;
88 1.5 kiyohara if (mem)
89 1.5 kiyohara enable |= PCI_COMMAND_MEM_ENABLE;
90 1.5 kiyohara if (master)
91 1.5 kiyohara enable |= PCI_COMMAND_MASTER_ENABLE;
92 1.5 kiyohara
93 1.5 kiyohara ppci = (u_char *)&PCI_slots[slot].config_addr[CMD];
94 1.5 kiyohara *ppci = enable;
95 1.6 riastrad __asm volatile("eieio" ::: "memory");
96 1.5 kiyohara }
97 1.5 kiyohara
98 1.5 kiyohara void
99 1.5 kiyohara scanPCI(void)
100 1.1 sakamoto {
101 1.5 kiyohara struct PCI_ConfigInfo *pslot;
102 1.5 kiyohara int slt, r;
103 1.5 kiyohara
104 1.5 kiyohara for (slt = 0; slt < NSLOTS; slt++) {
105 1.5 kiyohara pslot = &PCI_slots[slt];
106 1.5 kiyohara for (r = 0; r < NPCIREGS; r++)
107 1.5 kiyohara pslot->regs[r] = bswap32(pslot->config_addr[r]);
108 1.5 kiyohara }
109 1.5 kiyohara }
110 1.5 kiyohara
111 1.5 kiyohara int
112 1.5 kiyohara findPCIVga(void)
113 1.5 kiyohara {
114 1.5 kiyohara struct PCI_ConfigInfo *pslot;
115 1.5 kiyohara int theSlot = -1;
116 1.5 kiyohara int highVgaSlot = -1;
117 1.5 kiyohara int slt;
118 1.5 kiyohara
119 1.5 kiyohara for (slt = 0; slt < NSLOTS; slt++) {
120 1.5 kiyohara pslot = &PCI_slots[slt];
121 1.5 kiyohara if (pslot->regs[DEVID] != 0xffffffff) { /* card in slot ? */
122 1.5 kiyohara if (PCI_CLASS(pslot->regs[CLASS]) ==
123 1.5 kiyohara PCI_CLASS_DISPLAY) {
124 1.5 kiyohara highVgaSlot = slt;
125 1.5 kiyohara if ((pslot->regs[CMD] & 0x03)) { /* did firmware enable it ? */
126 1.5 kiyohara theSlot = slt;
127 1.5 kiyohara }
128 1.5 kiyohara }
129 1.5 kiyohara }
130 1.5 kiyohara }
131 1.5 kiyohara if (theSlot == -1)
132 1.5 kiyohara theSlot = highVgaSlot;
133 1.1 sakamoto
134 1.5 kiyohara return theSlot;
135 1.1 sakamoto }
136 1.1 sakamoto
137 1.5 kiyohara int
138 1.5 kiyohara PCISlotnum(u_int bus, u_int dev, u_int func)
139 1.1 sakamoto {
140 1.5 kiyohara u_long *tag;
141 1.5 kiyohara int i;
142 1.1 sakamoto
143 1.5 kiyohara if (bus != 0 ||
144 1.5 kiyohara dev < 11 || dev > 15 ||
145 1.5 kiyohara func > 7)
146 1.5 kiyohara return -1;
147 1.5 kiyohara
148 1.5 kiyohara tag = PCI_CONFIG_SPACE(dev, func);
149 1.5 kiyohara for (i = 0; i < sizeof(PCI_slots) / sizeof(struct PCI_ConfigInfo); i++)
150 1.5 kiyohara if (tag == PCI_slots[i].config_addr)
151 1.5 kiyohara return i;
152 1.5 kiyohara return -1;
153 1.1 sakamoto }
154 1.1 sakamoto
155 1.5 kiyohara /* return Vendor ID of card in the slot */
156 1.5 kiyohara int
157 1.5 kiyohara PCIVendor(int slotnum)
158 1.1 sakamoto {
159 1.5 kiyohara struct PCI_ConfigInfo *pslot;
160 1.1 sakamoto
161 1.5 kiyohara pslot = &PCI_slots[slotnum];
162 1.1 sakamoto
163 1.5 kiyohara return pslot->regs[DEVID] & 0xffff;
164 1.5 kiyohara }
165 1.1 sakamoto
166 1.5 kiyohara /* return mapped address for I/O or Memory */
167 1.5 kiyohara u_long
168 1.5 kiyohara PCIAddress(int slotnum, u_int bar, int type)
169 1.5 kiyohara {
170 1.5 kiyohara struct PCI_ConfigInfo *pslot;
171 1.2 sakamoto
172 1.5 kiyohara if (bar >= 6)
173 1.5 kiyohara return 0xffffffff;
174 1.1 sakamoto
175 1.5 kiyohara pslot = &PCI_slots[slotnum];
176 1.1 sakamoto
177 1.5 kiyohara if (pslot->regs[DEVID] == 0xffffffff ||
178 1.5 kiyohara PCI_MAPREG_TYPE(pslot->regs[BAR_BASE + bar]) != type)
179 1.5 kiyohara return 0xffffffff;
180 1.2 sakamoto
181 1.5 kiyohara return PCI_MAPREG_MEM_ADDR(pslot->regs[BAR_BASE + bar]);
182 1.5 kiyohara }
183 1.2 sakamoto
184 1.5 kiyohara #ifdef DEBUG
185 1.5 kiyohara void
186 1.5 kiyohara printPCIslots(void)
187 1.5 kiyohara {
188 1.5 kiyohara int i;
189 1.5 kiyohara for (i = 0; i < NSLOTS; i++) {
190 1.5 kiyohara printf("PCI Slot number: %d", i);
191 1.5 kiyohara printf(" Vendor ID: 0x%x\n", PCIVendor(i));
192 1.1 sakamoto }
193 1.1 sakamoto }
194 1.5 kiyohara #endif /* DEBUG */
195