lib: reset: Add early_init api for fdt_reset_drv
PATCH 1/1 lib: reset: Add early_init api for fdt_reset_drv
From: Guo Ren <[email protected]>
The fdt_reset_thead driver needs to modify the __reset_thead_csr_stub text region for the secondary harts booting. After that, the sbi_hart_pmp_configure may lock down the text region with M_READABLE & M_EXECUTABLE attributes in the future. Currently, the M_READABLE & M_EXECUtABLE have no effect on m-mode, the L-bit in pmpcfg csr is useless for the current opensbi scenario. See:
Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
When the L bit is clear, any M-mode access matching the PMP entry will succeed; the R/W/X permissions apply only to S and U modes.
That's why current fdt_reset_thead could still work well after commit:230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW regions"). So this patch fixes up a fake bug for the M-mode permission setting of the future.
--- include/sbi_utils/reset/fdt_reset.h | 9 +++++---- lib/utils/reset/fdt_reset.c | 20 +++++++++++++------- lib/utils/reset/fdt_reset_thead.c | 2 +- platform/generic/platform.c | 5 ++++- platform/generic/sifive/fu740.c | 2 +- platform/generic/starfive/jh7110.c | 2 +- 6 files changed, 25 insertions(+), 15 deletions(-)
include/sbi_utils/reset/fdt_reset.h +5 -4
@@ -15,6 +15,7 @@struct fdt_reset {const struct fdt_match *match_table;int (*init)(void *fdt,int nodeoff,const struct fdt_match *match); +int (*early_init)(void *fdt,int nodeoff,const struct fdt_match *match); };#ifdef CONFIG_FDT_RESET
@@ -22,22 +23,22 @@ struct fdt_reset {/** * fdt_reset_driver_init() - initialize reset driver based on the device-tree */ -int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv); +int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv,bool early);/** * fdt_reset_init() - initialize reset drivers based on the device-tree * * This function shall be invoked in final init. */ -void fdt_reset_init (void ); +void fdt_reset_init (bool early);#else -static inline int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv) +static inline int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv,bool early) {return 0 ; } -static inline void fdt_reset_init (void ) { } +static inline void fdt_reset_init (bool early) { }#endif
lib/utils/reset/fdt_reset.c +13 -7
@@ -17,31 +17,37 @@extern struct fdt_reset *fdt_reset_drivers[];extern unsigned long fdt_reset_drivers_size; -int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv) +int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv,bool early) {int noff, rc =SBI_ENODEV ;const struct fdt_match *match; +int (*init)(void *fdt,int nodeoff,const struct fdt_match *match); noff =fdt_find_match (fdt,-1 , drv->match_table, &match);if (noff <0 )return SBI_ENODEV ; -if (drv->init) { - rc = drv->init (fdt, noff, match); +if (early) + init = drv->early_init; +else + init = drv->init; + +if (init) { + rc =init (fdt, noff, match);if (rc && rc !=SBI_ENODEV ) { -sbi_printf ("%s: %s init failed, %d\n" , - __func__, match->compatible, rc); +sbi_printf ("%s: %s %s-init failed, %d\n" , + __func__, match->compatible, early?"early" :"final" , rc); } }return rc; } -void fdt_reset_init (void ) +void fdt_reset_init (bool early) {int pos;void *fdt =fdt_get_address ();for (pos =0 ; pos < fdt_reset_drivers_size; pos++) -fdt_reset_driver_init (fdt, fdt_reset_drivers[pos]); +fdt_reset_driver_init (fdt, fdt_reset_drivers[pos], early); }
lib/utils/reset/fdt_reset_thead.c +1 -1
@@ -130,5 +130,5 @@ static const struct fdt_match thead_reset_match[] = {struct fdt_reset fdt_reset_thead = { .match_table = thead_reset_match, - .init = thead_reset_init + .early_init = thead_reset_init };
platform/generic/platform.c +4 -1
@@ -146,6 +146,9 @@ static int generic_early_init(bool cold_boot)if (!generic_plat || !generic_plat->early_init)return 0 ; +if (cold_boot) +fdt_reset_init (true); +return generic_plat->early_init (cold_boot, generic_plat_match); }
@@ -155,7 +158,7 @@ static int generic_final_init(bool cold_boot)int rc;if (cold_boot) -fdt_reset_init (); +fdt_reset_init (false);if (generic_plat && generic_plat->final_init) { rc = generic_plat->final_init (cold_boot, generic_plat_match);
platform/generic/sifive/fu740.c +1 -1
@@ -233,7 +233,7 @@ static int sifive_fu740_final_init(bool cold_boot,void *fdt =fdt_get_address ();if (cold_boot) { - rc =fdt_reset_driver_init (fdt, &fdt_reset_da9063); + rc =fdt_reset_driver_init (fdt, &fdt_reset_da9063, false);if (rc)sbi_printf ("%s: failed to find da9063 for reset\n" , __func__);
platform/generic/starfive/jh7110.c +1 -1
@@ -277,7 +277,7 @@ static int starfive_jh7110_final_init(bool cold_boot,void *fdt =fdt_get_address ();if (cold_boot) { -fdt_reset_driver_init (fdt, &fdt_reset_pmic); +fdt_reset_driver_init (fdt, &fdt_reset_pmic, false);return starfive_jh7110_inst_init (fdt); }
Signature · 1 line
2.36.1
PATCH 1/1 lib: reset: Add early_init api for fdt_reset_drv
Quoted 147 lines · On Sat, Jun 17, 2023 at 10:57?AM <[email protected]> wrote:
From: Guo Ren <[email protected]>
The
fdt_reset_theaddriver needs to modify the__reset_thead_csr_stubtext region for the secondary harts booting. After that, thesbi_hart_pmp_configuremay lock down the text region withM_READABLE&M_EXECUTABLEattributes in the future. Currently, theM_READABLE&M_EXECUtABLEhave no effect on m-mode, the L-bit in pmpcfg csr is useless for the current opensbi scenario. See:Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
When the L bit is clear, any M-mode access matching the PMP entry will succeed; the R/W/X permissions apply only to S and U modes.That's why current
fdt_reset_theadcould still work well after commit:230278dcf127("lib: sbi: Add separate entries for firmware RX and RW regions"). So this patch fixes up a fake bug for the M-mode permission setting of the future.Fixes 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW regions")Reported-by Jessica Clarke <[email protected]>Signed-off-by Guo Ren <[email protected]>Signed-off-by Guo Ren <[email protected]>--- include/sbi_utils/reset/fdt_reset.h | 9 +++++---- lib/utils/reset/fdt_reset.c | 20 +++++++++++++------- lib/utils/reset/fdt_reset_thead.c | 2 +- platform/generic/platform.c | 5 ++++- platform/generic/sifive/fu740.c | 2 +- platform/generic/starfive/jh7110.c | 2 +- 6 files changed, 25 insertions(+), 15 deletions(-)include/sbi_utils/reset/fdt_reset.h +5
-4@@ -15,6 +15,7 @@struct fdt_reset {const struct fdt_match *match_table;int (*init)(void *fdt,int nodeoff,const struct fdt_match *match); +int (*early_init)(void *fdt,int nodeoff,const struct fdt_match *match); };#ifdef CONFIG_FDT_RESET @@ -22,22 +23,22 @@ struct fdt_reset {/** * fdt_reset_driver_init() - initialize reset driver based on the device-tree */ -int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv); +int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv,bool early);/** * fdt_reset_init() - initialize reset drivers based on the device-tree * * This function shall be invoked in final init. */ -void fdt_reset_init (void ); +void fdt_reset_init (bool early);#else -static inline int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv) +static inline int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv,bool early) {return 0 ; } -static inline void fdt_reset_init (void ) { } +static inline void fdt_reset_init (bool early) { }#endif lib/utils/reset/fdt_reset.c +13
-7@@ -17,31 +17,37 @@extern struct fdt_reset *fdt_reset_drivers[];extern unsigned long fdt_reset_drivers_size; -int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv) +int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv,bool early) {int noff, rc =SBI_ENODEV ;const struct fdt_match *match; +int (*init)(void *fdt,int nodeoff,const struct fdt_match *match); noff =fdt_find_match (fdt,-1 , drv->match_table, &match);if (noff <0 )return SBI_ENODEV ; -if (drv->init) { - rc = drv->init (fdt, noff, match); +if (early) + init = drv->early_init; +else + init = drv->init; + +if (init) { + rc =init (fdt, noff, match);if (rc && rc !=SBI_ENODEV ) { -sbi_printf ("%s: %s init failed, %d\n" , - __func__, match->compatible, rc); +sbi_printf ("%s: %s %s-init failed, %d\n" , + __func__, match->compatible, early?"early" :"final" , rc); } }return rc; } -void fdt_reset_init (void ) +void fdt_reset_init (bool early) {int pos;void *fdt =fdt_get_address ();for (pos =0 ; pos < fdt_reset_drivers_size; pos++) -fdt_reset_driver_init (fdt, fdt_reset_drivers[pos]); +fdt_reset_driver_init (fdt, fdt_reset_drivers[pos], early); }lib/utils/reset/fdt_reset_thead.c +1
-1@@ -130,5 +130,5 @@ static const struct fdt_match thead_reset_match[] = {struct fdt_reset fdt_reset_thead = { .match_table = thead_reset_match, - .init = thead_reset_init + .early_init = thead_reset_init };platform/generic/platform.c +3
-0@@ -146,6 +146,9 @@ static int generic_early_init(bool cold_boot)if (!generic_plat || !generic_plat->early_init)return 0 ; +if (cold_boot) +fdt_reset_init (true); +return generic_plat->early_init (cold_boot, generic_plat_match); }
platform/generic/platform.c static int generic_final_init(bool cold_boot) · line 161
Quoted 5 lines
platform/generic/platform.c +1
-1@@ -155,7 +158,7 @@ static int generic_final_init(bool cold_boot)int rc;if (cold_boot) -fdt_reset_init (); +fdt_reset_init (false);
We don't need this "early" flag business in fdt_reset_init().
Just move the fdt_reset_init() call to generic_early_init() before "if (!generic_plat || !generic_plat->early_init)".
Regards,
Anup
Quoted 37 lines
platform/generic/platform.c +0
-0if (generic_plat && generic_plat->final_init) { rc = generic_plat->final_init (cold_boot, generic_plat_match);platform/generic/sifive/fu740.c +1
-1@@ -233,7 +233,7 @@ static int sifive_fu740_final_init(bool cold_boot,void *fdt =fdt_get_address ();if (cold_boot) { - rc =fdt_reset_driver_init (fdt, &fdt_reset_da9063); + rc =fdt_reset_driver_init (fdt, &fdt_reset_da9063, false);if (rc)sbi_printf ("%s: failed to find da9063 for reset\n" , __func__);platform/generic/starfive/jh7110.c +1
-2@@ -277,7 +277,7 @@ static int starfive_jh7110_final_init(bool cold_boot,void *fdt =fdt_get_address ();if (cold_boot) { -fdt_reset_driver_init (fdt, &fdt_reset_pmic); +fdt_reset_driver_init (fdt, &fdt_reset_pmic, false);return starfive_jh7110_inst_init (fdt); } --2.36.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
PATCH 1/1 lib: reset: Add early_init api for fdt_reset_drv
Quoted 151 lines · On Sat, Jun 17, 2023 at 2:43?AM Anup Patel <[email protected]> wrote:
Quoted 149 lines · On Sat, Jun 17, 2023 at 10:57?AM <[email protected]> wrote:
From: Guo Ren <[email protected]>
The
fdt_reset_theaddriver needs to modify the__reset_thead_csr_stubtext region for the secondary harts booting. After that, thesbi_hart_pmp_configuremay lock down the text region withM_READABLE&M_EXECUTABLEattributes in the future. Currently, theM_READABLE&M_EXECUtABLEhave no effect on m-mode, the L-bit in pmpcfg csr is useless for the current opensbi scenario. See:Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
When the L bit is clear, any M-mode access matching the PMP entry will succeed; the R/W/X permissions apply only to S and U modes.That's why current
fdt_reset_theadcould still work well after commit:230278dcf127("lib: sbi: Add separate entries for firmware RX and RW regions"). So this patch fixes up a fake bug for the M-mode permission setting of the future.Fixes 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW regions")Reported-by Jessica Clarke <[email protected]>Signed-off-by Guo Ren <[email protected]>Signed-off-by Guo Ren <[email protected]>--- include/sbi_utils/reset/fdt_reset.h | 9 +++++---- lib/utils/reset/fdt_reset.c | 20 +++++++++++++------- lib/utils/reset/fdt_reset_thead.c | 2 +- platform/generic/platform.c | 5 ++++- platform/generic/sifive/fu740.c | 2 +- platform/generic/starfive/jh7110.c | 2 +- 6 files changed, 25 insertions(+), 15 deletions(-)include/sbi_utils/reset/fdt_reset.h +5
-4@@ -15,6 +15,7 @@struct fdt_reset {const struct fdt_match *match_table;int (*init)(void *fdt,int nodeoff,const struct fdt_match *match); +int (*early_init)(void *fdt,int nodeoff,const struct fdt_match *match); };#ifdef CONFIG_FDT_RESET @@ -22,22 +23,22 @@ struct fdt_reset {/** * fdt_reset_driver_init() - initialize reset driver based on the device-tree */ -int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv); +int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv,bool early);/** * fdt_reset_init() - initialize reset drivers based on the device-tree * * This function shall be invoked in final init. */ -void fdt_reset_init (void ); +void fdt_reset_init (bool early);#else -static inline int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv) +static inline int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv,bool early) {return 0 ; } -static inline void fdt_reset_init (void ) { } +static inline void fdt_reset_init (bool early) { }#endif lib/utils/reset/fdt_reset.c +13
-7@@ -17,31 +17,37 @@extern struct fdt_reset *fdt_reset_drivers[];extern unsigned long fdt_reset_drivers_size; -int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv) +int fdt_reset_driver_init (void *fdt,struct fdt_reset *drv,bool early) {int noff, rc =SBI_ENODEV ;const struct fdt_match *match; +int (*init)(void *fdt,int nodeoff,const struct fdt_match *match); noff =fdt_find_match (fdt,-1 , drv->match_table, &match);if (noff <0 )return SBI_ENODEV ; -if (drv->init) { - rc = drv->init (fdt, noff, match); +if (early) + init = drv->early_init; +else + init = drv->init; + +if (init) { + rc =init (fdt, noff, match);if (rc && rc !=SBI_ENODEV ) { -sbi_printf ("%s: %s init failed, %d\n" , - __func__, match->compatible, rc); +sbi_printf ("%s: %s %s-init failed, %d\n" , + __func__, match->compatible, early?"early" :"final" , rc); } }return rc; } -void fdt_reset_init (void ) +void fdt_reset_init (bool early) {int pos;void *fdt =fdt_get_address ();for (pos =0 ; pos < fdt_reset_drivers_size; pos++) -fdt_reset_driver_init (fdt, fdt_reset_drivers[pos]); +fdt_reset_driver_init (fdt, fdt_reset_drivers[pos], early); }lib/utils/reset/fdt_reset_thead.c +1
-1@@ -130,5 +130,5 @@ static const struct fdt_match thead_reset_match[] = {struct fdt_reset fdt_reset_thead = { .match_table = thead_reset_match, - .init = thead_reset_init + .early_init = thead_reset_init };platform/generic/platform.c +3
-0@@ -146,6 +146,9 @@ static int generic_early_init(bool cold_boot)if (!generic_plat || !generic_plat->early_init)return 0 ; +if (cold_boot) +fdt_reset_init (true); +return generic_plat->early_init (cold_boot, generic_plat_match); }@@ -155,7 +158,7 @@ static int generic_final_init(bool cold_boot)int rc;
Quoted 8 lines
platform/generic/platform.c static int generic_final_init(bool cold_boot) · line 161
Quoted 3 lines
platform/generic/platform.c +1
-1if (cold_boot) -fdt_reset_init (); +fdt_reset_init (false);We don't need this "early" flag business in
fdt_reset_init().Just move the
fdt_reset_init()call togeneric_early_init()before "if (!generic_plat || !generic_plat->early_init)".
I agree and that would be more direct.
Quoted 41 lines
Regards,
AnupQuoted 37 lines
platform/generic/platform.c +0
-0if (generic_plat && generic_plat->final_init) { rc = generic_plat->final_init (cold_boot, generic_plat_match);platform/generic/sifive/fu740.c +1
-1@@ -233,7 +233,7 @@ static int sifive_fu740_final_init(bool cold_boot,void *fdt =fdt_get_address ();if (cold_boot) { - rc =fdt_reset_driver_init (fdt, &fdt_reset_da9063); + rc =fdt_reset_driver_init (fdt, &fdt_reset_da9063, false);if (rc)sbi_printf ("%s: failed to find da9063 for reset\n" , __func__);platform/generic/starfive/jh7110.c +1
-2@@ -277,7 +277,7 @@ static int starfive_jh7110_final_init(bool cold_boot,void *fdt =fdt_get_address ();if (cold_boot) { -fdt_reset_driver_init (fdt, &fdt_reset_pmic); +fdt_reset_driver_init (fdt, &fdt_reset_pmic, false);return starfive_jh7110_inst_init (fdt); } --2.36.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
Signature · 2 lines
Best Regards Guo Ren