/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/sysmacros.h>
/*
* Platform-specific support for lgroups common to sun4 based platforms.
*
* Those sun4 platforms wanting default lgroup behavior build with
* MAX_MEM_NODES = 1. Those sun4 platforms wanting other than default
* lgroup behavior build with MAX_MEM_NODES > 1 and provide unique
* definitions to replace the #pragma weak interfaces.
*/
/*
* For now, there are 0 or 1 memnodes per lgroup on sun4 based platforms,
* plus the root lgroup.
*/
/*
* Allocate lgrp and lgrp stat arrays statically.
*/
static int nlgrps_alloc;
/*
* Arrays mapping lgroup handles to memnodes and vice versa. This helps
* manage a copy-rename operation during DR, which moves memory from one
*/
void plat_assign_lgrphand_to_mem_node(lgrp_handle_t, int);
/*
* Default sun4 lgroup interfaces which should be overriden
* by platform module.
*/
extern void plat_lgrp_init(void);
extern lgrp_handle_t plat_lgrp_root_hand(void);
int mpo_disabled = 0;
void
{
int i;
switch (stage) {
case LGRP_INIT_STAGE1:
/*
* Initialize lookup tables to invalid values so we catch
* any illegal use of them.
*/
for (i = 0; i < MAX_MEM_NODES; i++) {
memnode_to_lgrphand[i] = -1;
lgrphand_to_memnode[i] = -1;
}
if (lgrp_topo_ht_limit() == 1) {
max_mem_nodes = 1;
return;
}
if (&plat_lgrp_cpu_to_hand)
if (&plat_lgrp_init)
break;
default:
break;
}
}
/* ARGSUSED */
void
{
if (max_mem_nodes == 1)
return;
if (&plat_lgrp_config) {
}
}
{
return (plat_lgrp_cpu_to_hand(id));
else
return (LGRP_DEFAULT_HANDLE);
}
/*
* Lgroup interfaces common to all sun4 platforms.
*/
/*
* Return the platform handle of the lgroup that contains the physical memory
* corresponding to the given page frame number
*/
{
int mnode;
return (LGRP_DEFAULT_HANDLE);
return (LGRP_NULL_HANDLE);
if (mnode < 0)
return (LGRP_NULL_HANDLE);
return (MEM_NODE_2_LGRPHAND(mnode));
}
/*
* Return the maximum number of supported lgroups
*/
int
lgrp_plat_max_lgrps(void)
{
return (NLGRP);
}
/*
* Return the number of free pages in an lgroup.
*
* For query of LGRP_MEM_SIZE_FREE, return the number of base pagesize
* pages on freelists. For query of LGRP_MEM_SIZE_AVAIL, return the
* number of allocatable base pagesize pages corresponding to the
* lgroup (e.g. do not include page_t's, BOP_ALLOC()'ed memory, ..)
* For query of LGRP_MEM_SIZE_INSTALL, return the amount of physical
* memory installed, regardless of whether or not it's usable.
*/
{
int mnode;
extern struct memlist *phys_avail;
extern struct memlist *phys_install;
if (plathand != LGRP_NULL_HANDLE) {
switch (query) {
case LGRP_MEM_SIZE_FREE:
break;
case LGRP_MEM_SIZE_AVAIL:
break;
case LGRP_MEM_SIZE_INSTALL:
break;
default:
break;
}
}
}
return (npgs);
}
/*
* Return latency between "from" and "to" lgroups
* If "from" or "to" is LGRP_NONE, then just return latency within other
* lgroup. This latency number can only be used for relative comparison
* between lgroups on the running system, cannot be used across platforms,
* and may not reflect the actual latency. It is platform and implementation
* specific, so platform gets to decide its value.
*/
int
{
else
return (0);
}
/*
* Return platform handle for root lgroup
*/
lgrp_plat_root_hand(void)
{
if (&plat_lgrp_root_hand)
return (plat_lgrp_root_hand());
else
return (LGRP_DEFAULT_HANDLE);
}
/* Internal interfaces */
/*
* Return the number of free, allocatable, or installed
* pages in an lgroup
* This is a copy of the MAX_MEM_NODES == 1 version of the routine
* used when MPO is disabled (i.e. single lgroup)
*/
/* ARGSUSED */
static pgcnt_t
{
extern struct memlist *phys_install;
extern struct memlist *phys_avail;
switch (query) {
case LGRP_MEM_SIZE_FREE:
case LGRP_MEM_SIZE_AVAIL:
return (npgs);
case LGRP_MEM_SIZE_INSTALL:
return (npgs);
default:
return ((pgcnt_t)0);
}
}
/*
* Return the memnode associated with the specified lgroup handle
*/
int
{
int mnode;
return (-1);
/*
* We should always receive a valid pointer to a platform
* handle, as we can not choose the allocation policy in
* this layer.
*/
return (mnode);
}
{
return (lgrp_default_handle);
return (memnode_to_lgrphand[mnode]);
}
void
{
return;
}
lgrp_t *
{
return (NULL);
return (lgrp);
}