-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
psci reset with wdog #1849
psci reset with wdog #1849
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, I have not been through all of it. Yet here's some feedback.
core/include/kernel/dt.h
Outdated
@@ -89,6 +89,16 @@ const struct dt_driver *__dt_driver_end(void); | |||
int dt_map_dev(const void *fdt, int offs, vaddr_t *base, size_t *size); | |||
|
|||
/* | |||
* Check whether the node at @offs contains the proerty with propname or not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/proerty/property/
core/include/kernel/dt.h
Outdated
* @offs is the offset of the node that describes the device in @fdt. | ||
* @propname is the property that need to check | ||
* | ||
* Returs true on success or false if no propname. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Returs/Returns/
core/kernel/dt.c
Outdated
|
||
prop = fdt_getprop(fdt, offs, propname, NULL); | ||
|
||
return prop ? true : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: return prop;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to use true/false as return value, this is to check whether a property exist or not.
core/kernel/dt.c
Outdated
@@ -144,14 +144,17 @@ static paddr_t _fdt_read_paddr(const uint32_t *cell, int n) | |||
paddr_t _fdt_reg_base_address(const void *fdt, int offs) | |||
{ | |||
const void *reg; | |||
int ncells; | |||
int len; | |||
int parent, ncells, len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: split over 3 lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
core/arch/arm/kernel/generic_boot.c
Outdated
@@ -684,6 +696,8 @@ static void init_fdt(unsigned long phys_fdt) | |||
void *fdt; | |||
int ret; | |||
|
|||
dt_blob_addr = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dt_blob_addr is not a static variable. So init it with value NULL in init_fdt first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. Will fix it.
core/arch/arm/mm/core_mmu.c
Outdated
@@ -51,7 +51,7 @@ | |||
|
|||
#include "core_mmu_private.h" | |||
|
|||
#define MAX_MMAP_REGIONS 13 | |||
#define MAX_MMAP_REGIONS CFG_MMAP_REGIONS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the platform_config.h could set MAX_MMAP_REGIONS
and change here:
+#ifndef MAX_MMAP_REGIONS
#define MAX_MMAP_REGIONS 13
+#endif
Main point is that this config information does not really need to be CFG_xxx
format which are mainly used for config settings required in makefile scripts and eventually also source files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, fix in next version
core/drivers/imx_wdog.c
Outdated
write16(val, wdog_base + WCR_OFF); | ||
write16(val, wdog_base + WCR_OFF); | ||
|
||
asm volatile ("b .\r\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while(1)
;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
core/arch/arm/plat-imx/conf.mk
Outdated
@@ -82,4 +82,6 @@ ifeq ($(filter y, $(CFG_PSCI_ARM32)), y) | |||
CFG_HWSUPP_MEM_PERM_WXN = n | |||
endif | |||
|
|||
CFG_MMAP_REGIONS ?= 24 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comment on MAX_MMAP_REGIONS
.
core/include/kernel/dt.h
Outdated
* | ||
* Returs true on success or false if no propname. | ||
*/ | ||
bool dt_read_bool(const void *fdt, int offs, const char *propname); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer dt_have_prop()
or dt_prop_exists()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix in next version
@@ -726,6 +740,8 @@ static void init_fdt(unsigned long phys_fdt) | |||
phys_fdt, ret); | |||
panic(); | |||
} | |||
|
|||
dt_blob_addr = fdt; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pointer isn't valid forever. It should be cleared when OP-TEE has initialized and exits the first time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to parse the dtb to get fsl,ext-reset-output in wdog node. In this patchset, I use driver_init(xxx_wdog_xx) to handle that. If not expose dtb here, I am not able to parse dtb for the drivers. Could we expose fdt in init_fdt, and destroy the pointer when first back to normal world? Or we create a copy of the dtb in optee secure side?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you clear it before init_primary_helper()
(after calling init_teecore()
) returns it should be OK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I'll clear it as you suggested.
core/drivers/imx_wdog.c
Outdated
uint32_t i; | ||
|
||
#ifdef CFG_MX7 | ||
const char *wdog_path[4] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could have used []
instead of [4]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix in next version
Updated: |
core/arch/arm/kernel/generic_boot.c
Outdated
@@ -90,6 +90,11 @@ uint32_t sem_cpu_sync[CFG_TEE_CORE_NB_CORE]; | |||
KEEP_PAGER(sem_cpu_sync); | |||
#endif | |||
|
|||
#ifdef CFG_DT | |||
void *dt_blob_addr; | |||
KEEP_PAGER(dt_blob_addr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't needed, all non-const global variable are unpaged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. Will remove it.
@@ -61,4 +61,7 @@ int generic_boot_core_release(size_t core_idx, paddr_t entry); | |||
paddr_t generic_boot_core_hpen(void); | |||
#endif | |||
|
|||
extern void *dt_blob_addr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be just a static variable instead as there's a get function for it.
core/arch/arm/kernel/generic_boot.c
Outdated
if (cpu_mmu_enabled()) | ||
return dt_blob_addr; | ||
|
||
return (void *)virt_to_phys(dt_blob_addr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the limited time where dt_blob_addr
is valid we can guarantee that MMU is always enabled while the variable is valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. Then let the function directly return dt_blob_addr
is ok here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add assert(cpu_mmu_enabled());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. Will add it.
core/arch/arm/plat-imx/conf.mk
Outdated
endif | ||
|
||
MAX_MMAP_REGIONS ?= 24 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable should have a CFG_
prefix, also the config magic is only applied to CFG_
variables if I'm not misstaken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per @etienne-lms 's comments:
I think the platform_config.h could set MAX_MMAP_REGIONS and change here:
+#ifndef MAX_MMAP_REGIONS
#define MAX_MMAP_REGIONS 13
+#endif
Main point is that this config information does not really need to be CFG_xxx format which are mainly used for config settings required in makefile scripts and eventually also source files.
I changed to use MAX_MMAP_REGIONS.
So @jenswi-linaro @jforissier, you agree to use the following, add platform could define CFG_MMAP_REGIONS?
#ifndef CFG_MMAP_REGIONS
#define CFG_MMAP_REGIONS 13
#endif
#define MAX_MMAP_REGIONS CFG_MMAP_REGIONS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First thing: generally speaking, #ifndef CFG_X / #define CFG_X / #endif
is not good. CFG_x ?= some_value
in some .mk
file should always be preferred.
Second thing: whether or not the variable should be a CFG_
is easy to decide. If it makes sense to choose the value a compile time, use CFG_. Otherwise, hard-code the value in a .h and do NOT use #ifndef.
Third thing: I don't understand why you would need two variables (MAX_MMAP_REGIONS and CFG_MMAP_REGIONS).
It seems to me CFG_MMAP_REGIONS ?= some_value
is all we need. It may be set globally in core/config.mk
and a platform-specific value may be given in core/arch/arm/plat-imx/conf.mk
. A compile-time assert may be in order to make sure the value is acceptable in the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jforissier . Replacing MAX_MMAP_REGIONS with CFG_MMAP_REGIONS is simpler. How about the following patch?
diff --git a/core/arch/arm/arm.mk b/core/arch/arm/arm.mk
index bb65f77..6e52deb 100644
--- a/core/arch/arm/arm.mk
+++ b/core/arch/arm/arm.mk
@@ -4,6 +4,8 @@ CFG_LTC_OPTEE_THREAD ?= y
CFG_CORE_TZSRAM_EMUL_SIZE ?= 458752
CFG_LPAE_ADDR_SPACE_SIZE ?= (1ull << 32)
+CFG_MMAP_REGIONS ?= 13
+
ifeq ($(CFG_ARM64_core),y)
CFG_KERN_LINKER_FORMAT ?= elf64-littleaarch64
CFG_KERN_LINKER_ARCH ?= aarch64
diff --git a/core/arch/arm/mm/core_mmu.c b/core/arch/arm/mm/core_mmu.c
index f2d728d..7c5fb3d 100644
--- a/core/arch/arm/mm/core_mmu.c
+++ b/core/arch/arm/mm/core_mmu.c
@@ -51,7 +51,6 @@
#include "core_mmu_private.h"
-#define MAX_MMAP_REGIONS 13
#define RES_VASPACE_SIZE (CORE_MMU_PGDIR_SIZE * 10)
#define SHM_VASPACE_SIZE (1024 * 1024 * 32)
@@ -66,7 +65,7 @@ unsigned long default_nsec_shm_size;
unsigned long default_nsec_shm_paddr;
static struct tee_mmap_region
- static_memory_map[MAX_MMAP_REGIONS + 1];
+ static_memory_map[CFG_MMAP_REGIONS + 1];
/* Define the platform's memory layout. */
struct memaccess_area {
@@ -911,6 +910,7 @@ void core_init_mmu_map(void)
panic("Invalid memory access config: sec/nsec");
}
+ COMPILE_TIME_ASSERT(CFG_MMAP_REGIONS < 13);
init_mem_map(static_memory_map, ARRAY_SIZE(static_memory_map));
map = static_memory_map;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MrVan looks good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think MAX_MMAP_REGION
does not need to reach make script.
This value allocated static memory so it's a good thing to have it tunable. But the amount of memory is quite low. Maybe we would need a debug trace trace to get the number of entry used against max defined value.
In this scope, we should rather look at MAX_XLAT_TABLES
which cover bigger areas.
Minor comment: why restrict to 13. If no valid value, will panic. Ok 13 to be a default value, but why the lowest supported ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@etienne-lms I have no idea about the default value 13, 13 is not large enough in my case. The patch I listed above is the easy way to fix the issue I met.
Covering bigger areas, do you mean XLAT_TABLE_ENTRIES
?
core/kernel/dt.c
Outdated
|
||
prop = fdt_getprop(fdt, offs, propname, NULL); | ||
|
||
return prop ? true : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need for the ternary operator here. Since dt_have_prop()
returns bool
the compiler is required to normalize the value to return either true
or false
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure, but let compiler to normalize a value to true or false maybe not good, different compilers may have different behaviors? gcc/llvm or else. I checked linux and freebsd code, they not use compiler to normalize the value. freebsd not use bool, see https://github.com/freebsd/freebsd/blob/master/sys/dev/ofw/openfirm.c#L371
Linux kernel
static inline bool of_property_read_bool(const struct device_node *np,
const char *propname)
{
struct property *prop = of_find_property(np, propname, NULL);
return prop ? true : false;
}
So, could we keep prop ? true : false
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
? true : false
is clearly useless here because the bool
type in optee_os/core
is always defined as _Bool
, which is C99 standard.
There are reaons why the links you provide have the normalization to true/false (or 0/1):
- The FreeBSD function returns
int
, which is not_Bool
, - The Linux function is part of
libfdt
, which makes no assumption on the actual type behindbool
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the C99 standard:
6.3.1.2 Boolean type
When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jforissier for the explaination. I'll fix it in next version.
core/drivers/imx_wdog.c
Outdated
if (!core_mmu_add_mapping(mtype, pbase, sz)) { | ||
EMSG("Failed to map %zu bytes at PA 0x%"PRIxPA, | ||
(size_t)sz, pbase); | ||
return TEE_ERROR_GENERIC; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: indentation
core/arch/arm/kernel/generic_boot.c
Outdated
if (cpu_mmu_enabled()) | ||
return dt_blob_addr; | ||
|
||
return (void *)virt_to_phys(dt_blob_addr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add assert(cpu_mmu_enabled());
core/arch/arm/kernel/generic_boot.c
Outdated
@@ -760,6 +777,9 @@ static void init_primary_helper(unsigned long pageable_part, | |||
init_vfp_nsec(); | |||
if (init_teecore() != TEE_SUCCESS) | |||
panic(); | |||
#ifdef CFG_DT | |||
dt_blob_addr = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposal to add comment /* dt no more reached, reset pointer to invalid */
. It is not obvious why this is cleared.
Even add a reset_dt_references();
to remove #ifdef CFG_xxx
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. I'll fix it.
core/arch/arm/plat-imx/conf.mk
Outdated
endif | ||
|
||
MAX_MMAP_REGIONS ?= 24 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think MAX_MMAP_REGION
does not need to reach make script.
This value allocated static memory so it's a good thing to have it tunable. But the amount of memory is quite low. Maybe we would need a debug trace trace to get the number of entry used against max defined value.
In this scope, we should rather look at MAX_XLAT_TABLES
which cover bigger areas.
Minor comment: why restrict to 13. If no valid value, will panic. Ok 13 to be a default value, but why the lowest supported ?
core/drivers/imx_wdog.c
Outdated
#include <io.h> | ||
#include <keep.h> | ||
#include <kernel/generic_boot.h> | ||
#include <kernel/dt.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: 2 sorting error.
core/drivers/imx_wdog.c
Outdated
paddr_t pbase; | ||
vaddr_t vbase; | ||
ssize_t sz; | ||
int off, st; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: split in 2 lines.
Updated: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With my comment addressed:
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
core/arch/arm/kernel/generic_boot.c
Outdated
@@ -90,6 +90,10 @@ uint32_t sem_cpu_sync[CFG_TEE_CORE_NB_CORE]; | |||
KEEP_PAGER(sem_cpu_sync); | |||
#endif | |||
|
|||
#ifdef CFG_DT | |||
void *dt_blob_addr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be static
Typo fix: inseart -> insert Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
1. According to ePAPR spec, status should be okay/disabled/fail/fail-sss. To Linux device tree, "okay" and "ok" are both used. Function is_okay also use "okay" and "ok". But "ok" is not defined in spec. Here only correct comments 2. size -> sz Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Introudce dt_have_prop Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
According to ePAPR spec. " The #address-cells and #size-cells properties may be used in any device node that has children in the device tree hierarchy and describes how child device nodes should be addressed. The #address-cells property defines the number of <u32> cells used to encode the address field in a child node’s reg property. The #size-cells property defines the number of <u32> cells used to encode the size field in a child node’s reg property. The #address-cells and #size-cells properties are not inherited from ancestors in the device tree. They shall be explicitly defined. An ePAPR-compliant boot program shall supply #address-cells and #size-cells on all nodes that have children. If missing, a client program should assume a default value of 2 for An ePAPR-compliant boot program shall supply #address-cells and #size-cells on all nodes that have children. " So need to use the parent's address-cells and size-cells property. Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Introduce get_dt_blob. This could allow drivers to use device tree. Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Introduce CFG_MMAP_REGIONS to replace MAX_MMAP_REGIONS to allow platform specific value. Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Introducing the wdog support is for psci reset usage. To i.MX6/7, when `reboot`, need wdog to trigger soc reset or send out signal to pmic through wdog pin to trigger pmic reset. In linux device tree, there is a "fsl,ext-reset-output" property, this driver is to check whether the wdog node contains the property or not, then decide how to trigger reset. We still rely on normal world to initialize wdog and configure pinmux when need to trigger pmic reset. Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Set CFG_MMAP_REGIONS to 24. Signed-off-by: Peng Fan <peng.fan@nxp.com>
Implement psci reset support. Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
R-b Tags applied with changing"void *dt_blob_addr;" -> "static void *dt_blob_addr". |
This is to support psci reset on i.MX. The wdog is shared between normal world and secure world. The secure world needs to parse the wdog node and check whether
fsl,ext-reset-output
exists or not, then decide to how to trigger wdog reset. imx_wdog_restart is exposed to imx psci reset.Introduced get_dt_blob, dt_read_bool,CFG_MMAP_REGIONS.
CFG_MMAP_REGIONS maybe not a good way here, but the easiest way to fix my issue. core_mmu_add_mapping may fail, because RES_VASPACE entry in static memmap maybe used by others, such as device tree.
A few typo fixes.