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 2005 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/promif.h>
30 #include <sys/promimpl.h>
31 
32 /* All Serengeti only promif routines */
33 
34 char *
prom_serengeti_set_console_input(char * new_value)35 prom_serengeti_set_console_input(char *new_value)
36 {
37 	cell_t ci[5];
38 	int rv;
39 
40 	ci[0] = p1275_ptr2cell("SUNW,set-console-input");
41 	ci[1] = (cell_t)1;			/* #argument cells */
42 	ci[2] = (cell_t)1;			/* #return cells */
43 	ci[3] = p1275_ptr2cell(new_value);
44 
45 	promif_preprom();
46 	rv = p1275_cif_handler(&ci);
47 	promif_postprom();
48 
49 	if (rv != 0)
50 		return (NULL);
51 
52 	return (p1275_cell2ptr(ci[4]));
53 }
54 
55 /*
56  * These interfaces allow the client to attach/detach board.
57  */
58 int
prom_serengeti_attach_board(uint_t node,uint_t board)59 prom_serengeti_attach_board(uint_t node, uint_t board)
60 {
61 	cell_t ci[6];
62 	int rv;
63 
64 	ci[0] = p1275_ptr2cell("SUNW,Serengeti,add-board");	/* name */
65 	ci[1] = (cell_t)2;				/* #argument cells */
66 	ci[2] = (cell_t)1;				/* #result cells */
67 	ci[3] = p1275_uint2cell(board);
68 	ci[4] = p1275_uint2cell(node);
69 
70 	promif_preprom();
71 	rv = p1275_cif_handler(&ci);
72 	promif_postprom();
73 
74 	if (rv != 0)
75 		return (rv);
76 	if (p1275_cell2int(ci[5]) != 0)			/* Res1: Catch result */
77 		return (-1);
78 
79 	return (0);
80 }
81 
82 int
prom_serengeti_detach_board(uint_t node,uint_t board)83 prom_serengeti_detach_board(uint_t node, uint_t board)
84 {
85 	cell_t ci[6];
86 	int rv;
87 
88 	ci[0] = p1275_ptr2cell("SUNW,Serengeti,remove-board");	/* name */
89 	ci[1] = (cell_t)2;				/* #argument cells */
90 	ci[2] = (cell_t)1;				/* #result cells */
91 	ci[3] = p1275_uint2cell(board);
92 	ci[4] = p1275_uint2cell(node);
93 
94 	promif_preprom();
95 	rv = p1275_cif_handler(&ci);
96 	promif_postprom();
97 
98 	if (rv != 0)
99 		return (rv);
100 	if (p1275_cell2int(ci[5]) != 0)			/* Res1: Catch result */
101 		return (-1);
102 
103 	return (0);
104 }
105 
106 int
prom_serengeti_tunnel_switch(uint_t node,uint_t board)107 prom_serengeti_tunnel_switch(uint_t node, uint_t board)
108 {
109 	cell_t ci[6];
110 	int rv;
111 
112 	ci[0] = p1275_ptr2cell("SUNW,Serengeti,switch-tunnel");	/* name */
113 	ci[1] = (cell_t)2;				/* #argument cells */
114 	ci[2] = (cell_t)1;				/* #result cells */
115 	ci[3] = p1275_uint2cell(board);
116 	ci[4] = p1275_uint2cell(node);
117 
118 	promif_preprom();
119 	rv = p1275_cif_handler(&ci);
120 	promif_postprom();
121 
122 	if (rv != 0)
123 		return (rv);
124 	if (p1275_cell2int(ci[5]) != 0)			/* Res1: Catch result */
125 		return (-1);
126 
127 	return (0);
128 }
129 
130 int
prom_serengeti_cpu_off(pnode_t node)131 prom_serengeti_cpu_off(pnode_t node)
132 {
133 	cell_t ci[5];
134 	int rv;
135 
136 	ci[0] = p1275_ptr2cell("SUNW,Serengeti,park-cpu");
137 	ci[1] = (cell_t)1;			/* #argument cells */
138 	ci[2] = (cell_t)1;			/* #return cells */
139 	ci[3] = p1275_dnode2cell(node);
140 
141 	promif_preprom();
142 	rv = p1275_cif_handler(&ci);
143 	promif_postprom();
144 
145 	if (rv != 0)
146 		return (-1);
147 
148 	return (p1275_cell2int(ci[4]));
149 }
150 
151 /*
152  * This service converts the given physical address into a text string,
153  * representing the name of the field-replacable part for the given
154  * physical address. In other words, it tells the kernel which ecache
155  * module got the (un)correctable ECC error.
156  */
157 int
prom_serengeti_get_ecacheunum(int cpuid,unsigned long long physaddr,char * buf,uint_t buflen,int * ustrlen)158 prom_serengeti_get_ecacheunum(int cpuid, unsigned long long physaddr, char *buf,
159 		uint_t buflen, int *ustrlen)
160 {
161 	cell_t ci[12];
162 	int rv;
163 	ihandle_t imemory = prom_memory_ihandle();
164 
165 	*ustrlen = -1;
166 	if ((imemory == (ihandle_t)-1))
167 		return (-1);
168 
169 	if (prom_test_method("SUNW,Serengeti,get-ecache-unum",
170 	    prom_getphandle(imemory)) != 0)
171 		return (-1);
172 
173 	ci[0] = p1275_ptr2cell("call-method");		/* Service name */
174 	ci[1] = (cell_t)7;				/* #argument cells */
175 	ci[2] = (cell_t)2;				/* #result cells */
176 	ci[3] = p1275_ptr2cell("SUNW,Serengeti,get-ecache-unum");
177 							/* Arg1: Method name */
178 	ci[4] = p1275_ihandle2cell(imemory);		/* Arg2: mem. ihandle */
179 	ci[5] = p1275_uint2cell(buflen);		/* Arg3: buflen */
180 	ci[6] = p1275_ptr2cell(buf);			/* Arg4: buf */
181 	ci[7] = p1275_ull2cell_high(physaddr);		/* Arg5: physhi */
182 	ci[8] = p1275_ull2cell_low(physaddr);		/* Arg6: physlo */
183 	ci[9] = p1275_int2cell(cpuid);			/* Arg7: cpuid */
184 	ci[10] = (cell_t)-1;				/* ret1: catch result */
185 	ci[11] = (cell_t)-1;				/* ret2: length */
186 
187 	promif_preprom();
188 	rv = p1275_cif_handler(&ci);
189 	promif_postprom();
190 
191 	if (rv != 0)
192 		return (rv);
193 	if (p1275_cell2int(ci[10]) != 0)	/* Res1: catch result */
194 		return (-1);	/* "SUNW,Serengeti,get-ecache-unum" failed */
195 	*ustrlen = p1275_cell2uint(ci[11]);	/* Res2: unum str length */
196 	return (0);
197 }
198 
199 int
prom_serengeti_wakeupcpu(pnode_t node)200 prom_serengeti_wakeupcpu(pnode_t node)
201 {
202 	cell_t ci[5];
203 	int	rv;
204 
205 	ci[0] = p1275_ptr2cell("SUNW,Serengeti,wakeup-cpu"); /* Service name */
206 	ci[1] = (cell_t)1;			/* #argument cells */
207 	ci[2] = (cell_t)1;			/* #result cells */
208 	ci[3] = p1275_dnode2cell(node);		/* Arg1: nodeid to wakeup */
209 
210 	promif_preprom();
211 	rv = p1275_cif_handler(&ci);
212 	promif_postprom();
213 
214 	if (rv != 0)
215 		return (rv);
216 	else
217 		return (p1275_cell2int(ci[4])); /* Res1: Catch result */
218 }
219