1 /***********************license start***************
2 * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
18 * * Neither the name of Cavium Inc. nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written
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
28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29 * AND WITH ALL FAULTS AND CAVIUM INC. 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**************************************/
44 * Interface to debug exception handler
45 * NOTE: CARE SHOULD BE TAKE WHEN USING STD C LIBRARY FUNCTIONS IN
46 * THIS FILE IF SOMEONE PUTS A BREAKPOINT ON THOSE FUNCTIONS
47 * DEBUGGING WILL FAIL.
49 * <hr>$Revision: 50060 $<hr>
52 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
53 #include <linux/module.h>
54 #include <asm/octeon/octeon.h>
55 #include <asm/octeon/cvmx.h>
56 #include <asm/octeon/cvmx-debug.h>
57 #include <asm/octeon/cvmx-core.h>
58 #include <asm/octeon/cvmx-bootmem.h>
59 #include <asm/octeon/octeon-boot-info.h>
63 #include "cvmx-debug.h"
64 #include "cvmx-bootmem.h"
65 #include "cvmx-core.h"
66 #include "cvmx-coremask.h"
67 #include "octeon-boot-info.h"
70 #ifdef CVMX_DEBUG_LOGGING
71 # undef CVMX_DEBUG_LOGGING
72 # define CVMX_DEBUG_LOGGING 1
74 # define CVMX_DEBUG_LOGGING 0
77 #ifndef CVMX_DEBUG_ATTACH
78 # define CVMX_DEBUG_ATTACH 1
81 #define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_STATUS (0xFFFFFFFFFF301000ull)
82 #define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF301100ull + 0x100 * (num))
83 #define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF301108ull + 0x100 * (num))
84 #define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ASID(num) (0xFFFFFFFFFF301110ull + 0x100 * (num))
85 #define CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF301118ull + 0x100 * (num))
87 #define CVMX_DEBUG_HW_DATA_BREAKPOINT_STATUS (0xFFFFFFFFFF302000ull)
88 #define CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF302100ull + 0x100 * (num))
89 #define CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF302108ull + 0x100 * (num))
90 #define CVMX_DEBUG_HW_DATA_BREAKPOINT_ASID(num) (0xFFFFFFFFFF302110ull + 0x100 * (num))
91 #define CVMX_DEBUG_HW_DATA_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF302118ull + 0x100 * (num))
93 #define ERET_INSN 0x42000018U /* Hexcode for eret */
94 #define ISR_DELAY_COUNTER 120000000 /* Could be tuned down */
96 extern cvmx_debug_comm_t cvmx_debug_uart_comm;
97 extern cvmx_debug_comm_t cvmx_debug_remote_comm;
98 static const cvmx_debug_comm_t *cvmx_debug_comms[COMM_SIZE] = {&cvmx_debug_uart_comm, &cvmx_debug_remote_comm};
102 static cvmx_debug_globals_t *cvmx_debug_globals;
109 #ifndef CVMX_BUILD_FOR_LINUX_KERNEL
110 uint64_t __cvmx_debug_save_regs_area[32];
112 volatile uint64_t __cvmx_debug_mode_exception_ignore;
113 volatile uint64_t __cvmx_debug_mode_exception_occured;
115 static char cvmx_debug_stack[8*1024] __attribute ((aligned (16)));
116 char *__cvmx_debug_stack_top = &cvmx_debug_stack[8*1024];
118 #ifndef CVMX_BUILD_FOR_TOOLCHAIN
119 extern int cvmx_interrupt_in_isr;
121 #define cvmx_interrupt_in_isr 0
125 uint64_t __cvmx_debug_save_regs_area_all[CVMX_MAX_CORES][32];
126 #define __cvmx_debug_save_regs_area __cvmx_debug_save_regs_area_all[cvmx_get_core_num()]
128 volatile uint64_t __cvmx_debug_mode_exception_ignore_all[CVMX_MAX_CORES];
129 #define __cvmx_debug_mode_exception_ignore __cvmx_debug_mode_exception_ignore_all[cvmx_get_core_num()]
130 volatile uint64_t __cvmx_debug_mode_exception_occured_all[CVMX_MAX_CORES];
131 #define __cvmx_debug_mode_exception_occured __cvmx_debug_mode_exception_occured_all[cvmx_get_core_num()]
133 static char cvmx_debug_stack_all[CVMX_MAX_CORES][8*1024] __attribute ((aligned (16)));
134 char *__cvmx_debug_stack_top_all[CVMX_MAX_CORES];
136 #define cvmx_interrupt_in_isr 0
141 static size_t cvmx_debug_strlen (const char *str)
151 static void cvmx_debug_strcpy (char *dest, const char *src)
162 static void cvmx_debug_memcpy_align (void *dest, const void *src, int size) __attribute__ ((__noinline__));
163 static void cvmx_debug_memcpy_align (void *dest, const void *src, int size)
165 long long *dest1 = (long long*)dest;
166 const long long *src1 = (const long long*)src;
170 long long a0, a1, a2, a3, a4;
183 for(i = 0;i < size;i+=8)
192 static inline uint32_t cvmx_debug_core_mask(void)
194 #ifndef CVMX_BUILD_FOR_LINUX_KERNEL
195 #ifdef CVMX_BUILD_FOR_TOOLCHAIN
196 extern int __octeon_core_mask;
197 return __octeon_core_mask;
199 return cvmx_sysinfo_get()->core_mask;
201 return octeon_get_boot_coremask ();
205 static inline void cvmx_debug_update_state(cvmx_debug_state_t state)
207 cvmx_debug_memcpy_align(cvmx_debug_globals->state, &state, sizeof(cvmx_debug_state_t));
210 static inline cvmx_debug_state_t cvmx_debug_get_state(void)
212 cvmx_debug_state_t state;
213 cvmx_debug_memcpy_align(&state, cvmx_debug_globals->state, sizeof(cvmx_debug_state_t));
217 static void cvmx_debug_printf(char *format, ...) __attribute__((format(__printf__, 1, 2)));
218 static void cvmx_debug_printf(char *format, ...)
222 if (!CVMX_DEBUG_LOGGING)
225 va_start(ap, format);
226 cvmx_dvprintf(format, ap);
230 static inline int __cvmx_debug_in_focus(cvmx_debug_state_t state, unsigned core)
232 return state.focus_core == core;
235 static void cvmx_debug_install_handler(unsigned core)
237 extern void __cvmx_debug_handler_stage2(void);
238 int32_t *trampoline = CASTPTR(int32_t, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, BOOTLOADER_DEBUG_TRAMPOLINE_CORE));
241 *trampoline = (int32_t)(long)&__cvmx_debug_handler_stage2;
243 cvmx_debug_printf("Debug handled installed on core %d at %p\n", core, trampoline);
246 static int cvmx_debug_enabled(void)
248 return cvmx_debug_booted() || CVMX_DEBUG_ATTACH;
251 static void cvmx_debug_init_global_ptr (void *ptr)
253 uint64_t phys = cvmx_ptr_to_phys (ptr);
254 cvmx_debug_globals_t *p;
255 /* Since at this point, TLBs are not mapped 1 to 1, we should just use KSEG0 accesses. */
256 p = CASTPTR(cvmx_debug_globals_t, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, phys));
257 memset (p, 0, sizeof(cvmx_debug_globals_t));
258 p->version = CVMX_DEBUG_GLOBALS_VERSION;
259 p->tlb_entries = cvmx_core_get_tlb_entries();
262 static void cvmx_debug_init_globals(void)
267 if (cvmx_debug_globals)
269 ptr = cvmx_bootmem_alloc_named_range_once(sizeof(cvmx_debug_globals_t), 0, /* KSEG0 max, 512MB=*/0/*1024*1024*512*/, 8,
270 CVMX_DEBUG_GLOBALS_BLOCK_NAME, cvmx_debug_init_global_ptr);
271 phys = cvmx_ptr_to_phys (ptr);
273 /* Since TLBs are not always mapped 1 to 1, we should just use access via KSEG0. */
274 cvmx_debug_globals = CASTPTR(cvmx_debug_globals_t, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, phys));
275 cvmx_debug_printf("Debug named block at %p\n", cvmx_debug_globals);
279 static void cvmx_debug_globals_check_version(void)
281 if (cvmx_debug_globals->version != CVMX_DEBUG_GLOBALS_VERSION)
283 cvmx_dprintf("Wrong version on the globals struct spinining; expected %d, got: %d.\n", (int)CVMX_DEBUG_GLOBALS_VERSION, (int)(cvmx_debug_globals->version));
284 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
285 panic("Wrong version.\n");
292 static inline volatile cvmx_debug_core_context_t *cvmx_debug_core_context(void);
293 static inline void cvmx_debug_save_core_context(volatile cvmx_debug_core_context_t *context, uint64_t hi, uint64_t lo);
295 void cvmx_debug_init(void)
297 cvmx_debug_state_t state;
299 const cvmx_debug_comm_t *comm;
300 cvmx_spinlock_t *lock;
301 unsigned int coremask = cvmx_debug_core_mask();
303 if (!cvmx_debug_enabled())
306 cvmx_debug_init_globals();
308 #ifndef CVMX_BUILD_FOR_LINUX_KERNEL
309 // Put a barrier until all cores have got to this point.
310 cvmx_coremask_barrier_sync(coremask);
312 cvmx_debug_globals_check_version();
315 comm = cvmx_debug_comms[cvmx_debug_globals->comm_type];
316 lock = &cvmx_debug_globals->lock;
318 core = cvmx_get_core_num();
319 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
320 /* Install the debugger handler on the cores. */
323 for (core1 = 0; core1 < CVMX_MAX_CORES; core1++)
325 if ((1u<<core1) & coremask)
326 cvmx_debug_install_handler(core1);
330 cvmx_debug_install_handler(core);
337 cvmx_spinlock_lock(lock);
338 state = cvmx_debug_get_state();
339 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
340 state.known_cores |= coremask;
341 state.core_finished &= ~coremask;
343 state.known_cores |= (1u << core);
344 state.core_finished &= ~(1u << core);
346 cvmx_debug_update_state(state);
347 cvmx_spinlock_unlock(lock);
350 #ifndef CVMX_BUILD_FOR_LINUX_KERNEL
351 // Put a barrier until all cores have got to this point.
352 cvmx_coremask_barrier_sync(coremask);
354 if (cvmx_coremask_first_core(coremask))
357 cvmx_debug_printf("cvmx_debug_init core: %d\n", core);
358 state = cvmx_debug_get_state();
359 state.focus_core = core;
360 state.active_cores = state.known_cores;
361 state.focus_switch = 1;
363 cvmx_debug_printf("Known cores at init: 0x%x\n", (int)state.known_cores);
364 cvmx_debug_update_state(state);
366 /* Initialize __cvmx_debug_stack_top_all. */
367 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
370 for (i = 0; i < CVMX_MAX_CORES; i++)
371 __cvmx_debug_stack_top_all[i] = &cvmx_debug_stack_all[i][8*1024];
374 cvmx_debug_globals->init_complete = 1;
377 while (!cvmx_debug_globals->init_complete)
379 /* Spin waiting for init to complete */
382 if (cvmx_debug_booted())
383 cvmx_debug_trigger_exception();
385 /* Install the break handler after might tripper the debugger exception. */
386 #ifndef CVMX_BUILD_FOR_LINUX_KERNEL
387 if (cvmx_coremask_first_core(coremask))
390 if (comm->install_break_handler)
391 comm->install_break_handler();
395 static const char cvmx_debug_hexchar[] = "0123456789ABCDEF";
396 /* Put the hex value of t into str. */
397 static void cvmx_debug_int8_to_strhex(char *str, unsigned char t)
399 str[0] = cvmx_debug_hexchar[(t>>4)&0xf];
400 str[1] = cvmx_debug_hexchar[t&0xF];
404 static void cvmx_debug_int64_to_strhex(char *str, uint64_t t)
406 str[0] = cvmx_debug_hexchar[(t>>60)&0xF];
407 str[1] = cvmx_debug_hexchar[(t>>56)&0xF];
408 str[2] = cvmx_debug_hexchar[(t>>52)&0xF];
409 str[3] = cvmx_debug_hexchar[(t>>48)&0xF];
410 str[4] = cvmx_debug_hexchar[(t>>44)&0xF];
411 str[5] = cvmx_debug_hexchar[(t>>40)&0xF];
412 str[6] = cvmx_debug_hexchar[(t>>36)&0xF];
413 str[7] = cvmx_debug_hexchar[(t>>32)&0xF];
414 str[8] = cvmx_debug_hexchar[(t>>28)&0xF];
415 str[9] = cvmx_debug_hexchar[(t>>24)&0xF];
416 str[10] = cvmx_debug_hexchar[(t>>20)&0xF];
417 str[11] = cvmx_debug_hexchar[(t>>16)&0xF];
418 str[12] = cvmx_debug_hexchar[(t>>12)&0xF];
419 str[13] = cvmx_debug_hexchar[(t>>8)&0xF];
420 str[14] = cvmx_debug_hexchar[(t>>4)&0xF];
421 str[15] = cvmx_debug_hexchar[(t>>0)&0xF];
425 static int cvmx_debug_putpacket_noformat(char *packet)
427 if (cvmx_debug_comms[cvmx_debug_globals->comm_type]->putpacket == NULL)
429 cvmx_debug_printf("Reply: %s\n", packet);
430 return cvmx_debug_comms[cvmx_debug_globals->comm_type]->putpacket(packet);
433 static int cvmx_debug_putcorepacket(char *buf, int core)
435 char *tmp = "!Core XX ";
436 int tmpsize = cvmx_debug_strlen(tmp);
437 int bufsize = cvmx_debug_strlen(buf);
438 char *packet = __builtin_alloca(tmpsize + bufsize + 1);
439 cvmx_debug_strcpy(packet, tmp);
440 cvmx_debug_strcpy(&packet[tmpsize], buf);
444 packet[7] = core + '0';
449 packet[7] = core - 10 + '0';
454 packet[7] = core - 20 + '0';
459 packet[7] = core - 30 + '0';
461 return cvmx_debug_putpacket_noformat(packet);
464 /* Put a buf followed by an integer formated as a hex. */
465 static int cvmx_debug_putpacket_hexint(char *buf, uint64_t value)
467 size_t size = cvmx_debug_strlen(buf);
468 char *packet = __builtin_alloca(size + 16 + 1);
469 cvmx_debug_strcpy(packet, buf);
470 cvmx_debug_int64_to_strhex(&packet[size], value);
471 return cvmx_debug_putpacket_noformat(packet);
474 static int cvmx_debug_active_core(cvmx_debug_state_t state, unsigned core)
476 return state.active_cores & (1u << core);
479 static volatile cvmx_debug_core_context_t *cvmx_debug_core_context(void)
481 return &cvmx_debug_globals->contextes[cvmx_get_core_num()];
484 static volatile uint64_t *cvmx_debug_regnum_to_context_ref(int regnum, volatile cvmx_debug_core_context_t *context)
486 /* Must be kept in sync with mips_octeon_reg_names in gdb/mips-tdep.c. */
488 return &context->regs[regnum];
491 case 32: return &context->cop0.status;
492 case 33: return &context->lo;
493 case 34: return &context->hi;
494 case 35: return &context->cop0.badvaddr;
495 case 36: return &context->cop0.cause;
496 case 37: return &context->cop0.depc;
497 default: return NULL;
501 static int cvmx_debug_probe_load(unsigned char *ptr, unsigned char *result)
503 volatile unsigned char *p = ptr;
508 __cvmx_debug_mode_exception_ignore = 1;
509 __cvmx_debug_mode_exception_occured = 0;
510 /* We don't handle debug-mode exceptions in delay slots. Avoid them. */
511 asm volatile (".set push \n\t"
512 ".set noreorder \n\t"
516 ".set pop" : "=r"(tem) : "m"(*p));
517 ok = __cvmx_debug_mode_exception_occured == 0;
518 __cvmx_debug_mode_exception_ignore = 0;
519 __cvmx_debug_mode_exception_occured = 0;
525 static int cvmx_debug_probe_store(unsigned char *ptr)
527 volatile unsigned char *p = ptr;
530 __cvmx_debug_mode_exception_ignore = 1;
531 __cvmx_debug_mode_exception_occured = 0;
532 /* We don't handle debug-mode exceptions in delay slots. Avoid them. */
533 asm volatile (".set push \n\t"
534 ".set noreorder \n\t"
538 ".set pop" : "=m"(*p));
539 ok = __cvmx_debug_mode_exception_occured == 0;
541 __cvmx_debug_mode_exception_ignore = 0;
542 __cvmx_debug_mode_exception_occured = 0;
548 * Routines to handle hex data
553 static inline int cvmx_debug_hex(char ch)
555 if ((ch >= 'a') && (ch <= 'f'))
556 return(ch - 'a' + 10);
557 if ((ch >= '0') && (ch <= '9'))
559 if ((ch >= 'A') && (ch <= 'F'))
560 return(ch - 'A' + 10);
565 * While we find nice hex chars, build an int.
566 * Return number of chars processed.
572 static int cvmx_debug_hexToLong(const char **ptr, uint64_t *intValue)
580 hexValue = cvmx_debug_hex(**ptr);
584 *intValue = (*intValue << 4) | hexValue;
594 * Initialize the performance counter control registers.
597 static void cvmx_debug_set_perf_control_reg (volatile cvmx_debug_core_context_t *context, int perf_event, int perf_counter)
599 cvmx_core_perf_control_t control;
607 control.s.m = 1 - perf_counter;
608 control.s.event = perf_event;
610 context->cop0.perfctrl[perf_counter] = control.u32;
613 static cvmx_debug_command_t cvmx_debug_process_packet(const char *packet)
615 const char *buf = packet;
616 cvmx_debug_command_t result = COMMAND_NOP;
617 cvmx_debug_state_t state = cvmx_debug_get_state();
619 /* A one letter command code represents what to do. */
622 case '?': /* What protocol do I speak? */
623 cvmx_debug_putpacket_noformat("S0A");
626 case '\003': /* Control-C */
627 cvmx_debug_putpacket_noformat("T9");
630 case 'F': /* Change the focus core */
633 if (!cvmx_debug_hexToLong(&buf, &core))
635 cvmx_debug_putpacket_noformat("!Uknown core. Focus not changed.");
637 /* Only cores in the exception handler may become the focus.
638 If a core not in the exception handler got focus the
639 debugger would hang since nobody would talk to it. */
640 else if (state.handler_cores & (1u << core))
642 /* Focus change reply must be sent before the focus
643 changes. Otherwise the new focus core will eat our ACK
644 from the debugger. */
645 cvmx_debug_putpacket_hexint("F", core);
646 cvmx_debug_comms[cvmx_debug_globals->comm_type]->change_core(state.focus_core, core);
647 state.focus_core = core;
648 cvmx_debug_update_state(state);
652 cvmx_debug_putpacket_noformat("!Core is not in the exception handler. Focus not changed.");
653 /* Nothing changed, so we send back the old value */
656 case 'f': /* Get the focus core */
657 cvmx_debug_putpacket_hexint("F", state.focus_core);
660 case 'J': /* Set the flag for skip-over-isr in Single-Stepping mode */
663 state.step_isr = 1; /* Step in ISR */
665 state.step_isr = 0; /* Step over ISR */
666 cvmx_debug_update_state(state);
668 /* Fall through. The reply to the set step-isr command is the
669 same as the get step-isr command */
671 case 'j': /* Reply with step_isr status */
672 cvmx_debug_putpacket_hexint("J", (unsigned)state.step_isr);
676 case 'I': /* Set the active cores */
678 uint64_t active_cores;
679 if (!cvmx_debug_hexToLong(&buf, &active_cores))
681 /* Limit the active mask to the known to exist cores */
682 state.active_cores = active_cores & state.known_cores;
684 /* Lazy user hack to have 0 be all cores */
685 if (state.active_cores == 0)
686 state.active_cores = state.known_cores;
688 /* The focus core must be in the active_cores mask */
689 if ((state.active_cores & (1u << state.focus_core)) == 0)
691 cvmx_debug_putpacket_noformat("!Focus core was added to the masked.");
692 state.active_cores |= 1u << state.focus_core;
695 cvmx_debug_update_state(state);
697 /* Fall through. The reply to the set active cores command is the
698 same as the get active cores command */
700 case 'i': /* Get the active cores */
701 cvmx_debug_putpacket_hexint("I", state.active_cores);
704 case 'A': /* Setting the step mode all or one */
707 state.step_all = 1; /* A step or continue will start all cores */
709 state.step_all = 0; /* A step or continue only affects the focus core */
710 cvmx_debug_update_state(state);
712 /* Fall through. The reply to the set step-all command is the
713 same as the get step-all command */
715 case 'a': /* Getting the current step mode */
716 cvmx_debug_putpacket_hexint("A", state.step_all);
719 case 'g': /* read a register from global place. */
721 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context();
723 volatile uint64_t *reg;
725 /* Get the register number to read */
726 if (!cvmx_debug_hexToLong(&buf, ®no))
728 cvmx_debug_printf("Register number cannot be read.\n");
729 cvmx_debug_putpacket_hexint("", 0xDEADBEEF);
733 reg = cvmx_debug_regnum_to_context_ref(regno, context);
736 cvmx_debug_printf("Register #%d is not valid\n", (int)regno);
737 cvmx_debug_putpacket_hexint("", 0xDEADBEEF);
740 cvmx_debug_putpacket_hexint("", *reg);
744 case 'G': /* set the value of a register. */
746 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context();
748 volatile uint64_t *reg;
751 /* Get the register number to write. It should be followed by
753 if (!cvmx_debug_hexToLong(&buf, ®no)
755 || !cvmx_debug_hexToLong(&buf, &value))
757 cvmx_debug_printf("G packet corrupt: %s\n", buf);
761 reg = cvmx_debug_regnum_to_context_ref(regno, context);
764 cvmx_debug_printf("Register #%d is not valid\n", (int)regno);
771 case 'm': /* Memory read. mAA..AA,LLLL Read LLLL bytes at address AA..AA */
773 uint64_t addr, i, length;
777 /* Get the memory address, a comma, and the length */
778 if (!cvmx_debug_hexToLong(&buf, &addr)
780 || !cvmx_debug_hexToLong(&buf, &length))
782 cvmx_debug_printf("m packet corrupt: %s\n", buf);
787 cvmx_debug_printf("m packet length out of range: %lld\n", (long long)length);
791 reply = __builtin_alloca(length * 2 + 1);
792 ptr = (unsigned char *)(long)addr;
793 for (i = 0; i < length; i++)
795 /* Probe memory. If not accessible fail. */
797 if (!cvmx_debug_probe_load(&ptr[i], &t))
799 cvmx_debug_int8_to_strhex(&reply[i * 2], t);
801 cvmx_debug_putpacket_noformat(reply);
805 case 'M': /* Memory write. MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
807 uint64_t addr, i, length;
810 if (!cvmx_debug_hexToLong(&buf, &addr)
812 || !cvmx_debug_hexToLong(&buf, &length)
815 cvmx_debug_printf("M packet corrupt: %s\n", buf);
819 ptr = (unsigned char *)(long)addr;
820 for (i = 0; i < length; i++)
825 n = cvmx_debug_hex(buf[i * 2]);
826 n1 = cvmx_debug_hex(buf[i * 2 + 1]);
829 if (n == -1 || n1 == -1)
831 cvmx_debug_printf("M packet corrupt: %s\n", &buf[i * 2]);
834 /* Probe memory. If not accessible fail. */
835 if (!cvmx_debug_probe_store(&ptr[i]))
837 cvmx_debug_printf("M cannot write: %p\n", &ptr[i]);
842 cvmx_debug_putpacket_noformat("+");
846 case 'e': /* Set/get performance counter events. e[1234]XX..X: [01]
847 is the performance counter to set X is the performance
848 event. [34] is to get the same thing. */
850 uint64_t perf_event = 0;
851 char encoded_counter = *buf++;
853 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context();
855 /* Ignore errors from the packet. */
856 cvmx_debug_hexToLong(&buf, &perf_event);
858 switch (encoded_counter)
860 case '1': /* Set performance counter0 event. */
861 case '2': /* Set performance counter1 event. */
863 counter = encoded_counter - '1';
864 context->cop0.perfval[counter] = 0;
865 cvmx_debug_set_perf_control_reg(context, perf_event, counter);
868 case '3': /* Get performance counter0 event. */
869 case '4': /* Get performance counter1 event. */
871 cvmx_core_perf_control_t c;
872 char outpacket[16*2 +2];
873 counter = encoded_counter - '3';
874 /* Pass performance counter0 event and counter to
876 c.u32 = context->cop0.perfctrl[counter];
877 cvmx_debug_int64_to_strhex(outpacket, context->cop0.perfval[counter]);
879 cvmx_debug_int64_to_strhex(&outpacket[17], c.s.event);
881 cvmx_debug_putpacket_noformat(outpacket);
889 case 't': /* Return the trace buffer read data register contents. */
895 /* If trace buffer is disabled no trace data information is available. */
896 if ((tra_ctl & 0x1) == 0)
898 cvmx_debug_putpacket_noformat("!Trace buffer not enabled\n");
899 cvmx_debug_putpacket_noformat("t");
903 cvmx_debug_putpacket_noformat("!Trace buffer is enabled\n");
904 tra_data = cvmx_read_csr(OCTEON_TRA_READ_DATA);
905 mem2hex (&tra_data, tmp, 8);
906 strcpy (debug_output_buffer, "t");
907 strcat (debug_output_buffer, tmp);
908 cvmx_debug_putpacket_noformat(debug_output_buffer);
914 case 'Z': /* Insert hardware breakpoint: Z[di]NN..N,AA.A, [di] data or
915 instruction, NN..Nth at address AA..A */
927 char bp_type = *buf++;
928 const int BE = 1, TE = 4;
929 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context();
931 if (!cvmx_debug_hexToLong(&buf, &num)
933 || !cvmx_debug_hexToLong(&buf, &addr))
935 cvmx_debug_printf("Z packet corrupt: %s\n", &packet[1]);
941 case 'i': // Instruction hardware breakpoint
944 cvmx_debug_printf("Z packet corrupt: %s\n", &packet[1]);
948 context->hw_ibp.address[num] = addr;
949 context->hw_ibp.address_mask[num] = 0;
950 context->hw_ibp.asid[num] = 0;
951 context->hw_ibp.control[num] = BE | TE;
954 case 'd': // Data hardware breakpoint
956 uint64_t dbc = 0xff0 | BE | TE;
960 || !cvmx_debug_hexToLong(&buf, &size)
962 || !cvmx_debug_hexToLong(&buf, &type)
966 cvmx_debug_printf("Z packet corrupt: %s\n", &packet[1]);
970 /* Set DBC[BE,TE,BLM]. */
971 context->hw_dbp.address[num] = addr;
972 context->hw_dbp.asid[num] = 0;
974 dbc |= type == WP_STORE ? 0x1000 : type == WP_LOAD ? 0x2000 : 0;
975 /* Mask the bits depending on the size for
976 debugger to stop while accessing parts of the
978 dbm = (size == 8) ? 0x7 : ((size == 4) ? 3
979 : (size == 2) ? 1 : 0);
980 context->hw_dbp.address_mask[num] = dbm;
981 context->hw_dbp.control[num] = dbc;
985 cvmx_debug_printf("Z packet corrupt: %s\n", &packet[1]);
991 case 'z': /* Remove hardware breakpoint: z[di]NN..N remove NN..Nth
995 char bp_type = *buf++;
996 volatile cvmx_debug_core_context_t *context = cvmx_debug_core_context();
998 if (!cvmx_debug_hexToLong(&buf, &num) || num > 4)
1000 cvmx_debug_printf("z packet corrupt: %s\n", buf);
1006 case 'i': // Instruction hardware breakpoint
1007 context->hw_ibp.address[num] = 0;
1008 context->hw_ibp.address_mask[num] = 0;
1009 context->hw_ibp.asid[num] = 0;
1010 context->hw_ibp.control[num] = 0;
1012 case 'd': // Data hardware breakpoint
1013 context->hw_dbp.address[num] = 0;
1014 context->hw_dbp.address_mask[num] = 0;
1015 context->hw_dbp.asid[num] = 0;
1016 context->hw_dbp.control[num] = 0;
1019 cvmx_debug_printf("z packet corrupt: %s\n", buf);
1025 case 's': /* Single step. sAA..AA Step one instruction from AA..AA (optional) */
1026 result = COMMAND_STEP;
1029 case 'c': /* Continue. cAA..AA Continue at address AA..AA (optional) */
1030 result = COMMAND_CONTINUE;
1033 case '+': /* Don't know. I think it is a communications sync */
1034 /* Ignoring this command */
1038 cvmx_debug_printf("Unknown debug command: %s\n", buf - 1);
1040 cvmx_debug_putpacket_noformat("-");
1047 static cvmx_debug_command_t cvmx_debug_process_next_packet(void)
1049 char packet[CVMX_DEBUG_MAX_REQUEST_SIZE];
1050 if (cvmx_debug_comms[cvmx_debug_globals->comm_type]->getpacket(packet, CVMX_DEBUG_MAX_REQUEST_SIZE))
1052 cvmx_debug_printf("Request: %s\n", packet);
1053 return cvmx_debug_process_packet(packet);
1058 /* If a core isn't in the active core mask we need to start him up again. We
1059 can only do this if the core didn't hit a breakpoint or single step. If the
1060 core hit CVMX_CIU_DINT interrupt (generally happens when while executing
1061 _exit() at the end of the program). Remove the core from known cores so
1062 that when the cores in active core mask are done executing the program, the
1063 focus will not be transfered to this core. */
1065 static int cvmx_debug_stop_core(cvmx_debug_state_t state, unsigned core, cvmx_debug_register_t *debug_reg, int proxy)
1067 if (!cvmx_debug_active_core(state, core) && !debug_reg->s.dbp && !debug_reg->s.dss && (debug_reg->s.dint != 1))
1069 debug_reg->s.sst = 0;
1070 cvmx_debug_printf("Core #%d not in active cores, continuing.\n", core);
1073 if ((state.core_finished & (1u<<core)) && proxy)
1078 /* check to see if current exc is single-stepped and that no other exc
1079 was also simultaneously noticed. */
1080 static int cvmx_debug_single_step_exc(cvmx_debug_register_t *debug_reg)
1082 if (debug_reg->s.dss && !debug_reg->s.dib && !debug_reg->s.dbp && !debug_reg->s.ddbs && !debug_reg->s.ddbl)
1087 static void cvmx_debug_set_focus_core(cvmx_debug_state_t *state, int core)
1089 if (state->ever_been_in_debug)
1090 cvmx_debug_putcorepacket("taking focus.", core);
1091 cvmx_debug_comms[cvmx_debug_globals->comm_type]->change_core (state->focus_core, core);
1092 state->focus_core = core;
1095 static void cvmx_debug_may_elect_as_focus_core(cvmx_debug_state_t *state, int core, cvmx_debug_register_t *debug_reg)
1097 /* If another core has already elected itself as the focus core, we're late. */
1098 if (state->handler_cores & (1u << state->focus_core))
1101 /* If we hit a breakpoint, elect ourselves. */
1102 if (debug_reg->s.dib || debug_reg->s.dbp || debug_reg->s.ddbs || debug_reg->s.ddbl)
1103 cvmx_debug_set_focus_core(state, core);
1105 /* It is possible the focus core has completed processing and exited the
1106 program. When this happens the focus core will not be in
1107 known_cores. If this is the case we need to elect a new focus. */
1108 if ((state->known_cores & (1u << state->focus_core)) == 0)
1109 cvmx_debug_set_focus_core(state, core);
1112 static void cvmx_debug_send_stop_reason(cvmx_debug_register_t *debug_reg, volatile cvmx_debug_core_context_t *context)
1114 /* Handle Debug Data Breakpoint Store/Load Exception. */
1115 if (debug_reg->s.ddbs || debug_reg->s.ddbl)
1116 cvmx_debug_putpacket_hexint("T8:", (int) context->hw_dbp.status);
1118 cvmx_debug_putpacket_noformat("T9");
1122 static void cvmx_debug_clear_status(volatile cvmx_debug_core_context_t *context)
1124 /* SW needs to clear the BreakStatus bits after a watchpoint is hit or on
1126 context->hw_dbp.status &= ~0x3fff;
1128 /* Clear MCD0, which is write-1-to-clear. */
1129 context->cop0.multicoredebug |= 1;
1132 static void cvmx_debug_sync_up_cores(void)
1134 /* NOTE this reads directly from the state array for speed reasons
1135 and we don't change the array. */
1137 asm("": : : "memory");
1138 } while (cvmx_debug_globals->state[offsetof(cvmx_debug_state_t, step_all)/sizeof(uint32_t)]
1139 && cvmx_debug_globals->state[offsetof(cvmx_debug_state_t, handler_cores)/sizeof(uint32_t)] != 0);
1142 /* Delay the focus core a little if it is likely another core needs to steal
1143 focus. Once we enter the main loop focus can't be stolen */
1144 static void cvmx_debug_delay_focus_core(cvmx_debug_state_t state, unsigned core, cvmx_debug_register_t *debug_reg)
1147 if (debug_reg->s.dss || debug_reg->s.dbp || core != state.focus_core)
1149 for (i = 0; i < 2400; i++)
1151 asm volatile (".set push \n\t"
1152 ".set noreorder \n\t"
1158 /* Spin giving the breakpoint core time to steal focus */
1163 /* If this core was single-stepping in a group,
1164 && it was not the last focus-core,
1165 && last focus-core happens to be inside an ISR, blocking focus-switch
1166 then burn some cycles, to avoid unnecessary focus toggles. */
1167 static void cvmx_debug_delay_isr_core(unsigned core, uint32_t depc, int single_stepped_exc_only,
1168 cvmx_debug_state_t state)
1170 volatile uint64_t i;
1171 if(!single_stepped_exc_only || state.step_isr || core == state.focus_core || state.focus_switch)
1174 cvmx_debug_printf ("Core #%u spinning for focus at 0x%x\n", core, (unsigned int)depc);
1176 for(i = ISR_DELAY_COUNTER; i > 0 ; i--)
1178 state = cvmx_debug_get_state();
1179 /* Spin giving the focus core time to service ISR */
1180 /* But cut short the loop, if we can. Shrink down i, only once. */
1181 if (i > 600000 && state.focus_switch)
1187 static int cvmx_debug_perform_proxy(cvmx_debug_register_t *debug_reg, volatile cvmx_debug_core_context_t *context)
1189 unsigned core = cvmx_get_core_num();
1190 cvmx_debug_state_t state = cvmx_debug_get_state();
1191 cvmx_debug_command_t command = COMMAND_NOP;
1192 int single_stepped_exc_only = cvmx_debug_single_step_exc (debug_reg);
1194 /* All cores should respect the focus core if it has to
1195 stop focus switching while servicing an interrupt.
1196 If the system is single-stepping, then the following
1197 code path is valid. If the current core tripped on a
1198 break-point or some other error while going through
1199 an ISR, then we shouldn't be returning unconditionally.
1200 In that case (non-single-step case) we must enter
1201 the debugger exception stub fully. */
1202 if (!state.step_isr && (cvmx_interrupt_in_isr || (context->cop0.status & 0x2ULL)) && single_stepped_exc_only)
1204 cvmx_spinlock_lock(&cvmx_debug_globals->lock);
1205 state = cvmx_debug_get_state();
1206 /* If this is the focus core, switch off focus switching
1207 till ISR_DELAY_COUNTER. This will let focus core
1208 keep the focus until the ISR is completed. */
1209 if(state.focus_switch && core == state.focus_core)
1211 cvmx_debug_printf ("Core #%u stopped focus stealing at 0x%llx\n", core, (unsigned long long)context->cop0.depc);
1212 state.focus_switch = 0;
1214 /* Alow other cores to steal focus.
1215 Focus core has completed ISR. */
1216 if (*(uint32_t*)((__SIZE_TYPE__)context->cop0.depc) == ERET_INSN && core == state.focus_core)
1218 cvmx_debug_printf ("Core #%u resumed focus stealing at 0x%llx\n", core, (unsigned long long)context->cop0.depc);
1219 state.focus_switch = 1;
1221 cvmx_debug_update_state(state);
1222 cvmx_spinlock_unlock(&cvmx_debug_globals->lock);
1223 cvmx_debug_printf ("Core #%u resumed skipping isr.\n", core);
1227 /* Delay the focus core a little if it is likely another core needs to
1228 steal focus. Once we enter the main loop focus can't be stolen */
1229 cvmx_debug_delay_focus_core(state, core, debug_reg);
1231 cvmx_debug_delay_isr_core (core, context->cop0.depc, single_stepped_exc_only, state);
1233 /* The following section of code does two critical things. First, it
1234 populates the handler_cores bitmask of all cores in the exception
1235 handler. Only one core at a time can update this field. Second it
1236 changes the focus core if needed. */
1238 cvmx_debug_printf("Core #%d stopped\n", core);
1239 cvmx_spinlock_lock(&cvmx_debug_globals->lock);
1240 state = cvmx_debug_get_state();
1242 state.handler_cores |= (1u << core);
1243 cvmx_debug_may_elect_as_focus_core(&state, core, debug_reg);
1245 /* Push all updates before exiting the critical section */
1246 state.focus_switch = 1;
1247 cvmx_debug_update_state(state);
1248 cvmx_spinlock_unlock(&cvmx_debug_globals->lock);
1250 if (__cvmx_debug_in_focus(state, core))
1251 cvmx_debug_send_stop_reason(debug_reg, context);
1254 unsigned oldfocus = state.focus_core;
1255 state = cvmx_debug_get_state();
1256 /* Note the focus core can change in this loop. */
1257 if (__cvmx_debug_in_focus(state, core))
1259 /* If the focus has changed and the old focus has exited, then send a signal
1260 that we should stop if step_all is off. */
1261 if (oldfocus != state.focus_core && ((1u << oldfocus) & state.core_finished)
1263 cvmx_debug_send_stop_reason(debug_reg, context);
1265 command = cvmx_debug_process_next_packet();
1266 state = cvmx_debug_get_state();
1267 /* When resuming let the other cores resume as well with
1269 if (command != COMMAND_NOP && state.step_all)
1271 state.command = command;
1272 cvmx_debug_update_state(state);
1275 /* When steping all cores, update the non focus core's command too. */
1276 else if (state.step_all)
1277 command = state.command;
1279 /* If we did not get a command and the communication changed return,
1280 we are changing the communications. */
1281 if (command == COMMAND_NOP && cvmx_debug_globals->comm_changed)
1283 /* FIXME, this should a sync not based on cvmx_coremask_barrier_sync. */
1284 #ifndef CVMX_BUILD_FOR_LINUX_KERNEL
1286 cvmx_coremask_barrier_sync(state.handler_cores);
1290 } while (command == COMMAND_NOP);
1292 debug_reg->s.sst = command == COMMAND_STEP;
1293 cvmx_debug_printf("Core #%d running\n", core);
1296 cvmx_spinlock_lock(&cvmx_debug_globals->lock);
1297 state = cvmx_debug_get_state();
1298 state.handler_cores ^= (1u << core);
1299 cvmx_debug_update_state(state);
1300 cvmx_spinlock_unlock(&cvmx_debug_globals->lock);
1303 cvmx_debug_sync_up_cores();
1304 /* Now that all cores are out, reset the command. */
1305 if (__cvmx_debug_in_focus(state, core))
1307 cvmx_spinlock_lock(&cvmx_debug_globals->lock);
1308 state = cvmx_debug_get_state();
1309 state.command = COMMAND_NOP;
1310 cvmx_debug_update_state(state);
1311 cvmx_spinlock_unlock(&cvmx_debug_globals->lock);
1316 static void cvmx_debug_save_core_context(volatile cvmx_debug_core_context_t *context, uint64_t hi, uint64_t lo)
1319 cvmx_debug_memcpy_align ((char *) context->regs, __cvmx_debug_save_regs_area, sizeof(context->regs));
1322 CVMX_MF_COP0(context->cop0.index, COP0_INDEX);
1323 CVMX_MF_COP0(context->cop0.entrylo[0], COP0_ENTRYLO0);
1324 CVMX_MF_COP0(context->cop0.entrylo[1], COP0_ENTRYLO1);
1325 CVMX_MF_COP0(context->cop0.entryhi, COP0_ENTRYHI);
1326 CVMX_MF_COP0(context->cop0.pagemask, COP0_PAGEMASK);
1327 CVMX_MF_COP0(context->cop0.status, COP0_STATUS);
1328 CVMX_MF_COP0(context->cop0.cause, COP0_CAUSE);
1329 CVMX_MF_COP0(context->cop0.debug, COP0_DEBUG);
1330 CVMX_MF_COP0(context->cop0.multicoredebug, COP0_MULTICOREDEBUG);
1331 CVMX_MF_COP0(context->cop0.perfval[0], COP0_PERFVALUE0);
1332 CVMX_MF_COP0(context->cop0.perfval[1], COP0_PERFVALUE1);
1333 CVMX_MF_COP0(context->cop0.perfctrl[0], COP0_PERFCONTROL0);
1334 CVMX_MF_COP0(context->cop0.perfctrl[1], COP0_PERFCONTROL1);
1335 /* Save DEPC and DESAVE since debug-mode exceptions (see
1336 debug_probe_{load,store}) can clobber these. */
1337 CVMX_MF_COP0(context->cop0.depc, COP0_DEPC);
1338 CVMX_MF_COP0(context->cop0.desave, COP0_DESAVE);
1340 context->hw_ibp.status = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_STATUS);
1341 for (i = 0; i < 4; i++)
1343 context->hw_ibp.address[i] = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS(i));
1344 context->hw_ibp.address_mask[i] = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(i));
1345 context->hw_ibp.asid[i] = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ASID(i));
1346 context->hw_ibp.control[i] = cvmx_read_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_CONTROL(i));
1349 context->hw_dbp.status = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_STATUS);
1350 for (i = 0; i < 4; i++)
1352 context->hw_dbp.address[i] = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS(i));
1353 context->hw_dbp.address_mask[i] = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS_MASK(i));
1354 context->hw_dbp.asid[i] = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ASID(i));
1355 context->hw_dbp.control[i] = cvmx_read_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_CONTROL(i));
1358 for (i = 0; i < cvmx_debug_globals->tlb_entries; i++)
1360 CVMX_MT_COP0(i, COP0_INDEX);
1361 asm volatile ("tlbr");
1362 CVMX_MF_COP0(context->tlbs[i].entrylo[0], COP0_ENTRYLO0);
1363 CVMX_MF_COP0(context->tlbs[i].entrylo[1], COP0_ENTRYLO1);
1364 CVMX_MF_COP0(context->tlbs[i].entryhi, COP0_ENTRYHI);
1365 CVMX_MF_COP0(context->tlbs[i].pagemask, COP0_PAGEMASK);
1370 static void cvmx_debug_restore_core_context(volatile cvmx_debug_core_context_t *context)
1374 cvmx_debug_memcpy_align (__cvmx_debug_save_regs_area, (char *) context->regs, sizeof(context->regs));
1375 /* We don't change the TLB so no need to restore it. */
1376 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_STATUS, context->hw_dbp.status);
1377 for (i = 0; i < 4; i++)
1379 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS(i), context->hw_dbp.address[i]);
1380 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ADDRESS_MASK(i), context->hw_dbp.address_mask[i]);
1381 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_ASID(i), context->hw_dbp.asid[i]);
1382 cvmx_write_csr(CVMX_DEBUG_HW_DATA_BREAKPOINT_CONTROL(i), context->hw_dbp.control[i]);
1384 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_STATUS, context->hw_ibp.status);
1385 for (i = 0; i < 4; i++)
1387 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS(i), context->hw_ibp.address[i]);
1388 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(i), context->hw_ibp.address_mask[i]);
1389 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_ASID(i), context->hw_ibp.asid[i]);
1390 cvmx_write_csr(CVMX_DEBUG_HW_INSTRUCTION_BREAKPOINT_CONTROL(i), context->hw_ibp.control[i]);
1392 CVMX_MT_COP0(context->cop0.index, COP0_INDEX);
1393 CVMX_MT_COP0(context->cop0.entrylo[0], COP0_ENTRYLO0);
1394 CVMX_MT_COP0(context->cop0.entrylo[1], COP0_ENTRYLO1);
1395 CVMX_MT_COP0(context->cop0.entryhi, COP0_ENTRYHI);
1396 CVMX_MT_COP0(context->cop0.pagemask, COP0_PAGEMASK);
1397 CVMX_MT_COP0(context->cop0.status, COP0_STATUS);
1398 CVMX_MT_COP0(context->cop0.cause, COP0_CAUSE);
1399 CVMX_MT_COP0(context->cop0.debug, COP0_DEBUG);
1400 CVMX_MT_COP0(context->cop0.multicoredebug, COP0_MULTICOREDEBUG);
1401 CVMX_MT_COP0(context->cop0.perfval[0], COP0_PERFVALUE0);
1402 CVMX_MT_COP0(context->cop0.perfval[1], COP0_PERFVALUE1);
1403 CVMX_MT_COP0(context->cop0.perfctrl[0], COP0_PERFCONTROL0);
1404 CVMX_MT_COP0(context->cop0.perfctrl[1], COP0_PERFCONTROL1);
1405 CVMX_MT_COP0(context->cop0.depc, COP0_DEPC);
1406 CVMX_MT_COP0(context->cop0.desave, COP0_DESAVE);
1409 asm("mtlo %0" :: "r"(lo));
1410 asm("mthi %0" :: "r"(hi));
1413 static inline void cvmx_debug_print_cause(volatile cvmx_debug_core_context_t *context)
1415 if (!CVMX_DEBUG_LOGGING)
1417 if (context->cop0.multicoredebug & 1)
1418 cvmx_dprintf("MCD0 was pulsed\n");
1419 if (context->cop0.multicoredebug & (1 << 16))
1420 cvmx_dprintf("Exception %lld in Debug Mode\n", (long long)((context->cop0.debug >> 10) & 0x1f));
1421 if (context->cop0.debug & (1 << 19))
1422 cvmx_dprintf("DDBSImpr\n");
1423 if (context->cop0.debug & (1 << 18))
1424 cvmx_dprintf("DDBLImpr\n");
1425 if (context->cop0.debug & (1 << 5))
1426 cvmx_dprintf("DINT\n");
1427 if (context->cop0.debug & (1 << 4))
1428 cvmx_dprintf("Debug Instruction Breakpoint (DIB) exception\n");
1429 if (context->cop0.debug & (1 << 3))
1430 cvmx_dprintf("Debug Date Break Store (DDBS) exception\n");
1431 if (context->cop0.debug & (1 << 2))
1432 cvmx_dprintf("Debug Date Break Load (DDBL) exception\n");
1433 if (context->cop0.debug & (1 << 1))
1434 cvmx_dprintf("Debug Breakpoint (DBp) exception\n");
1435 if (context->cop0.debug & (1 << 0))
1436 cvmx_dprintf("Debug Single Step (DSS) exception\n");
1439 void __cvmx_debug_handler_stage3 (uint64_t lo, uint64_t hi)
1441 volatile cvmx_debug_core_context_t *context;
1442 int comms_changed = 0;
1444 cvmx_debug_printf("Entering debug exception handler\n");
1445 cvmx_debug_printf("Debug named block at %p\n", cvmx_debug_globals);
1446 if (__cvmx_debug_mode_exception_occured)
1449 CVMX_MF_COP0(depc, COP0_DEPC);
1450 cvmx_dprintf("Unexpected debug-mode exception occured at 0x%llx, 0x%llx spinning\n", (long long) depc, (long long)(__cvmx_debug_mode_exception_occured));
1451 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
1452 panic("Unexpected debug-mode exception occured at 0x%llx, 0x%llx\n", (long long) depc, (long long)(__cvmx_debug_mode_exception_occured));
1458 context = cvmx_debug_core_context();
1459 cvmx_debug_save_core_context(context, hi, lo);
1462 cvmx_debug_state_t state;
1463 cvmx_spinlock_lock(&cvmx_debug_globals->lock);
1464 state = cvmx_debug_get_state();
1465 state.ever_been_in_debug = 1;
1466 cvmx_debug_update_state (state);
1467 cvmx_spinlock_unlock(&cvmx_debug_globals->lock);
1469 cvmx_debug_print_cause(context);
1475 /* If the communication changes, change it. */
1476 cvmx_spinlock_lock(&cvmx_debug_globals->lock);
1477 if (cvmx_debug_globals->comm_changed)
1479 cvmx_debug_printf("Communication changed: %d\n", (int)cvmx_debug_globals->comm_changed);
1480 if (cvmx_debug_globals->comm_changed > COMM_SIZE)
1482 cvmx_dprintf("Unknown communication spinning: %lld > %d.\n", (long long)cvmx_debug_globals->comm_changed, (int)(COMM_SIZE));
1483 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
1484 panic("Unknown communication.\n");
1489 cvmx_debug_globals->comm_type = cvmx_debug_globals->comm_changed - 1;
1490 cvmx_debug_globals->comm_changed = 0;
1492 cvmx_spinlock_unlock(&cvmx_debug_globals->lock);
1493 needs_proxy = cvmx_debug_comms[cvmx_debug_globals->comm_type]->needs_proxy;
1496 cvmx_debug_register_t debug_reg;
1497 cvmx_debug_state_t state;
1498 unsigned core = cvmx_get_core_num();
1500 state = cvmx_debug_get_state();
1501 debug_reg.u64 = context->cop0.debug;
1502 /* All cores stop on any exception. See if we want nothing from this and
1503 it should resume. This needs to be done for non proxy based debugging
1504 so that some non active-cores can control the other cores. */
1505 if (!cvmx_debug_stop_core(state, core, &debug_reg, needs_proxy))
1507 context->cop0.debug = debug_reg.u64;
1514 cvmx_debug_register_t debug_reg;
1515 debug_reg.u64 = context->cop0.debug;
1516 cvmx_debug_printf("Starting to proxy\n");
1517 comms_changed = cvmx_debug_perform_proxy(&debug_reg, context);
1518 context->cop0.debug = debug_reg.u64;
1522 cvmx_debug_printf("Starting to wait for remote host\n");
1523 cvmx_debug_comms[cvmx_debug_globals->comm_type]->wait_for_resume(context, cvmx_debug_get_state());
1525 } while (comms_changed);
1527 cvmx_debug_clear_status(context);
1529 cvmx_debug_restore_core_context(context);
1530 cvmx_debug_printf("Exiting debug exception handler\n");
1533 void cvmx_debug_trigger_exception(void)
1535 /* Set CVMX_CIU_DINT to enter debug exception handler. */
1536 cvmx_write_csr (CVMX_CIU_DINT, 1u << cvmx_get_core_num ());
1537 /* Perform an immediate read after every write to an RSL register to force
1538 the write to complete. It doesn't matter what RSL read we do, so we
1539 choose CVMX_MIO_BOOT_BIST_STAT because it is fast and harmless */
1540 cvmx_read_csr (CVMX_MIO_BOOT_BIST_STAT);
1544 * Inform debugger about the end of the program. This is
1545 * called from crt0 after all the C cleanup code finishes.
1546 * Our current stack is the C one, not the debug exception
1548 void cvmx_debug_finish(void)
1550 unsigned coreid = cvmx_get_core_num();
1551 cvmx_debug_state_t state;
1553 if (!cvmx_debug_globals) return;
1554 cvmx_debug_printf ("Debug _exit reached!, core %d, cvmx_debug_globals = %p\n", coreid, cvmx_debug_globals);
1556 #ifndef CVMX_BUILD_FOR_LINUX_KERNEL
1561 cvmx_spinlock_lock(&cvmx_debug_globals->lock);
1562 state = cvmx_debug_get_state();
1563 state.known_cores ^= (1u << coreid);
1564 state.core_finished |= (1u <<coreid);
1565 cvmx_debug_update_state(state);
1567 /* Tell the user the core has finished. */
1568 if (state.ever_been_in_debug)
1569 cvmx_debug_putcorepacket("finished.", coreid);
1571 /* Notify the debugger if all cores have completed the program */
1572 if ((cvmx_debug_core_mask () & state.core_finished) == cvmx_debug_core_mask ())
1574 cvmx_debug_printf("All cores done!\n");
1575 if (state.ever_been_in_debug)
1576 cvmx_debug_putpacket_noformat("D0");
1578 if (state.focus_core == coreid && state.known_cores != 0)
1580 /* Loop through cores looking for someone to handle interrupts.
1581 Since we already check that known_cores is non zero, this
1582 should always find a core */
1584 for (newcore = 0; newcore < CVMX_MAX_CORES; newcore++)
1586 if (state.known_cores & (1u<<newcore))
1588 cvmx_debug_printf("Routing uart interrupts to Core #%u.\n", newcore);
1589 cvmx_debug_set_focus_core(&state, newcore);
1590 cvmx_debug_update_state(state);
1595 cvmx_spinlock_unlock(&cvmx_debug_globals->lock);
1597 /* If we ever been in the debug, report to it that we have exited the core. */
1598 if (state.ever_been_in_debug)
1599 cvmx_debug_trigger_exception();