From 76f0f814075338970c7e7914ab94644e855632f7 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 24 Apr 2020 16:53:32 +0530 Subject: [PATCH] lib: utils: Add simple FDT ipi framework We add simple ipi framework which will select and use ipi driver based on details in FDT passed by previous booting stage. Signed-off-by: Anup Patel Reviewed-by: Atish Patra --- include/sbi_utils/ipi/fdt_ipi.h | 32 +++++++++++ lib/utils/ipi/fdt_ipi.c | 99 +++++++++++++++++++++++++++++++++ lib/utils/ipi/fdt_ipi_clint.c | 44 +++++++++++++++ lib/utils/ipi/objects.mk | 11 ++++ 4 files changed, 186 insertions(+) create mode 100644 include/sbi_utils/ipi/fdt_ipi.h create mode 100644 lib/utils/ipi/fdt_ipi.c create mode 100644 lib/utils/ipi/fdt_ipi_clint.c create mode 100644 lib/utils/ipi/objects.mk diff --git a/include/sbi_utils/ipi/fdt_ipi.h b/include/sbi_utils/ipi/fdt_ipi.h new file mode 100644 index 00000000..e817141a --- /dev/null +++ b/include/sbi_utils/ipi/fdt_ipi.h @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel + */ + +#ifndef __FDT_IPI_H__ +#define __FDT_IPI_H__ + +#include + +struct fdt_ipi { + const struct fdt_match *match_table; + int (*cold_init)(void *fdt, int nodeoff, const struct fdt_match *match); + int (*warm_init)(void); + void (*exit)(void); + void (*send)(u32 target_hart); + void (*clear)(u32 target_hart); +}; + +void fdt_ipi_send(u32 target_hart); + +void fdt_ipi_clear(u32 target_hart); + +void fdt_ipi_exit(void); + +int fdt_ipi_init(bool cold_boot); + +#endif diff --git a/lib/utils/ipi/fdt_ipi.c b/lib/utils/ipi/fdt_ipi.c new file mode 100644 index 00000000..d8ba0b24 --- /dev/null +++ b/lib/utils/ipi/fdt_ipi.c @@ -0,0 +1,99 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel + */ + +#include +#include +#include + +extern struct fdt_ipi fdt_ipi_clint; + +static struct fdt_ipi *ipi_drivers[] = { + &fdt_ipi_clint +}; + +static void dummy_send(u32 target_hart) +{ +} + +static void dummy_clear(u32 target_hart) +{ +} + +static struct fdt_ipi dummy = { + .match_table = NULL, + .cold_init = NULL, + .warm_init = NULL, + .exit = NULL, + .send = dummy_send, + .clear = dummy_clear +}; + +static struct fdt_ipi *current_driver = &dummy; + +void fdt_ipi_send(u32 target_hart) +{ + current_driver->send(target_hart); +} + +void fdt_ipi_clear(u32 target_hart) +{ + current_driver->clear(target_hart); +} + +void fdt_ipi_exit(void) +{ + if (current_driver->exit) + current_driver->exit(); +} + +static int fdt_ipi_warm_init(void) +{ + if (current_driver->warm_init) + return current_driver->warm_init(); + return 0; +} + +static int fdt_ipi_cold_init(void) +{ + int pos, noff, rc; + struct fdt_ipi *drv; + const struct fdt_match *match; + void *fdt = sbi_scratch_thishart_arg1_ptr(); + + for (pos = 0; pos < array_size(ipi_drivers); pos++) { + drv = ipi_drivers[pos]; + + noff = fdt_find_match(fdt, drv->match_table, &match); + if (noff < 0) + continue; + + if (drv->cold_init) { + rc = drv->cold_init(fdt, noff, match); + if (rc) + return rc; + } + current_driver = drv; + break; + } + + return 0; +} + +int fdt_ipi_init(bool cold_boot) +{ + int rc; + + if (cold_boot) { + rc = fdt_ipi_cold_init(); + if (rc) + return rc; + } + + return fdt_ipi_warm_init(); +} diff --git a/lib/utils/ipi/fdt_ipi_clint.c b/lib/utils/ipi/fdt_ipi_clint.c new file mode 100644 index 00000000..05b66c60 --- /dev/null +++ b/lib/utils/ipi/fdt_ipi_clint.c @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel + */ + +#include +#include +#include + +static int ipi_clint_cold_init(void *fdt, int nodeoff, + const struct fdt_match *match) +{ + int rc; + u32 max_hartid; + unsigned long addr; + + rc = fdt_parse_max_hart_id(fdt, &max_hartid); + if (rc) + return rc; + + rc = fdt_get_node_addr_size(fdt, nodeoff, &addr, NULL); + if (rc) + return rc; + + return clint_cold_ipi_init(addr, max_hartid + 1); +} + +static const struct fdt_match ipi_clint_match[] = { + { .compatible = "riscv,clint0" }, + { }, +}; + +struct fdt_ipi fdt_ipi_clint = { + .match_table = ipi_clint_match, + .cold_init = ipi_clint_cold_init, + .warm_init = clint_warm_ipi_init, + .exit = NULL, + .send = clint_ipi_send, + .clear = clint_ipi_clear, +}; diff --git a/lib/utils/ipi/objects.mk b/lib/utils/ipi/objects.mk new file mode 100644 index 00000000..00719579 --- /dev/null +++ b/lib/utils/ipi/objects.mk @@ -0,0 +1,11 @@ +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2020 Western Digital Corporation or its affiliates. +# +# Authors: +# Anup Patel +# + +libsbiutils-objs-y += ipi/fdt_ipi.o +libsbiutils-objs-y += ipi/fdt_ipi_clint.o