From owner-svn-src-head@freebsd.org Sun May 29 17:33:50 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D82F1B54239; Sun, 29 May 2016 17:33:50 +0000 (UTC) (envelope-from zbb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 99B1F13A9; Sun, 29 May 2016 17:33:50 +0000 (UTC) (envelope-from zbb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u4THXn2c053933; Sun, 29 May 2016 17:33:49 GMT (envelope-from zbb@FreeBSD.org) Received: (from zbb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4THXn93053932; Sun, 29 May 2016 17:33:49 GMT (envelope-from zbb@FreeBSD.org) Message-Id: <201605291733.u4THXn93053932@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: zbb set sender to zbb@FreeBSD.org using -f From: Zbigniew Bodek Date: Sun, 29 May 2016 17:33:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r300968 - head/sys/arm/arm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 29 May 2016 17:33:50 -0000 Author: zbb Date: Sun May 29 17:33:49 2016 New Revision: 300968 URL: https://svnweb.freebsd.org/changeset/base/300968 Log: Fix debug_monitor code for older ARMs (ARM11) - Enable monitor mode prior to accessing watchpoint registers for v6, v6.1 architectures. - Fix configuration scheme for v6, v6.1 and v7 Debug Archs - Enable monitor unconditionally and for good instead of enabling and disabling it (needed for single stepping on on v6/v6.1) Tested on RPI-B and Arndale Differential Revision: https://reviews.freebsd.org/D6008 Modified: head/sys/arm/arm/debug_monitor.c Modified: head/sys/arm/arm/debug_monitor.c ============================================================================== --- head/sys/arm/arm/debug_monitor.c Sun May 29 17:32:19 2016 (r300967) +++ head/sys/arm/arm/debug_monitor.c Sun May 29 17:33:49 2016 (r300968) @@ -82,8 +82,6 @@ static boolean_t dbg_ossr; /* OS Save an static uint32_t dbg_watchpoint_num; static uint32_t dbg_breakpoint_num; -static int dbg_ref_count_mme; /* Times monitor mode was enabled */ - /* ID_DFR0 - Debug Feature Register 0 */ #define ID_DFR0_CP_DEBUG_M_SHIFT 0 #define ID_DFR0_CP_DEBUG_M_MASK (0xF << ID_DFR0_CP_DEBUG_M_SHIFT) @@ -250,6 +248,13 @@ dbg_wb_write_reg(int reg, int n, uint32_ boolean_t kdb_cpu_pc_is_singlestep(db_addr_t pc) { + /* + * XXX: If the platform fails to enable its debug arch. + * there will be no stepping capabilities + * (SOFTWARE_SSTEP is not defined for __ARM_ARCH >= 6). + */ + if (!dbg_capable) + return (FALSE); if (dbg_find_slot(DBG_TYPE_BREAKPOINT, pc) != ~0U) return (TRUE); @@ -265,6 +270,9 @@ kdb_cpu_set_singlestep(void) uint32_t wcr; u_int i; + if (!dbg_capable) + return; + /* * Disable watchpoints, e.g. stepping over watched instruction will * trigger break exception instead of single-step exception and locks @@ -295,6 +303,9 @@ kdb_cpu_clear_singlestep(void) uint32_t wvr, wcr; u_int i; + if (!dbg_capable) + return; + dbg_remove_breakpoint(DBG_BKPT_BT_SLOT); dbg_remove_breakpoint(DBG_BKPT_BNT_SLOT); @@ -572,34 +583,6 @@ dbg_enable_monitor(void) } static int -dbg_disable_monitor(void) -{ - uint32_t dbg_dscr; - - if (!dbg_monitor_is_enabled()) - return (0); - - dbg_dscr = cp14_dbgdscrint_get(); - switch (dbg_model) { - case ID_DFR0_CP_DEBUG_M_V6: - case ID_DFR0_CP_DEBUG_M_V6_1: /* fall through */ - dbg_dscr &= ~DBGSCR_MDBG_EN; - cp14_dbgdscr_v6_set(dbg_dscr); - break; - case ID_DFR0_CP_DEBUG_M_V7: /* fall through */ - case ID_DFR0_CP_DEBUG_M_V7_1: - dbg_dscr &= ~DBGSCR_MDBG_EN; - cp14_dbgdscr_v7_set(dbg_dscr); - break; - default: - return (ENXIO); - } - isb(); - - return (0); -} - -static int dbg_setup_xpoint(struct dbg_wb_conf *conf) { struct pcpu *pcpu; @@ -702,13 +685,6 @@ dbg_setup_xpoint(struct dbg_wb_conf *con dbg_wb_write_reg(reg_addr, i, addr); dbg_wb_write_reg(reg_ctrl, i, ctrl); - err = dbg_enable_monitor(); - if (err != 0) - return (err); - - /* Increment monitor enable counter */ - dbg_ref_count_mme++; - /* * Save watchpoint settings for all CPUs. * We don't need to do the same with breakpoints since HW breakpoints @@ -775,19 +751,6 @@ dbg_remove_xpoint(struct dbg_wb_conf *co dbg_wb_write_reg(reg_ctrl, i, 0); dbg_wb_write_reg(reg_addr, i, 0); - /* Decrement monitor enable counter */ - dbg_ref_count_mme--; - if (dbg_ref_count_mme < 0) - dbg_ref_count_mme = 0; - - atomic_thread_fence_rel(); - - if (dbg_ref_count_mme == 0) { - err = dbg_disable_monitor(); - if (err != 0) - return (err); - } - /* * Save watchpoint settings for all CPUs. * We don't need to do the same with breakpoints since HW breakpoints @@ -827,7 +790,7 @@ dbg_get_ossr(void) { switch (dbg_model) { - case ID_DFR0_CP_DEBUG_M_V6_1: + case ID_DFR0_CP_DEBUG_M_V7: if ((cp14_dbgoslsr_get() & DBGOSLSR_OSLM0) != 0) return (TRUE); @@ -844,10 +807,8 @@ dbg_arch_supported(void) { switch (dbg_model) { -#ifdef not_yet case ID_DFR0_CP_DEBUG_M_V6: case ID_DFR0_CP_DEBUG_M_V6_1: -#endif case ID_DFR0_CP_DEBUG_M_V7: case ID_DFR0_CP_DEBUG_M_V7_1: /* fall through */ return (TRUE); @@ -889,9 +850,16 @@ dbg_reset_state(void) switch (dbg_model) { case ID_DFR0_CP_DEBUG_M_V6: - /* v6 Debug logic reset upon power-up */ - return (0); - case ID_DFR0_CP_DEBUG_M_V6_1: + case ID_DFR0_CP_DEBUG_M_V6_1: /* fall through */ + /* + * Arch needs monitor mode selected and enabled + * to be able to access breakpoint/watchpoint registers. + */ + err = dbg_enable_monitor(); + if (err != 0) + return (err); + goto vectr_clr; + case ID_DFR0_CP_DEBUG_M_V7: /* Is core power domain powered up? */ if ((cp14_dbgprsr_get() & DBGPRSR_PU) == 0) err = ENXIO; @@ -902,8 +870,6 @@ dbg_reset_state(void) if (dbg_ossr) goto vectr_clr; break; - case ID_DFR0_CP_DEBUG_M_V7: - break; case ID_DFR0_CP_DEBUG_M_V7_1: /* Is double lock set? */ if ((cp14_dbgosdlr_get() & DBGPRSR_DLK) != 0) @@ -998,8 +964,11 @@ dbg_monitor_init(void) err = dbg_reset_state(); if (err == 0) { - dbg_capable = TRUE; - return; + err = dbg_enable_monitor(); + if (err == 0) { + dbg_capable = TRUE; + return; + } } db_printf("HW Breakpoints/Watchpoints not enabled on CPU%d\n", @@ -1050,21 +1019,6 @@ dbg_resume_dbreg(void) dbg_wb_write_reg(DBG_REG_BASE_WCR, i, d->dbg_wcr[i]); } - if ((dbg_ref_count_mme > 0) && !dbg_monitor_is_enabled()) { - err = dbg_enable_monitor(); - if (err != 0) { - panic("%s: Failed to enable Debug Monitor " - "on CPU%d", __func__, cpuid); - } - } - if ((dbg_ref_count_mme == 0) && dbg_monitor_is_enabled()) { - err = dbg_disable_monitor(); - if (err != 0) { - panic("%s: Failed to disable Debug Monitor " - "on CPU%d", __func__, cpuid); - } - } - PCPU_SET(dbreg_cmd, PC_DBREG_CMD_NONE); break; }