2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#include <stdlib.h>
2N/A#include <unistd.h>
2N/A#include <errno.h>
2N/A#include <sys/types.h>
2N/A#include <sys/mman.h>
2N/A#include "libproc.h"
2N/A#include "Pcontrol.h"
2N/A#include "Putil.h"
2N/A
2N/A
2N/Aint
2N/Apr_meminfo(struct ps_prochandle *Pr, const uint64_t *addrs,
2N/A int addr_count, const uint_t *info, int info_count,
2N/A uint64_t *outdata, uint_t *validity)
2N/A{
2N/A
2N/A
2N/A int error;
2N/A sysret_t rval;
2N/A argdes_t argd[7];
2N/A argdes_t *adp = &argd[0];
2N/A struct meminfo m;
2N/A#ifdef _LP64
2N/A struct meminfo32 m32;
2N/A int model;
2N/A#endif
2N/A int retval = -1;
2N/A uintptr_t inaddr, infoaddr, outaddr, validityaddr;
2N/A size_t outarraysize, infoarraysize;
2N/A size_t inarraysize, validityarraysize;
2N/A size_t totalsize;
2N/A char *totalmap = MAP_FAILED;
2N/A
2N/A inarraysize = addr_count * sizeof (uint64_t);
2N/A outarraysize = sizeof (uint64_t) * addr_count * info_count;
2N/A infoarraysize = info_count * sizeof (uint_t);
2N/A validityarraysize = sizeof (uint_t) * addr_count;
2N/A
2N/A
2N/A totalsize = inarraysize + outarraysize + infoarraysize +
2N/A validityarraysize;
2N/A
2N/A if ((totalmap = pr_zmap(Pr, 0, totalsize, PROT_READ | PROT_WRITE,
2N/A MAP_PRIVATE)) == MAP_FAILED) {
2N/A dprintf("pr_meminfo: mmap failed\n");
2N/A goto out;
2N/A }
2N/A
2N/A inaddr = (uintptr_t)totalmap;
2N/A
2N/A outaddr = inaddr + inarraysize;
2N/A
2N/A infoaddr = outaddr + outarraysize;
2N/A
2N/A validityaddr = infoaddr + infoarraysize;
2N/A
2N/A if (Pwrite(Pr, addrs, inarraysize, inaddr) != inarraysize) {
2N/A dprintf("pr_meminfo: Pwrite inaddr failed \n");
2N/A goto out;
2N/A }
2N/A
2N/A if (Pwrite(Pr, info, infoarraysize, infoaddr) !=
2N/A infoarraysize) {
2N/A dprintf("pr_meminfo: Pwrite info failed \n");
2N/A goto out;
2N/A }
2N/A
2N/A#ifdef _LP64
2N/A model = Pr->status.pr_dmodel;
2N/A if (model == PR_MODEL_ILP32) {
2N/A m32.mi_info_count = info_count;
2N/A m32.mi_inaddr = (caddr32_t)inaddr;
2N/A m32.mi_outdata = (caddr32_t)outaddr;
2N/A m32.mi_info_req = (caddr32_t)infoaddr;
2N/A m32.mi_validity = (caddr32_t)validityaddr;
2N/A } else
2N/A#endif
2N/A {
2N/A m.mi_info_count = info_count;
2N/A m.mi_inaddr = (uint64_t *)inaddr;
2N/A m.mi_outdata = (uint64_t *)outaddr;
2N/A m.mi_info_req = (uint_t *)infoaddr;
2N/A m.mi_validity = (uint_t *)validityaddr;
2N/A }
2N/A
2N/A
2N/A /*
2N/A * initial command
2N/A */
2N/A
2N/A adp->arg_value = MISYS_MEMINFO;
2N/A adp->arg_object = NULL;
2N/A adp->arg_type = AT_BYVAL;
2N/A adp->arg_inout = AI_INPUT;
2N/A adp->arg_size = 0;
2N/A adp++;
2N/A
2N/A /*
2N/A * length of input address vector
2N/A */
2N/A
2N/A adp->arg_value = addr_count;
2N/A adp->arg_object = NULL;
2N/A adp->arg_type = AT_BYVAL;
2N/A adp->arg_inout = AI_INPUT;
2N/A adp->arg_size = 0;
2N/A adp++;
2N/A
2N/A /*
2N/A * information wanted vector
2N/A */
2N/A
2N/A adp->arg_value = 0;
2N/A#ifdef _LP64
2N/A if (model == PR_MODEL_ILP32) {
2N/A adp->arg_object = &m32;
2N/A adp->arg_size = sizeof (struct meminfo32);
2N/A } else
2N/A#endif
2N/A {
2N/A adp->arg_object = &m;
2N/A adp->arg_size = sizeof (struct meminfo);
2N/A }
2N/A adp->arg_type = AT_BYREF;
2N/A adp->arg_inout = AI_INPUT;
2N/A
2N/A
2N/A error = Psyscall(Pr, &rval, SYS_meminfosys, 3, &argd[0]);
2N/A
2N/A if (error) {
2N/A errno = (error > 0) ? error: ENOSYS;
2N/A goto out;
2N/A }
2N/A
2N/A /* syscall was successful, copy out the data */
2N/A
2N/A if ((Pread(Pr, outdata, outarraysize, outaddr)) != outarraysize) {
2N/A dprintf("pr_meminfo: Pread of outarray failed\n");
2N/A goto out;
2N/A }
2N/A
2N/A if (Pread(Pr, validity, validityarraysize, validityaddr)
2N/A != validityarraysize) {
2N/A dprintf("pr_meminfo: Pread of validity array failed\n");
2N/A goto out;
2N/A }
2N/A
2N/A retval = rval.sys_rval1;
2N/A
2N/Aout:
2N/A
2N/A if (totalmap != MAP_FAILED &&
2N/A pr_munmap(Pr, totalmap, totalsize) == -1) {
2N/A dprintf("pr_meminfo: munmap failed\n");
2N/A retval = -1;
2N/A }
2N/A
2N/A return (retval);
2N/A
2N/A}