kernel boot stuck at udbg_putc_cpm()

Shawn Jin shawnxjin at gmail.com
Mon Jul 5 17:23:45 EST 2010


Hi,

I'm debugging the kernel (2.6.33.5) ported for a MPC870 board. The
changes are mostly based on the board adder875. The first thing I want
to test is the serial port. So I enabled CONFIG_PPC_EARLY_DEBUG and
CONFIG_PPC_EARLY_DEBUG_CPM, and changed
CONFIG_PPC_EARLY_DEBUG_CPM_ADDR to 0xfa202008. My IMMR is 0xfa200000.
However the kernel seems to stuck at udbg_putc_cpm(). The most
significant bit at 0xfa202008 never changed to zero.

I did a few debugging sessions, observed some frustrating things.
Would anyone here more experienced shed some lights on potential
causes?

First I set breakpoint at machine_init(). Below is the debug session.

(gdb) target remote bdi:2001
Remote debugging using bdi:2001
machine_init (dt_ptr=5890816) at arch/powerpc/kernel/setup_32.c:121
121	{
(gdb) next
125		udbg_early_init();
(gdb) next
^C
Program received signal SIGSTOP, Stopped (signal).
udelay (usecs=<value optimized out>)
    at /home/rayan/wti/code/wti-linux-2.6.33.5/arch/powerpc/include/asm/time.h:78
78		return mftbl();
(gdb) li
73	#if defined(CONFIG_403GCX)
74		unsigned long tbl;
75		asm volatile("mfspr %0, 0x3dd" : "=r" (tbl));
76		return tbl;
77	#else
78		return mftbl();
79	#endif
80	}
81	
82	static inline unsigned int get_tbu(void)
(gdb) step
413			while (get_tbl() - start < loops)
(gdb) step
414				HMT_low();
(gdb) print start
No symbol "start" in current context.
(gdb) print loops
No symbol "loops" in current context.
(gdb)

Several observations regarding to the above debugging session.
1. The kernel seems not able to pass udbg_early_init(). However if
breakpoint was set at functions being executed later such as
probe_machine() or start_kernel(), the udbg_early_init() was executed
properly.
2. When the execution was interrupted, it stopped at __delay(). And
the kernel seems not able to get out of this __delay() function. There
was even no symbols for local variables. Why?

Next I set the breakpoint at probe_machine(). The gdb session is shown
below. Again a couple of frustrating observations.
1. The kernel seems not able to get into the for loop. The breakpoint
set inside the for loop never got hit.
2. Once the execution was interrupted, it stopped at __delay() again,
same as the previous gdb session.

(gdb) target remote bdi:2001
Remote debugging using bdi:2001
probe_machine () at arch/powerpc/kernel/setup-common.c:525
525	{
(gdb) step
535		for (machine_id = &__machine_desc_start;
(gdb) print __machine_desc_start
$1 = {name = 0xc013ea64 "My MPC870", pci_dma_dev_setup = 0,
  pci_dma_bus_setup = 0, probe = 0xc01544c4 <my870_probe>,
  setup_arch = 0xc015442c <my870_setup>, init_early = 0, show_cpuinfo = 0,
  show_percpuinfo = 0, init_IRQ = 0xc01541d4 <mpc8xx_pics_init>,
  get_irq = 0xc001344c <mpc8xx_get_irq>, pcibios_fixup = 0,
  pci_probe_mode = 0, pci_irq_fixup = 0, pci_setup_phb = 0,
  restart = 0xc0013f0c <mpc8xx_restart>, power_off = 0, halt = 0, panic = 0,
  cpu_die = 0, time_init = 0, set_rtc_time = 0xc0013fdc <mpc8xx_set_rtc_time>,
  get_rtc_time = 0xc0013f78 <mpc8xx_get_rtc_time>, get_boot_time = 0,
  rtc_read_val = 0, rtc_write_val = 0,
  calibrate_decr = 0xc0151e70 <generic_calibrate_decr>,
  progress = 0xc0153110 <udbg_progress>, log_error = 0, nvram_read_val = 0,
  nvram_write_val = 0, nvram_write = 0, nvram_read = 0, nvram_size = 0,
  nvram_sync = 0, system_reset_exception = 0, machine_check_exception = 0,
  feature_call = 0, pci_get_legacy_ide_irq = 0, phys_mem_access_prot = 0,
  idle_loop = 0, power_save = 0, enable_pmcs = 0, set_dabr = 0, init = 0,
  kgdb_map_scc = 0, pcibios_after_init = 0, pci_exclude_device = 0,
  pcibios_fixup_resources = 0, pcibios_fixup_bus = 0,
  pcibios_enable_device_hook = 0, machine_shutdown = 0}
(gdb) print __machine_desc_end
$2 = {name = 0x0, pci_dma_dev_setup = 0, pci_dma_bus_setup = 0, probe = 0,
  setup_arch = 0, init_early = 0, show_cpuinfo = 0, show_percpuinfo = 0,
  init_IRQ = 0, get_irq = 0, pcibios_fixup = 0, pci_probe_mode = 0,
  pci_irq_fixup = 0, pci_setup_phb = 0, restart = 0, power_off = 0, halt = 0,
  panic = 0, cpu_die = 0, time_init = 0, set_rtc_time = 0, get_rtc_time = 0,
  get_boot_time = 0, rtc_read_val = 0, rtc_write_val = 0, calibrate_decr = 0,
  progress = 0, log_error = 0, nvram_read_val = 0, nvram_write_val = 0,
  nvram_write = 0, nvram_read = 0, nvram_size = 0, nvram_sync = 0,
  system_reset_exception = 0, machine_check_exception = 0, feature_call = 0,
  pci_get_legacy_ide_irq = 0, phys_mem_access_prot = 0, idle_loop = 0,
  power_save = 0, enable_pmcs = 0, set_dabr = 0, init = 0, kgdb_map_scc = 0,
  pcibios_after_init = 0, pci_exclude_device = 0, pcibios_fixup_resources = 0,
  pcibios_fixup_bus = 0, pcibios_enable_device_hook = 0, machine_shutdown = 0}
(gdb) step
536		     machine_id < &__machine_desc_end;
(gdb) print machine_id
$3 = (struct machdep_calls *) 0x0
(gdb) step
525	{
(gdb) step
535		for (machine_id = &__machine_desc_start;
(gdb) step
525	{
(gdb) step
536		     machine_id < &__machine_desc_end;
(gdb) step
535		for (machine_id = &__machine_desc_start;
(gdb) step
525	{
(gdb) step
535		for (machine_id = &__machine_desc_start;
(gdb) list
530		 * Iterate all ppc_md structures until we find the proper
531		 * one for the current machine type
532		 */
533		DBG("Probing machine type ...\n");
534	
535		for (machine_id = &__machine_desc_start;
536		     machine_id < &__machine_desc_end;
537		     machine_id++) {
538			DBG("  %s ...", machine_id->name);
539			memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls));
(gdb) list
540			if (ppc_md.probe()) {
541				DBG(" match !\n");
542				break;
543			}
544			DBG("\n");
545		}
546		/* What can we do if we didn't find ? */
547		if (machine_id >= &__machine_desc_end) {
548			DBG("No suitable machine found !\n");
549			for (;;);
(gdb) b 540
Breakpoint 1 at 0xc000cdb8: file arch/powerpc/kernel/setup-common.c, line 540.
(gdb) cont
Continuing.
^C
Program received signal SIGSTOP, Stopped (signal).
udelay (usecs=<value optimized out>) at arch/powerpc/kernel/time.c:414
414				HMT_low();
(gdb)

Finally I decided to set the breakpoint at start_kernel(). This time
where the kernel stuck was different from the previous two debugging
trials. The kernel was stuck before it reached the start_kernel(). And
I believe this udbg_put_cpm() was called when the kernel tried to
print "id mach(): done" inside machine_init().

 145        if (ppc_md.progress)
 146                ppc_md.progress("id mach(): done", 0x200);

The debug session is shown below. I also dump the cpm_udbg_txdesc from
BDI, which showed that the bit0 was always 1.

(gdb) target remote bdi:2001
Remote debugging using bdi:2001
0xc0012df8 in udbg_putc_cpm (c=105 'i')
    at /home/rayan/wti/code/wti-linux-2.6.33.5/arch/powerpc/include/asm/io.h:155
155	DEF_MMIO_IN_BE(in_be32, 32, lwz);
(gdb) next
48		while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
(gdb) next
48		while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
(gdb) next
48		while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
(gdb) b 51
Breakpoint 1 at 0xc0012e2c: file arch/powerpc/sysdev/cpm_common.c, line 51.
(gdb) cont
Continuing.
^C
Program received signal SIGSTOP, Stopped (signal).
udbg_putc_cpm (c=105 'i') at arch/powerpc/sysdev/cpm_common.c:48
48		while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
(gdb) frame
#0  udbg_putc_cpm (c=105 'i') at arch/powerpc/sysdev/cpm_common.c:48
48		while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
(gdb)

BDI>md 0xfa202000 4
fa202000 : 0xffffffff  -         1  ....
fa202004 : 0xffffffff  -         1  ....
fa202008 : 0xffffffff  -         1  ....
fa20200c : 0xffffffff  -         1  ....

Thanks a lot,
-Shawn.


More information about the Linuxppc-dev mailing list