xref: /onnv-gate/usr/src/uts/sun4u/seattle/os/seattle.c (revision 969:d3e3a7657934)
1920Sjbeloro /*
2920Sjbeloro  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3920Sjbeloro  * Use is subject to license terms.
4920Sjbeloro  */
5920Sjbeloro 
6920Sjbeloro #pragma ident	"%Z%%M%	%I%	%E% SMI"
7920Sjbeloro 
8920Sjbeloro #include <sys/param.h>
9920Sjbeloro #include <sys/systm.h>
10920Sjbeloro #include <sys/sysmacros.h>
11920Sjbeloro #include <sys/sunddi.h>
12920Sjbeloro #include <sys/esunddi.h>
13920Sjbeloro 
14920Sjbeloro #include <sys/platform_module.h>
15920Sjbeloro #include <sys/errno.h>
16920Sjbeloro #include <sys/cpu_sgnblk_defs.h>
17920Sjbeloro #include <sys/rmc_comm_dp.h>
18920Sjbeloro #include <sys/rmc_comm_drvintf.h>
19920Sjbeloro #include <sys/modctl.h>
20920Sjbeloro #include <sys/lgrp.h>
21920Sjbeloro #include <sys/memnode.h>
22920Sjbeloro #include <sys/promif.h>
23920Sjbeloro 
24920Sjbeloro /* Anything related to shared i2c access applies to Seattle only */
25920Sjbeloro #define	SHARED_MI2CV_PATH "/i2c@1f,530000"
26920Sjbeloro static dev_info_t *shared_mi2cv_dip;
27920Sjbeloro static kmutex_t mi2cv_mutex;
28920Sjbeloro 
29920Sjbeloro int (*p2get_mem_unum)(int, uint64_t, char *, int, int *);
30920Sjbeloro static void cpu_sgn_update(ushort_t, uchar_t, uchar_t, int);
31920Sjbeloro int (*rmc_req_now)(rmc_comm_msg_t *, uint8_t) = NULL;
32920Sjbeloro 
33920Sjbeloro void
34920Sjbeloro startup_platform(void)
35920Sjbeloro {
36920Sjbeloro 	mutex_init(&mi2cv_mutex, NULL, NULL, NULL);
37920Sjbeloro }
38920Sjbeloro 
39920Sjbeloro int
40920Sjbeloro set_platform_tsb_spares()
41920Sjbeloro {
42920Sjbeloro 	return (0);
43920Sjbeloro }
44920Sjbeloro 
45920Sjbeloro void
46920Sjbeloro set_platform_defaults(void)
47920Sjbeloro {
48920Sjbeloro 	extern char *tod_module_name;
49920Sjbeloro 	/* Set appropriate tod module */
50920Sjbeloro 	if (tod_module_name == NULL)
51920Sjbeloro 		tod_module_name = "todm5823";
52920Sjbeloro 
53920Sjbeloro 	cpu_sgn_func = cpu_sgn_update;
54920Sjbeloro }
55920Sjbeloro 
56920Sjbeloro /*
57920Sjbeloro  * Definitions for accessing the pci config space of the isa node
58920Sjbeloro  * of Southbridge.
59920Sjbeloro  */
60920Sjbeloro static ddi_acc_handle_t isa_handle = NULL;	/* handle for isa pci space */
61920Sjbeloro 
62920Sjbeloro /*
63920Sjbeloro  * Definition for accessing rmclomv
64920Sjbeloro  */
65920Sjbeloro #define	RMCLOMV_PATHNAME	"/pseudo/rmclomv@0"
66920Sjbeloro 
67920Sjbeloro void
68920Sjbeloro load_platform_drivers(void)
69920Sjbeloro {
70920Sjbeloro 	dev_info_t	*rmclomv_dip;
71920Sjbeloro 	/*
72920Sjbeloro 	 * It is OK to return error because 'us' driver is not available
73920Sjbeloro 	 * in all clusters (e.g. missing in Core cluster).
74920Sjbeloro 	 */
75920Sjbeloro 	(void) i_ddi_attach_hw_nodes("us");
76920Sjbeloro 
77920Sjbeloro 
78920Sjbeloro 	/*
79920Sjbeloro 	 * mc-us3i must stay loaded for plat_get_mem_unum()
80920Sjbeloro 	 */
81920Sjbeloro 	if (i_ddi_attach_hw_nodes("mc-us3i") != DDI_SUCCESS)
82920Sjbeloro 		cmn_err(CE_WARN, "mc-us3i driver failed to install");
83920Sjbeloro 	(void) ddi_hold_driver(ddi_name_to_major("mc-us3i"));
84920Sjbeloro 
85920Sjbeloro 	/*
86920Sjbeloro 	 * load the GPIO driver for the ALOM reset and watchdog lines
87920Sjbeloro 	 */
88920Sjbeloro 	if (i_ddi_attach_hw_nodes("pmugpio") != DDI_SUCCESS)
89920Sjbeloro 		cmn_err(CE_WARN, "pmugpio failed to install");
90920Sjbeloro 	else {
91920Sjbeloro 		extern int watchdog_enable, watchdog_available;
92920Sjbeloro 		extern int disable_watchdog_on_exit;
93920Sjbeloro 
94920Sjbeloro 		/*
95920Sjbeloro 		 * Disable an active h/w watchdog timer upon exit to OBP.
96920Sjbeloro 		 */
97920Sjbeloro 		disable_watchdog_on_exit = 1;
98920Sjbeloro 
99920Sjbeloro 		watchdog_enable = 1;
100920Sjbeloro 		watchdog_available = 1;
101920Sjbeloro 	}
102920Sjbeloro 	(void) ddi_hold_driver(ddi_name_to_major("pmugpio"));
103920Sjbeloro 
104920Sjbeloro 	/*
105920Sjbeloro 	 * Figure out which mi2cv dip is shared with OBP for the nvram
106920Sjbeloro 	 * device, so the lock can be acquired.
107920Sjbeloro 	 */
108920Sjbeloro 	shared_mi2cv_dip = e_ddi_hold_devi_by_path(SHARED_MI2CV_PATH, 0);
109920Sjbeloro 	/*
110920Sjbeloro 	 * Load the environmentals driver (rmclomv)
111920Sjbeloro 	 *
112920Sjbeloro 	 * We need this driver to handle events from the RMC when state
113920Sjbeloro 	 * changes occur in the environmental data.
114920Sjbeloro 	 */
115920Sjbeloro 	if (i_ddi_attach_hw_nodes("rmc_comm") != DDI_SUCCESS) {
116920Sjbeloro 		cmn_err(CE_WARN, "rmc_comm failed to install");
117920Sjbeloro 	} else {
118920Sjbeloro 		(void) ddi_hold_driver(ddi_name_to_major("rmc_comm"));
119920Sjbeloro 
120920Sjbeloro 		rmclomv_dip = e_ddi_hold_devi_by_path(RMCLOMV_PATHNAME, 0);
121920Sjbeloro 		if (rmclomv_dip == NULL) {
122920Sjbeloro 			cmn_err(CE_WARN, "Could not install rmclomv driver\n");
123920Sjbeloro 		}
124920Sjbeloro 	}
125920Sjbeloro 
126920Sjbeloro 	/*
127920Sjbeloro 	 * create a handle to the rmc_comm_request_nowait() function
128920Sjbeloro 	 * inside the rmc_comm module.
129920Sjbeloro 	 *
130920Sjbeloro 	 * The Seattle/Boston todm5823 driver will use this handle to
131920Sjbeloro 	 * use the rmc_comm_request_nowait() function to send time/date
132920Sjbeloro 	 * updates to ALOM.
133920Sjbeloro 	 */
134920Sjbeloro 	rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
135920Sjbeloro 		modgetsymvalue("rmc_comm_request_nowait", 0);
136920Sjbeloro }
137920Sjbeloro 
138920Sjbeloro /*
139920Sjbeloro  * This routine is needed if a device error or timeout occurs before the
140920Sjbeloro  * driver is loaded.
141920Sjbeloro  */
142920Sjbeloro /*ARGSUSED*/
143920Sjbeloro int
144920Sjbeloro plat_ide_chipreset(dev_info_t *dip, int chno)
145920Sjbeloro {
146920Sjbeloro 	int	ret = DDI_SUCCESS;
147920Sjbeloro 
148920Sjbeloro 	if (isa_handle == NULL) {
149920Sjbeloro 		return (DDI_FAILURE);
150920Sjbeloro 	}
151920Sjbeloro 
152920Sjbeloro 	/*
153920Sjbeloro 	 * This will be filled in with the reset logic
154920Sjbeloro 	 * for the ULI1573 when that becomes available.
155920Sjbeloro 	 * currently this is just a stub.
156920Sjbeloro 	 */
157920Sjbeloro 	return (ret);
158920Sjbeloro }
159920Sjbeloro 
160920Sjbeloro 
161920Sjbeloro /*ARGSUSED*/
162920Sjbeloro int
163920Sjbeloro plat_cpu_poweron(struct cpu *cp)
164920Sjbeloro {
165920Sjbeloro 	return (ENOTSUP);	/* not supported on this platform */
166920Sjbeloro }
167920Sjbeloro 
168920Sjbeloro /*ARGSUSED*/
169920Sjbeloro int
170920Sjbeloro plat_cpu_poweroff(struct cpu *cp)
171920Sjbeloro {
172920Sjbeloro 	return (ENOTSUP);	/* not supported on this platform */
173920Sjbeloro }
174920Sjbeloro 
175920Sjbeloro /*ARGSUSED*/
176920Sjbeloro void
177920Sjbeloro plat_freelist_process(int mnode)
178920Sjbeloro {
179920Sjbeloro }
180920Sjbeloro 
181920Sjbeloro char *platform_module_list[] = {
182920Sjbeloro 	"mi2cv",
183920Sjbeloro 	"pca9556",
184920Sjbeloro 	(char *)0
185920Sjbeloro };
186920Sjbeloro 
187920Sjbeloro /*ARGSUSED*/
188920Sjbeloro void
189920Sjbeloro plat_tod_fault(enum tod_fault_type tod_bad)
190920Sjbeloro {
191920Sjbeloro }
192920Sjbeloro 
193920Sjbeloro /*ARGSUSED*/
194920Sjbeloro int
195920Sjbeloro plat_get_mem_unum(int synd_code, uint64_t flt_addr, int flt_bus_id,
196920Sjbeloro     int flt_in_memory, ushort_t flt_status, char *buf, int buflen, int *lenp)
197920Sjbeloro {
198920Sjbeloro 	if (flt_in_memory && (p2get_mem_unum != NULL))
199920Sjbeloro 		return (p2get_mem_unum(synd_code, P2ALIGN(flt_addr, 8),
200920Sjbeloro 		    buf, buflen, lenp));
201920Sjbeloro 	else
202920Sjbeloro 		return (ENOTSUP);
203920Sjbeloro }
204920Sjbeloro 
205920Sjbeloro /*ARGSUSED*/
206920Sjbeloro int
207920Sjbeloro plat_get_cpu_unum(int cpuid, char *buf, int buflen, int *lenp)
208920Sjbeloro {
209920Sjbeloro 	if (snprintf(buf, buflen, "MB") >= buflen) {
210920Sjbeloro 		return (ENOSPC);
211920Sjbeloro 	} else {
212920Sjbeloro 		*lenp = strlen(buf);
213920Sjbeloro 		return (0);
214920Sjbeloro 	}
215920Sjbeloro }
216920Sjbeloro 
217920Sjbeloro /*
218920Sjbeloro  * Our nodename has been set, pass it along to the RMC.
219920Sjbeloro  */
220920Sjbeloro void
221920Sjbeloro plat_nodename_set(void)
222920Sjbeloro {
223920Sjbeloro 	rmc_comm_msg_t	req;	/* request */
224920Sjbeloro 	int (*rmc_req_res)(rmc_comm_msg_t *, rmc_comm_msg_t *, time_t) = NULL;
225920Sjbeloro 
226920Sjbeloro 	/*
227920Sjbeloro 	 * find the symbol for the mailbox routine
228920Sjbeloro 	 */
229920Sjbeloro 	rmc_req_res = (int (*)(rmc_comm_msg_t *, rmc_comm_msg_t *, time_t))
230920Sjbeloro 		modgetsymvalue("rmc_comm_request_response", 0);
231920Sjbeloro 
232920Sjbeloro 	if (rmc_req_res == NULL) {
233920Sjbeloro 		return;
234920Sjbeloro 	}
235920Sjbeloro 
236920Sjbeloro 	/*
237920Sjbeloro 	 * construct the message telling the RMC our nodename
238920Sjbeloro 	 */
239920Sjbeloro 	req.msg_type = DP_SET_CPU_NODENAME;
240920Sjbeloro 	req.msg_len = strlen(utsname.nodename) + 1;
241920Sjbeloro 	req.msg_bytes = 0;
242920Sjbeloro 	req.msg_buf = (caddr_t)utsname.nodename;
243920Sjbeloro 
244920Sjbeloro 	/*
245920Sjbeloro 	 * ship it
246920Sjbeloro 	 */
247920Sjbeloro 	(void) (rmc_req_res)(&req, NULL, 2000);
248920Sjbeloro }
249920Sjbeloro 
250920Sjbeloro sig_state_t current_sgn;
251920Sjbeloro 
252920Sjbeloro /*
253920Sjbeloro  * cpu signatures - we're only interested in the overall system
254920Sjbeloro  * "signature" on this platform - not individual cpu signatures
255920Sjbeloro  */
256920Sjbeloro /*ARGSUSED*/
257920Sjbeloro static void
258920Sjbeloro cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
259920Sjbeloro {
260920Sjbeloro 	dp_cpu_signature_t signature;
261920Sjbeloro 	rmc_comm_msg_t	req;	/* request */
262920Sjbeloro 	int (*rmc_req_res)(rmc_comm_msg_t *, rmc_comm_msg_t *, time_t) = NULL;
263920Sjbeloro 	int (*rmc_req_now)(rmc_comm_msg_t *, uint8_t) = NULL;
264920Sjbeloro 
265920Sjbeloro 
266920Sjbeloro 	/*
267920Sjbeloro 	 * Differentiate a panic reboot from a non-panic reboot in the
268920Sjbeloro 	 * setting of the substate of the signature.
269920Sjbeloro 	 *
270920Sjbeloro 	 * If the new substate is REBOOT and we're rebooting due to a panic,
271920Sjbeloro 	 * then set the new substate to a special value indicating a panic
272920Sjbeloro 	 * reboot, SIGSUBST_PANIC_REBOOT.
273920Sjbeloro 	 *
274920Sjbeloro 	 * A panic reboot is detected by a current (previous) signature
275920Sjbeloro 	 * state of SIGST_EXIT, and a new signature substate of SIGSUBST_REBOOT.
276920Sjbeloro 	 * The domain signature state SIGST_EXIT is used as the panic flow
277920Sjbeloro 	 * progresses.
278920Sjbeloro 	 *
279920Sjbeloro 	 * At the end of the panic flow, the reboot occurs but we should know
280920Sjbeloro 	 * one that was involuntary, something that may be quite useful to know
281920Sjbeloro 	 * at OBP level.
282920Sjbeloro 	 */
283920Sjbeloro 	if (state == SIGST_EXIT && sub_state == SIGSUBST_REBOOT) {
284920Sjbeloro 		if (current_sgn.state_t.state == SIGST_EXIT &&
285920Sjbeloro 		    current_sgn.state_t.sub_state != SIGSUBST_REBOOT)
286920Sjbeloro 			sub_state = SIGSUBST_PANIC_REBOOT;
287920Sjbeloro 	}
288920Sjbeloro 
289920Sjbeloro 	/*
290920Sjbeloro 	 * offline and detached states only apply to a specific cpu
291920Sjbeloro 	 * so ignore them.
292920Sjbeloro 	 */
293920Sjbeloro 	if (state == SIGST_OFFLINE || state == SIGST_DETACHED) {
294920Sjbeloro 		return;
295920Sjbeloro 	}
296920Sjbeloro 
297920Sjbeloro 	current_sgn.signature = CPU_SIG_BLD(sig, state, sub_state);
298920Sjbeloro 
299920Sjbeloro 	/*
300920Sjbeloro 	 * find the symbol for the mailbox routine
301920Sjbeloro 	 */
302920Sjbeloro 	rmc_req_res = (int (*)(rmc_comm_msg_t *, rmc_comm_msg_t *, time_t))
303920Sjbeloro 		modgetsymvalue("rmc_comm_request_response", 0);
304920Sjbeloro 	if (rmc_req_res == NULL) {
305920Sjbeloro 		return;
306920Sjbeloro 	}
307920Sjbeloro 
308920Sjbeloro 	/*
309920Sjbeloro 	 * find the symbol for the mailbox routine
310920Sjbeloro 	 */
311920Sjbeloro 	rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
312920Sjbeloro 		modgetsymvalue("rmc_comm_request_nowait", 0);
313920Sjbeloro 	if (rmc_req_now == NULL) {
314920Sjbeloro 		return;
315920Sjbeloro 	}
316920Sjbeloro 
317920Sjbeloro 	signature.cpu_id = -1;
318920Sjbeloro 	signature.sig = sig;
319920Sjbeloro 	signature.states = state;
320920Sjbeloro 	signature.sub_state = sub_state;
321920Sjbeloro 	req.msg_type = DP_SET_CPU_SIGNATURE;
322920Sjbeloro 	req.msg_len = (int)(sizeof (signature));
323920Sjbeloro 	req.msg_bytes = 0;
324920Sjbeloro 	req.msg_buf = (caddr_t)&signature;
325920Sjbeloro 
326920Sjbeloro 	/*
327920Sjbeloro 	 * ship it
328920Sjbeloro 	 * - note that for panic or reboot need to send with nowait/urgent
329920Sjbeloro 	 */
330920Sjbeloro 	if (state == SIGST_EXIT && (sub_state == SIGSUBST_HALT ||
331920Sjbeloro 	    sub_state == SIGSUBST_REBOOT || sub_state == SIGSUBST_ENVIRON ||
332920Sjbeloro 	    sub_state == SIGSUBST_PANIC_REBOOT))
333920Sjbeloro 		(void) (rmc_req_now)(&req, RMC_COMM_DREQ_URGENT);
334920Sjbeloro 	else
335920Sjbeloro 		(void) (rmc_req_res)(&req, NULL, 2000);
336920Sjbeloro }
337920Sjbeloro 
338920Sjbeloro /*
339920Sjbeloro  * Fiesta support for lgroups.
340920Sjbeloro  *
341920Sjbeloro  * On fiesta platform, an lgroup platform handle == CPU id
342920Sjbeloro  */
343920Sjbeloro 
344920Sjbeloro /*
345920Sjbeloro  * Macro for extracting the CPU number from the CPU id
346920Sjbeloro  */
347920Sjbeloro #define	CPUID_TO_LGRP(id)	((id) & 0x7)
348920Sjbeloro #define	PLATFORM_MC_SHIFT	36
349920Sjbeloro 
350920Sjbeloro /*
351920Sjbeloro  * Return the platform handle for the lgroup containing the given CPU
352920Sjbeloro  */
353920Sjbeloro void *
354920Sjbeloro plat_lgrp_cpu_to_hand(processorid_t id)
355920Sjbeloro {
356*969Sanovick 	return ((void *)(uintptr_t)CPUID_TO_LGRP(id));
357920Sjbeloro }
358920Sjbeloro 
359920Sjbeloro /*
360920Sjbeloro  * Platform specific lgroup initialization
361920Sjbeloro  */
362920Sjbeloro void
363920Sjbeloro plat_lgrp_init(void)
364920Sjbeloro {
365920Sjbeloro 	pnode_t		curnode;
366920Sjbeloro 	char		tmp_name[MAXSYSNAME];
367920Sjbeloro 	int		portid;
368920Sjbeloro 	int		cpucnt = 0;
369920Sjbeloro 	int		max_portid = -1;
370920Sjbeloro 	extern uint32_t lgrp_expand_proc_thresh;
371920Sjbeloro 	extern uint32_t lgrp_expand_proc_diff;
372920Sjbeloro 	extern pgcnt_t	lgrp_mem_free_thresh;
373920Sjbeloro 	extern uint32_t lgrp_loadavg_tolerance;
374920Sjbeloro 	extern uint32_t lgrp_loadavg_max_effect;
375920Sjbeloro 	extern uint32_t lgrp_load_thresh;
376920Sjbeloro 	extern lgrp_mem_policy_t  lgrp_mem_policy_root;
377920Sjbeloro 
378920Sjbeloro 	/*
379920Sjbeloro 	 * Count the number of CPUs installed to determine if
380920Sjbeloro 	 * NUMA optimization should be enabled or not.
381920Sjbeloro 	 *
382920Sjbeloro 	 * All CPU nodes reside in the root node and have a
383920Sjbeloro 	 * device type "cpu".
384920Sjbeloro 	 */
385920Sjbeloro 	curnode = prom_rootnode();
386920Sjbeloro 	for (curnode = prom_childnode(curnode); curnode;
387920Sjbeloro 	    curnode = prom_nextnode(curnode)) {
388920Sjbeloro 		bzero(tmp_name, MAXSYSNAME);
389920Sjbeloro 		if (prom_getproplen(curnode, OBP_NAME) < MAXSYSNAME) {
390920Sjbeloro 			if (prom_getprop(curnode, OBP_NAME,
391920Sjbeloro 			    (caddr_t)tmp_name) == -1 || prom_getprop(curnode,
392920Sjbeloro 			    OBP_DEVICETYPE, tmp_name) == -1 || strcmp(tmp_name,
393920Sjbeloro 			    "cpu") != 0)
394920Sjbeloro 			continue;
395920Sjbeloro 
396920Sjbeloro 			cpucnt++;
397920Sjbeloro 			if (prom_getprop(curnode, "portid", (caddr_t)&portid) !=
398920Sjbeloro 			    -1 && portid > max_portid)
399920Sjbeloro 				max_portid = portid;
400920Sjbeloro 		}
401920Sjbeloro 	}
402920Sjbeloro 	if (cpucnt <= 1)
403920Sjbeloro 		max_mem_nodes = 1;
404920Sjbeloro 	else if (max_portid >= 0 && max_portid < MAX_MEM_NODES)
405920Sjbeloro 		max_mem_nodes = max_portid + 1;
406920Sjbeloro 
407920Sjbeloro 	/*
408920Sjbeloro 	 * Set tuneables for fiesta architecture
409920Sjbeloro 	 *
410920Sjbeloro 	 * lgrp_expand_proc_thresh is the minimum load on the lgroups
411920Sjbeloro 	 * this process is currently running on before considering
412920Sjbeloro 	 * expanding threads to another lgroup.
413920Sjbeloro 	 *
414920Sjbeloro 	 * lgrp_expand_proc_diff determines how much less the remote lgroup
415920Sjbeloro 	 * must be loaded before expanding to it.
416920Sjbeloro 	 *
417920Sjbeloro 	 * Optimize for memory bandwidth by spreading multi-threaded
418920Sjbeloro 	 * program to different lgroups.
419920Sjbeloro 	 */
420920Sjbeloro 	lgrp_expand_proc_thresh = lgrp_loadavg_max_effect - 1;
421920Sjbeloro 	lgrp_expand_proc_diff = lgrp_loadavg_max_effect / 2;
422920Sjbeloro 	lgrp_loadavg_tolerance = lgrp_loadavg_max_effect / 2;
423920Sjbeloro 	lgrp_mem_free_thresh = 1;	/* home lgrp must have some memory */
424920Sjbeloro 	lgrp_expand_proc_thresh = lgrp_loadavg_max_effect - 1;
425920Sjbeloro 	lgrp_mem_policy_root = LGRP_MEM_POLICY_NEXT;
426920Sjbeloro 	lgrp_load_thresh = 0;
427920Sjbeloro 
428920Sjbeloro 	mem_node_pfn_shift = PLATFORM_MC_SHIFT - MMU_PAGESHIFT;
429920Sjbeloro }
430920Sjbeloro 
431920Sjbeloro /*
432920Sjbeloro  * Return latency between "from" and "to" lgroups
433920Sjbeloro  *
434920Sjbeloro  * This latency number can only be used for relative comparison
435920Sjbeloro  * between lgroups on the running system, cannot be used across platforms,
436920Sjbeloro  * and may not reflect the actual latency.  It is platform and implementation
437920Sjbeloro  * specific, so platform gets to decide its value.  It would be nice if the
438920Sjbeloro  * number was at least proportional to make comparisons more meaningful though.
439920Sjbeloro  * NOTE: The numbers below are supposed to be load latencies for uncached
440920Sjbeloro  * memory divided by 10.
441920Sjbeloro  */
442920Sjbeloro int
443920Sjbeloro plat_lgrp_latency(void *from, void *to)
444920Sjbeloro {
445920Sjbeloro 	/*
446920Sjbeloro 	 * Return remote latency when there are more than two lgroups
447920Sjbeloro 	 * (root and child) and getting latency between two different
448920Sjbeloro 	 * lgroups or root is involved
449920Sjbeloro 	 */
450920Sjbeloro 	if (lgrp_optimizations() && (from != to || from ==
451920Sjbeloro 	    (void *) LGRP_DEFAULT_HANDLE || to == (void *) LGRP_DEFAULT_HANDLE))
452920Sjbeloro 		return (17);
453920Sjbeloro 	else
454920Sjbeloro 		return (12);
455920Sjbeloro }
456920Sjbeloro 
457920Sjbeloro int
458920Sjbeloro plat_pfn_to_mem_node(pfn_t pfn)
459920Sjbeloro {
460920Sjbeloro 	ASSERT(max_mem_nodes > 1);
461920Sjbeloro 	return (pfn >> mem_node_pfn_shift);
462920Sjbeloro }
463920Sjbeloro 
464920Sjbeloro /*
465920Sjbeloro  * Assign memnode to lgroups
466920Sjbeloro  */
467920Sjbeloro void
468920Sjbeloro plat_fill_mc(pnode_t nodeid)
469920Sjbeloro {
470920Sjbeloro 	int		portid;
471920Sjbeloro 
472920Sjbeloro 	/*
473920Sjbeloro 	 * Memory controller portid == global CPU id
474920Sjbeloro 	 */
475920Sjbeloro 	if ((prom_getprop(nodeid, "portid", (caddr_t)&portid) == -1) ||
476920Sjbeloro 	    (portid < 0))
477920Sjbeloro 		return;
478920Sjbeloro 
479920Sjbeloro 	if (portid < max_mem_nodes)
480920Sjbeloro 		plat_assign_lgrphand_to_mem_node((lgrp_handle_t)portid, portid);
481920Sjbeloro }
482920Sjbeloro 
483920Sjbeloro /* ARGSUSED */
484920Sjbeloro void
485920Sjbeloro plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
486920Sjbeloro {
487920Sjbeloro 	size_t	elem;
488920Sjbeloro 	pfn_t	basepfn;
489920Sjbeloro 	pgcnt_t	npgs;
490920Sjbeloro 
491920Sjbeloro 	/*
492920Sjbeloro 	 * Boot install lists are arranged <addr, len>, <addr, len>, ...
493920Sjbeloro 	 */
494920Sjbeloro 	for (elem = 0; elem < nelems; elem += 2) {
495920Sjbeloro 		basepfn = btop(list[elem]);
496920Sjbeloro 		npgs = btop(list[elem+1]);
497920Sjbeloro 		mem_node_add_slice(basepfn, basepfn + npgs - 1);
498920Sjbeloro 	}
499920Sjbeloro }
500920Sjbeloro 
501920Sjbeloro /*
502920Sjbeloro  * Common locking enter code
503920Sjbeloro  */
504920Sjbeloro void
505920Sjbeloro plat_setprop_enter(void)
506920Sjbeloro {
507920Sjbeloro 	mutex_enter(&mi2cv_mutex);
508920Sjbeloro }
509920Sjbeloro 
510920Sjbeloro /*
511920Sjbeloro  * Common locking exit code
512920Sjbeloro  */
513920Sjbeloro void
514920Sjbeloro plat_setprop_exit(void)
515920Sjbeloro {
516920Sjbeloro 	mutex_exit(&mi2cv_mutex);
517920Sjbeloro }
518920Sjbeloro 
519920Sjbeloro /*
520920Sjbeloro  * Called by mi2cv driver
521920Sjbeloro  */
522920Sjbeloro void
523920Sjbeloro plat_shared_i2c_enter(dev_info_t *i2cnexus_dip)
524920Sjbeloro {
525920Sjbeloro 	if (i2cnexus_dip == shared_mi2cv_dip) {
526920Sjbeloro 		plat_setprop_enter();
527920Sjbeloro 	}
528920Sjbeloro }
529920Sjbeloro 
530920Sjbeloro /*
531920Sjbeloro  * Called by mi2cv driver
532920Sjbeloro  */
533920Sjbeloro void
534920Sjbeloro plat_shared_i2c_exit(dev_info_t *i2cnexus_dip)
535920Sjbeloro {
536920Sjbeloro 	if (i2cnexus_dip == shared_mi2cv_dip) {
537920Sjbeloro 		plat_setprop_exit();
538920Sjbeloro 	}
539920Sjbeloro }
540920Sjbeloro /*
541920Sjbeloro  * Called by todm5823 driver
542920Sjbeloro  */
543920Sjbeloro void
544920Sjbeloro plat_rmc_comm_req(struct rmc_comm_msg *request)
545920Sjbeloro {
546920Sjbeloro 	if (rmc_req_now)
547920Sjbeloro 		(void) rmc_req_now(request, 0);
548920Sjbeloro }
549