xref: /titanic_50/usr/src/uts/sun4u/blade/os/blade.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/sunddi.h>
32 #include <sys/esunddi.h>
33 #include <sys/ddi.h>
34 
35 #include <sys/platform_module.h>
36 #include <sys/modctl.h>
37 #include <sys/lom_priv.h>
38 #include <sys/errno.h>
39 #include <sys/utsname.h>
40 
41 #define	TOD_DRIVER_NAME	"todblade"
42 #define	BSC_DRV		SUNW_KERN_BSCV_MODULENAME
43 #define	BSC_DRV_FUNC	SUNW_KERN_BSCV_IDI_FN
44 
45 
46 /* local functions */
47 static void cpu_sgn_update(ushort_t, uchar_t, uchar_t, int);
48 
49 /* Globals */
50 void (*bsc_drv_func_ptr)(struct bscv_idi_info *) = NULL;
51 
52 
53 void
startup_platform(void)54 startup_platform(void)
55 {
56 	extern char	*tod_module_name;
57 	extern int	watchdog_available;
58 	extern int	watchdog_enable;
59 	extern int	disable_watchdog_on_exit;
60 
61 	/* Set appropriate tod module for blade */
62 	tod_module_name = TOD_DRIVER_NAME;
63 
64 	/* Set watchdog default configuration */
65 	watchdog_available = 1;
66 	watchdog_enable = 1;
67 	disable_watchdog_on_exit = 1;
68 }
69 
70 int
set_platform_tsb_spares()71 set_platform_tsb_spares()
72 {
73 	return (0);
74 }
75 
76 void
set_platform_defaults(void)77 set_platform_defaults(void)
78 {
79 	/* Set the CPU signature function pointer */
80 	cpu_sgn_func = cpu_sgn_update;
81 }
82 
83 /*
84  * Definitions for accessing the pci config space of the isa node
85  * of Southbridge.
86  */
87 #define	PLATFORM_ISA_PATHNAME	"/pci@1f,0/isa@7"
88 #define	PLATFORM_ISA_PATHNAME_WITH_SIMBA	"/pci@1f,0/pci@1,1/isa@7"
89 static ddi_acc_handle_t platform_isa_handle;	/* handle for isa pci space */
90 
91 void
load_platform_drivers(void)92 load_platform_drivers(void)
93 {
94 	extern int		watchdog_available;
95 	extern int		watchdog_enable;
96 	dev_info_t 		*dip;		/* dip of the isa driver */
97 	int			simba_present = 0;
98 	dev_info_t		*root_child_node;
99 	major_t	major;
100 
101 	if (ddi_install_driver("power") != DDI_SUCCESS)
102 		cmn_err(CE_WARN, "Failed to install \"power\" driver.");
103 
104 	/*
105 	 * Install Isa driver. This is required for the southbridge IDE
106 	 * workaround - to reset the IDE channel during IDE bus reset.
107 	 * Panic the system in case ISA driver could not be loaded or
108 	 * any problem in accessing its pci config space. Since the register
109 	 * to reset the channel for IDE is in ISA config space!.
110 	 */
111 	root_child_node = ddi_get_child(ddi_root_node());
112 
113 	while (root_child_node != NULL) {
114 		if (strcmp(ddi_node_name(root_child_node), "pci") == 0) {
115 			root_child_node = ddi_get_child(root_child_node);
116 			if (strcmp(ddi_node_name(root_child_node), "pci") == 0)
117 				simba_present = 1;
118 			break;
119 		}
120 		root_child_node = ddi_get_next_sibling(root_child_node);
121 	}
122 
123 	if (simba_present)
124 		dip = e_ddi_hold_devi_by_path(PLATFORM_ISA_PATHNAME_WITH_SIMBA,
125 		    0);
126 	else
127 		dip = e_ddi_hold_devi_by_path(PLATFORM_ISA_PATHNAME, 0);
128 
129 	if (dip == NULL) {
130 		cmn_err(CE_PANIC, "Could not install the isa driver\n");
131 		return;
132 	}
133 
134 	if (pci_config_setup(dip, &platform_isa_handle) != DDI_SUCCESS) {
135 		cmn_err(CE_PANIC, "Could not get the config space of isa\n");
136 		return;
137 	}
138 
139 	/*
140 	 * Load the blade support chip driver.
141 	 *
142 	 */
143 
144 	if (((major = ddi_name_to_major(BSC_DRV)) == -1) ||
145 		(ddi_hold_installed_driver(major) == NULL)) {
146 		cmn_err(CE_WARN, "%s: failed to load", BSC_DRV);
147 	} else {
148 
149 		bsc_drv_func_ptr = (void (*)(struct bscv_idi_info *))
150 		    modgetsymvalue(BSC_DRV_FUNC, 0);
151 
152 		if (bsc_drv_func_ptr == NULL) {
153 			cmn_err(CE_WARN, "load_platform_defaults: %s()"
154 			" not found; signatures will not be updated\n",
155 			BSC_DRV_FUNC);
156 			watchdog_available = 0;
157 			if (watchdog_enable) {
158 				cmn_err(CE_WARN, "load_platform_defaults: %s()"
159 			" not found; BSC OS watchdog service not available\n",
160 				BSC_DRV_FUNC);
161 			}
162 		}
163 	}
164 }
165 
166 /*
167  * This routine provides a workaround for a bug in the SB chip which
168  * can cause data corruption. Will be invoked from the IDE HBA driver for
169  * Acer SouthBridge at the time of IDE bus reset.
170  */
171 /*ARGSUSED*/
172 int
plat_ide_chipreset(dev_info_t * dip,int chno)173 plat_ide_chipreset(dev_info_t *dip, int chno)
174 {
175 	uint8_t	val;
176 	int	ret = DDI_SUCCESS;
177 
178 	if (platform_isa_handle == NULL)
179 		return (DDI_FAILURE);
180 
181 	val = pci_config_get8(platform_isa_handle, 0x58);
182 	/*
183 	 * The dip passed as the argument is not used for platform.
184 	 * This will be needed for platforms which have multiple on-board SB,
185 	 * The dip passed will be used to match the corresponding ISA node.
186 	 */
187 	switch (chno) {
188 		case 0:
189 			/*
190 			 * First disable the primary channel then re-enable it.
191 			 * As per ALI no wait should be required in between have
192 			 * given 1ms delay in between to be on safer side.
193 			 * bit 2 of register 0x58 when 0 disable the channel 0.
194 			 * bit 2 of register 0x58 when 1 enables the channel 0.
195 			 */
196 			pci_config_put8(platform_isa_handle, 0x58, val & 0xFB);
197 			drv_usecwait(1000);
198 			pci_config_put8(platform_isa_handle, 0x58, val);
199 			break;
200 		case 1:
201 			/*
202 			 * bit 3 of register 0x58 when 0 disable the channel 1.
203 			 * bit 3 of register 0x58 when 1 enables the channel 1.
204 			 */
205 			pci_config_put8(platform_isa_handle, 0x58, val & 0xF7);
206 			drv_usecwait(1000);
207 			pci_config_put8(platform_isa_handle, 0x58, val);
208 			break;
209 		default:
210 			/*
211 			 * Unknown channel number passed. Return failure.
212 			 */
213 			ret = DDI_FAILURE;
214 	}
215 
216 	return (ret);
217 }
218 
219 
220 
221 /*ARGSUSED*/
222 int
plat_cpu_poweron(struct cpu * cp)223 plat_cpu_poweron(struct cpu *cp)
224 {
225 	return (ENOTSUP);	/* not supported on this platform */
226 }
227 
228 /*ARGSUSED*/
229 int
plat_cpu_poweroff(struct cpu * cp)230 plat_cpu_poweroff(struct cpu *cp)
231 {
232 	return (ENOTSUP);	/* not supported on this platform */
233 }
234 
235 /*ARGSUSED*/
236 void
plat_freelist_process(int mnode)237 plat_freelist_process(int mnode)
238 {
239 }
240 
241 char *platform_module_list[] = {
242 	(char *)0
243 };
244 
245 /*ARGSUSED*/
246 void
plat_tod_fault(enum tod_fault_type tod_bad)247 plat_tod_fault(enum tod_fault_type tod_bad)
248 {
249 }
250 
251 /*
252  * Our nodename has been set, pass it along to the BSC.
253  */
254 void
plat_nodename_set(void)255 plat_nodename_set(void)
256 {
257 	struct bscv_idi_info bscv_info;
258 
259 	bscv_info.type = BSCV_IDI_NODENAME;
260 	bscv_info.data = utsname.nodename;
261 	bscv_info.size = strlen(utsname.nodename);
262 
263 	if (bsc_drv_func_ptr != NULL)
264 		(bsc_drv_func_ptr)(&bscv_info);
265 }
266 
267 /*
268  * Send an updated CPU signature to the BSC.
269  */
270 
271 static void
cpu_sgn_update(ushort_t sig,uchar_t state,uchar_t sub_state,int cpuid)272 cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
273 {
274 	struct bscv_idi_info bscv_info;
275 	bscv_sig_t sc;
276 
277 	sc.sig_info.signature = CPU_SIG_BLD(sig, state, sub_state);
278 	sc.cpu = cpuid;
279 
280 	bscv_info.type = BSCV_IDI_SIG;
281 	bscv_info.data = &sc;
282 	bscv_info.size = sizeof (sc);
283 
284 
285 	if (bsc_drv_func_ptr != NULL)
286 		(*bsc_drv_func_ptr)(&bscv_info);
287 }
288