1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 #include <sys/cpuvar.h>
  29 #include <sys/kdi_impl.h>
  30 #include <sys/reboot.h>
  31 #include <sys/errno.h>
  32 #include <sys/atomic.h>
  33 #include <sys/kmem.h>
  34 
  35 kdi_debugvec_t  *kdi_dvec;
  36 struct modctl   *kdi_dmods;
  37 
  38 static kdi_dtrace_state_t kdi_dtrace_state = KDI_DTSTATE_IDLE;
  39 
  40 void
  41 kdi_dvec_vmready(void)
  42 {
  43         kdi_dvec->dv_kctl_vmready();
  44         kdi_dvec->dv_vmready();
  45 }
  46 
  47 void
  48 kdi_dvec_memavail(void)
  49 {
  50         /*
  51          * The driver will allocate more memory (if requested), and will call
  52          * dv_memavail itself.
  53          */
  54         kdi_dvec->dv_kctl_memavail();
  55 }
  56 
  57 #if defined(__x86)
  58 void
  59 kdi_dvec_handle_fault(greg_t trapno, greg_t pc, greg_t sp, int cpuid)
  60 {
  61         kdi_dvec->dv_handle_fault(trapno, pc, sp, cpuid);
  62 }
  63 #endif
  64 
  65 #if defined(__sparc)
  66 /*
  67  * Called on the CPU being initialized
  68  */
  69 void
  70 kdi_dvec_cpu_init(struct cpu *cp)
  71 {
  72         kdi_dvec->dv_kctl_cpu_init();
  73         kdi_dvec->dv_cpu_init(cp);
  74 }
  75 
  76 void
  77 kdi_dvec_cpr_restart(void)
  78 {
  79         kdi_dvec->dv_kctl_cpu_init();
  80         kdi_dvec->dv_cpr_restart();
  81 }
  82 #endif  /* __sparc */
  83 
  84 void
  85 kdi_dvec_modavail(void)
  86 {
  87         kdi_dvec->dv_kctl_modavail();
  88 }
  89 
  90 void
  91 kdi_dvec_thravail(void)
  92 {
  93         kdi_dvec->dv_kctl_thravail();
  94 }
  95 
  96 void
  97 kdi_dvec_mod_loaded(struct modctl *modp)
  98 {
  99         kdi_dvec->dv_mod_loaded(modp);
 100 }
 101 
 102 void
 103 kdi_dvec_mod_unloading(struct modctl *modp)
 104 {
 105         kdi_dvec->dv_mod_unloading(modp);
 106 }
 107 
 108 kdi_dtrace_state_t
 109 kdi_dtrace_get_state(void)
 110 {
 111         return (kdi_dtrace_state);
 112 }
 113 
 114 int
 115 kdi_dtrace_set(kdi_dtrace_set_t transition)
 116 {
 117         kdi_dtrace_state_t new, cur;
 118 
 119         do {
 120                 cur = kdi_dtrace_state;
 121 
 122                 switch (transition) {
 123                 case KDI_DTSET_DTRACE_ACTIVATE:
 124                         if (cur == KDI_DTSTATE_KMDB_BPT_ACTIVE)
 125                                 return (EBUSY);
 126                         if (cur == KDI_DTSTATE_DTRACE_ACTIVE)
 127                                 return (0);
 128                         new = KDI_DTSTATE_DTRACE_ACTIVE;
 129                         break;
 130                 case KDI_DTSET_DTRACE_DEACTIVATE:
 131                         if (cur == KDI_DTSTATE_KMDB_BPT_ACTIVE)
 132                                 return (EBUSY);
 133                         if (cur == KDI_DTSTATE_IDLE)
 134                                 return (0);
 135                         new = KDI_DTSTATE_IDLE;
 136                         break;
 137                 case KDI_DTSET_KMDB_BPT_ACTIVATE:
 138                         if (cur == KDI_DTSTATE_DTRACE_ACTIVE)
 139                                 return (EBUSY);
 140                         if (cur == KDI_DTSTATE_KMDB_BPT_ACTIVE)
 141                                 return (0);
 142                         new = KDI_DTSTATE_KMDB_BPT_ACTIVE;
 143                         break;
 144                 case KDI_DTSET_KMDB_BPT_DEACTIVATE:
 145                         if (cur == KDI_DTSTATE_DTRACE_ACTIVE)
 146                                 return (EBUSY);
 147                         if (cur == KDI_DTSTATE_IDLE)
 148                                 return (0);
 149                         new = KDI_DTSTATE_IDLE;
 150                         break;
 151                 default:
 152                         return (EINVAL);
 153                 }
 154         } while (cas32((uint_t *)&kdi_dtrace_state, cur, new) != cur);
 155 
 156         return (0);
 157 }