a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * CDDL HEADER START
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * The contents of this file are subject to the terms of the
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Common Development and Distribution License (the "License").
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * You may not use this file except in compliance with the License.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * or http://www.opensolaris.org/os/licensing.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * See the License for the specific language governing permissions
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * and limitations under the License.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * When distributing Covered Code, include this CDDL HEADER in each
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * If applicable, add the following below this CDDL HEADER, with the
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * fields enclosed by brackets "[]" replaced with your own identifying
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * information: Portions Copyright [yyyy] [name of copyright owner]
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * CDDL HEADER END
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Use is subject to license terms.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright (c) 2010, Intel Corporation.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * All rights reserved.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * DR memory support routines.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/note.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/debug.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/types.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/errno.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/param.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/kmem.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/kobj.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/conf.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/dditypes.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/ddi.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/sunddi.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/sunndi.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/ddi_impldefs.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/ndi_impldefs.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/sysmacros.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/machsystm.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/promif.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/lgrp.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/mem_config.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <vm/seg_kmem.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <vm/page.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/dr.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/dr_util.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/drmach.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuextern struct memlist *phys_install;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* TODO: push this reference below drmach line */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuextern int kcage_on;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* for the DR*INTERNAL_ERROR macros. see sys/dr.h. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic char *dr_ie_fmt = "dr_mem_acpi.c %d";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void dr_init_mem_unit_data(dr_mem_unit_t *mp);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * dr_mem_unit_t.sbm_flags
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define DR_MFLAG_RESERVED 0x01 /* mem unit reserved for delete */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define DR_MFLAG_SOURCE 0x02 /* source brd of copy/rename op */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define DR_MFLAG_TARGET 0x04 /* target brd of copy/rename op */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define DR_MFLAG_RELOWNER 0x20 /* memory release (delete) owner */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define DR_MFLAG_RELDONE 0x40 /* memory release (delete) done */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* helper macros */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define _ptob64(p) ((uint64_t)(p) << PAGESHIFT)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define _b64top(b) ((pgcnt_t)((b) >> PAGESHIFT))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic struct memlist *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_get_memlist(dr_mem_unit_t *mp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct memlist *mlist = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sbd_error_t *err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu static fn_t f = "dr_get_memlist";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s for %s...\n", f, mp->sbm_cm.sbdev_path);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Return cached memlist, if present.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * This memlist will be present following an
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * unconfigure (a.k.a: detach) of this memunit.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * It should only be used in the case were a configure
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * is bringing this memunit back in without going
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * through the disconnect and connect states.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mp->sbm_mlist) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: found cached memlist\n", f);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mlist = memlist_dup(mp->sbm_mlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu uint64_t basepa = _ptob64(mp->sbm_basepfn);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* attempt to construct a memlist using phys_install */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* round down to slice base address */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu basepa &= ~mp->sbm_alignment_mask;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* get a copy of phys_install to edit */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_read_lock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mlist = memlist_dup(phys_install);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_read_unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* trim lower irrelevant span */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mlist)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mlist = memlist_del_span(mlist, 0ull, basepa);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* trim upper irrelevant span */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mlist) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu uint64_t endpa, toppa;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu toppa = mp->sbm_slice_top;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu endpa = _ptob64(physmax + 1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (endpa > toppa)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mlist = memlist_del_span(
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mlist, toppa,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu endpa - toppa);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mlist) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* successfully built a memlist */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: derived memlist from phys_install\n", f);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* if no mlist yet, try platform layer */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (!mlist) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = drmach_mem_get_memlist(
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_cm.sbdev_id, &mlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mlist = NULL; /* paranoia */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: memlist for %s\n", f, mp->sbm_cm.sbdev_path);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEMLIST_DUMP(mlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (mlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuvoid
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_release_mem(dr_common_unit_t *cp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuvoid
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_attach_mem(dr_handle_t *hp, dr_common_unit_t *cp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_mem_unit_t *mp = (dr_mem_unit_t *)cp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct memlist *ml, *mc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sbd_error_t *err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu static fn_t f = "dr_attach_mem";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu uint64_t dr_physmax;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s...\n", f);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_lock_status(hp->h_bd);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = drmach_configure(cp->sbdev_id, 0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_unlock_status(hp->h_bd);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu DRERR_SET_C(&cp->sbdev_error, &err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ml = dr_get_memlist(mp);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Skip memory with address above plat_dr_physmax or kpm_size */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_physmax = plat_dr_physmax ? ptob(plat_dr_physmax) : UINT64_MAX;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (kpm_size < dr_physmax)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_physmax = kpm_size;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ml = memlist_del_span(ml, dr_physmax, UINT64_MAX - dr_physmax);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (mc = ml; mc; mc = mc->ml_next) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int rv;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sbd_error_t *err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rv = kphysm_add_memory_dynamic(
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (pfn_t)btop(mc->ml_address),
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (pgcnt_t)btop(mc->ml_size));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (rv != KPHYSM_OK) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * translate kphysm error and
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * store in devlist error
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (rv) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case KPHYSM_ERESOURCE:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rv = ESBD_NOMEM;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case KPHYSM_EFAULT:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rv = ESBD_FAULT;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu default:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rv = ESBD_INTERNAL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (rv == ESBD_INTERNAL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu DR_DEV_INTERNAL_ERROR(&mp->sbm_cm);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_dev_err(CE_WARN, &mp->sbm_cm, rv);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = drmach_mem_add_span(
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_cm.sbdev_id, mc->ml_address, mc->ml_size);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_delete(ml);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_init_mem_unit_data(mp);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* back out if configure failed */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mp->sbm_cm.sbdev_error != NULL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_lock_status(hp->h_bd);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = drmach_unconfigure(cp->sbdev_id, 0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sbd_err_clear(&err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_unlock_status(hp->h_bd);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuvoid
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_detach_mem(dr_handle_t *hp, dr_common_unit_t *cp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * This routine acts as a wrapper for kphysm_del_span_query in order to
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * support potential memory holes in a board's physical address space.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * It calls kphysm_del_span_query for each node in a memlist and accumulates
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * the results in *mp.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_del_mlist_query(struct memlist *mlist, memquery_t *mp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int rv = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mlist == NULL)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cmn_err(CE_WARN, "dr_del_mlist_query: mlist=NULL\n");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->phys_pages = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->managed = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->nonrelocatable = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->first_nonrelocatable = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->last_nonrelocatable = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (rv);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * NOTE: This routine is only partially smart about multiple
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * mem-units. Need to make mem-status structure smart
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * about them also.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_mem_status(dr_handle_t *hp, dr_devset_t devset, sbd_dev_stat_t *dsp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int m, mix;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memquery_t mq;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_board_t *bp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_mem_unit_t *mp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sbd_mem_stat_t *msp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu static fn_t f = "dr_mem_status";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu bp = hp->h_bd;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu devset &= DR_DEVS_PRESENT(bp);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (m = mix = 0; m < MAX_MEM_UNITS_PER_BOARD; m++) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int rv;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sbd_error_t *err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu drmach_status_t pstat;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_mem_unit_t *p_mp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (DEVSET_IN_SET(devset, SBD_COMP_MEM, m) == 0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu continue;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp = dr_get_mem_unit(bp, m);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mp->sbm_cm.sbdev_state == DR_STATE_EMPTY) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* present, but not fully initialized */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu continue;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mp->sbm_cm.sbdev_id == (drmachid_t)0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu continue;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* fetch platform status */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = drmach_status(mp->sbm_cm.sbdev_id, &pstat);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu continue;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp = &dsp->d_mem;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu bzero((caddr_t)msp, sizeof (*msp));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) strlcpy(msp->ms_cm.c_id.c_name, pstat.type,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sizeof (msp->ms_cm.c_id.c_name));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cm.c_id.c_type = mp->sbm_cm.sbdev_type;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cm.c_id.c_unit = mp->sbm_cm.sbdev_unum;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cm.c_cond = mp->sbm_cm.sbdev_cond;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cm.c_busy = mp->sbm_cm.sbdev_busy | pstat.busy;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cm.c_time = mp->sbm_cm.sbdev_time;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cm.c_ostate = mp->sbm_cm.sbdev_ostate;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_totpages = mp->sbm_npages;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_basepfn = mp->sbm_basepfn;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_pageslost = mp->sbm_pageslost;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cage_enabled = kcage_on;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mp->sbm_flags & DR_MFLAG_RESERVED)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu p_mp = mp->sbm_peer;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu else
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu p_mp = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (p_mp == NULL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_peer_is_target = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_peer_ap_id[0] = '\0';
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else if (p_mp->sbm_flags & DR_MFLAG_RESERVED) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu char *minor;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * b_dip doesn't have to be held for ddi_pathname()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * because the board struct (dr_board_t) will be
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * destroyed before b_dip detaches.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) ddi_pathname(bp->b_dip, path);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu minor = strchr(p_mp->sbm_cm.sbdev_path, ':');
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) snprintf(msp->ms_peer_ap_id,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sizeof (msp->ms_peer_ap_id), "%s%s",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu path, (minor == NULL) ? "" : minor);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu kmem_free(path, MAXPATHLEN);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (p_mp->sbm_flags & DR_MFLAG_TARGET)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_peer_is_target = 1;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * kphysm_del_span_query can report non-reloc pages = total
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * pages for memory that is not yet configured
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mp->sbm_cm.sbdev_state != DR_STATE_UNCONFIGURED) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct memlist *ml;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ml = dr_get_memlist(mp);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rv = ml ? dr_del_mlist_query(ml, &mq) : -1;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_delete(ml);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (rv == KPHYSM_OK) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_managed_pages = mq.managed;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_noreloc_pages = mq.nonrelocatable;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_noreloc_first =
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mq.first_nonrelocatable;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_noreloc_last =
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mq.last_nonrelocatable;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cm.c_sflags = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mq.nonrelocatable &&
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu drmach_copy_rename_need_suspend(
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_cm.sbdev_id)) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu SBD_SET_SUSPEND(SBD_CMD_UNCONFIGURE,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cm.c_sflags);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: kphysm_del_span_query() = %d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu f, rv);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Check source unit state during copy-rename
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((mp->sbm_flags & DR_MFLAG_SOURCE) &&
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (mp->sbm_cm.sbdev_state == DR_STATE_UNREFERENCED ||
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_cm.sbdev_state == DR_STATE_RELEASE))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu msp->ms_cm.c_ostate = SBD_STAT_CONFIGURED;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mix++;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dsp++;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (mix);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_pre_attach_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int err_flag = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int d;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sbd_error_t *err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu static fn_t f = "dr_pre_attach_mem";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s...\n", f);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (d = 0; d < devnum; d++) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_mem_unit_t *mp = (dr_mem_unit_t *)devlist[d];
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_state_t state;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cmn_err(CE_CONT, "OS configure %s", mp->sbm_cm.sbdev_path);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu state = mp->sbm_cm.sbdev_state;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (state) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case DR_STATE_UNCONFIGURED:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: recovering from UNCONFIG for %s\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu f, mp->sbm_cm.sbdev_path);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* use memlist cached by dr_post_detach_mem_unit */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ASSERT(mp->sbm_mlist != NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: re-configuring cached memlist for %s:\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu f, mp->sbm_cm.sbdev_path);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEMLIST_DUMP(mp->sbm_mlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* kphysm del handle should be have been freed */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ASSERT((mp->sbm_flags & DR_MFLAG_RELOWNER) == 0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*FALLTHROUGH*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case DR_STATE_CONNECTED:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: reprogramming mem hardware on %s\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu f, mp->sbm_cm.sbdev_bp->b_path);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: enabling %s\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu f, mp->sbm_cm.sbdev_path);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = drmach_mem_enable(mp->sbm_cm.sbdev_id);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err_flag = 1;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu default:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_dev_err(CE_WARN, &mp->sbm_cm, ESBD_STATE);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err_flag = 1;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* exit for loop if error encountered */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err_flag)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (err_flag ? -1 : 0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_post_attach_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int d;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu static fn_t f = "dr_post_attach_mem";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s...\n", f);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (d = 0; d < devnum; d++) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_mem_unit_t *mp = (dr_mem_unit_t *)devlist[d];
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct memlist *mlist, *ml;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mlist = dr_get_memlist(mp);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Verify the memory really did successfully attach
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * by checking for its existence in phys_install.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_read_lock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (memlist_intersect(phys_install, mlist) == 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_read_unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu DR_DEV_INTERNAL_ERROR(&mp->sbm_cm);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: %s memlist not in phys_install",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu f, mp->sbm_cm.sbdev_path);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_delete(mlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu continue;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_read_unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (ml = mlist; ml != NULL; ml = ml->ml_next) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sbd_error_t *err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = drmach_mem_add_span(
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_cm.sbdev_id,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ml->ml_address,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ml->ml_size);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_delete(mlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Destroy cached memlist, if any.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * There will be a cached memlist in sbm_mlist if
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * this board is being configured directly after
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * an unconfigure.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * To support this transition, dr_post_detach_mem
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * left a copy of the last known memlist in sbm_mlist.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * This memlist could differ from any derived from
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * hardware if while this memunit was last configured
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * the system detected and deleted bad pages from
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * phys_install. The location of those bad pages
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * will be reflected in the cached memlist.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mp->sbm_mlist) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memlist_delete(mp->sbm_mlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_mlist = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_pre_detach_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (-1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_post_detach_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (-1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Successful return from this function will have the memory
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * handle in bp->b_dev[..mem-unit...].sbm_memhandle allocated
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * and waiting. This routine's job is to select the memory that
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * actually has to be released (detached) which may not necessarily
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * be the same memory node that came in in devlist[],
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * i.e. a copy-rename is needed.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_pre_release_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (-1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuvoid
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_release_mem_done(dr_common_unit_t *cp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_disconnect_mem(dr_mem_unit_t *mp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (-1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_cancel_mem(dr_mem_unit_t *s_mp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (-1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuvoid
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_init_mem_unit(dr_mem_unit_t *mp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_state_t new_state;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (DR_DEV_IS_ATTACHED(&mp->sbm_cm)) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu new_state = DR_STATE_CONFIGURED;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_cm.sbdev_cond = SBD_COND_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else if (DR_DEV_IS_PRESENT(&mp->sbm_cm)) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu new_state = DR_STATE_CONNECTED;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_cm.sbdev_cond = SBD_COND_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else if (mp->sbm_cm.sbdev_id != (drmachid_t)0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu new_state = DR_STATE_OCCUPIED;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu new_state = DR_STATE_EMPTY;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (DR_DEV_IS_PRESENT(&mp->sbm_cm))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_init_mem_unit_data(mp);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* delay transition until fully initialized */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu dr_device_transition(&mp->sbm_cm, new_state);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudr_init_mem_unit_data(dr_mem_unit_t *mp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu drmachid_t id = mp->sbm_cm.sbdev_id;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu drmach_mem_info_t minfo;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sbd_error_t *err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu static fn_t f = "dr_init_mem_unit_data";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s...\n", f);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* a little sanity checking */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ASSERT(mp->sbm_peer == NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ASSERT(mp->sbm_flags == 0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err = drmach_mem_get_info(id, &minfo)) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_basepfn = _b64top(minfo.mi_basepa);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_npages = _b64top(minfo.mi_size);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_alignment_mask = minfo.mi_alignment_mask;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_slice_base = minfo.mi_slice_base;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_slice_top = minfo.mi_slice_top;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mp->sbm_slice_size = minfo.mi_slice_size;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu PR_MEM("%s: %s (basepfn = 0x%lx, npgs = %ld)\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu f, mp->sbm_cm.sbdev_path, mp->sbm_basepfn, mp->sbm_npages);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}