diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-20 19:18:31 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-20 19:18:31 +0300 |
commit | 709ebe6dff50405ae83551578bc08c0f78b05158 (patch) | |
tree | 8d4343b429771129ad5820ccde63b2ba22bb116f /arch/arm | |
parent | b32649b863623d89fec83aa27d19c28715c4fae3 (diff) | |
parent | adc5f7029376049873289be305d507022281b8dd (diff) | |
download | linux-709ebe6dff50405ae83551578bc08c0f78b05158.tar.xz |
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM updates from Russell King:
- handle inexact watchpoint addresses (Douglas Anderson)
- decompressor serial debug cleanups (Linus Walleij)
- update L2 cache prefetch bits (Guillaume Tucker)
- add text offset and malloc size to the decompressor kexec data
* tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm:
ARM: add malloc size to decompressor kexec size structure
ARM: add TEXT_OFFSET to decompressor kexec image structure
ARM: 9007/1: l2c: fix prefetch bits init in L2X0_AUX_CTRL using DT values
ARM: 9010/1: uncompress: Print the location of appended DTB
ARM: 9009/1: uncompress: Enable debug in head.S
ARM: 9008/1: uncompress: Drop excess whitespace print
ARM: 9006/1: uncompress: Wait for ready and busy in debug prints
ARM: 9005/1: debug: Select flow control for all debug UARTs
ARM: 9004/1: debug: Split waituart to CTS and TXRDY
ARM: 9003/1: uncompress: Delete unused debug macros
ARM: 8997/2: hw_breakpoint: Handle inexact watchpoint addresses
Diffstat (limited to 'arch/arm')
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"); } |