mips/broadcom: Implement CFE-based EARLY_PRINTF support.

This adds support for EARLY_PRINTF via the CFE console; the aim is to
provide a fix for the otherwise cyclic dependency between PMU discovery
and console printf/DELAY:

- We need to parse the bhnd(4) core table to determine the address (and
  type) of the PMU/PLL registers and calculate the CPU clock frequency.
- The core table parsing code will emit a printf() if a parse error is
  hit.
- Safely calling printf() without EARLY_PRINTF requires a working
  DELAY+cninit, which means we need the PMU.

Errors in core table parsing shouldn't happen, but lack of EARLY_PRINTF
makes debugging more difficult.

Approved by:	adrian (mentor)
Differential Revision:	https://reviews.freebsd.org/D7498
This commit is contained in:
Landon J. Fuller 2016-08-17 20:24:14 +00:00
parent fdf95c0b81
commit e15461c7e9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=304314
3 changed files with 49 additions and 16 deletions

View File

@ -198,6 +198,21 @@ platform_start(__register_t a0, __register_t a1, __register_t a2,
/* Initialize pcpu stuff */
mips_pcpu0_init();
#ifdef CFE
/*
* Initialize CFE firmware trampolines. This must be done
* before any CFE APIs are called, including writing
* to the CFE console.
*
* CFE passes the following values in registers:
* a0: firmware handle
* a2: firmware entry point
* a3: entry point seal
*/
if (a3 == CFE_EPTSEAL)
cfe_init(a0, a2);
#endif
#if 0
/*
* Probe the Broadcom on-chip PLL clock registers
@ -234,23 +249,40 @@ platform_start(__register_t a0, __register_t a1, __register_t a2,
mips_timer_early_init(platform_counter_freq);
#ifdef CFE
/*
* Initialize CFE firmware trampolines before
* we initialize the low-level console.
*
* CFE passes the following values in registers:
* a0: firmware handle
* a2: firmware entry point
* a3: entry point seal
*/
if (a3 == CFE_EPTSEAL)
cfe_init(a0, a2);
#endif
cninit();
mips_init();
mips_timer_init_params(platform_counter_freq, socinfo->double_count);
}
/*
* CFE-based EARLY_PRINTF support. To use, add the following to the kernel
* config:
* option EARLY_PRINTF
* option CFE
* device cfe
*/
#if defined(EARLY_PRINTF) && defined(CFE)
static void
bcm_cfe_eputc(int c)
{
static int fd = -1;
unsigned char ch;
ch = (unsigned char) c;
if (fd == -1) {
if ((fd = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE)) < 0)
return;
}
if (ch == '\n')
early_putc('\r');
while ((cfe_write(fd, &ch, 1)) == 0)
continue;
}
early_putc_t *early_putc = bcm_cfe_eputc;
#endif /* EARLY_PRINTF */

View File

@ -52,6 +52,7 @@ options INVARIANT_SUPPORT
#options BHND_LOGLEVEL=BHND_DEBUG_LEVEL
#options BUS_DEBUG
#makeoptions BUS_DEBUG
options EARLY_PRINTF
#options VERBOSE_SYSINIT
#makeoptions VERBOSE_SYSINIT

View File

@ -31,9 +31,8 @@ makeoptions TRAMPLOADADDR=0x807963c0
hints "SENTRY5.hints"
include "../broadcom/std.broadcom"
# sentry5 normally ships with cfe firmware; use the console for now
# sentry5 normally ships with cfe firmware
options CFE
options CFE_CONSOLE
options ALT_BREAK_TO_DEBUGGER
device cfe
@ -57,6 +56,7 @@ options INVARIANT_SUPPORT
#options BUS_DEBUG
#makeoptions BUS_DEBUG
options EARLY_PRINTF
device bhnd
device siba