Lines Matching +full:ctrl +full:- +full:len

1 // SPDX-License-Identifier: GPL-2.0-only
10 * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
13 #define pr_fmt(fmt) "hw-breakpoint: " fmt
150 /* We don't support the memory-mapped interface. */ in debug_arch_supported()
215 return core_has_mismatch_brps() ? brps - 1 : brps; in get_num_brps()
256 return -ENODEV; in enable_monitor_mode()
264 return -EPERM; in enable_monitor_mode()
292 * Check if 8-bit byte-address select is available.
298 struct arch_hw_breakpoint_ctrl ctrl; in get_max_wp_len() local
304 memset(&ctrl, 0, sizeof(ctrl)); in get_max_wp_len()
305 ctrl.len = ARM_BREAKPOINT_LEN_8; in get_max_wp_len()
306 ctrl_reg = encode_ctrl_reg(ctrl); in get_max_wp_len()
330 u32 addr, ctrl; in arch_install_hw_breakpoint() local
332 addr = info->address; in arch_install_hw_breakpoint()
333 ctrl = encode_ctrl_reg(info->ctrl) | 0x1; in arch_install_hw_breakpoint()
335 if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { in arch_install_hw_breakpoint()
360 return -EBUSY; in arch_install_hw_breakpoint()
364 if (info->step_ctrl.enabled) { in arch_install_hw_breakpoint()
365 addr = info->trigger & ~0x3; in arch_install_hw_breakpoint()
366 ctrl = encode_ctrl_reg(info->step_ctrl); in arch_install_hw_breakpoint()
367 if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE) { in arch_install_hw_breakpoint()
378 write_wb_reg(ctrl_base + i, ctrl); in arch_install_hw_breakpoint()
388 if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { in arch_uninstall_hw_breakpoint()
416 if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE && in arch_uninstall_hw_breakpoint()
417 info->step_ctrl.enabled) { in arch_uninstall_hw_breakpoint()
453 unsigned int len; in arch_check_bp_in_kernelspace() local
456 va = hw->address; in arch_check_bp_in_kernelspace()
457 len = get_hbp_len(hw->ctrl.len); in arch_check_bp_in_kernelspace()
459 return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); in arch_check_bp_in_kernelspace()
467 int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, in arch_bp_generic_fields() argument
471 switch (ctrl.type) { in arch_bp_generic_fields()
485 return -EINVAL; in arch_bp_generic_fields()
488 /* Len */ in arch_bp_generic_fields()
489 switch (ctrl.len) { in arch_bp_generic_fields()
503 return -EINVAL; in arch_bp_generic_fields()
517 switch (attr->bp_type) { in arch_build_bp_info()
519 hw->ctrl.type = ARM_BREAKPOINT_EXECUTE; in arch_build_bp_info()
522 hw->ctrl.type = ARM_BREAKPOINT_LOAD; in arch_build_bp_info()
525 hw->ctrl.type = ARM_BREAKPOINT_STORE; in arch_build_bp_info()
528 hw->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE; in arch_build_bp_info()
531 return -EINVAL; in arch_build_bp_info()
534 /* Len */ in arch_build_bp_info()
535 switch (attr->bp_len) { in arch_build_bp_info()
537 hw->ctrl.len = ARM_BREAKPOINT_LEN_1; in arch_build_bp_info()
540 hw->ctrl.len = ARM_BREAKPOINT_LEN_2; in arch_build_bp_info()
543 hw->ctrl.len = ARM_BREAKPOINT_LEN_4; in arch_build_bp_info()
546 hw->ctrl.len = ARM_BREAKPOINT_LEN_8; in arch_build_bp_info()
547 if ((hw->ctrl.type != ARM_BREAKPOINT_EXECUTE) in arch_build_bp_info()
552 return -EINVAL; in arch_build_bp_info()
561 if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE && in arch_build_bp_info()
562 hw->ctrl.len != ARM_BREAKPOINT_LEN_2 && in arch_build_bp_info()
563 hw->ctrl.len != ARM_BREAKPOINT_LEN_4) in arch_build_bp_info()
564 return -EINVAL; in arch_build_bp_info()
567 hw->address = attr->bp_addr; in arch_build_bp_info()
570 hw->ctrl.privilege = ARM_BREAKPOINT_USER; in arch_build_bp_info()
572 hw->ctrl.privilege |= ARM_BREAKPOINT_PRIV; in arch_build_bp_info()
575 hw->ctrl.enabled = !attr->disabled; in arch_build_bp_info()
578 hw->ctrl.mismatch = 0; in arch_build_bp_info()
584 * Validate the arch-specific HW Breakpoint register settings.
595 return -ENODEV; in hw_breakpoint_arch_parse()
603 if (hw->ctrl.len == ARM_BREAKPOINT_LEN_8) in hw_breakpoint_arch_parse()
605 offset = hw->address & alignment_mask; in hw_breakpoint_arch_parse()
613 if (hw->ctrl.len == ARM_BREAKPOINT_LEN_2) in hw_breakpoint_arch_parse()
618 if (hw->ctrl.len == ARM_BREAKPOINT_LEN_1) in hw_breakpoint_arch_parse()
622 ret = -EINVAL; in hw_breakpoint_arch_parse()
626 hw->address &= ~alignment_mask; in hw_breakpoint_arch_parse()
627 hw->ctrl.len <<= offset; in hw_breakpoint_arch_parse()
631 * Mismatch breakpoints are required for single-stepping in hw_breakpoint_arch_parse()
635 return -EINVAL; in hw_breakpoint_arch_parse()
639 return -EPERM; in hw_breakpoint_arch_parse()
642 * Per-cpu breakpoints are not supported by our stepping in hw_breakpoint_arch_parse()
645 if (!bp->hw.target) in hw_breakpoint_arch_parse()
646 return -EINVAL; in hw_breakpoint_arch_parse()
653 (hw->ctrl.type == ARM_BREAKPOINT_LOAD || in hw_breakpoint_arch_parse()
654 hw->ctrl.type == ARM_BREAKPOINT_STORE)) in hw_breakpoint_arch_parse()
655 return -EINVAL; in hw_breakpoint_arch_parse()
663 * Enable/disable single-stepping over the breakpoint bp at address addr.
670 info->step_ctrl.mismatch = 1; in enable_single_step()
671 info->step_ctrl.len = ARM_BREAKPOINT_LEN_4; in enable_single_step()
672 info->step_ctrl.type = ARM_BREAKPOINT_EXECUTE; in enable_single_step()
673 info->step_ctrl.privilege = info->ctrl.privilege; in enable_single_step()
674 info->step_ctrl.enabled = 1; in enable_single_step()
675 info->trigger = addr; in enable_single_step()
682 counter_arch_bp(bp)->step_ctrl.enabled = 0; in disable_single_step()
690 * addresses. There is no straight-forward way, short of disassembling the
702 struct arch_hw_breakpoint_ctrl *ctrl) in get_distance_from_watchpoint() argument
707 lens = __ffs(ctrl->len); in get_distance_from_watchpoint()
708 lene = __fls(ctrl->len); in get_distance_from_watchpoint()
713 return wp_low - addr; in get_distance_from_watchpoint()
715 return addr - wp_high; in get_distance_from_watchpoint()
723 return !user_mode(regs) && info->ctrl.privilege == ARM_BREAKPOINT_USER; in watchpoint_fault_on_uaccess()
730 u32 min_dist = -1, dist; in watchpoint_handler()
734 struct arch_hw_breakpoint_ctrl ctrl; in watchpoint_handler() local
757 info->trigger = wp->attr.bp_addr; in watchpoint_handler()
769 decode_ctrl_reg(ctrl_reg, &ctrl); in watchpoint_handler()
770 dist = get_distance_from_watchpoint(addr, val, &ctrl); in watchpoint_handler()
781 info->trigger = addr; in watchpoint_handler()
784 pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); in watchpoint_handler()
799 * we can single-step over the watchpoint trigger. in watchpoint_handler()
807 if (min_dist > 0 && min_dist != -1) { in watchpoint_handler()
811 info->trigger = addr; in watchpoint_handler()
812 pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); in watchpoint_handler()
838 if (!info->step_ctrl.enabled) in watchpoint_single_step_handler()
843 * single-step. in watchpoint_single_step_handler()
845 if (info->trigger != pc) in watchpoint_single_step_handler()
859 struct arch_hw_breakpoint_ctrl ctrl; in breakpoint_handler() local
864 addr = regs->ARM_pc; in breakpoint_handler()
884 decode_ctrl_reg(ctrl_reg, &ctrl); in breakpoint_handler()
885 if ((1 << (addr & 0x3)) & ctrl.len) { in breakpoint_handler()
886 info->trigger = addr; in breakpoint_handler()
896 if (info->step_ctrl.enabled) in breakpoint_handler()
902 /* Handle any pending watchpoint single-step breakpoints. */ in breakpoint_handler()
962 * One-time initialisation.
1019 * can be maintained across low-power modes without leaving the debug in reset_ctrl_regs()
1032 * Ensure sticky power-down is clear (i.e. debug logic is in reset_ctrl_regs()
1037 err = -EPERM; in reset_ctrl_regs()
1048 err = -EPERM; in reset_ctrl_regs()
1066 * Clear any configured vector-catch events before in reset_ctrl_regs()