linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Nicolas Pitre <nico@fluxnic.net>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>,
	Arnd Bergmann <arnd@arndb.de>,
	Russell King <linux@armlinux.org.uk>,
	linux-arm-kernel@lists.infradead.org,
	Ard Biesheuvel <ardb@kernel.org>
Subject: Re: [PATCH 3/3] RFC: ARM: head: Debug prints for section mappings
Date: Fri, 4 Sep 2020 11:51:42 -0400 (EDT)	[thread overview]
Message-ID: <nycvar.YSQ.7.78.906.2009041058240.4095746@knanqh.ubzr> (raw)
In-Reply-To: <20200904081949.5594-4-linus.walleij@linaro.org>

On Fri, 4 Sep 2020, Linus Walleij wrote:

> This creates a facility to print the early 1MB section mappings
> of the kernel. By selecting the symbol CONFIG_DEBUG_EARLY_MAPPINGS
> we can get a printout of some of the early mappings as they
> are written into the swapper_pg_dir page table during very early
> boot.
> 
> Currently I introduced hooks for printing the MMU enable 1:1
> mappings, the kernel RAM mappings and the "r2" (ATAGs or DTB)
> mappings.
> 
> The debug prints will show the physical address base and the
> virtual address base map, something like this for example:
> 
> Uncompressing Linux... done, booting the kernel.
> MMU enable: 0x40300000->0x40300000
> Kernel RAM: 0x40000000->0xc0000000
> Kernel RAM: 0x40100000->0xc0100000
> Kernel RAM: 0x40200000->0xc0200000
> (...)
> Kernel RAM: 0x42500000->0xc2500000
> Kernel RAM: 0x42600000->0xc2600000
> ATAG/DTB  : 0x43000000->0xc3000000
> ATAG/DTB  : 0x43100000->0xc3100000
> 
> This code does not try to be clever and shuffle registers
> around like some puzzle, instead we just store out r1 thru r6
> into memory while printing and read them back afterwards.
> It is debug code anyway, so optimizations are not any concern
> here.
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  arch/arm/Kconfig.debug |  13 ++++-
>  arch/arm/kernel/head.S | 109 ++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 120 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> index 87912e5c2256..a1620f2d0963 100644
> --- a/arch/arm/Kconfig.debug
> +++ b/arch/arm/Kconfig.debug
> @@ -1919,7 +1919,18 @@ config DEBUG_UNCOMPRESS
>  	  When this option is set, the selected DEBUG_LL output method
>  	  will be re-used for normal decompressor output on multiplatform
>  	  kernels.
> -	  
> +
> +config DEBUG_EARLY_MAPPINGS
> +	bool "Enable early section mapping debugging via DEBUG_LL output"
> +	depends on DEBUG_LL
> +	help
> +	  This option enables the kernel to print a list of all the 1 MB
> +	  section mappings used to map physical to virtual mempory
> +	  during the early boot. These mappings are used until the
> +	  kernel sets up the proper page table.
> +
> +	  The selected DEBUG_LL output method will be used for these debug
> +	  messages.
>  
>  config UNCOMPRESS_INCLUDE
>  	string
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index 8b089c4c0d17..5758a99f6f0f 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -163,6 +163,109 @@ ENDPROC(stext)
>  	.long	PAGE_OFFSET
>  #endif
>  
> +#ifdef CONFIG_DEBUG_EARLY_MAPPINGS
> +__debug_tmp:
> +	.align
> +	.long	0, 0, 0, 0, 0, 0 /* r1 thru r6 */

You shouldn't write to the .text segment. This won't work for XIP as 
you'll read 0 back, or worse you'll trigger a flash memory controller 
operation. You should allocate your temporary buffer in the .bss section 
instead. Look at the printhex code for example.

> +__en_mmu_debug_txt:
> +	.asciz	"MMU enable: "
> +	.align
> +__ram_debug_txt:
> +	.asciz	"Kernel RAM: "
> +	.align
> +__r2_debug_txt:
> +	.asciz	"ATAG/DTB  : "
> +	.align

No need to align string starts. This is necessary only after the last 
one.

> +	/*
> +	 * This macro prints one physical to virtual section map using
> +	 * a section descriptor and a section table address
> +	 */
> +	.macro	dbg_pr, secd, vindex
> +	/* Only the physical address in secd please */
> +	bic	\secd, \secd, #0x000ff000
> +	bic	\secd, \secd, #0x00000ff0
> +	bic	\secd, \secd, #0x0000000f
> +	/* Convert the section index to a virtual address */
> +	bic	\vindex, \vindex, #0xff000000
> +	bic	\vindex, \vindex, #0x00ff0000
> +	bic	\vindex, \vindex, #0x0000c000
> +	lsr	\vindex, \vindex, #PMD_ORDER /* Convert to index */
> +	lsl	\vindex, \vindex, #SECTION_SHIFT /* Convert to virtual address */
> +	mov	r0, #'0'
> +	bl	printch
> +	mov	r0, #'x'
> +	bl	printch
> +	mov	r0, \secd
> +	bl	printhex8
> +	mov	r0, #'-'
> +	bl	printch
> +	mov	r0, #'>'
> +	bl	printch
> +	mov	r0, #'0'
> +	bl	printch
> +	mov	r0, #'x'
> +	bl	printch

Here I'd suggest you add the string "->0x", or even " -> 0x" for 
some breathing room, e.g.:

__num_prefix_debug_txt:
	.asciz	" -> 0x"

Then, with the first number you use:

	adr	r0, __num_prefix_debug_txt + 4
	bl	printascii

and no string offset for the second number.

> +	mov	r0, \vindex
> +	bl	printhex8
> +	mov	r0, #'\n'
> +	bl	printch
> +	.endm
> +
> +	/*
> +	 * r3 = current section descriptor, bits 31-20 is the physical address
> +	 * r5 = section table index
> +	 */
> +	.macro	dbg_pr_mmu
> +	adr	r0, __debug_tmp
> +	stmia	r0, {r1-r6}
> +	mov	r6, r3 /* Save r3 to r6 (print corrupts r3) */
> +	adr	r0, __en_mmu_debug_txt
> +	bl	printascii
> +	/* Print helper wants physical offset index */
> +	lsl	r5, r5, #PMD_ORDER
> +	dbg_pr	r6, r5
> +	adr	r0, __debug_tmp
> +	ldmia	r0, {r1-r6}
> +	.endm
> +
> +	/*
> +	 * r0 = section table index absolute address in physical memory
> +	 * r3 = current section descriptor, bits 31-20 is the physical address
> +	 */
> +	.macro	dbg_pr_ram
> +	mov	r5, r0 /* Save r0 in r5 */
> +	adr	r0, __debug_tmp
> +	stmia	r0, {r1-r6}
> +	mov	r6, r3 /* Save r3 to r6 (print corrupts r3) */

A long long time ago I had a patch that shuffled registers around so 
that the long lived values would be kept in r4 and above so to free 
r0-r3 for short lived values and parameter passing to make things easier 
when doing this sort of thing. I don't remember if I pushed it to the 
patch system, and if I did probably it got outdated and I didn't refresh 
it.

> +	adr	r0, __ram_debug_txt
> +	bl	printascii
> +	dbg_pr	r6, r5
> +	adr	r0, __debug_tmp
> +	ldmia	r0, {r1-r6}
> +	mov	r0, r5 /* Restore r0 from r5 */
> +	.endm
> +
> +	/* Debug text for "what is in r2" either ATAGs or a DTB */
> +	.macro	dbg_pr_r2
> +	adr	r0, __debug_tmp
> +	stmia	r0, {r1-r6}
> +	mov	r5, r3 /* Save r3 to r5 (print corrupts r3) */
> +	adr	r0, __r2_debug_txt
> +	bl	printascii
> +	dbg_pr	r6, r5
> +	adr	r0, __debug_tmp
> +	ldmia	r0, {r1-r6}
> +	.endm
> +#else
> +	/* Dummy stubs when not debugging */
> +	.macro	dbg_pr_mmu
> +	.endm
> +	.macro	dbg_pr_ram
> +	.endm
> +	.macro	dbg_pr_r2
> +	.endm
> +#endif /* CONFIG_DEBUG_EARLY_MAPPINGS */
> +
>  /*
>   * Setup the initial page tables.  We only setup the barest
>   * amount which are required to get the kernel running, which
> @@ -234,6 +337,7 @@ __create_page_tables:
>  	mov	r6, r6, lsr #SECTION_SHIFT
>  
>  1:	orr	r3, r7, r5, lsl #SECTION_SHIFT	@ flags + kernel base
> +	dbg_pr_mmu
>  	str	r3, [r4, r5, lsl #PMD_ORDER]	@ identity mapping
>  	cmp	r5, r6
>  	addlo	r5, r5, #1			@ next section
> @@ -246,7 +350,8 @@ __create_page_tables:
>  	ldr	r6, =(_end - 1)
>  	orr	r3, r8, r7
>  	add	r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
> -1:	str	r3, [r0], #1 << PMD_ORDER
> +1:	dbg_pr_ram
> +	str	r3, [r0], #1 << PMD_ORDER
>  	add	r3, r3, #1 << SECTION_SHIFT
>  	cmp	r0, r6
>  	bls	1b
> @@ -281,8 +386,10 @@ __create_page_tables:
>  	add	r3, r3, #PAGE_OFFSET
>  	add	r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
>  	orr	r6, r7, r0
> +	dbg_pr_r2
>  	str	r6, [r3], #1 << PMD_ORDER
>  	add	r6, r6, #1 << SECTION_SHIFT
> +	dbg_pr_r2
>  	str	r6, [r3]
>  1:
>  
> -- 
> 2.26.2
> 
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2020-09-04 15:53 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-04  8:19 [PATCH 0/3] RFC: ARM section mapping debug prints Linus Walleij
2020-09-04  8:19 ` [PATCH 1/3] RFC: ARM: head: Use non-conditional instructions Linus Walleij
2020-09-04  8:19 ` [PATCH 2/3] RFC: ARM: head: Save lr in r11 while setting up page tables Linus Walleij
2020-09-04 14:53   ` Nicolas Pitre
2020-09-04  8:19 ` [PATCH 3/3] RFC: ARM: head: Debug prints for section mappings Linus Walleij
2020-09-04 15:51   ` Nicolas Pitre [this message]
2020-09-04 18:33     ` Nicolas Pitre

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=nycvar.YSQ.7.78.906.2009041058240.4095746@knanqh.ubzr \
    --to=nico@fluxnic.net \
    --cc=ardb@kernel.org \
    --cc=arnd@arndb.de \
    --cc=geert+renesas@glider.be \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux@armlinux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).