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 /* 29 * SPARC-specific portions of the KDI 30 */ 31 32 #include <sys/types.h> 33 #include <sys/kdi_impl.h> 34 35 #include <kmdb/kaif.h> 36 #include <kmdb/kmdb_dpi.h> 37 #include <kmdb/kmdb_promif.h> 38 #include <mdb/mdb_debug.h> 39 #include <mdb/mdb_err.h> 40 #include <mdb/mdb.h> 41 42 #define KDI_XC_RETRIES 10 43 44 static size_t kdi_dcache_size; 45 static size_t kdi_dcache_linesize; 46 static size_t kdi_icache_size; 47 static size_t kdi_icache_linesize; 48 49 static uint_t kdi_max_cpu_freq; 50 static uint_t kdi_sticks_per_usec; 51 52 /* XXX needs to go into a header */ 53 54 void 55 kdi_usecwait(clock_t n) 56 { 57 mdb.m_kdi->mkdi_tickwait(n * kdi_sticks_per_usec); 58 } 59 60 static int 61 kdi_cpu_ready_iter(int (*cb)(int, void *), void *arg) 62 { 63 return (mdb.m_kdi->mkdi_cpu_ready_iter(cb, arg)); 64 } 65 66 static int 67 kdi_xc_one(int cpuid, void (*cb)(void)) 68 { 69 return (mdb.m_kdi->mkdi_xc_one(cpuid, (void (*)())cb, NULL, NULL)); 70 } 71 72 /*ARGSUSED1*/ 73 static int 74 kdi_init_cpus_cb(pnode_t node, void *arg, void *result) 75 { 76 /* 77 * Sun4v dosen't support virtual address cache 78 */ 79 #ifndef sun4v 80 int dcache_size, dcache_linesize; 81 int icache_size, icache_linesize; 82 #endif 83 int cpu_freq; 84 85 #ifndef sun4v 86 /* Get the real cpu property node if needed */ 87 node = kmdb_prom_getcpu_propnode(node); 88 89 /* 90 * data cache 91 */ 92 93 if (kmdb_prom_getprop(node, "dcache-size", 94 (caddr_t)&dcache_size) == -1 && 95 kmdb_prom_getprop(node, "l1-dcache-size", 96 (caddr_t)&dcache_size) == -1) 97 fail("can't get dcache size for node %x\n", node); 98 99 if (kdi_dcache_size == 0 || dcache_size > kdi_dcache_size) 100 kdi_dcache_size = dcache_size; 101 102 if (kmdb_prom_getprop(node, "dcache-line-size", 103 (caddr_t)&dcache_linesize) == -1 && 104 kmdb_prom_getprop(node, "l1-dcache-line-size", 105 (caddr_t)&dcache_linesize) == -1) 106 fail("can't get dcache line size for node %x\n", node); 107 108 if (kdi_dcache_linesize == 0 || dcache_linesize < kdi_dcache_linesize) 109 kdi_dcache_linesize = dcache_linesize; 110 111 /* 112 * instruction cache 113 */ 114 115 if (kmdb_prom_getprop(node, "icache-size", 116 (caddr_t)&icache_size) == -1 && 117 kmdb_prom_getprop(node, "l1-icache-size", 118 (caddr_t)&icache_size) == -1) 119 fail("can't get icache size for node %x\n", node); 120 121 if (kdi_icache_size == 0 || icache_size > kdi_icache_size) 122 kdi_icache_size = icache_size; 123 124 if (kmdb_prom_getprop(node, "icache-line-size", 125 (caddr_t)&icache_linesize) == -1 && 126 kmdb_prom_getprop(node, "l1-icache-line-size", 127 (caddr_t)&icache_linesize) == -1) 128 fail("can't get icache size for node %x\n", node); 129 130 if (kdi_icache_linesize == 0 || icache_linesize < kdi_icache_linesize) 131 kdi_icache_linesize = icache_linesize; 132 #endif 133 134 if (kmdb_prom_getprop(node, "clock-frequency", 135 (caddr_t)&cpu_freq) == -1) { 136 fail("can't get cpu frequency for node %x\n", node); 137 } 138 139 kdi_max_cpu_freq = MAX(kdi_max_cpu_freq, cpu_freq); 140 141 return (0); 142 } 143 144 /* 145 * Called on an individual CPU. Tries to send it off to the state saver if it 146 * hasn't already entered the debugger. Returns non-zero if it *fails* to stop 147 * the CPU. 148 */ 149 static int 150 kdi_halt_cpu(int cpuid, void *state_saverp) 151 { 152 void (*state_saver)(void) = (void (*)(void))state_saverp; 153 int state = kmdb_dpi_get_cpu_state(cpuid); 154 const char *msg; 155 int rc = 0; 156 int res; 157 158 if (state != DPI_CPU_STATE_MASTER && state != DPI_CPU_STATE_SLAVE) { 159 res = kdi_xc_one(cpuid, state_saver); 160 rc = 1; 161 162 if (res == KDI_XC_RES_OK) 163 msg = "accepted the"; 164 else { 165 if (res == KDI_XC_RES_BUSY) 166 msg = "too busy for"; 167 else if (res == KDI_XC_RES_NACK) 168 msg = "NACKED the"; 169 else 170 msg = "errored the"; 171 } 172 mdb_dprintf(MDB_DBG_KDI, "CPU %d %s halt\n", cpuid, msg); 173 } 174 175 return (rc); 176 } 177 178 /*ARGSUSED1*/ 179 static int 180 kdi_report_unhalted(int cpuid, void *junk) 181 { 182 int state = kmdb_dpi_get_cpu_state(cpuid); 183 184 if (state != DPI_CPU_STATE_MASTER && state != DPI_CPU_STATE_SLAVE) 185 mdb_warn("CPU %d: stop failed\n", cpuid); 186 187 return (0); 188 } 189 190 /*ARGSUSED*/ 191 void 192 kmdb_kdi_stop_slaves(int my_cpuid, int doxc) 193 { 194 int i; 195 196 for (i = 0; i < KDI_XC_RETRIES; i++) { 197 if (kdi_cpu_ready_iter(kdi_halt_cpu, 198 (void *)kaif_slave_entry) == 0) 199 break; 200 201 kdi_usecwait(2000); 202 } 203 (void) kdi_cpu_ready_iter(kdi_report_unhalted, NULL); 204 } 205 206 void 207 kmdb_kdi_start_slaves(void) 208 { 209 } 210 211 void 212 kmdb_kdi_slave_wait(void) 213 { 214 } 215 216 int 217 kmdb_kdi_get_stick(uint64_t *stickp) 218 { 219 return (mdb.m_kdi->mkdi_get_stick(stickp)); 220 } 221 222 caddr_t 223 kmdb_kdi_get_trap_vatotte(void) 224 { 225 return ((caddr_t)mdb.m_kdi->mkdi_trap_vatotte); 226 } 227 228 void 229 kmdb_kdi_kernpanic(struct regs *regs, uint_t tt) 230 { 231 uintptr_t args[2]; 232 233 args[0] = (uintptr_t)regs; 234 args[1] = tt; 235 236 (void) kmdb_dpi_call((uintptr_t)mdb.m_kdi->mkdi_kernpanic, 2, args); 237 } 238 239 /*ARGSUSED*/ 240 void 241 kmdb_kdi_init_isadep(kdi_t *kdi, kmdb_auxv_t *kav) 242 { 243 kdi_dcache_size = kdi_dcache_linesize = 244 kdi_icache_size = kdi_icache_linesize = 0; 245 246 kdi_max_cpu_freq = kdi_sticks_per_usec = 0; 247 248 mdb_dprintf(MDB_DBG_KDI, "Initializing CPUs\n"); 249 250 kmdb_prom_walk_cpus(kdi_init_cpus_cb, NULL, NULL); 251 252 /* 253 * If we can't find one, guess high. The CPU frequency is going to be 254 * used to determine the length of various delays, such as the mondo 255 * interrupt retry delay. Too long is generally better than too short. 256 */ 257 if (kdi_max_cpu_freq == 0) { 258 mdb_dprintf(MDB_DBG_KDI, "No CPU freq found - assuming " 259 "500MHz\n"); 260 kdi_max_cpu_freq = 500 * MICROSEC; 261 } 262 263 kdi_sticks_per_usec = 264 MAX((kdi_max_cpu_freq + (MICROSEC - 1)) / MICROSEC, 1); 265 266 mdb.m_kdi->mkdi_cpu_init(kdi_dcache_size, kdi_dcache_linesize, 267 kdi_icache_size, kdi_icache_linesize); 268 269 #ifndef sun4v 270 kmdb_prom_preserve_kctx_init(); 271 #endif /* sun4v */ 272 273 } 274