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
34char *
35prom_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 */
58int
59prom_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
82int
83prom_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
106int
107prom_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
130int
131prom_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 */
157int
158prom_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
199int
200prom_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