Re: Reset on Beaglebone Black has become unreliable/broken

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Dec 04, 2024 at 07:14:17AM +0100, Ahmad Fatoum wrote:

> Very interesting. You can now try to move the 4 putc_ll`s to a later point in the
> startup code and then see which line of barebox code needed the delay in front of
> it.

Dear Ahmad, I will try my best to put across what I did to the code and
where I get exactly stuck.

There is lowlevel.c with beaglebone_sram_init():

	am33xx_uart_soft_reset((void *)AM33XX_UART0_BASE);
	am33xx_enable_uart0_pin_mux();
	omap_debug_ll_init();
	putc_ll('>');
	putc_ll('6');
//	putc_ll('6');

	barebox_arm_entry(0x80000000, sdram_size, fdt);


Then I went to uncompress.c where there is barebox_pbl_start():

	void *handoff_data;

	putc_ll('A');
	/* piggy data is not relocated, so determine the bounds now */
	pg_start = runtime_address(input_data);
	pg_end = runtime_address(input_data_end);

	/*
	 * If we run from inside the memory just relocate the binary
	 * to the current address. Otherwise it may be a readonly location.
	 * Copy and relocate to the start of the memory in this case.
	 */
	if (pc > membase && pc - membase < memsize)
		relocate_to_current_adr();
	else
		relocate_to_adr(membase);

	pg_len = pg_end - pg_start;
	uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4));

	putc_ll('B');
	setup_c();

	putc_ll('C');
	pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);

	putc_ll('D');
	if (IS_ENABLED(CONFIG_MMU))
		mmu_early_enable(membase, memsize);

In mmu_32.c there is mmu_early_enable():

	set_ttbr(ttb);

	putc_ll('E');
	/* For the XN bit to take effect, we can't be using DOMAIN_MANAGER. */
	if (cpu_architecture() >= CPU_ARCH_ARMv7)
		set_domain(DOMAIN_CLIENT);
	else
		set_domain(DOMAIN_MANAGER);

	putc_ll('F');
	/*
	 * This marks the whole address space as uncachable as well as
	 * unexecutable if possible
	 */
	create_flat_mapping();

	putc_ll('G');
	/* maps main memory as cachable */
	early_remap_range(membase, memsize - OPTEE_SIZE, MAP_CACHED);
	putc_ll('H');
	early_remap_range(membase + memsize - OPTEE_SIZE, OPTEE_SIZE, MAP_UNCACHED);
	putc_ll('I');
	early_remap_range(PAGE_ALIGN_DOWN((uintptr_t)_stext), PAGE_ALIGN(_etext - _stext), MAP_CACHED);
	putc_ll('J');

	__mmu_cache_on();
	putc_ll('K');

For early_remap_range() I end up in __arch_remap_range() there is:

	u32 pte_flags, pmd_flags;
	putc_ll('-');
	uint32_t *ttb = get_ttb();

	putc_ll('|');
	BUG_ON(!IS_ALIGNED(virt_addr, PAGE_SIZE));
	putc_ll('!');
	BUG_ON(!IS_ALIGNED(phys_addr, PAGE_SIZE));

	putc_ll('_');
	pte_flags = get_pte_flags(map_type);

Well, lets mark get_ttb():

static inline uint32_t *get_ttb(void)
{
	putc_ll('%');
	/* Clear unpredictable bits [13:0] */
	return (uint32_t *)(get_ttbr() & ~0x3fff);
}

I _think_ this is the critical path, I have more putc_ll() inserted, but
they are not important.
If by any chance it is better readable for anyone I could provide a
complete diff, of course.

So, when I power up, I get:

2>6ABCDEF%G-%|!_H-%|!_I-%|!_%%%%JKLMNOPQZSwitch to console [cs0]

before the banner.

When I reset, S1, blabla, I get:

>6ABCDEF%G-%|

So I assume it dies at 

BUG_ON(!IS_ALIGNED(virt_addr, PAGE_SIZE));

at _arch_remap_range() in mmu_32.c.

Which yields to get_ttbr(void) in mmu_32.h which contains something like 
asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r"(ttb));

*EEEK*

Now I triple check with the second 6 enabled in lowlevel.c, no I change
it to 5, so:

	omap_debug_ll_init();
	putc_ll('>');
	putc_ll('6');
	putc_ll('5 ');

	barebox_arm_entry(0x80000000, sdram_size, fdt);

Powerup:
2>65ABCDEF%G-%|!_H-%|!_I-%|!_%%%%JKLMNOPQZSwitch to console [cs0]
reset:
>65ABCDEF%G-%|!_H-%|!_I-%|!_%%%%JKLMNOPQZSwitch to console [cs0]
S1:
>65ABCDEF%G-%|!_H-%|!_I-%|!_%%%%JKLMNOPQZSwitch to console [cs0]
mw 0x44e00f00 0x1:
�>65ABCDEF%G-%|!_H-%|!_I-%|!_%%%%JKLMNOPQZSwitch to console [cs0]
wd 1:
>65ABCDEF%G-%|!_H-%|!_I-%|!_%%%%JKLMNOPQZSwitch to console [cs0]
Booting linux, entering reboot there:
reboot: Restarting system
>65ABCDEF%G-%|!_H-%|!_I-%|!_%%%%JKLMNOPQZSwitch to console [cs0]

So each warm restart method gives me a proper reboot. 
With an additional putc_ll() in lowlevel.c in beaglebone_sram_init().
The later debug putc_ll() have no influence on starting not starting.

Kind regards
Konsti

-- 
INSIDE M2M GmbH
Konstantin Kletschke
Berenbosteler Straße 76 B
30823 Garbsen

Telefon: +49 (0) 5137 90950136
Mobil: +49 (0) 151 15256238
Fax: +49 (0) 5137 9095010

konstantin.kletschke@xxxxxxxxxxxxx
http://www.inside-m2m.de 

Geschäftsführung: Michael Emmert, Derek Uhlig
HRB: 111204, AG Hannover





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux