Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bda0f5ba authored by Chris Metcalf's avatar Chris Metcalf
Browse files

tile: various console improvements



This change improves and cleans up the tile console.

- We enable HVC_IRQ support on tilegx, with the addition of a new
  Tilera hypervisor API for tilegx to allow a console IPI.  If IPI
  support is not available we fall back to the previous polling mode.

- We simplify the earlyprintk code to use CON_BOOT and eliminate some
  of the other supporting earlyprintk code.

- A new tile_console_write() primitive is used to send output to
  the console and is factored out of the hvc_tile driver.
  This lets us support a "sim_console" boot argument to allow using
  simulator hooks to send output to the "console" as a slightly
  faster alternative to emulating the hardware more directly.

Signed-off-by: default avatarChris Metcalf <cmetcalf@tilera.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7c29b78a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@ config SMP
config HVC_TILE
	depends on TTY
	select HVC_DRIVER
	select HVC_IRQ if TILEGX
	def_bool y

config TILEGX
+1 −2
Original line number Diff line number Diff line
@@ -24,9 +24,8 @@
 */
#define MAXMEM_PFN	PFN_DOWN(MAXMEM)

int tile_console_write(const char *buf, int count);
void early_panic(const char *fmt, ...);
void warn_early_printk(void);
void __init disable_early_printk(void);

/* Init-time routine to do tile-specific per-cpu setup. */
void setup_cpu(int boot);
+28 −1
Original line number Diff line number Diff line
@@ -318,8 +318,11 @@
/** hv_set_pte_super_shift */
#define HV_DISPATCH_SET_PTE_SUPER_SHIFT           57

/** hv_console_set_ipi */
#define HV_DISPATCH_CONSOLE_SET_IPI               63

/** One more than the largest dispatch value */
#define _HV_DISPATCH_END                          58
#define _HV_DISPATCH_END                          64


#ifndef __ASSEMBLER__
@@ -585,6 +588,30 @@ typedef struct
 */
int hv_get_ipi_pte(HV_Coord tile, int pl, HV_PTE* pte);

/** Configure the console interrupt.
 *
 * When the console client interrupt is enabled, the hypervisor will
 * deliver the specified IPI to the client in the following situations:
 *
 * - The console has at least one character available for input.
 *
 * - The console can accept new characters for output, and the last call
 *   to hv_console_write() did not write all of the characters requested
 *   by the client.
 *
 * Note that in some system configurations, console interrupt will not
 * be available; clients should be prepared for this routine to fail and
 * to fall back to periodic console polling in that case.
 *
 * @param ipi Index of the IPI register which will receive the interrupt.
 * @param event IPI event number for console interrupt. If less than 0,
 *        disable the console IPI interrupt.
 * @param coord Tile to be targeted for console interrupt.
 * @return 0 on success, otherwise, HV_EINVAL if illegal parameter,
 *         HV_ENOTSUP if console interrupt are not available.
 */
int hv_console_set_ipi(int ipi, int event, HV_Coord coord);

#else /* !CHIP_HAS_IPI() */

/** A set of interrupts. */
+11 −36
Original line number Diff line number Diff line
@@ -23,19 +23,24 @@

static void early_hv_write(struct console *con, const char *s, unsigned n)
{
	hv_console_write((HV_VirtAddr) s, n);
	tile_console_write(s, n);

	/*
	 * Convert NL to NLCR (close enough to CRNL) during early boot.
	 * We assume newlines are at the ends of strings, which turns out
	 * to be good enough for early boot console output.
	 */
	if (n && s[n-1] == '\n')
		tile_console_write("\r", 1);
}

static struct console early_hv_console = {
	.name =		"earlyhv",
	.write =	early_hv_write,
	.flags =	CON_PRINTBUFFER,
	.flags =	CON_PRINTBUFFER | CON_BOOT,
	.index =	-1,
};

/* Direct interface for emergencies */
static int early_console_complete;

void early_panic(const char *fmt, ...)
{
	va_list ap;
@@ -43,51 +48,21 @@ void early_panic(const char *fmt, ...)
	va_start(ap, fmt);
	early_printk("Kernel panic - not syncing: ");
	early_vprintk(fmt, ap);
	early_console->write(early_console, "\n", 1);
	early_printk("\n");
	va_end(ap);
	dump_stack();
	hv_halt();
}

static int __initdata keep_early;

static int __init setup_early_printk(char *str)
{
	if (early_console)
		return 1;

	if (str != NULL && strncmp(str, "keep", 4) == 0)
		keep_early = 1;

	early_console = &early_hv_console;
	register_console(early_console);

	return 0;
}

void __init disable_early_printk(void)
{
	early_console_complete = 1;
	if (!early_console)
		return;
	if (!keep_early) {
		early_printk("disabling early console\n");
		unregister_console(early_console);
		early_console = NULL;
	} else {
		early_printk("keeping early console\n");
	}
}

void warn_early_printk(void)
{
	if (early_console_complete || early_console)
		return;
	early_printk("\
Machine shutting down before console output is fully initialized.\n\
You may wish to reboot and add the option 'earlyprintk' to your\n\
boot command line to see any diagnostic early console output.\n\
");
}

early_param("earlyprintk", setup_early_printk);
+2 −1
Original line number Diff line number Diff line
@@ -56,4 +56,5 @@ hv_inquire_realpa = TEXT_OFFSET + 0x106c0;
hv_flush_all = TEXT_OFFSET + 0x106e0;
hv_get_ipi_pte = TEXT_OFFSET + 0x10700;
hv_set_pte_super_shift = TEXT_OFFSET + 0x10720;
hv_glue_internals = TEXT_OFFSET + 0x10740;
hv_console_set_ipi = TEXT_OFFSET + 0x107e0;
hv_glue_internals = TEXT_OFFSET + 0x10800;
Loading