From a84a1ddbbabb2389b5af91473250d0aff90e40d7 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Thu, 22 Apr 2021 14:14:02 +0530 Subject: [PATCH] lib: sbi: Simplify HSM platform operations Instead of having hsm_start(), hsm_stop() and hsm_suspend() callbacks in platform operations, it will be much simpler for HSM driver to directly register these operations as a device to the sbi_hsm implementation. Signed-off-by: Anup Patel Reviewed-by: Alistair Francis --- include/sbi/sbi_hsm.h | 31 +++++++++++++++++ include/sbi/sbi_platform.h | 83 +--------------------------------------------- lib/sbi/sbi_hsm.c | 68 ++++++++++++++++++++++++++++++------- lib/sbi/sbi_platform.c | 6 ---- 4 files changed, 88 insertions(+), 100 deletions(-) diff --git a/include/sbi/sbi_hsm.h b/include/sbi/sbi_hsm.h index bf0c1a5..c16e871 100644 --- a/include/sbi/sbi_hsm.h +++ b/include/sbi/sbi_hsm.h @@ -12,9 +12,40 @@ #include +/** Hart state managment device */ +struct sbi_hsm_device { + /** Name of the hart state managment device */ + char name[32]; + + /** Start (or power-up) the given hart */ + int (*hart_start)(u32 hartid, ulong saddr); + + /** + * Stop (or power-down) the current hart from running. This call + * doesn't expect to return if success. + */ + int (*hart_stop)(void); + + /** + * Put the current hart in platform specific suspend (or low-power) + * state. + * + * For successful retentive suspend, the call will return 0 when + * the hart resumes normal execution. + * + * For successful non-retentive suspend, the hart will resume from + * specified resume address + */ + int (*hart_suspend)(u32 suspend_type, ulong raddr); +}; + struct sbi_domain; struct sbi_scratch; +const struct sbi_hsm_device *sbi_hsm_get_device(void); + +void sbi_hsm_set_device(const struct sbi_hsm_device *dev); + int sbi_hsm_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot); void __noreturn sbi_hsm_exit(struct sbi_scratch *scratch); diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h index 921d39c..f8074d2 100644 --- a/include/sbi/sbi_platform.h +++ b/include/sbi/sbi_platform.h @@ -51,15 +51,11 @@ struct sbi_trap_regs; /** Possible feature flags of a platform */ enum sbi_platform_features { - /** Platform has HART hotplug support */ - SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 0), /** Platform has fault delegation support */ SBI_PLATFORM_HAS_MFAULTS_DELEGATION = (1 << 1), - /** Platform has custom secondary hart booting support */ - SBI_PLATFORM_HAS_HART_SECONDARY_BOOT = (1 << 2), /** Last index of Platform features*/ - SBI_PLATFORM_HAS_LAST_FEATURE = SBI_PLATFORM_HAS_HART_SECONDARY_BOOT, + SBI_PLATFORM_HAS_LAST_FEATURE = SBI_PLATFORM_HAS_MFAULTS_DELEGATION, }; /** Default feature set for a platform */ @@ -114,19 +110,6 @@ struct sbi_platform_operations { /** Exit platform timer for current HART */ void (*timer_exit)(void); - /** Bringup the given hart */ - int (*hart_start)(u32 hartid, ulong saddr); - /** - * Stop the current hart from running. This call doesn't expect to - * return if success. - */ - int (*hart_stop)(void); - /** - * Put the current hart in platform specific suspend (or low-power) - * state. - */ - int (*hart_suspend)(u32 suspend_type, ulong raddr); - /** platform specific SBI extension implementation probe function */ int (*vendor_ext_check)(long extid); /** platform specific SBI extension implementation provider */ @@ -193,15 +176,9 @@ struct sbi_platform { #define sbi_platform_ops(__p) \ ((const struct sbi_platform_operations *)(__p)->platform_ops_addr) -/** Check whether the platform supports HART hotplug */ -#define sbi_platform_has_hart_hotplug(__p) \ - ((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG) /** Check whether the platform supports fault delegation */ #define sbi_platform_has_mfaults_delegation(__p) \ ((__p)->features & SBI_PLATFORM_HAS_MFAULTS_DELEGATION) -/** Check whether the platform supports custom secondary hart booting support */ -#define sbi_platform_has_hart_secondary_boot(__p) \ - ((__p)->features & SBI_PLATFORM_HAS_HART_SECONDARY_BOOT) /** * Get HART index for the given HART @@ -317,64 +294,6 @@ static inline bool sbi_platform_hart_invalid(const struct sbi_platform *plat, } /** - * Bringup a given hart from previous stage. Platform should implement this - * operation if they support a custom mechanism to start a hart. Otherwise, - * a generic WFI based approach will be used to start/stop a hart in OpenSBI. - * - * @param plat pointer to struct sbi_platform - * @param hartid HART id - * @param saddr M-mode start physical address for the HART - * - * @return 0 if sucessful and negative error code on failure - */ -static inline int sbi_platform_hart_start(const struct sbi_platform *plat, - u32 hartid, ulong saddr) -{ - if (plat && sbi_platform_ops(plat)->hart_start) - return sbi_platform_ops(plat)->hart_start(hartid, saddr); - return SBI_ENOTSUPP; -} - -/** - * Stop the current hart in OpenSBI. - * - * @param plat pointer to struct sbi_platform - * - * @return Negative error code on failure. It doesn't return on success. - */ -static inline int sbi_platform_hart_stop(const struct sbi_platform *plat) -{ - if (plat && sbi_platform_ops(plat)->hart_stop) - return sbi_platform_ops(plat)->hart_stop(); - return SBI_ENOTSUPP; -} - -/** - * Put the current hart in platform specific suspend (or low-power) state. - * - * For successful retentive suspend, the call will return 0 when the hart - * resumes normal execution. - * - * For successful non-retentive suspend, the hart will resume from specified - * resume address - * - * @param plat pointer to struct sbi_platform - * @param suspend_type the type of suspend - * @param raddr physical address where the hart can resume in M-mode after - * non-retantive suspend - * - * @return 0 if successful and negative error code on failure - */ -static inline int sbi_platform_hart_suspend(const struct sbi_platform *plat, - u32 suspend_type, ulong raddr) -{ - if (plat && sbi_platform_ops(plat)->hart_suspend) - return sbi_platform_ops(plat)->hart_suspend(suspend_type, - raddr); - return SBI_ENOTSUPP; -} - -/** * Early initialization for current HART * * @param plat pointer to struct sbi_platform diff --git a/lib/sbi/sbi_hsm.c b/lib/sbi/sbi_hsm.c index 64d299b..4662150 100644 --- a/lib/sbi/sbi_hsm.c +++ b/lib/sbi/sbi_hsm.c @@ -21,11 +21,12 @@ #include #include #include -#include +#include #include #include #include +static const struct sbi_hsm_device *hsm_dev = NULL; static unsigned long hart_data_offset; /** Per hart specific data to manage state transition **/ @@ -129,6 +130,54 @@ static void sbi_hsm_hart_wait(struct sbi_scratch *scratch, u32 hartid) */ } +const struct sbi_hsm_device *sbi_hsm_get_device(void) +{ + return hsm_dev; +} + +void sbi_hsm_set_device(const struct sbi_hsm_device *dev) +{ + if (!dev || hsm_dev) + return; + + hsm_dev = dev; +} + +static bool hsm_device_has_hart_hotplug(void) +{ + if (hsm_dev && hsm_dev->hart_start && hsm_dev->hart_stop) + return true; + return false; +} + +static bool hsm_device_has_hart_secondary_boot(void) +{ + if (hsm_dev && hsm_dev->hart_start && !hsm_dev->hart_stop) + return true; + return false; +} + +static int hsm_device_hart_start(u32 hartid, ulong saddr) +{ + if (hsm_dev && hsm_dev->hart_start) + return hsm_dev->hart_start(hartid, saddr); + return SBI_ENOTSUPP; +} + +static int hsm_device_hart_stop(void) +{ + if (hsm_dev && hsm_dev->hart_stop) + return hsm_dev->hart_stop(); + return SBI_ENOTSUPP; +} + +static int hsm_device_hart_suspend(u32 suspend_type, ulong raddr) +{ + if (hsm_dev && hsm_dev->hart_suspend) + return hsm_dev->hart_suspend(suspend_type, raddr); + return SBI_ENOTSUPP; +} + int sbi_hsm_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot) { u32 i; @@ -164,7 +213,6 @@ int sbi_hsm_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot) void __noreturn sbi_hsm_exit(struct sbi_scratch *scratch) { u32 hstate; - const struct sbi_platform *plat = sbi_platform_ptr(scratch); struct sbi_hsm_data *hdata = sbi_scratch_offset_ptr(scratch, hart_data_offset); void (*jump_warmboot)(void) = (void (*)(void))scratch->warmboot_addr; @@ -174,8 +222,8 @@ void __noreturn sbi_hsm_exit(struct sbi_scratch *scratch) if (hstate != SBI_HSM_STATE_STOP_PENDING) goto fail_exit; - if (sbi_platform_has_hart_hotplug(plat)) { - sbi_platform_hart_stop(plat); + if (hsm_device_has_hart_hotplug()) { + hsm_device_hart_stop(); /* It should never reach here */ goto fail_exit; } @@ -201,7 +249,6 @@ int sbi_hsm_hart_start(struct sbi_scratch *scratch, unsigned int hstate; struct sbi_scratch *rscratch; struct sbi_hsm_data *hdata; - const struct sbi_platform *plat = sbi_platform_ptr(scratch); /* For now, we only allow start mode to be S-mode or U-mode. */ if (smode != PRV_S && smode != PRV_U) @@ -233,10 +280,9 @@ int sbi_hsm_hart_start(struct sbi_scratch *scratch, rscratch->next_addr = saddr; rscratch->next_mode = smode; - if (sbi_platform_has_hart_hotplug(plat) || - (sbi_platform_has_hart_secondary_boot(plat) && !init_count)) { - return sbi_platform_hart_start(plat, hartid, - scratch->warmboot_addr); + if (hsm_device_has_hart_hotplug() || + (hsm_device_has_hart_secondary_boot() && !init_count)) { + return hsm_device_hart_start(hartid, scratch->warmboot_addr); } else { sbi_ipi_raw_send(hartid); } @@ -374,7 +420,6 @@ int sbi_hsm_hart_suspend(struct sbi_scratch *scratch, u32 suspend_type, { int oldstate, ret; const struct sbi_domain *dom = sbi_domain_thishart_ptr(); - const struct sbi_platform *plat = sbi_platform_ptr(scratch); struct sbi_hsm_data *hdata = sbi_scratch_offset_ptr(scratch, hart_data_offset); @@ -420,8 +465,7 @@ int sbi_hsm_hart_suspend(struct sbi_scratch *scratch, u32 suspend_type, hdata->suspend_type = suspend_type; /* Try platform specific suspend */ - ret = sbi_platform_hart_suspend(plat, suspend_type, - scratch->warmboot_addr); + ret = hsm_device_hart_suspend(suspend_type, scratch->warmboot_addr); if (ret == SBI_ENOTSUPP) { /* Try generic implementation of default suspend types */ if (suspend_type == SBI_HSM_SUSPEND_RET_DEFAULT) { diff --git a/lib/sbi/sbi_platform.c b/lib/sbi/sbi_platform.c index e78119a..e8b94a3 100644 --- a/lib/sbi/sbi_platform.c +++ b/lib/sbi/sbi_platform.c @@ -19,15 +19,9 @@ static inline char *sbi_platform_feature_id2string(unsigned long feature) return NULL; switch (feature) { - case SBI_PLATFORM_HAS_HART_HOTPLUG: - fstr = "hotplug"; - break; case SBI_PLATFORM_HAS_MFAULTS_DELEGATION: fstr = "mfdeleg"; break; - case SBI_PLATFORM_HAS_HART_SECONDARY_BOOT: - fstr = "sec_boot"; - break; default: break; } -- 2.7.4