serengeti.c revision e12a8a13c5492eeed938960ff7c68a46f982288b
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * CDDL HEADER START
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms of the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Common Development and Distribution License (the "License").
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You may not use this file except in compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * or http://www.opensolaris.org/os/licensing.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing permissions
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL HEADER in each
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below this CDDL HEADER, with the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * fields enclosed by brackets "[]" replaced with your own identifying
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * information: Portions Copyright [yyyy] [name of copyright owner]
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * CDDL HEADER END
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Use is subject to license terms.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington#pragma ident "%Z%%M% %I% %E% SMI"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/time.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/cpuvar.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/dditypes.h>
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden#include <sys/ddipropdefs.h>
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden#include <sys/ddi_impldefs.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/sunddi.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/esunddi.h>
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott#include <sys/sunndi.h>
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott#include <sys/platform_module.h>
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott#include <sys/errno.h>
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott#include <sys/conf.h>
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott#include <sys/modctl.h>
01a939641aeb0a095851921879620c3fab295cb2Robert Wapshott#include <sys/promif.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/promimpl.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/prom_plat.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/cmn_err.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/sysmacros.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/mem_cage.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/kobj.h>
01a939641aeb0a095851921879620c3fab295cb2Robert Wapshott#include <sys/utsname.h>
01a939641aeb0a095851921879620c3fab295cb2Robert Wapshott#include <sys/cpu_sgnblk_defs.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/atomic.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/kdi_impl.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
01a939641aeb0a095851921879620c3fab295cb2Robert Wapshott#include <sys/sgsbbc.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/sgsbbc_iosram.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/sgsbbc_iosram_priv.h>
01a939641aeb0a095851921879620c3fab295cb2Robert Wapshott#include <sys/sgsbbc_mailbox.h>
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott#include <sys/sgsgn.h>
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell#include <sys/sgcn.h>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#include <sys/serengeti.h>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#include <sys/sgfrutypes.h>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#include <sys/machsystm.h>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#include <sys/sbd_ioctl.h>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#include <sys/sbd.h>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#include <sys/sbdp_mem.h>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#include <sys/memnode.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <vm/vm_dep.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <vm/page.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
01a939641aeb0a095851921879620c3fab295cb2Robert Wapshott#include <sys/cheetahregs.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/plat_ecc_unum.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/plat_ecc_dimm.h>
01a939641aeb0a095851921879620c3fab295cb2Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#include <sys/lgrp.h>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic int sg_debug = 0;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#ifdef DEBUG
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#define DCMNERR if (sg_debug) cmn_err
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#else
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#define DCMNERR
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#endif
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint (*p2get_mem_unum)(int, uint64_t, char *, int, int *);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/* local functions */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic void cpu_sgn_update(ushort_t sgn, uchar_t state,
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford uchar_t sub_state, int cpuid);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Local data.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * iosram_write_ptr is a pointer to iosram_write(). Because of
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * kernel dynamic linking, we can't get to the function by name,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * but we can look up its address, and store it in this variable
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * instead.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * We include the extern for iosram_write() here not because we call
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * it, but to force compilation errors if its prototype doesn't
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * match the prototype of iosram_write_ptr.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The same issues apply to iosram_read() and iosram_read_ptr.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford/*CSTYLED*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterextern int iosram_write (int, uint32_t, caddr_t, uint32_t);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamfordstatic int (*iosram_write_ptr)(int, uint32_t, caddr_t, uint32_t) = NULL;
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford/*CSTYLED*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterextern int iosram_read (int, uint32_t, caddr_t, uint32_t);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamfordstatic int (*iosram_read_ptr)(int, uint32_t, caddr_t, uint32_t) = NULL;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Variable to indicate if the date should be obtained from the SC or not.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint todsg_use_sc = FALSE; /* set the false at the beginning */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Preallocation of spare tsb's for DR
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * We don't allocate spares for Wildcat since TSBs should come
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * out of memory local to the node.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#define IOMMU_PER_SCHIZO 2
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint serengeti_tsb_spares = (SG_MAX_IO_BDS * SG_SCHIZO_PER_IO_BD *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster IOMMU_PER_SCHIZO);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * sg_max_ncpus is the maximum number of CPUs supported on Serengeti.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * sg_max_ncpus is set to be smaller than NCPU to reduce the amount of
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * memory the logs take up until we have a dynamic log memory allocation
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * solution.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint sg_max_ncpus = (24 * 2); /* (max # of processors * # of cores/proc) */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * variables to control mailbox message timeouts.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * These can be patched via /etc/system or mdb.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint sbbc_mbox_default_timeout = MBOX_DEFAULT_TIMEOUT;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint sbbc_mbox_min_timeout = MBOX_MIN_TIMEOUT;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/* cached 'chosen' node_id */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpnode_t chosen_nodeid = (pnode_t)0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic void (*sg_ecc_taskq_func)(sbbc_ecc_mbox_t *) = NULL;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic int (*sg_ecc_mbox_func)(sbbc_ecc_mbox_t *) = NULL;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Table that maps memory slices to a specific memnode.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint slice_to_memnode[SG_MAX_SLICE];
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_dimm_sid_board_t domain_dimm_sids[SG_MAX_CPU_BDS];
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterset_platform_tsb_spares()
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington{
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington return (MIN(serengeti_tsb_spares, MAX_UPA));
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington}
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington#pragma weak mmu_init_large_pages
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterset_platform_defaults(void)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster extern int watchdog_enable;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster extern uint64_t xc_tick_limit_scale;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster extern void mmu_init_large_pages(size_t);
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell#ifdef DEBUG
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell char *todsg_name = "todsg";
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell ce_verbose_memory = 2;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell ce_verbose_other = 2;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell#endif /* DEBUG */
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster watchdog_enable = TRUE;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster watchdog_available = TRUE;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell cpu_sgn_func = cpu_sgn_update;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#ifdef DEBUG
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell /* tod_module_name should be set to "todsg" from OBP property */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott if (tod_module_name && (strcmp(tod_module_name, todsg_name) == 0))
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott prom_printf("Using todsg driver\n");
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell else {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell prom_printf("Force using todsg driver\n");
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell tod_module_name = todsg_name;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell }
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell#endif /* DEBUG */
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell /* Serengeti does not support forthdebug */
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell forthdebug_supported = 0;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell /*
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * Some DR operations require the system to be sync paused.
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * Sync pause on Serengeti could potentially take up to 4
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * seconds to complete depending on the load on the SC. To
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * avoid send_mond panics during such operations, we need to
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * increase xc_tick_limit to a larger value on Serengeti by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * setting xc_tick_limit_scale to 5.
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster xc_tick_limit_scale = 5;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((mmu_page_sizes == max_mmu_page_sizes) &&
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (mmu_ism_pagesize != DEFAULT_ISM_PAGESIZE)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (&mmu_init_large_pages)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster mmu_init_large_pages(mmu_ism_pagesize);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterload_platform_modules(void)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (modload("misc", "pcihp") < 0) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cmn_err(CE_NOTE, "pcihp driver failed to load");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*ARGSUSED*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_cpu_poweron(struct cpu *cp)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int (*serengeti_cpu_poweron)(struct cpu *) = NULL;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott serengeti_cpu_poweron =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (int (*)(struct cpu *))modgetsymvalue("sbdp_cpu_poweron", 0);
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (serengeti_cpu_poweron == NULL)
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford return (ENOTSUP);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster else
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return ((serengeti_cpu_poweron)(cp));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*ARGSUSED*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_cpu_poweroff(struct cpu *cp)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int (*serengeti_cpu_poweroff)(struct cpu *) = NULL;
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster serengeti_cpu_poweroff =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (int (*)(struct cpu *))modgetsymvalue("sbdp_cpu_poweroff", 0);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (serengeti_cpu_poweroff == NULL)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott return (ENOTSUP);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford else
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return ((serengeti_cpu_poweroff)(cp));
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott}
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#ifdef DEBUG
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottpgcnt_t serengeti_cage_size_limit;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#endif
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/* Preferred minimum cage size (expressed in pages)... for DR */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottpgcnt_t serengeti_minimum_cage_size = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottvoid
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottset_platform_cage_params(void)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott{
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott extern pgcnt_t total_pages;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott extern struct memlist *phys_avail;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott int ret;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (kernel_cage_enable) {
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott pgcnt_t preferred_cage_size;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster preferred_cage_size =
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott MAX(serengeti_minimum_cage_size, total_pages / 256);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#ifdef DEBUG
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott if (serengeti_cage_size_limit)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott preferred_cage_size = serengeti_cage_size_limit;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#endif
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott kcage_range_lock();
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott /*
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * Post copies obp into the lowest slice. This requires the
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * cage to grow upwards
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott ret = kcage_range_init(phys_avail, 0);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott if (ret == 0)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott kcage_init(preferred_cage_size);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott kcage_range_unlock();
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott }
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott /* Only note when the cage is off since it should always be on. */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott if (!kcage_on)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott cmn_err(CE_NOTE, "!DR Kernel Cage is DISABLED");
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott}
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott#define ALIGN(x, a) ((a) == 0 ? (uint64_t)(x) : \
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott (((uint64_t)(x) + (uint64_t)(a) - 1l) & ~((uint64_t)(a) - 1l)))
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottvoid
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottupdate_mem_bounds(int brd, uint64_t base, uint64_t sz)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott{
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott uint64_t end;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott int mnode;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott end = base + sz - 1;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott /*
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * First see if this board already has a memnode associated
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with it. If not, see if this slice has a memnode. This
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * covers the cases where a single slice covers multiple
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * boards (cross-board interleaving) and where a single
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * board has multiple slices (1+GB DIMMs).
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((mnode = plat_lgrphand_to_mem_node(brd)) == -1) {
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott if ((mnode = slice_to_memnode[PA_2_SLICE(base)]) == -1)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott mnode = mem_node_alloc();
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott plat_assign_lgrphand_to_mem_node(brd, mnode);
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott }
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott /*
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * Align base at 16GB boundary
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott base = ALIGN(base, (1ul << PA_SLICE_SHIFT));
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott while (base < end) {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell slice_to_memnode[PA_2_SLICE(base)] = mnode;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott base += (1ul << PA_SLICE_SHIFT);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott }
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott}
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott/*
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * Dynamically detect memory slices in the system by decoding
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * the cpu memory decoder registers at boot time.
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottvoid
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottplat_fill_mc(pnode_t nodeid)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott{
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell uint64_t mc_addr, mask;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott uint64_t mc_decode[SG_MAX_BANKS_PER_MC];
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott uint64_t base, size;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott uint32_t regs[4];
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int len;
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford int local_mc;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int portid;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int boardid;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int i;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott if ((prom_getprop(nodeid, "portid", (caddr_t)&portid) < 0) ||
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (portid == -1))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Decode the board number from the MC portid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boardid = SG_PORTID_TO_BOARD_NUM(portid);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The "reg" property returns 4 32-bit values. The first two are
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * combined to form a 64-bit address. The second two are for a
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * 64-bit size, but we don't actually need to look at that value.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster len = prom_getproplen(nodeid, "reg");
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford if (len != (sizeof (uint32_t) * 4)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster prom_printf("Warning: malformed 'reg' property\n");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford if (prom_getprop(nodeid, "reg", (caddr_t)regs) < 0)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster mc_addr = ((uint64_t)regs[0]) << 32;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster mc_addr |= (uint64_t)regs[1];
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Figure out whether the memory controller we are examining
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * belongs to this CPU or a different one.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (portid == cpunodes[CPU->cpu_id].portid)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott local_mc = 1;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster else
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster local_mc = 0;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell for (i = 0; i < SG_MAX_BANKS_PER_MC; i++) {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell mask = SG_REG_2_OFFSET(i);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If the memory controller is local to this CPU, we use
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the special ASI to read the decode registers.
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * Otherwise, we load the values from a magic address in
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * I/O space.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
bcb85423bc6855cb1c7accc69fa051e1771c000aMark de Reeper if (local_mc)
bcb85423bc6855cb1c7accc69fa051e1771c000aMark de Reeper mc_decode[i] = lddmcdecode(mask & MC_OFFSET_MASK);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster else
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster mc_decode[i] = lddphysio((mc_addr | mask));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott if (mc_decode[i] >> MC_VALID_SHIFT) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The memory decode register is a bitmask field,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * so we can decode that into both a base and
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * a span.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster base = MC_BASE(mc_decode[i]) << PHYS2UM_SHIFT;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott size = MC_UK2SPAN(mc_decode[i]);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster update_mem_bounds(boardid, base, size);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This routine is run midway through the boot process. By the time we get
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * here, we know about all the active CPU boards in the system, and we have
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * extracted information about each board's memory from the memory
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * controllers. We have also figured out which ranges of memory will be
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * assigned to which memnodes, so we walk the slice table to build the table
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * of memnodes.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/* ARGSUSED */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnellplat_build_mem_nodes(u_longlong_t *list, size_t nelems)
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell{
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell int slice;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell pfn_t basepfn;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell pgcnt_t npgs;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell mem_node_pfn_shift = PFN_SLICE_SHIFT;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell mem_node_physalign = (1ull << PA_SLICE_SHIFT);
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell for (slice = 0; slice < SG_MAX_SLICE; slice++) {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell if (slice_to_memnode[slice] == -1)
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell continue;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell basepfn = (uint64_t)slice << PFN_SLICE_SHIFT;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell npgs = 1ull << PFN_SLICE_SHIFT;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell mem_node_add_slice(basepfn, basepfn + npgs - 1);
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell }
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell}
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnellint
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnellplat_pfn_to_mem_node(pfn_t pfn)
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell{
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell int node;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell node = slice_to_memnode[PFN_2_SLICE(pfn)];
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell return (node);
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell}
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell/*
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * Serengeti support for lgroups.
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell *
d28c31c7d0cf9ac19eaf07942956e707222fb5ebPeter Major * On Serengeti, an lgroup platform handle == board number.
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell *
d28c31c7d0cf9ac19eaf07942956e707222fb5ebPeter Major * Mappings between lgroup handles and memnodes are managed
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * in addition to mappings between memory slices and memnodes
d28c31c7d0cf9ac19eaf07942956e707222fb5ebPeter Major * to support cross-board interleaving as well as multiple
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * slices per board (e.g. >1GB DIMMs). The initial mapping
9709ff1b979ab7830f3e00b809f1157554566ed3Steve Ferris * of memnodes to lgroup handles is determined at boot time.
d28c31c7d0cf9ac19eaf07942956e707222fb5ebPeter Major * A DR addition of memory adds a new mapping. A DR copy-rename
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * swaps mappings.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
9709ff1b979ab7830f3e00b809f1157554566ed3Steve Ferris * Macro for extracting the board number from the CPU id
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#define CPUID_TO_BOARD(id) (((id) >> 2) & 0x7)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Return the platform handle for the lgroup containing the given CPU
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * For Serengeti, lgroup platform handle == board number
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterlgrp_handle_t
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_lgrp_cpu_to_hand(processorid_t id)
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (CPUID_TO_BOARD(id));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Platform specific lgroup initialization
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_lgrp_init(void)
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int i;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster extern uint32_t lgrp_expand_proc_thresh;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster extern uint32_t lgrp_expand_proc_diff;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Initialize lookup tables to invalid values so we catch
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * any illegal use of them.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford for (i = 0; i < SG_MAX_SLICE; i++) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster slice_to_memnode[i] = -1;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Set tuneables for Serengeti architecture
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * lgrp_expand_proc_thresh is the minimum load on the lgroups
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * this process is currently running on before considering
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * expanding threads to another lgroup.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * lgrp_expand_proc_diff determines how much less the remote lgroup
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * must be loaded before expanding to it.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Bandwidth is maximized on Serengeti by spreading load across
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the machine. The impact to inter-thread communication isn't
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * too costly since remote latencies are relatively low. These
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * values equate to one CPU's load and so attempt to spread the
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * load out across as many lgroups as possible one CPU at a time.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford lgrp_expand_proc_thresh = LGRP_LOADAVG_THREAD_MAX;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster lgrp_expand_proc_diff = LGRP_LOADAVG_THREAD_MAX;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Platform notification of lgroup (re)configuration changes
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*ARGSUSED*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_lgrp_config(lgrp_config_flag_t evt, uintptr_t arg)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster update_membounds_t *umb;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster lgrp_config_mem_rename_t lmr;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster lgrp_handle_t shand, thand;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int snode, tnode;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster switch (evt) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case LGRP_CONFIG_MEM_ADD:
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott umb = (update_membounds_t *)arg;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster update_mem_bounds(umb->u_board, umb->u_base, umb->u_len);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case LGRP_CONFIG_MEM_DEL:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* We don't have to do anything */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case LGRP_CONFIG_MEM_RENAME:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * During a DR copy-rename operation, all of the memory
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * on one board is moved to another board -- but the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * addresses/pfns and memnodes don't change. This means
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the memory has changed locations without changing identity.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Source is where we are copying from and target is where we
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * are copying to. After source memnode is copied to target
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * memnode, the physical addresses of the target memnode are
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * renamed to match what the source memnode had. Then target
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * memnode can be removed and source memnode can take its
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * place.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * To do this, swap the lgroup handle to memnode mappings for
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the boards, so target lgroup will have source memnode and
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * source lgroup will have empty target memnode which is where
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * its memory will go (if any is added to it later).
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Then source memnode needs to be removed from its lgroup
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * and added to the target lgroup where the memory was living
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * but under a different name/memnode. The memory was in the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * target memnode and now lives in the source memnode with
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * different physical addresses even though it is the same
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * memory.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster shand = arg & 0xffff;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster thand = (arg & 0xffff0000) >> 16;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster snode = plat_lgrphand_to_mem_node(shand);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford tnode = plat_lgrphand_to_mem_node(thand);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster plat_assign_lgrphand_to_mem_node(thand, snode);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster plat_assign_lgrphand_to_mem_node(shand, tnode);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Remove source memnode of copy rename from its lgroup
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * and add it to its new target lgroup
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford lmr.lmem_rename_from = shand;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster lmr.lmem_rename_to = thand;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster lgrp_config(LGRP_CONFIG_MEM_RENAME, (uintptr_t)snode,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (uintptr_t)&lmr);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster default:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Return latency between "from" and "to" lgroups
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This latency number can only be used for relative comparison
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * between lgroups on the running system, cannot be used across platforms,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * and may not reflect the actual latency. It is platform and implementation
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * specific, so platform gets to decide its value. It would be nice if the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * number was at least proportional to make comparisons more meaningful though.
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington * NOTE: The numbers below are supposed to be load latencies for uncached
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington * memory divided by 10.
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington */
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunningtonint
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunningtonplat_lgrp_latency(lgrp_handle_t from, lgrp_handle_t to)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Return min remote latency when there are more than two lgroups
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (root and child) and getting latency between two different lgroups
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * or root is involved
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden */
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden if (lgrp_optimizations() && (from != to ||
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden from == LGRP_DEFAULT_HANDLE || to == LGRP_DEFAULT_HANDLE))
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden return (28);
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden else
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden return (23);
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden}
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden/* ARGSUSED */
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunningtonvoid
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunningtonplat_freelist_process(int mnode)
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden{
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * Find dip for chosen IOSRAM
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterdev_info_t *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterfind_chosen_dip(void)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dev_info_t *dip;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster char master_sbbc[MAXNAMELEN];
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster pnode_t nodeid;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster uint_t tunnel;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * find the /chosen SBBC node, prom interface will handle errors
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster nodeid = prom_chosennode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * get the 'iosram' property from the /chosen node
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (prom_getprop(nodeid, IOSRAM_CHOSEN_PROP, (caddr_t)&tunnel) <= 0) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SBBC_ERR(CE_PANIC, "No iosram property found! \n");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott if (prom_phandle_to_path((phandle_t)tunnel, master_sbbc,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sizeof (master_sbbc)) < 0) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SBBC_ERR1(CE_PANIC, "prom_phandle_to_path(%d) failed\n",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster tunnel);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster chosen_nodeid = nodeid;
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * load and attach the sgsbbc driver.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This will also attach all the sgsbbc driver instances
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (i_ddi_attach_hw_nodes("sgsbbc") != DDI_SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cmn_err(CE_WARN, "sgsbbc failed to load\n");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* translate a path name to a dev_info_t */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dip = e_ddi_hold_devi_by_path(master_sbbc, 0);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford if ((dip == NULL) || (ddi_get_nodeid(dip) != tunnel)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cmn_err(CE_PANIC, "i_ddi_path_to_devi(%x) failed for SBBC\n",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster tunnel);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* make sure devi_ref is ZERO */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ndi_rele_devi(dip);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster DCMNERR(CE_CONT, "Chosen IOSRAM is at %s \n", master_sbbc);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott return (dip);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamfordload_platform_drivers(void)
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int ret;
e2c8a434054afd7228765bdfb72df3c6117be3b8David Luna
e2c8a434054afd7228765bdfb72df3c6117be3b8David Luna /*
e2c8a434054afd7228765bdfb72df3c6117be3b8David Luna * Load and attach the mc-us3 memory driver.
e2c8a434054afd7228765bdfb72df3c6117be3b8David Luna */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (i_ddi_attach_hw_nodes("mc-us3") != DDI_SUCCESS)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cmn_err(CE_WARN, "mc-us3 failed to load");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster else
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (void) ddi_hold_driver(ddi_name_to_major("mc-us3"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Initialize the chosen IOSRAM before its clients
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * are loaded.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (void) find_chosen_dip();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * Ideally, we'd do this in set_platform_defaults(), but
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * at that point it's too early to look up symbols.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster iosram_write_ptr = (int (*)(int, uint32_t, caddr_t, uint32_t))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modgetsymvalue("iosram_write", 0);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (iosram_write_ptr == NULL) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster DCMNERR(CE_WARN, "load_platform_defaults: iosram_write()"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster " not found; signatures will not be updated\n");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The iosram read ptr is only needed if we can actually
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * write CPU signatures, so only bother setting it if we
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * set a valid write pointer, above.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster iosram_read_ptr = (int (*)(int, uint32_t, caddr_t, uint32_t))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modgetsymvalue("iosram_read", 0);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (iosram_read_ptr == NULL)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster DCMNERR(CE_WARN, "load_platform_defaults: iosram_read()"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster " not found\n");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Set todsg_use_sc to TRUE so that we will be getting date
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * from the SC.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford todsg_use_sc = TRUE;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * Now is a good time to activate hardware watchdog (if one exists).
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster mutex_enter(&tod_lock);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott if (watchdog_enable)
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell ret = tod_ops.tod_set_watchdog_timer(watchdog_timeout_seconds);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster mutex_exit(&tod_lock);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (ret != 0)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster printf("Hardware watchdog enabled\n");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Load and attach the schizo pci bus nexus driver.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (i_ddi_attach_hw_nodes("pcisch") != DDI_SUCCESS)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cmn_err(CE_WARN, "pcisch failed to load");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster plat_ecc_init();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * No platform drivers on this platform
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterchar *platform_module_list[] = {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (char *)0
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster};
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott/*ARGSUSED*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_tod_fault(enum tod_fault_type tod_bad)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamfordplat_max_boards()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (SG_MAX_BDS);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottint
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottplat_max_io_units_per_board()
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (SG_MAX_IO_PER_BD);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_max_cmp_units_per_board()
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (SG_MAX_CMPS_PER_BD);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_max_cpu_units_per_board()
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott{
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott return (SG_MAX_CPUS_PER_BD);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_max_mc_units_per_board()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (SG_MAX_CMPS_PER_BD); /* each CPU die has a memory controller */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_max_mem_units_per_board()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (SG_MAX_MEM_PER_BD);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamfordint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_max_cpumem_boards(void)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (SG_MAX_CPU_BDS);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterset_platform_max_ncpus(void)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott return (sg_max_ncpus);
6b0b9411405932b5ada376bb06d6bc3d94980d7fPeter Major}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_dmv_params(uint_t *hwint, uint_t *swint)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott *hwint = MAX_UPA;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *swint = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Our nodename has been set, pass it along to the SC.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_nodename_set(void)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sbbc_msg_t req; /* request */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sbbc_msg_t resp; /* response */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int rv; /* return value from call to mbox */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott struct nodename_info {
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott int32_t namelen;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott char nodename[_SYS_NMLN];
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } nni;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int (*sg_mbox)(sbbc_msg_t *, sbbc_msg_t *, time_t) = NULL;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * find the symbol for the mailbox routine
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sg_mbox = (int (*)(sbbc_msg_t *, sbbc_msg_t *, time_t))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modgetsymvalue("sbbc_mbox_request_response", 0);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (sg_mbox == NULL) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cmn_err(CE_NOTE, "!plat_nodename_set: sg_mbox not found\n");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington }
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * construct the message telling the SC our nodename
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington */
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington (void) strcpy(nni.nodename, utsname.nodename);
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington nni.namelen = (int32_t)strlen(nni.nodename);
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington req.msg_type.type = INFO_MBOX;
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington req.msg_type.sub_type = INFO_MBOX_NODENAME;
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington req.msg_status = 0;
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington req.msg_len = (int)(nni.namelen + sizeof (nni.namelen));
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington req.msg_bytes = 0;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott req.msg_buf = (caddr_t)&nni;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell req.msg_data[0] = 0;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell req.msg_data[1] = 0;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington /*
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington * initialize the response back from the SC
f79113ae65937c28690ec71f68f54f862b758baePhill Cunnington */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott resp.msg_type.type = INFO_MBOX;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott resp.msg_type.sub_type = INFO_MBOX_NODENAME;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster resp.msg_status = 0;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott resp.msg_len = 0;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell resp.msg_bytes = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster resp.msg_buf = (caddr_t)0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster resp.msg_data[0] = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster resp.msg_data[1] = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell /*
bcb85423bc6855cb1c7accc69fa051e1771c000aMark de Reeper * ship it and check for success
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster rv = (sg_mbox)(&req, &resp, sbbc_mbox_default_timeout);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
d28c31c7d0cf9ac19eaf07942956e707222fb5ebPeter Major if (rv != 0) {
9709ff1b979ab7830f3e00b809f1157554566ed3Steve Ferris cmn_err(CE_NOTE, "!plat_nodename_set: sg_mbox retval %d\n", rv);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (resp.msg_status != 0) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cmn_err(CE_NOTE, "!plat_nodename_set: msg_status %d\n",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster resp.msg_status);
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell } else {
bcb85423bc6855cb1c7accc69fa051e1771c000aMark de Reeper DCMNERR(CE_NOTE, "!plat_nodename_set was successful\n");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * It is necessary to exchange the capability bitmap
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with SC before sending any ecc error information and
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * indictment. We are calling the plat_ecc_capability_send()
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * here just after sending the nodename successfully.
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell */
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell rv = plat_ecc_capability_send();
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell if (rv == 0) {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell DCMNERR(CE_NOTE, "!plat_ecc_capability_send was"
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell " successful\n");
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * flag to allow users switch between using OBP's
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * prom_get_unum() and mc-us3 driver's p2get_mem_unum()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (for main memory errors only).
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint sg_use_prom_get_unum = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Debugging flag: set to 1 to call into obp for get_unum, or set it to 0
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * to call into the unum cache system. This is the E$ equivalent of
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * sg_use_prom_get_unum.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint sg_use_prom_ecache_unum = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/* used for logging ECC errors to the SC */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#define SG_MEMORY_ECC 1
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#define SG_ECACHE_ECC 2
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#define SG_UNKNOWN_ECC (-1)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * plat_get_mem_unum() generates a string identifying either the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * memory or E$ DIMM(s) during error logging. Depending on whether
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the error is E$ or memory related, the appropriate support
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * routine is called to assist in the string generation.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * - For main memory errors we can use the mc-us3 drivers p2getunum()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (or prom_get_unum() for debugging purposes).
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * - For E$ errors we call sg_get_ecacheunum() to generate the unum (or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * prom_serengeti_get_ecacheunum() for debugging purposes).
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottstatic int
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostersg_prom_get_unum(int synd_code, uint64_t paddr, char *buf, int buflen,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int *lenp)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((prom_get_unum(synd_code, (unsigned long long)paddr,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster buf, buflen, lenp)) != 0)
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford return (EIO);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster else if (*lenp <= 1)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (EINVAL);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott else
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott return (0);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*ARGSUSED*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_get_mem_unum(int synd_code, uint64_t flt_addr, int flt_bus_id,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int flt_in_memory, ushort_t flt_status, char *buf, int buflen, int *lenp)
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
56ed5bbb263838f338eb8afc978091c01a4f2a2bjeff.schenk * unum_func will either point to the memory drivers p2get_mem_unum()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * or to prom_get_unum() for memory errors.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int (*unum_func)(int synd_code, uint64_t paddr, char *buf,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int buflen, int *lenp) = p2get_mem_unum;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * check if it's a Memory or an Ecache error.
6f6d45938671719a3c22abd091398ec1cfcf7788Peter Major */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (flt_in_memory) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
6f6d45938671719a3c22abd091398ec1cfcf7788Peter Major * It's a main memory error.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * For debugging we allow the user to switch between
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * using OBP's get_unum and the memory driver's get_unum
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * so we create a pointer to the functions and switch
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * depending on the sg_use_prom_get_unum flag.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (sg_use_prom_get_unum) {
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford DCMNERR(CE_NOTE, "Using prom_get_unum from OBP");
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott return (sg_prom_get_unum(synd_code,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster P2ALIGN(flt_addr, 8), buf, buflen, lenp));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (unum_func != NULL) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (unum_func(synd_code, P2ALIGN(flt_addr, 8),
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster buf, buflen, lenp));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (ENOTSUP);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (flt_status & ECC_ECACHE) {
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott /*
6f6d45938671719a3c22abd091398ec1cfcf7788Peter Major * It's an E$ error.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (sg_use_prom_ecache_unum) {
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * We call to OBP to handle this.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster DCMNERR(CE_NOTE,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Using prom_serengeti_get_ecacheunum from OBP");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (prom_serengeti_get_ecacheunum(flt_bus_id,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster P2ALIGN(flt_addr, 8), buf, buflen, lenp) != 0) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (EIO);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (sg_get_ecacheunum(flt_bus_id, flt_addr,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster buf, buflen, lenp));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford return (ENOTSUP);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (0);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott}
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This platform hook gets called from mc_add_mem_unum_label() in the mc-us3
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * driver giving each platform the opportunity to add platform
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * specific label information to the unum for ECC error logging purposes.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_add_mem_unum_label(char *unum, int mcid, int bank, int dimm)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster char new_unum[UNUM_NAMLEN] = "";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int node = SG_PORTID_TO_NODEID(mcid);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int board = SG_CPU_BD_PORTID_TO_BD_NUM(mcid);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int position = SG_PORTID_TO_CPU_POSN(mcid);
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The mc-us3 driver deals with logical banks but for unum
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * purposes we need to use physical banks so that the correct
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * dimm can be physically located. Logical banks 0 and 2
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * make up physical bank 0. Logical banks 1 and 3 make up
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * physical bank 1. Here we do the necessary conversion.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster bank = (bank % 2);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (dimm == -1) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SET_FRU_NAME_NODE(new_unum, node);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SET_FRU_NAME_CPU_BOARD(new_unum, board);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SET_FRU_NAME_MODULE(new_unum, position);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SET_FRU_NAME_BANK(new_unum, bank);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SET_FRU_NAME_NODE(new_unum, node);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SET_FRU_NAME_CPU_BOARD(new_unum, board);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SET_FRU_NAME_MODULE(new_unum, position);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SET_FRU_NAME_BANK(new_unum, bank);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SET_FRU_NAME_DIMM(new_unum, dimm);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster strcat(new_unum, " ");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster strcat(new_unum, unum);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster strcpy(unum, new_unum);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_get_cpu_unum(int cpuid, char *buf, int buflen, int *lenp)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int node = SG_PORTID_TO_NODEID(cpuid);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int board = SG_CPU_BD_PORTID_TO_BD_NUM(cpuid);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (snprintf(buf, buflen, "/N%d/%s%d", node,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_HPU_TYPE_CPU_BOARD_ID, board) >= buflen) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (ENOSPC);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott *lenp = strlen(buf);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (0);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * We log all ECC events to the SC so we send a mailbox
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * message to the SC passing it the relevant data.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * ECC mailbox messages are sent via a taskq mechanism to
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * prevent impaired system performance during ECC floods.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Indictments have already passed through a taskq, so they
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * are not queued here.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_send_ecc_mailbox_msg(plat_ecc_message_type_t msg_type, void *datap)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott sbbc_ecc_mbox_t *msgp;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott size_t msg_size;
efad633539be6ecb378fafe208b80b81739e28d1Neil Madden uint16_t msg_subtype;
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott int sleep_flag, log_error;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (sg_ecc_taskq_func == NULL) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sg_ecc_taskq_func = (void (*)(sbbc_ecc_mbox_t *))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modgetsymvalue("sbbc_mbox_queue_ecc_event", 0);
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell if (sg_ecc_taskq_func == NULL) {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell cmn_err(CE_NOTE, "!plat_send_ecc_mailbox_msg: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "sbbc_mbox_queue_ecc_event not found");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (ENODEV);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (sg_ecc_mbox_func == NULL) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sg_ecc_mbox_func = (int (*)(sbbc_ecc_mbox_t *))
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford modgetsymvalue("sbbc_mbox_ecc_output", 0);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (sg_ecc_mbox_func == NULL) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cmn_err(CE_NOTE, "!plat_send_ecc_mailbox_msg: "
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott "sbbc_mbox_ecc_output not found");
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott return (ENODEV);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott /*
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott * Initialize the request and response structures
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott */
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott switch (msg_type) {
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott case PLAT_ECC_ERROR_MESSAGE:
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msg_subtype = INFO_MBOX_ERROR_ECC;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msg_size = sizeof (plat_ecc_error_data_t);
fd21d481e26774c37a197c7cc8ab56096a21e7aaPhill Cunnington sleep_flag = KM_NOSLEEP;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott log_error = 1;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_ERROR2_MESSAGE:
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msg_subtype = INFO_MBOX_ECC;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msg_size = sizeof (plat_ecc_error2_data_t);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sleep_flag = KM_NOSLEEP;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott log_error = 1;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_INDICTMENT_MESSAGE:
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msg_subtype = INFO_MBOX_ERROR_INDICT;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msg_size = sizeof (plat_ecc_indictment_data_t);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sleep_flag = KM_SLEEP;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott log_error = 0;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_INDICTMENT2_MESSAGE:
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell msg_subtype = INFO_MBOX_ECC;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msg_size = sizeof (plat_ecc_indictment2_data_t);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sleep_flag = KM_SLEEP;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster log_error = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_CAPABILITY_MESSAGE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msg_subtype = INFO_MBOX_ECC_CAP;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msg_size = sizeof (plat_capability_data_t) +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster strlen(utsname.release) + strlen(utsname.version) + 2;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sleep_flag = KM_SLEEP;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster log_error = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_DIMM_SID_MESSAGE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msg_subtype = INFO_MBOX_ECC;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell msg_size = sizeof (plat_dimm_sid_request_data_t);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sleep_flag = KM_SLEEP;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster log_error = 0;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster default:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (EINVAL);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp = (sbbc_ecc_mbox_t *)kmem_zalloc(sizeof (sbbc_ecc_mbox_t),
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sleep_flag);
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott if (msgp == NULL) {
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott cmn_err(CE_NOTE, "!plat_send_ecc_mailbox_msg: "
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott "unable to allocate sbbc_ecc_mbox");
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott return (ENOMEM);
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott }
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msgp->ecc_log_error = log_error;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msgp->ecc_req.msg_type.type = INFO_MBOX;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msgp->ecc_req.msg_type.sub_type = msg_subtype;
d0da70ccbba38b773e7a7cc71bc124b06206d201Robert Wapshott msgp->ecc_req.msg_status = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_req.msg_len = (int)msg_size;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_req.msg_bytes = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_req.msg_buf = (caddr_t)kmem_zalloc(msg_size, sleep_flag);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_req.msg_data[0] = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_req.msg_data[1] = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott if (msgp->ecc_req.msg_buf == NULL) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cmn_err(CE_NOTE, "!plat_send_ecc_mailbox_msg: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "unable to allocate request msg_buf");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster kmem_free((void *)msgp, sizeof (sbbc_ecc_mbox_t));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (ENOMEM);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster bcopy(datap, (void *)msgp->ecc_req.msg_buf, msg_size);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * initialize the response back from the SC
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_type.type = INFO_MBOX;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_type.sub_type = msg_subtype;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_status = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_len = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_bytes = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_buf = NULL;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_data[0] = 0;
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott msgp->ecc_resp.msg_data[1] = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster switch (msg_type) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_ERROR_MESSAGE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_ERROR2_MESSAGE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott * For Error Messages, we go through a taskq.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Queue up the message for processing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (*sg_ecc_taskq_func)(msgp);
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden return (0);
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_CAPABILITY_MESSAGE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * For indictment and capability messages, we've already gone
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford * through the taskq, so we can call the mailbox routine
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * directly. Find the symbol for the routine that sends
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the mailbox msg
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_len = (int)msg_size;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_buf = (caddr_t)kmem_zalloc(msg_size,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sleep_flag);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* FALLTHRU */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_INDICTMENT_MESSAGE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_INDICTMENT2_MESSAGE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return ((*sg_ecc_mbox_func)(msgp));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case PLAT_ECC_DIMM_SID_MESSAGE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster msgp->ecc_resp.msg_len = sizeof (plat_dimm_sid_board_data_t);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott msgp->ecc_resp.msg_buf = (caddr_t)kmem_zalloc(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sizeof (plat_dimm_sid_board_data_t), sleep_flag);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return ((*sg_ecc_mbox_func)(msgp));
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster default:
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford ASSERT(0);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (EINVAL);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * m is redundant on serengeti as the multiplier is always 4
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*ARGSUSED*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_make_fru_cpuid(int sb, int m, int proc)
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (MAKE_CPUID(sb, proc));
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * board number for a given proc
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterplat_make_fru_boardnum(int proc)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (SG_CPU_BD_PORTID_TO_BD_NUM(proc));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostercpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster uint32_t signature = CPU_SIG_BLD(sig, state, sub_state);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sig_state_t current_sgn;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int i;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (iosram_write_ptr == NULL) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If the IOSRAM write pointer isn't set, we won't be able
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * to write signatures to ANYTHING, so we may as well just
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * write out an error message (if desired) and exit this
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * routine now...
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster DCMNERR(CE_WARN,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "cpu_sgn_update: iosram_write() not found;"
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott " cannot write signature 0x%x for CPU(s) or domain\n",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster signature);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell }
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Differentiate a panic reboot from a non-panic reboot in the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * setting of the substate of the signature.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If the new substate is REBOOT and we're rebooting due to a panic,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * then set the new substate to a special value indicating a panic
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * reboot, SIGSUBST_PANIC_REBOOT.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * A panic reboot is detected by a current (previous) domain signature
72450cb9c2ca854c6d3479832c2738196c1d3282Robert Wapshott * state of SIGST_EXIT, and a new signature substate of SIGSUBST_REBOOT.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The domain signature state SIGST_EXIT is used as the panic flow
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * progresses.
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * At the end of the panic flow, the reboot occurs but we should now
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * one that was involuntary, something that may be quite useful to know
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * at OBP level.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (sub_state == SIGSUBST_REBOOT) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (iosram_read_ptr == NULL) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster DCMNERR(CE_WARN,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "cpu_sgn_update: iosram_read() not found;"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster " could not check current domain signature\n");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (void) (*iosram_read_ptr)(SBBC_SIGBLCK_KEY,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SGNBLK_DOMAINSIG_OFFSET,
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott (char *)&current_sgn, sizeof (current_sgn));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (current_sgn.state_t.state == SIGST_EXIT)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster signature = CPU_SIG_BLD(sig, state,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SIGSUBST_PANIC_REBOOT);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * cpuid == -1 indicates that the operation applies to all cpus.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (cpuid >= 0) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (void) (*iosram_write_ptr)(SBBC_SIGBLCK_KEY,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SGNBLK_CPUSIG_OFFSET(cpuid), (char *)&signature,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sizeof (signature));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (i = 0; i < NCPU; i++) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (cpu[i] == NULL || !(cpu[i]->cpu_flags &
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (CPU_EXISTS|CPU_QUIESCED))) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster continue;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (void) (*iosram_write_ptr)(SBBC_SIGBLCK_KEY,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SGNBLK_CPUSIG_OFFSET(i), (char *)&signature,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sizeof (signature));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (state == SIGST_OFFLINE || state == SIGST_DETACHED) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (void) (*iosram_write_ptr)(SBBC_SIGBLCK_KEY,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SG_SGNBLK_DOMAINSIG_OFFSET, (char *)&signature,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sizeof (signature));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervoid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstartup_platform(void)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * A routine to convert a number (represented as a string) to
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the integer value it represents.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic int
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterisdigit(int ch)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (ch >= '0' && ch <= '9');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamfordstatic int
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstrtoi(char *p, char **pos)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int n;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott int c, neg = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!isdigit(c = *p)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster while (isspace(c))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster c = *++p;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster switch (c) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case '-':
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott neg++;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* FALLTHROUGH */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case '+':
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster c = *++p;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!isdigit(c)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (pos != NULL)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *pos = p;
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden return (0);
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden }
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden }
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden for (n = '0' - c; isdigit(c = *++p); ) {
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden n *= 10; /* two steps to avoid unnecessary overflow */
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden n += '0' - c; /* accum neg to avoid surprises at MAX */
1d407e39b7d8f68d9a2b1e178f35fab037d9835aRobert Wapshott }
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden if (pos != NULL)
87d68743726585ee101ba2e7be2cf06cd34ebb80Neil Madden *pos = p;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (neg ? n : -n);
}
/*
* Get the three parts of the Serengeti PROM version.
* Used for feature readiness tests.
*
* Return 0 if version extracted successfully, -1 otherwise.
*/
int
sg_get_prom_version(int *sysp, int *intfp, int *bldp)
{
int plen;
char vers[512];
static pnode_t node;
static char version[] = "version";
char *verp, *ep;
node = prom_finddevice("/openprom");
if (node == OBP_BADNODE)
return (-1);
plen = prom_getproplen(node, version);
if (plen <= 0 || plen >= sizeof (vers))
return (-1);
(void) prom_getprop(node, version, vers);
vers[plen] = '\0';
/* Make sure it's an OBP flashprom */
if (vers[0] != 'O' && vers[1] != 'B' && vers[2] != 'P') {
cmn_err(CE_WARN, "sg_get_prom_version: "
"unknown <version> string in </openprom>\n");
return (-1);
}
verp = &vers[4];
*sysp = strtoi(verp, &ep);
if (ep == verp || *ep != '.')
return (-1);
verp = ep + 1;
*intfp = strtoi(verp, &ep);
if (ep == verp || *ep != '.')
return (-1);
verp = ep + 1;
*bldp = strtoi(verp, &ep);
if (ep == verp || (*ep != '\0' && !isspace(*ep)))
return (-1);
return (0);
}
/*
* Return 0 if system board Dynamic Reconfiguration
* is supported by the firmware, -1 otherwise.
*/
int
sg_prom_sb_dr_check(void)
{
static int prom_res = 1;
if (prom_res == 1) {
int sys, intf, bld;
int rv;
rv = sg_get_prom_version(&sys, &intf, &bld);
if (rv == 0 && sys == 5 &&
(intf >= 12 || (intf == 11 && bld >= 200))) {
prom_res = 0;
} else {
prom_res = -1;
}
}
return (prom_res);
}
/*
* Return 0 if cPCI Dynamic Reconfiguration
* is supported by the firmware, -1 otherwise.
*/
int
sg_prom_cpci_dr_check(void)
{
/*
* The version check is currently the same as for
* system boards. Since the two DR sub-systems are
* independent, this could change.
*/
return (sg_prom_sb_dr_check());
}
/*
* KDI functions - used by the in-situ kernel debugger (kmdb) to perform
* platform-specific operations. These functions execute when the world is
* stopped, and as such cannot make any blocking calls, hold locks, etc.
* promif functions are a special case, and may be used.
*/
/*
* Our implementation of this KDI op updates the CPU signature in the system
* controller. Note that we set the signature to OBP_SIG, rather than DBG_SIG.
* The Forth words we execute will, among other things, transform our OBP_SIG
* into DBG_SIG. They won't function properly if we try to use DBG_SIG.
*/
static void
sg_system_claim(void)
{
prom_interpret("sigb-sig! my-sigb-sig!", OBP_SIG, OBP_SIG, 0, 0, 0);
}
static void
sg_system_release(void)
{
prom_interpret("sigb-sig! my-sigb-sig!", OS_SIG, OS_SIG, 0, 0, 0);
}
static void
sg_console_claim(void)
{
prom_serengeti_set_console_input(SGCN_OBP_STR);
}
static void
sg_console_release(void)
{
prom_serengeti_set_console_input(SGCN_CLNT_STR);
}
void
plat_kdi_init(kdi_t *kdi)
{
kdi->pkdi_system_claim = sg_system_claim;
kdi->pkdi_system_release = sg_system_release;
kdi->pkdi_console_claim = sg_console_claim;
kdi->pkdi_console_release = sg_console_release;
}