[U-Boot] [PATCH v2 0/3] Add generic early debug UART feature
Simon Glass
sjg at chromium.org
Tue Jan 27 02:27:06 CET 2015
This series adds debug UART infrastructure which can in principle be used on
any architecture. It works best with those that don't need a stack to call
functions (e.g. ARM, PowerPC).
This came up in a discussion on the mailing list here:
https://patchwork.ozlabs.org/patch/384613/
My concerns at the time were:
- it doesn't need to be written in assembler
- it doesn't need to be ARM-specific
- it only supports one serial driver
This potentially creates a problem where to support n architectures and m
serial drivers we need n * m lots of assembler-coded functions. For example,
in Linux for ARM we have:
../plat-spear/include/plat/debug-macro.S
../mach-s5pc100/include/mach/debug-macro.S
../mach-shark/include/mach/debug-macro.S
../mach-spear3xx/include/mach/debug-macro.S
../mach-sa1100/include/mach/debug-macro.S
../mach-l7200/include/mach/debug-macro.S
../mach-mv78xx0/include/mach/debug-macro.S
../mach-realview/include/mach/debug-macro.S
../mach-mmp/include/mach/debug-macro.S
../mach-s3c64xx/include/mach/debug-macro.S
../mach-s5pv210/include/mach/debug-macro.S
../mach-clps711x/include/mach/debug-macro.S
../mach-versatile/include/mach/debug-macro.S
../mach-iop32x/include/mach/debug-macro.S
../mach-ebsa110/include/mach/debug-macro.S
../mach-ux500/include/mach/debug-macro.S
../mach-orion5x/include/mach/debug-macro.S
../mach-lpc32xx/include/mach/debug-macro.S
../mach-vt8500/include/mach/debug-macro.S
../mach-rpc/include/mach/debug-macro.S
../mach-kirkwood/include/mach/debug-macro.S
../mach-spear6xx/include/mach/debug-macro.S
../mach-footbridge/include/mach/debug-macro.S
../mach-davinci/include/mach/debug-macro.S
../plat-samsung/include/plat/debug-macro.S
../mach-spear13xx/include/mach/debug-macro.S
../mach-exynos/include/mach/debug-macro.S
../mach-exynos/include/mach/regs-debug.h
../mach-dove/include/mach/debug-macro.S
../mach-omap1/include/mach/debug-macro.S
../mach-u300/include/mach/debug-macro.S
../mach-bcm2835/include/mach/debug-macro.S
../mach-h720x/include/mach/debug-macro.S
../mach-ep93xx/include/mach/debug-macro.S
../mach-gemini/include/mach/debug-macro.S
../mach-s3c24xx/include/mach/debug-macro.S
../mach-at91/include/mach/debug-macro.S
../mach-ixp4xx/include/mach/debug-macro.S
../mach-nomadik/include/mach/debug-macro.S
../mach-cns3xxx/include/mach/debug-macro.S
../mach-mxs/include/mach/debug-macro.S
../mach-iop33x/include/mach/debug-macro.S
../mach-ks8695/include/mach/debug-macro.S
../mach-netx/include/mach/debug-macro.S
../mach-iop13xx/include/mach/debug-macro.S
../mach-integrator/include/mach/debug-macro.S
../mach-msm/include/mach/debug-macro.S
../mach-pxa/include/mach/debug-macro.S
../mach-s5p64x0/include/mach/debug-macro.S
../mach-prima2/include/mach/debug-macro.S
../mach-omap2/include/mach/debug-macro.S
This series provides a possible alternative. It works by allowing any serial
driver to export one init function and provide a putc() function. These
can be used to output debug data before the real serial driver is available.
Only one debug UART can be used at a time, and its address and serial clock
must be provided statically in Kconfig.
This implementation does not depend on driver model being set up, and it is
possible for it to operate without a stack on some architectures (e.g.
PowerPC, ARM). It provides the same features as the ARM-specific debug.S but
with more UART and architecture support.
As an example, here is the code generated for printch() by gcc 4.8 on ARM
using the ns16550 driver (Tegra Seaboard):
0013b3b0 <printch>:
13b3b0: e59f201c ldr r2, [pc, #28] ; 13b3d4 <printch+0x24>
13b3b4: e5d23305 ldrb r3, [r2, #773] ; 0x305
13b3b8: e6ef3073 uxtb r3, r3
13b3bc: e3130020 tst r3, #32
13b3c0: 0afffffb beq 13b3b4 <printch+0x4>
13b3c4: e6ef0070 uxtb r0, r0
13b3c8: e59f3004 ldr r3, [pc, #4] ; 13b3d4 <printch+0x24>
13b3cc: e5c30300 strb r0, [r3, #768] ; 0x300
13b3d0: e12fff1e bx lr
13b3d4: 70006000 .word 0x70006000
The PowerPC 4xx code (ELDK-5.3) for printhex8() is this:
0102db44 <printhex8>:
102db44: 3c c0 ef 60 lis r6,-4256
102db48: 3c e0 ef 60 lis r7,-4256
102db4c: 39 20 00 1c li r9,28
102db50: 60 c6 03 05 ori r6,r6,773
102db54: 60 e7 03 00 ori r7,r7,768
102db58: 7c 6a 4c 30 srw r10,r3,r9
102db5c: 55 4a 07 3e clrlwi r10,r10,28
102db60: 2b 8a 00 09 cmplwi cr7,r10,9
102db64: 39 0a 00 30 addi r8,r10,48
102db68: 40 9d 00 08 ble- cr7,102db70 <printhex8+0x2c>
102db6c: 39 0a 00 57 addi r8,r10,87
102db70: 7c 00 04 ac sync
102db74: 89 46 00 00 lbz r10,0(r6)
102db78: 0c 0a 00 00 twi 0,r10,0
102db7c: 4c 00 01 2c isync
102db80: 55 4a 06 b4 rlwinm r10,r10,0,26,26
102db84: 71 45 00 ff andi. r5,r10,255
102db88: 41 82 ff e8 beq+ 102db70 <printhex8+0x2c>
102db8c: 55 08 06 3e clrlwi r8,r8,24
102db90: 7c 00 04 ac sync
102db94: 99 07 00 00 stb r8,0(r7)
102db98: 2f 89 00 00 cmpwi cr7,r9,0
102db9c: 39 29 ff fc addi r9,r9,-4
102dba0: 40 9e ff b8 bne+ cr7,102db58 <printhex8+0x14>
102dba4: 4e 80 00 20 blr
However this is somewhat toolchain-dependent. For example, some toolchains
may spill over the available registers and use the stack. It would be nice to
have a way to tell gcc not to do that.
This is not offered as a catch-all solution, but I believe it has value for
many use cases.
Changes in v2:
- Add asmlinkage to exported functions
- Split series out on its own
- Add x86 support (asmlinkage, so it still needs a stack at present)
- Add better cover letter
Simon Glass (3):
serial: Support an early UART for debugging
serial: ns16550: Add access functions that don't need platdata
serial: ns16550: Support debug UART
drivers/serial/Kconfig | 59 ++++++++++++++++++++
drivers/serial/ns16550.c | 98 ++++++++++++++++++++++++++-------
include/debug_uart.h | 139 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 276 insertions(+), 20 deletions(-)
create mode 100644 include/debug_uart.h
--
2.2.0.rc0.207.ga3a616c
More information about the U-Boot
mailing list