home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
- /*
- * @OSF_COPYRIGHT@
- */
- /*
- * HISTORY
- *
- * Revision 1.1.1.1 1998/09/22 21:05:49 wsanchez
- * Import of Mac OS X kernel (~semeria)
- *
- * Revision 1.1.1.1 1998/03/07 02:26:08 wsanchez
- * Import of OSF Mach kernel (~mburg)
- *
- * Revision 1.1.5.1 1995/01/06 19:54:04 devrcs
- * mk6 CR668 - 1.3b26 merge
- * new file for mk6
- * [1994/10/12 22:25:34 dwm]
- *
- * Revision 1.1.2.1 1994/04/08 17:52:05 meissner
- * Add callback function to _profile_kgmon.
- * [1994/02/16 22:38:31 meissner]
- *
- * _profile_kgmon now returns pointer to area, doesn't do move itself.
- * [1994/02/11 16:52:17 meissner]
- *
- * Move all printfs into if (pv->debug) { ... } blocks.
- * Add debug printfs protected by if (pv->debug) for all error conditions.
- * Add code to reset profiling information.
- * Add code to get/set debug flag.
- * Expand copyright.
- * [1994/02/07 12:41:14 meissner]
- *
- * Add support to copy arbitrary regions.
- * Delete several of the KGMON_GET commands, now that arb. regions are supported.
- * Explicitly call _profile_update_stats before dumping vars or stats.
- * [1994/02/03 00:59:05 meissner]
- *
- * Combine _profile_{vars,stats,md}; Allow more than one _profile_vars.
- * [1994/02/01 12:04:09 meissner]
- *
- * CR 10198 - Initial version.
- * [1994/01/28 23:33:37 meissner]
- *
- * $EndLog$
- */
-
- #include <profiling/profile-internal.h>
-
- #ifdef MACH_KERNEL
- #include <profiling/machine/profile-md.h>
- #endif
-
- #ifndef PROFILE_VARS
- #define PROFILE_VARS(cpu) (&_profile_vars)
- #endif
-
- extern int printf(const char *, ...);
-
-
- /*
- * Kgmon interface. This returns the count of bytes moved if everything was ok,
- * or -1 if there were errors.
- */
-
- long
- _profile_kgmon(int write,
- size_t count,
- long indx,
- int max_cpus,
- void **p_ptr,
- void (*control_func)(kgmon_control_t))
- {
- kgmon_control_t kgmon;
- int cpu;
- int error = 0;
- int i;
- struct profile_vars *pv;
- static struct callback dummy_callback;
-
- *p_ptr = (void *)0;
-
- /*
- * If the number passed is not within bounds, just copy the data directly.
- */
-
- if (!LEGAL_KGMON(indx)) {
- *p_ptr = (void *)indx;
- if (!write) {
- if (PROFILE_VARS(0)->debug) {
- printf("_profile_kgmon: copy %5ld bytes, from 0x%lx\n",
- (long)count,
- (long)indx);
- }
-
- } else {
- if (PROFILE_VARS(0)->debug) {
- printf("_profile_kgmon: copy %5ld bytes, to 0x%lx\n",
- (long)count,
- (long)indx);
- }
- }
-
- return count;
- }
-
- /*
- * Decode the record number into the component pieces.
- */
-
- DECODE_KGMON(indx, kgmon, cpu);
-
- if (PROFILE_VARS(0)->debug) {
- printf("_profile_kgmon: start: kgmon control = %2d, cpu = %d, count = %ld\n",
- kgmon, cpu, (long)count);
- }
-
- /* Validate the CPU number */
- if (cpu < 0 || cpu >= max_cpus) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON, bad cpu %d\n", cpu);
- }
-
- return -1;
-
- } else {
- pv = PROFILE_VARS(cpu);
-
- if (!write) {
- switch (kgmon) {
- default:
- if (PROFILE_VARS(0)->debug) {
- printf("Unknown KGMON read command\n");
- }
-
- error = -1;
- break;
-
- case KGMON_GET_STATUS: /* return whether or not profiling is active */
- if (cpu != 0) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_GET_STATUS: cpu = %d\n", cpu);
- }
-
- error = -1;
- break;
- }
-
- if (count != sizeof(pv->active)) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_GET_STATUS: count = %ld, should be %ld\n",
- (long)count,
- (long)sizeof(pv->active));
- }
-
- error = -1;
- break;
- }
-
- *p_ptr = (void *)&pv->active;
- break;
-
- case KGMON_GET_DEBUG: /* return whether or not debugging is active */
- if (cpu != 0) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_GET_DEBUG: cpu = %d\n", cpu);
- }
-
- error = -1;
- break;
- }
-
- if (count != sizeof(pv->debug)) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_GET_DEBUG: count = %ld, should be %ld\n",
- (long)count,
- (long)sizeof(pv->active));
- }
-
- error = -1;
- break;
- }
-
- *p_ptr = (void *)&pv->debug;
- break;
-
- case KGMON_GET_PROFILE_VARS: /* return the _profile_vars structure */
- if (count != sizeof(struct profile_vars)) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_GET_PROFILE_VARS: count = %ld, should be %ld\n",
- (long)count,
- (long)sizeof(struct profile_vars));
- }
-
- error = -1;
- break;
- }
-
- _profile_update_stats(pv);
- *p_ptr = (void *)pv;
- break;
-
- case KGMON_GET_PROFILE_STATS: /* return the _profile_stats structure */
- if (count != sizeof(struct profile_stats)) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_GET_PROFILE_STATS: count = %ld, should be = %ld\n",
- (long)count,
- (long)sizeof(struct profile_stats));
- }
-
- error = -1;
- break;
- }
-
- _profile_update_stats(pv);
- *p_ptr = (void *)&pv->stats;
- break;
- }
-
- } else {
- switch (kgmon) {
- default:
- if (PROFILE_VARS(0)->debug) {
- printf("Unknown KGMON write command\n");
- }
-
- error = -1;
- break;
-
- case KGMON_SET_PROFILE_ON: /* turn on profiling */
- if (cpu != 0) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_SET_PROFILE_ON, cpu = %d\n", cpu);
- }
-
- error = -1;
- break;
- }
-
- if (!PROFILE_VARS(0)->active) {
- for (i = 0; i < max_cpus; i++) {
- PROFILE_VARS(i)->active = 1;
- }
-
- if (control_func) {
- (*control_func)(kgmon);
- }
-
- _profile_md_start();
- }
-
- count = 0;
- break;
-
- case KGMON_SET_PROFILE_OFF: /* turn off profiling */
- if (cpu != 0) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_SET_PROFILE_OFF, cpu = %d\n", cpu);
- }
-
- error = -1;
- break;
- }
-
- if (PROFILE_VARS(0)->active) {
- for (i = 0; i < max_cpus; i++) {
- PROFILE_VARS(i)->active = 0;
- }
-
- _profile_md_stop();
-
- if (control_func) {
- (*control_func)(kgmon);
- }
- }
-
- count = 0;
- break;
-
- case KGMON_SET_PROFILE_RESET: /* reset profiling */
- if (cpu != 0) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_SET_PROFILE_RESET, cpu = %d\n", cpu);
- }
-
- error = -1;
- break;
- }
-
- for (i = 0; i < max_cpus; i++) {
- _profile_reset(PROFILE_VARS(i));
- }
-
- if (control_func) {
- (*control_func)(kgmon);
- }
-
- count = 0;
- break;
-
- case KGMON_SET_DEBUG_ON: /* turn on profiling */
- if (cpu != 0) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_SET_DEBUG_ON, cpu = %d\n", cpu);
- }
-
- error = -1;
- break;
- }
-
- if (!PROFILE_VARS(0)->debug) {
- for (i = 0; i < max_cpus; i++) {
- PROFILE_VARS(i)->debug = 1;
- }
-
- if (control_func) {
- (*control_func)(kgmon);
- }
- }
-
- count = 0;
- break;
-
- case KGMON_SET_DEBUG_OFF: /* turn off profiling */
- if (cpu != 0) {
- if (PROFILE_VARS(0)->debug) {
- printf("KGMON_SET_DEBUG_OFF, cpu = %d\n", cpu);
- }
-
- error = -1;
- break;
- }
-
- if (PROFILE_VARS(0)->debug) {
- for (i = 0; i < max_cpus; i++) {
- PROFILE_VARS(i)->debug = 0;
- }
-
- if (control_func) {
- (*control_func)(kgmon);
- }
- }
-
- count = 0;
- break;
- }
- }
- }
-
- if (error) {
- if (PROFILE_VARS(0)->debug) {
- printf("_profile_kgmon: done: kgmon control = %2d, cpu = %d, error = %d\n",
- kgmon, cpu, error);
- }
-
- return -1;
- }
-
- if (PROFILE_VARS(0)->debug) {
- printf("_profile_kgmon: done: kgmon control = %2d, cpu = %d, count = %ld\n",
- kgmon, cpu, (long)count);
- }
-
- return count;
- }
-