Skip to content
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

the coprocessor save area in function pxPortInitialiseStack would not be same address in function vPortStoreTaskMPUSettings #2

Open
frog7259 opened this issue Jul 1, 2019 · 0 comments
Labels
bug Something isn't working

Comments

@frog7259
Copy link

frog7259 commented Jul 1, 2019

Describe the bug
1.
In function pxPortInitialiseStack(StackType_t *pxTopOfStack....)
p = (uint32_t *)(((uint32_t) pxTopOfStack - XT_CP_SIZE) & ~0xf);

In function prvInitialiseNewTask (file: task.c)
pxTopOfStack =( pxStack + (ulStackDepth - 1) ) &( ~portBYTE_ALIGNMENT_MASK)

so we know co-processor stack is at
p = (uint32_t *)(((uint32_t) (( pxStack + (ulStackDepth - 1) ) &( ~portBYTE_ALIGNMENT_MASK))- XT_CP_SIZE) & ~0xf);

In function vPortStoreTaskMPUSettings( .... , StackType_t pxBottomOfStack ...)
xMPUSettings->coproc_area = (StackType_t
)((((uint32_t)(pxBottomOfStack + usStackDepth - 1)) - XT_CP_SIZE ) & ~0xf);

pxBottomOfStack = pxStack

=> xMPUSettings->coproc_area = (StackType_t*)((((uint32_t)(pxStack+ ulStackDepth - 1)) - XT_CP_SIZE ) & ~0xf);

combine 1 & 2, p should equal to coproc_area.
when portBYTE_ALIGNMENT_MASK set 128 bytes.

(uint32_t )(((uint32_t) (( pxStack + (ulStackDepth - 1) ) &( ~portBYTE_ALIGNMENT_MASK))- XT_CP_SIZE) & ~0xf)
not equal to
(StackType_t
)((((uint32_t)(pxStack+ usStackDepth - 1)) - XT_CP_SIZE ) & ~0xf);

And it would cause co-processor context switch error, because the stack save area is not correct

btw, because the cache line is 128 alignment, so we need to set the portBYTE_ALIGNMENT_MASK = 0x007F

System information

  • Which hardware board or part numbers? Hifi3
  • IDE used : RI-2018.0-linux
  • Operating System : Linux
  • Version of Amazon FreeRTOS (run git describe --tags to find it) : V10.0.1
  • Project [Custom Application]
  • If your project is a Custom Application, please add the relevant code snippet in the section Code to reproduce the bug.
    (file: portable.h)
    #if portBYTE_ALIGNMENT == 128
    #define portBYTE_ALIGNMENT_MASK ( 0x007FU )
    #endif

Expected behavior
co-processor context switch is normal, not trigger exception

Screenshots or console output
no

To reproduce
Steps to reproduce the behavior:

  1. ...
  2. ...

Code to reproduce the bug

If the code is longer than 30 lines, GIST is preferred.

Additional context
Add any other context about the problem here.

Thank you!

@frog7259 frog7259 added the bug Something isn't working label Jul 1, 2019
magicse7en added a commit to magicse7en/FreeRTOS-Kernel that referenced this issue Aug 12, 2020
foss-xtensa/amazon-freertos#2 mentioned a issue:
1.
In function pxPortInitialiseStack(StackType_t *pxTopOfStack....)
p = (uint32_t *)(((uint32_t) pxTopOfStack - XT_CP_SIZE) & ~0xf);

In function prvInitialiseNewTask (file: task.c)
pxTopOfStack = (pxStack + (ulStackDepth - 1)) & (~portBYTE_ALIGNMENT_MASK)

So the co-processor area is at
p = (uint32_t *)(((uint32_t)((pxStack + (ulStackDepth - 1)) & (~portBYTE_ALIGNMENT_MASK)) - XT_CP_SIZE) & ~0xf);

2.
In function vPortStoreTaskMPUSettings( .... , StackType_t pxBottomOfStack ...)
xMPUSettings->coproc_area = (StackType_t)((((uint32_t)(pxBottomOfStack + usStackDepth - 1)) - XT_CP_SIZE) & ~0xf);

pxBottomOfStack = pxStack

=> xMPUSettings->coproc_area = (StackType_t*)((((uint32_t)(pxStack+ ulStackDepth - 1)) - XT_CP_SIZE ) & ~0xf);

The p is coproc_area that should be equal to xMPUSettings->coproc_area.

For example, assume pxStack is 0xa0000000, ulStackDepth is 0x2000,
portBYTE_ALIGNMENT_MASK is 0x7f, XT_CP_SIZE is 0x100.

The p = (uint32_t)(((uint32_t)((pxStack + (ulStackDepth - 1)) & (~portBYTE_ALIGNMENT_MASK)) - XT_CP_SIZE) & ~0xf)
      = 0xa0001e80
The xMPUSettings->coproc_area = (StackType_t)((((uint32_t)(pxStack+ usStackDepth - 1)) - XT_CP_SIZE ) & ~0xf)
                              = 0xa0001ef0
Obviously, the p is not equal to the xMPUSettings->coproc_area, which will cause context switching error.

Signed-off-by: magicse7en <[email protected]>
lundinc2 added a commit to FreeRTOS/FreeRTOS-Kernel that referenced this issue Oct 26, 2020
* Xtensa: fix the coproc_area incorrect issue

foss-xtensa/amazon-freertos#2 mentioned a issue:
1.
In function pxPortInitialiseStack(StackType_t *pxTopOfStack....)
p = (uint32_t *)(((uint32_t) pxTopOfStack - XT_CP_SIZE) & ~0xf);

In function prvInitialiseNewTask (file: task.c)
pxTopOfStack = (pxStack + (ulStackDepth - 1)) & (~portBYTE_ALIGNMENT_MASK)

So the co-processor area is at
p = (uint32_t *)(((uint32_t)((pxStack + (ulStackDepth - 1)) & (~portBYTE_ALIGNMENT_MASK)) - XT_CP_SIZE) & ~0xf);

2.
In function vPortStoreTaskMPUSettings( .... , StackType_t pxBottomOfStack ...)
xMPUSettings->coproc_area = (StackType_t)((((uint32_t)(pxBottomOfStack + usStackDepth - 1)) - XT_CP_SIZE) & ~0xf);

pxBottomOfStack = pxStack

=> xMPUSettings->coproc_area = (StackType_t*)((((uint32_t)(pxStack+ ulStackDepth - 1)) - XT_CP_SIZE ) & ~0xf);

The p is coproc_area that should be equal to xMPUSettings->coproc_area.

For example, assume pxStack is 0xa0000000, ulStackDepth is 0x2000,
portBYTE_ALIGNMENT_MASK is 0x7f, XT_CP_SIZE is 0x100.

The p = (uint32_t)(((uint32_t)((pxStack + (ulStackDepth - 1)) & (~portBYTE_ALIGNMENT_MASK)) - XT_CP_SIZE) & ~0xf)
      = 0xa0001e80
The xMPUSettings->coproc_area = (StackType_t)((((uint32_t)(pxStack+ usStackDepth - 1)) - XT_CP_SIZE ) & ~0xf)
                              = 0xa0001ef0
Obviously, the p is not equal to the xMPUSettings->coproc_area, which will cause context switching error.

Signed-off-by: magicse7en <[email protected]>

* Update port.c

Co-authored-by: Carl Lundin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant