bsps/zynqmp: Use direct fdt_* calls

This changes the ZynqMP device tree parsing over to direct libfdt calls
to avoid inclusion of malloc() in the base BSP which currently causes
sp01 to fail due to unexpected use of TLS space.
This commit is contained in:
Kinsey Moore
2022-11-17 12:18:18 -06:00
committed by Joel Sherrill
parent a9861ceea0
commit efe8c37046

View File

@@ -37,7 +37,6 @@
#include <rtems/console.h> #include <rtems/console.h>
#include <rtems/bspIo.h> #include <rtems/bspIo.h>
#include <rtems/endian.h> #include <rtems/endian.h>
#include <rtems/rtems-fdt.h>
#include <rtems/sysinit.h> #include <rtems/sysinit.h>
#include <bsp/aarch64-mmu.h> #include <bsp/aarch64-mmu.h>
@@ -47,6 +46,7 @@
#include <dev/serial/zynq-uart.h> #include <dev/serial/zynq-uart.h>
#include <bspopts.h> #include <bspopts.h>
#include <libfdt.h>
#include <libchip/ns16550.h> #include <libchip/ns16550.h>
@@ -92,42 +92,36 @@ __attribute__ ((weak)) void zynqmp_configure_management_console(rtems_termios_de
static void zynqmp_management_console_init(void) static void zynqmp_management_console_init(void)
{ {
/* Find the management console in the device tree */ /* Find the management console in the device tree */
rtems_fdt_handle fdt_handle; const void *fdt = bsp_fdt_get();
const uint32_t *prop; const uint32_t *prop;
uint32_t outprop[4]; uint32_t outprop[4];
int proplen; int proplen;
int node; int node;
rtems_fdt_init_handle(&fdt_handle); const char *alias = fdt_get_alias(fdt, "mgmtport");
rtems_fdt_register(bsp_fdt_get(), &fdt_handle);
const char *alias = rtems_fdt_get_alias(&fdt_handle, "mgmtport");
if (alias == NULL) { if (alias == NULL) {
rtems_fdt_release_handle(&fdt_handle);
return; return;
} }
node = rtems_fdt_path_offset(&fdt_handle, alias); node = fdt_path_offset(fdt, alias);
prop = rtems_fdt_getprop(&fdt_handle, node, "clock-frequency", &proplen); prop = fdt_getprop(fdt, node, "clock-frequency", &proplen);
if ( prop == NULL || proplen != 4 ) { if ( prop == NULL || proplen != 4 ) {
rtems_fdt_release_handle(&fdt_handle);
zynqmp_mgmt_uart_context.port = 0; zynqmp_mgmt_uart_context.port = 0;
return; return;
} }
outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]); outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
zynqmp_mgmt_uart_context.clock = outprop[0]; zynqmp_mgmt_uart_context.clock = outprop[0];
prop = rtems_fdt_getprop(&fdt_handle, node, "current-speed", &proplen); prop = fdt_getprop(fdt, node, "current-speed", &proplen);
if ( prop == NULL || proplen != 4 ) { if ( prop == NULL || proplen != 4 ) {
rtems_fdt_release_handle(&fdt_handle);
zynqmp_mgmt_uart_context.port = 0; zynqmp_mgmt_uart_context.port = 0;
return; return;
} }
outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]); outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
zynqmp_mgmt_uart_context.initial_baud = outprop[0]; zynqmp_mgmt_uart_context.initial_baud = outprop[0];
prop = rtems_fdt_getprop(&fdt_handle, node, "interrupts", &proplen); prop = fdt_getprop(fdt, node, "interrupts", &proplen);
if ( prop == NULL || proplen != 12 ) { if ( prop == NULL || proplen != 12 ) {
rtems_fdt_release_handle(&fdt_handle);
zynqmp_mgmt_uart_context.port = 0; zynqmp_mgmt_uart_context.port = 0;
return; return;
} }
@@ -137,14 +131,12 @@ static void zynqmp_management_console_init(void)
/* proplen is in bytes, interrupt mapping expects a length in 32-bit cells */ /* proplen is in bytes, interrupt mapping expects a length in 32-bit cells */
zynqmp_mgmt_uart_context.irq = bsp_fdt_map_intr(outprop, proplen / 4); zynqmp_mgmt_uart_context.irq = bsp_fdt_map_intr(outprop, proplen / 4);
if ( zynqmp_mgmt_uart_context.irq == 0 ) { if ( zynqmp_mgmt_uart_context.irq == 0 ) {
rtems_fdt_release_handle(&fdt_handle);
zynqmp_mgmt_uart_context.port = 0; zynqmp_mgmt_uart_context.port = 0;
return; return;
} }
prop = rtems_fdt_getprop(&fdt_handle, node, "reg", &proplen); prop = fdt_getprop(fdt, node, "reg", &proplen);
if ( prop == NULL || proplen != 16 ) { if ( prop == NULL || proplen != 16 ) {
rtems_fdt_release_handle(&fdt_handle);
zynqmp_mgmt_uart_context.port = 0; zynqmp_mgmt_uart_context.port = 0;
return; return;
} }
@@ -164,26 +156,22 @@ static void zynqmp_management_console_init(void)
return; return;
} }
prop = rtems_fdt_getprop(&fdt_handle, node, "reg-offset", &proplen); prop = fdt_getprop(fdt, node, "reg-offset", &proplen);
if ( prop == NULL || proplen != 4 ) { if ( prop == NULL || proplen != 4 ) {
rtems_fdt_release_handle(&fdt_handle);
zynqmp_mgmt_uart_context.port = 0; zynqmp_mgmt_uart_context.port = 0;
return; return;
} }
outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]); outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
zynqmp_mgmt_uart_context.port += outprop[0]; zynqmp_mgmt_uart_context.port += outprop[0];
prop = rtems_fdt_getprop(&fdt_handle, node, "reg-shift", &proplen); prop = fdt_getprop(fdt, node, "reg-shift", &proplen);
if ( prop == NULL || proplen != 4 ) { if ( prop == NULL || proplen != 4 ) {
rtems_fdt_release_handle(&fdt_handle);
zynqmp_mgmt_uart_context.port = 0; zynqmp_mgmt_uart_context.port = 0;
return; return;
} }
outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]); outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
mgmt_uart_reg_shift = outprop[0]; mgmt_uart_reg_shift = outprop[0];
rtems_fdt_release_handle(&fdt_handle);
ns16550_probe(&zynqmp_mgmt_uart_context.base); ns16550_probe(&zynqmp_mgmt_uart_context.base);
zynqmp_configure_management_console(&zynqmp_mgmt_uart_context.base); zynqmp_configure_management_console(&zynqmp_mgmt_uart_context.base);