1/***********************license start*************** 2 * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights 3 * reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 18 * * Neither the name of Cavium Networks nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written 21 * permission. 22 23 * This Software, including technical data, may be subject to U.S. export control 24 * laws, including the U.S. Export Administration Act and its associated 25 * regulations, and may be subject to export or import regulations in other 26 * countries. 27 28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR 30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38 ***********************license end**************************************/ 39 40 41/* 42 * @file 43 * 44 * Interface to debug exception handler 45 * 46 * <hr>$Revision: 50060 $<hr> 47 */ 48 49#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 50#include <linux/module.h> 51#include <asm/octeon/octeon.h> 52#include <asm/octeon/cvmx.h> 53#include <asm/octeon/cvmx-debug.h> 54#include <asm/octeon/cvmx-core.h> 55#include <asm/octeon/cvmx-bootmem.h> 56#include <asm/octeon/octeon-boot-info.h> 57#else 58#include <stdint.h> 59#include "executive-config.h" 60#include "cvmx.h" 61#include "cvmx-debug.h" 62#include "cvmx-bootmem.h" 63#include "cvmx-core.h" 64#include "cvmx-coremask.h" 65 66#ifndef __OCTEON_NEWLIB__ 67#include "../../bootloader/u-boot/include/octeon_mem_map.h" 68#else 69#include "octeon-boot-info.h" 70#endif 71 72#endif 73 74#ifdef CVMX_DEBUG_LOGGING 75# undef CVMX_DEBUG_LOGGING 76# define CVMX_DEBUG_LOGGING 1 77#else 78# define CVMX_DEBUG_LOGGING 0 79#endif 80 81#ifndef CVMX_DEBUG_ATTACH 82# define CVMX_DEBUG_ATTACH 1 83#endif 84 85#define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_STATUS (0xFFFFFFFFFF301000ull) 86#define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF301100ull + 0x100 * (num)) 87#define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF301108ull + 0x100 * (num)) 88#define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ASID(num) (0xFFFFFFFFFF301110ull + 0x100 * (num)) 89#define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF301118ull + 0x100 * (num)) 90 91#define CVMX_DEBUG_HW_DATA_BREAKPOINT_STATUS (0xFFFFFFFFFF302000ull) 92#define CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF302100ull + 0x100 * (num)) 93#define CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF302108ull + 0x100 * (num)) 94#define CVMX_DEBUG_HW_DATA_BREAKPOINT_ASID(num) (0xFFFFFFFFFF302110ull + 0x100 * (num)) 95#define CVMX_DEBUG_HW_DATA_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF302118ull + 0x100 * (num)) 96 97#define ERET_INSN 0x42000018U /* Hexcode for eret */ 98#define ISR_DELAY_COUNTER 120000000 /* Could be tuned down */ 99 100extern cvmx_debug_comm_t cvmx_debug_uart_comm; 101extern cvmx_debug_comm_t cvmx_debug_remote_comm; 102static const cvmx_debug_comm_t *cvmx_debug_comms[COMM_SIZE] = {&cvmx_debug_uart_comm, &cvmx_debug_remote_comm}; 103 104 105 106static cvmx_debug_globals_t *cvmx_debug_globals; 107 108/** 109 * @file 110 * 111 */ 112 113#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 114uint64_t __cvmx_debug_save_regs_area[32]; 115 116volatile uint64_t __cvmx_debug_mode_exception_ignore; 117volatile uint64_t __cvmx_debug_mode_exception_occured; 118 119static char cvmx_debug_stack[8*1024] __attribute ((aligned (16))); 120char *__cvmx_debug_stack_top = &cvmx_debug_stack[8*1024]; 121 122#ifndef __OCTEON_NEWLIB__ 123extern int cvmx_interrupt_in_isr; 124#else 125#define cvmx_interrupt_in_isr 0 126#endif 127 128#else 129uint64_t __cvmx_debug_save_regs_area_all[OCTEON_NUM_CORES][32]; 130#define __cvmx_debug_save_regs_area __cvmx_debug_save_regs_area_all[cvmx_get_core_num()] 131 132volatile uint64_t __cvmx_debug_mode_exception_ignore_all[OCTEON_NUM_CORES]; 133#define __cvmx_debug_mode_exception_ignore __cvmx_debug_mode_exception_ignore_all[cvmx_get_core_num()] 134volatile uint64_t __cvmx_debug_mode_exception_occured_all[OCTEON_NUM_CORES]; 135#define __cvmx_debug_mode_exception_occured __cvmx_debug_mode_exception_occured_all[cvmx_get_core_num()] 136 137static char cvmx_debug_stack_all[OCTEON_NUM_CORES][8*1024] __attribute ((aligned (16))); 138char *__cvmx_debug_stack_top_all[OCTEON_NUM_CORES]; 139 140#define cvmx_interrupt_in_isr 0 141 142#endif 143 144 145static inline uint32_t cvmx_debug_core_mask(void) 146{ 147#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 148#ifdef __OCTEON_NEWLIB__ 149 extern int __octeon_core_mask; 150 return __octeon_core_mask; 151#endif 152return cvmx_sysinfo_get()->core_mask; 153#else 154return octeon_get_boot_coremask (); 155#endif 156} 157 158static inline void cvmx_debug_update_state(cvmx_debug_state_t state) 159{ 160 memcpy(cvmx_debug_globals->state, &state, sizeof(cvmx_debug_state_t)); 161} 162 163static inline cvmx_debug_state_t cvmx_debug_get_state(void) 164{ 165 cvmx_debug_state_t state; 166 memcpy(&state, cvmx_debug_globals->state, sizeof(cvmx_debug_state_t)); 167 return state; 168} 169 170static void cvmx_debug_printf(char *format, ...) __attribute__((format(__printf__, 1, 2))); 171static void cvmx_debug_printf(char *format, ...) 172{ 173 va_list ap; 174 175 if (!CVMX_DEBUG_LOGGING) 176 return; 177 178 va_start(ap, format); 179 cvmx_dvprintf(format, ap); 180 va_end(ap); 181} 182 183static inline int __cvmx_debug_in_focus(cvmx_debug_state_t state, unsigned core) 184{ 185 return state.focus_core == core; 186} 187 188static void cvmx_debug_install_handler(unsigned core) 189{ 190 extern void __cvmx_debug_handler_stage2(void); 191 int32_t *trampoline = CASTPTR(int32_t, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, BOOTLOADER_DEBUG_TRAMPOLINE_CORE)); 192 trampoline += core; 193 194 *trampoline = (int32_t)(long)&__cvmx_debug_handler_stage2; 195 196 cvmx_debug_printf("Debug handled installed on core %d at %p\n", core, trampoline); 197} 198 199static int cvmx_debug_enabled(void) 200{ 201 return cvmx_debug_booted() || CVMX_DEBUG_ATTACH; 202} 203 204static void cvmx_debug_init_globals(void) 205{ 206 int toclear = 0; 207 uint64_t phys; 208 void *a; 209 210 if (cvmx_debug_globals) 211 return; 212 213 if (cvmx_get_core_num() != 0) 214 { 215 volatile size_t i; 216 /* Delay here just enough for the writing of the version. */ 217 for(i = 0; i < sizeof(cvmx_debug_globals_t)/2 + 8; i++) 218 ; 219 } 220 221 a = cvmx_bootmem_alloc_named(sizeof(cvmx_debug_globals_t), 8, CVMX_DEBUG_GLOBALS_BLOCK_NAME); 222 if (a) 223 { 224 phys = cvmx_ptr_to_phys(a); 225 toclear = 1; 226 } 227 else 228 { 229 const cvmx_bootmem_named_block_desc_t *debug_globals_nblk; 230 debug_globals_nblk = cvmx_bootmem_find_named_block (CVMX_DEBUG_GLOBALS_BLOCK_NAME); 231 phys = debug_globals_nblk->base_addr; 232 } 233 cvmx_debug_globals = CASTPTR(cvmx_debug_globals_t, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, phys)); 234 cvmx_debug_printf("Debug named block at %p\n", cvmx_debug_globals); 235 if (toclear) 236 cvmx_debug_printf("Debug named block cleared\n"); 237 238 if (toclear) 239 { 240 memset (cvmx_debug_globals, 0, sizeof(cvmx_debug_globals_t)); 241 cvmx_debug_globals->version = CVMX_DEBUG_GLOBALS_VERSION; 242 cvmx_debug_globals->tlb_entries = cvmx_core_get_tlb_entries(); 243 } 244 else 245 { 246 volatile size_t i; 247 /* Delay here just enough for the writing of the version. */ 248 for(i = 0; i < sizeof(cvmx_debug_globals_t) + 8; i++) 249 ; 250 } 251} 252 253 254static void cvmx_debug_globals_check_version(void) 255{ 256 if (cvmx_debug_globals->version != CVMX_DEBUG_GLOBALS_VERSION) 257 { 258 cvmx_dprintf("Wrong version on the globals struct spinining; expected %d, got: %d.\n", (int)CVMX_DEBUG_GLOBALS_VERSION, (int)(cvmx_debug_globals->version)); 259#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 260 panic("Wrong version.\n"); 261#endif 262 while (1) 263 ; 264 } 265} 266 267static inline volatile cvmx_debug_core_context_t *cvmx_debug_core_context(void); 268static inline void cvmx_debug_save_core_context(volatile cvmx_debug_core_context_t *context); 269 270void cvmx_debug_init(void) 271{ 272 cvmx_debug_state_t state; 273 int core; 274 const cvmx_debug_comm_t *comm; 275 cvmx_spinlock_t *lock; 276 unsigned int coremask = cvmx_debug_core_mask(); 277 278 if (!cvmx_debug_enabled()) 279 return; 280 281 cvmx_debug_init_globals(); 282 283#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 284 // Put a barrier until all cores have got to this point. 285 cvmx_coremask_barrier_sync(coremask); 286#endif 287 cvmx_debug_globals_check_version(); 288 289 290 comm = cvmx_debug_comms[cvmx_debug_globals->comm_type]; 291 lock = &cvmx_debug_globals->lock; 292 293 core = cvmx_get_core_num(); 294#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 295 /* Install the debugger handler on the cores. */ 296 { 297 int core1 = 0; 298 for (core1 = 0; core1 < OCTEON_NUM_CORES; core1++) 299 { 300 if ((1<<core1) & coremask) 301 cvmx_debug_install_handler(core1); 302 } 303 } 304#else 305 cvmx_debug_install_handler(core); 306#endif 307 308 if (comm->init) 309 comm->init(); 310 311 { 312 cvmx_spinlock_lock(lock); 313 state = cvmx_debug_get_state(); 314#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 315 state.known_cores |= coremask; 316 state.core_finished &= ~coremask; 317#else 318 state.known_cores |= (1 << core); 319 state.core_finished &= ~(1 << core); 320#endif 321 cvmx_debug_update_state(state); 322 cvmx_spinlock_unlock(lock); 323 } 324 325#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 326 // Put a barrier until all cores have got to this point. 327 cvmx_coremask_barrier_sync(coremask); 328 329 if (cvmx_coremask_first_core(coremask)) 330#endif 331 { 332 cvmx_debug_printf("cvmx_debug_init core: %d\n", core); 333 state = cvmx_debug_get_state(); 334 state.focus_core = core; 335 state.active_cores = state.known_cores; 336 state.focus_switch = 1; 337 state.step_isr = 1; 338 cvmx_debug_printf("Known cores at init: 0x%x\n", (int)state.known_cores); 339 cvmx_debug_update_state(state); 340 341 /* Initialize __cvmx_debug_stack_top_all. */ 342#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 343 { 344 int i; 345 for (i = 0; i < OCTEON_NUM_CORES; i++) 346 __cvmx_debug_stack_top_all[i] = &cvmx_debug_stack_all[i][8*1024]; 347 } 348#endif 349 cvmx_debug_globals->init_complete = 1; 350 CVMX_SYNCW; 351 } 352 while (!cvmx_debug_globals->init_complete) 353 { 354 /* Spin waiting for init to complete */ 355 } 356 357 if (cvmx_debug_booted()) 358 cvmx_debug_trigger_exception(); 359 360 /* Install the break handler after might tripper the debugger exception. */ 361#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 362 if (cvmx_coremask_first_core(coremask)) 363#endif 364 { 365 if (comm->install_break_handler) 366 comm->install_break_handler(); 367 } 368} 369 370static int cvmx_debug_putpacket_noformat(char *packet); 371 372static __attribute__ ((format (printf, 1, 2))) int cvmx_debug_putpacket(char *format, ...) 373{ 374 va_list ap; 375 size_t n; 376 char packet[CVMX_DEBUG_MAX_RESPONSE_SIZE]; 377 378 if (cvmx_debug_comms[cvmx_debug_globals->comm_type]->putpacket == NULL) 379 return 0; 380 381 va_start(ap, format); 382 n = vsnprintf(packet, sizeof(packet), format, ap); 383 va_end(ap); 384 385 if (n >= sizeof(packet)) 386 { 387 cvmx_debug_printf("packet truncated (needed %d bytes): %s\n", (int)n, packet); 388 return 0; 389 } 390 return cvmx_debug_putpacket_noformat(packet); 391} 392 393static int cvmx_debug_putpacket_noformat(char *packet) 394{ 395 if (cvmx_debug_comms[cvmx_debug_globals->comm_type]->putpacket == NULL) 396 return 0; 397 cvmx_debug_printf("Reply: %s\n", packet); 398 return cvmx_debug_comms[cvmx_debug_globals->comm_type]->putpacket(packet); 399} 400 401static int cvmx_debug_active_core(cvmx_debug_state_t state, int core) 402{ 403 return state.active_cores & (1 << core); 404} 405 406static volatile cvmx_debug_core_context_t *cvmx_debug_core_context(void) 407{ 408 return &cvmx_debug_globals->contextes[cvmx_get_core_num()]; 409} 410 411static volatile uint64_t *cvmx_debug_regnum_to_context_ref(int regnum, volatile cvmx_debug_core_context_t *context) 412{ 413 /* Must be kept in sync with mips_octeon_reg_names in gdb/mips-tdep.c. */ 414 if (regnum < 32) 415 return &context->regs[regnum]; 416 switch (regnum) 417 { 418 case 32: return &context->cop0.status; 419 case 33: return &context->lo; 420 case 34: return &context->hi; 421 case 35: return &context->cop0.badvaddr; 422 case 36: return &context->cop0.cause; 423 case 37: return &context->cop0.depc; 424 default: return NULL; 425 } 426} 427 428static int cvmx_debug_probe_load(unsigned char *ptr, unsigned char *result) 429{ 430 volatile unsigned char *p = ptr; 431 int ok; 432 unsigned char tem; 433 434 { 435 __cvmx_debug_mode_exception_ignore = 1; 436 __cvmx_debug_mode_exception_occured = 0; 437 /* We don't handle debug-mode exceptions in delay slots. Avoid them. */ 438 asm volatile (".set push \n\t" 439 ".set noreorder \n\t" 440 "nop \n\t" 441 "lbu %0, %1 \n\t" 442 "nop \n\t" 443 ".set pop" : "=r"(tem) : "m"(*p)); 444 ok = __cvmx_debug_mode_exception_occured == 0; 445 __cvmx_debug_mode_exception_ignore = 0; 446 __cvmx_debug_mode_exception_occured = 0; 447 *result = tem; 448 } 449 return ok; 450} 451 452static int cvmx_debug_probe_store(unsigned char *ptr) 453{ 454 volatile unsigned char *p = ptr; 455 int ok; 456 457 __cvmx_debug_mode_exception_ignore = 1; 458 __cvmx_debug_mode_exception_occured = 0; 459 /* We don't handle debug-mode exceptions in delay slots. Avoid them. */ 460 asm volatile (".set push \n\t" 461 ".set noreorder \n\t" 462 "nop \n\t" 463 "sb $0, %0 \n\t" 464 "nop \n\t" 465 ".set pop" : "=m"(*p)); 466 ok = __cvmx_debug_mode_exception_occured == 0; 467 468 __cvmx_debug_mode_exception_ignore = 0; 469 __cvmx_debug_mode_exception_occured = 0; 470 return ok; 471} 472 473/* Put the hex value of t into str. */ 474static void strhex(char *str, unsigned char t) 475{ 476 char a[] = "0123456789ABCDEF"; 477 str[0] = a[(t>>4)]; 478 str[1] = a[t&0xF]; 479 str[2] = 0; 480} 481 482/** 483 * Initialize the performance counter control registers. 484 * 485 */ 486static void cvmx_debug_set_perf_control_reg (int perf_event, int perf_counter) 487{ 488 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context(); 489 cvmx_core_perf_control_t control; 490 491 control.u32 = 0; 492 control.s.u = 1; 493 control.s.s = 1; 494 control.s.k = 1; 495 control.s.ex = 1; 496 control.s.w = 1; 497 control.s.m = 1 - perf_counter; 498 control.s.event = perf_event; 499 500 context->cop0.perfctrl[perf_counter] = control.u32; 501} 502 503static cvmx_debug_command_t cvmx_debug_process_packet(char *packet) 504{ 505 const char *buf = packet; 506 cvmx_debug_command_t result = COMMAND_NOP; 507 cvmx_debug_state_t state = cvmx_debug_get_state(); 508 509 /* A one letter command code represents what to do. */ 510 switch (*buf++) 511 { 512 case '?': /* What protocol do I speak? */ 513 cvmx_debug_putpacket_noformat("S0A"); 514 break; 515 516 case '\003': /* Control-C */ 517 cvmx_debug_putpacket_noformat("T9"); 518 break; 519 520 case 'F': /* Change the focus core */ 521 { 522 int core; 523 sscanf(buf, "%x", &core); 524 525 /* Only cores in the exception handler may become the focus. 526 If a core not in the exception handler got focus the 527 debugger would hang since nobody would talk to it. */ 528 if (state.handler_cores & (1 << core)) 529 { 530 /* Focus change reply must be sent before the focus 531 changes. Otherwise the new focus core will eat our ACK 532 from the debugger. */ 533 cvmx_debug_putpacket("F%02x", core); 534 cvmx_debug_comms[cvmx_debug_globals->comm_type]->change_core(state.focus_core, core); 535 state.focus_core = core; 536 cvmx_debug_update_state(state); 537 break; 538 } 539 else 540 cvmx_debug_putpacket_noformat("!Core is not in the exception handler. Focus not changed."); 541 /* Nothing changed, so we send back the old value */ 542 } 543 /* fall through */ 544 case 'f': /* Get the focus core */ 545 cvmx_debug_putpacket("F%02x", (unsigned)state.focus_core); 546 break; 547 548 case 'J': /* Set the flag for skip-over-isr in Single-Stepping mode */ 549 { 550 if (*buf == '1') 551 state.step_isr = 1; /* Step in ISR */ 552 else 553 state.step_isr = 0; /* Step over ISR */ 554 cvmx_debug_update_state(state); 555 } 556 /* Fall through. The reply to the set step-isr command is the 557 same as the get step-isr command */ 558 559 case 'j': /* Reply with step_isr status */ 560 cvmx_debug_putpacket("J%x", (unsigned)state.step_isr); 561 break; 562 563 564 case 'I': /* Set the active cores */ 565 { 566 long long active_cores; 567 sscanf(buf, "%llx", &active_cores); 568 /* Limit the active mask to the known to exist cores */ 569 state.active_cores = active_cores & state.known_cores; 570 571 /* Lazy user hack to have 0 be all cores */ 572 if (state.active_cores == 0) 573 state.active_cores = state.known_cores; 574 575 /* The focus core must be in the active_cores mask */ 576 if ((state.active_cores & (1 << state.focus_core)) == 0) 577 { 578 cvmx_debug_putpacket_noformat("!Focus core was added to the masked."); 579 state.active_cores |= 1 << state.focus_core; 580 } 581 582 cvmx_debug_update_state(state); 583 } 584 /* Fall through. The reply to the set active cores command is the 585 same as the get active cores command */ 586 587 case 'i': /* Get the active cores */ 588 cvmx_debug_putpacket("I%llx", (long long) state.active_cores); 589 break; 590 591 case 'A': /* Setting the step mode all or one */ 592 { 593 if (*buf == '1') 594 state.step_all = 1; /* A step or continue will start all cores */ 595 else 596 state.step_all = 0; /* A step or continue only affects the focus core */ 597 cvmx_debug_update_state(state); 598 } 599 /* Fall through. The reply to the set step-all command is the 600 same as the get step-all command */ 601 602 case 'a': /* Getting the current step mode */ 603 cvmx_debug_putpacket("A%x", (unsigned)state.step_all); 604 break; 605 606 case 'g': /* read a register from global place. */ 607 { 608 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context(); 609 int regno; 610 volatile uint64_t *reg; 611 612 /* Get the register number to read */ 613 sscanf(buf, "%x", ®no); 614 615 reg = cvmx_debug_regnum_to_context_ref(regno, context); 616 if (!reg) 617 cvmx_debug_printf("Register #%d is not valid\n", regno); 618 cvmx_debug_putpacket("%llx", (unsigned long long) *reg); 619 } 620 break; 621 622 case 'G': /* set the value of a register. */ 623 { 624 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context(); 625 int regno; 626 volatile uint64_t *reg; 627 long long value; 628 629 /* Get the register number to read */ 630 if (sscanf(buf, "%x,%llx", ®no, &value) != 2) 631 { 632 cvmx_debug_printf("G packet corrupt: %s\n", buf); 633 goto error_packet; 634 } 635 636 reg = cvmx_debug_regnum_to_context_ref(regno, context); 637 if (!reg) 638 { 639 cvmx_debug_printf("Register #%d is not valid\n", regno); 640 goto error_packet; 641 } 642 *reg = value; 643 } 644 break; 645 646 case 'm': /* Memory read. mAA..AA,LLLL Read LLLL bytes at address AA..AA */ 647 { 648 long long addr, i, length; 649 unsigned char *ptr; 650 char *reply; 651 652 if (sscanf(buf, "%llx,%llx", &addr, &length) != 2) 653 { 654 cvmx_debug_printf("m packet corrupt: %s\n", buf); 655 goto error_packet; 656 } 657 if (length >= 1024) 658 { 659 cvmx_debug_printf("m packet length out of range: %lld\n", length); 660 goto error_packet; 661 } 662 663 reply = __builtin_alloca(length * 2 + 1); 664 ptr = (unsigned char *)(long)addr; 665 for (i = 0; i < length; i++) 666 { 667 /* Probe memory. If not accessible fail. */ 668 unsigned char t; 669 if (!cvmx_debug_probe_load(&ptr[i], &t)) 670 goto error_packet; 671 strhex(&reply[i * 2], t); 672 } 673 cvmx_debug_putpacket_noformat(reply); 674 } 675 break; 676 677 case 'M': /* Memory write. MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ 678 { 679 long long addr, i, length; 680 unsigned char *ptr; 681 char value[1024]; 682 683 if (sscanf(buf, "%llx,%llx:%1024s", &addr, &length, value) != 3) 684 { 685 cvmx_debug_printf("M packet corrupt: %s\n", buf); 686 goto error_packet; 687 } 688 689 ptr = (unsigned char *)(long)addr; 690 for (i = 0; i < length; i++) 691 { 692 int c; 693 int n; 694 char tempstr[3] = {0, 0, 0}; 695 memcpy (tempstr, &value[i * 2], 2); 696 697 n = sscanf(tempstr, "%2x", &c); 698 if (n != 1) 699 { 700 cvmx_debug_printf("M packet corrupt: %s\n", &value[i * 2]); 701 goto error_packet; 702 } 703 /* Probe memory. If not accessible fail. */ 704 if (!cvmx_debug_probe_store(&ptr[i])) 705 { 706 cvmx_debug_printf("M cannot write: %p\n", &ptr[i]); 707 goto error_packet; 708 } 709 ptr[i] = c; 710 } 711 cvmx_debug_putpacket_noformat("+"); 712 } 713 break; 714 715 case 'e': /* Set/get performance counter events. e[1234]XX..X: [01] 716 is the performance counter to set X is the performance 717 event. [34] is to get the same thing. */ 718 { 719 int perf_event = 0; 720 int counter, encoded_counter; 721 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context(); 722 sscanf(buf, "%1d%x", &encoded_counter, &perf_event); 723 724 switch (encoded_counter) 725 { 726 case 1: /* Set performance counter0 event. */ 727 case 2: /* Set performance counter1 event. */ 728 729 counter = encoded_counter - 1; 730 context->cop0.perfval[counter] = 0; 731 cvmx_debug_set_perf_control_reg(perf_event, counter); 732 break; 733 734 case 3: /* Get performance counter0 event. */ 735 case 4: /* Get performance counter1 event. */ 736 { 737 cvmx_core_perf_control_t c; 738 counter = encoded_counter - 3; 739 /* Pass performance counter0 event and counter to 740 the debugger. */ 741 c.u32 = context->cop0.perfctrl[counter]; 742 cvmx_debug_putpacket("%llx,%llx", (long long) context->cop0.perfval[counter], (long long) c.s.event); 743 } 744 break; 745 } 746 } 747 break; 748 749#if 0 750 case 't': /* Return the trace buffer read data register contents. */ 751 { 752 uint64_t tra_data; 753 uint64_t tra_ctl; 754 char tmp[64]; 755 756 /* If trace buffer is disabled no trace data information is available. */ 757 if ((tra_ctl & 0x1) == 0) 758 { 759 cvmx_debug_putpacket_noformat("!Trace buffer not enabled\n"); 760 cvmx_debug_putpacket_noformat("t"); 761 } 762 else 763 { 764 cvmx_debug_putpacket_noformat("!Trace buffer is enabled\n"); 765 tra_data = cvmx_read_csr(OCTEON_TRA_READ_DATA); 766 mem2hex (&tra_data, tmp, 8); 767 strcpy (debug_output_buffer, "t"); 768 strcat (debug_output_buffer, tmp); 769 cvmx_debug_putpacket_noformat(debug_output_buffer); 770 } 771 } 772 break; 773#endif 774 775 case 'Z': /* Insert hardware breakpoint: Z[di]NN..N,AA.A, [di] data or 776 instruction, NN..Nth at address AA..A */ 777 { 778 enum type 779 { 780 WP_LOAD = 1, 781 WP_STORE = 2, 782 WP_ACCESS = 3 783 }; 784 785 int num, size; 786 long long addr; 787 enum type type; 788 char bp_type; 789 const int BE = 1, TE = 4; 790 int n; 791 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context(); 792 793 n = sscanf(buf, "%c%x,%llx,%x,%x", &bp_type, &num, &addr, &size, &type); 794 switch (bp_type) 795 { 796 case 'i': // Instruction hardware breakpoint 797 if (n != 3 || num > 4) 798 { 799 cvmx_debug_printf("Z packet corrupt: %s\n", buf); 800 goto error_packet; 801 } 802 803 context->hw_ibp.address[num] = addr; 804 context->hw_ibp.address_mask[num] = 0; 805 context->hw_ibp.asid[num] = 0; 806 context->hw_ibp.control[num] = BE | TE; 807 break; 808 809 case 'd': // Data hardware breakpoint 810 { 811 uint64_t dbc = 0xff0 | BE | TE; 812 uint64_t dbm; 813 if (n != 5 || num > 4) 814 { 815 cvmx_debug_printf("Z packet corrupt: %s\n", buf); 816 goto error_packet; 817 } 818 819 /* Set DBC[BE,TE,BLM]. */ 820 context->hw_dbp.address[num] = addr; 821 context->hw_dbp.asid[num] = 0; 822 823 dbc |= type == WP_STORE ? 0x1000 : type == WP_LOAD ? 0x2000 : 0; 824 /* Mask the bits depending on the size for 825 debugger to stop while accessing parts of the 826 memory location. */ 827 dbm = (size == 8) ? 0x7 : ((size == 4) ? 3 828 : (size == 2) ? 1 : 0); 829 context->hw_dbp.address_mask[num] = dbm; 830 context->hw_dbp.control[num] = dbc; 831 break; 832 } 833 default: 834 cvmx_debug_printf("z packet corrupt: %s\n", buf); 835 goto error_packet; 836 } 837 } 838 break; 839 840 case 'z': /* Remove hardware breakpoint: z[di]NN..N remove NN..Nth 841breakpoint. */ 842 { 843 int num; 844 char bp_type; 845 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context(); 846 847 if (sscanf(buf, "%c%x", &bp_type, &num) != 2 || num > 4) 848 { 849 cvmx_debug_printf("z packet corrupt: %s\n", buf); 850 goto error_packet; 851 } 852 853 switch (bp_type) 854 { 855 case 'i': // Instruction hardware breakpoint 856 context->hw_ibp.address[num] = 0; 857 context->hw_ibp.address_mask[num] = 0; 858 context->hw_ibp.asid[num] = 0; 859 context->hw_ibp.control[num] = 0; 860 break; 861 case 'd': // Data hardware breakpoint 862 context->hw_dbp.address[num] = 0; 863 context->hw_dbp.address_mask[num] = 0; 864 context->hw_dbp.asid[num] = 0; 865 context->hw_dbp.control[num] = 0; 866 break; 867 default: 868 cvmx_debug_printf("z packet corrupt: %s\n", buf); 869 goto error_packet; 870 } 871 } 872 break; 873 874 case 's': /* Single step. sAA..AA Step one instruction from AA..AA (optional) */ 875 result = COMMAND_STEP; 876 break; 877 878 case 'c': /* Continue. cAA..AA Continue at address AA..AA (optional) */ 879 result = COMMAND_CONTINUE; 880 break; 881 882 case '+': /* Don't know. I think it is a communications sync */ 883 /* Ignoring this command */ 884 break; 885 886 default: 887 cvmx_debug_printf("Unknown debug command: %s\n", buf - 1); 888error_packet: 889 cvmx_debug_putpacket_noformat("-"); 890 break; 891 } 892 893 return result; 894} 895 896static cvmx_debug_command_t cvmx_debug_process_next_packet(void) 897{ 898 char packet[CVMX_DEBUG_MAX_REQUEST_SIZE]; 899 if (cvmx_debug_comms[cvmx_debug_globals->comm_type]->getpacket(packet, CVMX_DEBUG_MAX_REQUEST_SIZE)) 900 { 901 cvmx_debug_printf("Request: %s\n", packet); 902 return cvmx_debug_process_packet(packet); 903 } 904 return COMMAND_NOP; 905} 906 907/* If a core isn't in the active core mask we need to start him up again. We 908 can only do this if the core didn't hit a breakpoint or single step. If the 909 core hit CVMX_CIU_DINT interrupt (generally happens when while executing 910 _exit() at the end of the program). Remove the core from known cores so 911 that when the cores in active core mask are done executing the program, the 912 focus will not be transfered to this core. */ 913 914static int cvmx_debug_stop_core(cvmx_debug_state_t state, unsigned core, cvmx_debug_register_t *debug_reg, int proxy) 915{ 916 if (!cvmx_debug_active_core(state, core) && !debug_reg->s.dbp && !debug_reg->s.dss && (debug_reg->s.dint != 1)) 917 { 918 debug_reg->s.sst = 0; 919 cvmx_debug_printf("Core #%d not in active cores, continuing.\n", core); 920 return 0; 921 } 922 if ((state.core_finished & (1<<core)) && proxy) 923 return 0; 924 return 1; 925} 926 927/* check to see if current exc is single-stepped and that no other exc 928 was also simultaneously noticed. */ 929static int cvmx_debug_single_step_exc(cvmx_debug_register_t *debug_reg) 930{ 931 if (debug_reg->s.dss && !debug_reg->s.dib && !debug_reg->s.dbp && !debug_reg->s.ddbs && !debug_reg->s.ddbl) 932 return 1; 933 return 0; 934} 935 936static void cvmx_debug_set_focus_core(cvmx_debug_state_t *state, int core) 937{ 938 if (state->ever_been_in_debug) 939 cvmx_debug_putpacket("!Core %2x taking focus.", core); 940 cvmx_debug_comms[cvmx_debug_globals->comm_type]->change_core (state->focus_core, core); 941 state->focus_core = core; 942} 943 944static void cvmx_debug_may_elect_as_focus_core(cvmx_debug_state_t *state, int core, cvmx_debug_register_t *debug_reg) 945{ 946 /* If another core has already elected itself as the focus core, we're late. */ 947 if (state->handler_cores & (1 << state->focus_core)) 948 return; 949 950 /* If we hit a breakpoint, elect ourselves. */ 951 if (debug_reg->s.dib || debug_reg->s.dbp || debug_reg->s.ddbs || debug_reg->s.ddbl) 952 cvmx_debug_set_focus_core(state, core); 953 954 /* It is possible the focus core has completed processing and exited the 955 program. When this happens the focus core will not be in 956 known_cores. If this is the case we need to elect a new focus. */ 957 if ((state->known_cores & (1 << state->focus_core)) == 0) 958 cvmx_debug_set_focus_core(state, core); 959} 960 961static void cvmx_debug_send_stop_reason(cvmx_debug_register_t *debug_reg, volatile cvmx_debug_core_context_t *context) 962{ 963 /* Handle Debug Data Breakpoint Store/Load Exception. */ 964 if (debug_reg->s.ddbs || debug_reg->s.ddbl) 965 cvmx_debug_putpacket("T8:%x", (int) context->hw_dbp.status); 966 else 967 cvmx_debug_putpacket_noformat("T9"); 968} 969 970 971static void cvmx_debug_clear_status(volatile cvmx_debug_core_context_t *context) 972{ 973 /* SW needs to clear the BreakStatus bits after a watchpoint is hit or on 974 reset. */ 975 context->hw_dbp.status &= ~0x3fff; 976 977 /* Clear MCD0, which is write-1-to-clear. */ 978 context->cop0.multicoredebug |= 1; 979} 980 981static void cvmx_debug_sync_up_cores(void) 982{ 983 cvmx_debug_state_t state; 984 do { 985 state = cvmx_debug_get_state(); 986 } while (state.step_all && state.handler_cores != 0); 987} 988 989/* Delay the focus core a little if it is likely another core needs to steal 990 focus. Once we enter the main loop focus can't be stolen */ 991static void cvmx_debug_delay_focus_core(cvmx_debug_state_t state, unsigned core, cvmx_debug_register_t *debug_reg) 992{ 993 volatile int i; 994 if (debug_reg->s.dss || debug_reg->s.dbp || core != state.focus_core) 995 return; 996 for (i = 0; i < 24000; i++) 997 { 998 asm volatile (".set push \n\t" 999 ".set noreorder \n\t" 1000 "nop \n\t" 1001 "nop \n\t" 1002 "nop \n\t" 1003 "nop \n\t" 1004 ".set pop"); 1005 /* Spin giving the breakpoint core time to steal focus */ 1006 } 1007 1008} 1009 1010/* If this core was single-stepping in a group, 1011 && it was not the last focus-core, 1012 && last focus-core happens to be inside an ISR, blocking focus-switch 1013 then burn some cycles, to avoid unnecessary focus toggles. */ 1014static void cvmx_debug_delay_isr_core(unsigned core, uint32_t depc, int single_stepped_exc_only, 1015 cvmx_debug_state_t state) 1016{ 1017 volatile uint64_t i; 1018 if(!single_stepped_exc_only || state.step_isr || core == state.focus_core || state.focus_switch) 1019 return; 1020 1021 cvmx_debug_printf ("Core #%u spinning for focus at 0x%x\n", core, (unsigned int)depc); 1022 1023 for(i = ISR_DELAY_COUNTER; i > 0 ; i--) 1024 { 1025 state = cvmx_debug_get_state(); 1026 /* Spin giving the focus core time to service ISR */ 1027 /* But cut short the loop, if we can. Shrink down i, only once. */ 1028 if (i > 600000 && state.focus_switch) 1029 i = 500000; 1030 } 1031 1032} 1033 1034static int cvmx_debug_perform_proxy(cvmx_debug_register_t *debug_reg, volatile cvmx_debug_core_context_t *context) 1035{ 1036 unsigned core = cvmx_get_core_num(); 1037 cvmx_debug_state_t state = cvmx_debug_get_state(); 1038 cvmx_debug_command_t command = COMMAND_NOP; 1039 int single_stepped_exc_only = cvmx_debug_single_step_exc (debug_reg); 1040 1041 /* All cores should respect the focus core if it has to 1042 stop focus switching while servicing an interrupt. 1043 If the system is single-stepping, then the following 1044 code path is valid. If the current core tripped on a 1045 break-point or some other error while going through 1046 an ISR, then we shouldn't be returning unconditionally. 1047 In that case (non-single-step case) we must enter 1048 the debugger exception stub fully. */ 1049 if (!state.step_isr && (cvmx_interrupt_in_isr || (context->cop0.status & 0x2ULL)) && single_stepped_exc_only) 1050 { 1051 cvmx_spinlock_lock(&cvmx_debug_globals->lock); 1052 state = cvmx_debug_get_state(); 1053 /* If this is the focus core, switch off focus switching 1054 till ISR_DELAY_COUNTER. This will let focus core 1055 keep the focus until the ISR is completed. */ 1056 if(state.focus_switch && core == state.focus_core) 1057 { 1058 cvmx_debug_printf ("Core #%u stopped focus stealing at 0x%llx\n", core, (unsigned long long)context->cop0.depc); 1059 state.focus_switch = 0; 1060 } 1061 /* Alow other cores to steal focus. 1062 Focus core has completed ISR. */ 1063 if (*(uint32_t*)((__SIZE_TYPE__)context->cop0.depc) == ERET_INSN && core == state.focus_core) 1064 { 1065 cvmx_debug_printf ("Core #%u resumed focus stealing at 0x%llx\n", core, (unsigned long long)context->cop0.depc); 1066 state.focus_switch = 1; 1067 } 1068 cvmx_debug_update_state(state); 1069 cvmx_spinlock_unlock(&cvmx_debug_globals->lock); 1070 cvmx_debug_printf ("Core #%u resumed skipping isr.\n", core); 1071 return 0; 1072 } 1073 1074 /* Delay the focus core a little if it is likely another core needs to 1075 steal focus. Once we enter the main loop focus can't be stolen */ 1076 cvmx_debug_delay_focus_core(state, core, debug_reg); 1077 1078 cvmx_debug_delay_isr_core (core, context->cop0.depc, single_stepped_exc_only, state); 1079 1080 /* The following section of code does two critical things. First, it 1081 populates the handler_cores bitmask of all cores in the exception 1082 handler. Only one core at a time can update this field. Second it 1083 changes the focus core if needed. */ 1084 { 1085 cvmx_debug_printf("Core #%d stopped\n", core); 1086 cvmx_spinlock_lock(&cvmx_debug_globals->lock); 1087 state = cvmx_debug_get_state(); 1088 1089 state.handler_cores |= (1 << core); 1090 cvmx_debug_may_elect_as_focus_core(&state, core, debug_reg); 1091 1092/* Push all updates before exiting the critical section */ 1093 state.focus_switch = 1; 1094 cvmx_debug_update_state(state); 1095 cvmx_spinlock_unlock(&cvmx_debug_globals->lock); 1096 } 1097 if (__cvmx_debug_in_focus(state, core)) 1098 cvmx_debug_send_stop_reason(debug_reg, context); 1099 1100 do { 1101 state = cvmx_debug_get_state(); 1102 /* Note the focus core can change in this loop. */ 1103 if (__cvmx_debug_in_focus(state, core)) 1104 { 1105 command = cvmx_debug_process_next_packet(); 1106 state = cvmx_debug_get_state(); 1107 /* When resuming let the other cores resume as well with 1108 step-all. */ 1109 if (command != COMMAND_NOP && state.step_all) 1110 { 1111 state.command = command; 1112 cvmx_debug_update_state(state); 1113 } 1114 } 1115 /* When steping all cores, update the non focus core's command too. */ 1116 else if (state.step_all) 1117 command = state.command; 1118 1119 /* If we did not get a command and the communication changed return, 1120 we are changing the communications. */ 1121 if (command == COMMAND_NOP && cvmx_debug_globals->comm_changed) 1122 { 1123 /* FIXME, this should a sync not based on cvmx_coremask_barrier_sync. */ 1124#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 1125 /* Sync up. */ 1126 cvmx_coremask_barrier_sync(state.handler_cores); 1127#endif 1128 return 1; 1129 } 1130 } while (command == COMMAND_NOP); 1131 1132 debug_reg->s.sst = command == COMMAND_STEP; 1133 cvmx_debug_printf("Core #%d running\n", core); 1134 1135 { 1136 cvmx_spinlock_lock(&cvmx_debug_globals->lock); 1137 state = cvmx_debug_get_state(); 1138 state.handler_cores ^= (1 << core); 1139 cvmx_debug_update_state(state); 1140 cvmx_spinlock_unlock(&cvmx_debug_globals->lock); 1141 } 1142 1143 cvmx_debug_sync_up_cores(); 1144 /* Now that all cores are out, reset the command. */ 1145 if (__cvmx_debug_in_focus(state, core)) 1146 { 1147 cvmx_spinlock_lock(&cvmx_debug_globals->lock); 1148 state = cvmx_debug_get_state(); 1149 state.command = COMMAND_NOP; 1150 cvmx_debug_update_state(state); 1151 cvmx_spinlock_unlock(&cvmx_debug_globals->lock); 1152 } 1153 return 0; 1154} 1155 1156static void cvmx_debug_save_core_context(volatile cvmx_debug_core_context_t *context) 1157{ 1158 unsigned i; 1159 memcpy((char *) context->regs, __cvmx_debug_save_regs_area, sizeof(context->regs)); 1160 asm("mflo %0" : "=r"(context->lo)); 1161 asm("mfhi %0" : "=r"(context->hi)); 1162 CVMX_MF_COP0(context->cop0.index, COP0_INDEX); 1163 CVMX_MF_COP0(context->cop0.entrylo[0], COP0_ENTRYLO0); 1164 CVMX_MF_COP0(context->cop0.entrylo[1], COP0_ENTRYLO1); 1165 CVMX_MF_COP0(context->cop0.entryhi, COP0_ENTRYHI); 1166 CVMX_MF_COP0(context->cop0.pagemask, COP0_PAGEMASK); 1167 CVMX_MF_COP0(context->cop0.status, COP0_STATUS); 1168 CVMX_MF_COP0(context->cop0.cause, COP0_CAUSE); 1169 CVMX_MF_COP0(context->cop0.debug, COP0_DEBUG); 1170 CVMX_MF_COP0(context->cop0.multicoredebug, COP0_MULTICOREDEBUG); 1171 CVMX_MF_COP0(context->cop0.perfval[0], COP0_PERFVALUE0); 1172 CVMX_MF_COP0(context->cop0.perfval[1], COP0_PERFVALUE1); 1173 CVMX_MF_COP0(context->cop0.perfctrl[0], COP0_PERFCONTROL0); 1174 CVMX_MF_COP0(context->cop0.perfctrl[1], COP0_PERFCONTROL1); 1175 /* Save DEPC and DESAVE since debug-mode exceptions (see 1176 debug_probe_{load,store}) can clobber these. */ 1177 CVMX_MF_COP0(context->cop0.depc, COP0_DEPC); 1178 CVMX_MF_COP0(context->cop0.desave, COP0_DESAVE); 1179 1180 context->hw_ibp.status = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_STATUS); 1181 for (i = 0; i < 4; i++) 1182 { 1183 context->hw_ibp.address[i] = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS(i)); 1184 context->hw_ibp.address_mask[i] = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(i)); 1185 context->hw_ibp.asid[i] = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ASID(i)); 1186 context->hw_ibp.control[i] = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_CONTROL(i)); 1187 } 1188 1189 context->hw_dbp.status = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_STATUS); 1190 for (i = 0; i < 4; i++) 1191 { 1192 context->hw_dbp.address[i] = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS(i)); 1193 context->hw_dbp.address_mask[i] = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS_MASK(i)); 1194 context->hw_dbp.asid[i] = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ASID(i)); 1195 context->hw_dbp.control[i] = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_CONTROL(i)); 1196 } 1197 1198 for (i = 0; i < cvmx_debug_globals->tlb_entries; i++) 1199 { 1200 CVMX_MT_COP0(i, COP0_INDEX); 1201 asm volatile ("tlbr"); 1202 CVMX_MF_COP0(context->tlbs[i].entrylo[0], COP0_ENTRYLO0); 1203 CVMX_MF_COP0(context->tlbs[i].entrylo[1], COP0_ENTRYLO1); 1204 CVMX_MF_COP0(context->tlbs[i].entryhi, COP0_ENTRYHI); 1205 CVMX_MF_COP0(context->tlbs[i].pagemask, COP0_PAGEMASK); 1206 } 1207 CVMX_SYNCW; 1208} 1209 1210static void cvmx_debug_restore_core_context(volatile cvmx_debug_core_context_t *context) 1211{ 1212 int i; 1213 memcpy(__cvmx_debug_save_regs_area, (char *) context->regs, sizeof(context->regs)); 1214 asm("mtlo %0" :: "r"(context->lo)); 1215 asm("mthi %0" :: "r"(context->hi)); 1216 /* We don't change the TLB so no need to restore it. */ 1217 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_STATUS, context->hw_dbp.status); 1218 for (i = 0; i < 4; i++) 1219 { 1220 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS(i), context->hw_dbp.address[i]); 1221 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS_MASK(i), context->hw_dbp.address_mask[i]); 1222 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ASID(i), context->hw_dbp.asid[i]); 1223 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_CONTROL(i), context->hw_dbp.control[i]); 1224 } 1225 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_STATUS, context->hw_ibp.status); 1226 for (i = 0; i < 4; i++) 1227 { 1228 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS(i), context->hw_ibp.address[i]); 1229 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(i), context->hw_ibp.address_mask[i]); 1230 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ASID(i), context->hw_ibp.asid[i]); 1231 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_CONTROL(i), context->hw_ibp.control[i]); 1232 } 1233 CVMX_MT_COP0(context->cop0.index, COP0_INDEX); 1234 CVMX_MT_COP0(context->cop0.entrylo[0], COP0_ENTRYLO0); 1235 CVMX_MT_COP0(context->cop0.entrylo[1], COP0_ENTRYLO1); 1236 CVMX_MT_COP0(context->cop0.entryhi, COP0_ENTRYHI); 1237 CVMX_MT_COP0(context->cop0.pagemask, COP0_PAGEMASK); 1238 CVMX_MT_COP0(context->cop0.status, COP0_STATUS); 1239 CVMX_MT_COP0(context->cop0.cause, COP0_CAUSE); 1240 CVMX_MT_COP0(context->cop0.debug, COP0_DEBUG); 1241 CVMX_MT_COP0(context->cop0.multicoredebug, COP0_MULTICOREDEBUG); 1242 CVMX_MT_COP0(context->cop0.perfval[0], COP0_PERFVALUE0); 1243 CVMX_MT_COP0(context->cop0.perfval[1], COP0_PERFVALUE1); 1244 CVMX_MT_COP0(context->cop0.perfctrl[0], COP0_PERFCONTROL0); 1245 CVMX_MT_COP0(context->cop0.perfctrl[1], COP0_PERFCONTROL1); 1246 CVMX_MT_COP0(context->cop0.depc, COP0_DEPC); 1247 CVMX_MT_COP0(context->cop0.desave, COP0_DESAVE); 1248} 1249 1250static inline void cvmx_debug_print_cause(volatile cvmx_debug_core_context_t *context) 1251{ 1252 if (!CVMX_DEBUG_LOGGING) 1253 return; 1254 if (context->cop0.multicoredebug & 1) 1255 cvmx_dprintf("MCD0 was pulsed\n"); 1256 if (context->cop0.multicoredebug & (1 << 16)) 1257 cvmx_dprintf("Exception %lld in Debug Mode\n", (long long)((context->cop0.debug >> 10) & 0x1f)); 1258 if (context->cop0.debug & (1 << 19)) 1259 cvmx_dprintf("DDBSImpr\n"); 1260 if (context->cop0.debug & (1 << 18)) 1261 cvmx_dprintf("DDBLImpr\n"); 1262 if (context->cop0.debug & (1 << 5)) 1263 cvmx_dprintf("DINT\n"); 1264 if (context->cop0.debug & (1 << 4)) 1265 cvmx_dprintf("Debug Instruction Breakpoint (DIB) exception\n"); 1266 if (context->cop0.debug & (1 << 3)) 1267 cvmx_dprintf("Debug Date Break Store (DDBS) exception\n"); 1268 if (context->cop0.debug & (1 << 2)) 1269 cvmx_dprintf("Debug Date Break Load (DDBL) exception\n"); 1270 if (context->cop0.debug & (1 << 1)) 1271 cvmx_dprintf("Debug Breakpoint (DBp) exception\n"); 1272 if (context->cop0.debug & (1 << 0)) 1273 cvmx_dprintf("Debug Single Step (DSS) exception\n"); 1274} 1275 1276void __cvmx_debug_handler_stage3 (void) 1277{ 1278 volatile cvmx_debug_core_context_t *context; 1279 int comms_changed = 0; 1280 1281 cvmx_debug_printf("Entering debug exception handler\n"); 1282 cvmx_debug_printf("Debug named block at %p\n", cvmx_debug_globals); 1283 if (__cvmx_debug_mode_exception_occured) 1284 { 1285 uint64_t depc; 1286 CVMX_MF_COP0(depc, COP0_DEPC); 1287 cvmx_dprintf("Unexpected debug-mode exception occured at 0x%llx, 0x%llx spinning\n", (long long) depc, (long long)(__cvmx_debug_mode_exception_occured)); 1288#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 1289 panic("Unexpected debug-mode exception occured at 0x%llx, 0x%llx\n", (long long) depc, (long long)(__cvmx_debug_mode_exception_occured)); 1290#endif 1291 while (1) 1292 ; 1293 } 1294 1295 context = cvmx_debug_core_context(); 1296 cvmx_debug_save_core_context(context); 1297 1298 { 1299 cvmx_debug_state_t state; 1300 cvmx_spinlock_lock(&cvmx_debug_globals->lock); 1301 state = cvmx_debug_get_state(); 1302 state.ever_been_in_debug = 1; 1303 cvmx_debug_update_state (state); 1304 cvmx_spinlock_unlock(&cvmx_debug_globals->lock); 1305 } 1306 cvmx_debug_print_cause(context); 1307 1308 do 1309 { 1310 int needs_proxy; 1311 comms_changed = 0; 1312 /* If the communication changes, change it. */ 1313 cvmx_spinlock_lock(&cvmx_debug_globals->lock); 1314 if (cvmx_debug_globals->comm_changed) 1315 { 1316 cvmx_debug_printf("Communication changed: %d\n", (int)cvmx_debug_globals->comm_changed); 1317 if (cvmx_debug_globals->comm_changed > COMM_SIZE) 1318 { 1319 cvmx_dprintf("Unknown communication spinning: %lld > %d.\n", (long long)cvmx_debug_globals->comm_changed, (int)(COMM_SIZE)); 1320#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 1321 panic("Unknown communication.\n"); 1322#endif 1323 while (1) 1324 ; 1325 } 1326 cvmx_debug_globals->comm_type = cvmx_debug_globals->comm_changed - 1; 1327 cvmx_debug_globals->comm_changed = 0; 1328 } 1329 cvmx_spinlock_unlock(&cvmx_debug_globals->lock); 1330 needs_proxy = cvmx_debug_comms[cvmx_debug_globals->comm_type]->needs_proxy; 1331 1332 { 1333 cvmx_debug_register_t debug_reg; 1334 cvmx_debug_state_t state; 1335 unsigned core = cvmx_get_core_num(); 1336 1337 state = cvmx_debug_get_state(); 1338 debug_reg.u64 = context->cop0.debug; 1339 /* All cores stop on any exception. See if we want nothing from this and 1340 it should resume. This needs to be done for non proxy based debugging 1341 so that some non active-cores can control the other cores. */ 1342 if (!cvmx_debug_stop_core(state, core, &debug_reg, needs_proxy)) 1343 { 1344 context->cop0.debug = debug_reg.u64; 1345 break; 1346 } 1347 } 1348 1349 if (needs_proxy) 1350 { 1351 cvmx_debug_register_t debug_reg; 1352 debug_reg.u64 = context->cop0.debug; 1353 cvmx_debug_printf("Starting to proxy\n"); 1354 comms_changed = cvmx_debug_perform_proxy(&debug_reg, context); 1355 context->cop0.debug = debug_reg.u64; 1356 } 1357 else 1358 { 1359 cvmx_debug_printf("Starting to wait for remote host\n"); 1360 cvmx_debug_comms[cvmx_debug_globals->comm_type]->wait_for_resume(context, cvmx_debug_get_state()); 1361 } 1362 } while (comms_changed); 1363 1364 cvmx_debug_clear_status(context); 1365 1366 cvmx_debug_restore_core_context(context); 1367 cvmx_debug_printf("Exiting debug exception handler\n"); 1368} 1369 1370void cvmx_debug_trigger_exception(void) 1371{ 1372 /* Set CVMX_CIU_DINT to enter debug exception handler. */ 1373 cvmx_write_csr (CVMX_CIU_DINT, 1 << cvmx_get_core_num ()); 1374 /* Perform an immediate read after every write to an RSL register to force 1375 the write to complete. It doesn't matter what RSL read we do, so we 1376 choose CVMX_MIO_BOOT_BIST_STAT because it is fast and harmless */ 1377 cvmx_read_csr (CVMX_MIO_BOOT_BIST_STAT); 1378} 1379 1380/** 1381 * Inform debugger about the end of the program. This is 1382 * called from crt0 after all the C cleanup code finishes. 1383 * Our current stack is the C one, not the debug exception 1384 * stack. */ 1385void cvmx_debug_finish(void) 1386{ 1387 unsigned coreid = cvmx_get_core_num(); 1388 cvmx_debug_state_t state; 1389 1390 cvmx_debug_printf ("Debug _exit reached!, core %d, cvmx_debug_globals = %p\n", coreid, cvmx_debug_globals); 1391 1392#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 1393 fflush (stdout); 1394 fflush (stderr); 1395#endif 1396 1397 cvmx_spinlock_lock(&cvmx_debug_globals->lock); 1398 state = cvmx_debug_get_state(); 1399 state.known_cores ^= (1 << coreid); 1400 state.core_finished |= (1<<coreid); 1401 cvmx_debug_update_state(state); 1402 1403 /* Tell the user the core has finished. */ 1404 if (state.ever_been_in_debug) 1405 cvmx_debug_putpacket("!Core %d finish.", coreid); 1406 1407 /* Notify the debugger if all cores have completed the program */ 1408 if ((cvmx_debug_core_mask () & state.core_finished) == cvmx_debug_core_mask ()) 1409 { 1410 cvmx_debug_printf("All cores done!\n"); 1411 if (state.ever_been_in_debug) 1412 cvmx_debug_putpacket_noformat("D0"); 1413 } 1414 if (state.focus_core == coreid && state.known_cores != 0) 1415 { 1416 /* Loop through cores looking for someone to handle interrupts. 1417 Since we already check that known_cores is non zero, this 1418 should always find a core */ 1419 unsigned newcore; 1420 for (newcore = 0; newcore < CVMX_DEBUG_MAX_CORES; newcore++) 1421 { 1422 if (state.known_cores & (1<<newcore)) 1423 { 1424 cvmx_debug_printf("Routing uart interrupts to Core #%u.\n", newcore); 1425 cvmx_debug_set_focus_core(&state, newcore); 1426 cvmx_debug_update_state(state); 1427 break; 1428 } 1429 } 1430 } 1431 cvmx_spinlock_unlock(&cvmx_debug_globals->lock); 1432 1433 /* If we ever been in the debug, report to it that we have exited the core. */ 1434 if (state.ever_been_in_debug) 1435 cvmx_debug_trigger_exception(); 1436} 1437