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 #include <sys/cpuvar.h> 27 #include <sys/kdi_impl.h> 28 #include <sys/reboot.h> 29 #include <sys/errno.h> 30 #include <sys/atomic.h> 31 #include <sys/kmem.h> 32 33 kdi_debugvec_t *kdi_dvec; 34 struct modctl *kdi_dmods; 35 36 static kdi_dtrace_state_t kdi_dtrace_state = KDI_DTSTATE_IDLE; 37 38 void 39 kdi_dvec_vmready(void) 40 { 41 kdi_dvec->dv_kctl_vmready(); 42 kdi_dvec->dv_vmready(); 43 } 44 45 void 46 kdi_dvec_memavail(void) 47 { 48 /* 49 * The driver will allocate more memory (if requested), and will call 50 * dv_memavail itself. 51 */ 52 kdi_dvec->dv_kctl_memavail(); 53 } 54 55 #if defined(__x86) 56 void 57 kdi_dvec_handle_fault(greg_t trapno, greg_t pc, greg_t sp, int cpuid) 58 { 59 kdi_dvec->dv_handle_fault(trapno, pc, sp, cpuid); 60 } 61 #endif 62 63 #if defined(__sparc) 64 /* 65 * Called on the CPU being initialized 66 */ 67 void 68 kdi_dvec_cpu_init(struct cpu *cp) 69 { 70 kdi_dvec->dv_kctl_cpu_init(); 71 kdi_dvec->dv_cpu_init(cp); 72 } 73 74 void 75 kdi_dvec_cpr_restart(void) 76 { 77 kdi_dvec->dv_kctl_cpu_init(); 78 kdi_dvec->dv_cpr_restart(); 79 } 80 #endif /* __sparc */ 81 82 void 83 kdi_dvec_modavail(void) 84 { 85 kdi_dvec->dv_kctl_modavail(); 86 } 87 88 void 89 kdi_dvec_thravail(void) 90 { 91 kdi_dvec->dv_kctl_thravail(); 92 } 93 94 void 95 kdi_dvec_mod_loaded(struct modctl *modp) 96 { 97 kdi_dvec->dv_mod_loaded(modp); 98 } 99 100 void 101 kdi_dvec_mod_unloading(struct modctl *modp) 102 { 103 kdi_dvec->dv_mod_unloading(modp); 104 } 105 106 kdi_dtrace_state_t 107 kdi_dtrace_get_state(void) 108 { 109 return (kdi_dtrace_state); 110 } 111 112 int 113 kdi_dtrace_set(kdi_dtrace_set_t transition) 114 { 115 kdi_dtrace_state_t new, cur; 116 117 do { 118 cur = kdi_dtrace_state; 119 120 switch (transition) { 121 case KDI_DTSET_DTRACE_ACTIVATE: 122 if (cur == KDI_DTSTATE_KMDB_BPT_ACTIVE) 123 return (EBUSY); 124 if (cur == KDI_DTSTATE_DTRACE_ACTIVE) 125 return (0); 126 new = KDI_DTSTATE_DTRACE_ACTIVE; 127 break; 128 case KDI_DTSET_DTRACE_DEACTIVATE: 129 if (cur == KDI_DTSTATE_KMDB_BPT_ACTIVE) 130 return (EBUSY); 131 if (cur == KDI_DTSTATE_IDLE) 132 return (0); 133 new = KDI_DTSTATE_IDLE; 134 break; 135 case KDI_DTSET_KMDB_BPT_ACTIVATE: 136 if (cur == KDI_DTSTATE_DTRACE_ACTIVE) 137 return (EBUSY); 138 if (cur == KDI_DTSTATE_KMDB_BPT_ACTIVE) 139 return (0); 140 new = KDI_DTSTATE_KMDB_BPT_ACTIVE; 141 break; 142 case KDI_DTSET_KMDB_BPT_DEACTIVATE: 143 if (cur == KDI_DTSTATE_DTRACE_ACTIVE) 144 return (EBUSY); 145 if (cur == KDI_DTSTATE_IDLE) 146 return (0); 147 new = KDI_DTSTATE_IDLE; 148 break; 149 default: 150 return (EINVAL); 151 } 152 } while (atomic_cas_32((uint_t *)&kdi_dtrace_state, cur, new) != cur); 153 154 return (0); 155 } 156