~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to arch/arm/kernel/hw_breakpoint.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
 
46
46
/* Number of BRP/WRP registers on this CPU. */
47
47
static int core_num_brps;
48
 
static int core_num_reserved_brps;
49
48
static int core_num_wrps;
50
49
 
51
50
/* Debug architecture version. */
137
136
        u32 didr;
138
137
 
139
138
        /* Do we implement the extended CPUID interface? */
140
 
        if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf),
141
 
            "CPUID feature registers not supported. "
142
 
            "Assuming v6 debug is present.\n"))
 
139
        if (((read_cpuid_id() >> 16) & 0xf) != 0xf) {
 
140
                pr_warning("CPUID feature registers not supported. "
 
141
                           "Assuming v6 debug is present.\n");
143
142
                return ARM_DEBUG_ARCH_V6;
 
143
        }
144
144
 
145
145
        ARM_DBG_READ(c0, 0, didr);
146
146
        return (didr >> 16) & 0xf;
154
154
static int debug_arch_supported(void)
155
155
{
156
156
        u8 arch = get_debug_arch();
157
 
        return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14;
158
 
}
159
 
 
160
 
/* Determine number of BRP register available. */
 
157
 
 
158
        /* We don't support the memory-mapped interface. */
 
159
        return (arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14) ||
 
160
                arch >= ARM_DEBUG_ARCH_V7_1;
 
161
}
 
162
 
 
163
/* Determine number of WRP registers available. */
 
164
static int get_num_wrp_resources(void)
 
165
{
 
166
        u32 didr;
 
167
        ARM_DBG_READ(c0, 0, didr);
 
168
        return ((didr >> 28) & 0xf) + 1;
 
169
}
 
170
 
 
171
/* Determine number of BRP registers available. */
161
172
static int get_num_brp_resources(void)
162
173
{
163
174
        u32 didr;
176
187
static int get_num_wrps(void)
177
188
{
178
189
        /*
179
 
         * FIXME: When a watchpoint fires, the only way to work out which
180
 
         * watchpoint it was is by disassembling the faulting instruction
181
 
         * and working out the address of the memory access.
 
190
         * On debug architectures prior to 7.1, when a watchpoint fires, the
 
191
         * only way to work out which watchpoint it was is by disassembling
 
192
         * the faulting instruction and working out the address of the memory
 
193
         * access.
182
194
         *
183
195
         * Furthermore, we can only do this if the watchpoint was precise
184
196
         * since imprecise watchpoints prevent us from calculating register
192
204
         * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows
193
205
         * that it is set on some implementations].
194
206
         */
195
 
 
196
 
#if 0
197
 
        int wrps;
198
 
        u32 didr;
199
 
        ARM_DBG_READ(c0, 0, didr);
200
 
        wrps = ((didr >> 28) & 0xf) + 1;
201
 
#endif
202
 
        int wrps = 1;
203
 
 
204
 
        if (core_has_mismatch_brps() && wrps >= get_num_brp_resources())
205
 
                wrps = get_num_brp_resources() - 1;
206
 
 
207
 
        return wrps;
208
 
}
209
 
 
210
 
/* We reserve one breakpoint for each watchpoint. */
211
 
static int get_num_reserved_brps(void)
212
 
{
213
 
        if (core_has_mismatch_brps())
214
 
                return get_num_wrps();
215
 
        return 0;
 
207
        if (get_debug_arch() < ARM_DEBUG_ARCH_V7_1)
 
208
                return 1;
 
209
 
 
210
        return get_num_wrp_resources();
216
211
}
217
212
 
218
213
/* Determine number of usable BRPs available. */
219
214
static int get_num_brps(void)
220
215
{
221
216
        int brps = get_num_brp_resources();
222
 
        if (core_has_mismatch_brps())
223
 
                brps -= get_num_reserved_brps();
224
 
        return brps;
 
217
        return core_has_mismatch_brps() ? brps - 1 : brps;
225
218
}
226
219
 
227
220
/*
239
232
 
240
233
        /* Ensure that halting mode is disabled. */
241
234
        if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
242
 
                        "halting debug mode enabled. Unable to access hardware resources.\n")) {
 
235
                "halting debug mode enabled. Unable to access hardware resources.\n")) {
243
236
                ret = -EPERM;
244
237
                goto out;
245
238
        }
255
248
                ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN));
256
249
                break;
257
250
        case ARM_DEBUG_ARCH_V7_ECP14:
 
251
        case ARM_DEBUG_ARCH_V7_1:
258
252
                ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN));
259
253
                break;
260
254
        default:
346
340
                val_base = ARM_BASE_BVR;
347
341
                slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
348
342
                max_slots = core_num_brps;
349
 
                if (info->step_ctrl.enabled) {
350
 
                        /* Override the breakpoint data with the step data. */
351
 
                        addr = info->trigger & ~0x3;
352
 
                        ctrl = encode_ctrl_reg(info->step_ctrl);
353
 
                }
354
343
        } else {
355
344
                /* Watchpoint */
356
 
                if (info->step_ctrl.enabled) {
357
 
                        /* Install into the reserved breakpoint region. */
358
 
                        ctrl_base = ARM_BASE_BCR + core_num_brps;
359
 
                        val_base = ARM_BASE_BVR + core_num_brps;
360
 
                        /* Override the watchpoint data with the step data. */
361
 
                        addr = info->trigger & ~0x3;
362
 
                        ctrl = encode_ctrl_reg(info->step_ctrl);
363
 
                } else {
364
 
                        ctrl_base = ARM_BASE_WCR;
365
 
                        val_base = ARM_BASE_WVR;
366
 
                }
 
345
                ctrl_base = ARM_BASE_WCR;
 
346
                val_base = ARM_BASE_WVR;
367
347
                slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
368
348
                max_slots = core_num_wrps;
369
349
        }
382
362
                goto out;
383
363
        }
384
364
 
 
365
        /* Override the breakpoint data with the step data. */
 
366
        if (info->step_ctrl.enabled) {
 
367
                addr = info->trigger & ~0x3;
 
368
                ctrl = encode_ctrl_reg(info->step_ctrl);
 
369
                if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE) {
 
370
                        i = 0;
 
371
                        ctrl_base = ARM_BASE_BCR + core_num_brps;
 
372
                        val_base = ARM_BASE_BVR + core_num_brps;
 
373
                }
 
374
        }
 
375
 
385
376
        /* Setup the address register. */
386
377
        write_wb_reg(val_base + i, addr);
387
378
 
405
396
                max_slots = core_num_brps;
406
397
        } else {
407
398
                /* Watchpoint */
408
 
                if (info->step_ctrl.enabled)
409
 
                        base = ARM_BASE_BCR + core_num_brps;
410
 
                else
411
 
                        base = ARM_BASE_WCR;
 
399
                base = ARM_BASE_WCR;
412
400
                slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
413
401
                max_slots = core_num_wrps;
414
402
        }
426
414
        if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
427
415
                return;
428
416
 
 
417
        /* Ensure that we disable the mismatch breakpoint. */
 
418
        if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE &&
 
419
            info->step_ctrl.enabled) {
 
420
                i = 0;
 
421
                base = ARM_BASE_BCR + core_num_brps;
 
422
        }
 
423
 
429
424
        /* Reset the control register. */
430
425
        write_wb_reg(base + i, 0);
431
426
}
632
627
         * we can use the mismatch feature as a poor-man's hardware
633
628
         * single-step, but this only works for per-task breakpoints.
634
629
         */
635
 
        if (WARN_ONCE(!bp->overflow_handler &&
636
 
                (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
637
 
                 || !bp->hw.bp_target),
638
 
                        "overflow handler required but none found\n")) {
 
630
        if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) ||
 
631
            !core_has_mismatch_brps() || !bp->hw.bp_target)) {
 
632
                pr_warning("overflow handler required but none found\n");
639
633
                ret = -EINVAL;
640
634
        }
641
635
out:
666
660
        arch_install_hw_breakpoint(bp);
667
661
}
668
662
 
669
 
static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)
 
663
static void watchpoint_handler(unsigned long addr, unsigned int fsr,
 
664
                               struct pt_regs *regs)
670
665
{
671
 
        int i;
 
666
        int i, access;
 
667
        u32 val, ctrl_reg, alignment_mask;
672
668
        struct perf_event *wp, **slots;
673
669
        struct arch_hw_breakpoint *info;
 
670
        struct arch_hw_breakpoint_ctrl ctrl;
674
671
 
675
672
        slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
676
673
 
677
 
        /* Without a disassembler, we can only handle 1 watchpoint. */
678
 
        BUG_ON(core_num_wrps > 1);
679
 
 
680
674
        for (i = 0; i < core_num_wrps; ++i) {
681
675
                rcu_read_lock();
682
676
 
683
677
                wp = slots[i];
684
678
 
685
 
                if (wp == NULL) {
686
 
                        rcu_read_unlock();
687
 
                        continue;
688
 
                }
 
679
                if (wp == NULL)
 
680
                        goto unlock;
689
681
 
 
682
                info = counter_arch_bp(wp);
690
683
                /*
691
 
                 * The DFAR is an unknown value. Since we only allow a
692
 
                 * single watchpoint, we can set the trigger to the lowest
693
 
                 * possible faulting address.
 
684
                 * The DFAR is an unknown value on debug architectures prior
 
685
                 * to 7.1. Since we only allow a single watchpoint on these
 
686
                 * older CPUs, we can set the trigger to the lowest possible
 
687
                 * faulting address.
694
688
                 */
695
 
                info = counter_arch_bp(wp);
696
 
                info->trigger = wp->attr.bp_addr;
 
689
                if (debug_arch < ARM_DEBUG_ARCH_V7_1) {
 
690
                        BUG_ON(i > 0);
 
691
                        info->trigger = wp->attr.bp_addr;
 
692
                } else {
 
693
                        if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
 
694
                                alignment_mask = 0x7;
 
695
                        else
 
696
                                alignment_mask = 0x3;
 
697
 
 
698
                        /* Check if the watchpoint value matches. */
 
699
                        val = read_wb_reg(ARM_BASE_WVR + i);
 
700
                        if (val != (addr & ~alignment_mask))
 
701
                                goto unlock;
 
702
 
 
703
                        /* Possible match, check the byte address select. */
 
704
                        ctrl_reg = read_wb_reg(ARM_BASE_WCR + i);
 
705
                        decode_ctrl_reg(ctrl_reg, &ctrl);
 
706
                        if (!((1 << (addr & alignment_mask)) & ctrl.len))
 
707
                                goto unlock;
 
708
 
 
709
                        /* Check that the access type matches. */
 
710
                        access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W :
 
711
                                 HW_BREAKPOINT_R;
 
712
                        if (!(access & hw_breakpoint_type(wp)))
 
713
                                goto unlock;
 
714
 
 
715
                        /* We have a winner. */
 
716
                        info->trigger = addr;
 
717
                }
 
718
 
697
719
                pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
698
720
                perf_bp_event(wp, regs);
699
721
 
705
727
                if (!wp->overflow_handler)
706
728
                        enable_single_step(wp, instruction_pointer(regs));
707
729
 
 
730
unlock:
708
731
                rcu_read_unlock();
709
732
        }
710
733
}
717
740
 
718
741
        slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
719
742
 
720
 
        for (i = 0; i < core_num_reserved_brps; ++i) {
 
743
        for (i = 0; i < core_num_wrps; ++i) {
721
744
                rcu_read_lock();
722
745
 
723
746
                wp = slots[i];
796
819
 
797
820
/*
798
821
 * Called from either the Data Abort Handler [watchpoint] or the
799
 
 * Prefetch Abort Handler [breakpoint] with preemption disabled.
 
822
 * Prefetch Abort Handler [breakpoint] with interrupts disabled.
800
823
 */
801
824
static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
802
825
                                 struct pt_regs *regs)
804
827
        int ret = 0;
805
828
        u32 dscr;
806
829
 
807
 
        /* We must be called with preemption disabled. */
808
 
        WARN_ON(preemptible());
 
830
        preempt_disable();
 
831
 
 
832
        if (interrupts_enabled(regs))
 
833
                local_irq_enable();
809
834
 
810
835
        /* We only handle watchpoints and hardware breakpoints. */
811
836
        ARM_DBG_READ(c1, 0, dscr);
818
843
        case ARM_ENTRY_ASYNC_WATCHPOINT:
819
844
                WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n");
820
845
        case ARM_ENTRY_SYNC_WATCHPOINT:
821
 
                watchpoint_handler(addr, regs);
 
846
                watchpoint_handler(addr, fsr, regs);
822
847
                break;
823
848
        default:
824
849
                ret = 1; /* Unhandled fault. */
825
850
        }
826
851
 
827
 
        /*
828
 
         * Re-enable preemption after it was disabled in the
829
 
         * low-level exception handling code.
830
 
         */
831
852
        preempt_enable();
832
853
 
833
854
        return ret;
836
857
/*
837
858
 * One-time initialisation.
838
859
 */
839
 
static void reset_ctrl_regs(void *info)
840
 
{
841
 
        int i, cpu = smp_processor_id();
 
860
static cpumask_t debug_err_mask;
 
861
 
 
862
static int debug_reg_trap(struct pt_regs *regs, unsigned int instr)
 
863
{
 
864
        int cpu = smp_processor_id();
 
865
 
 
866
        pr_warning("Debug register access (0x%x) caused undefined instruction on CPU %d\n",
 
867
                   instr, cpu);
 
868
 
 
869
        /* Set the error flag for this CPU and skip the faulting instruction. */
 
870
        cpumask_set_cpu(cpu, &debug_err_mask);
 
871
        instruction_pointer(regs) += 4;
 
872
        return 0;
 
873
}
 
874
 
 
875
static struct undef_hook debug_reg_hook = {
 
876
        .instr_mask     = 0x0fe80f10,
 
877
        .instr_val      = 0x0e000e10,
 
878
        .fn             = debug_reg_trap,
 
879
};
 
880
 
 
881
static void reset_ctrl_regs(void *unused)
 
882
{
 
883
        int i, raw_num_brps, err = 0, cpu = smp_processor_id();
842
884
        u32 dbg_power;
843
 
        cpumask_t *cpumask = info;
844
885
 
845
886
        /*
846
887
         * v7 debug contains save and restore registers so that debug state
850
891
         * Access Register to avoid taking undefined instruction exceptions
851
892
         * later on.
852
893
         */
853
 
        if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) {
 
894
        switch (debug_arch) {
 
895
        case ARM_DEBUG_ARCH_V6:
 
896
        case ARM_DEBUG_ARCH_V6_1:
 
897
                /* ARMv6 cores just need to reset the registers. */
 
898
                goto reset_regs;
 
899
        case ARM_DEBUG_ARCH_V7_ECP14:
854
900
                /*
855
901
                 * Ensure sticky power-down is clear (i.e. debug logic is
856
902
                 * powered up).
857
903
                 */
858
904
                asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power));
859
 
                if ((dbg_power & 0x1) == 0) {
860
 
                        pr_warning("CPU %d debug is powered down!\n", cpu);
861
 
                        cpumask_or(cpumask, cpumask, cpumask_of(cpu));
862
 
                        return;
863
 
                }
864
 
 
865
 
                /*
866
 
                 * Unconditionally clear the lock by writing a value
867
 
                 * other than 0xC5ACCE55 to the access register.
868
 
                 */
869
 
                asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0));
870
 
                isb();
871
 
 
872
 
                /*
873
 
                 * Clear any configured vector-catch events before
874
 
                 * enabling monitor mode.
875
 
                 */
876
 
                asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0));
877
 
                isb();
878
 
        }
879
 
 
 
905
                if ((dbg_power & 0x1) == 0)
 
906
                        err = -EPERM;
 
907
                break;
 
908
        case ARM_DEBUG_ARCH_V7_1:
 
909
                /*
 
910
                 * Ensure the OS double lock is clear.
 
911
                 */
 
912
                asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (dbg_power));
 
913
                if ((dbg_power & 0x1) == 1)
 
914
                        err = -EPERM;
 
915
                break;
 
916
        }
 
917
 
 
918
        if (err) {
 
919
                pr_warning("CPU %d debug is powered down!\n", cpu);
 
920
                cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
 
921
                return;
 
922
        }
 
923
 
 
924
        /*
 
925
         * Unconditionally clear the lock by writing a value
 
926
         * other than 0xC5ACCE55 to the access register.
 
927
         */
 
928
        asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0));
 
929
        isb();
 
930
 
 
931
        /*
 
932
         * Clear any configured vector-catch events before
 
933
         * enabling monitor mode.
 
934
         */
 
935
        asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0));
 
936
        isb();
 
937
 
 
938
reset_regs:
880
939
        if (enable_monitor_mode())
881
940
                return;
882
941
 
883
942
        /* We must also reset any reserved registers. */
884
 
        for (i = 0; i < core_num_brps + core_num_reserved_brps; ++i) {
 
943
        raw_num_brps = get_num_brp_resources();
 
944
        for (i = 0; i < raw_num_brps; ++i) {
885
945
                write_wb_reg(ARM_BASE_BCR + i, 0UL);
886
946
                write_wb_reg(ARM_BASE_BVR + i, 0UL);
887
947
        }
897
957
{
898
958
        if (action == CPU_ONLINE)
899
959
                smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1);
 
960
 
900
961
        return NOTIFY_OK;
901
962
}
902
963
 
907
968
static int __init arch_hw_breakpoint_init(void)
908
969
{
909
970
        u32 dscr;
910
 
        cpumask_t cpumask = { CPU_BITS_NONE };
911
971
 
912
972
        debug_arch = get_debug_arch();
913
973
 
918
978
 
919
979
        /* Determine how many BRPs/WRPs are available. */
920
980
        core_num_brps = get_num_brps();
921
 
        core_num_reserved_brps = get_num_reserved_brps();
922
981
        core_num_wrps = get_num_wrps();
923
982
 
924
 
        pr_info("found %d breakpoint and %d watchpoint registers.\n",
925
 
                core_num_brps + core_num_reserved_brps, core_num_wrps);
926
 
 
927
 
        if (core_num_reserved_brps)
928
 
                pr_info("%d breakpoint(s) reserved for watchpoint "
929
 
                                "single-step.\n", core_num_reserved_brps);
 
983
        /*
 
984
         * We need to tread carefully here because DBGSWENABLE may be
 
985
         * driven low on this core and there isn't an architected way to
 
986
         * determine that.
 
987
         */
 
988
        register_undef_hook(&debug_reg_hook);
930
989
 
931
990
        /*
932
991
         * Reset the breakpoint resources. We assume that a halting
933
992
         * debugger will leave the world in a nice state for us.
934
993
         */
935
 
        on_each_cpu(reset_ctrl_regs, &cpumask, 1);
936
 
        if (!cpumask_empty(&cpumask)) {
 
994
        on_each_cpu(reset_ctrl_regs, NULL, 1);
 
995
        unregister_undef_hook(&debug_reg_hook);
 
996
        if (!cpumask_empty(&debug_err_mask)) {
937
997
                core_num_brps = 0;
938
 
                core_num_reserved_brps = 0;
939
998
                core_num_wrps = 0;
940
999
                return 0;
941
1000
        }
942
1001
 
 
1002
        pr_info("found %d " "%s" "breakpoint and %d watchpoint registers.\n",
 
1003
                core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " :
 
1004
                "", core_num_wrps);
 
1005
 
943
1006
        ARM_DBG_READ(c1, 0, dscr);
944
1007
        if (dscr & ARM_DSCR_HDBGEN) {
945
1008
                max_watchpoint_len = 4;