Commit 709ebe6d authored by Linus Torvalds's avatar Linus Torvalds

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
parents b32649b8 adc5f702
...@@ -1546,6 +1546,17 @@ config DEBUG_SIRFSOC_UART ...@@ -1546,6 +1546,17 @@ config DEBUG_SIRFSOC_UART
bool bool
depends on ARCH_SIRF 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 config DEBUG_LL_INCLUDE
string string
default "debug/sa1100.S" if DEBUG_SA1100 default "debug/sa1100.S" if DEBUG_SA1100
...@@ -1893,11 +1904,6 @@ config DEBUG_UART_8250_PALMCHIP ...@@ -1893,11 +1904,6 @@ config DEBUG_UART_8250_PALMCHIP
except for having a different register layout. Say Y here if except for having a different register layout. Say Y here if
the debug UART is of this type. 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 config DEBUG_UNCOMPRESS
bool "Enable decompressor debugging via DEBUG_LL output" bool "Enable decompressor debugging via DEBUG_LL output"
depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M
......
...@@ -143,6 +143,9 @@ head-y := arch/arm/kernel/head$(MMUEXT).o ...@@ -143,6 +143,9 @@ head-y := arch/arm/kernel/head$(MMUEXT).o
# Text offset. This list is sorted numerically by address in order to # Text offset. This list is sorted numerically by address in order to
# provide a means to avoid/resolve conflicts in multi-arch kernels. # 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 textofs-y := 0x00008000
# We don't want the htc bootloader to corrupt kernel during resume # We don't want the htc bootloader to corrupt kernel during resume
textofs-$(CONFIG_PM_H1940) := 0x00108000 textofs-$(CONFIG_PM_H1940) := 0x00108000
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
OBJS = OBJS =
AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
HEAD = head.o HEAD = head.o
OBJS += misc.o decompress.o OBJS += misc.o decompress.o
ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y) ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
OBJS += debug.o OBJS += debug.o
AFLAGS_head.o += -DDEBUG
endif endif
FONTC = $(srctree)/lib/fonts/font_acorn_8x8.c FONTC = $(srctree)/lib/fonts/font_acorn_8x8.c
...@@ -68,7 +68,12 @@ ZTEXTADDR := 0 ...@@ -68,7 +68,12 @@ ZTEXTADDR := 0
ZBSSADDR := ALIGN(8) ZBSSADDR := ALIGN(8)
endif 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_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_GZIP) = gzip
compress-$(CONFIG_KERNEL_LZO) = lzo compress-$(CONFIG_KERNEL_LZO) = lzo
......
...@@ -8,7 +8,10 @@ ...@@ -8,7 +8,10 @@
ENTRY(putc) ENTRY(putc)
addruart r1, r2, r3 addruart r1, r2, r3
waituart r3, r1 #ifdef CONFIG_DEBUG_UART_FLOW_CONTROL
waituartcts r3, r1
#endif
waituarttxrdy r3, r1
senduart r0, r1 senduart r0, r1
busyuart r3, r1 busyuart r3, r1
mov pc, lr mov pc, lr
......
...@@ -28,19 +28,19 @@ ...@@ -28,19 +28,19 @@
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
.macro loadsp, rb, tmp1, tmp2 .macro loadsp, rb, tmp1, tmp2
.endm .endm
.macro writeb, ch, rb .macro writeb, ch, rb, tmp
mcr p14, 0, \ch, c0, c5, 0 mcr p14, 0, \ch, c0, c5, 0
.endm .endm
#elif defined(CONFIG_CPU_XSCALE) #elif defined(CONFIG_CPU_XSCALE)
.macro loadsp, rb, tmp1, tmp2 .macro loadsp, rb, tmp1, tmp2
.endm .endm
.macro writeb, ch, rb .macro writeb, ch, rb, tmp
mcr p14, 0, \ch, c8, c0, 0 mcr p14, 0, \ch, c8, c0, 0
.endm .endm
#else #else
.macro loadsp, rb, tmp1, tmp2 .macro loadsp, rb, tmp1, tmp2
.endm .endm
.macro writeb, ch, rb .macro writeb, ch, rb, tmp
mcr p14, 0, \ch, c1, c0, 0 mcr p14, 0, \ch, c1, c0, 0
.endm .endm
#endif #endif
...@@ -49,8 +49,13 @@ ...@@ -49,8 +49,13 @@
#include CONFIG_DEBUG_LL_INCLUDE #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 senduart \ch, \rb
busyuart \tmp, \rb
.endm .endm
#if defined(CONFIG_ARCH_SA1100) #if defined(CONFIG_ARCH_SA1100)
...@@ -81,42 +86,11 @@ ...@@ -81,42 +86,11 @@
bl phex bl phex
.endm .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 * Debug kernel copy by printing the memory addresses involved
*/ */
.macro dbgkc, begin, end, cbegin, cend .macro dbgkc, begin, end, cbegin, cend
#ifdef DEBUG #ifdef DEBUG
kputc #'\n'
kputc #'C' kputc #'C'
kputc #':' kputc #':'
kputc #'0' kputc #'0'
...@@ -136,7 +110,28 @@ ...@@ -136,7 +110,28 @@
kputc #'x' kputc #'x'
kphex \cend, 8 /* End of kernel copy */ kphex \cend, 8 /* End of kernel copy */
kputc #'\n' 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 #endif
.endm .endm
...@@ -303,7 +298,7 @@ restart: adr r0, LC1 ...@@ -303,7 +298,7 @@ restart: adr r0, LC1
#ifndef CONFIG_ZBOOT_ROM #ifndef CONFIG_ZBOOT_ROM
/* malloc space is above the relocated stack (64k max) */ /* malloc space is above the relocated stack (64k max) */
add r10, sp, #0x10000 add r10, sp, #MALLOC_SIZE
#else #else
/* /*
* With ZBOOT_ROM the bss/stack is non relocatable, * With ZBOOT_ROM the bss/stack is non relocatable,
...@@ -357,6 +352,7 @@ restart: adr r0, LC1 ...@@ -357,6 +352,7 @@ restart: adr r0, LC1
mov r5, r5, ror #8 mov r5, r5, ror #8
eor r5, r5, r1, lsr #8 eor r5, r5, r1, lsr #8
#endif #endif
dbgadtb r6, r5
/* 50% DTB growth should be good enough */ /* 50% DTB growth should be good enough */
add r5, r5, r5, lsr #1 add r5, r5, r5, lsr #1
/* preserve 64-bit alignment */ /* preserve 64-bit alignment */
...@@ -614,7 +610,7 @@ not_relocated: mov r0, #0 ...@@ -614,7 +610,7 @@ not_relocated: mov r0, #0
*/ */
mov r0, r4 mov r0, r4
mov r1, sp @ malloc space above stack mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max add r2, sp, #MALLOC_SIZE @ 64k max
mov r3, r7 mov r3, r7
bl decompress_kernel bl decompress_kernel
...@@ -1356,7 +1352,7 @@ puts: loadsp r3, r2, r1 ...@@ -1356,7 +1352,7 @@ puts: loadsp r3, r2, r1
1: ldrb r2, [r0], #1 1: ldrb r2, [r0], #1
teq r2, #0 teq r2, #0
moveq pc, lr moveq pc, lr
2: writeb r2, r3 2: writeb r2, r3, r1
mov r1, #0x00020000 mov r1, #0x00020000
3: subs r1, r1, #1 3: subs r1, r1, #1
bne 3b bne 3b
......
...@@ -44,10 +44,12 @@ SECTIONS ...@@ -44,10 +44,12 @@ SECTIONS
} }
.table : ALIGN(4) { .table : ALIGN(4) {
_table_start = .; _table_start = .;
LONG(ZIMAGE_MAGIC(4)) LONG(ZIMAGE_MAGIC(6))
LONG(ZIMAGE_MAGIC(0x5a534c4b)) LONG(ZIMAGE_MAGIC(0x5a534c4b))
LONG(ZIMAGE_MAGIC(__piggy_size_addr - _start)) LONG(ZIMAGE_MAGIC(__piggy_size_addr - _start))
LONG(ZIMAGE_MAGIC(_kernel_bss_size)) LONG(ZIMAGE_MAGIC(_kernel_bss_size))
LONG(ZIMAGE_MAGIC(TEXT_OFFSET))
LONG(ZIMAGE_MAGIC(MALLOC_SIZE))
LONG(0) LONG(0)
_table_end = .; _table_end = .;
} }
......
...@@ -45,10 +45,11 @@ ...@@ -45,10 +45,11 @@
bne 1002b bne 1002b
.endm .endm
.macro waituart,rd,rx .macro waituarttxrdy,rd,rx
#ifdef CONFIG_DEBUG_UART_8250_FLOW_CONTROL .endm
.macro waituartcts,rd,rx
1001: load \rd, [\rx, #UART_MSR << UART_SHIFT] 1001: load \rd, [\rx, #UART_MSR << UART_SHIFT]
tst \rd, #UART_MSR_CTS tst \rd, #UART_MSR_CTS
beq 1001b beq 1001b
#endif
.endm .endm
...@@ -11,7 +11,10 @@ ...@@ -11,7 +11,10 @@
ldr \rv, = CONFIG_DEBUG_UART_VIRT ldr \rv, = CONFIG_DEBUG_UART_VIRT
.endm .endm
.macro waituart,rd,rx .macro waituarttxrdy,rd,rx
.endm
.macro waituartcts,rd,rx
.endm .endm
.macro senduart,rd,rx .macro senduart,rd,rx
......
...@@ -19,12 +19,15 @@ ...@@ -19,12 +19,15 @@
strb \rd, [\rx, #(AT91_DBGU_THR)] @ Write to Transmitter Holding Register strb \rd, [\rx, #(AT91_DBGU_THR)] @ Write to Transmitter Holding Register
.endm .endm
.macro waituart,rd,rx .macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register 1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register
tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit
beq 1001b beq 1001b
.endm .endm
.macro waituartcts,rd,rx
.endm
.macro busyuart,rd,rx .macro busyuart,rd,rx
1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register 1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register
tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete
......
...@@ -17,12 +17,15 @@ ...@@ -17,12 +17,15 @@
strb \rd, [\rx, #UART_FIFO_REG] strb \rd, [\rx, #UART_FIFO_REG]
.endm .endm
.macro waituart, rd, rx .macro waituarttxrdy, rd, rx
1001: ldr \rd, [\rx, #UART_IR_REG] 1001: ldr \rd, [\rx, #UART_IR_REG]
tst \rd, #(1 << UART_IR_TXEMPTY) tst \rd, #(1 << UART_IR_TXEMPTY)
beq 1001b beq 1001b
.endm .endm
.macro waituartcts, rd, rx
.endm
.macro busyuart, rd, rx .macro busyuart, rd, rx
1002: ldr \rd, [\rx, #UART_IR_REG] 1002: ldr \rd, [\rx, #UART_IR_REG]
tst \rd, #(1 << UART_IR_TXTRESH) tst \rd, #(1 << UART_IR_TXTRESH)
......
...@@ -142,7 +142,10 @@ ARM_BE8( rev \rd, \rd ) ...@@ -142,7 +142,10 @@ ARM_BE8( rev \rd, \rd )
bne 1002b bne 1002b
.endm .endm
.macro waituart,rd,rx .macro waituarttxrdy,rd,rx
.endm
.macro waituartcts,rd,rx
.endm .endm
/* /*
......
...@@ -20,7 +20,10 @@ ...@@ -20,7 +20,10 @@
ldr \rp, =CLPS711X_UART_PADDR ldr \rp, =CLPS711X_UART_PADDR
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
.endm .endm
.macro senduart,rd,rx .macro senduart,rd,rx
......
...@@ -34,5 +34,8 @@ ...@@ -34,5 +34,8 @@
bne 1001b bne 1001b
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
.endm .endm
...@@ -21,7 +21,10 @@ ...@@ -21,7 +21,10 @@
strb \rd, [\rx, #UA0_EMI_REC] strb \rd, [\rx, #UA0_EMI_REC]
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
.endm .endm
.macro busyuart,rd,rx .macro busyuart,rd,rx
......
...@@ -29,7 +29,10 @@ ...@@ -29,7 +29,10 @@
strb \rd, [\rx, #UARTn_TXDATA] strb \rd, [\rx, #UARTn_TXDATA]
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #UARTn_STATUS] 1001: ldr \rd, [\rx, #UARTn_STATUS]
tst \rd, #UARTn_STATUS_TXBL tst \rd, #UARTn_STATUS_TXBL
beq 1001b beq 1001b
......
...@@ -23,7 +23,10 @@ ...@@ -23,7 +23,10 @@
beq 1001b beq 1001b
.endm .endm
.macro waituart, rd, rx .macro waituartcts, rd, rx
.endm
.macro waituarttxrdy, rd, rx
mov \rd, #0x2000000 mov \rd, #0x2000000
1001: 1001:
subs \rd, \rd, #1 subs \rd, \rd, #1
...@@ -47,7 +50,10 @@ ...@@ -47,7 +50,10 @@
beq 1001b beq 1001b
.endm .endm
.macro waituart, rd, rx .macro waituartcts, rd, rx
.endm
.macro waituarttxrdy, rd, rx
mov \rd, #0x10000000 mov \rd, #0x10000000
1001: 1001:
subs \rd, \rd, #1 subs \rd, \rd, #1
...@@ -72,7 +78,10 @@ ...@@ -72,7 +78,10 @@
.endm .endm
.macro waituart, rd, rx .macro waituartcts, rd, rx
.endm
.macro waituarttxrdy, rd, rx
mov \rd, #0x2000000 mov \rd, #0x2000000
1001: 1001:
subs \rd, \rd, #1 subs \rd, \rd, #1
......
...@@ -35,7 +35,10 @@ ...@@ -35,7 +35,10 @@
str \rd, [\rx, #0x40] @ TXDATA str \rd, [\rx, #0x40] @ TXDATA
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
.endm .endm
.macro busyuart,rd,rx .macro busyuart,rd,rx
......
...@@ -25,7 +25,10 @@ ...@@ -25,7 +25,10 @@
beq 1002b beq 1002b
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #MESON_AO_UART_STATUS] 1001: ldr \rd, [\rx, #MESON_AO_UART_STATUS]
tst \rd, #MESON_AO_UART_TX_FIFO_FULL tst \rd, #MESON_AO_UART_TX_FIFO_FULL
bne 1001b bne 1001b
......
...@@ -17,7 +17,10 @@ ARM_BE8(rev \rd, \rd ) ...@@ -17,7 +17,10 @@ ARM_BE8(rev \rd, \rd )
str \rd, [\rx, #0x70] str \rd, [\rx, #0x70]
.endm .endm
.macro waituart, rd, rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy, rd, rx
@ check for TX_EMT in UARTDM_SR @ check for TX_EMT in UARTDM_SR
ldr \rd, [\rx, #0x08] ldr \rd, [\rx, #0x08]
ARM_BE8(rev \rd, \rd ) ARM_BE8(rev \rd, \rd )
......
...@@ -75,5 +75,8 @@ omap_uart_lsr: .word 0 ...@@ -75,5 +75,8 @@ omap_uart_lsr: .word 0
bne 1001b bne 1001b
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
.endm .endm
...@@ -26,7 +26,10 @@ ...@@ -26,7 +26,10 @@
strb \rd, [\rx, #UART01x_DR] strb \rd, [\rx, #UART01x_DR]
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #UART01x_FR] 1001: ldr \rd, [\rx, #UART01x_FR]
ARM_BE8( rev \rd, \rd ) ARM_BE8( rev \rd, \rd )
tst \rd, #UART01x_FR_TXFF tst \rd, #UART01x_FR_TXFF
......
...@@ -33,7 +33,10 @@ ...@@ -33,7 +33,10 @@
ldr \rv, =SCIF_VIRT ldr \rv, =SCIF_VIRT
.endm .endm
.macro waituart, rd, rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy, rd, rx
1001: ldrh \rd, [\rx, #FSR] 1001: ldrh \rd, [\rx, #FSR]
tst \rd, #TDFE tst \rd, #TDFE
beq 1001b beq 1001b
......
...@@ -51,7 +51,10 @@ ...@@ -51,7 +51,10 @@
str \rd, [\rx, #UTDR] str \rd, [\rx, #UTDR]
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #UTSR1] 1001: ldr \rd, [\rx, #UTSR1]
tst \rd, #UTSR1_TNF tst \rd, #UTSR1_TNF
beq 1001b beq 1001b
......
...@@ -69,7 +69,10 @@ ARM_BE8(rev \rd, \rd) ...@@ -69,7 +69,10 @@ ARM_BE8(rev \rd, \rd)
1002: @ exit busyuart 1002: @ exit busyuart
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
ldr \rd, [\rx, # S3C2410_UFCON] ldr \rd, [\rx, # S3C2410_UFCON]
ARM_BE8(rev \rd, \rd) ARM_BE8(rev \rd, \rd)
tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled?
......
...@@ -29,7 +29,10 @@ ...@@ -29,7 +29,10 @@
.macro busyuart,rd,rx .macro busyuart,rd,rx
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #SIRF_LLUART_TXFIFO_STATUS] 1001: ldr \rd, [\rx, #SIRF_LLUART_TXFIFO_STATUS]
tst \rd, #SIRF_LLUART_TXFIFO_EMPTY tst \rd, #SIRF_LLUART_TXFIFO_EMPTY
beq 1001b beq 1001b
......
...@@ -45,7 +45,10 @@ ...@@ -45,7 +45,10 @@
strb \rd, [\rx, #ASC_TX_BUF_OFF] strb \rd, [\rx, #ASC_TX_BUF_OFF]
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #ASC_STA_OFF] 1001: ldr \rd, [\rx, #ASC_STA_OFF]
tst \rd, #ASC_STA_TX_FULL tst \rd, #ASC_STA_TX_FULL
bne 1001b bne 1001b
......
...@@ -27,7 +27,10 @@ ...@@ -27,7 +27,10 @@
strb \rd, [\rx, #STM32_USART_TDR_OFF] strb \rd, [\rx, #STM32_USART_TDR_OFF]
.endm .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 1001: ldr \rd, [\rx, #(STM32_USART_SR_OFF)] @ Read Status Register
tst \rd, #STM32_USART_TXE @ TXE = 1 = tx empty tst \rd, #STM32_USART_TXE @ TXE = 1 = tx empty
beq 1001b beq 1001b
......
...@@ -178,15 +178,16 @@ ...@@ -178,15 +178,16 @@
1002: 1002:
.endm .endm
.macro waituart, rd, rx .macro waituartcts, rd, rx
#ifdef FLOW_CONTROL
cmp \rx, #0 cmp \rx, #0
beq 1002f beq 1002f
1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] 1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT]
tst \rd, #UART_MSR_CTS tst \rd, #UART_MSR_CTS
beq 1001b beq 1001b
1002: 1002:
#endif .endm
.macro waituarttxrdy,rd,rx
.endm .endm
/* /*
......
...@@ -29,5 +29,8 @@ ...@@ -29,5 +29,8 @@
beq 1001b @ wait until transmit done beq 1001b @ wait until transmit done
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
.endm .endm
...@@ -28,7 +28,10 @@ ...@@ -28,7 +28,10 @@
bne 1001b bne 1001b
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
.endm .endm
#endif #endif
...@@ -33,7 +33,10 @@ ...@@ -33,7 +33,10 @@
strb \rd, [\rx, #UART_FIFO_OFFSET] @ TXDATA strb \rd, [\rx, #UART_FIFO_OFFSET] @ TXDATA
.endm .endm
.macro waituart,rd,rx .macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #UART_SR_OFFSET] 1001: ldr \rd, [\rx, #UART_SR_OFFSET]
ARM_BE8( rev \rd, \rd ) ARM_BE8( rev \rd, \rd )
tst \rd, #UART_SR_TXEMPTY tst \rd, #UART_SR_TXEMPTY
......
...@@ -89,11 +89,18 @@ ENTRY(printascii) ...@@ -89,11 +89,18 @@ ENTRY(printascii)
2: teq r1, #'\n' 2: teq r1, #'\n'
bne 3f bne 3f
mov r1, #'\r' mov r1, #'\r'
waituart r2, r3 #ifdef CONFIG_DEBUG_UART_FLOW_CONTROL
waituartcts r2, r3
#endif
waituarttxrdy r2, r3
senduart r1, r3 senduart r1, r3
busyuart r2, r3 busyuart r2, r3
mov r1, #'\n' mov r1, #'\n'
3: waituart r2, r3 3:
#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL
waituartcts r2, r3
#endif
waituarttxrdy r2, r3
senduart r1, r3 senduart r1, r3
busyuart r2, r3 busyuart r2, r3
b 1b b 1b
......
...@@ -683,6 +683,40 @@ static void disable_single_step(struct perf_event *bp) ...@@ -683,6 +683,40 @@ static void disable_single_step(struct perf_event *bp)
arch_install_hw_breakpoint(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, static int watchpoint_fault_on_uaccess(struct pt_regs *regs,
struct arch_hw_breakpoint *info) struct arch_hw_breakpoint *info)
{ {
...@@ -692,23 +726,25 @@ static int watchpoint_fault_on_uaccess(struct pt_regs *regs, ...@@ -692,23 +726,25 @@ static int watchpoint_fault_on_uaccess(struct pt_regs *regs,
static void watchpoint_handler(unsigned long addr, unsigned int fsr, static void watchpoint_handler(unsigned long addr, unsigned int fsr,
struct pt_regs *regs) struct pt_regs *regs)
{ {
int i, access; int i, access, closest_match = 0;
u32 val, ctrl_reg, alignment_mask; u32 min_dist = -1, dist;
u32 val, ctrl_reg;
struct perf_event *wp, **slots; struct perf_event *wp, **slots;
struct arch_hw_breakpoint *info; struct arch_hw_breakpoint *info;
struct arch_hw_breakpoint_ctrl ctrl; struct arch_hw_breakpoint_ctrl ctrl;
slots = this_cpu_ptr(wp_on_reg); slots = this_cpu_ptr(wp_on_reg);
for (i = 0; i < core_num_wrps; ++i) { /*
* Find all watchpoints that match the reported address. If no exact
* match is found. Attribute the hit to the closest watchpoint.
*/
rcu_read_lock(); rcu_read_lock();
for (i = 0; i < core_num_wrps; ++i) {
wp = slots[i]; wp = slots[i];
if (wp == NULL) if (wp == NULL)
goto unlock; continue;
info = counter_arch_bp(wp);
/* /*
* The DFAR is an unknown value on debug architectures prior * The DFAR is an unknown value on debug architectures prior
* to 7.1. Since we only allow a single watchpoint on these * 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, ...@@ -717,33 +753,31 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
*/ */
if (debug_arch < ARM_DEBUG_ARCH_V7_1) { if (debug_arch < ARM_DEBUG_ARCH_V7_1) {
BUG_ON(i > 0); BUG_ON(i > 0);
info = counter_arch_bp(wp);
info->trigger = wp->attr.bp_addr; info->trigger = wp->attr.bp_addr;
} else { } 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. */ /* Check that the access type matches. */
if (debug_exception_updates_fsr()) { if (debug_exception_updates_fsr()) {
access = (fsr & ARM_FSR_ACCESS_MASK) ? access = (fsr & ARM_FSR_ACCESS_MASK) ?
HW_BREAKPOINT_W : HW_BREAKPOINT_R; HW_BREAKPOINT_W : HW_BREAKPOINT_R;
if (!(access & hw_breakpoint_type(wp))) 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. */ /* We have a winner. */
info = counter_arch_bp(wp);
info->trigger = addr; info->trigger = addr;
} }
...@@ -765,13 +799,23 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, ...@@ -765,13 +799,23 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
* we can single-step over the watchpoint trigger. * we can single-step over the watchpoint trigger.
*/ */
if (!is_default_overflow_handler(wp)) if (!is_default_overflow_handler(wp))
goto unlock; continue;
step: step:
enable_single_step(wp, instruction_pointer(regs)); 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) static void watchpoint_single_step_handler(unsigned long pc)
......
...@@ -1249,20 +1249,28 @@ static void __init l2c310_of_parse(const struct device_node *np, ...@@ -1249,20 +1249,28 @@ static void __init l2c310_of_parse(const struct device_node *np,
ret = of_property_read_u32(np, "prefetch-data", &val); ret = of_property_read_u32(np, "prefetch-data", &val);
if (ret == 0) { if (ret == 0) {
if (val) if (val) {
prefetch |= L310_PREFETCH_CTRL_DATA_PREFETCH; prefetch |= L310_PREFETCH_CTRL_DATA_PREFETCH;
else *aux_val |= L310_PREFETCH_CTRL_DATA_PREFETCH;
} else {
prefetch &= ~L310_PREFETCH_CTRL_DATA_PREFETCH; prefetch &= ~L310_PREFETCH_CTRL_DATA_PREFETCH;
*aux_val &= ~L310_PREFETCH_CTRL_DATA_PREFETCH;
}
*aux_mask &= ~L310_PREFETCH_CTRL_DATA_PREFETCH;
} else if (ret != -EINVAL) { } else if (ret != -EINVAL) {
pr_err("L2C-310 OF prefetch-data property value is missing\n"); pr_err("L2C-310 OF prefetch-data property value is missing\n");
} }
ret = of_property_read_u32(np, "prefetch-instr", &val); ret = of_property_read_u32(np, "prefetch-instr", &val);
if (ret == 0) { if (ret == 0) {
if (val) if (val) {
prefetch |= L310_PREFETCH_CTRL_INSTR_PREFETCH; prefetch |= L310_PREFETCH_CTRL_INSTR_PREFETCH;
else *aux_val |= L310_PREFETCH_CTRL_INSTR_PREFETCH;
} else {
prefetch &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH; prefetch &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH;
*aux_val &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH;
}
*aux_mask &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH;
} else if (ret != -EINVAL) { } else if (ret != -EINVAL) {
pr_err("L2C-310 OF prefetch-instr property value is missing\n"); pr_err("L2C-310 OF prefetch-instr property value is missing\n");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment