summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig.debug16
-rw-r--r--arch/arm/Makefile3
-rw-r--r--arch/arm/boot/compressed/Makefile7
-rw-r--r--arch/arm/boot/compressed/debug.S5
-rw-r--r--arch/arm/boot/compressed/head.S74
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.S4
-rw-r--r--arch/arm/include/debug/8250.S7
-rw-r--r--arch/arm/include/debug/asm9260.S5
-rw-r--r--arch/arm/include/debug/at91.S5
-rw-r--r--arch/arm/include/debug/bcm63xx.S5
-rw-r--r--arch/arm/include/debug/brcmstb.S5
-rw-r--r--arch/arm/include/debug/clps711x.S5
-rw-r--r--arch/arm/include/debug/dc21285.S5
-rw-r--r--arch/arm/include/debug/digicolor.S5
-rw-r--r--arch/arm/include/debug/efm32.S5
-rw-r--r--arch/arm/include/debug/icedcc.S15
-rw-r--r--arch/arm/include/debug/imx.S5
-rw-r--r--arch/arm/include/debug/meson.S5
-rw-r--r--arch/arm/include/debug/msm.S5
-rw-r--r--arch/arm/include/debug/omap2plus.S5
-rw-r--r--arch/arm/include/debug/pl01x.S5
-rw-r--r--arch/arm/include/debug/renesas-scif.S5
-rw-r--r--arch/arm/include/debug/sa1100.S5
-rw-r--r--arch/arm/include/debug/samsung.S5
-rw-r--r--arch/arm/include/debug/sirf.S5
-rw-r--r--arch/arm/include/debug/sti.S5
-rw-r--r--arch/arm/include/debug/stm32.S5
-rw-r--r--arch/arm/include/debug/tegra.S7
-rw-r--r--arch/arm/include/debug/vf.S5
-rw-r--r--arch/arm/include/debug/vt8500.S5
-rw-r--r--arch/arm/include/debug/zynq.S5
-rw-r--r--arch/arm/kernel/debug.S11
-rw-r--r--arch/arm/kernel/hw_breakpoint.c100
-rw-r--r--arch/arm/mm/cache-l2x0.c16
34 files changed, 263 insertions, 112 deletions
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 80000a66a4e3..87912e5c2256 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -1546,6 +1546,17 @@ config DEBUG_SIRFSOC_UART
bool
depends on ARCH_SIRF
+config DEBUG_UART_FLOW_CONTROL
+ bool "Enable flow control (CTS) for the debug UART"
+ depends on DEBUG_LL
+ default y if ARCH_EBSA110 || DEBUG_FOOTBRIDGE_COM1 || DEBUG_GEMINI || ARCH_RPC
+ help
+ Some UART ports are connected to terminals that will use modem
+ control signals to indicate whether they are ready to receive text.
+ In practice this means that the terminal is asserting the special
+ control signal CTS (Clear To Send). If your debug UART supports
+ this and your debug terminal will require it, enable this option.
+
config DEBUG_LL_INCLUDE
string
default "debug/sa1100.S" if DEBUG_SA1100
@@ -1893,11 +1904,6 @@ config DEBUG_UART_8250_PALMCHIP
except for having a different register layout. Say Y here if
the debug UART is of this type.
-config DEBUG_UART_8250_FLOW_CONTROL
- bool "Enable flow control for 8250 UART"
- depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
- default y if ARCH_EBSA110 || DEBUG_FOOTBRIDGE_COM1 || DEBUG_GEMINI || ARCH_RPC
-
config DEBUG_UNCOMPRESS
bool "Enable decompressor debugging via DEBUG_LL output"
depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index e589da3c8949..c4301437ca72 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -143,6 +143,9 @@ head-y := arch/arm/kernel/head$(MMUEXT).o
# Text offset. This list is sorted numerically by address in order to
# provide a means to avoid/resolve conflicts in multi-arch kernels.
+# Note: the 32kB below this value is reserved for use by the kernel
+# during boot, and this offset is critical to the functioning of
+# kexec-tools.
textofs-y := 0x00008000
# We don't want the htc bootloader to corrupt kernel during resume
textofs-$(CONFIG_PM_H1940) := 0x00108000
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 58028abd05d9..47f001ca5499 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -7,11 +7,11 @@
OBJS =
-AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
HEAD = head.o
OBJS += misc.o decompress.o
ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
OBJS += debug.o
+AFLAGS_head.o += -DDEBUG
endif
FONTC = $(srctree)/lib/fonts/font_acorn_8x8.c
@@ -68,7 +68,12 @@ ZTEXTADDR := 0
ZBSSADDR := ALIGN(8)
endif
+MALLOC_SIZE := 65536
+
+AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) -DMALLOC_SIZE=$(MALLOC_SIZE)
CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"
+CPPFLAGS_vmlinux.lds += -DTEXT_OFFSET="$(TEXT_OFFSET)"
+CPPFLAGS_vmlinux.lds += -DMALLOC_SIZE="$(MALLOC_SIZE)"
compress-$(CONFIG_KERNEL_GZIP) = gzip
compress-$(CONFIG_KERNEL_LZO) = lzo
diff --git a/arch/arm/boot/compressed/debug.S b/arch/arm/boot/compressed/debug.S
index 6bf2917a4621..fac40a717fcf 100644
--- a/arch/arm/boot/compressed/debug.S
+++ b/arch/arm/boot/compressed/debug.S
@@ -8,7 +8,10 @@
ENTRY(putc)
addruart r1, r2, r3
- waituart r3, r1
+#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL
+ waituartcts r3, r1
+#endif
+ waituarttxrdy r3, r1
senduart r0, r1
busyuart r3, r1
mov pc, lr
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 434a16982e34..2e04ec5b5446 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -28,19 +28,19 @@
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
.macro loadsp, rb, tmp1, tmp2
.endm
- .macro writeb, ch, rb
+ .macro writeb, ch, rb, tmp
mcr p14, 0, \ch, c0, c5, 0
.endm
#elif defined(CONFIG_CPU_XSCALE)
.macro loadsp, rb, tmp1, tmp2
.endm
- .macro writeb, ch, rb
+ .macro writeb, ch, rb, tmp
mcr p14, 0, \ch, c8, c0, 0
.endm
#else
.macro loadsp, rb, tmp1, tmp2
.endm
- .macro writeb, ch, rb
+ .macro writeb, ch, rb, tmp
mcr p14, 0, \ch, c1, c0, 0
.endm
#endif
@@ -49,8 +49,13 @@
#include CONFIG_DEBUG_LL_INCLUDE
- .macro writeb, ch, rb
+ .macro writeb, ch, rb, tmp
+#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL
+ waituartcts \tmp, \rb
+#endif
+ waituarttxrdy \tmp, \rb
senduart \ch, \rb
+ busyuart \tmp, \rb
.endm
#if defined(CONFIG_ARCH_SA1100)
@@ -81,42 +86,11 @@
bl phex
.endm
- .macro debug_reloc_start
-#ifdef DEBUG
- kputc #'\n'
- kphex r6, 8 /* processor id */
- kputc #':'
- kphex r7, 8 /* architecture id */
-#ifdef CONFIG_CPU_CP15
- kputc #':'
- mrc p15, 0, r0, c1, c0
- kphex r0, 8 /* control reg */
-#endif
- kputc #'\n'
- kphex r5, 8 /* decompressed kernel start */
- kputc #'-'
- kphex r9, 8 /* decompressed kernel end */
- kputc #'>'
- kphex r4, 8 /* kernel execution address */
- kputc #'\n'
-#endif
- .endm
-
- .macro debug_reloc_end
-#ifdef DEBUG
- kphex r5, 8 /* end of kernel */
- kputc #'\n'
- mov r0, r4
- bl memdump /* dump 256 bytes at start of kernel */
-#endif
- .endm
-
/*
* Debug kernel copy by printing the memory addresses involved
*/
.macro dbgkc, begin, end, cbegin, cend
#ifdef DEBUG
- kputc #'\n'
kputc #'C'
kputc #':'
kputc #'0'
@@ -136,7 +110,28 @@
kputc #'x'
kphex \cend, 8 /* End of kernel copy */
kputc #'\n'
- kputc #'\r'
+#endif
+ .endm
+
+ /*
+ * Debug print of the final appended DTB location
+ */
+ .macro dbgadtb, begin, end
+#ifdef DEBUG
+ kputc #'D'
+ kputc #'T'
+ kputc #'B'
+ kputc #':'
+ kputc #'0'
+ kputc #'x'
+ kphex \begin, 8 /* Start of appended DTB */
+ kputc #' '
+ kputc #'('
+ kputc #'0'
+ kputc #'x'
+ kphex \end, 8 /* End of appended DTB */
+ kputc #')'
+ kputc #'\n'
#endif
.endm
@@ -303,7 +298,7 @@ restart: adr r0, LC1
#ifndef CONFIG_ZBOOT_ROM
/* malloc space is above the relocated stack (64k max) */
- add r10, sp, #0x10000
+ add r10, sp, #MALLOC_SIZE
#else
/*
* With ZBOOT_ROM the bss/stack is non relocatable,
@@ -357,6 +352,7 @@ restart: adr r0, LC1
mov r5, r5, ror #8
eor r5, r5, r1, lsr #8
#endif
+ dbgadtb r6, r5
/* 50% DTB growth should be good enough */
add r5, r5, r5, lsr #1
/* preserve 64-bit alignment */
@@ -614,7 +610,7 @@ not_relocated: mov r0, #0
*/
mov r0, r4
mov r1, sp @ malloc space above stack
- add r2, sp, #0x10000 @ 64k max
+ add r2, sp, #MALLOC_SIZE @ 64k max
mov r3, r7
bl decompress_kernel
@@ -1356,7 +1352,7 @@ puts: loadsp r3, r2, r1
1: ldrb r2, [r0], #1
teq r2, #0
moveq pc, lr
-2: writeb r2, r3
+2: writeb r2, r3, r1
mov r1, #0x00020000
3: subs r1, r1, #1
bne 3b
diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
index b914be3a207b..1bcb68ac4b01 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.S
+++ b/arch/arm/boot/compressed/vmlinux.lds.S
@@ -44,10 +44,12 @@ SECTIONS
}
.table : ALIGN(4) {
_table_start = .;
- LONG(ZIMAGE_MAGIC(4))
+ LONG(ZIMAGE_MAGIC(6))
LONG(ZIMAGE_MAGIC(0x5a534c4b))
LONG(ZIMAGE_MAGIC(__piggy_size_addr - _start))
LONG(ZIMAGE_MAGIC(_kernel_bss_size))
+ LONG(ZIMAGE_MAGIC(TEXT_OFFSET))
+ LONG(ZIMAGE_MAGIC(MALLOC_SIZE))
LONG(0)
_table_end = .;
}
diff --git a/arch/arm/include/debug/8250.S b/arch/arm/include/debug/8250.S
index e4a036f082c2..e3692a37cede 100644
--- a/arch/arm/include/debug/8250.S
+++ b/arch/arm/include/debug/8250.S
@@ -45,10 +45,11 @@
bne 1002b
.endm
- .macro waituart,rd,rx
-#ifdef CONFIG_DEBUG_UART_8250_FLOW_CONTROL
+ .macro waituarttxrdy,rd,rx
+ .endm
+
+ .macro waituartcts,rd,rx
1001: load \rd, [\rx, #UART_MSR << UART_SHIFT]
tst \rd, #UART_MSR_CTS
beq 1001b
-#endif
.endm
diff --git a/arch/arm/include/debug/asm9260.S b/arch/arm/include/debug/asm9260.S
index 0da1eb625331..5a0ce145c44a 100644
--- a/arch/arm/include/debug/asm9260.S
+++ b/arch/arm/include/debug/asm9260.S
@@ -11,7 +11,10 @@
ldr \rv, = CONFIG_DEBUG_UART_VIRT
.endm
- .macro waituart,rd,rx
+ .macro waituarttxrdy,rd,rx
+ .endm
+
+ .macro waituartcts,rd,rx
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S
index 6c91cbaaa20b..17722824e2f2 100644
--- a/arch/arm/include/debug/at91.S
+++ b/arch/arm/include/debug/at91.S
@@ -19,12 +19,15 @@
strb \rd, [\rx, #(AT91_DBGU_THR)] @ Write to Transmitter Holding Register
.endm
- .macro waituart,rd,rx
+ .macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register
tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit
beq 1001b
.endm
+ .macro waituartcts,rd,rx
+ .endm
+
.macro busyuart,rd,rx
1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register
tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete
diff --git a/arch/arm/include/debug/bcm63xx.S b/arch/arm/include/debug/bcm63xx.S
index 06a896227396..da65abb6738d 100644
--- a/arch/arm/include/debug/bcm63xx.S
+++ b/arch/arm/include/debug/bcm63xx.S
@@ -17,12 +17,15 @@
strb \rd, [\rx, #UART_FIFO_REG]
.endm
- .macro waituart, rd, rx
+ .macro waituarttxrdy, rd, rx
1001: ldr \rd, [\rx, #UART_IR_REG]
tst \rd, #(1 << UART_IR_TXEMPTY)
beq 1001b
.endm
+ .macro waituartcts, rd, rx
+ .endm
+
.macro busyuart, rd, rx
1002: ldr \rd, [\rx, #UART_IR_REG]
tst \rd, #(1 << UART_IR_TXTRESH)
diff --git a/arch/arm/include/debug/brcmstb.S b/arch/arm/include/debug/brcmstb.S
index 132a20c4a676..7ffe66993029 100644
--- a/arch/arm/include/debug/brcmstb.S
+++ b/arch/arm/include/debug/brcmstb.S
@@ -142,7 +142,10 @@ ARM_BE8( rev \rd, \rd )
bne 1002b
.endm
- .macro waituart,rd,rx
+ .macro waituarttxrdy,rd,rx
+ .endm
+
+ .macro waituartcts,rd,rx
.endm
/*
diff --git a/arch/arm/include/debug/clps711x.S b/arch/arm/include/debug/clps711x.S
index 774a67ac3877..a983d12a6515 100644
--- a/arch/arm/include/debug/clps711x.S
+++ b/arch/arm/include/debug/clps711x.S
@@ -20,7 +20,10 @@
ldr \rp, =CLPS711X_UART_PADDR
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/include/debug/dc21285.S b/arch/arm/include/debug/dc21285.S
index d7e8c71706ab..4ec0e5e31704 100644
--- a/arch/arm/include/debug/dc21285.S
+++ b/arch/arm/include/debug/dc21285.S
@@ -34,5 +34,8 @@
bne 1001b
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
.endm
diff --git a/arch/arm/include/debug/digicolor.S b/arch/arm/include/debug/digicolor.S
index 256f5f4da275..443674cad76a 100644
--- a/arch/arm/include/debug/digicolor.S
+++ b/arch/arm/include/debug/digicolor.S
@@ -21,7 +21,10 @@
strb \rd, [\rx, #UA0_EMI_REC]
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
.endm
.macro busyuart,rd,rx
diff --git a/arch/arm/include/debug/efm32.S b/arch/arm/include/debug/efm32.S
index 5ed5028306f4..b0083d6e31e8 100644
--- a/arch/arm/include/debug/efm32.S
+++ b/arch/arm/include/debug/efm32.S
@@ -29,7 +29,10 @@
strb \rd, [\rx, #UARTn_TXDATA]
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #UARTn_STATUS]
tst \rd, #UARTn_STATUS_TXBL
beq 1001b
diff --git a/arch/arm/include/debug/icedcc.S b/arch/arm/include/debug/icedcc.S
index 74a0dd036a17..d5e65da8a687 100644
--- a/arch/arm/include/debug/icedcc.S
+++ b/arch/arm/include/debug/icedcc.S
@@ -23,7 +23,10 @@
beq 1001b
.endm
- .macro waituart, rd, rx
+ .macro waituartcts, rd, rx
+ .endm
+
+ .macro waituarttxrdy, rd, rx
mov \rd, #0x2000000
1001:
subs \rd, \rd, #1
@@ -47,7 +50,10 @@
beq 1001b
.endm
- .macro waituart, rd, rx
+ .macro waituartcts, rd, rx
+ .endm
+
+ .macro waituarttxrdy, rd, rx
mov \rd, #0x10000000
1001:
subs \rd, \rd, #1
@@ -72,7 +78,10 @@
.endm
- .macro waituart, rd, rx
+ .macro waituartcts, rd, rx
+ .endm
+
+ .macro waituarttxrdy, rd, rx
mov \rd, #0x2000000
1001:
subs \rd, \rd, #1
diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S
index 1c1b9d1da4c8..bb7b9550580c 100644
--- a/arch/arm/include/debug/imx.S
+++ b/arch/arm/include/debug/imx.S
@@ -35,7 +35,10 @@
str \rd, [\rx, #0x40] @ TXDATA
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
.endm
.macro busyuart,rd,rx
diff --git a/arch/arm/include/debug/meson.S b/arch/arm/include/debug/meson.S
index 1e501a0054ae..7b60e4401225 100644
--- a/arch/arm/include/debug/meson.S
+++ b/arch/arm/include/debug/meson.S
@@ -25,7 +25,10 @@
beq 1002b
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #MESON_AO_UART_STATUS]
tst \rd, #MESON_AO_UART_TX_FIFO_FULL
bne 1001b
diff --git a/arch/arm/include/debug/msm.S b/arch/arm/include/debug/msm.S
index 9405b71461da..530edc74f9a3 100644
--- a/arch/arm/include/debug/msm.S
+++ b/arch/arm/include/debug/msm.S
@@ -17,7 +17,10 @@ ARM_BE8(rev \rd, \rd )
str \rd, [\rx, #0x70]
.endm
- .macro waituart, rd, rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy, rd, rx
@ check for TX_EMT in UARTDM_SR
ldr \rd, [\rx, #0x08]
ARM_BE8(rev \rd, \rd )
diff --git a/arch/arm/include/debug/omap2plus.S b/arch/arm/include/debug/omap2plus.S
index b5696a33ba0f..0680be6c79d3 100644
--- a/arch/arm/include/debug/omap2plus.S
+++ b/arch/arm/include/debug/omap2plus.S
@@ -75,5 +75,8 @@ omap_uart_lsr: .word 0
bne 1001b
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
.endm
diff --git a/arch/arm/include/debug/pl01x.S b/arch/arm/include/debug/pl01x.S
index a2a553afe7b8..0c7bfa4c10db 100644
--- a/arch/arm/include/debug/pl01x.S
+++ b/arch/arm/include/debug/pl01x.S
@@ -26,7 +26,10 @@
strb \rd, [\rx, #UART01x_DR]
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #UART01x_FR]
ARM_BE8( rev \rd, \rd )
tst \rd, #UART01x_FR_TXFF
diff --git a/arch/arm/include/debug/renesas-scif.S b/arch/arm/include/debug/renesas-scif.S
index 25f06663a9a4..8e433e981bbe 100644
--- a/arch/arm/include/debug/renesas-scif.S
+++ b/arch/arm/include/debug/renesas-scif.S
@@ -33,7 +33,10 @@
ldr \rv, =SCIF_VIRT
.endm
- .macro waituart, rd, rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy, rd, rx
1001: ldrh \rd, [\rx, #FSR]
tst \rd, #TDFE
beq 1001b
diff --git a/arch/arm/include/debug/sa1100.S b/arch/arm/include/debug/sa1100.S
index 6109e6058e5b..7968ea52df3d 100644
--- a/arch/arm/include/debug/sa1100.S
+++ b/arch/arm/include/debug/sa1100.S
@@ -51,7 +51,10 @@
str \rd, [\rx, #UTDR]
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #UTSR1]
tst \rd, #UTSR1_TNF
beq 1001b
diff --git a/arch/arm/include/debug/samsung.S b/arch/arm/include/debug/samsung.S
index 69201d7fb48f..ab474d564a90 100644
--- a/arch/arm/include/debug/samsung.S
+++ b/arch/arm/include/debug/samsung.S
@@ -69,7 +69,10 @@ ARM_BE8(rev \rd, \rd)
1002: @ exit busyuart
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
ldr \rd, [\rx, # S3C2410_UFCON]
ARM_BE8(rev \rd, \rd)
tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled?
diff --git a/arch/arm/include/debug/sirf.S b/arch/arm/include/debug/sirf.S
index e73e4de0a015..3612c7b9cbe7 100644
--- a/arch/arm/include/debug/sirf.S
+++ b/arch/arm/include/debug/sirf.S
@@ -29,7 +29,10 @@
.macro busyuart,rd,rx
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #SIRF_LLUART_TXFIFO_STATUS]
tst \rd, #SIRF_LLUART_TXFIFO_EMPTY
beq 1001b
diff --git a/arch/arm/include/debug/sti.S b/arch/arm/include/debug/sti.S
index 6b42c91f217d..72d052511890 100644
--- a/arch/arm/include/debug/sti.S
+++ b/arch/arm/include/debug/sti.S
@@ -45,7 +45,10 @@
strb \rd, [\rx, #ASC_TX_BUF_OFF]
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #ASC_STA_OFF]
tst \rd, #ASC_STA_TX_FULL
bne 1001b
diff --git a/arch/arm/include/debug/stm32.S b/arch/arm/include/debug/stm32.S
index f3c4a37210ed..b6d9df30e37d 100644
--- a/arch/arm/include/debug/stm32.S
+++ b/arch/arm/include/debug/stm32.S
@@ -27,7 +27,10 @@
strb \rd, [\rx, #STM32_USART_TDR_OFF]
.endm
-.macro waituart,rd,rx
+.macro waituartcts,rd,rx
+.endm
+
+.macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #(STM32_USART_SR_OFF)] @ Read Status Register
tst \rd, #STM32_USART_TXE @ TXE = 1 = tx empty
beq 1001b
diff --git a/arch/arm/include/debug/tegra.S b/arch/arm/include/debug/tegra.S
index 2148d0f88591..98daa7f48314 100644
--- a/arch/arm/include/debug/tegra.S
+++ b/arch/arm/include/debug/tegra.S
@@ -178,15 +178,16 @@
1002:
.endm
- .macro waituart, rd, rx
-#ifdef FLOW_CONTROL
+ .macro waituartcts, rd, rx
cmp \rx, #0
beq 1002f
1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT]
tst \rd, #UART_MSR_CTS
beq 1001b
1002:
-#endif
+ .endm
+
+ .macro waituarttxrdy,rd,rx
.endm
/*
diff --git a/arch/arm/include/debug/vf.S b/arch/arm/include/debug/vf.S
index 854d9bd82770..035bcbf117ab 100644
--- a/arch/arm/include/debug/vf.S
+++ b/arch/arm/include/debug/vf.S
@@ -29,5 +29,8 @@
beq 1001b @ wait until transmit done
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
.endm
diff --git a/arch/arm/include/debug/vt8500.S b/arch/arm/include/debug/vt8500.S
index 8dc1df2d91b8..d01094fdbc8c 100644
--- a/arch/arm/include/debug/vt8500.S
+++ b/arch/arm/include/debug/vt8500.S
@@ -28,7 +28,10 @@
bne 1001b
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
.endm
#endif
diff --git a/arch/arm/include/debug/zynq.S b/arch/arm/include/debug/zynq.S
index 58d77c972fd6..5d42cc35ecf3 100644
--- a/arch/arm/include/debug/zynq.S
+++ b/arch/arm/include/debug/zynq.S
@@ -33,7 +33,10 @@
strb \rd, [\rx, #UART_FIFO_OFFSET] @ TXDATA
.endm
- .macro waituart,rd,rx
+ .macro waituartcts,rd,rx
+ .endm
+
+ .macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #UART_SR_OFFSET]
ARM_BE8( rev \rd, \rd )
tst \rd, #UART_SR_TXEMPTY
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index e112072b579d..d92f44bdf438 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -89,11 +89,18 @@ ENTRY(printascii)
2: teq r1, #'\n'
bne 3f
mov r1, #'\r'
- waituart r2, r3
+#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL
+ waituartcts r2, r3
+#endif
+ waituarttxrdy r2, r3
senduart r1, r3
busyuart r2, r3
mov r1, #'\n'
-3: waituart r2, r3
+3:
+#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL
+ waituartcts r2, r3
+#endif
+ waituarttxrdy r2, r3
senduart r1, r3
busyuart r2, r3
b 1b
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 7a4853b1213a..08660ae9dcbc 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -683,6 +683,40 @@ static void disable_single_step(struct perf_event *bp)
arch_install_hw_breakpoint(bp);
}
+/*
+ * Arm32 hardware does not always report a watchpoint hit address that matches
+ * one of the watchpoints set. It can also report an address "near" the
+ * watchpoint if a single instruction access both watched and unwatched
+ * addresses. There is no straight-forward way, short of disassembling the
+ * offending instruction, to map that address back to the watchpoint. This
+ * function computes the distance of the memory access from the watchpoint as a
+ * heuristic for the likelyhood that a given access triggered the watchpoint.
+ *
+ * See this same function in the arm64 platform code, which has the same
+ * problem.
+ *
+ * The function returns the distance of the address from the bytes watched by
+ * the watchpoint. In case of an exact match, it returns 0.
+ */
+static u32 get_distance_from_watchpoint(unsigned long addr, u32 val,
+ struct arch_hw_breakpoint_ctrl *ctrl)
+{
+ u32 wp_low, wp_high;
+ u32 lens, lene;
+
+ lens = __ffs(ctrl->len);
+ lene = __fls(ctrl->len);
+
+ wp_low = val + lens;
+ wp_high = val + lene;
+ if (addr < wp_low)
+ return wp_low - addr;
+ else if (addr > wp_high)
+ return addr - wp_high;
+ else
+ return 0;
+}
+
static int watchpoint_fault_on_uaccess(struct pt_regs *regs,
struct arch_hw_breakpoint *info)
{
@@ -692,23 +726,25 @@ static int watchpoint_fault_on_uaccess(struct pt_regs *regs,
static void watchpoint_handler(unsigned long addr, unsigned int fsr,
struct pt_regs *regs)
{
- int i, access;
- u32 val, ctrl_reg, alignment_mask;
+ int i, access, closest_match = 0;
+ u32 min_dist = -1, dist;
+ u32 val, ctrl_reg;
struct perf_event *wp, **slots;
struct arch_hw_breakpoint *info;
struct arch_hw_breakpoint_ctrl ctrl;
slots = this_cpu_ptr(wp_on_reg);
+ /*
+ * Find all watchpoints that match the reported address. If no exact
+ * match is found. Attribute the hit to the closest watchpoint.
+ */
+ rcu_read_lock();
for (i = 0; i < core_num_wrps; ++i) {
- rcu_read_lock();
-
wp = slots[i];
-
if (wp == NULL)
- goto unlock;
+ continue;
- info = counter_arch_bp(wp);
/*
* The DFAR is an unknown value on debug architectures prior
* to 7.1. Since we only allow a single watchpoint on these
@@ -717,33 +753,31 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
*/
if (debug_arch < ARM_DEBUG_ARCH_V7_1) {
BUG_ON(i > 0);
+ info = counter_arch_bp(wp);
info->trigger = wp->attr.bp_addr;
} else {
- if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
- alignment_mask = 0x7;
- else
- alignment_mask = 0x3;
-
- /* Check if the watchpoint value matches. */
- val = read_wb_reg(ARM_BASE_WVR + i);
- if (val != (addr & ~alignment_mask))
- goto unlock;
-
- /* Possible match, check the byte address select. */
- ctrl_reg = read_wb_reg(ARM_BASE_WCR + i);
- decode_ctrl_reg(ctrl_reg, &ctrl);
- if (!((1 << (addr & alignment_mask)) & ctrl.len))
- goto unlock;
-
/* Check that the access type matches. */
if (debug_exception_updates_fsr()) {
access = (fsr & ARM_FSR_ACCESS_MASK) ?
HW_BREAKPOINT_W : HW_BREAKPOINT_R;
if (!(access & hw_breakpoint_type(wp)))
- goto unlock;
+ continue;
}
+ val = read_wb_reg(ARM_BASE_WVR + i);
+ ctrl_reg = read_wb_reg(ARM_BASE_WCR + i);
+ decode_ctrl_reg(ctrl_reg, &ctrl);
+ dist = get_distance_from_watchpoint(addr, val, &ctrl);
+ if (dist < min_dist) {
+ min_dist = dist;
+ closest_match = i;
+ }
+ /* Is this an exact match? */
+ if (dist != 0)
+ continue;
+
/* We have a winner. */
+ info = counter_arch_bp(wp);
info->trigger = addr;
}
@@ -765,13 +799,23 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
* we can single-step over the watchpoint trigger.
*/
if (!is_default_overflow_handler(wp))
- goto unlock;
-
+ continue;
step:
enable_single_step(wp, instruction_pointer(regs));
-unlock:
- rcu_read_unlock();
}
+
+ if (min_dist > 0 && min_dist != -1) {
+ /* No exact match found. */
+ wp = slots[closest_match];
+ info = counter_arch_bp(wp);
+ info->trigger = addr;
+ pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
+ perf_bp_event(wp, regs);
+ if (is_default_overflow_handler(wp))
+ enable_single_step(wp, instruction_pointer(regs));
+ }
+
+ rcu_read_unlock();
}
static void watchpoint_single_step_handler(unsigned long pc)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 12c26eb88afb..43d91bfd2360 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -1249,20 +1249,28 @@ static void __init l2c310_of_parse(const struct device_node *np,
ret = of_property_read_u32(np, "prefetch-data", &val);
if (ret == 0) {
- if (val)
+ if (val) {
prefetch |= L310_PREFETCH_CTRL_DATA_PREFETCH;
- else
+ *aux_val |= L310_PREFETCH_CTRL_DATA_PREFETCH;
+ } else {
prefetch &= ~L310_PREFETCH_CTRL_DATA_PREFETCH;
+ *aux_val &= ~L310_PREFETCH_CTRL_DATA_PREFETCH;
+ }
+ *aux_mask &= ~L310_PREFETCH_CTRL_DATA_PREFETCH;
} else if (ret != -EINVAL) {
pr_err("L2C-310 OF prefetch-data property value is missing\n");
}
ret = of_property_read_u32(np, "prefetch-instr", &val);
if (ret == 0) {
- if (val)
+ if (val) {
prefetch |= L310_PREFETCH_CTRL_INSTR_PREFETCH;
- else
+ *aux_val |= L310_PREFETCH_CTRL_INSTR_PREFETCH;
+ } else {
prefetch &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH;
+ *aux_val &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH;
+ }
+ *aux_mask &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH;
} else if (ret != -EINVAL) {
pr_err("L2C-310 OF prefetch-instr property value is missing\n");
}