U-Boot: Factor-out debug UART setup from FDT for kernel use
This commit is contained in:
@@ -24,6 +24,8 @@ extern "C" {
|
||||
};
|
||||
|
||||
|
||||
extern "C" DebugUART *debug_uart_from_fdt(const void *fdt);
|
||||
|
||||
DebugUART* gUART;
|
||||
|
||||
static int32 sSerialEnabled = 0;
|
||||
@@ -96,90 +98,11 @@ serial_cleanup(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
serial_init_fdt(const void *fdt)
|
||||
{
|
||||
const char *name;
|
||||
const char *type;
|
||||
int node;
|
||||
int len;
|
||||
phys_addr_t regs;
|
||||
int32 clock = 0;
|
||||
int32 speed = 0;
|
||||
const void *prop;
|
||||
|
||||
if (fdt == NULL)
|
||||
return;
|
||||
|
||||
name = fdt_get_alias(fdt, "serial");
|
||||
if (name == NULL)
|
||||
name = fdt_get_alias(fdt, "serial0");
|
||||
if (name == NULL)
|
||||
name = fdt_get_alias(fdt, "serial1");
|
||||
// TODO: else use /chosen linux,stdout-path
|
||||
if (name == NULL)
|
||||
return;
|
||||
|
||||
node = fdt_path_offset(fdt, name);
|
||||
//dprintf("serial: using '%s', node %d\n", name, node);
|
||||
if (node < 0)
|
||||
return;
|
||||
|
||||
type = (const char *)fdt_getprop(fdt, node, "device_type", &len);
|
||||
//dprintf("serial: type: '%s'\n", type);
|
||||
if (type == NULL || strcmp(type, "serial"))
|
||||
return;
|
||||
|
||||
// determine the MMIO address
|
||||
// TODO: ppc460 use 64bit addressing, but U-Boot seems to map it below 4G,
|
||||
// and the FDT is not very clear. libfdt is also getting 64bit addr support.
|
||||
// so FIXME someday.
|
||||
prop = fdt_getprop(fdt, node, "virtual-reg", &len);
|
||||
if (prop && len == 4) {
|
||||
regs = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
//dprintf("serial: virtual-reg 0x%08llx\n", (int64)regs);
|
||||
} else {
|
||||
prop = fdt_getprop(fdt, node, "reg", &len);
|
||||
if (prop && len >= 4) {
|
||||
regs = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
//dprintf("serial: reg 0x%08llx\n", (int64)regs);
|
||||
} else
|
||||
return;
|
||||
}
|
||||
|
||||
// get the UART clock rate
|
||||
prop = fdt_getprop(fdt, node, "clock-frequency", &len);
|
||||
if (prop && len == 4) {
|
||||
clock = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
//dprintf("serial: clock %ld\n", clock);
|
||||
}
|
||||
|
||||
// get current speed (XXX: not yet passed over)
|
||||
prop = fdt_getprop(fdt, node, "current-speed", &len);
|
||||
if (prop && len == 4) {
|
||||
speed = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
//dprintf("serial: speed %ld\n", speed);
|
||||
}
|
||||
|
||||
if (fdt_node_check_compatible(fdt, node, "ns16550a") == 1
|
||||
|| fdt_node_check_compatible(fdt, node, "ns16550") == 1) {
|
||||
gUART = arch_get_uart_8250(regs, clock);
|
||||
//dprintf("serial: using 8250\n");
|
||||
// XXX:assume speed is already set
|
||||
(void)speed;
|
||||
return;
|
||||
}
|
||||
|
||||
// for when we can use U-Boot's console
|
||||
panic("Unknown UART type %s", type);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
serial_init(const void *fdt)
|
||||
{
|
||||
// first try with hints from the FDT
|
||||
serial_init_fdt(fdt);
|
||||
gUART = debug_uart_from_fdt(fdt);
|
||||
|
||||
#ifdef BOARD_UART_DEBUG
|
||||
// fallback to hardcoded board UART
|
||||
|
||||
@@ -26,6 +26,8 @@ KernelMergeObject kernel_arch_ppc.o :
|
||||
arch_vm.cpp
|
||||
arch_vm_translation_map.cpp
|
||||
arch_asm.S
|
||||
debug_uart_8250.cpp
|
||||
arch_uart_8250.cpp
|
||||
|
||||
generic_vm_physical_page_mapper.cpp
|
||||
generic_vm_physical_page_ops.cpp
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <arch/generic/debug_uart.h>
|
||||
#include <arch/generic/debug_uart_8250.h>
|
||||
|
||||
extern "C" {
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
@@ -21,6 +24,7 @@ void *gFDT;
|
||||
#endif
|
||||
|
||||
extern "C" void dump_fdt(const void *fdt);
|
||||
extern "C" DebugUART *debug_uart_from_fdt(const void *fdt);
|
||||
|
||||
//#define FDT_DUMP_NODES
|
||||
//#define FDT_DUMP_PROPS
|
||||
@@ -117,3 +121,84 @@ void dump_fdt(const void *fdt)
|
||||
}
|
||||
|
||||
|
||||
DebugUART *
|
||||
debug_uart_from_fdt(const void *fdt)
|
||||
{
|
||||
const char *name;
|
||||
const char *type;
|
||||
int node;
|
||||
int len;
|
||||
phys_addr_t regs;
|
||||
int32 clock = 0;
|
||||
int32 speed = 0;
|
||||
const void *prop;
|
||||
DebugUART *uart = NULL;
|
||||
|
||||
if (fdt == NULL)
|
||||
return NULL;
|
||||
|
||||
name = fdt_get_alias(fdt, "serial");
|
||||
if (name == NULL)
|
||||
name = fdt_get_alias(fdt, "serial0");
|
||||
if (name == NULL)
|
||||
name = fdt_get_alias(fdt, "serial1");
|
||||
// TODO: else use /chosen linux,stdout-path
|
||||
if (name == NULL)
|
||||
return NULL;
|
||||
|
||||
node = fdt_path_offset(fdt, name);
|
||||
//dprintf("serial: using '%s', node %d\n", name, node);
|
||||
if (node < 0)
|
||||
return NULL;
|
||||
|
||||
type = (const char *)fdt_getprop(fdt, node, "device_type", &len);
|
||||
//dprintf("serial: type: '%s'\n", type);
|
||||
if (type == NULL || strcmp(type, "serial"))
|
||||
return NULL;
|
||||
|
||||
// determine the MMIO address
|
||||
// TODO: ppc460 use 64bit addressing, but U-Boot seems to map it below 4G,
|
||||
// and the FDT is not very clear. libfdt is also getting 64bit addr support.
|
||||
// so FIXME someday.
|
||||
prop = fdt_getprop(fdt, node, "virtual-reg", &len);
|
||||
if (prop && len == 4) {
|
||||
regs = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
//dprintf("serial: virtual-reg 0x%08llx\n", (int64)regs);
|
||||
} else {
|
||||
prop = fdt_getprop(fdt, node, "reg", &len);
|
||||
if (prop && len >= 4) {
|
||||
regs = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
//dprintf("serial: reg 0x%08llx\n", (int64)regs);
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// get the UART clock rate
|
||||
prop = fdt_getprop(fdt, node, "clock-frequency", &len);
|
||||
if (prop && len == 4) {
|
||||
clock = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
//dprintf("serial: clock %ld\n", clock);
|
||||
}
|
||||
|
||||
// get current speed (XXX: not yet passed over)
|
||||
prop = fdt_getprop(fdt, node, "current-speed", &len);
|
||||
if (prop && len == 4) {
|
||||
speed = fdt32_to_cpu(*(uint32_t *)prop);
|
||||
//dprintf("serial: speed %ld\n", speed);
|
||||
}
|
||||
|
||||
if (fdt_node_check_compatible(fdt, node, "ns16550a") == 1
|
||||
|| fdt_node_check_compatible(fdt, node, "ns16550") == 1) {
|
||||
uart = arch_get_uart_8250(regs, clock);
|
||||
//dprintf("serial: using 8250\n");
|
||||
// XXX:assume speed is already set
|
||||
(void)speed;
|
||||
} else {
|
||||
// TODO: handle more UART types
|
||||
// for when we can use U-Boot's console
|
||||
panic("Unknown UART type %s", type);
|
||||
}
|
||||
|
||||
return uart;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user