rmixl_cpunode.c revision 1.1.2.5 1 1.1.2.5 matt /* $NetBSD: rmixl_cpunode.c,v 1.1.2.5 2011/12/24 01:57:54 matt Exp $ */
2 1.1.2.1 cliff
3 1.1.2.1 cliff /*
4 1.1.2.1 cliff * Copyright (c) 1994,1995 Mark Brinicombe.
5 1.1.2.1 cliff * Copyright (c) 1994 Brini.
6 1.1.2.1 cliff * All rights reserved.
7 1.1.2.1 cliff *
8 1.1.2.1 cliff * Redistribution and use in source and binary forms, with or without
9 1.1.2.1 cliff * modification, are permitted provided that the following conditions
10 1.1.2.1 cliff * are met:
11 1.1.2.1 cliff * 1. Redistributions of source code must retain the above copyright
12 1.1.2.1 cliff * notice, this list of conditions and the following disclaimer.
13 1.1.2.1 cliff * 2. Redistributions in binary form must reproduce the above copyright
14 1.1.2.1 cliff * notice, this list of conditions and the following disclaimer in the
15 1.1.2.1 cliff * documentation and/or other materials provided with the distribution.
16 1.1.2.1 cliff * 3. All advertising materials mentioning features or use of this software
17 1.1.2.1 cliff * must display the following acknowledgement:
18 1.1.2.1 cliff * This product includes software developed by Brini.
19 1.1.2.1 cliff * 4. The name of the company nor the name of the author may be used to
20 1.1.2.1 cliff * endorse or promote products derived from this software without specific
21 1.1.2.1 cliff * prior written permission.
22 1.1.2.1 cliff *
23 1.1.2.1 cliff * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 1.1.2.1 cliff * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 1.1.2.1 cliff * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.1.2.1 cliff * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 1.1.2.1 cliff * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 1.1.2.1 cliff * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 1.1.2.1 cliff * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1.2.1 cliff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1.2.1 cliff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1.2.1 cliff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1.2.1 cliff * SUCH DAMAGE.
34 1.1.2.1 cliff *
35 1.1.2.1 cliff * RiscBSD kernel project
36 1.1.2.1 cliff *
37 1.1.2.1 cliff * mainbus.c
38 1.1.2.1 cliff *
39 1.1.2.1 cliff * cpunode configuration
40 1.1.2.1 cliff *
41 1.1.2.1 cliff * Created : 15/12/94
42 1.1.2.1 cliff */
43 1.1.2.1 cliff
44 1.1.2.1 cliff #include <sys/cdefs.h>
45 1.1.2.5 matt __KERNEL_RCSID(0, "$NetBSD: rmixl_cpunode.c,v 1.1.2.5 2011/12/24 01:57:54 matt Exp $");
46 1.1.2.1 cliff
47 1.1.2.1 cliff #include <sys/param.h>
48 1.1.2.1 cliff #include <sys/systm.h>
49 1.1.2.1 cliff #include <sys/kernel.h>
50 1.1.2.1 cliff #include <sys/conf.h>
51 1.1.2.1 cliff #include <sys/malloc.h>
52 1.1.2.1 cliff #include <sys/device.h>
53 1.1.2.5 matt #include <sys/bus.h>
54 1.1.2.5 matt
55 1.1.2.5 matt #include <dev/pci/pcidevs.h>
56 1.1.2.5 matt #include <dev/pci/pcireg.h>
57 1.1.2.1 cliff
58 1.1.2.1 cliff #include <evbmips/rmixl/autoconf.h>
59 1.1.2.3 matt
60 1.1.2.3 matt #include <mips/rmi/rmixlvar.h>
61 1.1.2.1 cliff #include <mips/rmi/rmixl_cpunodevar.h>
62 1.1.2.3 matt
63 1.1.2.1 cliff #include <machine/bus.h>
64 1.1.2.1 cliff #include "locators.h"
65 1.1.2.1 cliff
66 1.1.2.5 matt const char *rmixl_cpuname;
67 1.1.2.5 matt static char xlpxxx_cpuname[8];
68 1.1.2.5 matt
69 1.1.2.3 matt static int cpunode_rmixl_match(device_t, cfdata_t, void *);
70 1.1.2.3 matt static void cpunode_rmixl_attach(device_t, device_t, void *);
71 1.1.2.3 matt static int cpunode_rmixl_print(void *, const char *);
72 1.1.2.1 cliff
73 1.1.2.3 matt CFATTACH_DECL_NEW(cpunode_rmixl, sizeof(struct cpunode_softc),
74 1.1.2.3 matt cpunode_rmixl_match, cpunode_rmixl_attach, NULL, NULL);
75 1.1.2.1 cliff
76 1.1.2.5 matt rmixlp_variant_t rmixl_xlp_variant;
77 1.1.2.5 matt static u_int rmixl_nodes;
78 1.1.2.5 matt
79 1.1.2.1 cliff static int
80 1.1.2.3 matt cpunode_rmixl_match(device_t parent, cfdata_t cf, void *aux)
81 1.1.2.1 cliff {
82 1.1.2.5 matt struct mainbus_attach_args * const ma = aux;
83 1.1.2.5 matt u_int node = ma->ma_node;
84 1.1.2.1 cliff
85 1.1.2.3 matt if (!cpu_rmixl(mips_options.mips_cpu))
86 1.1.2.3 matt return 0;
87 1.1.2.3 matt
88 1.1.2.5 matt if (node == MAINBUSCF_NODE_DEFAULT) {
89 1.1.2.5 matt node = ffs(rmixl_nodes) - 1;
90 1.1.2.5 matt if (node == 0)
91 1.1.2.5 matt return 0;
92 1.1.2.5 matt ma->ma_node = node;
93 1.1.2.5 matt }
94 1.1.2.5 matt
95 1.1.2.5 matt /* max of 4 nodes */
96 1.1.2.5 matt if (node >= 4)
97 1.1.2.5 matt return 0;
98 1.1.2.5 matt
99 1.1.2.5 matt /* Make sure we haven't attached this node before */
100 1.1.2.5 matt if (rmixl_nodes & __BIT(node))
101 1.1.2.5 matt return 0;
102 1.1.2.5 matt
103 1.1.2.5 matt /* Node 0 always is good */
104 1.1.2.5 matt if (node == 0)
105 1.1.2.5 matt return 1;
106 1.1.2.5 matt
107 1.1.2.5 matt /* XLR/XLS can only have one node */
108 1.1.2.5 matt if (cpu_rmixlr(mips_options.mips_cpu)
109 1.1.2.5 matt || cpu_rmixls(mips_options.mips_cpu))
110 1.1.2.5 matt return 0;
111 1.1.2.5 matt
112 1.1.2.5 matt /*
113 1.1.2.5 matt * To see if a node is present, check to see if it PCI devices exist.
114 1.1.2.5 matt */
115 1.1.2.5 matt const pcireg_t id =
116 1.1.2.5 matt rmixlp_read_4(_RMIXL_PCITAG(0, node * 8, 0), PCI_ID_REG);
117 1.1.2.5 matt if (id != PCI_ID_CODE(PCI_VENDOR_NETLOGIC,PCI_PRODUCT_NETLOGIC_XLP_SBC))
118 1.1.2.1 cliff return 0;
119 1.1.2.1 cliff
120 1.1.2.1 cliff return 1;
121 1.1.2.1 cliff }
122 1.1.2.1 cliff
123 1.1.2.1 cliff static void
124 1.1.2.3 matt cpunode_rmixl_attach(device_t parent, device_t self, void *aux)
125 1.1.2.1 cliff {
126 1.1.2.5 matt struct cpunode_softc * const sc = device_private(self);
127 1.1.2.5 matt struct mainbus_attach_args * const ma = aux;
128 1.1.2.1 cliff struct cpunode_attach_args na;
129 1.1.2.2 matt const u_int cpu_cidflags = mips_options.mips_cpu->cpu_cidflags;
130 1.1.2.5 matt u_int sz;
131 1.1.2.1 cliff
132 1.1.2.1 cliff aprint_naive("\n");
133 1.1.2.1 cliff aprint_normal("\n");
134 1.1.2.1 cliff
135 1.1.2.1 cliff sc->sc_dev = self;
136 1.1.2.1 cliff sc->sc_node = ma->ma_node;
137 1.1.2.5 matt rmixl_nodes |= __BIT(ma->ma_node);
138 1.1.2.5 matt
139 1.1.2.5 matt u_int ncores = MIPS_CIDFL_RMI_NCORES(cpu_cidflags);
140 1.1.2.5 matt const u_int rmi_type = cpu_cidflags & MIPS_CIDFL_RMI_TYPE;
141 1.1.2.1 cliff
142 1.1.2.5 matt switch (rmi_type) {
143 1.1.2.1 cliff case CIDFL_RMI_TYPE_XLR:
144 1.1.2.1 cliff case CIDFL_RMI_TYPE_XLS:
145 1.1.2.1 cliff /*
146 1.1.2.1 cliff * L2 is unified on XLR, XLS
147 1.1.2.1 cliff */
148 1.1.2.2 matt sz = (size_t)MIPS_CIDFL_RMI_L2SZ(cpu_cidflags);
149 1.1.2.5 matt aprint_normal_dev(self,
150 1.1.2.5 matt "%uKB/32B %u-banked 8-way set associative"
151 1.1.2.5 matt " L2 unified cache\n",
152 1.1.2.1 cliff sz/1024, sz/(256 * 1024));
153 1.1.2.1 cliff break;
154 1.1.2.5 matt case CIDFL_RMI_TYPE_XLP: {
155 1.1.2.5 matt uint32_t cfg_status0 = rmixlp_read_4(RMIXLP_SM_PCITAG,
156 1.1.2.5 matt RMIXLP_SM_EFUSE_DEVICE_CFG_STATUS0);
157 1.1.2.5 matt const char *sfx = "";
158 1.1.2.5 matt char msd;
159 1.1.2.5 matt if (mips_options.mips_cpu->cpu_pid == MIPS_XLP8XX) {
160 1.1.2.5 matt /*
161 1.1.2.5 matt * From XLP 8xx-4XX PRM 1.41 (2011-12-16)
162 1.1.2.5 matt * 31.4 System Configuration
163 1.1.2.5 matt */
164 1.1.2.5 matt uint32_t cfg_status1 = rmixlp_read_4(RMIXLP_SM_PCITAG,
165 1.1.2.5 matt RMIXLP_SM_EFUSE_DEVICE_CFG_STATUS1);
166 1.1.2.5 matt uint8_t id0 = cfg_status0; /* bits 7:0 */
167 1.1.2.5 matt for (ncores = 8; id0 != 0; id0 >>= 1) {
168 1.1.2.5 matt ncores -= id0 & 1;
169 1.1.2.5 matt }
170 1.1.2.5 matt if ((cfg_status1 & 7) == 0) {
171 1.1.2.5 matt msd = '8';
172 1.1.2.5 matt rmixl_xlp_variant = RMIXLP_8XX;
173 1.1.2.5 matt } else {
174 1.1.2.5 matt msd = '4';
175 1.1.2.5 matt rmixl_xlp_variant = RMIXLP_4XX;
176 1.1.2.5 matt }
177 1.1.2.5 matt } else if (mips_options.mips_cpu->cpu_pid == MIPS_XLP3XX) {
178 1.1.2.5 matt /*
179 1.1.2.5 matt * From XLP3xx_3xx-Lite PRM 1.41 (2011-12-16)
180 1.1.2.5 matt * 30.4 System Configuration
181 1.1.2.5 matt */
182 1.1.2.5 matt uint8_t idl = (cfg_status0 >> 8) & 0xf;
183 1.1.2.5 matt uint8_t idh = (cfg_status0 >> 16) & 0xff;
184 1.1.2.5 matt size_t variant = (cfg_status0 >> 4) & 0x3;
185 1.1.2.5 matt static const char sfxs[4][2] = { "", "L", "H", "Q" };
186 1.1.2.5 matt sfx = sfxs[variant];
187 1.1.2.5 matt if (idh == 0xff) {
188 1.1.2.5 matt ncores = 1;
189 1.1.2.5 matt } else if (idl != 0) {
190 1.1.2.5 matt ncores = 2;
191 1.1.2.5 matt } else {
192 1.1.2.5 matt ncores = 4;
193 1.1.2.5 matt }
194 1.1.2.5 matt msd = '3';
195 1.1.2.5 matt rmixl_xlp_variant = RMIXLP_3XX + variant;
196 1.1.2.5 matt } else {
197 1.1.2.5 matt panic("%s: unknown RMI XLP variant %#x!",
198 1.1.2.5 matt __func__, mips_options.mips_cpu->cpu_pid);
199 1.1.2.5 matt }
200 1.1.2.5 matt
201 1.1.2.5 matt snprintf(xlpxxx_cpuname, sizeof(xlpxxx_cpuname),
202 1.1.2.5 matt "XLP%c%02u%s", msd, ncores * 4, sfx);
203 1.1.2.5 matt rmixl_cpuname = xlpxxx_cpuname;
204 1.1.2.5 matt
205 1.1.2.5 matt /*
206 1.1.2.5 matt * L3 is unified on XLP. Why they don't use COP0 Config2 for
207 1.1.2.5 matt * this bothers me (except 16-way doesn't have an encoding).
208 1.1.2.5 matt */
209 1.1.2.5 matt sz = (size_t)MIPS_CIDFL_RMI_L3SZ(cpu_cidflags);
210 1.1.2.5 matt aprint_normal_dev(self,
211 1.1.2.5 matt "%u bank%s of %uKB/64B 16-way set associative L3 unified cache\n",
212 1.1.2.5 matt ncores, ncores == 1 ? "" : "s", sz/1024);
213 1.1.2.1 cliff break;
214 1.1.2.1 cliff }
215 1.1.2.5 matt }
216 1.1.2.1 cliff
217 1.1.2.5 matt aprint_normal_dev(self, "%u %s on node\n", ncores,
218 1.1.2.1 cliff ncores == 1 ? "core" : "cores");
219 1.1.2.1 cliff
220 1.1.2.1 cliff /*
221 1.1.2.1 cliff * Attach cpu (RMI thread) devices
222 1.1.2.1 cliff */
223 1.1.2.5 matt for (u_int i = 0; i < ncores; i++) {
224 1.1.2.1 cliff na.na_name = "cpucore";
225 1.1.2.1 cliff na.na_node = ma->ma_node;
226 1.1.2.1 cliff na.na_core = i;
227 1.1.2.5 matt na.na_dmat29 = ma->ma_dmat29;
228 1.1.2.5 matt na.na_dmat32 = ma->ma_dmat32;
229 1.1.2.5 matt na.na_dmat64 = ma->ma_dmat64;
230 1.1.2.3 matt config_found(self, &na, cpunode_rmixl_print);
231 1.1.2.1 cliff }
232 1.1.2.1 cliff
233 1.1.2.1 cliff /*
234 1.1.2.5 matt * Attach obio (XLR/XLS)
235 1.1.2.1 cliff */
236 1.1.2.5 matt switch (rmi_type) {
237 1.1.2.5 matt case CIDFL_RMI_TYPE_XLR:
238 1.1.2.5 matt case CIDFL_RMI_TYPE_XLS:
239 1.1.2.5 matt na.na_name = "obio";
240 1.1.2.5 matt config_found(self, &na, NULL);
241 1.1.2.5 matt break;
242 1.1.2.5 matt case CIDFL_RMI_TYPE_XLP:
243 1.1.2.5 matt break;
244 1.1.2.5 matt }
245 1.1.2.1 cliff }
246 1.1.2.1 cliff
247 1.1.2.1 cliff static int
248 1.1.2.3 matt cpunode_rmixl_print(void *aux, const char *pnp)
249 1.1.2.1 cliff {
250 1.1.2.1 cliff struct cpunode_attach_args *na = aux;
251 1.1.2.1 cliff
252 1.1.2.1 cliff if (pnp != NULL)
253 1.1.2.1 cliff aprint_normal("%s:", pnp);
254 1.1.2.1 cliff aprint_normal(" core %d", na->na_core);
255 1.1.2.1 cliff
256 1.1.2.1 cliff return (UNCONF);
257 1.1.2.1 cliff }
258