Compare commits

...

161 commits

Author SHA1 Message Date
yinshengkai
5d8cdeaea8 note: print without relying on format strings
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2024-10-25 19:04:02 +08:00
yinshengkai
57a385a994 gote: implement asynchronous printf formatting
Do not format immediately when calling sched_note_printf, but delay formatting until dump trace.
After turning on SYSTEM_NOTE, similar asynchronous syslog functions can be achieved.

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2024-10-25 19:04:02 +08:00
yinshengkai
c87454220d note: change sched_note_counter to a macro
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2024-10-25 19:04:02 +08:00
Neo Xu
7e6f83a2b8 boards/arm/stm32/stm32f429i-disco: use serial console by default
Make it easy to access for beginners, using the default serial as console.
Enable wdog sched note.

Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
xuxingliang
f3d6119282 sched/note: add wdog note for segger sysview
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-25 19:04:02 +08:00
xuxingliang
46b1c8605a sched/note: add note for wdog module
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-25 19:04:02 +08:00
Neo Xu
f81c8051a3 Documentation: add segger sysview heap trace example
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
xuxingliang
dceb26c7b2 drivers/segger: add heap data plot
Add heap current used to note.
Plot it in segger sysview data plot.

Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
Neo Xu
17efd01d13 drivers/segger: upgrade segger to v356
From V3.5.6 on, data plot is supported.

Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
xuxingliang
f61bfd5608 drivers/segger: add heap note support
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
xuxingliang
001de69be9 drivers/noteram: fix compile error
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
xuxingliang
7e89ff5d11 sched/note: add note when mm add new region
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
xuxingliang
c2bcc56546 sched/note: specify note event for heap instrumentation
1. Add NOTE_HEAP_ prefix for heap note event.
2. Use note type as heap instrumentation parameter.

Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
yinshengkai
cff121bc23 mm: fix memory statistics error
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
yinshengkai
2c0e2ac36b note: add memory tracing event support
Record all memory allocation and release, save to ram, used to analyze memory allocation rate and memory usage
Its absolute value is not trustworthy because the memory will be allocated in thread A and released in thread B

 netinit-5   [0]   0.105984392: tracing_mark_write: C|5|Heap Usage|96|free: heap: 0x606000000020 size:24, address: 0x603000000370
 netinit-5   [0]   0.105996874: tracing_mark_write: C|5|Heap Usage|24|free: heap: 0x606000000020 size:72, address: 0x6070000008e0
nsh_main-4   [0]   3.825169408: tracing_mark_write: C|4|Heap Usage|2177665|free: heap: 0x606000000020 size:424, address: 0x614000000840
nsh_main-4   [0]   3.825228525: tracing_mark_write: C|4|Heap Usage|14977|free: heap: 0x606000000020 size:2162688, address: 0x7f80a639f800
nsh_main-4   [0]   3.825298789: tracing_mark_write: C|4|Heap Usage|15189|malloc: heap: 0x606000000020 size:20, address: 0x6030000003a0

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
lijianjun
803489b546 add mm_uninitialize empty implementation for sim
Signed-off-by: lijianjun <lijianjun@xiaomi.com>
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
2024-10-25 19:04:02 +08:00
xuxingliang
17cbaadce8 task: use get_task_name where possible
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-25 19:04:02 +08:00
dulibo1
c0ce2083ad ramlog:flush should reset the tail of the reader
Signed-off-by: dulibo1 <dulibo1@xiaomi.com>
2024-10-25 19:04:02 +08:00
dulibo1
2f12e18297 noteram:read noteram may cause crash
noteram_get may cause _read = ni_bufsize cause assert crash

[ 1493.627200] [79] [ EMERG] [ap] _assert: Assertion failed : at file: note/noteram_driver.c:370 task: trace process: trace 0x446f238a
[ 1493.627400] [79] [ EMERG] [ap] backtrace:
[ 1493.627500] [79] [ EMERG] [ap] [79] [<0xf7933c9d>] _fini+0xae0720b9/0xb673e41b
[ 1493.628400] [79] [ EMERG] [ap] [79] [<0x498b1b0c>] host_backtrace+0x42/0x72
[ 1493.629300] [79] [ EMERG] [ap] [79] [<0x48bef3d1>] up_backtrace+0x127/0x2d2
[ 1493.630200] [79] [ EMERG] [ap] [79] [<0x48b86bed>] sched_backtrace+0x71/0x8a
[ 1493.631100] [79] [ EMERG] [ap] [79] [<0x44676273>] sched_dumpstack+0xed/0x486
[ 1493.631600] [79] [ EMERG] [ap] [79] [<0x445c61ff>] _assert+0x9f0/0xb38
[ 1493.632200] [79] [ EMERG] [ap] [79] [<0x4420dd07>] __assert+0x3f/0x4c
[ 1493.632800] [79] [ EMERG] [ap] [79] [<0x44151648>] noteram_get+0x1b0/0x5fe
[ 1493.633600] [79] [ EMERG] [ap] [79] [<0x44152370>] noteram_read+0x331/0x4f7
[ 1493.634200] [79] [ EMERG] [ap] [79] [<0x444c66f9>] file_read+0x38b/0x3c0
[ 1493.634700] [79] [ EMERG] [ap] [79] [<0x444c6840>] nx_read+0x112/0x170
[ 1493.635300] [79] [ EMERG] [ap] [79] [<0x444c68e5>] NXread+0x47/0xfa
[ 1493.635800] [79] [ EMERG] [ap] [79] [<0x446f2c70>] trace_dump+0x148/0x2f4
[ 1493.636400] [79] [ EMERG] [ap] [79] [<0x446f110b>] trace_cmd_dump+0x41b/0x4b9
[ 1493.636900] [79] [ EMERG] [ap] [79] [<0x446f2723>] trace_main+0x399/0x6e2
[ 1493.637500] [79] [ EMERG] [ap] [79] [<0x44217fc9>] nxtask_startup+0x69/0x7c
[ 1493.638000] [79] [ EMERG] [ap] [79] [<0x440f9b78>] nxtask_start+0x8a5/0x8b8

Signed-off-by: dulibo1 <dulibo1@xiaomi.com>
2024-10-25 19:04:02 +08:00
yinshengkai
1c8d0bfdc7 note: add ringbuffer aligned access handle
Fix ubsan warning that writes need to be aligned to memory boundaries when writing data

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2024-10-25 19:04:02 +08:00
dulibo1
ca989b5101 noteram:overflow may discard all the trace message
noteram_add may cause head = tail when remain == NOTE_ALIGN(notelen)
log:
nsh_main-14  [0]   2.132127493: tracing_mark_write: B|14|trace dump -c

nsh_main-14  [0]   2.143322780: tracing_mark_write: E|14|trace dump -c

nsh_main-14  [0]   2.513023895: tracing_mark_write: B|14|trace dump -c

nsh_main-14  [0]   2.524060048: tracing_mark_write: E|14|trace dump -c

nsh_main-14  [0]   2.897055341: tracing_mark_write: B|14|trace dump -c

ap> trace dump -c
nsh_main-14  [0]   3.270037241: tracing_mark_write: B|14|trace dump -c

ap> trace dump -c

Signed-off-by: dulibo1 <dulibo1@xiaomi.com>
2024-10-25 19:04:02 +08:00
hujun5
9dc3e4ee41 arm64: fix fvp smp faild to boot
reason:
we should give a busy wait addr

This commit fixes the regression from https://github.com/apache/nuttx/pull/13640

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-24 18:04:49 +08:00
hujun5
6e7d90e195 arm64: remove the operation of clearing interrupts during GIC initialization
To align with the implementation of ARMv7-A, remove the operation of clearing
interrupts during GIC initialization to avoid losing interrupts during asynchronous startup.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-24 18:04:49 +08:00
hujun5
956d77ba23 arm64:add busy wait flag
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-24 18:04:49 +08:00
hujun5
6dd26a3e68 arm64/smp: changing the startup of arm64 SMP from serial to parallel
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-24 18:04:49 +08:00
yangsong8
5ff98fb4e1 syslog: enable LF to CRLF config as default
This commit fixes the issue #14418

Signed-off-by: yangsong8 <yangsong8@xiaomi.com>
2024-10-21 15:06:31 +02:00
ligd
d39bcd4ad5 Doc: add maskable nested interrupt description
Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-18 23:54:11 +08:00
ligd
9a317472fd arm-m: support zero interrupt back to game
Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-18 23:54:11 +08:00
ligd
946b01d4a8 arm-M: set current regs for crash dump
Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-18 23:54:11 +08:00
ligd
8b8a2610ab armv6/7/8m: use pendsv to handle context switch
This PR support Nested interrupt in armv6/7/8m:

There are two types of nested interrupt model:

Zero latency nested interrupt
Interrupt           Priority            Note
Data abort          Highest
SVC                 0x50
High irq1           0x60             ISR can't access system API
irq_save()          0x70
High irq2           0x80             ISR can't access system API
normal irq3         0xB0
We have already support this mode before this PR

Nested interrupt which interrupt level lower than up_irq_save()
Interrupt           Priority            Note
Data abort          Highest
SVC                 0x70
irq_save()          0x80
High irq1           0x90              ISR can access system API
High irq2           0xA0              ISR can access system API
normal irq3         0xB0
Now, this PR can support this mode

Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-18 23:54:11 +08:00
ligd
064415a765 armv6m: add up_trigger_irq() support
Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-18 23:54:11 +08:00
ligd
aa4a428825 armv7/8m: unmask all the IRQ when thread start
NVIC_SYSH_PRIORITY_MIN not the basepri loweest prio
spec says:
basepri 0 - Disables masking by BASEPRI

Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-18 23:54:11 +08:00
hujun5
33e30239f1 sched: replace sync pause with async pause for nxtask_terminate
reason:
In the kernel, we are planning to remove all occurrences of up_cpu_pause as one of the steps to
simplify the implementation of critical sections. The goal is to enable spin_lock_irqsave to encapsulate critical sections,
thereby facilitating the replacement of critical sections(big lock) with smaller spin_lock_irqsave(small lock)

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-17 12:51:14 +02:00
zhangyuan29
cdb5a7c6d4 sched: Disable the scheduling when send SIGCHLD signal
Disable the scheduling to prevent other tasks from being
deleted after they are awakened

Signed-off-by: zhangyuan29 <zhangyuan29@xiaomi.com>
2024-10-17 12:51:14 +02:00
hujun5
b52ad53cc1 sched: replace sync pause with async pause for nxsched_suspend
reason:
In the kernel, we are planning to remove all occurrences of up_cpu_pause as one of the steps to
simplify the implementation of critical sections. The goal is to enable spin_lock_irqsave to encapsulate critical sections,
thereby facilitating the replacement of critical sections(big lock) with smaller spin_lock_irqsave(small lock)

Configuring NuttX and compile:
$ ./tools/configure.sh -l qemu-armv8a:nsh_smp
$ make
Running with qemu
$ qemu-system-aarch64 -cpu cortex-a53 -smp 4 -nographic
-machine virt,virtualization=on,gic-version=3
-net none -chardev stdio,id=con,mux=on -serial chardev:con
-mon chardev=con,mode=readline -kernel ./nuttx

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-17 12:51:14 +02:00
hujun5
28cfadb4b0 sched: replace sync pause with async pause for setpriority
reason:
In the kernel, we are planning to remove all occurrences of up_cpu_pause as one of the steps to
simplify the implementation of critical sections. The goal is to enable spin_lock_irqsave to encapsulate critical sections,
thereby facilitating the replacement of critical sections(big lock) with smaller spin_lock_irqsave(small lock)

Configuring NuttX and compile:
$ ./tools/configure.sh -l qemu-armv8a:nsh_smp
$ make
Running with qemu
$ qemu-system-aarch64 -cpu cortex-a53 -smp 4 -nographic
-machine virt,virtualization=on,gic-version=3
-net none -chardev stdio,id=con,mux=on -serial chardev:con
-mon chardev=con,mode=readline -kernel ./nuttx

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-17 12:51:14 +02:00
Alin Jerpelea
1b64c80d72 Revert "sim: fix context-switch when do wdog callback()"
This reverts commit a3568af105.
2024-10-17 12:51:14 +02:00
Filipe Cavalcanti
71d57aac25 tools/espressif: add esptool version check to Espressif build system 2024-10-16 18:41:02 +08:00
hujun5
cedcb1a674
sim: add NXSYMBOLS pthread_gettid_np pthread_self
reason:
enable sim:smp can boot

This commit fixes the regression from https://github.com/apache/nuttx/pull/12561

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-16 11:27:30 +02:00
Alin Jerpelea
9192916a4e Revert "tools: update esptool version reference"
This reverts commit a157436a57.
2024-10-16 15:45:41 +08:00
Filipe Cavalcanti
997162685c ci: add Python linter to check 2024-10-16 07:53:37 +08:00
Marco Casaroli
8ca0bb35af ci: use venv for check
To avoid the following CI error:

This environment is externally managed
--> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.

    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.

    See /usr/share/doc/python3.12/README.venv for more information.
2024-10-16 07:53:37 +08:00
xuxingliang
07c48eb7d0 tools: make isort and black formatters to work together
Config multi line output to mode 3, so isort and black can agree with
each other:
```
3 - Vertical Hanging Indent

from third_party import (
    lib1,
    lib2,
    lib3,
    lib4,
)
```

Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-16 00:57:57 +02:00
xuxingliang
cc711e0c99 tools: exit with error if py needs to format
Make CI fail if format not pass.

Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-16 00:57:57 +02:00
Xiang Xiao
002d89885e net: Remove IFF_DOWN flag to compatible with Linux/*BSD
turn off interface by checking IFF_UP flag isn't set:
https://github.com/apache/nuttx/issues/1838

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2024-10-15 22:40:22 +08:00
wangmingrong1
c5f816e16a libc/machine: Fix the error caused by tag kasan
Use address addition and subtraction, no longer as the return value of the address. Tags must be removed before calculation

Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
2024-10-12 11:54:04 +08:00
Filipe Cavalcanti
a157436a57 tools: update esptool version reference 2024-10-11 22:04:43 +08:00
SPRESENSE
801805d4a2 binfmt/libelf: Fix return code
Fix return code in case of error in loading constructor and destructor section.

Detected by Codesonar 54667871, 54667873
2024-10-11 17:23:03 +08:00
wangmingrong1
0b98e9e680 board_reset: flush cache before reset
Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
2024-10-11 01:30:51 +08:00
xuxingliang
8074812517 assert: dump all CPU registers and stack
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-11 01:30:51 +08:00
xuxingliang
e65b03edd2 assert: cleanup assert handler
1. extract dump from assert main flow
2. use OSINIT_PANIC for fatal error.
3. fix the method to judge kernel thread.

Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-11 01:30:51 +08:00
Xu Xingliang
9da6761453 assert: disable kasan in assert
Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
f51c5452b2 sched: replace sync pause with async pause for nxtask_restart
reason:
In the kernel, we are planning to remove all occurrences of up_cpu_pause as one of the steps to
simplify the implementation of critical sections. The goal is to enable spin_lock_irqsave to encapsulate critical sections,
thereby facilitating the replacement of critical sections(big lock) with smaller spin_lock_irqsave(small lock)

Configuring NuttX and compile:
$ ./tools/configure.sh -l qemu-armv8a:nsh_smp
$ make
Running with qemu
$ qemu-system-aarch64 -cpu cortex-a53 -smp 4 -nographic
-machine virt,virtualization=on,gic-version=3
-net none -chardev stdio,id=con,mux=on -serial chardev:con
-mon chardev=con,mode=readline -kernel ./nuttx

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
b1932c668d sim: fix sim smp boot regression
This commit fixes the regression from https://github.com/apache/nuttx/pull/13716

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
c35e25b7e5 arch: rename xxxx_pause.c to xxxx_smpcall.c
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
d54bc8a9f8 arch: remove up_cpu_pause up_cpu_resume up_cpu_paused up_cpu_pausereq
reason:
  To remove the "sync pause" and decouple the critical section from the dependency on enabling interrupts,
  after that we need to further implement "schedlock + spinlock".
changelist
  1 Modify the implementation of critical sections to no longer involve enabling interrupts or handling synchronous pause events.
  2 GIC_SMP_CPUCALL attach to pause handler to remove arch interface up_cpu_paused_restore up_cpu_paused_save
  3 Completely remove up_cpu_pause, up_cpu_resume, up_cpu_paused, and up_cpu_pausereq
  4 change up_cpu_pause_async to up_send_cpu_sgi

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
6392d5a6b3 xtensa: Replace the implementation of up_cpu_pause
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
fbed4ece2c x86_64: we should call x86_64_restorestate/x86_64_savestate
reason:
In x86_64, g_current_regs is still used for context switching.

This commit fixes the regression from https://github.com/apache/nuttx/pull/13616

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
p-szafonimateusz
f5a449487c arch/intel64: colorize IDLE stack for AP cores
colorize IDLE stack for AP cores in x86_64

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
4a796c39bb xtensa: add parameters to xtensa_pause_handler
reason:
nxsched_smp_call_handler need these parameters

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
xuxingliang
5e2d205e1b sched: handle sched lock in interrupt
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-11 01:30:51 +08:00
dulibo1
755bef6c56 sched_smp:adjust the unlock order
1.nxsem_post wake up  nxsched_smp_call;
2.stack smp_call_data_s may return;
3.nxsched_smp_call_handler access call_data->lock is not safety;
so adjust the unlock order

Signed-off-by: dulibo1 <dulibo1@xiaomi.com>
2024-10-11 01:30:51 +08:00
p-szafonimateusz
e0d9cc432c arch/intel64: fix IRQ conflict with GOLDFISH
Also move MSI IRQ definition to place where other IRQ definitions are.

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
4fd92edee7 sched: replace sync pause with async pause for nxsig_process
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
487fcb3bce signal: adjust the signal processing logic to remove the judgment
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
hujun5
8275a846b1 arch: move sigdeliver to common code
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-11 01:30:51 +08:00
buxiasen
ec58a6ab25 arch: cpu pause when sigaction only necessary if tcb running
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2024-10-11 01:30:51 +08:00
p-szafonimateusz
fad4232925 arch/x86_64/intel64/intel64_schedulesigaction.c: properly align signal handler stack for vector operations
signal handler stack must be properly aligned, otherwise vector instructions doesn't work in signal handler

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
2024-10-11 01:30:51 +08:00
p-szafonimateusz
a33528fa4a arch/x86_64/intel64/intel64_cpuidlestack.c: stack_alloc should point to stack base not stack top
stack_alloc should point to stack base not stack top

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
2024-10-11 01:30:51 +08:00
p-szafonimateusz
bbea8dcefe arch/x86_64/intel64/intel64_head.S: move initial RSP for AP cores below regs area
move initial RSP for AP cores below regs area.
otherwise IDLE thread for AP cores can be corrupted

XCP region now match regs allocation in up_initial_state()

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
2024-10-11 01:30:51 +08:00
Ville Juven
192dde1b58 arm64_task/pthread_start: Set sp_el0 upon starting user process
As the handling of sp_el0 was moved from the context switch routine
to exception entry/exit, we must set sp_el0 explicitly when the user
process is first started.
2024-10-11 01:30:51 +08:00
lipengfei28
7975c94d88 Kernel build: enter exception save sp_sl0,exit exception restroe sp_el0
Signed-off-by: lipengfei28 <lipengfei28@xiaomi.com>
2024-10-11 01:30:51 +08:00
ligd
669cd3aa2c arm64: simply the vectors
Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-11 01:30:51 +08:00
ligd
7cbcf82bed arm64: save FPU regs every time
Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-11 01:30:51 +08:00
qinwei1
d782f6c1ac arm64: add arm64_current_el to obtain current EL
Summary
  Add a macro to obtain current execute level

Signed-off-by: qinwei1 <qinwei1@xiaomi.com>
2024-10-11 01:30:51 +08:00
qinwei1
40d40015f4 arm64: refine the fatal handler
Summary
  The original implement for exception handler is very simple and
haven't framework for breakpoint/watchpoint routine or brk instruction.
  I refine the fatal handler and add framework for debug handler to
register or unregister. this is a prepare for watchpoint/breakpoint
implement

Signed-off-by: qinwei1 <qinwei1@xiaomi.com>
2024-10-11 01:30:51 +08:00
likun17
068c7176bb usensor.c:fix container_of member error.
Signed-off-by: likun17 <likun17@xiaomi.com>
2024-10-11 00:52:00 +08:00
guoshichao
bb8eb9398d armv7-m/irq: fix the greenhills compiler compile error
CXX:  libcxxmini/libxx_new.cxx "/home/guoshichao/work_profile/vela_os/vela_qemu_1/nuttx/include/arch/armv7-m/irq.h", line 594: error #3422:
          use of the "register" storage class specifier is not allowed
    register uint32_t sp;
    ^

"/home/guoshichao/work_profile/vela_os/vela_qemu_1/nuttx/include/arch/armv7-m/irq.h", line 594: error #3422:
          use of the "register" storage class specifier is not allowed
    register uint32_t sp;
    ^

"/home/guoshichao/work_profile/vela_os/vela_qemu_1/nuttx/include/arch/armv7-m/irq.h", line 594: error #3422:
          use of the "register" storage class specifier is not allowed
    register uint32_t sp;
    ^

make[1]: *** [Makefile:69: libxx_delete_sized.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make[1]: *** [Makefile:69: libxx_deletea_sized.o] Error 1
make[1]: *** [Makefile:69: libxx_new.o] Error 1
"/home/guoshichao/work_profile/vela_os/vela_qemu_1/nuttx/include/arch/armv7-m/irq.h", line 594: error #3422:
          use of the "register" storage class specifier is not allowed
    register uint32_t sp;
    ^

"/home/guoshichao/work_profile/vela_os/vela_qemu_1/nuttx/include/arch/armv7-m/irq.h", line 594: error #3422:
          use of the "register" storage class specifier is not allowed
    register uint32_t sp;
    ^

Signed-off-by: guoshichao <guoshichao@xiaomi.com>
2024-10-10 15:31:50 +02:00
hujun5
542e46319c xtensa: g_current_regs is only used to determine if we are in irq, with other functionalities removed.
reason:
by doing this we can reduce context switch time,
When we exit from an interrupt handler, we directly use tcb->xcp.regs

before
text    data     bss     dec     hex filename
178368     876  130604  309848   4ba58 nuttx
after
text    data     bss     dec     hex filename
178120     876  130212  309208   4b7d8 nuttx

szie change -248

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-10 15:31:50 +02:00
ligd
a9df7f0d1e xtesa: fix lost save & restore states caused by merge code
this is caused by:
35c8c80a00

Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-10 15:31:50 +02:00
ligd
1fb4f8f50e arch: change nxsched_suspend/resume_scheduler() called position
for the citimon stats:

thread 0:                     thread 1:
enter_critical (t0)
up_switch_context
note suspend thread0 (t1)

                              thread running
                              IRQ happen, in ISR:
                                post thread0
                                up_switch_context
                                note resume thread0 (t2)
                                ISR continue f1
                                ISR continue f2
                                ...
                                ISR continue fn

leave_critical (t3)

You will see, the thread 0, critical_section time is:
(t1 - t0) + (t3 - t2)

BUT, this result contains f1 f2 .. fn time spent, it is wrong
to tell user thead0 hold the critical lots of time but actually
not belong to it.

Resolve:
change the nxsched_suspend/resume_scheduler to real hanppends

Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-10 15:31:50 +02:00
hujun5
2f4c067c50 fix compile error:
Register: smp
Register: nsh
Register: sh
Register: getprime
Register: ostest
Espressif HAL for 3rd Party Platforms: b4c723a119344b4b71d69819019d55637fb570fd
common/xtensa_cpupause.c: In function 'xtensa_pause_handler':
common/xtensa_cpupause.c:240:3: warning: implicit declaration of function 'xtensa_savestate'; did you mean 'xtensa_setps'? [-Wimplicit-function-declaration]
  240 |   xtensa_savestate(tcb->xcp.regs);
      |   ^~~~~~~~~~~~~~~~
      |   xtensa_setps
common/xtensa_cpupause.c:243:3: warning: implicit declaration of function 'xtensa_restorestate'; did you mean 'xtensa_context_restore'? [-Wimplicit-function-declaration]
  243 |   xtensa_restorestate(tcb->xcp.regs);
      |   ^~~~~~~~~~~~~~~~~~~
      |   xtensa_context_restore

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-10 15:31:50 +02:00
Yongrong Wang
c48f158e66 arm_gicv2.c: fix armv7a compile error
/vela/nuttx/drivers/pci/pci_ecam.c:432:(.text.pci_ecam_get_irq+0x16): undefined reference to `up_get_legacy_irq'

Signed-off-by: Yongrong Wang <wangyongrong@xiaomi.com>
2024-10-10 15:31:08 +02:00
lipengfei28
7cf9b73f18 arm64 pci legacy irq do not support yet
Signed-off-by: lipengfei28 <lipengfei28@xiaomi.com>
2024-10-10 15:31:08 +02:00
lipengfei28
1cb81f9a8f armv7a pci irq support
Signed-off-by: lipengfei28 <lipengfei28@xiaomi.com>
2024-10-10 15:31:08 +02:00
Bowen Wang
3b1870028c include/pci.h: sync the subvendor/subdevice type in id table and pci_device_s
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
2024-10-10 15:31:08 +02:00
Bowen Wang
f2a4d59900 pci/pci_ecam: add read_io/write_io for pci ecam
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
2024-10-10 15:31:08 +02:00
Bowen Wang
fb97285a36 drivers/pci: one pci device should only associate with one driver
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
2024-10-10 15:31:08 +02:00
Bowen Wang
dbcef4f297 drivers/pci: change all devfn type to unsigned int
Now all the type of devfn in pci framework are unsigned int

Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
2024-10-10 15:31:08 +02:00
Yongrong Wang
fe1286b44a pci.c: fix compile warning
pci/pci.c:1128:15: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
 1128 |       pciinfo("Limit MME to %x, num to %d\n", mmc, num);
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  ~~~
      |                                               |
      |                                               uint32_t {aka long unsigned int}
pci/pci.c:1128:30: note: format string is defined here
 1128 |       pciinfo("Limit MME to %x, num to %d\n", mmc, num);
      |                             ~^
      |                              |
      |                              unsigned int
      |                             %lx

Signed-off-by: Yongrong Wang <wangyongrong@xiaomi.com>
2024-10-10 15:31:08 +02:00
p-szafonimateusz
87b940a611 drivers/pci_qemu_test.c: fix compiler warning
pci/pci_qemu_test.c:218:6: warning: ‘ops’ may be used uninitialized [-Wmaybe-uninitialized]
  218 |   ops->write(dev->bus, &hdr->test, num, sizeof(num));
      |   ~~~^~~~~~~
pci/pci_qemu_test.c: In function ‘pci_qemu_test_probe’:
pci/pci_qemu_test.c:286:41: note: ‘ops’ was declared here
  286 |   FAR const struct pci_qemu_test_ops_s *ops;
      |

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
2024-10-10 15:31:08 +02:00
yanghuatao
52473d7fa2 toolchain/ghs: Fix ?? "trigraphs not allowed" warnings
"/mnt/yang/qixinwei_vela_warnings_04_23/nuttx/include/nuttx/pci/pci_regs.h", line 263: warning #1695-D:
          trigraphs not allowed
  #define  PCI_PM_CTRL_DATA_SEL_MASK        0x1e00  /* Data select (??) */
                                                                    ^

"/mnt/yang/qixinwei_vela_warnings_04_23/nuttx/include/nuttx/pci/pci_regs.h", line 264: warning #1695-D:
          trigraphs not allowed
  #define  PCI_PM_CTRL_DATA_SCALE_MASK      0x6000  /* Data scale (??) */
                                                                   ^

"/mnt/yang/qixinwei_vela_warnings_04_23/nuttx/include/nuttx/pci/pci_regs.h", line 266: warning #1695-D:
          trigraphs not allowed
  #define PCI_PM_PPB_EXTENSIONS             6       /* PPB support extensions (??) */
                                                                               ^

"/mnt/yang/qixinwei_vela_warnings_04_23/nuttx/include/nuttx/pci/pci_regs.h", line 267: warning #1695-D:
          trigraphs not allowed
  #define  PCI_PM_PPB_B2_B3                 0x40    /* Stop clock when in D3hot (??) */
                                                                                 ^

"/mnt/yang/qixinwei_vela_warnings_04_23/nuttx/include/nuttx/pci/pci_regs.h", line 268: warning #1695-D:
          trigraphs not allowed
  #define  PCI_PM_BPCC_ENABLE               0x80    /* Bus power/clock control enable (??) */
                                                                                       ^

"/mnt/yang/qixinwei_vela_warnings_04_23/nuttx/include/nuttx/pci/pci_regs.h", line 269: warning #1695-D:
          trigraphs not allowed
  #define PCI_PM_DATA_REGISTER              7       /* (??) */

Signed-off-by: yanghuatao <yanghuatao@xiaomi.com>
2024-10-10 15:31:08 +02:00
wangyongrong
7f4f7f293d pci.c: fix pci 32bit warning
pci/pci.c:863:66: warning: right shift count >= width of type [-Wshift-count-overflow]
  863 |       pci_write_config_dword(dev, msi + PCI_MSI_ADDRESS_HI, (mar >> 32));

Signed-off-by: wangyongrong <wangyongrong@xiaomi.com>
2024-10-10 15:31:08 +02:00
Bowen Wang
e33bdd9e38 include/pci_regs: add PCI_STD_NUM_BARS macro
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
2024-10-10 15:31:08 +02:00
Bowen Wang
1407a44862 drivers/pci/pci.c: fix warning when CONFIG_PCI_ASSIGN_ALL_BUSES=n
pci/pci.c:415:34: warning: variable ‘res’ set but not used [-Wunused-but-set-variable]
  415 |       FAR struct pci_resource_s *res;
      |                                  ^~~
pci/pci.c: In function ‘pci_scan_bus’:
pci/pci.c:663:32: warning: unused variable ‘ctrl’ [-Wunused-variable]
  663 |   FAR struct pci_controller_s *ctrl = bus->ctrl;

Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
2024-10-10 15:31:08 +02:00
lipengfei28
519c5c86aa add pci irq interface
Signed-off-by: lipengfei28 <lipengfei28@xiaomi.com>
2024-10-10 15:31:08 +02:00
wangyongrong
1e091fb2e0 pci.c: add pci_read/write_io_qword support
Signed-off-by: wangyongrong <wangyongrong@xiaomi.com>
2024-10-10 15:31:08 +02:00
wangyongrong
db95659a9c x86_64_pci.c: x86_64_pci_read/write_io memory support
Signed-off-by: wangyongrong <wangyongrong@xiaomi.com>
2024-10-10 15:31:08 +02:00
Bowen Wang
271893ed6d rpmsgfs/rpmsgfs_client: init the priv->wait before register rpmsg callback
Should init the priv->wait before rpmsg_register_callback() because
rpmsgfs_ns_bound() may has been called before rpmsg_register_callback()
returned.

Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
2024-10-10 15:30:41 +02:00
fangzhenwei
439c52937a rpmsgfs: add tty fd ioctl(TCGETS/TCSETS) support
rpmsgfs client ioctl support TCDRN/TCFLSH/TCGETS/TCSETS

Signed-off-by: fangzhenwei <fangzhenwei@xiaomi.com>
2024-10-10 15:30:41 +02:00
Bowen Wang
536ed46ac4 rpmsgfs_server: add error log for rpmsgfs server ept callback
Because the rpmsg_virtio will assert when endpoint callback return
error, so add more error log to the rpmsgfs server to help to locate
the root cause.

Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
2024-10-10 15:30:41 +02:00
ligd
5613675834 rpmsgfs: remove memcpy in rpmsgfs open/close
improve the rpmsgfs performance

Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-10 15:30:41 +02:00
chenrun1
3f47fd767a fs/xxfs:Replace kmm with fs heap
Summary:
  1.Add configuration to allocate memory from the specified section
  2.Replace all memory operations (kmm_) in the vfs with
    fs_heap_. When FS_HEAPSIZE > 0, memory is requested for the file system by specifying a configured heap location. By default (i.e. FS_HEAPSIZE=0) fs_heap_ is equivalent to kmm_

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
2024-10-10 15:30:41 +02:00
chenrun1
94fe00ebec accept4:move function from net to fs
Summary:
  Implementation in accept4 is special, the requested newsock is saved as filep->priv. This will cause sock_file_close to use fs_heap_free filep->priv during close. When fs_heap is configured, the released memory will not be on fs_heap, causing a crash.

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
2024-10-10 15:30:41 +02:00
Michal Lenc
01bed328ef smartfs: add support for FIOC_FILEPATH ioctl
The FIOC_FILEPATH ioctl call is required if smartfs is to be used
together with inotify monitoring system. This implements the
call support to smartfs file system. The path to the file has to
be stored in smartfs_ofile_s structure during file open (and is freed
during close) as smartfs currently is not able to obtain the path
knowing only the file node. The full path is concatenated with the file
name and creates the full path needed for inotify to detect whether
the file is on the watchlist.

Signed-off-by: Michal Lenc <michallenc@seznam.cz>
2024-10-10 15:30:41 +02:00
chenrun1
0ac21a911b fs_rammap:Check last fileseek restore fpos
Summary:
  When restoring rammap fpos, we check the return value to avoid potential problems caused by no error return if the restore fails.

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
2024-10-10 15:30:41 +02:00
zhangshoukui
8155102f7d FS_RAMMAP depends on FS_REFCOUNT and remove useless macro
Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2024-10-10 15:30:41 +02:00
zhangshoukui
e6b703c29f Should call fs_putfilep put fs reference when call files_fget complete
Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2024-10-10 15:30:41 +02:00
yezhonghui
52ffca5b8e arm64 support gicv2m for pci irq
Signed-off-by: yezhonghui <yezhonghui@xiaomi.com>
2024-10-10 15:30:00 +02:00
zhaohaiyang1
45bb7a9c1c char driver CAN: add tx_confirm function in upperCAN driver.
add tx_confirm function in upperCAN driver1

Signed-off-by: zhaohaiyang1 <zhaohaiyang1@xiaomi.com>
2024-10-10 17:58:36 +08:00
zhaohaiyang1
63515d584b chardriver upperCAN: support to independent set TX/RX FIFO size.
support to independent set TX/RX FIFO size.

Signed-off-by: zhaohaiyang1 <zhaohaiyang1@xiaomi.com>
2024-10-10 17:58:36 +08:00
zhaohaiyang1
9b698b2304 add the ability that control CAN transceiver state.
add the ability that control CAN transceiver state in nuttx.

Signed-off-by: zhaohaiyang1 <zhaohaiyang1@xiaomi.com>
2024-10-10 17:58:36 +08:00
zhaohaiyang1
2bb4ec0fd2 nuttx/can: add can controller state setting and getting in uppercan.
add can controller state setting and getting in uppercan.

Signed-off-by: zhaohaiyang1 <zhaohaiyang1@xiaomi.com>
2024-10-10 17:58:36 +08:00
Xiang Xiao
ccddaa78c9 can: Add more critical section to fix the race condition.
since routines called by IRQ need to be protected in SMP too.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2024-10-10 17:58:36 +08:00
Xiang Xiao
4324970980 can: Merge cd_error and rx_overflow into rx_error so the error could dispath to each client without interference
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2024-10-10 17:58:36 +08:00
hujun5
f791311138 sched/sched: next pointer value is definitely not null
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-10 17:57:30 +08:00
hujun5
508c5889d7 sched: change nxsched_islocked_global to nxsched_islocked_tcb
reason:
1 To improve efficiency, we mimic Linux's behavior where preemption disabling is only applicable to the current CPU and does not affect other CPUs.
2 In the future, we will implement "spinlock+sched_lock", and use it extensively. Under such circumstances, if preemption is still globally disabled, it will seriously impact the scheduling efficiency.
3 We have removed g_cpu_lockset and used irqcount in order to eliminate the dependency of schedlock on critical sections in the future, simplify the logic, and further enhance the performance of sched_lock.
4 We set lockcount to 1 in order to lock scheduling on all CPUs during startup, without the need to provide additional functions to disable scheduling on other CPUs.
5 Cpu1~n must wait for cpu0 to enter the idle state before enabling scheduling because it prevents CPUs1~n from competing with cpu0 for the memory manager mutex, which could cause the cpu0 idle task to enter a wait state and trigger an assert.

size nuttx
before:
   text    data     bss     dec     hex filename
 265396   51057   63646  380099   5ccc3 nuttx
after:
   text    data     bss     dec     hex filename
 265184   51057   63642  379883   5cbeb nuttx

size -216

Configuring NuttX and compile:
$ ./tools/configure.sh -l qemu-armv8a:nsh_smp
$ make
Running with qemu
$ qemu-system-aarch64 -cpu cortex-a53 -smp 4 -nographic \
   -machine virt,virtualization=on,gic-version=3 \
   -net none -chardev stdio,id=con,mux=on -serial chardev:con \
   -mon chardev=con,mode=readline -kernel ./nuttx

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-10 17:57:30 +08:00
dulibo1
1237e9fcea smp:fix sim build error under config CONFIG_SMP
CC:  sim/sim_smpsignal.c init/nx_smpstart.c: In function ‘nx_idle_trampoline’:
init/nx_smpstart.c:68:21: warning: unused variable ‘tcb’ [-Wunused-variable]
   68 |   FAR struct tcb_s *tcb = this_task_inirq();
      |                     ^~~
sim/sim_smpsignal.c: In function ‘host_cpu_started’:
sim/sim_smpsignal.c:271:17: warning: unused variable ‘tcb’ [-Wunused-variable]
  271 |   struct tcb_s *tcb = this_task();

sim/sim_smpsignal.c:249:33: error: ‘cpu’ undeclared (first use in this function)
  249 |   restore_critical_section(tcb, cpu);
      |                                 ^~~

Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2024-10-10 17:55:47 +08:00
dulibo1
f1f38b6e16 sched_smp:adjust the critical section to protect refcount from multi cores access
Signed-off-by: dulibo1 <dulibo1@xiaomi.com>
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2024-10-10 17:55:47 +08:00
dulibo1
6fd1ca64a1 sched_smp:sync refcount before enqueue smp call queue
Signed-off-by: dulibo1 <dulibo1@xiaomi.com>

1.call_data->refcount is not remote_cpus;
2.nxsched_smp_call_add enqueue  the call_data;
3.maybe nxsched_smp_call_handler is just doing;
4.dequeue the call_data but call_data->refcount is not corret;
5.unpredictability case will occur;
2024-10-10 17:55:47 +08:00
xuxingliang
a26051e7bc fs: fix wrong config for FS_SHMFS
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-10 00:29:57 +08:00
hujun5
a8717c6453 arch: We can use an independent SIG interrupt to handle async pause, which can save processing time.
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-09 23:32:31 +08:00
hujun5
ed998c08c4 sched: change the SMP scheduling policy from synchronous to asynchronous
reason:
Currently, if we need to schedule a task to another CPU, we have to completely halt the other CPU,
manipulate the scheduling linked list, and then resume the operation of that CPU. This process is both time-consuming and unnecessary.

During this process, both the current CPU and the target CPU are inevitably subjected to busyloop.

The improved strategy is to simply send a cross-core interrupt to the target CPU.
The current CPU continues to run while the target CPU responds to the interrupt, eliminating the certainty of a busyloop occurring.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-09 23:32:31 +08:00
fangzhenwei
cc9d42804b local_sock: fix accept use-after-free
we should get next waiter before acceptor released

Signed-off-by: fangzhenwei <fangzhenwei@xiaomi.com>
2024-10-09 23:00:32 +08:00
raiden00pl
a8ffa96b65 arch/arm/Kconfig: fix copy-paste error
ARCH_CHIP_CSK6 has nothing to do with ST chips:
fix option string and move below ST related options
2024-10-09 23:00:06 +08:00
7edb84c0c5 build.yml: Check out the correct branch of nuttx-apps
When building a branch like `releases/12.7`, the CI Workflow incorrectly checks out the `master` branch of `nuttx-apps`, instead of `releases/12.7`. This PR fixes a typo in `apps_ref`, to check out the correct branch.
2024-10-09 19:30:38 +08:00
hujun5
5f6eb292a8 sched: add nxsched_remove_self
reason:
1In the scenario of active waiting, context switching is inevitable, and we can eliminate redundant judgments.

code size
before
hujun5@hujun5-OptiPlex-7070:~/downloads1/vela_sim/nuttx$ size nuttx
   text    data     bss     dec     hex filename
 262848   49985   63893  376726   5bf96 nuttx

after
hujun5@hujun5-OptiPlex-7070:~/downloads1/vela_sim/nuttx$ size nuttx
   text    data     bss     dec     hex filename
 263324   49985   63893  377202   5c172 nuttx

reduce code size by  -476

Configuring NuttX and compile:
$ ./tools/configure.sh -l qemu-armv8a:nsh_smp
$ make
Running with qemu
$ qemu-system-aarch64 -cpu cortex-a53 -smp 4 -nographic \
   -machine virt,virtualization=on,gic-version=3 \
   -net none -chardev stdio,id=con,mux=on -serial chardev:con \
   -mon chardev=con,mode=readline -kernel ./nuttx

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-09 18:19:13 +08:00
chao an
9dbde04327 Revert "toolchain/ghs: Fix CONFIG_SCHED_CRITMONITOR_MAXTIME_XXX "zero used for undefined preprocessing identifier" warnings"
move private define to public

This reverts commit 236678d730.

Signed-off-by: chao an <anchao@lixiang.com>
2024-10-09 18:16:56 +08:00
hujun5
8cd52bee2e arm64: g_current_regs is only used to determine if we are in irq, with other functionalities removed.
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-09 18:16:43 +08:00
hujun5
d573952790 irq: use up_interrupt_context to replace up_current_regs
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-09 18:16:43 +08:00
hujun5
4ecb6efee8 arm: tc32 nested interrupts are not supported
Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-09 18:16:43 +08:00
hujun5
ee81823546 arm: g_current_regs is only used to determine if we are in irq, with other functionalities removed.
reason:
by doing this we can reduce context switch time,
When we exit from an interrupt handler, we directly use tcb->xcp.regs

before
size nuttx
   text    data     bss     dec     hex filename
 225920     409   30925  257254   3ece6 nuttx

after
   text    data     bss     dec     hex filename
 225604     409   30925  256938   3ebaa nuttx

 szie change -316

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-09 18:16:43 +08:00
xuxingliang
b63826a736 arch/sim: fix uart could lose log
Need to loop to write untill all data written or error happened

Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2024-10-09 18:16:28 +08:00
Xiang Xiao
42ee317eab arch/sim: dataheap should disable exec permission
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2024-10-09 18:16:28 +08:00
yinshengkai
593768e11e sim/gcov: Fix conflicts between fprofile-orderate and __asan_default_options
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2024-10-09 18:16:28 +08:00
yinshengkai
b7121aac86 Revert "arch/sim: suppress libasan checks"
This reverts commit 53ddc3ef7f

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-09 18:16:28 +08:00
ligd
d8637788a7 sim: fix context-switch when do wdog callback()
Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-09 18:16:28 +08:00
raiden00pl
dff79e8e54 boards/stm32f7/stm32f746g-disco: fix FMC pin
during migration from legacy pinout some of the FMC pins were ommited because
their names were identical to the new pinout, which didn't cause a compilation error.

This fixes LCD examples.

Also update incomplete stm32f769i-disco FMC support to avoid this kind of bug in the future
2024-10-09 00:04:57 +08:00
buxiasen
77d1f78996 board/arm/stm32: highpri up_interrupt_context to is_nesting_interrupt
up_interrupt_context indicates that we self inside interrupt/handler mode,
replaced to private function is_nesting_interrupt to make less confused.

Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2024-10-08 23:53:57 +08:00
buxiasen
431b848c79 board/arm/nrf52: fix use up_interrupt_context to is_nesting_interrupt
The case want to determine if a interrupt with higher priority and the
interrupt preemption occurred, but up_interrupt_context indicates that we
self inside interrupt/handler mode. As we previously did not handle the
ramvector interrupt correctly, after update breaked the case. We should
use a more clear private function is_nesting_interrupt.

Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2024-10-08 23:53:57 +08:00
chenxiaoyi
21501f65b1 sim: add link option /LARGEADDRESSAWARE:NO for windows64
Signed-off-by: chenxiaoyi <chenxiaoyi@xiaomi.com>
2024-10-08 23:51:33 +08:00
chenxiaoyi
a23ed77782 sim: add windows64 setjmp/longjmp support
Signed-off-by: chenxiaoyi <chenxiaoyi@xiaomi.com>
2024-10-08 23:51:33 +08:00
chenxiaoyi
835aac23b7 sim: change the type of xcpt_reg_t
Signed-off-by: chenxiaoyi <chenxiaoyi@xiaomi.com>
2024-10-08 23:51:33 +08:00
chenxiaoyi
2f512f78bf libc: fix build warning
nuttx\libs\libc\misc\lib_bitmap.c(1,1): warning C4819: The file contains a character that cannot
 be represented in the current code page (936).

Signed-off-by: chenxiaoyi <chenxiaoyi@xiaomi.com>
2024-10-08 23:51:33 +08:00
chenxiaoyi
753e4d64ee sim/irq: fix windows64 build error
nuttx\vs2022\include\arch\irq.h(144,9): error C2065: 'mov': undeclared identifier

Signed-off-by: chenxiaoyi <chenxiaoyi@xiaomi.com>
2024-10-08 23:51:33 +08:00
chenxiaoyi
d309d49cae sim/types: fix windows64 build error
nuttx\include\sys\types.h(133,22): error C2371: 'size_t': redefinition; different basic types

Signed-off-by: chenxiaoyi <chenxiaoyi@xiaomi.com>
2024-10-08 23:51:33 +08:00
chenxiaoyi
3100deda9d sim: add windows64 defconfig
Signed-off-by: chenxiaoyi <chenxiaoyi@xiaomi.com>
2024-10-08 23:51:33 +08:00
anjiahao
9403bc126b modlib/dlfcn:unify same code
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
2024-10-08 23:51:33 +08:00
dongjiuzhu1
79b4b39994 libc/modlib: free memory resource when rmmod elf
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2024-10-08 23:51:33 +08:00
dongjiuzhu1
3b0e2be058 binfmt/modlib: support loading each sections to different memory for Relocate object
The feature depends on ARCH_USE_SEPARATED_SECTION
the different memory area has different access speed and cache
capability, so the arch can custom allocate them based on
section names to achieve performance optimization

test:
sim:elf
sim:sotest

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2024-10-08 23:51:33 +08:00
ligd
a965e3c3f9 math: remove is_power_of_2() keep IS_POWER_OF_2()
Caused it may conflict with other platfrom

Signed-off-by: ligd <liguiding1@xiaomi.com>
2024-10-08 23:50:47 +08:00
Ville Juven
10e44f8915 riscv_fork.c: Fix race condition when handling parent integer registers
We need to record the parent's integer register context upon exception
entry to a separate non-volatile area. Why?

Because xcp.regs can move due to a context switch within the fork() system
call, be it either via interrupt or a synchronization point.

Fix this by adding a "sregs" area where the saved user context is placed.
The critical section within fork() is also unnecessary.
2024-10-03 09:07:57 +08:00
Ville Juven
2d3c94411b riscv_fork.c: Fix vfork() for kernel mode + SMP
There was an error in the fork() routine when system calls are in use:
the child context is saved on the child's user stack, which is incorrect,
the context must be saved on the kernel stack instead.

The result is a full system crash if (when) the child executes on a
different CPU which does not have the same MMU mappings active.
2024-10-03 09:07:57 +08:00
hujun5
d1fec65e1b riscv: use g_running_task store current regs
This commit fixes the regression from https://github.com/apache/nuttx/pull/13561

In order to determine whether a context switch has occurred,
we can use g_running_task to store the current regs.
This allows us to compare the current register state with the previously
stored state to identify if a context switch has taken place.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2024-10-03 09:07:48 +08:00
likun17
57f84aaca8 sensor: Added 6dof motion and gesture related types. For details, see: https://developer.android.com/reference/android/hardware/SensorEvent#values
Signed-off-by: likun17 <likun17@xiaomi.com>
2024-10-03 09:06:59 +08:00
likun17
a4e90b7268 inlclude/uorb.h:Update data types to be sorted by macro definition.
Signed-off-by: likun17 <likun17@xiaomi.com>
2024-10-03 09:06:59 +08:00
likun17
6a4196c572 sensor:sensor info power max_range and resolution are unified with Android type. 0e67aa0cae:include_all/hardware/sensors.h
Nuttx    <-------------------------------> Android
int32_t  <-- version                   --> int
float    <-- power                     --> float
float    <-- max_range                 --> float
float    <-- resolution                --> float
int32_t  <-- min_delay                 --> int32_t
int32_t  <-- max_delay                 --> int32/64_t
uint32_t <-- fifo_reserved_event_count --> uint32_t
uint32_t <-- fifo_max_event_count      --> uint32_t
char[]   <-- name                      --> char*
char[]   <-- vendor                    --> char*

Signed-off-by: likun17 <likun17@xiaomi.com>
2024-10-03 09:06:59 +08:00
dongjiuzhu1
eb0732a183 nuttx/uorb.h: align sensor_type value with aosp refs:0e67aa0cae:include_all/hardware/sensors-base.h
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2024-10-03 09:06:59 +08:00
buxiasen
40354619f3 Doc/ioexpand: add descriptions about ioexpander
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2024-10-03 09:06:04 +08:00
dulibo1
1179802cfe gpio:add feature for gpio wakeup
1.add pin type to cfg gpio as wake up source
2.add IOEXPANDER_OPTION_WAKEUPCFG for set wake up option

Signed-off-by: dulibo1 <dulibo1@xiaomi.com>
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2024-10-03 09:06:04 +08:00
Alin Jerpelea
2ec6c6e1fc Documentation: add NuttX-12.7.0 release notes
Add release notes for 12.7.0 release

Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
2024-10-02 20:56:47 +08:00
541 changed files with 13068 additions and 15857 deletions

View file

@ -2,6 +2,7 @@
ignore = W503,W605,E203
max-complexity = 27
max-line-length = 125
multi_line_output=3
show-source = True
statistics = True

View file

@ -86,7 +86,7 @@ jobs:
fi
echo "name=$OS_REF" >> $GITHUB_OUTPUT
echo "app_ref=$APPS_REF" >> $GITHUB_OUTPUT
echo "apps_ref=$APPS_REF" >> $GITHUB_OUTPUT
- name: Checkout nuttx repo
uses: actions/checkout@v4

View file

@ -39,7 +39,9 @@ jobs:
- name: Check Pull Request
run: |
echo "::add-matcher::nuttx/.github/nxstyle.json"
pip install cmake-format
python3 -m venv .venv
source .venv/bin/activate
pip install cmake-format black isort flake8
cd nuttx
commits="${{ github.event.pull_request.base.sha }}..HEAD"
git log --oneline $commits

View file

@ -667,6 +667,9 @@ elseif(WIN32)
"${CONFIG_SIM_STACKSIZE_ADJUSTMENT} + ${CONFIG_IDLETHREAD_STACKSIZE}"
OUTPUT_FORMAT DECIMAL)
target_link_options(nuttx PUBLIC /STACK:${LINK_STACKSIZE},${LINK_STACKSIZE})
if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "x64")
target_link_options(nuttx PUBLIC /LARGEADDRESSAWARE:NO)
endif()
set(nuttx_libs_paths)
foreach(lib ${nuttx_libs})
list(APPEND nuttx_libs_paths $<TARGET_FILE:${lib}>)

View file

@ -0,0 +1,768 @@
What's New In This Release
Core OS
Sched
* [#13395](https://github.com/apache/nuttx/pull/13395) Critmon optimize, make possible open cpuload based on critmon and disable critical section & sched_lock to save cost.
* [#12691](https://github.com/apache/nuttx/pull/12691) sched.h: add SCHED_BATCH and SCHED_IDLE definition
* [#12584](https://github.com/apache/nuttx/pull/12584) sched.h: CPU_XXX macros can also be used without CONFIG_SMP
* [#12703](https://github.com/apache/nuttx/pull/12703) sched.h: Update doc link for tcbinfo_s
* [#13274](https://github.com/apache/nuttx/pull/13274) sched: add DEBUGASSERT to assure that affinity not zero
* [#13341](https://github.com/apache/nuttx/pull/13341) sched: adjust the scheduling strategy
* [#13105](https://github.com/apache/nuttx/pull/13105) sched: change pthread_mutex implementation from sem to mutex
* [#12742](https://github.com/apache/nuttx/pull/12742) sched: Improve Kconfig help of INIT_ENTRYPOINT
* [#13525](https://github.com/apache/nuttx/pull/13525) sched: move DUMP_ON_EXIT to sched
* [#13211](https://github.com/apache/nuttx/pull/13211) sched: replace up_cpu_index with this_cpu
* [#13271](https://github.com/apache/nuttx/pull/13271) sched: use this_task replace nxsched_self
* [#13263](https://github.com/apache/nuttx/pull/13263) sched/event: clear pending events before enable the scheduler
* [#13329](https://github.com/apache/nuttx/pull/13329) sched/group/setuptask_file: duplicate idle task fd for kernel thread
* [#13083](https://github.com/apache/nuttx/pull/13083) sched/irq: correct critical section to spin lock
* [#12802](https://github.com/apache/nuttx/pull/12802) sched/nxevent: add support of kernel event group
* [#13264](https://github.com/apache/nuttx/pull/13264) sched/policy: move g_policy from data to rodata
* [#13017](https://github.com/apache/nuttx/pull/13017) sched/sched: simplify the implementation of the function nxsched_readytorun_setpriority
* [#13134](https://github.com/apache/nuttx/pull/13134) sched/signal: fix pthread_kill use after free
* [#13530](https://github.com/apache/nuttx/pull/13530) sched/signal: Simplified Implementation for SIGEV_THREAD_TID
* [#12283](https://github.com/apache/nuttx/pull/12283) sched/signal: There is no need to use sched_[un]lock
* [#12553](https://github.com/apache/nuttx/pull/12553) sched/tcb: amend pull/12320
MM
* [#12550](https://github.com/apache/nuttx/pull/12550) mm: add mm_initialize_pool, make pool more flexible
* [#12556](https://github.com/apache/nuttx/pull/12556) mm: mm_threshold perfer from init
* [#12501](https://github.com/apache/nuttx/pull/12501) mm/iob: Simplify IOB alloc/free logic
* [#12923](https://github.com/apache/nuttx/pull/12923) mm/map/vm_region.c: Fix usage of void* arithmetics
* [#12946](https://github.com/apache/nuttx/pull/12946) mm/mempool: rename the mempool_alloc and mempool_free function
* [#12659](https://github.com/apache/nuttx/pull/12659) mm_ubsan: add dummy to bypass runtime actions
* [#12646](https://github.com/apache/nuttx/pull/12646) mm_ubsan: add implement for dynamic_type_cache_miss
libc
* [#12672](https://github.com/apache/nuttx/pull/12672) add rint and expm1 function to cmath from libm
* [#13420](https://github.com/apache/nuttx/pull/13420) Add dummy implementations for `shm_open` `pthread_setaffinity_np` and `RLIMIT_RTPRIO`
* [#13429](https://github.com/apache/nuttx/pull/13429) arm64_task/pthread_start: Convert the C / inline ASM code to assembly
* [#13366](https://github.com/apache/nuttx/pull/13366) arm64/task/pthread_start: Fix rare issue with context register location
* [#13011](https://github.com/apache/nuttx/pull/13011) lib_getcwd:Fix the Name in the function description.
* [#12966](https://github.com/apache/nuttx/pull/12966) lib_remove:Repair the logical judgment
* [#12890](https://github.com/apache/nuttx/pull/12890) libc: Add macro restrictions to code that uses floating point numbers
* [#13111](https://github.com/apache/nuttx/pull/13111) libc: compile stackchk function by default
* [#12953](https://github.com/apache/nuttx/pull/12953) libs: fix the default value of process-shared attribute
* [#12975](https://github.com/apache/nuttx/pull/12975) libs: fix the default value of process-shared attribute
* [#12605](https://github.com/apache/nuttx/pull/12605) libc: scanf, printf %z change switch const to if
* [#12585](https://github.com/apache/nuttx/pull/12585) libc/execinfo: extract a common backtrace format function
* [#13013](https://github.com/apache/nuttx/pull/13013) libc/msic: Implement get_nprocs API
* [#13381](https://github.com/apache/nuttx/pull/13381) libc/misc/crc32: crc32 add slow mode, optional decrease size
* [#13441](https://github.com/apache/nuttx/pull/13441) libc/netdb: Remove unnecessary CONFIG_LIBC_NETDB checks
* [#13025](https://github.com/apache/nuttx/pull/13025) libc/netdb: Separate IPv4 and IPv6 cache size limit
* [#13220](https://github.com/apache/nuttx/pull/13220) libc/sysconf: add _SC_GETPW_R_SIZE_MAX
* [#13479](https://github.com/apache/nuttx/pull/13479) libc/time: add g_lcl_lock to protect local context in localsub
* [#13080](https://github.com/apache/nuttx/pull/13080) libc/time: remove lib_strptime
* [#12693](https://github.com/apache/nuttx/pull/12693) libc/unistd: added an implementation of the lib_flock function
* [#12609](https://github.com/apache/nuttx/pull/12609) libc/x86_64: port string functions from bionic
* [#13110](https://github.com/apache/nuttx/pull/13110) libcxxabi: libcxxabi enables exceptions by default
* [#13079](https://github.com/apache/nuttx/pull/13079) libs/libc/obstack: correctly append null byte at the end of string
* [#13482](https://github.com/apache/nuttx/pull/13482) libs/libc/obstack: implement ptr and int growing functions
* [#13495](https://github.com/apache/nuttx/pull/13495) libs/libc/obstack: revert invalid null byte append to obstack_vprintf
* [#13185](https://github.com/apache/nuttx/pull/13185) libs/libc/stdio/*printf *scanf:Add string serialization and deserialization functions
* [#13294](https://github.com/apache/nuttx/pull/13294) libs/libm: fix epsilon relaxation in log and logf
* [#13307](https://github.com/apache/nuttx/pull/13307) libs/libm/libm: apply epsilon relax factor only if epsilon is small
* [#12568](https://github.com/apache/nuttx/pull/12568) libm{libm|newlib}: fix broken sincos optimization for GCC
* [#12811](https://github.com/apache/nuttx/pull/12811) libm/copysign: respect signed zero/NaN handling in copysign
* [#13174](https://github.com/apache/nuttx/pull/13174) syscall: delete getrandom in syscall because it have moved to lib
* [#13428](https://github.com/apache/nuttx/pull/13428) gdb plugin: Encapsulate the gdb native command gcore as nxgcore
* [#12557](https://github.com/apache/nuttx/pull/12557) gdbstub: fix typo
* [#12549](https://github.com/apache/nuttx/pull/12549) gdbstub: support gdbstub_debugpoint_add/remove smp call
* [#13339](https://github.com/apache/nuttx/pull/13339) nuttx/pthread: export priority protect in pthread with ceiling priority in semaphore
* [#12561](https://github.com/apache/nuttx/pull/12561) pthread: add pthread_self/pthread_gettid_np function
* [#13462](https://github.com/apache/nuttx/pull/13462) pthread_mutx: remove unused critical_secton lock
* [#13456](https://github.com/apache/nuttx/pull/13456) pthread_mutex: add deadlock assert
tools
* [#12701](https://github.com/apache/nuttx/pull/12701) Feature/mcuboot toolchain support
* [#13021](https://github.com/apache/nuttx/pull/13021) tools: add improved pre-commit tool
* [#12794](https://github.com/apache/nuttx/pull/12794) tools: nxstyle if statement check
* [#12651](https://github.com/apache/nuttx/pull/12651) tools/imx9: prepare bootable bootloader image
* [#12838](https://github.com/apache/nuttx/pull/12838) tools/[Rust|D]: Fix build break for RISC-V
* [#12854](https://github.com/apache/nuttx/pull/12854) tools/[Rust|D]: Fix the Rust and D Builds for QEMU RISC-V
* [#12983](https://github.com/apache/nuttx/pull/12983) tools/parsetrace.py:fix parsetrace script error
* [#13321](https://github.com/apache/nuttx/pull/13321) greenhills support: add ghs linker script for mps2-an500 platform
* [#12884](https://github.com/apache/nuttx/pull/12884) greenhills support: add Kconfig, makefile, make.defs support for ghs compiler
* [#12887](https://github.com/apache/nuttx/pull/12887) greenhills support: add new platform of qemu cortex-m7
* [#13146](https://github.com/apache/nuttx/pull/13146) greenhills support: add the "__sync_synchronize" func impl
* [#12877](https://github.com/apache/nuttx/pull/12877) greenhills support: add up_getsp() implementation to adapting greenhills compiler
* [#12883](https://github.com/apache/nuttx/pull/12883) greenhills support: fix the asm build error for adapting to greenhills compiler
* [#12885](https://github.com/apache/nuttx/pull/12885) greenhills support: fix the build and link error specific to ghs platform
* [#13144](https://github.com/apache/nuttx/pull/13144) greenhills support: fix the build options warning
* [#13207](https://github.com/apache/nuttx/pull/13207) greenhills support: fix the build option warning
* [#13145](https://github.com/apache/nuttx/pull/13145) greenhills support: fix the build warning while support greenhills build
* [#12886](https://github.com/apache/nuttx/pull/12886) greenhills support: fix the build warning for ghs platform
* [#13533](https://github.com/apache/nuttx/pull/13533) greenhills support: fix the enumerated type mixed using warning
* [#13322](https://github.com/apache/nuttx/pull/13322) greenhills support: fix the ghs build warning
* [#13502](https://github.com/apache/nuttx/pull/13502) greenhills support: fix the greenhills compile warning on sizeof operand
* [#13195](https://github.com/apache/nuttx/pull/13195) greenhills support: fix the pointless comparison build warning
various
* [#12552](https://github.com/apache/nuttx/pull/12552) compiler.h: rename CMSE extension attribute macros
* [#12874](https://github.com/apache/nuttx/pull/12874) fix stm32wl5_rcc.h: Add the missing argument to RCC_PLLCFG_PLLP define.
* [#13148](https://github.com/apache/nuttx/pull/13148) include/fcntl.h: add O_LARGEFILE flags
* [#13324](https://github.com/apache/nuttx/pull/13324) include/sensors: import public definitions types and to uorb.h
* [#12690](https://github.com/apache/nuttx/pull/12690) ioctl.h: add SIOCATMARK definition to resolve compilation errors
* [#13314](https://github.com/apache/nuttx/pull/13314) ip6_tables.h: fix gcc 14 errors
* [#13257](https://github.com/apache/nuttx/pull/13257) socketlin : add lin.h and lin bus-type
* [#12692](https://github.com/apache/nuttx/pull/12692) sysinfo.h: add get_nprocs_conf/get_nprocs definition
* [#13149](https://github.com/apache/nuttx/pull/13149) sys/shm.h: add macro define for posix
* [#12594](https://github.com/apache/nuttx/pull/12594) x86_64/irq.h: use 32bit operations in up_cpu_index(
Build System
New Features
* [#12904](https://github.com/apache/nuttx/pull/12904) [Cross-Platform] Remove Unix-specific code in savedefconfig and replace it with cmake script
* [#12910](https://github.com/apache/nuttx/pull/12910) [cmake] add_application supports only registration but not compilation
* [#12964](https://github.com/apache/nuttx/pull/12964) [cmake] split the archive process to avoid parameter too long problems
* [#13019](https://github.com/apache/nuttx/pull/13019) [cmake] add nuttx_post and app_context inter targets for timing control
* [#12908](https://github.com/apache/nuttx/pull/12908) [Win32 sim] enable win32 native platfrom sim compilation by CMake fix compilation error
* [#12900](https://github.com/apache/nuttx/pull/12900) arch/sim/src/cmake/Toolchain.cmake: macOS fix unknown options: --gc-sections
* [#12856](https://github.com/apache/nuttx/pull/12856) build: Fix libc/pwd CMakeLists.txt
* [#13347](https://github.com/apache/nuttx/pull/13347) build: fix memory manager compile options for CMake
* [#12859](https://github.com/apache/nuttx/pull/12859) build: Fix Toolchain.cmake for CONFIG_SIM_ASAN enabled
* [#12880](https://github.com/apache/nuttx/pull/12880) build: set CMake policy to allow FetchContent_Populate
* [#12784](https://github.com/apache/nuttx/pull/12784) build/cmake: add user_ldscript preprocessing
* [#12866](https://github.com/apache/nuttx/pull/12866) build/cmake: fix system include dir for PROTECTED mode
* [#13143](https://github.com/apache/nuttx/pull/13143) board/maix-bit: initial cmake support
* [#13090](https://github.com/apache/nuttx/pull/13090) board/qemu-armv7a: add CMake support
* [#12868](https://github.com/apache/nuttx/pull/12868) boards/rv-virt: cmake for pnsh and nsbi
* [#13175](https://github.com/apache/nuttx/pull/13175) Cmake: [arch arm] added initial support for MSYS2
* [#13389](https://github.com/apache/nuttx/pull/13389) cmake: add support for PCI
* [#12516](https://github.com/apache/nuttx/pull/12516) cmake: reuse OpenAMP own CMake script for CMake build
* [#12592](https://github.com/apache/nuttx/pull/12592) cmake: refine sim cmake redefine symbols
* [#13449](https://github.com/apache/nuttx/pull/13449) cmake: Refactor extra_lib tagert,build include_arch path,refine sim link script target
* [#12667](https://github.com/apache/nuttx/pull/12667) cmake: strip file full path to save the code size
* [#13451](https://github.com/apache/nuttx/pull/13451) cmake: support openlibm,dhara,libmcs,lic regex CMake build scripts
* [#12608](https://github.com/apache/nuttx/pull/12608) cmake/add_library: enable library install by default
* [#12714](https://github.com/apache/nuttx/pull/12714) cmake/boards: fix build break on custom board
* [#13085](https://github.com/apache/nuttx/pull/13085) CMakeLists.txt: warning D9002 on Windows + msvc
* [#13253](https://github.com/apache/nuttx/pull/13253) cmake/nuttx_kconfig.cmake: fixed the correct .config path in the buid folder
* [#13276](https://github.com/apache/nuttx/pull/13276) cmake/tricore: filter out nostdlib in linker phase to avoid build break
* [#13499](https://github.com/apache/nuttx/pull/13499) libc: add missing preadv/pwritev in CMakeLists.txt
* [#12700](https://github.com/apache/nuttx/pull/12700) riscv/cmake: fix Toolchain.cmake
* [#12694](https://github.com/apache/nuttx/pull/12694) riscv/k230: fix apps ROMFS cmake
* [#12996](https://github.com/apache/nuttx/pull/12996) riscv/qemu-rv: add RPTUN cmake
* [#12634](https://github.com/apache/nuttx/pull/12634) sim/cmake: enable garbage collection of unused input sections
* [#12721](https://github.com/apache/nuttx/pull/12721) tools/testbuild.sh: add option -N use CMake with Ninja
* [#12805](https://github.com/apache/nuttx/pull/12805) tools/testbuild.sh: added store compilation artifacts for cmake
* [#12724](https://github.com/apache/nuttx/pull/12724) tricore/cmake: add support of cmake build for tricore
Bug Fixes
* [#12558](https://github.com/apache/nuttx/pull/12558) [bugfix] cmake:fix a few issues during CMake build
* [#12915](https://github.com/apache/nuttx/pull/12915) [bugfix] fix CMake build block when enable LTO
* [#12582](https://github.com/apache/nuttx/pull/12582) Fix cmake for cxd56xx
* [#12581](https://github.com/apache/nuttx/pull/12581) cmake: Fix build failure when -DNUTTX_APPS_DIR is specified
* [#13171](https://github.com/apache/nuttx/pull/13171) CMake: fix CMake compile errors during the protected build mode
* [#13081](https://github.com/apache/nuttx/pull/13081) cmake: fix invalid syntax when generating version.h from tags
Architectural Support
unsorted
* [#12827](https://github.com/apache/nuttx/pull/12827) Additional encoder for F7 and added functions for TimerHook for F745 …
* [#12924](https://github.com/apache/nuttx/pull/12924) Bugfix/esp spi fix
* [#12770](https://github.com/apache/nuttx/pull/12770) Enable SMPS for STM32H745I-DISCO by default
* [#12574](https://github.com/apache/nuttx/pull/12574) arch: Add --whole-archive linker option for some of architectures
* [#13200](https://github.com/apache/nuttx/pull/13200) arch: cxd56xx: Add logic for i2c reset
* [#13496](https://github.com/apache/nuttx/pull/13496) arch: cxd56xx: Fix issue by update of inode reference
* [#13201](https://github.com/apache/nuttx/pull/13201) arch: cxd56xx: Fix SCU sensor data format
* [#12962](https://github.com/apache/nuttx/pull/12962) arch: inline this_task to improve performence
* [#13270](https://github.com/apache/nuttx/pull/13270) arch: remove unused up_cpu_pausereq waiting
* [#13423](https://github.com/apache/nuttx/pull/13423) arch: use up_current_regs/up_set_current_regs replace CURRENT_REGS
* [#13041](https://github.com/apache/nuttx/pull/13041) arch/EXTRA_LIBS: link all staging library.
* [#12624](https://github.com/apache/nuttx/pull/12624) arch/sim: add custom data section support
* [#12909](https://github.com/apache/nuttx/pull/12909) arch/sim/Kconfig: set SIM_FBBPP to 32 by default
* [#12845](https://github.com/apache/nuttx/pull/12845) arch/stm32h7: add defines for USART clock selection
* [#13292](https://github.com/apache/nuttx/pull/13292) arch/xmc4 : Add input pin DX0 selection for multiple SPI channel
* [#12823](https://github.com/apache/nuttx/pull/12823) arch/xmc4 : Fixed critical section in i2c_transfer
* [#12761](https://github.com/apache/nuttx/pull/12761) arch/xmc4 : i2c master lower-half driver
* [#12545](https://github.com/apache/nuttx/pull/12545) BL808: Add support for UARTs 0-2 and serial configuration
* [#12575](https://github.com/apache/nuttx/pull/12575) BL808: Replace courier with M0 interrupt controller
* [#12795](https://github.com/apache/nuttx/pull/12795) elf: Enable ELF loader if text heap read is word-aligned and enable ELF loader for ESP32-S3
* [#12620](https://github.com/apache/nuttx/pull/12620) esp32: add simple boot support
* [#12616](https://github.com/apache/nuttx/pull/12616) ESP32: emac initialization adding cpu id
* [#13249](https://github.com/apache/nuttx/pull/13249) esp32: enable APP_CPU cache earlier
* [#13244](https://github.com/apache/nuttx/pull/13244) esp32: cache_sram_mmu_set: update the correct register bits
* [#13222](https://github.com/apache/nuttx/pull/13222) esp32: fix a crash with PSRAM + SMP
* [#13243](https://github.com/apache/nuttx/pull/13243) esp32: fix seemingly wrong calculations
* [#13250](https://github.com/apache/nuttx/pull/13250) esp32: psram_set_cs_timing: sync with esp-idf
* [#13311](https://github.com/apache/nuttx/pull/13311) esp32: Port the bootloader patch
* [#12572](https://github.com/apache/nuttx/pull/12572) esp32[c3|c6|h2]: Add I2C master support
* [#12573](https://github.com/apache/nuttx/pull/12573) esp32[c3|c6|h2]: Add GDMA support
* [#13298](https://github.com/apache/nuttx/pull/13298) esp32c6: PCNT Quadrature Encoder driver
* [#13269](https://github.com/apache/nuttx/pull/13269) esp32s2: fix SPI flash and file system mounting
* [#12647](https://github.com/apache/nuttx/pull/12647) esp32s3-devkit: add a config for qemu
* [#12851](https://github.com/apache/nuttx/pull/12851) esp32s3-devkit/toywasm: enable ESP32S3_SPI_FLASH_SUPPORT_PSRAM_STACK
* [#12725](https://github.com/apache/nuttx/pull/12725) esp32s3_textheap.c: fix a build error w/o CONFIG_ESP32S3_SPIRAM
* [#12565](https://github.com/apache/nuttx/pull/12565) esp32s3/wifi: Fix bug related to IOB off-loading with SMP
* [#12789](https://github.com/apache/nuttx/pull/12789) esp32s3/i2s: Fix faulty initialization when SMP is enabled
* [#13265](https://github.com/apache/nuttx/pull/13265) esp32_psram.c: Remove a seemingly stale comment
* [#12669](https://github.com/apache/nuttx/pull/12669) Feature/esp mcuboot support
* [#12776](https://github.com/apache/nuttx/pull/12776) Feature/esp spi dma
* [#12775](https://github.com/apache/nuttx/pull/12775) Feature/esp temperature sensor
* [#12604](https://github.com/apache/nuttx/pull/12604) fix(esp32-qemu-openeth): allocate buffers in internal memory
* [#13193](https://github.com/apache/nuttx/pull/13193) gd32f4xx_at24: Fix uninitialized use of local variables i2c and at24
* [#13401](https://github.com/apache/nuttx/pull/13401) Imx9 ethernet fixes
* [#12632](https://github.com/apache/nuttx/pull/12632) Imx9 support flexspi m25p nor
* [#13399](https://github.com/apache/nuttx/pull/13399) imx9/edma: Fix function prototypes
* [#13400](https://github.com/apache/nuttx/pull/13400) imx9/LPUART fixes
* [#12921](https://github.com/apache/nuttx/pull/12921) imx93: Add more base addresses
* [#12623](https://github.com/apache/nuttx/pull/12623) imxrt: Correctly update PLL, bit has to toggled instead of being set
* [#12562](https://github.com/apache/nuttx/pull/12562) imxrt: imxrt11xx set core clock to 1p15v regardless of ocotp
* [#12821](https://github.com/apache/nuttx/pull/12821) k230_start.c: Fix condition for k230_copy_init_data()
* [#12894](https://github.com/apache/nuttx/pull/12894) mps3-an547:support mps3-an547 reset
* [#12989](https://github.com/apache/nuttx/pull/12989) nuttx/sim:By default, stack-use-after-return is not checked when enabling SIM_ASAN.
* [#13043](https://github.com/apache/nuttx/pull/13043) nuttx/sim:By default, stack-use-after-return is not checked when enabling SIM_ASAN.
* [#13548](https://github.com/apache/nuttx/pull/13548) nrf91: Update GPS to GNSS
* [#12612](https://github.com/apache/nuttx/pull/12612) refactor(esp32-qemu-openeth): use lower half driver interface
* [#12660](https://github.com/apache/nuttx/pull/12660) refresh esp32s3-devkit:qemu_debug
* [#12707](https://github.com/apache/nuttx/pull/12707) rp2040 Rename the RP2040-specific PWM_MULTICHAN definition
* [#12610](https://github.com/apache/nuttx/pull/12610) rp2040: Add support to MAX6675
* [#13318](https://github.com/apache/nuttx/pull/13318) rp2040: Support pico-sdk 2.0.0
* [#13070](https://github.com/apache/nuttx/pull/13070) Sync the modifications of the WiFi function in simulator.
* [#12697](https://github.com/apache/nuttx/pull/12697) s32k1xx: FlexIO i2c driver
* [#12678](https://github.com/apache/nuttx/pull/12678) samv7: fix compile warning in PWM driver
* [#12627](https://github.com/apache/nuttx/pull/12627) samv7/sam_mcan.c: fix TSEG1, TSEG2 and SJW compile warnings for MCAN1
* [#12622](https://github.com/apache/nuttx/pull/12622) sim: make possible keep ubsan and bypass feature
* [#13034](https://github.com/apache/nuttx/pull/13034) sim: read the second buffer
* [#13097](https://github.com/apache/nuttx/pull/13097) sim: Support to use of non-consecutive framebuffers
* [#13355](https://github.com/apache/nuttx/pull/13355) sim_offload: add lame library to apps/audioutils/lame
* [#12870](https://github.com/apache/nuttx/pull/12870) sim/login: remove login restrictions to improve the experience for green hands
* [#13534](https://github.com/apache/nuttx/pull/13534) sim/minmea: Fix defconfig warning
* [#13042](https://github.com/apache/nuttx/pull/13042) simwifi: Add the netlink event of connect/disconnect.
* [#12778](https://github.com/apache/nuttx/pull/12778) Small improvements to nrf91
* [#13282](https://github.com/apache/nuttx/pull/13282) smp: enable smp_call in all smp arch
* [#12566](https://github.com/apache/nuttx/pull/12566) STM32G47XXX: Added basic HRTIM support.
* [#12600](https://github.com/apache/nuttx/pull/12600) tee smp support
* [#12640](https://github.com/apache/nuttx/pull/12640) Userleds support to seed-xiao-rp2040
* [#13032](https://github.com/apache/nuttx/pull/13032) wifi_sim.c:fix compile warning
Architecture Improvements
arm
* [#12626](https://github.com/apache/nuttx/pull/12626) arch/arm/stm32: Fix EXTI lines definitions for STM32G47XX.
* [#12664](https://github.com/apache/nuttx/pull/12664) arch/armv8-r: new config to set SPIs Configuration to edge-triggered
* [#12666](https://github.com/apache/nuttx/pull/12666) arch/armv8-r: update g_running_tasks before context switch
* [#13472](https://github.com/apache/nuttx/pull/13472) arch/arm-m: Clear lr before jump to __start
* [#13284](https://github.com/apache/nuttx/pull/13284) arch/arm: support kernel heap in BUILD_FLAT mode
* [#13416](https://github.com/apache/nuttx/pull/13416) arm generate busfault & recursive bug fix
* [#13268](https://github.com/apache/nuttx/pull/13268) arm: armv7-a/r and armv8-r up_cpu_index inline
* [#13024](https://github.com/apache/nuttx/pull/13024) arm: Fix DS1307 initialization for common STM32 logic
* [#12888](https://github.com/apache/nuttx/pull/12888) arm: Select ram vector on armv6m
* [#13505](https://github.com/apache/nuttx/pull/13505) arm_addrenv:fix app crash when enable shm in kernel mode
* [#12787](https://github.com/apache/nuttx/pull/12787) arm_backtrace_unwind:Make the backtrace search the entire stack as much as possible
* [#12954](https://github.com/apache/nuttx/pull/12954) arm/armv[7|8]-m: add syn barrier for MPU ops
* [#12925](https://github.com/apache/nuttx/pull/12925) arm/armv8-r: invalidate d-cache on boot
* [#12928](https://github.com/apache/nuttx/pull/12928) arm/armv8-r: add cp15 ops for mpu
* [#13529](https://github.com/apache/nuttx/pull/13529) arm/cortex-a,r: replace cp15 instruct to macros to align operation
* [#13239](https://github.com/apache/nuttx/pull/13239) arm/giv3: add g_ prefix to some global variables
* [#13262](https://github.com/apache/nuttx/pull/13262) arm/gicv3: set routing affinity before enable IRQ
* [#13240](https://github.com/apache/nuttx/pull/13240) arm/linum-stm32h753bi: Add support to RFID MFRC522
* [#12873](https://github.com/apache/nuttx/pull/12873) arm/lm3s6965-ek: Disable NTPC for lm3s6965 to fix maximum flash space…
* [#13557](https://github.com/apache/nuttx/pull/13557) arm/qemu: Add mounting of tmpfs
* [#13117](https://github.com/apache/nuttx/pull/13117) arm/qemu: enable WFI in `up_idle`
* [#13131](https://github.com/apache/nuttx/pull/13131) arm/spinlock: up_testset() sould not depends on SMP
* [#12879](https://github.com/apache/nuttx/pull/12879) arm/stm32f401rc-rs485: Add support to BMP280 sensor
* [#13565](https://github.com/apache/nuttx/pull/13565) arm/stm32f401rc-rs485: Add support to LCD 16x2 with I2C Backpack
* [#12839](https://github.com/apache/nuttx/pull/12839) arm/stm32f401rc-rs485: Add support to RFID MFRC522
* [#12860](https://github.com/apache/nuttx/pull/12860) arm/stm32h7/stm32h745i-disco: Add STM32H745I-DISCO Per Core Support
* [#12902](https://github.com/apache/nuttx/pull/12902) arm/stm32h7x3x_rcc.c: Add External Power Supply option to stm32h7x3x …
* [#12679](https://github.com/apache/nuttx/pull/12679) arm/xmc4: pwm driver
* [#13466](https://github.com/apache/nuttx/pull/13466) armv7-a gic related update
* [#13176](https://github.com/apache/nuttx/pull/13176) armv7-a timer:fix timer overflow.
* [#12956](https://github.com/apache/nuttx/pull/12956) armv7a/irq: enable fiq in tee, enable irq in ap
* [#13453](https://github.com/apache/nuttx/pull/13453) armv8-m:arch libc function need save ip register use pacbti
* [#13237](https://github.com/apache/nuttx/pull/13237) armv8-r/gicv3: correct cpu index of irouter
* [#13275](https://github.com/apache/nuttx/pull/13275) armv8-r/r52: add neon support into compiler lin
arm64
* [#12633](https://github.com/apache/nuttx/pull/12633) arch/arm64/src/imx9/imx9_lowputc.c: Fix an arithmetic sign error in d…
* [#12648](https://github.com/apache/nuttx/pull/12648) arch/arm64: allow to use custom up_idle
* [#13397](https://github.com/apache/nuttx/pull/13397) arch/arm64/src/imx9/imx9_lpi2c.c: Cleanups and error fixes
* [#13402](https://github.com/apache/nuttx/pull/13402) arch/arm64/imx9: Change Kconfig logic
* [#13403](https://github.com/apache/nuttx/pull/13403) arch/arm64/imx9: Add system reset controller
* [#13427](https://github.com/apache/nuttx/pull/13427) arch/arm64/src/imx9/imx9_lpi2c.c: Ignore spurious RX interrupts
* [#13218](https://github.com/apache/nuttx/pull/13218) arch/arm64: Move ELF_64BIT selection to arch/Kconfig
* [#12681](https://github.com/apache/nuttx/pull/12681) arm64: add initial support for ZYNQ MPSOC and ZCU111 Evaluation Kit
* [#12580](https://github.com/apache/nuttx/pull/12580) arm64: inline up_cpu_index
* [#13560](https://github.com/apache/nuttx/pull/13560) arm64_addrenv: Add support for 4 level MMU translations
* [#13363](https://github.com/apache/nuttx/pull/13363) arm64_addrenv_pgmap.c: Revoke user execution access to kernel mmap'd pages
* [#13364](https://github.com/apache/nuttx/pull/13364) arm64_addrenv.c: Flush kernel page table copy to user mappings
* [#13204](https://github.com/apache/nuttx/pull/13204) arm64_checkstack.c: Fix traversing of user stack when ARCH_ADDRENV=Y
* [#13361](https://github.com/apache/nuttx/pull/13361) arm64_syscall.c: Don't need to set register context during syscall
* [#13365](https://github.com/apache/nuttx/pull/13365) arm64_vector_table.S: Remove unnecessary instruction
* [#12695](https://github.com/apache/nuttx/pull/12695) arm64/arm64_boot.c: Fix exception caused by accesses to ICC_SRE_EL3 when GICv3 was not implemented
* [#13373](https://github.com/apache/nuttx/pull/13373) arm64/crt0.c: Fix stack alignment when executing signal trampoline
* [#12649](https://github.com/apache/nuttx/pull/12649) arm64/imx9: ccm: add default clk init
* [#13205](https://github.com/apache/nuttx/pull/13205) arm64/imx9: Force 64-bit ELF format
* [#13360](https://github.com/apache/nuttx/pull/13360) arm64/mmu: Fixes for MMU driver
* [#13362](https://github.com/apache/nuttx/pull/13362) arm64/syscall: (Re-)enable interrupts only if they were previously enable
tricore
* [#12682](https://github.com/apache/nuttx/pull/12682) arch/tricore: add support of tricore gcc toolchain
* [#12706](https://github.com/apache/nuttx/pull/12706) arch/tricore: synchronize instruction/data following MTCR/MFC
risc-v
* [#12961](https://github.com/apache/nuttx/pull/12961) arch: inline up_testset in arm arm64 riscv xtensa
* [#12579](https://github.com/apache/nuttx/pull/12579) arch/riscv: add all region in NAPOT
* [#12881](https://github.com/apache/nuttx/pull/12881) arch/riscv: add cluster local hartid
* [#12906](https://github.com/apache/nuttx/pull/12906) arch/riscv: fix IRQ_SOFT for non-SMP
* [#12546](https://github.com/apache/nuttx/pull/12546) arch/riscv: fix NuttSBI PMP config
* [#12717](https://github.com/apache/nuttx/pull/12717) arch/riscv: fix trap sp restore logic
* [#13430](https://github.com/apache/nuttx/pull/13430) arch/riscv: Fixed hardware timer warps-around issue
* [#13278](https://github.com/apache/nuttx/pull/13278) arch/riscv: revert pull#12864
* [#12864](https://github.com/apache/nuttx/pull/12864) arch/riscv: unify in-kernel syscall
* [#12619](https://github.com/apache/nuttx/pull/12619) arch/risc-v: add support for capture driver on ESP32C6 and ESP32H2.
* [#12726](https://github.com/apache/nuttx/pull/12726) arch/risc-v: make common up_allocate_heap weak symbol
* [#12732](https://github.com/apache/nuttx/pull/12732) arch/risc-v: does not clear IPI address in S mode
* [#12460](https://github.com/apache/nuttx/pull/12460) arch/risc-v/common: provide architecture specific perfmon bindings.
* [#13353](https://github.com/apache/nuttx/pull/13353) arch/risc-v/litex: Fix the litex arty_a7 build
* [#13382](https://github.com/apache/nuttx/pull/13382) arch/risc-v/src/litex: Claim all pending PLIC interrupts.
* [#13547](https://github.com/apache/nuttx/pull/13547) arch/risc-v/src/litex_ticked: Set initial tick count to known value.
* [#12804](https://github.com/apache/nuttx/pull/12804) arch/risc-v: introduce AIA support
* [#12843](https://github.com/apache/nuttx/pull/12843) arch/risc-v: add support for DC motor control on ESP32|C6|H2|
* [#12586](https://github.com/apache/nuttx/pull/12586) riscv_exception.c: Add missing comma in exception reasons array
* [#13408](https://github.com/apache/nuttx/pull/13408) riscv_mtimer: modify riscv_mtimer_current to reduce precision lost
* [#12643](https://github.com/apache/nuttx/pull/12643) riscv_tcbinfo: Fix register ordering for PC
* [#13564](https://github.com/apache/nuttx/pull/13564) riscv: add a return value to riscv_swint
* [#13561](https://github.com/apache/nuttx/pull/13561) riscv: g_current_regs is only used to determine if we are in irq
* [#12812](https://github.com/apache/nuttx/pull/12812) riscv: Fix fork() system call
* [#13354](https://github.com/apache/nuttx/pull/13354) riscv: Unify the extended context save/restore
* [#12554](https://github.com/apache/nuttx/pull/12554) riscv: Initial support for debug trigger module
* [#12559](https://github.com/apache/nuttx/pull/12559) riscv: Improve exception and irq mapping
* [#12809](https://github.com/apache/nuttx/pull/12809) riscv/debug: Add support for steppoint
* [#12819](https://github.com/apache/nuttx/pull/12819) riscv/espressif: Mark private data as static in esp_spi.c
* [#12861](https://github.com/apache/nuttx/pull/12861) riscv/fork: fix fp/gp handling
* [#12589](https://github.com/apache/nuttx/pull/12589) riscv/k230: revise canmv230:nsbi
* [#12677](https://github.com/apache/nuttx/pull/12677) riscv/k230: updates for nsh and pnsh
* [#12744](https://github.com/apache/nuttx/pull/12744) riscv/nsbi: fix k230 AMP confs
* [#12799](https://github.com/apache/nuttx/pull/12799) riscv/qemu-rv: skip reloading mhartid
* [#12807](https://github.com/apache/nuttx/pull/12807) riscv/qemu-rv: Add BUILD_PROTECTED target for rv-virt
* [#12944](https://github.com/apache/nuttx/pull/12944) riscv/qemu-rv: add RPTUN support
* [#12772](https://github.com/apache/nuttx/pull/12772) riscv/rv-virt: use RAM_START in ld.script
* [#12816](https://github.com/apache/nuttx/pull/12816) riscv/qemu-rv: add NuttSBI target for rv-virt
* [#12831](https://github.com/apache/nuttx/pull/12831) riscv/qemu-rv: revise PROTECTED mode
* [#12840](https://github.com/apache/nuttx/pull/12840) riscv/nsbi: fix up_udelay for rv32
* [#13510](https://github.com/apache/nuttx/pull/13510) risc-v: Add a new option to control exception reason
* [#12722](https://github.com/apache/nuttx/pull/12722) risc-v/bl808, sg2000: Configure MMU to cache Kernel Text, Data and Heap (T-Head C906)
* [#12571](https://github.com/apache/nuttx/pull/12571) risc-v/bl808: Add GPIO Driver
* [#12621](https://github.com/apache/nuttx/pull/12621) risc-v/bl808: Add GPADC character driver
* [#12663](https://github.com/apache/nuttx/pull/12663) risc-v/bl808: Add SPI driver
* [#12771](https://github.com/apache/nuttx/pull/12771) risc-v/bl808: Add watchdog driver
* [#12752](https://github.com/apache/nuttx/pull/12752) risc-v/bl808: Add timer driver
* [#12614](https://github.com/apache/nuttx/pull/12614) risc-v/ox64: Add LED Driver
* [#12762](https://github.com/apache/nuttx/pull/12762) risc-v/qemu-rv: Add LED Driver for QEMU RISC-V 32-bit and 64-bit
xtensa
* [#13223](https://github.com/apache/nuttx/pull/13223) Add spi slave dev to esp32 xtensa
* [#13225](https://github.com/apache/nuttx/pull/13225) espressif: Fix build with RTC
* [#13255](https://github.com/apache/nuttx/pull/13255) espressif: Fix deadlock in RT timer caused by critical section
* [#12560](https://github.com/apache/nuttx/pull/12560) espressif: Fix error while evaluating Wi-Fi task ID
* [#13368](https://github.com/apache/nuttx/pull/13368) espressif: Update external libraries to fix GPIO interrupt bug
* [#13236](https://github.com/apache/nuttx/pull/13236) espressif: Update HAL library reference to include debug assert
* [#13022](https://github.com/apache/nuttx/pull/13022) espressif: Update internal libraries reference
* [#12551](https://github.com/apache/nuttx/pull/12551) xtensa: add support for capture driver on ESP32 and ESP32|S3|
* [#12781](https://github.com/apache/nuttx/pull/12781) xtensa: add support for motor control driver
* [#12967](https://github.com/apache/nuttx/pull/12967) xtensa_cache:add up_get_cachesize api
* [#12865](https://github.com/apache/nuttx/pull/12865) xtensa/esp32: replace nxsig_usleep() with up_udelay()
* [#12750](https://github.com/apache/nuttx/pull/12750) xtensa/esp32s3: Add peripheral DMA request return value and optimize DMA initialization
* [#13277](https://github.com/apache/nuttx/pull/13277) xtensa/esp32s3: Add timing delay set interface for QSPI
* [#13291](https://github.com/apache/nuttx/pull/13291) xtensa/esp32s2: add WiFi support
* [#13454](https://github.com/apache/nuttx/pull/13454) xtensa/esp32s3: Adjust I2C clock timing
* [#12720](https://github.com/apache/nuttx/pull/12720) xtensa/esp32s3: Deinitialize ESP32-S3 QSPI GDMA engine.
* [#12871](https://github.com/apache/nuttx/pull/12871) xtensa/esp32s3: Update the rtc code to fix system blocking issue
* [#12919](https://github.com/apache/nuttx/pull/12919) xtensa/esp32s3: partition name duplicate and free
* [#12918](https://github.com/apache/nuttx/pull/12918) xtensa/esp32s3: reserve memory for a mutex struct depending on the OS
* [#12932](https://github.com/apache/nuttx/pull/12932) xtensa/esp32s3: Separate address and command flag for QSPI DMA transfer
* [#13165](https://github.com/apache/nuttx/pull/13165) xtensa/esp32s3/esp32s3_sdmmc.c: wait for command done event also on error response
x86_64
* [#13391](https://github.com/apache/nuttx/pull/13391) Add MSI/MSI-X support for intel64
* [#12583](https://github.com/apache/nuttx/pull/12583) arch/intel64: add cpu specific data and per-cpu interrupt stacks
* [#12803](https://github.com/apache/nuttx/pull/12803) arch/intel64: add support for HPET as system clock
* [#12588](https://github.com/apache/nuttx/pull/12588) arch/intel64: add support for inter-processor signaling
* [#12570](https://github.com/apache/nuttx/pull/12570) arch/intel64: get TSC frequency only when not provided from Kconfig
* [#12801](https://github.com/apache/nuttx/pull/12801) arch/intel64/irq.h: rename rdtsc macros
* [#13392](https://github.com/apache/nuttx/pull/13392) intel64: Improvements for HPET
* [#12567](https://github.com/apache/nuttx/pull/12567) arch/x86_64: addrenv should add offset only for RAM region
* [#12577](https://github.com/apache/nuttx/pull/12577) arch/x86_64/intel64/intel64_rtc.c: fix compilation
* [#12591](https://github.com/apache/nuttx/pull/12591) arch/x86_64: add SMP support
* [#13417](https://github.com/apache/nuttx/pull/13417) arch/x86_64: Add ARCH_INTEL64_DISABLE_CET
* [#13409](https://github.com/apache/nuttx/pull/13409) arch/x86_64: Add ARCH_X86_64_IDLE_NOP and ARCH_X86_64_IDLE_MWAIT
* [#13436](https://github.com/apache/nuttx/pull/13436) arch/x86_64: add basic support for R_X86_64_REX_GOTPCRELX relocation
* [#13422](https://github.com/apache/nuttx/pull/13422) arch/x86_64: Add elf32 multiboot1 wrapper for NuttX binary
* [#13313](https://github.com/apache/nuttx/pull/13313) arch/x86_64: convert all asm() to __asm__
* [#13317](https://github.com/apache/nuttx/pull/13317) arch/x86_64: Fix wrong RDTSCP implementation
* [#13316](https://github.com/apache/nuttx/pull/13316) arch/x86_64: Support QEMU PVH ELF loader
* [#13426](https://github.com/apache/nuttx/pull/13426) arch/x86_64/intel64: fix compilation errors in intel64_oneshot_lower.c
* [#12800](https://github.com/apache/nuttx/pull/12800) arch/x86_64/intel64/intel64_cpu.c: remove workaround for spin_lock
* [#13390](https://github.com/apache/nuttx/pull/13390) qemu-intel64: restore functionality of PCI test configs
* [#13315](https://github.com/apache/nuttx/pull/13315) qemu-intel64: simplify linker script
* [#12597](https://github.com/apache/nuttx/pull/12597) x86_64: add AVX support
* [#12613](https://github.com/apache/nuttx/pull/12613) x86_64: addrenv support
* [#12569](https://github.com/apache/nuttx/pull/12569) x86_64: hide --whole-archive behind Kconfig option
Driver Support
New Driver Support
* [#12829](https://github.com/apache/nuttx/pull/12829) Add amg88xx driver
* [#13396](https://github.com/apache/nuttx/pull/13396) Add Intel e1000 and igc support
* [#13393](https://github.com/apache/nuttx/pull/13393) Add support for 16550 compatible PCI serial cards
* [#12715](https://github.com/apache/nuttx/pull/12715) Add support for the Sensirion SHT4x temperature and humidity sensor
* [#12824](https://github.com/apache/nuttx/pull/12824) Add thermal framework
* [#11605](https://github.com/apache/nuttx/pull/11605) Coresight: add init coresight driver framework
* [#13082](https://github.com/apache/nuttx/pull/13082) driver/mem: add Mem Driver.
* [#12834](https://github.com/apache/nuttx/pull/12834) driver/ssd1680: Add support for 1.54 inch e-paper display
* [#12938](https://github.com/apache/nuttx/pull/12938) drivers/video: add goldfish gpu fb
* [#13470](https://github.com/apache/nuttx/pull/13470) drivers/pinctl: add pinctrl framework
* [#13471](https://github.com/apache/nuttx/pull/13471) drivers/goldfish-pipe: implement goldfish pipe
* [#13553](https://github.com/apache/nuttx/pull/13553) Pci ep framework
Drivers Improvements
* [#12998](https://github.com/apache/nuttx/pull/12998) [driver][bcm43xxx] reset tx_seq of sido-bus when ifdown wlan-if
* [#13154](https://github.com/apache/nuttx/pull/13154) can/sja1000: drop driver dependency on __builtin functions
* [#13524](https://github.com/apache/nuttx/pull/13524) can: Add g_ prefix to can_dlc_to_len and len_to_can_dlc.
* [#13141](https://github.com/apache/nuttx/pull/13141) can: Merge netpacket/can.h into nuttx/can.h
* [#12676](https://github.com/apache/nuttx/pull/12676) driver/net/lan9250: Add lan9250_ioctl and lan9250_uninitialize APIs
* [#13464](https://github.com/apache/nuttx/pull/13464) driver/ftl: Read the consecutive eraseblocks
* [#13320](https://github.com/apache/nuttx/pull/13320) driver/usbdev: support userspace to access ep0
* [#12641](https://github.com/apache/nuttx/pull/12641) drivers: add API for drivers early initialization
* [#13492](https://github.com/apache/nuttx/pull/13492) drivers: fix gcc14 errors for virtio
* [#13107](https://github.com/apache/nuttx/pull/13107) drivers/audio: fix samp rate conversion issue
* [#13323](https://github.com/apache/nuttx/pull/13323) drivers/bch: fix uint32 overflow issue
* [#12564](https://github.com/apache/nuttx/pull/12564) drivers/net/ksz9477: Add port mirroring support
* [#12765](https://github.com/apache/nuttx/pull/12765) drivers/drivers_initialize.c: check if only one console is selected
* [#13411](https://github.com/apache/nuttx/pull/13411) drivers/fb: add panbuffer clear ioctl
* [#13468](https://github.com/apache/nuttx/pull/13468) drivers/gpio: support poll gpio device and optimize code to save memory
* [#12976](https://github.com/apache/nuttx/pull/12976) drivers/input: enable touch/kbd/mouse for virtio input
* [#13060](https://github.com/apache/nuttx/pull/13060) drivers/modem/alt1250: Disable the PIN feature in ALT1250
* [#13327](https://github.com/apache/nuttx/pull/13327) drivers/mtd/bch: fix size_t overflow when offset > 4GB
* [#13480](https://github.com/apache/nuttx/pull/13480) drivers/pty: support pty write to kill signal, like serial driver
* [#12830](https://github.com/apache/nuttx/pull/12830) drivers/serial: Make the 16550 rx trigger level configurable
* [#13202](https://github.com/apache/nuttx/pull/13202) drivers/regmap: add exit function interface.
* [#13469](https://github.com/apache/nuttx/pull/13469) drivers/reset: support rpmsg reset
* [#13328](https://github.com/apache/nuttx/pull/13328) drivers/rwbuffer: Bug fix: Set nblocks 0 after direct using wrflush
* [#13434](https://github.com/apache/nuttx/pull/13434) drivers/serial
* [#13576](https://github.com/apache/nuttx/pull/13576) drivers/syslog: compile syslog_device.c if console/char/file channel enabled
* [#12857](https://github.com/apache/nuttx/pull/12857) drivers/touchscreen: add grab for touchscreen
* [#13481](https://github.com/apache/nuttx/pull/13481) drivers/usbdev: minor update for cdcacm
* [#12930](https://github.com/apache/nuttx/pull/12930) drivers/virtio-net: Support VIRTIO_F_ANY_LAYOUT
* [#13170](https://github.com/apache/nuttx/pull/13170) drivers: Fix goldfish events x64 unresponsive interrupt issue
* [#13531](https://github.com/apache/nuttx/pull/13531) Fix build error of drivers/sensors/usensor.c
* [#13325](https://github.com/apache/nuttx/pull/13325) Input/ff: new driver frameworks for vibrator(haptic)
* [#13078](https://github.com/apache/nuttx/pull/13078) video: fix warning & update sim camera
* [#12760](https://github.com/apache/nuttx/pull/12760) virtio/serial: initial CONSOLE support
* [#12971](https://github.com/apache/nuttx/pull/12971) mmcsd_sdio:Fix performing read and write in irq
* [#12949](https://github.com/apache/nuttx/pull/12949) mmcsd: add support of getting ext_csd reg data
* [#13157](https://github.com/apache/nuttx/pull/13157) mmcsd: add write ext csd reg support
* [#13528](https://github.com/apache/nuttx/pull/13528) mmcsd: fix a logic error
* [#13215](https://github.com/apache/nuttx/pull/13215) mmcsd: make a compatibility change for cmd12 and cmd23
* [#13380](https://github.com/apache/nuttx/pull/13380) mtd:ramtron MB85RS256B address length is 2
* [#13136](https://github.com/apache/nuttx/pull/13136) mtd:use part->name as partition name when CONFIG_MTD_PARTITION_NAMES set
* [#12796](https://github.com/apache/nuttx/pull/12796) mtd/Kconfig: fix W25_SLOWREAD menu item.
* [#13252](https://github.com/apache/nuttx/pull/13252) mtd/nvs: fix align size
* [#13219](https://github.com/apache/nuttx/pull/13219) nuttx/drivers:Modify errcode returned by relay_ioctl
* [#12848](https://github.com/apache/nuttx/pull/12848) Optimize iic and spi parts and add iic slave drivers
* [#13344](https://github.com/apache/nuttx/pull/13344) pci ivshmem related driveres support
* [#13337](https://github.com/apache/nuttx/pull/13337) Revert "Fix unwanted flush in the SPI slave driver"
* [#13251](https://github.com/apache/nuttx/pull/13251) rndis: correct usb descriptor
* [#13538](https://github.com/apache/nuttx/pull/13538) sensor:Fixed the problem of user information lag in cross-core communication "stublist".
* [#13539](https://github.com/apache/nuttx/pull/13539) sensor_rpmsg.c:Fix that "stub" will be created when local core only has subscribers.
* [#12927](https://github.com/apache/nuttx/pull/12927) serial/uart_16550: include stdint.h in uart_16550.h
* [#13383](https://github.com/apache/nuttx/pull/13383) serial/uart_16550: remove up_putc spinlock
* [#13384](https://github.com/apache/nuttx/pull/13384) serial/uart_pl011: default syslog needs to check flow control in up_putc
* [#13509](https://github.com/apache/nuttx/pull/13509) serial/pci_16550: make sure that interrupts are disabled during init
* [#13102](https://github.com/apache/nuttx/pull/13102) syslog_rpmsg: Ensure the syslog ept is ready when rpmsg_send
* [#13184](https://github.com/apache/nuttx/pull/13184) timer driver:support poll.
* [#13075](https://github.com/apache/nuttx/pull/13075) usb_cdcmbim: add mbim device driver
* [#13367](https://github.com/apache/nuttx/pull/13367) usbdev: Add fastboot boardctl
* [#12914](https://github.com/apache/nuttx/pull/12914) usbdev: add USB cdcncm device driver
* [#12745](https://github.com/apache/nuttx/pull/12745) usbdev: delete unsigned comparison with 0
* [#13216](https://github.com/apache/nuttx/pull/13216) usbdev: extend the usb req len to unit32_t
* [#13190](https://github.com/apache/nuttx/pull/13190) USB 3.0 device side suppor
Board Support
New Boards
* [#13248](https://github.com/apache/nuttx/pull/13248) arm: Add support for CSK6011A SOC and CSK6011A-NANO board
* [#11709](https://github.com/apache/nuttx/pull/11709) at32uc3a0: Initial work for SimpleMachines' Mizar32-A
* [#12813](https://github.com/apache/nuttx/pull/12813) boards/esp32s3: Add initial support to the ESP32-S3-Korvo-2 board
* [#13467](https://github.com/apache/nuttx/pull/13467) boards/esp32s3: add support to esp32s3-lhcbit board
Boards Improvements
* [#13532](https://github.com/apache/nuttx/pull/13532) [Bugfix]Kconfig:ensure compatibility between kconfig-frontend and kconfiglib in kernel build
* [#12698](https://github.com/apache/nuttx/pull/12698) Add defconfig to use the ws2812 driver
* [#12878](https://github.com/apache/nuttx/pull/12878) arm/stm32f103-minimum: Use common board MFRC522
* [#12922](https://github.com/apache/nuttx/pull/12922) arm64: Initial implementation of CONFIG_BUILD_KERNEL
* [#13376](https://github.com/apache/nuttx/pull/13376) arm64/Kconfig: Make the ARM64_PA/VA_BITS a true Kconfig variable
* [#12973](https://github.com/apache/nuttx/pull/12973) board/arm/rp2040/seeed-xiao-studio-rp2040 GPIO configuration
* [#12738](https://github.com/apache/nuttx/pull/12738) board/linum-stm32h753bi: Add support to external sdram
* [#12882](https://github.com/apache/nuttx/pull/12882) board/lm3s6965-ek: restore 128K kflash
* [#12699](https://github.com/apache/nuttx/pull/12699) board/stm32f401rc-rs485: Add support to Device Configuration over Telnet
* [#12737](https://github.com/apache/nuttx/pull/12737) board/stm32f401rc-rs485: Add support to MAX7219 8x8 LED Matrix
* [#13516](https://github.com/apache/nuttx/pull/13516) boards: Update EXAMPLES_SOTEST_DEVMINOR to EXAMPLES_SOTEST_DEVMINOR_MAX
* [#12743](https://github.com/apache/nuttx/pull/12743) boards/arm/rp2040: Userled configuration to Seeed-Stdio RP2040
* [#13142](https://github.com/apache/nuttx/pull/13142) boards/arm/stm32/stm32f4discovery: Add support to RFID MFRC522
* [#13440](https://github.com/apache/nuttx/pull/13440) boards/arm/stm32h7/stm32h745i-disco: Add RPTUN support
* [#12825](https://github.com/apache/nuttx/pull/12825) boards/armv5: Make ARMv5 boards work again
* [#12593](https://github.com/apache/nuttx/pull/12593) boards/stm32: DRV8825 driver
* [#12673](https://github.com/apache/nuttx/pull/12673) boards/esp32[c3|c6|h2|s2|s3]: Ignore etctmp in common board
* [#13124](https://github.com/apache/nuttx/pull/13124) boards/esp32s3_lan9250: deinitialize the ethernet device lan9250
* [#12716](https://github.com/apache/nuttx/pull/12716) boards/esp32s3: Increse the default stack size for usbnsh
* [#12763](https://github.com/apache/nuttx/pull/12763) boards/imx93-evk: add sdimage cleanup
* [#12876](https://github.com/apache/nuttx/pull/12876) boards/lm3s6965-ek: fix memory.ld for PROTECTED
* [#12598](https://github.com/apache/nuttx/pull/12598) boards/MIMXRT1020-EVK: Fix board I2C code to adapt to last IMXRT I2C/pi…
* [#13137](https://github.com/apache/nuttx/pull/13137) boards/risc-v/esp32c6/esp32c6-devkitm: Add support to RFID MFRC522
* [#12869](https://github.com/apache/nuttx/pull/12869) boards/rv-virt: unify RV32 config names
* [#13226](https://github.com/apache/nuttx/pull/13226) boards/sim: Defconfigs for nand and mnemofs
* [#12898](https://github.com/apache/nuttx/pull/12898) boards/xtensa/esp32s3: ESP32S3 Emmc Support
* [#13478](https://github.com/apache/nuttx/pull/13478) boardctl: add board control api to start slave core
* [#13273](https://github.com/apache/nuttx/pull/13273) boardcrtl: change BOARDCTL_TESTSET to BOARDIOC_SPINLOCK
* [#12747](https://github.com/apache/nuttx/pull/12747) Change nucleof429zi nsh defconfig
* [#13059](https://github.com/apache/nuttx/pull/13059) defconfig: add SYSTEM_TELNETD related config
* [#13334](https://github.com/apache/nuttx/pull/13334) esp32: fix a way to test a config
* [#13563](https://github.com/apache/nuttx/pull/13563) esp32s3: Fix faulty `esp32s3-devkit:stack` example
* [#13234](https://github.com/apache/nuttx/pull/13234) imx9_usdhc.c: Fix build error when CONFIG_ARM64_DCACHE_DISABLE=y
* [#12867](https://github.com/apache/nuttx/pull/12867) LTDC for Linum board
* [#12780](https://github.com/apache/nuttx/pull/12780) nrf9160-dk: disable FPU for modem example
* [#13476](https://github.com/apache/nuttx/pull/13476) nucleo-h745zi: fix potential bl jump to app failed issue
* [#13069](https://github.com/apache/nuttx/pull/13069) nucleo-l432kc: Revert the USART2 config to be use by virtual COM port
* [#12987](https://github.com/apache/nuttx/pull/12987) nuttx/boards:Uniform initialization format for init_array.
* [#13208](https://github.com/apache/nuttx/pull/13208) risc-v/bl808: Configure MMU to cache User Text, Data and Heap
* [#13199](https://github.com/apache/nuttx/pull/13199) risc-v/mmu: Configure T-Head MMU to cache User Text, Data and Heap
* [#12862](https://github.com/apache/nuttx/pull/12862) risc-v/qemu-rv: Add Build Config for leds64_rust
* [#13186](https://github.com/apache/nuttx/pull/13186) risc-v/qemu-rv: Add Build Config for leds64_zig
* [#12896](https://github.com/apache/nuttx/pull/12896) risc-v/qemu-rv: add cluster PLIC/CLINT configs
* [#12544](https://github.com/apache/nuttx/pull/12544) riscv/nuttsbi: add MTVAL argument
* [#12645](https://github.com/apache/nuttx/pull/12645) stm32h7/linum-stm32h753bi: add support to qencoder
* [#12739](https://github.com/apache/nuttx/pull/12739) stm32f777zit6-meadow: Add support for two USB CDC/ACM
* [#12637](https://github.com/apache/nuttx/pull/12637) Usbnsh to seed-xiao-rp2040 board
* [#12713](https://github.com/apache/nuttx/pull/12713) zynq_mpsoc/zcu111: add support for gpio and board auto led
* [#12806](https://github.com/apache/nuttx/pull/12806) zynq-mpsoc/zcu111: independent JTAG configs from normal nsh configs
* [#12797](https://github.com/apache/nuttx/pull/12797) w25c: add W25_DEBUG sub-menu config option and update debug traces.
File System
New FS
* [#13001](https://github.com/apache/nuttx/pull/13001) V9FS For NuttX
FS Improvements
* [#13514](https://github.com/apache/nuttx/pull/13514) add sched note for littlefs/romfs/rpmsgfs
* [#12863](https://github.com/apache/nuttx/pull/12863) Fix the location of tmpfs pwrite write and Fixed some code check warnings
* [#13500](https://github.com/apache/nuttx/pull/13500) fs.h: fix a comment in file_operations
* [#12532](https://github.com/apache/nuttx/pull/12532) fs: add backtrace to where file opens
* [#13150](https://github.com/apache/nuttx/pull/13150) fs: add fs_heap, support shm/tmpfs/pseudofile with indepent heap
* [#12587](https://github.com/apache/nuttx/pull/12587) Fs: backtrace tweak
* [#13512](https://github.com/apache/nuttx/pull/13512) fs: Dump the list of files when the file description runs out
* [#13194](https://github.com/apache/nuttx/pull/13194) fs: nfs: Fix nfsmount error
* [#12978](https://github.com/apache/nuttx/pull/12978) fs: Rename node with inode.
* [#12969](https://github.com/apache/nuttx/pull/12969) Fslock optimize
* [#12937](https://github.com/apache/nuttx/pull/12937) fs/mnemofs: Fix journal log rw issue, rw size issue
* [#12945](https://github.com/apache/nuttx/pull/12945) fs/hostfs: Replace strcpy with memcpy
* [#13443](https://github.com/apache/nuttx/pull/13443) fs_inode:Change the type of i_crefs to atomic_int
* [#13458](https://github.com/apache/nuttx/pull/13458) fs_dup2 bug fix, memleak
* [#13573](https://github.com/apache/nuttx/pull/13573) fs/chmod/fchmod/lchmod: only set permissions by mode_t and ignore othjer bits
* [#12931](https://github.com/apache/nuttx/pull/12931) fs/epoll: Optimize implementation details
* [#12615](https://github.com/apache/nuttx/pull/12615) fs/fat: Fix Fseek Bug When File Size Is Multiple of Cluster Size
* [#12548](https://github.com/apache/nuttx/pull/12548) fs/fat/fs_fat32.c Return EOF when reading past the end of the file.
* [#13521](https://github.com/apache/nuttx/pull/13521) fs/dump: correct SCHED_DUMP_ON_EXIT to DUMP_ON_EXIT
* [#12990](https://github.com/apache/nuttx/pull/12990) fs/mmap: Fix build warning with [-Wmaybe-uninitialized].
* [#13132](https://github.com/apache/nuttx/pull/13132) fs/procfs: Supports any number of thread displays
* [#13123](https://github.com/apache/nuttx/pull/13123) fs/shmfs:Avoid an integer overflow
* [#12790](https://github.com/apache/nuttx/pull/12790) fs/spiffs: Return OK on `spiffs_fstat` success
* [#13407](https://github.com/apache/nuttx/pull/13407) fs/mmap: Add MADV_HUGEPAGE definitions
* [#13406](https://github.com/apache/nuttx/pull/13406) fs/mmap: Ensure anonymous pages are initialized to zero
* [#12661](https://github.com/apache/nuttx/pull/12661) fs/mnemofs: Adds Block Allocator
* [#12668](https://github.com/apache/nuttx/pull/12668) fs/mnemofs: Add parent iterator and path methods.
* [#12680](https://github.com/apache/nuttx/pull/12680) fs/mnemofs: Add LRU and CTZ methods
* [#12683](https://github.com/apache/nuttx/pull/12683) fs/mnemofs: Add journal methods.
* [#12702](https://github.com/apache/nuttx/pull/12702) fs/mnemofs: Add master node and r/w methods
* [#12943](https://github.com/apache/nuttx/pull/12943) fs/mnemofs: Autoformat
* [#12808](https://github.com/apache/nuttx/pull/12808) fs/mnemofs: Refactoring path logic, direntry size bug fix, open free bug fix
* [#12658](https://github.com/apache/nuttx/pull/12658) fs/mnemofs: Setup and VFS methods
* [#13475](https://github.com/apache/nuttx/pull/13475) fs/mount: add ftl proxy to mount block filesystem on mtd device
* [#13258](https://github.com/apache/nuttx/pull/13258) fs/mq_open: revise comments
* [#13326](https://github.com/apache/nuttx/pull/13326) fs/files_extend: Bug Fix
* [#13331](https://github.com/apache/nuttx/pull/13331) fs/inode: using inode reference to indicate unlink and simply code
* [#13077](https://github.com/apache/nuttx/pull/13077) Fsnotify
* [#12942](https://github.com/apache/nuttx/pull/12942) Hostfs support get filepath by ioctl
* [#12817](https://github.com/apache/nuttx/pull/12817) procfs/meminfo: free delaylist before reporting
* [#13058](https://github.com/apache/nuttx/pull/13058) procfs/mempool: fix did not remove when pool not enabled
* [#13092](https://github.com/apache/nuttx/pull/13092) rpmsgfs: fix out of bounds access caused by data transmission farmat
* [#13063](https://github.com/apache/nuttx/pull/13063) rpmsgfs: set fs type to rpmsgfs when mount through rpmsgfs
* [#13348](https://github.com/apache/nuttx/pull/13348) smartfs procfs: fix double declare g_smartfs_operations
* [#12939](https://github.com/apache/nuttx/pull/12939) rpmsgfs_client:Fix error return exception
* [#12941](https://github.com/apache/nuttx/pull/12941) rpmsgfs: support filelock
* [#13098](https://github.com/apache/nuttx/pull/13098) tmpfs: old data was loaded when SEEK_SET beyond end of the file
* [#13490](https://github.com/apache/nuttx/pull/13490) vfs:fix a type mismatch issue and a typo
Networking
Improvements
* [#13385](https://github.com/apache/nuttx/pull/13385) Fix the bug that netlink receive wait does not hang up
* [#13053](https://github.com/apache/nuttx/pull/13053) icmp:add net_lock to protect icmp connection
* [#13336](https://github.com/apache/nuttx/pull/13336) local_socket: add SO_SNDBUF & SO_RCVBUF support
* [#13045](https://github.com/apache/nuttx/pull/13045) localsocket improvment
* [#12639](https://github.com/apache/nuttx/pull/12639) net: Enable ICMP by default if IPv4 is enabled
* [#13028](https://github.com/apache/nuttx/pull/13028) net_chksum.c:mod process of generating sum to solve checksum error
* [#12991](https://github.com/apache/nuttx/pull/12991) net/icmpv6/icmpv6_input.c: fix undefined build error
* [#13093](https://github.com/apache/nuttx/pull/13093) net/netdev: Add periodic log for netdev statistics
* [#12689](https://github.com/apache/nuttx/pull/12689) net/netfilter: fix windows compile error
* [#12688](https://github.com/apache/nuttx/pull/12688) net/pkt: correct PF_PACKET family sending errors
* [#12995](https://github.com/apache/nuttx/pull/12995) net/pkt: fix issue that set nonblock by fcntl does not take effect
* [#13010](https://github.com/apache/nuttx/pull/13010) net/pkt: fix raw socket send data length is insufficient
* [#13120](https://github.com/apache/nuttx/pull/13120) net/tcp_timer: fix tcp_timer idle loop and retransmission bug
* [#13051](https://github.com/apache/nuttx/pull/13051) net/tcp: reset the dupack counter.
* [#12899](https://github.com/apache/nuttx/pull/12899) net/tun: Remove unused variables in read & write
* [#13191](https://github.com/apache/nuttx/pull/13191) net/tun: Support changing carrier state of TUN/TAP
* [#13350](https://github.com/apache/nuttx/pull/13350) net/udp: Fixed the issue of sending ICMP error when the destination address is broadcast/multicast.
* [#13037](https://github.com/apache/nuttx/pull/13037) netdev_upperhalf: add polling mode support for tx/rx
* [#13046](https://github.com/apache/nuttx/pull/13046) netdev/ioctl: Setting log level to warning on SIOCGIFHWADDR failure
* [#13007](https://github.com/apache/nuttx/pull/13007) netdev/lower: Add reclaim callback and use it in virtio-net
* [#13343](https://github.com/apache/nuttx/pull/13343) netdev/statistics: Add bytes for netdev statistics
* [#13008](https://github.com/apache/nuttx/pull/13008) netdev/upper: Delay replied packets to prevent TX quota become negated
* [#12992](https://github.com/apache/nuttx/pull/12992) netinet/in.h: add macro definitions to resolve compilation errors
* [#12994](https://github.com/apache/nuttx/pull/12994) netlib/route: add length for add/del route-func to reduce caller stack usage
* [#13335](https://github.com/apache/nuttx/pull/13335) netdb: Make NETDB_DNSSERVER_NAMESERVERS effective for NETDB_RESOLVCONF
* [#13038](https://github.com/apache/nuttx/pull/13038) netdb: netdb code support ffmpeg rtsp(getaddrinfo & getnameinfo)
* [#13049](https://github.com/apache/nuttx/pull/13049) Modify the IPV6 address acquisition method and the gateway settings.
* [#13125](https://github.com/apache/nuttx/pull/13125) modify for offload checksum and add macro with tcp/icmp/icmpv6/igmp checksum
* [#13026](https://github.com/apache/nuttx/pull/13026) modify the type of the ipv6 parameters to solve runtime error
* [#13029](https://github.com/apache/nuttx/pull/13029) solve Problem of tcp parameter calculation exceeding the boundary
* [#13156](https://github.com/apache/nuttx/pull/13156) sys/socket: implement compiler agnostic sockaddr_storage alignment
* [#13158](https://github.com/apache/nuttx/pull/13158) tcp_close.c:when tcp socket stays in TCP_FIN_WAIT_1 or TCP_FIN_WAIT_2,calling tcp_close_eventhandler releases received packets
* [#12999](https://github.com/apache/nuttx/pull/12999) tcp_input: if tcp->req > recvreq, send ack only when state is TCP_ESTABLISHED
Unsorted
Improvements
* [#13448](https://github.com/apache/nuttx/pull/13448) [Bug-Fix] Resource leaks
* [#13100](https://github.com/apache/nuttx/pull/13100) [BugFix]Command "critmon" error
* [#13002](https://github.com/apache/nuttx/pull/13002) 12K sample rate support
* [#13486](https://github.com/apache/nuttx/pull/13486) Accelerate access to interrupt status
* [#12980](https://github.com/apache/nuttx/pull/12980) add fb_vsync_pollnotify
* [#12959](https://github.com/apache/nuttx/pull/12959) Add goldfish events
* [#12951](https://github.com/apache/nuttx/pull/12951) Add irq disable func
* [#13130](https://github.com/apache/nuttx/pull/13130) Add memory pressure monitoring
* [#13089](https://github.com/apache/nuttx/pull/13089) api:add lib_realpath function
* [#12947](https://github.com/apache/nuttx/pull/12947) assert: add compile_assert macro
* [#13020](https://github.com/apache/nuttx/pull/13020) assert: check COMPILE_TIME_ASSERT before define
* [#13087](https://github.com/apache/nuttx/pull/13087) Audio upstream
* [#13044](https://github.com/apache/nuttx/pull/13044) Basic Atomic for NuttX
* [#13099](https://github.com/apache/nuttx/pull/13099) bch: alloc bch->buffer when offset not aligned
* [#13513](https://github.com/apache/nuttx/pull/13513) BCH: Add readonly configuration for BCH devices
* [#12853](https://github.com/apache/nuttx/pull/12853) binfmt/elf_loadfile: Set sh_addr even if SHF_ALLOC == 0
* [#12965](https://github.com/apache/nuttx/pull/12965) boot: fix potential bl jump to app failed issue
* [#13094](https://github.com/apache/nuttx/pull/13094) Bugfix hcreate
* [#13300](https://github.com/apache/nuttx/pull/13300) can: Before we use pstate, we should check if it is NULL.
* [#13570](https://github.com/apache/nuttx/pull/13570) can: Add g_ prefix to can_dlc_to_len and len_to_can_dlc.
* [#13048](https://github.com/apache/nuttx/pull/13048) can: CAN code optimization
* [#12656](https://github.com/apache/nuttx/pull/12656) can: fixes and tweaks for CAN FD support
* [#13126](https://github.com/apache/nuttx/pull/13126) Capture adds the function of edges counting
* [#12934](https://github.com/apache/nuttx/pull/12934) clk: fix reg operation not compatible with 64bit
* [#13210](https://github.com/apache/nuttx/pull/13210) cdcacm: align cdcacm_epconfigure function parameters
* [#13189](https://github.com/apache/nuttx/pull/13189) Controlling rgb led bp
* [#12889](https://github.com/apache/nuttx/pull/12889) Coredump enhancement, optimized prompt statements
* [#13474](https://github.com/apache/nuttx/pull/13474) coredump: just save latest core file
* [#12958](https://github.com/apache/nuttx/pull/12958) coredump: refine coredump info analyse
* [#13066](https://github.com/apache/nuttx/pull/13066) crypto: import the ability to clone session
* [#13109](https://github.com/apache/nuttx/pull/13109) crypto/bn: Provide software algorithms to calculate inverse elements and greatest common divisor
* [#13431](https://github.com/apache/nuttx/pull/13431) crypto/rsa: add exp mod in software crypto
* [#12970](https://github.com/apache/nuttx/pull/12970) Disable clean/flush optimization in case of SMP restriction
* [#12777](https://github.com/apache/nuttx/pull/12777) dlfcn: Add stub for dladdr
* [#12779](https://github.com/apache/nuttx/pull/12779) dlfcn: Fix indent issue in lib_dlclose.c
* [#13159](https://github.com/apache/nuttx/pull/13159) dynamically create work queues
* [#13489](https://github.com/apache/nuttx/pull/13489) enable O_CLOEXEC explicitly to avoid fd leak
* [#13118](https://github.com/apache/nuttx/pull/13118) Enhance ASSERT
* [#13424](https://github.com/apache/nuttx/pull/13424) Enhance Kasan
* [#13559](https://github.com/apache/nuttx/pull/13559) Enhance Kasan's global variable out of bounds detection
* [#13388](https://github.com/apache/nuttx/pull/13388) Expose IPTOS_xxx to the application layer
* [#12963](https://github.com/apache/nuttx/pull/12963) fdcheck: fix race condition in fdcheck
* [#13096](https://github.com/apache/nuttx/pull/13096) fb:add select overlay FB_NO_OVERLAY
* [#13296](https://github.com/apache/nuttx/pull/13296) filep Reference count
* [#12578](https://github.com/apache/nuttx/pull/12578) Fix allocated memory test
* [#13461](https://github.com/apache/nuttx/pull/13461) Fix dev_mem related
* [#13555](https://github.com/apache/nuttx/pull/13555) Fix greater-than-or-equal-to-zero issue
* [#12741](https://github.com/apache/nuttx/pull/12741) Fix pin LTDC_B0, should be PJ12 instead of PF0
* [#13129](https://github.com/apache/nuttx/pull/13129) Fix task_setup race condition
* [#13054](https://github.com/apache/nuttx/pull/13054) Fix the compilation warnings
* [#12955](https://github.com/apache/nuttx/pull/12955) fix the potential bug of putwc, fgetwc, ungetwc, wcsstr, fputwc
* [#13095](https://github.com/apache/nuttx/pull/13095) fix:uart_rpmsg_dmareceive
* [#13477](https://github.com/apache/nuttx/pull/13477) ftl: should pre-allocate eblock for car case
* [#13000](https://github.com/apache/nuttx/pull/13000) getrlimit: implement RLIMIT_STACK return limit stack size
* [#13459](https://github.com/apache/nuttx/pull/13459) GNSS: Add support for constellation, measurement, clock and geofence
* [#13504](https://github.com/apache/nuttx/pull/13504) goldfish:add kernel mode support
* [#13330](https://github.com/apache/nuttx/pull/13330) group/filelist: add reference to protect filelist of group
* [#13554](https://github.com/apache/nuttx/pull/13554) i2c: Optimize access to private data
* [#13233](https://github.com/apache/nuttx/pull/13233) Increase the chance for _assert to work early in the boot
* [#13306](https://github.com/apache/nuttx/pull/13306) init: add OSINIT_TASK_READY
* [#13228](https://github.com/apache/nuttx/pull/13228) inline restore_critical_section and add parameters to restore_critical_section
* [#12981](https://github.com/apache/nuttx/pull/12981) input: fix goldfish input and lvgl input device name mismatch problem
* [#13108](https://github.com/apache/nuttx/pull/13108) input: fix touchevent race condition
* [#13073](https://github.com/apache/nuttx/pull/13073) inode: call inode_release when close success
* [#13198](https://github.com/apache/nuttx/pull/13198) Introduce new PCI framework
* [#13442](https://github.com/apache/nuttx/pull/13442) input/ff: modify FF_MAX to support 64-bit machine
* [#13387](https://github.com/apache/nuttx/pull/13387) ipfrag: fix warnig
* [#13163](https://github.com/apache/nuttx/pull/13163) ipfrag: remove assert for actual product reasons
* [#13012](https://github.com/apache/nuttx/pull/13012) irq: add [enter|leave]_critical_section_nonirq
* [#13018](https://github.com/apache/nuttx/pull/13018) irq: add isr thread
* [#13242](https://github.com/apache/nuttx/pull/13242) irq: dynaminc create g_irqmap
* [#13256](https://github.com/apache/nuttx/pull/13256) irq: irq with the same priority share the same wqueue
* [#12595](https://github.com/apache/nuttx/pull/12595) irq: remove g_cpu_nestcount in restore_critical_section
* [#12935](https://github.com/apache/nuttx/pull/12935) irq: remove restore_critical_section in irq
* [#12596](https://github.com/apache/nuttx/pull/12596) irq: remove restore_critical_section in irq
* [#13369](https://github.com/apache/nuttx/pull/13369) irq: simplify code by using OSINIT_TASK_READY
* [#13119](https://github.com/apache/nuttx/pull/13119) Kasan enhance
* [#12893](https://github.com/apache/nuttx/pull/12893) kasan:fix bug write error is recognized as read error
* [#13133](https://github.com/apache/nuttx/pull/13133) Keep the log level consistent with assert
* [#12590](https://github.com/apache/nuttx/pull/12590) libmetal/atomic: enable 64-bit atomic by toolchain builtin flags
* [#13543](https://github.com/apache/nuttx/pull/13543) lilygo_tbeam_lora_gps/gps: Enable GNSSUTILS_MINMEA_LIB for EXAMPLES_GPS
* [#13549](https://github.com/apache/nuttx/pull/13549) lzf:Add macro judgment to header file reference.
* [#12929](https://github.com/apache/nuttx/pull/12929) make/disassembly: generate disassembly file
* [#13179](https://github.com/apache/nuttx/pull/13179) memset:optimizate speed.
* [#12985](https://github.com/apache/nuttx/pull/12985) minidumpserver: fix parsing bug
* [#13287](https://github.com/apache/nuttx/pull/13287) mksymtab.c support for structure
* [#13452](https://github.com/apache/nuttx/pull/13452) modify BUILD_LOADABLE to MODULES which backwards-compatible Kernel
* [#12968](https://github.com/apache/nuttx/pull/12968) MPU update
* [#13460](https://github.com/apache/nuttx/pull/13460) New Rpmsg Transports: Rpmsg Port SPI, Rpmsg Port Uart and Rpmsg Router Transport Support
* [#13104](https://github.com/apache/nuttx/pull/13104) nxmutex api enhance
* [#13047](https://github.com/apache/nuttx/pull/13047) nuttx-names.in:add popen & pclose assign to glibc interface
* [#13006](https://github.com/apache/nuttx/pull/13006) nuttx/audio: add AUDIOIOC_GETPOSITION ioctl
* [#13005](https://github.com/apache/nuttx/pull/13005) nuttx/audio: add offload buffer size config
* [#13340](https://github.com/apache/nuttx/pull/13340) nuttx/crypto: export asymmetric algorithms about ecdh and ecc256 via /dev/crypto
* [#13138](https://github.com/apache/nuttx/pull/13138) nuttx/crypto: fix wrong implementation in crypto module
* [#13173](https://github.com/apache/nuttx/pull/13173) nuttx/crypto: support new algorithm about crc32 and aes-cmac
* [#13084](https://github.com/apache/nuttx/pull/13084) nuttx/crypto: support poly1305 and ripemd160 algorithm
* [#12986](https://github.com/apache/nuttx/pull/12986) nuttx/note: fix missing the last character when printing custom labels.
* [#12730](https://github.com/apache/nuttx/pull/12730) NVS: fix align size
* [#13187](https://github.com/apache/nuttx/pull/13187) nvs: modify nvs block size and block numbers
* [#12601](https://github.com/apache/nuttx/pull/12601) queue: inline queue
* [#13435](https://github.com/apache/nuttx/pull/13435) pci/pci_uio_ivshmem: pci uio ivshmem msix interrupt support
* [#13178](https://github.com/apache/nuttx/pull/13178) pl031:change mktime to timegm.
* [#13057](https://github.com/apache/nuttx/pull/13057) pm_runtime: fix missing header
* [#13064](https://github.com/apache/nuttx/pull/13064) pm_activity: fix deadlock with spinlock and critcal_section
* [#13055](https://github.com/apache/nuttx/pull/13055) pm: add pm_idle, up_idle only handle pm state execution
* [#12933](https://github.com/apache/nuttx/pull/12933) pm: add debug_assert for cb register/unregister api
* [#13072](https://github.com/apache/nuttx/pull/13072) pm: update document, add pm_idle interface for not-smp case
* [#13279](https://github.com/apache/nuttx/pull/13279) poll: fix thread_cancel() caused poll used after free
* [#13074](https://github.com/apache/nuttx/pull/13074) Private requirement for wapi
* [#13168](https://github.com/apache/nuttx/pull/13168) protected build: userspace threads will unexpectly work in privileged mode after syscall
* [#13153](https://github.com/apache/nuttx/pull/13153) pty: use mutex to protect alloc minor
* [#13295](https://github.com/apache/nuttx/pull/13295) psram_cache_init: remove cosmetic differences between PRO/APP
* [#13438](https://github.com/apache/nuttx/pull/13438) ramlog bug fix
* [#13283](https://github.com/apache/nuttx/pull/13283) Refactor wdog module
* [#12891](https://github.com/apache/nuttx/pull/12891) Reimplemented the mempool traversal function and fixed some existing bugs in the mempool
* [#13463](https://github.com/apache/nuttx/pull/13463) rename, strtoul & sscanf
* [#13309](https://github.com/apache/nuttx/pull/13309) Restore ASSERT/VERIFY semantics
* [#13485](https://github.com/apache/nuttx/pull/13485) Revert "irq: add [enter|leave]_critical_section_nonirq"
* [#12607](https://github.com/apache/nuttx/pull/12607) Revert "irq: remove restore_critical_section in irq"
* [#13432](https://github.com/apache/nuttx/pull/13432) Rpmsg VirtIO Transport support and releated patches
* [#13183](https://github.com/apache/nuttx/pull/13183) rpmsg_rtc:Update g_basetime from rpmsg.
* [#13169](https://github.com/apache/nuttx/pull/13169) rpmsg.c: move onceinit judge logic to common part
* [#13404](https://github.com/apache/nuttx/pull/13404) rpmsgblk: split multi_cmd only when it is too large to be placed into…
* [#13465](https://github.com/apache/nuttx/pull/13465) rpmsgdev: Support server export and oneway polling
* [#13172](https://github.com/apache/nuttx/pull/13172) rptun.c: fix rptun.c format follow rpmsg virtio
* [#13203](https://github.com/apache/nuttx/pull/13203) rtc alarm:fix doesn't call nxsig_notification
* [#13515](https://github.com/apache/nuttx/pull/13515) shm: remove useless macro
* [#13280](https://github.com/apache/nuttx/pull/13280) smp: smp call handler add up_cpu_paused_[save|restore]
* [#13405](https://github.com/apache/nuttx/pull/13405) spi_slave: change length to nwords
* [#12599](https://github.com/apache/nuttx/pull/12599) spin_lock: inline spin_lock
* [#12837](https://github.com/apache/nuttx/pull/12837) spinlock: add support of spin_trylock_irqsave()
* [#12836](https://github.com/apache/nuttx/pull/12836) spinlock: inline no trace implement to remove duplicate logic
* [#13272](https://github.com/apache/nuttx/pull/13272) spinlock: spin_initialize should add memory barrier
* [#13457](https://github.com/apache/nuttx/pull/13457) stack recored bug fix
* [#13386](https://github.com/apache/nuttx/pull/13386) stream/syslograw: remove support for iob buffer in syslog
* [#13511](https://github.com/apache/nuttx/pull/13511) Support msync
* [#13196](https://github.com/apache/nuttx/pull/13196) support rss/arfs with device
* [#13106](https://github.com/apache/nuttx/pull/13106) suppress libasan checks
* [#13031](https://github.com/apache/nuttx/pull/13031) Synchronize the modification of the WiFi problems in QEMU.
* [#13113](https://github.com/apache/nuttx/pull/13113) Swift embedded support
* [#12820](https://github.com/apache/nuttx/pull/12820) task_fork.c: Fix vfork for BUILD_KERNEL
* [#12754](https://github.com/apache/nuttx/pull/12754) up_backtrace: fix maybe backtrace the exiting thread
* [#13293](https://github.com/apache/nuttx/pull/13293) Update clock speed
* [#13410](https://github.com/apache/nuttx/pull/13410) Update posix timer
* [#12611](https://github.com/apache/nuttx/pull/12611) Upgrade Segger SystemView to V3.54
* [#12705](https://github.com/apache/nuttx/pull/12705) V4l2m2m openh264 x264 to builtin
* [#13030](https://github.com/apache/nuttx/pull/13030) video/fb: changed circbuf_write assert to warning
* [#13433](https://github.com/apache/nuttx/pull/13433) VirtIO PCI Transport Support for NuttX
* [#13338](https://github.com/apache/nuttx/pull/13338) virtio-blk: support called read/write in interrupt
* [#13437](https://github.com/apache/nuttx/pull/13437) wqueue bug fix
* [#13241](https://github.com/apache/nuttx/pull/13241) wqueue: add interface work_queue_priority_wq and work_queue_priority

View file

@ -1,3 +1,35 @@
==========================
IO Expander Device Drivers
==========================
- ``include/nuttx/ioexpander/ioexpander.h`` and ``include/nuttx/ioexpander/gpio.h``.
All structures and APIs needed to work with ioexpander drivers are provided in
this header file.
- ``struct ioexpander_ops_s``. Each ioexpand device driver must implement
an instance of ``struct ioexpander_ops_s``. That structure defines a
call table with the methods, and we also provide macros to help access methods.
- we also provide method ``gpio_lower_half`` to make ioexpander compatible with normal gpio.
- **Binding ioexpander Drivers**. ioexpander drivers are not normally directly
accessed by user code, we should always get lower level drivers, for example I2C,
and map extended gpio feature same asa normal gpio. See for example,
``int nrf52_sx1509_initialize(void)``
in ``boards/arm/nrf52/thingy52/src/nrf52_sx1509.c``. In general, the binding
sequence is:
#. Get an instance of ``struct i2c_master_s`` from the
hardware-specific I2C device driver, and
#. Provide that instance and configurations to the ioexpander initialization method
to get the ``struct ioexpander_dev_s`` ioe device instance.
#. Then use ioe device instance to do ioexpander operations, or use ``gpio_lower_half``
to make ioexpand compatible with normal gpio.
- **Examples**: ``drivers/ioexpander/pca9555.c``,
``drivers/input/aw86225.c``,
``drivers/analog/lmp92001.c``,
``drivers/ioexpander/ioe_rpmsg.c``,
``boards/sim/sim/sim/src/sim_ioexpander.c``,
``boards/arm/nrf52/thingy52/src/nrf52_sx1509.c`` etc.

View file

@ -17,7 +17,7 @@ Supported Segger drivers:
Segger SystemView
=================
Steps to enable SystemView support:
1. Steps to enable SystemView support:
#. Make sure your architecture supports a high-performance counter.
In most cases it will be:
@ -62,3 +62,14 @@ Steps to enable SystemView support:
In case SystemView returns buffer overflow errors, you should increase
``CONFIG_NOTE_RTT_BUFFER_SIZE_UP``.
2. Use SystemView for heap tracing:
Refer to example configuration at ``stm32f429i-disco/configs/systemview``.
Make sure that ``CONFIG_SCHED_INSTRUMENTATION_HEAP`` is enabled.
Example of screenshot from SystemView:
.. image:: sysview.png
:width: 800px
:align: center

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 KiB

View file

@ -1,6 +1,6 @@
=========================================
High Performance, Zero Latency Interrupts
=========================================
=====================================================================
High Performance: Zero Latency Interrupts, Maskable nested interrupts
=====================================================================
Generic Interrupt Handling
==========================
@ -111,6 +111,62 @@ between the high priority interrupt handler and *PendSV* interrupt
handler. A detailed discussion of that custom logic is beyond the
scope of this Wiki page.
The following table shows the priority levels of the Cortex-M family:
.. code-block::
IRQ type Priority
Dataabort 0x00
High prio IRQ1 0x20 (Zero-latency interrupt)
High prio IRQ2 0x30 (Can't call OS API in ISR)
SVC 0x70
Disable IRQ 0x80
(critical-section)
Low prio IRQ 0xB0
PendSV 0xE0
As you can see, the priority levels of the zero-latency interrupts can
beyond the critical section and SVC.
But High prio IRQ can't call OS API.
Maskable Nested Interrupts
==========================
The ARM Cortex-M family supports a feature called *BASEPRI* that can be
used to disable interrupts at a priority level below a certain level.
This feature can be used to support maskable nested interrupts.
Maskable nested interrupts differ from zero-latency interrupts in
that they obey the interrupt masking mechanisms of the system.
For example, setting the BASEPRI register to a specific threshold will
block all interrupts of a lower or equal priority.
However, high-priority interrupts (such as Non-Maskable Interrupts
or zero-latency interrupts) are unaffected by these masks.
This is useful when you have a high-priority interrupt that needs to
be able to interrupt the system, but you also have lower-priority
interrupts that you want to be able to mask.
The following table shows the priority levels of the Cortex-M family:
.. code-block::
IRQ type Priority
Dataabort 0x00
SVC 0x70
Disable IRQ 0x80
(critical-section)
High prio IRQ1 0x90 (Maskable nested interrupt)
High prio IRQ2 0xA0 (Can call OS API in ISR)
Low prio IRQ 0xB0
PendSV 0xE0
As you can see, the priority levels of the maskable nested interrupts
are between the critical section and the low-priority interrupts.
And High prio IRQ can call OS API in ISR.
Nested Interrupt Handling
=========================

View file

@ -695,7 +695,8 @@ MCAN1 Loopback Test
Device Drivers -> CAN Driver support
CONFIG_CAN=y # Enable the upper-half CAN driver
CONFIG_CAN_FIFOSIZE=8
CONFIG_CAN_TXFIFOSIZE=8
CONFIG_CAN_RXFIFOSIZE=8
CONFIG_CAN_NPENDINGRTR=4
System Type -> SAMV7 Peripheral Selections

View file

@ -1288,7 +1288,8 @@ MCAN1 Loopback Test
Device Drivers -> CAN Driver support
CONFIG_CAN=y # Enable the upper-half CAN driver
CONFIG_CAN_FIFOSIZE=8
CONFIG_CAN_TXFIFOSIZE=8
CONFIG_CAN_RXFIFOSIZE=8
CONFIG_CAN_NPENDINGRTR=4
System Type -> SAMV7 Peripheral Selections

View file

@ -385,7 +385,11 @@ Cloudctrl-specific Configuration Options
CONFIG_CAN - Enables CAN support (one or both of CONFIG_STM32_CAN1 or
CONFIG_STM32_CAN2 must also be defined)
CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.
Default: 4

View file

@ -501,7 +501,11 @@ M3 Wildfire-specific Configuration Options
CONFIG_STM32_CAN2 must also be defined)
CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default
Standard 11-bit IDs.
CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.
Default: 4

View file

@ -282,7 +282,11 @@ HY-Mini specific Configuration Options
CONFIG_STM32_CAN2 must also be defined)
CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default
Standard 11-bit IDs.
CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.
Default: 4

View file

@ -395,7 +395,11 @@ Shenzhou-specific Configuration Options
CONFIG_CAN - Enables CAN support (one or both of CONFIG_STM32_CAN1 or
CONFIG_STM32_CAN2 must also be defined)
CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.
Default: 4

View file

@ -444,7 +444,11 @@ STM3210E-EVAL-specific Configuration Options
CONFIG_STM32_CAN2 must also be defined)
CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default
Standard 11-bit IDs.
CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.
Default: 4

View file

@ -231,7 +231,11 @@ STM32 Tiny - specific Configuration Options
CONFIG_STM32_CAN2 must also be defined)
CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default
Standard 11-bit IDs.
CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.
Default: 4

View file

@ -740,7 +740,11 @@ STM32F103 Minimum - specific Configuration Options
CONFIG_STM32_CAN2 must also be defined)
CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default
Standard 11-bit IDs.
CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.
Default: 4

View file

@ -93,7 +93,12 @@ CAN
- CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID.
Default Standard 11-bit IDs.
- CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
- CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
- CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
- CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.

View file

@ -140,7 +140,12 @@ CAN character device
- CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default
Standard 11-bit IDs.
- CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
- CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
- CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
- CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.

View file

@ -144,7 +144,12 @@ CAN
- CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default
Standard 11-bit IDs.
- CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages.
- CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
- CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
- CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests.

View file

@ -189,7 +189,13 @@ CAN
- CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs.
- CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. Default: 8
- CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer
of CAN messages.
Default: 8
- CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer
of CAN messages.
Default: 8
- CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. Default: 4

View file

@ -670,6 +670,14 @@ config ARCH_USE_DATA_HEAP
This option enables architecture-specific memory allocator
for dynamic data loading.
config ARCH_USE_SEPARATED_SECTION
bool "Enable separate section allocation for dynamic loading"
default n
depends on ARCH_USE_TEXT_HEAP || ARCH_USE_DATA_HEAP
---help---
This option enables loading different sections into different
memory areas, allowing for different speeds.
menuconfig ARCH_ADDRENV
bool "Address environments"
default n

View file

@ -103,6 +103,23 @@ config ARCH_CHIP_C5471
---help---
TI TMS320 C5471, A180, or DA180 (ARM7TDMI)
config ARCH_CHIP_CSK6
bool "LISTEANAI CSK6 6001A/6011B/6012"
select ARCH_HAVE_MPU
select ARCH_HAVE_FETCHADD
select ARCH_HAVE_I2CRESET
select ARCH_HAVE_HEAPCHECK
select ARCH_HAVE_PROGMEM
select ARCH_HAVE_SPI_BITORDER
select ARCH_HAVE_TICKLESS
select ARCH_HAVE_TIMEKEEPING
select ARM_HAVE_MPU_UNIFIED
select ARMV8M_HAVE_STACKCHECK
select ARCH_HAVE_ADJTIME
select ARCH_CORTEXM33
---help---
LISTEANAI CSK6 architectures (ARM Cortex-M33).
config ARCH_CHIP_DM320
bool "TMS320 DM320"
select ARCH_ARM926EJS
@ -441,23 +458,6 @@ config ARCH_CHIP_STM32
---help---
STMicro STM32 architectures (ARM Cortex-M3/4).
config ARCH_CHIP_CSK6
bool "STMicro STM6 6001A/6011B/6012"
select ARCH_HAVE_MPU
select ARCH_HAVE_FETCHADD
select ARCH_HAVE_I2CRESET
select ARCH_HAVE_HEAPCHECK
select ARCH_HAVE_PROGMEM
select ARCH_HAVE_SPI_BITORDER
select ARCH_HAVE_TICKLESS
select ARCH_HAVE_TIMEKEEPING
select ARM_HAVE_MPU_UNIFIED
select ARMV8M_HAVE_STACKCHECK
select ARCH_HAVE_ADJTIME
select ARCH_CORTEXM33
---help---
LISTEANAI CSK6architectures (ARM Cortex-M33).
config ARCH_CHIP_STM32F0
bool "STMicro STM32 F0"
select ARCH_CORTEXM0
@ -817,6 +817,7 @@ config ARCH_CORTEXM0
select ARM_THUMB
select ARCH_ARMV6M
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_IRQTRIGGER
select ARCH_HAVE_RAMVECTORS
select ARCH_HAVE_RESET
select ARCH_HAVE_HARDFAULT_DEBUG

View file

@ -127,12 +127,6 @@
#ifndef __ASSEMBLY__
struct xcptcontext
{
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of the context used during
* signal processing.
*/

View file

@ -152,12 +152,6 @@ struct xcpt_syscall_s
struct xcptcontext
{
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of the context used during
* signal processing.
*/

View file

@ -253,12 +253,6 @@ struct xcpt_syscall_s
struct xcptcontext
{
/* The following function pointer is non-zero if there are pending signals
* to be processed.
*/
void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of the context used during
* signal processing.
*/

View file

@ -212,12 +212,6 @@ struct xcpt_syscall_s
struct xcptcontext
{
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of the context used during
* signal processing.
*/
@ -446,7 +440,7 @@ static inline void up_irq_enable(void)
{
/* In this case, we are always retaining or lowering the priority value */
setbasepri(NVIC_SYSH_PRIORITY_MIN);
setbasepri(0);
__asm__ __volatile__ ("\tcpsie i\n");
}

View file

@ -253,12 +253,6 @@ struct xcpt_syscall_s
struct xcptcontext
{
/* The following function pointer is non-zero if there are pending signals
* to be processed.
*/
void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of the context used during
* signal processing.
*/

View file

@ -223,12 +223,6 @@ struct xcpt_syscall_s
struct xcptcontext
{
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of the context used during
* signal processing.
*/
@ -419,7 +413,7 @@ static inline void up_irq_enable(void)
{
/* In this case, we are always retaining or lowering the priority value */
setbasepri(NVIC_SYSH_PRIORITY_MIN);
setbasepri(0);
__asm__ __volatile__ ("\tcpsie i\n");
}

View file

@ -253,12 +253,6 @@ struct xcpt_syscall_s
struct xcptcontext
{
/* The following function pointer is non-zero if there are pending signals
* to be processed.
*/
void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of the context used during
* signal processing.
*/

View file

@ -100,19 +100,17 @@ typedef enum
typedef struct
{
struct timespec ts; /* timestamp */
fault_flags_t flags; /* What is in the dump */
uintptr_t current_regs; /* Used to validate the dump */
int lineno; /* __LINE__ to up_assert */
pid_t pid; /* Process ID */
uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */
crash_stack_t stacks; /* Stack info */
#if CONFIG_TASK_NAME_SIZE > 0
char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL
* terminator) */
#endif
char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in
* __FILE__ to up_assert */
struct timespec ts; /* timestamp */
fault_flags_t flags; /* What is in the dump */
uintptr_t current_regs; /* Used to validate the dump */
int lineno; /* __LINE__ to up_assert */
pid_t pid; /* Process ID */
uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */
crash_stack_t stacks; /* Stack info */
char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL
* terminator) */
char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in
* __FILE__ to up_assert */
} info_t;
typedef struct

View file

@ -158,7 +158,7 @@
#define CXD56_IRQ_SPH13 (CXD56_IRQ_EXTINT+93) /* SPH13 IRQ number */
#define CXD56_IRQ_SPH14 (CXD56_IRQ_EXTINT+94) /* SPH14 IRQ number */
#define CXD56_IRQ_SPH15 (CXD56_IRQ_EXTINT+95) /* SPH15 IRQ number */
#define CXD56_IRQ_SW_INT (CXD56_IRQ_EXTINT+96) /* SW_INT IRQ number */
#define CXD56_IRQ_SMP_CALL (CXD56_IRQ_EXTINT+96) /* SMP_CALL IRQ number */
#define CXD56_IRQ_TIMER0 (CXD56_IRQ_EXTINT+97) /* TIMER0 IRQ number */
#define CXD56_IRQ_TIMER1 (CXD56_IRQ_EXTINT+98) /* TIMER1 IRQ number */
#define CXD56_IRQ_TIMER2 (CXD56_IRQ_EXTINT+99) /* TIMER2 IRQ number */

View file

@ -59,11 +59,11 @@
#define LC823450_IRQ_INTERRUPTS (16) /* Vector number of the first external interrupt */
#define LC823450_IRQ_CTXM3_00 (LC823450_IRQ_INTERRUPTS+0) /* 16: CortexM3_00 interrupt */
#define LC823450_IRQ_CTXM3_01 (LC823450_IRQ_INTERRUPTS+1) /* 17: CortexM3_01 interrupt */
#define LC823450_IRQ_SMP_CALL_01 (LC823450_IRQ_INTERRUPTS+1) /* 17: CortexM3_01 interrupt */
#define LC823450_IRQ_CTXM3_02 (LC823450_IRQ_INTERRUPTS+2) /* 18: CortexM3_02 interrupt */
#define LC823450_IRQ_CTXM3_03 (LC823450_IRQ_INTERRUPTS+3) /* 19: CortexM3_03 interrupt */
#define LC823450_IRQ_CTXM3_10 (LC823450_IRQ_INTERRUPTS+4) /* 20: CortexM3_00 interrupt */
#define LC823450_IRQ_CTXM3_11 (LC823450_IRQ_INTERRUPTS+5) /* 21: CortexM3_01 interrupt */
#define LC823450_IRQ_SMP_CALL_11 (LC823450_IRQ_INTERRUPTS+5) /* 21: CortexM3_01 interrupt */
#define LC823450_IRQ_CTXM3_12 (LC823450_IRQ_INTERRUPTS+6) /* 22: CortexM3_02 interrupt */
#define LC823450_IRQ_CTXM3_13 (LC823450_IRQ_INTERRUPTS+7) /* 23: CortexM3_03 interrupt */
#define LC823450_IRQ_LPDSP0 (LC823450_IRQ_INTERRUPTS+8) /* 24: LPDSP0 interrupt */

View file

@ -75,8 +75,8 @@
#define RP2040_DMA_IRQ_1 (RP2040_IRQ_EXTINT+12)
#define RP2040_IO_IRQ_BANK0 (RP2040_IRQ_EXTINT+13)
#define RP2040_IO_IRQ_QSPI (RP2040_IRQ_EXTINT+14)
#define RP2040_SIO_IRQ_PROC0 (RP2040_IRQ_EXTINT+15)
#define RP2040_SIO_IRQ_PROC1 (RP2040_IRQ_EXTINT+16)
#define RP2040_SMP_CALL_PROC0 (RP2040_IRQ_EXTINT+15)
#define RP2040_SMP_CALL_PROC1 (RP2040_IRQ_EXTINT+16)
#define RP2040_CLOCKS_IRQ (RP2040_IRQ_EXTINT+17)
#define RP2040_SPI0_IRQ (RP2040_IRQ_EXTINT+18)
#define RP2040_SPI1_IRQ (RP2040_IRQ_EXTINT+19)

View file

@ -114,7 +114,7 @@
#define SAM_IRQ_TC5 (SAM_IRQ_EXTINT+SAM_PID_TC5) /* PID 28: Timer Counter 5 */
#define SAM_IRQ_ADC (SAM_IRQ_EXTINT+SAM_PID_ADC) /* PID 29: Analog To Digital Converter */
#define SAM_IRQ_ARM (SAM_IRQ_EXTINT+SAM_PID_ARM) /* PID 30: FPU signals (only on CM4P1 core): FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC */
#define SAM_IRQ_IPC0 (SAM_IRQ_EXTINT+SAM_PID_IPC0) /* PID 31: Interprocessor communication 0 */
#define SAM_IRQ_SMP_CALL0 (SAM_IRQ_EXTINT+SAM_PID_IPC0) /* PID 31: Interprocessor communication 0 */
#define SAM_IRQ_SLCDC (SAM_IRQ_EXTINT+SAM_PID_SLCDC) /* PID 32: Segment LCD Controller */
#define SAM_IRQ_TRNG (SAM_IRQ_EXTINT+SAM_PID_TRNG) /* PID 33: True Random Generator */
#define SAM_IRQ_ICM (SAM_IRQ_EXTINT+SAM_PID_ICM) /* PID 34: Integrity Check Module */
@ -122,7 +122,7 @@
#define SAM_IRQ_AES (SAM_IRQ_EXTINT+SAM_PID_AES) /* PID 36: Advanced Enhanced Standard */
#define SAM_IRQ_PIOC (SAM_IRQ_EXTINT+SAM_PID_PIOC) /* PID 37: Parallel I/O Controller C */
#define SAM_IRQ_UART1 (SAM_IRQ_EXTINT+SAM_PID_UART1) /* PID 38: Universal Asynchronous Receiver Transmitter 1 */
#define SAM_IRQ_IPC1 (SAM_IRQ_EXTINT+SAM_PID_IPC1) /* PID 39: Interprocessor communication 1 */
#define SAM_IRQ_SMP_CALL1 (SAM_IRQ_EXTINT+SAM_PID_IPC1) /* PID 39: Interprocessor communication 1 */
#define SAM_IRQ_RESERVED_40 (SAM_IRQ_EXTINT+SAM_PID_RESERVED_40) /* PID 40: Reserved */
#define SAM_IRQ_PWM (SAM_IRQ_EXTINT+SAM_PID_PWM) /* PID 41: Pulse Width Modulation */
#define SAM_IRQ_SRAM (SAM_IRQ_EXTINT+SAM_PID_SRAM) /* PID 42: SRAM1 (I/D Code bus of CM4P1), SRAM2 (Systembus of CM4P1) */

View file

@ -158,12 +158,6 @@
#ifndef __ASSEMBLY__
struct xcptcontext
{
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved register array pointer used during
* signal processing.
*/

View file

@ -58,6 +58,8 @@
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
@ -71,6 +73,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
*/
up_set_current_regs(regs);
tcb->xcp.regs = regs;
/* Acknowledge the interrupt */
@ -79,6 +82,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
/* Deliver the IRQ */
irq_dispatch(irq, regs);
tcb = this_task();
/* Check for a context switch. If a context switch occurred, then
* current_regs will have a different value than it did on entry. If an
@ -87,7 +91,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* returning from the interrupt.
*/
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
@ -99,14 +103,19 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
addrenv_switch(NULL);
#endif
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
g_running_tasks[this_cpu()] = this_task();
g_running_tasks[this_cpu()] = tcb;
regs = up_current_regs();
regs = tcb->xcp.regs;
}
/* Set current_regs to NULL to indicate that we are no longer in an

View file

@ -75,125 +75,61 @@
*
****************************************************************************/
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
void up_schedule_sigaction(struct tcb_s *tcb)
{
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb, this_task(),
this_task()->xcp.regs);
/* Refuse to handle nested signal actions */
/* First, handle some special cases when the signal is
* being delivered to the currently executing task.
*/
if (!tcb->xcp.sigdeliver)
if (tcb == this_task() && !up_interrupt_context())
{
tcb->xcp.sigdeliver = sigdeliver;
/* In this case just deliver the signal now. */
/* First, handle some special cases when the signal is
* being delivered to the currently executing task.
(tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}
/* Otherwise, we are (1) signaling a task is not running
* from an interrupt handler or (2) we are not in an
* interrupt handler and the running task is signalling
* some non-running task.
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
/* Save the current register context location */
if (tcb == this_task())
{
/* CASE 1: We are not in an interrupt handler and
* a task is signalling itself for some reason.
*/
tcb->xcp.saved_regs = tcb->xcp.regs;
if (!up_current_regs())
{
/* In this case just deliver the signal now. */
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: We are in an interrupt handler AND the
* interrupted task is the same as the one that
* must receive the signal, then we will have to modify
* the return state as well as the state in the TCB.
*
* Hmmm... there looks like a latent bug here: The following
* logic would fail in the strange case where we are in an
* interrupt handler, the thread is signalling itself, but
* a context switch to another task has occurred so that
* current_regs does not refer to the thread of this_task()!
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
*/
/* And make sure that the saved context in the TCB
* is the same as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs() +
XCPTCONTEXT_REGS);
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
up_current_regs()[REG_CPSR] = PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT;
#ifdef CONFIG_ARM_THUMB
up_current_regs()[REG_CPSR] |= PSR_T_BIT;
#endif
}
}
/* Otherwise, we are (1) signaling a task is not running
* from an interrupt handler or (2) we are not in an
* interrupt handler and the running task is signalling
* some non-running task.
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
/* Save the current register context location */
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT;
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT;
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
}
}
}

View file

@ -59,8 +59,8 @@ void arm_sigdeliver(void)
board_autoled_on(LED_SIGNAL);
sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
rtcb, rtcb->sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->sigdeliver != NULL);
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
@ -72,7 +72,7 @@ void arm_sigdeliver(void)
/* Deliver the signal */
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
(rtcb->sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -92,7 +92,7 @@ void arm_sigdeliver(void)
* could be modified by a hostile program.
*/
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
rtcb->sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View file

@ -54,7 +54,7 @@
uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb;
struct tcb_s *tcb = this_task();
uint32_t cmd;
int cpu;
@ -66,6 +66,7 @@ uint32_t *arm_syscall(uint32_t *regs)
* current_regs is also used to manage interrupt level context switches.
*/
tcb->xcp.regs = regs;
up_set_current_regs(regs);
/* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */
@ -94,7 +95,7 @@ uint32_t *arm_syscall(uint32_t *regs)
* set will determine the restored context.
*/
up_set_current_regs((uint32_t *)regs[REG_R1]);
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
DEBUGASSERT(up_current_regs());
}
break;
@ -133,15 +134,9 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}
#ifdef CONFIG_ARCH_ADDRENV
/* Check for a context switch. If a context switch occurred, then
* current_regs will have a different value than it did on entry. If an
* interrupt level context switch has occurred, then establish the correct
* address environment before returning from the interrupt.
*/
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new
@ -149,13 +144,8 @@ uint32_t *arm_syscall(uint32_t *regs)
*/
addrenv_switch(NULL);
}
#endif
/* Restore the cpu lock */
if (regs != up_current_regs())
{
/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
*/
@ -181,5 +171,5 @@ uint32_t *arm_syscall(uint32_t *regs)
* SYS_context_switch system call.
*/
return regs;
return tcb->xcp.regs;
}

View file

@ -29,6 +29,7 @@ set(SRCS
arm_svcall.c
arm_systemreset.c
arm_tcbinfo.c
arm_trigger_irq.c
arm_vectors.c)
if(CONFIG_DEBUG_FEATURES)

View file

@ -27,6 +27,7 @@ CMN_ASRCS += arm_exception.S arm_saveusercontext.S
CMN_CSRCS += arm_cpuinfo.c arm_doirq.c arm_hardfault.c arm_initialstate.c
CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_svcall.c
CMN_CSRCS += arm_systemreset.c arm_tcbinfo.c arm_vectors.c
CMN_CSRCS += arm_trigger_irq.c
ifeq ($(CONFIG_DEBUG_FEATURES),y)
CMN_CSRCS += arm_dumpnvic.c

View file

@ -35,30 +35,60 @@
#include "arm_internal.h"
#include "exc_return.h"
#include "nvic.h"
/****************************************************************************
* Public Functions
****************************************************************************/
void exception_direct(void)
{
int irq = getipsr();
arm_ack_irq(irq);
irq_dispatch(irq, NULL);
if (g_running_tasks[this_cpu()] != this_task())
{
up_trigger_irq(NVIC_IRQ_PENDSV, 0);
}
}
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
up_set_current_regs(regs);
}
/* Acknowledge the interrupt */
arm_ack_irq(irq);
/* Deliver the IRQ */
/* Set current regs for crash dump */
irq_dispatch(irq, regs);
up_set_current_regs(regs);
if (irq == NVIC_IRQ_PENDSV)
{
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
/* Dispatch the PendSV interrupt */
irq_dispatch(irq, regs);
#endif
up_irq_save();
g_running_tasks[this_cpu()]->xcp.regs = regs;
}
else
{
/* Dispatch irq */
tcb->xcp.regs = regs;
irq_dispatch(irq, regs);
}
/* If a context switch occurred while processing the interrupt then
* current_regs may have change value. If we return any value different
@ -66,27 +96,27 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* switch occurred during interrupt processing.
*/
if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
/* Restore the cpu lock */
tcb = this_task();
if (regs != up_current_regs())
{
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
/* Update scheduler parameters */
g_running_tasks[this_cpu()] = this_task();
regs = up_current_regs();
}
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_resume_scheduler(tcb);
/* Update the current_regs to NULL. */
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
up_set_current_regs(NULL);
}
g_running_tasks[this_cpu()] = tcb;
regs = tcb->xcp.regs;
#endif
/* Clear current regs */
up_set_current_regs(NULL);
board_autoled_off(LED_INIRQ);
return regs;
}

View file

@ -78,333 +78,60 @@
*
****************************************************************************/
#ifndef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
void up_schedule_sigaction(struct tcb_s *tcb)
{
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
DEBUGASSERT(tcb != NULL && sigdeliver != NULL);
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb, this_task(),
this_task()->xcp.regs);
/* Refuse to handle nested signal actions */
/* First, handle some special cases when the signal is
* being delivered to the currently executing task.
*/
if (tcb->xcp.sigdeliver == NULL)
if (tcb == this_task() && !up_interrupt_context())
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to the currently executing task.
/* In this case just deliver the signal now.
* REVISIT: Signal handle will run in a critical section!
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb == this_task())
{
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (!up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handle will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: We are in an interrupt handler AND the interrupted
* task is the same as the one that must receive the signal, then
* we will have to modify the return state as well as the state in
* the TCB.
*/
else
{
/* Save the return PC, CPSR and PRIMASK
* registers (and perhaps also the LR). These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* And make sure that the saved context in the TCB is the same
* as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs() +
XCPTCONTEXT_REGS);
/* Then set up to vector to the trampoline with interrupts
* disabled. The kernel-space trampoline must run in
* privileged thread mode.
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
up_current_regs()[REG_PRIMASK] = 1;
up_current_regs()[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
up_current_regs()[REG_LR] = EXC_RETURN_THREAD;
up_current_regs()[REG_EXC_RETURN] = EXC_RETURN_THREAD;
up_current_regs()[REG_CONTROL] = getcontrol() &
~CONTROL_NPRIV;
#endif
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling* some non-running task.
(tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
else
{
/* Save the return PC, CPSR and PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
/* Save the current register context location */
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
}
#endif /* !CONFIG_SMP */
#ifdef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
int cpu;
int me;
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
/* Refuse to handle nested signal actions */
if (!tcb->xcp.sigdeliver)
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to task that is currently executing on any CPU.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb->task_state == TSTATE_TASK_RUNNING)
{
me = this_cpu();
cpu = tcb->cpu;
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (cpu == me && !up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/
else
{
/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/
if (cpu != me)
{
/* Pause the CPU */
up_cpu_pause(cpu);
/* Now tcb on the other CPU can be accessed safely */
/* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode
* to be here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
else
{
/* tcb is running on the same CPU */
/* Save the return PC, CPSR and either the BASEPRI or
* PRIMASK registers (and perhaps also the LR). These
* will be restored by the signal trampoline after the
* signal has been delivered.
*/
/* And make sure that the saved context in the TCB is the
* same as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs()
+ XCPTCONTEXT_REGS);
/* Then set up vector to the trampoline with interrupts
* disabled. The kernel-space trampoline must run in
* privileged thread mode.
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
up_current_regs()[REG_PRIMASK] = 1;
up_current_regs()[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
up_current_regs()[REG_LR] = EXC_RETURN_THREAD;
up_current_regs()[REG_CONTROL] = getcontrol() &
~CONTROL_NPRIV;
#endif
}
/* NOTE: If the task runs on another CPU(cpu), adjusting
* global IRQ controls will be done in the pause handler
* on the CPU(cpu) by taking a critical section.
* If the task is scheduled on this CPU(me), do nothing
* because this CPU already took a critical section
*/
/* RESUME the other CPU if it was PAUSED */
if (cpu != me)
{
up_cpu_resume(cpu);
}
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling some other non-running task.
*/
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
}
#endif /* CONFIG_SMP */

View file

@ -68,8 +68,8 @@ void arm_sigdeliver(void)
board_autoled_on(LED_SIGNAL);
sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
rtcb, rtcb->sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->sigdeliver != NULL);
retry:
#ifdef CONFIG_SMP
@ -101,7 +101,7 @@ retry:
/* Deliver the signal */
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
(rtcb->sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -148,7 +148,7 @@ retry:
* could be modified by a hostile program.
*/
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
rtcb->sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of
* execution.

View file

@ -117,10 +117,10 @@ static void dispatch_syscall(void)
int arm_svcall(int irq, void *context, void *arg)
{
struct tcb_s *tcb = this_task();
uint32_t *regs = (uint32_t *)context;
uint32_t cmd;
DEBUGASSERT(regs && regs == up_current_regs());
cmd = regs[REG_R0];
/* The SVCall software interrupt is called with R0 = system call command
@ -167,7 +167,7 @@ int arm_svcall(int irq, void *context, void *arg)
case SYS_restore_context:
{
DEBUGASSERT(regs[REG_R1] != 0);
up_set_current_regs((uint32_t *)regs[REG_R1]);
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
}
break;
@ -192,7 +192,7 @@ int arm_svcall(int irq, void *context, void *arg)
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
up_set_current_regs((uint32_t *)regs[REG_R2]);
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
}
break;
@ -450,23 +450,20 @@ int arm_svcall(int irq, void *context, void *arg)
# ifndef CONFIG_DEBUG_SVCALL
if (cmd > SYS_switch_context)
# else
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
# endif
{
regs = (uint32_t *)tcb->xcp.regs;
svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
up_current_regs()[REG_R0], up_current_regs()[REG_R1],
up_current_regs()[REG_R2], up_current_regs()[REG_R3],
up_current_regs()[REG_R4], up_current_regs()[REG_R5],
up_current_regs()[REG_R6], up_current_regs()[REG_R7]);
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
up_current_regs()[REG_R8], up_current_regs()[REG_R9],
up_current_regs()[REG_R10], up_current_regs()[REG_R11],
up_current_regs()[REG_R12], up_current_regs()[REG_R13],
up_current_regs()[REG_R14], up_current_regs()[REG_R15]);
svcinfo(" PSR: %08x PRIMASK: %08x EXC_RETURN: %08x\n",
up_current_regs()[REG_XPSR], up_current_regs()[REG_PRIMASK],
up_current_regs()[REG_EXC_RETURN]);
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
regs[REG_XPSR], regs[REG_EXC_RETURN], regs[REG_CONTROL]);
}
# ifdef CONFIG_DEBUG_SVCALL
else

View file

@ -0,0 +1,87 @@
/****************************************************************************
* arch/arm/src/armv6-m/arm_trigger_irq.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/arch.h>
#include <arch/irq.h>
#include "arm_internal.h"
#include "nvic.h"
#ifdef CONFIG_ARCH_HAVE_IRQTRIGGER
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_trigger_irq
*
* Description:
* Trigger an IRQ by software.
*
****************************************************************************/
void up_trigger_irq(int irq, cpu_set_t cpuset)
{
uint32_t pend_bit = 0;
DEBUGASSERT(irq >= NVIC_IRQ_NMI && irq < NR_IRQS);
if (irq >= NVIC_IRQ_FIRST)
{
putreg32(irq - NVIC_IRQ_FIRST, ARMV6M_NVIC2_BASE);
}
else
{
switch (irq)
{
case NVIC_IRQ_PENDSV:
pend_bit = SYSCON_ICSR_PENDSVSET;
break;
case NVIC_IRQ_NMI:
pend_bit = SYSCON_ICSR_NMIPENDSET;
break;
case NVIC_IRQ_SYSTICK:
pend_bit = SYSCON_ICSR_PENDSTSET;
break;
default:
break;
}
if (pend_bit)
{
modifyreg32(ARMV6M_SYSCON_ICSR, 0, pend_bit);
}
}
}
#endif /* CONFIG_ARCH_HAVE_IRQTRIGGER */

View file

@ -45,6 +45,8 @@
#include "chip.h"
#include "arm_internal.h"
#include "ram_vectors.h"
#include "nvic.h"
/****************************************************************************
* Pre-processor Definitions
@ -81,6 +83,7 @@ static void start(void)
/* Common exception entrypoint */
extern void exception_common(void);
extern void exception_direct(void);
/****************************************************************************
* Public data
@ -92,7 +95,7 @@ extern void exception_common(void);
* As all exceptions (interrupts) are routed via exception_common, we just
* need to fill this array with pointers to it.
*
* Note that the [ ... ] designated initialiser is a GCC extension.
* Note that the [ ... ] designated initializer is a GCC extension.
*/
const void * const _vectors[] locate_data(".vectors") =
@ -107,5 +110,7 @@ const void * const _vectors[] locate_data(".vectors") =
/* Vectors 2 - n point directly at the generic handler */
[2 ... (15 + ARMV6M_PERIPHERAL_INTERRUPTS)] = exception_common
[2 ... NVIC_IRQ_PENDSV] = &exception_common,
[(NVIC_IRQ_PENDSV + 1) ... (15 + ARMV6M_PERIPHERAL_INTERRUPTS)]
= &exception_direct
};

View file

@ -32,6 +32,31 @@
* Pre-processor Definitions
****************************************************************************/
/* Exception/interrupt vector numbers ***************************************/
/* Vector 0: Reset stack
* pointer value
*/
/* Vector 1: Reset */
#define NVIC_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */
#define NVIC_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */
#define NVIC_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */
#define NVIC_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */
#define NVIC_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */
/* Vectors 7-10: Reserved */
#define NVIC_IRQ_SVCALL (11) /* Vector 11: SVC call */
#define NVIC_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */
/* Vector 13: Reserved */
#define NVIC_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */
#define NVIC_IRQ_SYSTICK (15) /* Vector 15: System tick */
/* External interrupts (vectors >= 16).
* These definitions are chip-specific
*/
#define NVIC_IRQ_FIRST (16) /* Vector number of the first interrupt */
/* Base addresses ***********************************************************/
#define ARMV6M_SYSCON1_BASE 0xe000e008 /* 0xe000e008-0xe000e00f System Control Block */

View file

@ -52,6 +52,10 @@ if(CONFIG_ARCH_PERF_EVENTS)
list(APPEND SRCS arm_perf.c)
endif()
if(CONFIG_ARMV7A_GICv2M)
list(APPEND SRCS arm_gicv2m.c)
endif()
if(CONFIG_ARMV7A_HAVE_PTM)
list(APPEND SRCS arm_timer.c)
endif()
@ -105,7 +109,7 @@ if(CONFIG_ARCH_FPU)
endif()
if(CONFIG_SMP)
list(APPEND SRCS arm_cpustart.c arm_cpupause.c arm_cpuidlestack.c arm_scu.c)
list(APPEND SRCS arm_cpustart.c arm_smpcall.c arm_cpuidlestack.c arm_scu.c)
endif()
if(CONFIG_ARCH_HAVE_PSCI)

View file

@ -24,6 +24,17 @@ config ARMV7A_GIC_EOIMODE
Enable GICC_CTLR.EOImode, this will separates the priority drop and interrupt
deactivation operations.
config ARMV7A_GICV2_LEGACY_IRQ0
int "pci legacy irq0 default val"
default 35
---help---
The qemu pci lagacy irq0 default is 35. -1 mean disable
config ARMV7A_GICv2M
bool "gic support msi irq"
depends on PCI_MSIX
default n
endif # ARMV7A_HAVE_GICv2
config ARMV7A_HAVE_GTM

View file

@ -47,7 +47,11 @@ CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c
CMN_CSRCS += arm_syscall.c arm_tcbinfo.c arm_undefinedinsn.c
CMN_CSRCS += arm_perf.c cp15_cacheops.c
ifeq ($(CONFIG_ARMV7A_HAVE_PTM), y)
ifeq ($(CONFIG_ARMV7A_GICv2M),y)
CMN_CSRCS += arm_gicv2m.c
endif
ifeq ($(CONFIG_ARMV7A_HAVE_PTM),y)
CMN_CSRCS += arm_timer.c
endif
@ -90,7 +94,7 @@ ifeq ($(CONFIG_ARCH_FPU),y)
endif
ifeq ($(CONFIG_SMP),y)
CMN_CSRCS += arm_cpustart.c arm_cpupause.c arm_cpuidlestack.c
CMN_CSRCS += arm_cpustart.c arm_smpcall.c arm_cpuidlestack.c
CMN_CSRCS += arm_scu.c
endif

View file

@ -1,381 +0,0 @@
/****************************************************************************
* arch/arm/src/armv7-a/arm_cpupause.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include <nuttx/spinlock.h>
#include <nuttx/sched_note.h>
#include "arm_internal.h"
#include "gic.h"
#include "sched/sched.h"
#ifdef CONFIG_SMP
/****************************************************************************
* Private Data
****************************************************************************/
/* These spinlocks are used in the SMP configuration in order to implement
* up_cpu_pause(). The protocol for CPUn to pause CPUm is as follows
*
* 1. The up_cpu_pause() implementation on CPUn locks both g_cpu_wait[m]
* and g_cpu_paused[m]. CPUn then waits spinning on g_cpu_paused[m].
* 2. CPUm receives the interrupt it (1) unlocks g_cpu_paused[m] and
* (2) locks g_cpu_wait[m]. The first unblocks CPUn and the second
* blocks CPUm in the interrupt handler.
*
* When CPUm resumes, CPUn unlocks g_cpu_wait[m] and the interrupt handler
* on CPUm continues. CPUm must, of course, also then unlock g_cpu_wait[m]
* so that it will be ready for the next pause operation.
*/
static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS];
static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS];
static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS];
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_cpu_pausereq
*
* Description:
* Return true if a pause request is pending for this CPU.
*
* Input Parameters:
* cpu - The index of the CPU to be queried
*
* Returned Value:
* true = a pause request is pending.
* false = no pasue request is pending.
*
****************************************************************************/
bool up_cpu_pausereq(int cpu)
{
return spin_is_locked(&g_cpu_paused[cpu]);
}
/****************************************************************************
* Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
* executed from interrupt handling logic within the architecture-specific
* However, it is sometimes necessary to perform the pending
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
* Input Parameters:
* None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
* the nature of the failure is returned.
*
****************************************************************************/
int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
/* Update scheduler parameters */
nxsched_suspend_scheduler(tcb);
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we are paused */
sched_note_cpu_paused(tcb);
#endif
/* Save the current context at current_regs into the TCB at the head
* of the assigned task list for this CPU.
*/
arm_savestate(tcb->xcp.regs);
return OK;
}
/****************************************************************************
* Name: up_cpu_paused
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
* executed from interrupt handling logic within the architecture-specific
* However, it is sometimes necessary to perform the pending
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
* This function performs the following operations:
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It waits on a spinlock, then
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
* Input Parameters:
* cpu - The index of the CPU to be paused
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
* the nature of the failure is returned.
*
****************************************************************************/
int up_cpu_paused(int cpu)
{
/* Release the g_cpu_paused spinlock to synchronize with the
* requesting CPU.
*/
spin_unlock(&g_cpu_paused[cpu]);
/* Ensure the CPU has been resumed to avoid causing a deadlock */
spin_lock(&g_cpu_resumed[cpu]);
/* Wait for the spinlock to be released. The requesting CPU will release
* the spinlock when the CPU is resumed.
*/
spin_lock(&g_cpu_wait[cpu]);
spin_unlock(&g_cpu_wait[cpu]);
spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
/****************************************************************************
* Name: up_cpu_paused_restore
*
* Description:
* Restore the state of the CPU after it was paused via up_cpu_pause(),
* and resume normal tasking.
*
* Input Parameters:
* None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
* the nature of the failure is returned.
*
****************************************************************************/
int up_cpu_paused_restore(void)
{
struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
sched_note_cpu_resumed(tcb);
#endif
/* Reset scheduler parameters */
nxsched_resume_scheduler(tcb);
/* Then switch contexts. Any necessary address environment changes
* will be made when the interrupt returns.
*/
arm_restorestate(tcb->xcp.regs);
return OK;
}
/****************************************************************************
* Name: arm_pause_handler
*
* Description:
* This is the handler for SGI2. It performs the following operations:
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It waits on a spinlock, then
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
* Input Parameters:
* Standard interrupt handling
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int arm_pause_handler(int irq, void *context, void *arg)
{
int cpu = this_cpu();
/* Check for false alarms. Such false could occur as a consequence of
* some deadlock breaking logic that might have already serviced the SG2
* interrupt by calling up_cpu_paused(). If the pause event has already
* been processed then g_cpu_paused[cpu] will not be locked.
*/
if (up_cpu_pausereq(cpu))
{
/* NOTE: The following enter_critical_section() will call
* up_cpu_paused() to process a pause request to break a deadlock
* because the caller held a critical section. Once up_cpu_paused()
* finished, the caller will proceed and release the g_cpu_irqlock.
* Then this CPU will acquire g_cpu_irqlock in the function.
*/
irqstate_t flags = enter_critical_section();
/* NOTE: the pause request should not exist here */
DEBUGVERIFY(!up_cpu_pausereq(cpu));
leave_critical_section(flags);
}
return OK;
}
/****************************************************************************
* Name: up_cpu_pause
*
* Description:
* Save the state of the current task at the head of the
* g_assignedtasks[cpu] task list and then pause task execution on the
* CPU.
*
* This function is called by the OS when the logic executing on one CPU
* needs to modify the state of the g_assignedtasks[cpu] list for another
* CPU.
*
* Input Parameters:
* cpu - The index of the CPU to be stopped
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int up_cpu_pause(int cpu)
{
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the pause event */
sched_note_cpu_pause(this_task(), cpu);
#endif
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2
* handler from returning until up_cpu_resume() is called; g_cpu_paused
* is a handshake that will prefent this function from returning until
* the CPU is actually paused.
* Note that we might spin before getting g_cpu_wait, this just means that
* the other CPU still hasn't finished responding to the previous resume
* request.
*/
DEBUGASSERT(!spin_is_locked(&g_cpu_paused[cpu]));
spin_lock(&g_cpu_wait[cpu]);
spin_lock(&g_cpu_paused[cpu]);
/* Execute SGI2 */
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
/* Wait for the other CPU to unlock g_cpu_paused meaning that
* it is fully paused and ready for up_cpu_resume();
*/
spin_lock(&g_cpu_paused[cpu]);
spin_unlock(&g_cpu_paused[cpu]);
/* On successful return g_cpu_wait will be locked, the other CPU will be
* spinning on g_cpu_wait and will not continue until g_cpu_resume() is
* called. g_cpu_paused will be unlocked in any case.
*/
return OK;
}
/****************************************************************************
* Name: up_cpu_resume
*
* Description:
* Restart the cpu after it was paused via up_cpu_pause(), restoring the
* state of the task at the head of the g_assignedtasks[cpu] list, and
* resume normal tasking.
*
* This function is called after up_cpu_pause in order resume operation of
* the CPU after modifying its g_assignedtasks[cpu] list.
*
* Input Parameters:
* cpu - The index of the CPU being re-started.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int up_cpu_resume(int cpu)
{
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the resume event */
sched_note_cpu_resume(this_task(), cpu);
#endif
/* Release the spinlock. Releasing the spinlock will cause the SGI2
* handler on 'cpu' to continue and return from interrupt to the newly
* established thread.
*/
DEBUGASSERT(spin_is_locked(&g_cpu_wait[cpu]) &&
!spin_is_locked(&g_cpu_paused[cpu]));
spin_unlock(&g_cpu_wait[cpu]);
/* Ensure the CPU has been resumed to avoid causing a deadlock */
spin_lock(&g_cpu_resumed[cpu]);
spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
#endif /* CONFIG_SMP */

View file

@ -79,18 +79,8 @@ int arm_start_handler(int irq, void *context, void *arg)
nxsched_resume_scheduler(tcb);
/* Dump registers so that we can see what is going to happen on return */
UNUSED(tcb);
#if 0
up_dump_register(tcb->xcp.regs);
#endif
/* Then switch contexts. This instantiates the exception context of the
* tcb at the head of the assigned task list. In this case, this should
* be the CPUs NULL task.
*/
arm_restorestate(tcb->xcp.regs);
return OK;
}

View file

@ -53,6 +53,8 @@
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
@ -61,6 +63,18 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
/* if irq == GIC_SMP_CPUSTART
* We are initiating the multi-core jumping state to up_idle,
* and we will use this_task(). Therefore, it cannot be overridden.
*/
#ifdef CONFIG_SMP
if (irq != GIC_SMP_CPUSTART)
#endif
{
tcb->xcp.regs = regs;
}
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/
@ -70,10 +84,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
/* Deliver the IRQ */
irq_dispatch(irq, regs);
tcb = this_task();
/* Restore the cpu lock */
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
@ -85,13 +98,18 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
addrenv_switch(NULL);
#endif
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
g_running_tasks[this_cpu()] = this_task();
regs = up_current_regs();
g_running_tasks[this_cpu()] = tcb;
regs = tcb->xcp.regs;
}
/* Set current_regs to NULL to indicate that we are no longer in an

View file

@ -30,6 +30,7 @@
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/pci/pci.h>
#include <nuttx/spinlock.h>
#include <arch/irq.h>
@ -210,13 +211,16 @@ void arm_gic0_initialize(void)
putreg32(0x01010101, GIC_ICDIPTR(irq)); /* SPI on CPU0 */
}
#ifdef CONFIG_ARMV7A_GICv2M
gic_v2m_initialize();
#endif
#ifdef CONFIG_SMP
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_SCHED, arm_smp_sched_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CALL, nxsched_smp_call_handler, NULL));
#endif
arm_gic_dump("Exit arm_gic0_initialize", true, 0);
@ -749,24 +753,27 @@ void arm_cpu_sgi(int sgi, unsigned int cpuset)
putreg32(regval, GIC_ICDSGIR);
}
#ifdef CONFIG_SMP
/****************************************************************************
* Name: up_send_smp_call
* Name: up_get_legacy_irq
*
* Description:
* Send smp call to target cpu.
*
* Input Parameters:
* cpuset - The set of CPUs to receive the SGI.
*
* Returned Value:
* None.
* Reserve vector for legacy
*
****************************************************************************/
void up_send_smp_call(cpu_set_t cpuset)
int up_get_legacy_irq(uint32_t devfn, uint8_t line, uint8_t pin)
{
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
}
#if CONFIG_ARMV7A_GICV2_LEGACY_IRQ0 >= 0
uint8_t slot;
uint8_t tmp;
UNUSED(line);
slot = PCI_SLOT(devfn);
tmp = (pin - 1 + slot) % 4;
return CONFIG_ARMV7A_GICV2_LEGACY_IRQ0 + tmp;
#else
return -ENOTSUP;
#endif
}
#endif /* CONFIG_ARMV7A_HAVE_GICv2 */

View file

@ -0,0 +1,139 @@
/****************************************************************************
* arch/arm/src/armv7-a/arm_gicv2m.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <errno.h>
#include <nuttx/bits.h>
#include <nuttx/kmalloc.h>
#include <nuttx/pci/pci.h>
#include <nuttx/spinlock.h>
#include "arm_internal.h"
#include "gic.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
struct gic_v2m_s
{
spinlock_t lock;
uint32_t spi_start;
uint32_t spi_number;
unsigned long *spi_bitmap;
};
/****************************************************************************
* Private Data
****************************************************************************/
static struct gic_v2m_s g_v2m =
{
SP_LOCKED
};
/****************************************************************************
* Private Functions
****************************************************************************/
static bool is_valid_spi(uint32_t base, uint32_t number)
{
if (base < GIC_IRQ_SPI)
{
return false;
}
if (number == 0 || base + number > NR_IRQS)
{
return false;
}
return true;
}
/****************************************************************************
* Public Functions
****************************************************************************/
int gic_v2m_initialize(void)
{
uint32_t typer;
typer = getreg32(GIC_V2MTYPER);
g_v2m.spi_start = GIC_V2MTYPES_BASE(typer);
g_v2m.spi_number = GIC_V2MTYPES_NUMBER(typer);
if (!is_valid_spi(g_v2m.spi_start, g_v2m.spi_number))
{
return -EINVAL;
}
g_v2m.spi_bitmap = kmm_zalloc(BITS_TO_LONGS(g_v2m.spi_number));
if (g_v2m.spi_bitmap == NULL)
{
return -ENOMEM;
}
return 0;
}
int up_alloc_irq_msi(int *num)
{
irqstate_t flags;
int offset;
int irq;
int i;
flags = spin_lock_irqsave(&g_v2m.lock);
offset = bitmap_find_free_region(g_v2m.spi_bitmap, g_v2m.spi_number, *num);
spin_unlock_irqrestore(&g_v2m.lock, flags);
irq = g_v2m.spi_start + offset;
for (i = 0; i < *num; i++)
{
arm_gic_irq_trigger(i + irq, true);
}
return irq;
}
void up_release_irq_msi(int *irq, int num)
{
irqstate_t flags;
flags = spin_lock_irqsave(&g_v2m.lock);
bitmap_release_region(g_v2m.spi_bitmap, *irq - g_v2m.spi_start, num);
spin_unlock_irqrestore(&g_v2m.lock, flags);
}
int up_connect_irq(int *irq, int num,
uintptr_t *mar, uint32_t *mdr)
{
*mar = GIC_V2MSETSPI;
*mdr = *irq;
return 0;
}

View file

@ -77,324 +77,56 @@
*
****************************************************************************/
#ifndef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
void up_schedule_sigaction(struct tcb_s *tcb)
{
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb, this_task(),
this_task()->xcp.regs);
/* Refuse to handle nested signal actions */
/* First, handle some special cases when the signal is
* being delivered to the currently executing task.
*/
if (!tcb->xcp.sigdeliver)
if (tcb == this_task() && !up_interrupt_context())
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to task that is currently executing on this CPU.
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb == this_task())
{
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (!up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: We are in an interrupt handler AND the interrupted
* task is the same as the one that must receive the signal, then
* we will have to modify the return state as well as the state
* in the TCB.
*
* Hmmm... there looks like a latent bug here: The following logic
* would fail in the strange case where we are in an interrupt
* handler, the thread is signaling itself, but a context switch
* to another task has occurred so that current_regs does not
* refer to the thread of this_task()!
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
*/
/* And make sure that the saved context in the TCB is the same
* as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs() +
XCPTCONTEXT_REGS);
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
up_current_regs()[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
up_current_regs()[REG_CPSR] |= PSR_T_BIT;
#endif
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling some other non-running task.
(tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
/* Save the current register context location */
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT);
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
}
}
}
#endif /* !CONFIG_SMP */
#ifdef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
int cpu;
int me;
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
/* Refuse to handle nested signal actions */
if (!tcb->xcp.sigdeliver)
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to task that is currently executing on any CPU.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb->task_state == TSTATE_TASK_RUNNING)
{
me = this_cpu();
cpu = tcb->cpu;
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (cpu == me && !up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/
else
{
/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/
if (cpu != me)
{
/* Pause the CPU */
up_cpu_pause(cpu);
/* Now tcb on the other CPU can be accessed safely */
/* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
}
else
{
/* tcb is running on the same CPU */
/* Save the return PC, CPSR and either the BASEPRI or
* PRIMASK registers (and perhaps also the LR). These will
* be restored by the signal trampoline after the signal
* has been delivered.
*/
/* And make sure that the saved context in the TCB is the
* same as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs()
+ XCPTCONTEXT_REGS);
/* Then set up vector to the trampoline with interrupts
* disabled. The kernel-space trampoline must run in
* privileged thread mode.
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
up_current_regs()[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
up_current_regs()[REG_CPSR] |= PSR_T_BIT;
#endif
}
/* NOTE: If the task runs on another CPU(cpu), adjusting
* global IRQ controls will be done in the pause handler
* on the CPU(cpu) by taking a critical section.
* If the task is scheduled on this CPU(me), do nothing
* because this CPU already took a critical section
*/
/* RESUME the other CPU if it was PAUSED */
if (cpu != me)
{
up_cpu_resume(cpu);
}
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling some other non-running task.
*/
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
}
}
}
#endif /* CONFIG_SMP */

View file

@ -68,8 +68,8 @@ void arm_sigdeliver(void)
board_autoled_on(LED_SIGNAL);
sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
rtcb, rtcb->sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->sigdeliver != NULL);
retry:
#ifdef CONFIG_SMP
@ -101,7 +101,7 @@ retry:
/* Deliver the signal */
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
(rtcb->sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -148,7 +148,7 @@ retry:
* could be modified by a hostile program.
*/
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
rtcb->sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View file

@ -0,0 +1,122 @@
/****************************************************************************
* arch/arm/src/armv7-a/arm_smpcall.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include <nuttx/spinlock.h>
#include <nuttx/sched_note.h>
#include "arm_internal.h"
#include "gic.h"
#include "sched/sched.h"
#ifdef CONFIG_SMP
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: arm_smp_sched_handler
*
* Description:
* This is the handler for sched.
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It porcess g_delivertasks
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
* Input Parameters:
* Standard interrupt handling
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int arm_smp_sched_handler(int irq, void *context, void *arg)
{
int cpu = this_cpu();
nxsched_process_delivered(cpu);
return OK;
}
/****************************************************************************
* Name: up_send_smp_sched
*
* Description:
* pause task execution on the CPU
* check whether there are tasks delivered to specified cpu
* and try to run them.
*
* Input Parameters:
* cpu - The index of the CPU to be paused.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
* Assumptions:
* Called from within a critical section;
*
****************************************************************************/
int up_send_smp_sched(int cpu)
{
arm_cpu_sgi(GIC_SMP_SCHED, (1 << cpu));
return OK;
}
/****************************************************************************
* Name: up_send_smp_call
*
* Description:
* Send smp call to target cpu.
*
* Input Parameters:
* cpuset - The set of CPUs to receive the SGI.
*
* Returned Value:
* None.
*
****************************************************************************/
void up_send_smp_call(cpu_set_t cpuset)
{
up_trigger_irq(GIC_SMP_CALL, cpuset);
}
#endif /* CONFIG_SMP */

View file

@ -160,7 +160,7 @@ static void dispatch_syscall(void)
uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb;
struct tcb_s *tcb = this_task();
uint32_t cmd;
int cpu;
#ifdef CONFIG_BUILD_KERNEL
@ -171,6 +171,8 @@ uint32_t *arm_syscall(uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
tcb->xcp.regs = regs;
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/
@ -272,7 +274,7 @@ uint32_t *arm_syscall(uint32_t *regs)
* set will determine the restored context.
*/
up_set_current_regs((uint32_t *)regs[REG_R1]);
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
DEBUGASSERT(up_current_regs());
}
break;
@ -298,7 +300,7 @@ uint32_t *arm_syscall(uint32_t *regs)
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
up_set_current_regs((uint32_t *)regs[REG_R2]);
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
}
break;
@ -428,7 +430,7 @@ uint32_t *arm_syscall(uint32_t *regs)
/* Copy "info" into user stack */
if (rtcb->xcp.sigdeliver)
if (rtcb->sigdeliver)
{
usp = rtcb->xcp.saved_regs[REG_SP];
}
@ -565,15 +567,9 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}
#ifdef CONFIG_ARCH_ADDRENV
/* Check for a context switch. If a context switch occurred, then
* current_regs will have a different value than it did on entry. If an
* interrupt level context switch has occurred, then establish the correct
* address environment before returning from the interrupt.
*/
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new
@ -581,25 +577,26 @@ uint32_t *arm_syscall(uint32_t *regs)
*/
addrenv_switch(NULL);
}
#endif
/* Restore the cpu lock */
cpu = this_cpu();
tcb = current_task(cpu);
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[cpu]);
nxsched_resume_scheduler(tcb);
if (regs != up_current_regs())
{
/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
*/
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;
/* Restore the cpu lock */
restore_critical_section(tcb, cpu);
regs = up_current_regs();
regs = tcb->xcp.regs;
}
/* Report what happened */

View file

@ -136,6 +136,11 @@
/* 0x0020-0x003c: Implementation defined */
/* 0x0040-0x007c: Reserved */
/* V2M Registers */
#define GIC_V2MTYPER_OFFSET 0x008
#define GIC_V2MSETSPI_OFFSET 0x040
/* Interrupt Security Registers: 0x0080-0x009c */
#define GIC_ICDISR_OFFSET(n) (0x0080 + GIC_OFFSET32(n))
@ -277,6 +282,11 @@
#define GIC_ICDPIDR(n) (MPCORE_ICD_VBASE+GIC_ICDPIDR_OFFSET(n))
#define GIC_ICDCIDR(n) (MPCORE_ICD_VBASE+GIC_ICDCIDR_OFFSET(n))
/* V2M Registers */
#define GIC_V2MTYPER (MPCORE_V2M_VBASE + GIC_V2MTYPER_OFFSET)
#define GIC_V2MSETSPI (MPCORE_V2M_VBASE + GIC_V2MSETSPI_OFFSET)
/* GIC Register Bit Definitions *********************************************/
/* CPU Interface registers */
@ -557,6 +567,14 @@
# define GIC_ICDSGIR_TGTFILTER_THIS (2 << GIC_ICDSGIR_TGTFILTER_SHIFT) /* Interrupt is sent to requesting CPU only */
/* Bits 26-31: Reserved */
/* V2M Registers */
#define GIC_V2MTYPES_BASE_SHIFT 16
#define GIC_V2MTYPES_BASE_MASK 0x3FF
#define GIC_V2MTYPES_NUMBER_MASK 0x3FF
#define GIC_V2MTYPES_BASE(x) (((x) >> GIC_V2MTYPES_BASE_SHIFT) & GIC_V2MTYPES_BASE_MASK)
#define GIC_V2MTYPES_NUMBER(x) ((x) & GIC_V2MTYPES_NUMBER_MASK)
/* Interrupt IDs ************************************************************/
/* The Global Interrupt Controller (GIC) collects up to 224 interrupt
@ -617,12 +635,12 @@
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
# define GIC_SMP_CALL GIC_IRQ_SGI10
# define GIC_SMP_SCHED GIC_IRQ_SGI11
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
# define GIC_SMP_CALL GIC_IRQ_SGI2
# define GIC_SMP_SCHED GIC_IRQ_SGI3
#endif
/****************************************************************************
@ -816,14 +834,14 @@ int arm_start_handler(int irq, void *context, void *arg);
#endif
/****************************************************************************
* Name: arm_pause_handler
* Name: arm_smp_sched_handler
*
* Description:
* This is the handler for SGI2. It performs the following operations:
* This is the handler for sched.
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It waits on a spinlock, then
* 2. It porcess g_delivertasks
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
@ -836,9 +854,8 @@ int arm_start_handler(int irq, void *context, void *arg);
****************************************************************************/
#ifdef CONFIG_SMP
int arm_pause_handler(int irq, void *context, void *arg);
int arm_smp_sched_handler(int irq, void *context, void *arg);
#endif
/****************************************************************************
* Name: arm_gic_dump
*
@ -861,6 +878,10 @@ void arm_gic_dump(const char *msg, bool all, int irq);
# define arm_gic_dump(msg, all, irq)
#endif
#ifdef CONFIG_ARMV7A_GICv2M
int gic_v2m_initialize(void);
#endif
#undef EXTERN
#ifdef __cplusplus
}

View file

@ -73,5 +73,6 @@
#define MPCORE_GTM_VBASE (CHIP_MPCORE_VBASE+MPCORE_GTM_OFFSET)
#define MPCORE_PTM_VBASE (CHIP_MPCORE_VBASE+MPCORE_PTM_OFFSET)
#define MPCORE_ICD_VBASE (CHIP_MPCORE_VBASE+MPCORE_ICD_OFFSET)
#define MPCORE_V2M_VBASE (CHIP_MPCORE_VBASE+MPCORE_V2M_OFFSET)
#endif /* __ARCH_ARM_SRC_ARMV7_A_MPCORE_H */

View file

@ -35,30 +35,60 @@
#include "arm_internal.h"
#include "exc_return.h"
#include "nvic.h"
/****************************************************************************
* Public Functions
****************************************************************************/
void exception_direct(void)
{
int irq = getipsr();
arm_ack_irq(irq);
irq_dispatch(irq, NULL);
if (g_running_tasks[this_cpu()] != this_task())
{
up_trigger_irq(NVIC_IRQ_PENDSV, 0);
}
}
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
up_set_current_regs(regs);
}
/* Acknowledge the interrupt */
arm_ack_irq(irq);
/* Deliver the IRQ */
/* Set current regs for crash dump */
irq_dispatch(irq, regs);
up_set_current_regs(regs);
if (irq == NVIC_IRQ_PENDSV)
{
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
/* Dispatch the PendSV interrupt */
irq_dispatch(irq, regs);
#endif
up_irq_save();
g_running_tasks[this_cpu()]->xcp.regs = regs;
}
else
{
/* Dispatch irq */
tcb->xcp.regs = regs;
irq_dispatch(irq, regs);
}
/* If a context switch occurred while processing the interrupt then
* current_regs may have change value. If we return any value different
@ -66,27 +96,27 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* switch occurred during interrupt processing.
*/
if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
/* Restore the cpu lock */
tcb = this_task();
if (regs != up_current_regs())
{
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
/* Update scheduler parameters */
g_running_tasks[this_cpu()] = this_task();
regs = up_current_regs();
}
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_resume_scheduler(tcb);
/* Update the current_regs to NULL. */
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
up_set_current_regs(NULL);
}
g_running_tasks[this_cpu()] = tcb;
regs = tcb->xcp.regs;
#endif
/* Clear current regs */
up_set_current_regs(NULL);
board_autoled_off(LED_INIRQ);
return regs;
}

View file

@ -163,7 +163,7 @@ void up_initial_state(struct tcb_s *tcb)
#else /* CONFIG_SUPPRESS_INTERRUPTS */
#ifdef CONFIG_ARMV7M_USEBASEPRI
xcp->regs[REG_BASEPRI] = NVIC_SYSH_PRIORITY_MIN;
xcp->regs[REG_BASEPRI] = 0;
#endif
#endif /* CONFIG_SUPPRESS_INTERRUPTS */

View file

@ -79,355 +79,64 @@
*
****************************************************************************/
#ifndef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
void up_schedule_sigaction(struct tcb_s *tcb)
{
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
DEBUGASSERT(tcb != NULL && sigdeliver != NULL);
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb, this_task(),
this_task()->xcp.regs);
/* Refuse to handle nested signal actions */
/* First, handle some special cases when the signal is
* being delivered to the currently executing task.
*/
if (tcb->xcp.sigdeliver == NULL)
if (tcb == this_task() && !up_interrupt_context())
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to the currently executing task.
/* In this case just deliver the signal now.
* REVISIT: Signal handle will run in a critical section!
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb == this_task())
{
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (!up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handle will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: We are in an interrupt handler AND the interrupted
* task is the same as the one that must receive the signal, then
* we will have to modify the return state as well as the state in
* the TCB.
*/
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* And make sure that the saved context in the TCB is the same
* as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs() +
XCPTCONTEXT_REGS);
/* Then set up to vector to the trampoline with interrupts
* disabled. The kernel-space trampoline must run in
* privileged thread mode.
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV7M_USEBASEPRI
up_current_regs()[REG_BASEPRI] =
NVIC_SYSH_DISABLE_PRIORITY;
#else
up_current_regs()[REG_PRIMASK] = 1;
#endif
up_current_regs()[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
up_current_regs()[REG_LR] = EXC_RETURN_THREAD;
up_current_regs()[REG_EXC_RETURN] = EXC_RETURN_THREAD;
up_current_regs()[REG_CONTROL] = getcontrol() &
~CONTROL_NPRIV;
#endif
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling* some non-running task.
(tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
/* Save the current register context location */
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV7M_USEBASEPRI
tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
#else
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_PRIMASK] = 1;
#endif
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
}
#endif /* !CONFIG_SMP */
#ifdef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
int cpu;
int me;
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
/* Refuse to handle nested signal actions */
if (!tcb->xcp.sigdeliver)
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to task that is currently executing on any CPU.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb->task_state == TSTATE_TASK_RUNNING)
{
me = this_cpu();
cpu = tcb->cpu;
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (cpu == me && !up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/
else
{
/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/
if (cpu != me)
{
/* Pause the CPU */
up_cpu_pause(cpu);
/* Now tcb on the other CPU can be accessed safely */
/* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode
* to be here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV7M_USEBASEPRI
tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
#else
tcb->xcp.regs[REG_PRIMASK] = 1;
#endif
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
else
{
/* tcb is running on the same CPU */
/* Save the return PC, CPSR and either the BASEPRI or
* PRIMASK registers (and perhaps also the LR). These
* will be restored by the signal trampoline after the
* signal has been delivered.
*/
/* And make sure that the saved context in the TCB is the
* same as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs()
+ XCPTCONTEXT_REGS);
/* Then set up vector to the trampoline with interrupts
* disabled. The kernel-space trampoline must run in
* privileged thread mode.
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV7M_USEBASEPRI
up_current_regs()[REG_BASEPRI] =
NVIC_SYSH_DISABLE_PRIORITY;
#else
up_current_regs()[REG_PRIMASK] = 1;
#endif
up_current_regs()[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
up_current_regs()[REG_LR] = EXC_RETURN_THREAD;
up_current_regs()[REG_CONTROL] = getcontrol() &
~CONTROL_NPRIV;
#endif
}
/* NOTE: If the task runs on another CPU(cpu), adjusting
* global IRQ controls will be done in the pause handler
* on the CPU(cpu) by taking a critical section.
* If the task is scheduled on this CPU(me), do nothing
* because this CPU already took a critical section
*/
/* RESUME the other CPU if it was PAUSED */
if (cpu != me)
{
up_cpu_resume(cpu);
}
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling some other non-running task.
*/
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV7M_USEBASEPRI
tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
#else
tcb->xcp.regs[REG_PRIMASK] = 1;
#endif
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
}
#endif /* CONFIG_SMP */

View file

@ -68,8 +68,8 @@ void arm_sigdeliver(void)
board_autoled_on(LED_SIGNAL);
sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
rtcb, rtcb->sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->sigdeliver != NULL);
retry:
#ifdef CONFIG_SMP
@ -105,7 +105,7 @@ retry:
/* Deliver the signal */
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
(rtcb->sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -156,7 +156,7 @@ retry:
* could be modified by a hostile program.
*/
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
rtcb->sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of
* execution.

View file

@ -125,10 +125,10 @@ static void dispatch_syscall(void)
int arm_svcall(int irq, void *context, void *arg)
{
struct tcb_s *tcb = this_task();
uint32_t *regs = (uint32_t *)context;
uint32_t cmd;
DEBUGASSERT(regs && regs == up_current_regs());
cmd = regs[REG_R0];
/* The SVCall software interrupt is called with R0 = system call command
@ -176,7 +176,7 @@ int arm_svcall(int irq, void *context, void *arg)
case SYS_restore_context:
{
DEBUGASSERT(regs[REG_R1] != 0);
up_set_current_regs((uint32_t *)regs[REG_R1]);
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
}
break;
@ -201,7 +201,7 @@ int arm_svcall(int irq, void *context, void *arg)
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
up_set_current_regs((uint32_t *)regs[REG_R2]);
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
}
break;
@ -298,8 +298,9 @@ int arm_svcall(int irq, void *context, void *arg)
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_start
* R1 = entrypt
* R2 = arg
* R1 = startup (trampoline)
* R2 = entrypt
* R3 = arg
*/
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
@ -459,24 +460,20 @@ int arm_svcall(int irq, void *context, void *arg)
# ifndef CONFIG_DEBUG_SVCALL
if (cmd > SYS_switch_context)
# else
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
# endif
{
regs = (uint32_t *)tcb->xcp.regs;
svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
up_current_regs()[REG_R0], up_current_regs()[REG_R1],
up_current_regs()[REG_R2], up_current_regs()[REG_R3],
up_current_regs()[REG_R4], up_current_regs()[REG_R5],
up_current_regs()[REG_R6], up_current_regs()[REG_R7]);
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
up_current_regs()[REG_R8], up_current_regs()[REG_R9],
up_current_regs()[REG_R10], up_current_regs()[REG_R11],
up_current_regs()[REG_R12], up_current_regs()[REG_R13],
up_current_regs()[REG_R14], up_current_regs()[REG_R15]);
svcinfo(" PSR: %08x EXC_RETURN: %08x, CONTROL: %08x\n",
up_current_regs()[REG_XPSR],
up_current_regs()[REG_EXC_RETURN],
up_current_regs()[REG_CONTROL]);
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
regs[REG_XPSR], regs[REG_EXC_RETURN], regs[REG_CONTROL]);
}
# ifdef CONFIG_DEBUG_SVCALL
else

View file

@ -41,6 +41,7 @@
#include "chip.h"
#include "arm_internal.h"
#include "ram_vectors.h"
#include "nvic.h"
/****************************************************************************
* Pre-processor Definitions
@ -71,6 +72,7 @@ static void start(void)
/* Common exception entrypoint */
extern void exception_common(void);
extern void exception_direct(void);
/****************************************************************************
* Public data
@ -98,5 +100,7 @@ const void * const _vectors[] locate_data(".vectors")
/* Vectors 2 - n point directly at the generic handler */
[2 ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)] = exception_common
[2 ... NVIC_IRQ_PENDSV] = &exception_common,
[(NVIC_IRQ_PENDSV + 1) ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)]
= &exception_direct
};

View file

@ -71,7 +71,7 @@ if(CONFIG_SMP)
SRCS
arm_cpuhead.S
arm_cpustart.c
arm_cpupause.c
arm_smpcall.c
arm_cpuidlestack.c
arm_scu.c)
endif()

View file

@ -59,6 +59,6 @@ endif
ifeq ($(CONFIG_SMP),y)
CMN_ASRCS += arm_cpuhead.S
CMN_CSRCS += arm_cpustart.c arm_cpupause.c
CMN_CSRCS += arm_cpustart.c arm_smpcall.c
CMN_CSRCS += arm_cpuidlestack.c arm_scu.c
endif

View file

@ -1,381 +0,0 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_cpupause.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include <nuttx/spinlock.h>
#include <nuttx/sched_note.h>
#include "arm_internal.h"
#include "gic.h"
#include "sched/sched.h"
#ifdef CONFIG_SMP
/****************************************************************************
* Private Data
****************************************************************************/
/* These spinlocks are used in the SMP configuration in order to implement
* up_cpu_pause(). The protocol for CPUn to pause CPUm is as follows
*
* 1. The up_cpu_pause() implementation on CPUn locks both g_cpu_wait[m]
* and g_cpu_paused[m]. CPUn then waits spinning on g_cpu_paused[m].
* 2. CPUm receives the interrupt it (1) unlocks g_cpu_paused[m] and
* (2) locks g_cpu_wait[m]. The first unblocks CPUn and the second
* blocks CPUm in the interrupt handler.
*
* When CPUm resumes, CPUn unlocks g_cpu_wait[m] and the interrupt handler
* on CPUm continues. CPUm must, of course, also then unlock g_cpu_wait[m]
* so that it will be ready for the next pause operation.
*/
static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS];
static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS];
static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS];
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_cpu_pausereq
*
* Description:
* Return true if a pause request is pending for this CPU.
*
* Input Parameters:
* cpu - The index of the CPU to be queried
*
* Returned Value:
* true = a pause request is pending.
* false = no pasue request is pending.
*
****************************************************************************/
bool up_cpu_pausereq(int cpu)
{
return spin_is_locked(&g_cpu_paused[cpu]);
}
/****************************************************************************
* Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
* executed from interrupt handling logic within the architecture-specific
* However, it is sometimes necessary to perform the pending
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
* Input Parameters:
* None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
* the nature of the failure is returned.
*
****************************************************************************/
int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
/* Update scheduler parameters */
nxsched_suspend_scheduler(tcb);
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we are paused */
sched_note_cpu_paused(tcb);
#endif
/* Save the current context at current_regs into the TCB at the head
* of the assigned task list for this CPU.
*/
arm_savestate(tcb->xcp.regs);
return OK;
}
/****************************************************************************
* Name: up_cpu_paused
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
* executed from interrupt handling logic within the architecture-specific
* However, it is sometimes necessary to perform the pending
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
* This function performs the following operations:
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It waits on a spinlock, then
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
* Input Parameters:
* cpu - The index of the CPU to be paused
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
* the nature of the failure is returned.
*
****************************************************************************/
int up_cpu_paused(int cpu)
{
/* Release the g_cpu_paused spinlock to synchronize with the
* requesting CPU.
*/
spin_unlock(&g_cpu_paused[cpu]);
/* Ensure the CPU has been resumed to avoid causing a deadlock */
spin_lock(&g_cpu_resumed[cpu]);
/* Wait for the spinlock to be released. The requesting CPU will release
* the spinlock when the CPU is resumed.
*/
spin_lock(&g_cpu_wait[cpu]);
spin_unlock(&g_cpu_wait[cpu]);
spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
/****************************************************************************
* Name: up_cpu_paused_restore
*
* Description:
* Restore the state of the CPU after it was paused via up_cpu_pause(),
* and resume normal tasking.
*
* Input Parameters:
* None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
* the nature of the failure is returned.
*
****************************************************************************/
int up_cpu_paused_restore(void)
{
struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
sched_note_cpu_resumed(tcb);
#endif
/* Reset scheduler parameters */
nxsched_resume_scheduler(tcb);
/* Then switch contexts. Any necessary address environment changes
* will be made when the interrupt returns.
*/
arm_restorestate(tcb->xcp.regs);
return OK;
}
/****************************************************************************
* Name: arm_pause_handler
*
* Description:
* This is the handler for SGI2. It performs the following operations:
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It waits on a spinlock, then
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
* Input Parameters:
* Standard interrupt handling
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int arm_pause_handler(int irq, void *context, void *arg)
{
int cpu = this_cpu();
/* Check for false alarms. Such false could occur as a consequence of
* some deadlock breaking logic that might have already serviced the SG2
* interrupt by calling up_cpu_paused(). If the pause event has already
* been processed then g_cpu_paused[cpu] will not be locked.
*/
if (up_cpu_pausereq(cpu))
{
/* NOTE: The following enter_critical_section() will call
* up_cpu_paused() to process a pause request to break a deadlock
* because the caller held a critical section. Once up_cpu_paused()
* finished, the caller will proceed and release the g_cpu_irqlock.
* Then this CPU will acquire g_cpu_irqlock in the function.
*/
irqstate_t flags = enter_critical_section();
/* NOTE: the pause request should not exist here */
DEBUGVERIFY(!up_cpu_pausereq(cpu));
leave_critical_section(flags);
}
return OK;
}
/****************************************************************************
* Name: up_cpu_pause
*
* Description:
* Save the state of the current task at the head of the
* g_assignedtasks[cpu] task list and then pause task execution on the
* CPU.
*
* This function is called by the OS when the logic executing on one CPU
* needs to modify the state of the g_assignedtasks[cpu] list for another
* CPU.
*
* Input Parameters:
* cpu - The index of the CPU to be stopped
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int up_cpu_pause(int cpu)
{
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the pause event */
sched_note_cpu_pause(this_task(), cpu);
#endif
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2
* handler from returning until up_cpu_resume() is called; g_cpu_paused
* is a handshake that will prefent this function from returning until
* the CPU is actually paused.
* Note that we might spin before getting g_cpu_wait, this just means that
* the other CPU still hasn't finished responding to the previous resume
* request.
*/
DEBUGASSERT(!spin_is_locked(&g_cpu_paused[cpu]));
spin_lock(&g_cpu_wait[cpu]);
spin_lock(&g_cpu_paused[cpu]);
/* Execute SGI2 */
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
/* Wait for the other CPU to unlock g_cpu_paused meaning that
* it is fully paused and ready for up_cpu_resume();
*/
spin_lock(&g_cpu_paused[cpu]);
spin_unlock(&g_cpu_paused[cpu]);
/* On successful return g_cpu_wait will be locked, the other CPU will be
* spinning on g_cpu_wait and will not continue until g_cpu_resume() is
* called. g_cpu_paused will be unlocked in any case.
*/
return OK;
}
/****************************************************************************
* Name: up_cpu_resume
*
* Description:
* Restart the cpu after it was paused via up_cpu_pause(), restoring the
* state of the task at the head of the g_assignedtasks[cpu] list, and
* resume normal tasking.
*
* This function is called after up_cpu_pause in order resume operation of
* the CPU after modifying its g_assignedtasks[cpu] list.
*
* Input Parameters:
* cpu - The index of the CPU being re-started.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int up_cpu_resume(int cpu)
{
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the resume event */
sched_note_cpu_resume(this_task(), cpu);
#endif
/* Release the spinlock. Releasing the spinlock will cause the SGI2
* handler on 'cpu' to continue and return from interrupt to the newly
* established thread.
*/
DEBUGASSERT(spin_is_locked(&g_cpu_wait[cpu]) &&
!spin_is_locked(&g_cpu_paused[cpu]));
spin_unlock(&g_cpu_wait[cpu]);
/* Ensure the CPU has been resumed to avoid causing a deadlock */
spin_lock(&g_cpu_resumed[cpu]);
spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
#endif /* CONFIG_SMP */

View file

@ -79,12 +79,8 @@ int arm_start_handler(int irq, void *context, void *arg)
nxsched_resume_scheduler(tcb);
/* Then switch contexts. This instantiates the exception context of the
* tcb at the head of the assigned task list. In this case, this should
* be the CPUs NULL task.
*/
UNUSED(tcb);
arm_restorestate(tcb->xcp.regs);
return OK;
}

View file

@ -41,6 +41,8 @@
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
@ -50,6 +52,18 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
/* if irq == GIC_SMP_CPUSTART
* We are initiating the multi-core jumping state to up_idle,
* and we will use this_task(). Therefore, it cannot be overridden.
*/
#ifdef CONFIG_SMP
if (irq != GIC_SMP_CPUSTART)
#endif
{
tcb->xcp.regs = regs;
}
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/
@ -59,18 +73,22 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
/* Deliver the IRQ */
irq_dispatch(irq, regs);
tcb = this_task();
/* Restore the cpu lock */
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
{
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
g_running_tasks[this_cpu()] = this_task();
regs = up_current_regs();
g_running_tasks[this_cpu()] = tcb;
regs = tcb->xcp.regs;
}
/* Set current_regs to NULL to indicate that we are no longer in an

View file

@ -160,9 +160,8 @@ void arm_gic0_initialize(void)
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_SCHED, arm_smp_sched_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CALL, nxsched_smp_call_handler, NULL));
#endif
arm_gic_dump("Exit arm_gic0_initialize", true, 0);
@ -659,24 +658,4 @@ int arm_gic_irq_trigger(int irq, bool edge)
return -EINVAL;
}
# ifdef CONFIG_SMP
/****************************************************************************
* Name: up_send_smp_call
*
* Description:
* Send smp call to target cpu.
*
* Input Parameters:
* cpuset - The set of CPUs to receive the SGI.
*
* Returned Value:
* None.
*
****************************************************************************/
void up_send_smp_call(cpu_set_t cpuset)
{
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
}
# endif
#endif /* CONFIG_ARMV7R_HAVE_GICv2 */

View file

@ -75,328 +75,56 @@
*
****************************************************************************/
#ifndef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
void up_schedule_sigaction(struct tcb_s *tcb)
{
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb, this_task(),
this_task()->xcp.regs);
/* Refuse to handle nested signal actions */
/* First, handle some special cases when the signal is
* being delivered to the currently executing task.
*/
if (!tcb->xcp.sigdeliver)
if (tcb == this_task() && !up_interrupt_context())
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to the currently executing task.
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb == this_task())
{
/* CASE 1: We are not in an interrupt handler and a task is
* signalling itself for some reason.
*/
if (!up_current_regs())
{
/* In this case just deliver the signal now. */
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: We are in an interrupt handler AND the interrupted
* task is the same as the one that must receive the signal, then
* we will have to modify the return state as well as the state
* in the TCB.
*
* Hmmm... there looks like a latent bug here: The following logic
* would fail in the strange case where we are in an interrupt
* handler, the thread is signalling itself, but a context switch
* to another task has occurred so that current_regs does not
* refer to the thread of this_task()!
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
*/
/* And make sure that the saved context in the TCB is the same
* as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs() +
XCPTCONTEXT_REGS);
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
up_current_regs()[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
up_current_regs()[REG_CPSR] |= PSR_T_BIT;
#endif
#ifdef CONFIG_ENDIAN_BIG
up_current_regs()[REG_CPSR] |= PSR_E_BIT;
#endif
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signalling some non-running task.
(tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
/* Save the current register context location */
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
#ifdef CONFIG_ENDIAN_BIG
tcb->xcp.regs[REG_CPSR] |= PSR_E_BIT;
#endif
}
}
}
#else
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
int cpu;
int me;
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
/* Refuse to handle nested signal actions */
if (!tcb->xcp.sigdeliver)
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to task that is currently executing on any CPU.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb->task_state == TSTATE_TASK_RUNNING)
{
me = this_cpu();
cpu = tcb->cpu;
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (cpu == me && !up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/
else
{
/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/
if (cpu != me)
{
/* Pause the CPU */
up_cpu_pause(cpu);
/* Now tcb on the other CPU can be accessed safely */
/* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
}
else
{
/* tcb is running on the same CPU */
/* Save the return PC, CPSR and either the BASEPRI or
* PRIMASK registers (and perhaps also the LR). These will
* be restored by the signal trampoline after the signal
* has been delivered.
*/
/* And make sure that the saved context in the TCB is the
* same as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs()
+ XCPTCONTEXT_REGS);
/* Then set up vector to the trampoline with interrupts
* disabled. The kernel-space trampoline must run in
* privileged thread mode.
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
up_current_regs()[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
up_current_regs()[REG_CPSR] |= PSR_T_BIT;
#endif
}
/* NOTE: If the task runs on another CPU(cpu), adjusting
* global IRQ controls will be done in the pause handler
* on the CPU(cpu) by taking a critical section.
* If the task is scheduled on this CPU(me), do nothing
* because this CPU already took a critical section
*/
/* RESUME the other CPU if it was PAUSED */
if (cpu != me)
{
up_cpu_resume(cpu);
}
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling some other non-running task.
*/
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
}
}
}
#endif

View file

@ -68,8 +68,8 @@ void arm_sigdeliver(void)
board_autoled_on(LED_SIGNAL);
sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
rtcb, rtcb->sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->sigdeliver != NULL);
retry:
#ifdef CONFIG_SMP
@ -101,7 +101,7 @@ retry:
/* Deliver the signal */
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
(rtcb->sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -145,7 +145,7 @@ retry:
* could be modified by a hostile program.
*/
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
rtcb->sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View file

@ -0,0 +1,122 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_smpcall.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include <nuttx/spinlock.h>
#include <nuttx/sched_note.h>
#include "arm_internal.h"
#include "gic.h"
#include "sched/sched.h"
#ifdef CONFIG_SMP
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: arm_smp_sched_handler
*
* Description:
* This is the handler for sched.
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It porcess g_delivertasks
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
* Input Parameters:
* Standard interrupt handling
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int arm_smp_sched_handler(int irq, void *context, void *arg)
{
int cpu = this_cpu();
nxsched_process_delivered(cpu);
return OK;
}
/****************************************************************************
* Name: up_send_smp_sched
*
* Description:
* pause task execution on the CPU
* check whether there are tasks delivered to specified cpu
* and try to run them.
*
* Input Parameters:
* cpu - The index of the CPU to be paused.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
* Assumptions:
* Called from within a critical section;
*
****************************************************************************/
int up_send_smp_sched(int cpu)
{
arm_cpu_sgi(GIC_SMP_SCHED, (1 << cpu));
return OK;
}
/****************************************************************************
* Name: up_send_smp_call
*
* Description:
* Send smp call to target cpu.
*
* Input Parameters:
* cpuset - The set of CPUs to receive the SGI.
*
* Returned Value:
* None.
*
****************************************************************************/
void up_send_smp_call(cpu_set_t cpuset)
{
up_trigger_irq(GIC_SMP_CALL, cpuset);
}
#endif /* CONFIG_SMP */

View file

@ -156,7 +156,8 @@ static void dispatch_syscall(void)
uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb;
struct tcb_s *tcb = this_task();
uint32_t cmd;
int cpu;
#ifdef CONFIG_BUILD_PROTECTED
@ -167,6 +168,8 @@ uint32_t *arm_syscall(uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
tcb->xcp.regs = regs;
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/
@ -268,7 +271,7 @@ uint32_t *arm_syscall(uint32_t *regs)
* set will determine the restored context.
*/
up_set_current_regs((uint32_t *)regs[REG_R1]);
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
DEBUGASSERT(up_current_regs());
}
break;
@ -294,7 +297,7 @@ uint32_t *arm_syscall(uint32_t *regs)
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
up_set_current_regs((uint32_t *)regs[REG_R2]);
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
}
break;
@ -424,7 +427,7 @@ uint32_t *arm_syscall(uint32_t *regs)
/* Copy "info" into user stack */
if (rtcb->xcp.sigdeliver)
if (rtcb->sigdeliver)
{
usp = rtcb->xcp.saved_regs[REG_SP];
}
@ -561,22 +564,25 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}
/* Restore the cpu lock */
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
{
cpu = this_cpu();
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[cpu]);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
*/
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;
/* Restore the cpu lock */
restore_critical_section(tcb, cpu);
regs = up_current_regs();
regs = tcb->xcp.regs;
}
/* Report what happened */

View file

@ -608,12 +608,12 @@
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
# define GIC_SMP_CALL GIC_IRQ_SGI10
# define GIC_SMP_SCHED GIC_IRQ_SGI11
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
# define GIC_SMP_CALL GIC_IRQ_SGI2
# define GIC_SMP_SCHED GIC_IRQ_SGI3
#endif
/****************************************************************************
@ -804,14 +804,14 @@ int arm_start_handler(int irq, void *context, void *arg);
#endif
/****************************************************************************
* Name: arm_pause_handler
* Name: arm_smp_sched_handler
*
* Description:
* This is the handler for SGI2. It performs the following operations:
* This is the handler for sched.
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It waits on a spinlock, then
* 2. It porcess g_delivertasks
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
@ -824,7 +824,7 @@ int arm_start_handler(int irq, void *context, void *arg);
****************************************************************************/
#ifdef CONFIG_SMP
int arm_pause_handler(int irq, void *context, void *arg);
int arm_smp_sched_handler(int irq, void *context, void *arg);
#endif
/****************************************************************************

View file

@ -35,79 +35,60 @@
#include "arm_internal.h"
#include "exc_return.h"
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Name: arm_from_thread
*
* Description:
* If not defined CONFIG_ARCH_HAVE_TRUSTZONE
* Return true if interrupt return to thread mode, false otherwise.
*
* If defined CONFIG_ARCH_HAVE_TRUSTZONE
* Return true if interrupt return to thread mode, or if it is the first
* interrupt from TEE to REE, or REE to TEE, false otherwise.
*
* Interrupt nesting between TEE and REE can be determined based
* on the S and ES bits of EXC_RETURN
* If TEE interrupts REE, then EXC_RETURN.S=0, EXC_RETURN.ES=1;
* Conversely, EXC_RETURN.S=1, EXC_RETURN.ES=0.
*
* But only one level nesting between TEE and REE is supported, and
* recursive nesting between TEE and REE is not supported.
*
****************************************************************************/
static inline bool arm_from_thread(uint32_t excret)
{
if (excret & EXC_RETURN_THREAD_MODE)
{
return true;
}
#if defined(CONFIG_ARCH_TRUSTZONE_SECURE)
if (!(excret & EXC_RETURN_SECURE_STACK) &&
(excret & EXC_RETURN_EXC_SECURE))
{
return true;
}
if (!(excret & EXC_RETURN_EXC_SECURE) &&
(excret & EXC_RETURN_SECURE_STACK))
{
return true;
}
#endif
return false;
}
#include "nvic.h"
/****************************************************************************
* Public Functions
****************************************************************************/
void exception_direct(void)
{
int irq = getipsr();
arm_ack_irq(irq);
irq_dispatch(irq, NULL);
if (g_running_tasks[this_cpu()] != this_task())
{
up_trigger_irq(NVIC_IRQ_PENDSV, 0);
}
}
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
if (arm_from_thread(regs[REG_EXC_RETURN]))
{
up_set_current_regs(regs);
}
/* Acknowledge the interrupt */
arm_ack_irq(irq);
/* Deliver the IRQ */
/* Set current regs for crash dump */
irq_dispatch(irq, regs);
up_set_current_regs(regs);
if (irq == NVIC_IRQ_PENDSV)
{
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
/* Dispatch the PendSV interrupt */
irq_dispatch(irq, regs);
#endif
up_irq_save();
g_running_tasks[this_cpu()]->xcp.regs = regs;
}
else
{
/* Dispatch irq */
tcb->xcp.regs = regs;
irq_dispatch(irq, regs);
}
/* If a context switch occurred while processing the interrupt then
* current_regs may have change value. If we return any value different
@ -115,27 +96,26 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* switch occurred during interrupt processing.
*/
if (arm_from_thread(regs[REG_EXC_RETURN]))
{
/* Restore the cpu lock */
tcb = this_task();
if (regs != up_current_regs())
{
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
/* Update scheduler parameters */
g_running_tasks[this_cpu()] = this_task();
regs = up_current_regs();
}
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_resume_scheduler(tcb);
/* Update the current_regs to NULL. */
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
up_set_current_regs(NULL);
}
g_running_tasks[this_cpu()] = tcb;
regs = tcb->xcp.regs;
#endif
/* Clear current regs */
up_set_current_regs(NULL);
board_autoled_off(LED_INIRQ);
#ifdef CONFIG_ARMV8M_TRUSTZONE_HYBRID

View file

@ -169,7 +169,7 @@ void up_initial_state(struct tcb_s *tcb)
#else /* CONFIG_SUPPRESS_INTERRUPTS */
#ifdef CONFIG_ARMV8M_USEBASEPRI
xcp->regs[REG_BASEPRI] = NVIC_SYSH_PRIORITY_MIN;
xcp->regs[REG_BASEPRI] = 0;
#endif
#endif /* CONFIG_SUPPRESS_INTERRUPTS */

View file

@ -79,348 +79,64 @@
*
****************************************************************************/
#ifndef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
void up_schedule_sigaction(struct tcb_s *tcb)
{
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
DEBUGASSERT(tcb != NULL && sigdeliver != NULL);
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb, this_task(),
this_task()->xcp.regs);
/* Refuse to handle nested signal actions */
/* First, handle some special cases when the signal is
* being delivered to the currently executing task.
*/
if (tcb->xcp.sigdeliver == NULL)
if (tcb == this_task() && !up_interrupt_context())
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to the currently executing task.
/* In this case just deliver the signal now.
* REVISIT: Signal handle will run in a critical section!
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb == this_task())
{
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (!up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handle will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: We are in an interrupt handler AND the interrupted
* task is the same as the one that must receive the signal, then
* we will have to modify the return state as well as the state in
* the TCB.
*/
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* And make sure that the saved context in the TCB is the same
* as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs() +
XCPTCONTEXT_REGS);
/* Then set up to vector to the trampoline with interrupts
* disabled. The kernel-space trampoline must run in
* privileged thread mode.
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV8M_USEBASEPRI
up_current_regs()[REG_BASEPRI] =
NVIC_SYSH_DISABLE_PRIORITY;
#else
up_current_regs()[REG_PRIMASK] = 1;
#endif
up_current_regs()[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
up_current_regs()[REG_LR] = EXC_RETURN_THREAD;
up_current_regs()[REG_EXC_RETURN] = EXC_RETURN_THREAD;
up_current_regs()[REG_CONTROL] = getcontrol() &
~CONTROL_NPRIV;
#endif
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling* some non-running task.
(tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
/* Save the current register context location */
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV8M_USEBASEPRI
tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
#else
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_PRIMASK] = 1;
#endif
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
}
#endif /* !CONFIG_SMP */
#ifdef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
int cpu;
int me;
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
/* Refuse to handle nested signal actions */
if (!tcb->xcp.sigdeliver)
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to task that is currently executing on any CPU.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb->task_state == TSTATE_TASK_RUNNING)
{
me = this_cpu();
cpu = tcb->cpu;
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (cpu == me && !up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/
else
{
/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/
if (cpu != me)
{
/* Pause the CPU */
up_cpu_pause(cpu);
/* Now tcb on the other CPU can be accessed safely */
/* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode
* to be here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV8M_USEBASEPRI
tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
#else
tcb->xcp.regs[REG_PRIMASK] = 1;
#endif
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
else
{
/* tcb is running on the same CPU */
/* Save the return PC, CPSR and either the BASEPRI or
* PRIMASK registers (and perhaps also the LR). These
* will be restored by the signal trampoline after the
* signal has been delivered.
*/
/* And make sure that the saved context in the TCB is the
* same as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs()
+ XCPTCONTEXT_REGS);
/* Then set up vector to the trampoline with interrupts
* disabled. The kernel-space trampoline must run in
* privileged thread mode.
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV8M_USEBASEPRI
up_current_regs()[REG_BASEPRI] =
NVIC_SYSH_DISABLE_PRIORITY;
#else
up_current_regs()[REG_PRIMASK] = 1;
#endif
up_current_regs()[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
up_current_regs()[REG_LR] = EXC_RETURN_THREAD;
up_current_regs()[REG_CONTROL] = getcontrol() &
~CONTROL_NPRIV;
#endif
}
/* RESUME the other CPU if it was PAUSED */
if (cpu != me)
{
up_cpu_resume(cpu);
}
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling some other non-running task.
*/
else
{
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
#ifdef CONFIG_ARMV8M_USEBASEPRI
tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
#else
tcb->xcp.regs[REG_PRIMASK] = 1;
#endif
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
}
#endif /* CONFIG_SMP */

View file

@ -68,8 +68,8 @@ void arm_sigdeliver(void)
board_autoled_on(LED_SIGNAL);
sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
rtcb, rtcb->sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->sigdeliver != NULL);
retry:
#ifdef CONFIG_SMP
@ -105,7 +105,7 @@ retry:
/* Deliver the signal */
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
(rtcb->sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -156,7 +156,7 @@ retry:
* could be modified by a hostile program.
*/
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
rtcb->sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of
* execution.

View file

@ -24,6 +24,7 @@
#include <nuttx/config.h>
#include <inttypes.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
@ -124,10 +125,10 @@ static void dispatch_syscall(void)
int arm_svcall(int irq, void *context, void *arg)
{
struct tcb_s *tcb = this_task();
uint32_t *regs = (uint32_t *)context;
uint32_t cmd;
DEBUGASSERT(regs && regs == up_current_regs());
cmd = regs[REG_R0];
/* The SVCall software interrupt is called with R0 = system call command
@ -175,7 +176,7 @@ int arm_svcall(int irq, void *context, void *arg)
case SYS_restore_context:
{
DEBUGASSERT(regs[REG_R1] != 0);
up_set_current_regs((uint32_t *)regs[REG_R1]);
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
}
break;
@ -200,7 +201,7 @@ int arm_svcall(int irq, void *context, void *arg)
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
up_set_current_regs((uint32_t *)regs[REG_R2]);
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
}
break;
@ -397,7 +398,6 @@ int arm_svcall(int irq, void *context, void *arg)
/* Return privileged mode */
regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
rtcb->xcp.sigreturn = 0;
}
break;
@ -446,7 +446,7 @@ int arm_svcall(int irq, void *context, void *arg)
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", (int)regs[REG_R0]);
svcerr("ERROR: Bad SYS call: %" PRId32 "\n", regs[REG_R0]);
#endif
}
break;
@ -460,24 +460,20 @@ int arm_svcall(int irq, void *context, void *arg)
# ifndef CONFIG_DEBUG_SVCALL
if (cmd > SYS_switch_context)
# else
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
# endif
{
regs = (uint32_t *)tcb->xcp.regs;
svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
up_current_regs()[REG_R0], up_current_regs()[REG_R1],
up_current_regs()[REG_R2], up_current_regs()[REG_R3],
up_current_regs()[REG_R4], up_current_regs()[REG_R5],
up_current_regs()[REG_R6], up_current_regs()[REG_R7]);
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
up_current_regs()[REG_R8], up_current_regs()[REG_R9],
up_current_regs()[REG_R10], up_current_regs()[REG_R11],
up_current_regs()[REG_R12], up_current_regs()[REG_R13],
up_current_regs()[REG_R14], up_current_regs()[REG_R15]);
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
up_current_regs()[REG_XPSR],
up_current_regs()[REG_EXC_RETURN],
up_current_regs()[REG_CONTROL]);
regs[REG_XPSR], regs[REG_EXC_RETURN], regs[REG_CONTROL]);
}
# ifdef CONFIG_DEBUG_SVCALL
else

View file

@ -40,6 +40,8 @@
#include "chip.h"
#include "arm_internal.h"
#include "ram_vectors.h"
#include "nvic.h"
/****************************************************************************
* Pre-processor Definitions
@ -74,12 +76,13 @@ static void start(void)
/* Common exception entrypoint */
extern void exception_common(void);
extern void exception_direct(void);
/****************************************************************************
* Public data
****************************************************************************/
/* The v7m vector table consists of an array of function pointers, with the
/* The v8m vector table consists of an array of function pointers, with the
* first slot (vector zero) used to hold the initial stack pointer.
*
* As all exceptions (interrupts) are routed via exception_common, we just
@ -100,5 +103,7 @@ const void * const _vectors[] locate_data(".vectors") =
/* Vectors 2 - n point directly at the generic handler */
[2 ... (15 + ARMV8M_PERIPHERAL_INTERRUPTS)] = &exception_common
[2 ... NVIC_IRQ_PENDSV] = &exception_common,
[(NVIC_IRQ_PENDSV + 1) ... (15 + ARMV8M_PERIPHERAL_INTERRUPTS)]
= &exception_direct
};

View file

@ -42,6 +42,8 @@
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
@ -51,6 +53,16 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
/* if irq == GIC_SMP_CPUSTART
* We are initiating the multi-core jumping state to up_idle,
* and we will use this_task(). Therefore, it cannot be overridden.
*/
if (irq != GIC_SMP_CPUSTART)
{
tcb->xcp.regs = regs;
}
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/
@ -61,17 +73,22 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
irq_dispatch(irq, regs);
/* Restore the cpu lock */
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
{
tcb = this_task();
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
g_running_tasks[this_cpu()] = this_task();
regs = up_current_regs();
regs = tcb->xcp.regs;
}
/* Set current_regs to NULL to indicate that we are no longer in an

View file

@ -311,12 +311,12 @@
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
# define GIC_SMP_CALL GIC_IRQ_SGI10
# define GIC_SMP_SCHED GIC_IRQ_SGI11
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
# define GIC_SMP_CALL GIC_IRQ_SGI2
# define GIC_SMP_SCHED GIC_IRQ_SGI3
#endif
/****************************************************************************
@ -333,28 +333,7 @@ int arm_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list);
#ifdef CONFIG_SMP
/****************************************************************************
* Name: arm_pause_handler
*
* Description:
* This is the handler for SGI2. It performs the following operations:
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It waits on a spinlock, then
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
* Input Parameters:
* Standard interrupt handling
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int arm_pause_handler(int irq, void *context, void *arg);
int arm_smp_sched_handler(int irq, void *context, void *arg);
void arm_gic_secondary_init(void);
#endif

View file

@ -567,9 +567,8 @@ static void gicv3_dist_init(void)
#ifdef CONFIG_SMP
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_SCHED, arm64_smp_sched_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CALL, nxsched_smp_call_handler, NULL));
#endif
}
@ -813,7 +812,8 @@ static void arm_gic_init(void)
gicv3_cpuif_init();
#ifdef CONFIG_SMP
up_enable_irq(GIC_SMP_CPUPAUSE);
up_enable_irq(GIC_SMP_CALL);
up_enable_irq(GIC_SMP_SCHED);
#endif
}
@ -841,24 +841,4 @@ void arm_gic_secondary_init(void)
arm_gic_init();
}
# ifdef CONFIG_SMP
/***************************************************************************
* Name: up_send_smp_call
*
* Description:
* Send smp call to target cpu.
*
* Input Parameters:
* cpuset - The set of CPUs to receive the SGI.
*
* Returned Value:
* None.
*
***************************************************************************/
void up_send_smp_call(cpu_set_t cpuset)
{
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
}
# endif
#endif

View file

@ -75,342 +75,56 @@
*
****************************************************************************/
#ifndef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
void up_schedule_sigaction(struct tcb_s *tcb)
{
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb, this_task(),
this_task()->xcp.regs);
/* Refuse to handle nested signal actions */
/* First, handle some special cases when the signal is
* being delivered to the currently executing task.
*/
if (!tcb->xcp.sigdeliver)
if (tcb == this_task() && !up_interrupt_context())
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to the currently executing task.
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb == this_task())
{
/* CASE 1: We are not in an interrupt handler and a task is
* signalling itself for some reason.
*/
if (!up_current_regs())
{
/* In this case just deliver the signal now. */
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: We are in an interrupt handler AND the interrupted
* task is the same as the one that must receive the signal, then
* we will have to modify the return state as well as the state
* in the TCB.
*
* Hmmm... there looks like a latent bug here: The following logic
* would fail in the strange case where we are in an interrupt
* handler, the thread is signalling itself, but a context switch
* to another task has occurred so that current_regs does not
* refer to the thread of this_task()!
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
*/
/* And make sure that the saved context in the TCB is the same
* as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs() +
XCPTCONTEXT_REGS);
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
up_current_regs()[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
up_current_regs()[REG_CPSR] |= PSR_T_BIT;
#endif
#ifdef CONFIG_ENDIAN_BIG
up_current_regs()[REG_CPSR] |= PSR_E_BIT;
#endif
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signalling some non-running task.
(tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
/* Save the current register context location */
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
#ifdef CONFIG_ENDIAN_BIG
tcb->xcp.regs[REG_CPSR] |= PSR_E_BIT;
#endif
}
}
}
#else
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
int cpu;
int me;
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
/* Refuse to handle nested signal actions */
if (!tcb->xcp.sigdeliver)
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to task that is currently executing on any CPU.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb->task_state == TSTATE_TASK_RUNNING)
{
me = this_cpu();
cpu = tcb->cpu;
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (cpu == me && !up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/
else
{
/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/
if (cpu != me)
{
/* Pause the CPU */
up_cpu_pause(cpu);
/* Now tcb on the other CPU can be accessed safely */
/* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
}
else
{
/* tcb is running on the same CPU */
/* Save the return PC, CPSR and either the BASEPRI or
* PRIMASK registers (and perhaps also the LR). These will
* be restored by the signal trampoline after the signal
* has been delivered.
*/
/* And make sure that the saved context in the TCB is the
* same as the interrupt return context.
*/
arm_savestate(tcb->xcp.saved_regs);
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
up_set_current_regs(up_current_regs() - XCPTCONTEXT_REGS);
memcpy(up_current_regs(), tcb->xcp.saved_regs,
XCPTCONTEXT_SIZE);
up_current_regs()[REG_SP] = (uint32_t)(up_current_regs()
+ XCPTCONTEXT_REGS);
/* Then set up vector to the trampoline with interrupts
* disabled. The kernel-space trampoline must run in
* privileged thread mode.
*/
up_current_regs()[REG_PC] = (uint32_t)arm_sigdeliver;
up_current_regs()[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
up_current_regs()[REG_CPSR] |= PSR_T_BIT;
#endif
}
/* Increment the IRQ lock count so that when the task is
* restarted, it will hold the IRQ spinlock.
*/
DEBUGASSERT(tcb->irqcount < INT16_MAX);
tcb->irqcount++;
/* NOTE: If the task runs on another CPU(cpu), adjusting
* global IRQ controls will be done in the pause handler
* on the CPU(cpu) by taking a critical section.
* If the task is scheduled on this CPU(me), do nothing
* because this CPU already took a critical section
*/
/* RESUME the other CPU if it was PAUSED */
if (cpu != me)
{
up_cpu_resume(cpu);
}
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling some other non-running task.
*/
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
/* Increment the IRQ lock count so that when the task is restarted,
* it will hold the IRQ spinlock.
*/
DEBUGASSERT(tcb->irqcount < INT16_MAX);
tcb->irqcount++;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT);
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
}
}
}
#endif

View file

@ -68,8 +68,8 @@ void arm_sigdeliver(void)
board_autoled_on(LED_SIGNAL);
sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
rtcb, rtcb->sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->sigdeliver != NULL);
retry:
#ifdef CONFIG_SMP
@ -101,7 +101,7 @@ retry:
/* Deliver the signal */
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
(rtcb->sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -145,7 +145,7 @@ retry:
* could be modified by a hostile program.
*/
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
rtcb->sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View file

@ -156,7 +156,7 @@ static void dispatch_syscall(void)
uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb;
struct tcb_s *tcb = this_task();
uint32_t cmd;
int cpu;
#ifdef CONFIG_BUILD_PROTECTED
@ -167,6 +167,8 @@ uint32_t *arm_syscall(uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
tcb->xcp.regs = regs;
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/
@ -268,7 +270,7 @@ uint32_t *arm_syscall(uint32_t *regs)
* set will determine the restored context.
*/
up_set_current_regs((uint32_t *)regs[REG_R1]);
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
DEBUGASSERT(up_current_regs());
}
break;
@ -294,7 +296,7 @@ uint32_t *arm_syscall(uint32_t *regs)
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
up_set_current_regs((uint32_t *)regs[REG_R2]);
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
}
break;
@ -424,7 +426,7 @@ uint32_t *arm_syscall(uint32_t *regs)
/* Copy "info" into user stack */
if (rtcb->xcp.sigdeliver)
if (rtcb->sigdeliver)
{
usp = rtcb->xcp.saved_regs[REG_SP];
}
@ -561,22 +563,25 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}
/* Restore the cpu lock */
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
{
cpu = this_cpu();
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[cpu]);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
*/
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;
/* Restore the cpu lock */
restore_critical_section(tcb, cpu);
regs = up_current_regs();
regs = tcb->xcp.regs;
}
/* Report what happened */

View file

@ -1586,7 +1586,7 @@ static int at32can_rxinterrupt(struct can_dev_s *dev, int rxmb)
#ifdef CONFIG_CAN_ERRORS
hdr.ch_error = 0; /* Error reporting not supported */
#endif
hdr.ch_unused = 0;
hdr.ch_tcf = 0;
/* Extract the RTR bit */
@ -1895,7 +1895,7 @@ static int at32can_sceinterrupt(int irq, void *context, void *arg)
#ifdef CONFIG_CAN_EXTID
hdr.ch_extid = 0;
#endif
hdr.ch_unused = 0;
hdr.ch_tcf = 0;
/* And provide the error report to the upper half logic */

View file

@ -56,12 +56,6 @@ void up_exit(int status)
{
struct tcb_s *tcb = this_task();
/* Make sure that we are in a critical section with local interrupts.
* The IRQ state will be restored when the next task is started.
*/
enter_critical_section();
/* Destroy the task at the head of the ready to run list. */
nxtask_exit();

View file

@ -96,11 +96,6 @@
#define INTSTACK_SIZE (CONFIG_ARCH_INTERRUPTSTACK & ~STACK_ALIGN_MASK)
/* Macros to handle saving and restoring interrupt state. */
#define arm_savestate(regs) (regs = up_current_regs())
#define arm_restorestate(regs) up_set_current_regs(regs)
/* Toolchain dependent, linker defined section addresses */
#if defined(__ICCARM__)

View file

@ -55,39 +55,10 @@
void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
{
/* Update scheduler parameters */
nxsched_suspend_scheduler(rtcb);
/* Are we in an interrupt handler? */
if (up_current_regs())
if (!up_interrupt_context())
{
/* Yes, then we have to do things differently.
* Just copy the current_regs into the OLD rtcb.
*/
arm_savestate(rtcb->xcp.regs);
/* Update scheduler parameters */
nxsched_resume_scheduler(tcb);
/* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
*/
arm_restorestate(tcb->xcp.regs);
}
/* No, then we will need to perform the user context switch */
else
{
/* Update scheduler parameters */
nxsched_resume_scheduler(tcb);
/* Switch context to the context of the task at the head of the
* ready to run list.
*/

View file

@ -42,7 +42,7 @@ set(SRCS
if(CONFIG_SMP)
list(APPEND SRCS cxd56_cpuidlestack.c)
list(APPEND SRCS cxd56_cpuindex.c)
list(APPEND SRCS cxd56_cpupause.c)
list(APPEND SRCS cxd56_smpcall.c)
list(APPEND SRCS cxd56_cpustart.c)
if(CONFIG_CXD56_TESTSET)
list(APPEND SRCS cxd56_testset.c)

View file

@ -41,7 +41,7 @@ CHIP_CSRCS += cxd56_sysctl.c
ifeq ($(CONFIG_SMP), y)
CHIP_CSRCS += cxd56_cpuidlestack.c
CHIP_CSRCS += cxd56_cpuindex.c
CHIP_CSRCS += cxd56_cpupause.c
CHIP_CSRCS += cxd56_smpcall.c
CHIP_CSRCS += cxd56_cpustart.c
ifeq ($(CONFIG_CXD56_TESTSET),y)
CHIP_CSRCS += cxd56_testset.c

View file

@ -1,584 +0,0 @@
/****************************************************************************
* arch/arm/src/cxd56xx/cxd56_cpupause.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <string.h>
#include <stdio.h>
#include <nuttx/arch.h>
#include <nuttx/spinlock.h>
#include <nuttx/sched_note.h>
#include "sched/sched.h"
#include "arm_internal.h"
#include "hardware/cxd5602_memorymap.h"
#ifdef CONFIG_SMP
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if 0
# define DPRINTF(fmt, args...) _err(fmt, ##args)
#else
# define DPRINTF(fmt, args...) do {} while (0)
#endif
#define CXD56_CPU_P2_INT (CXD56_SWINT_BASE + 0x8) /* for APP_DSP0 */
/****************************************************************************
* Private Data
****************************************************************************/
/* These spinlocks are used in the SMP configuration in order to implement
* up_cpu_pause(). The protocol for CPUn to pause CPUm is as follows
*
* 1. The up_cpu_pause() implementation on CPUn locks both g_cpu_wait[m]
* and g_cpu_paused[m]. CPUn then waits spinning on g_cpu_paused[m].
* 2. CPUm receives the interrupt it (1) unlocks g_cpu_paused[m] and
* (2) locks g_cpu_wait[m]. The first unblocks CPUn and the second
* blocks CPUm in the interrupt handler.
*
* When CPUm resumes, CPUn unlocks g_cpu_wait[m] and the interrupt handler
* on CPUm continues. CPUm must, of course, also then unlock g_cpu_wait[m]
* so that it will be ready for the next pause operation.
*/
static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS];
static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS];
static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS];
static volatile int g_irq_to_handle[CONFIG_SMP_NCPUS][2];
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: handle_irqreq
*
* Description:
* If an irq handling request is found on cpu, call up_enable_irq() or
* up_disable_irq(), then return true.
*
* Input Parameters:
* cpu - The index of the CPU to be queried
*
* Returned Value:
* true = an irq handling request is found
* false = no irq handling request is found
*
****************************************************************************/
static bool handle_irqreq(int cpu)
{
int i;
bool handled = false;
/* Check both cases */
for (i = 0; i < 2; i++)
{
int irqreq = g_irq_to_handle[cpu][i];
if (irqreq)
{
/* Unlock the spinlock first */
spin_unlock(&g_cpu_paused[cpu]);
/* Then wait for the spinlock to be released */
spin_lock(&g_cpu_wait[cpu]);
/* Clear g_irq_to_handle[cpu][i] */
g_irq_to_handle[cpu][i] = 0;
if (0 == i)
{
up_enable_irq(irqreq);
}
else
{
up_disable_irq(irqreq);
}
/* Finally unlock the spinlock */
spin_unlock(&g_cpu_wait[cpu]);
handled = true;
break;
}
}
return handled;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_cpu_pausereq
*
* Description:
* Return true if a pause request is pending for this CPU.
*
* Input Parameters:
* cpu - The index of the CPU to be queried
*
* Returned Value:
* true = a pause request is pending.
* false = no pasue request is pending.
*
****************************************************************************/
bool up_cpu_pausereq(int cpu)
{
return spin_is_locked(&g_cpu_paused[cpu]);
}
/****************************************************************************
* Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
* executed from interrupt handling logic within the architecture-specific
* However, it is sometimes necessary to perform the pending
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
* Input Parameters:
* None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
* the nature of the failure is returned.
*
****************************************************************************/
int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
/* Update scheduler parameters */
nxsched_suspend_scheduler(tcb);
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we are paused */
sched_note_cpu_paused(tcb);
#endif
/* Save the current context at current_regs into the TCB at the head
* of the assigned task list for this CPU.
*/
arm_savestate(tcb->xcp.regs);
return OK;
}
/****************************************************************************
* Name: up_cpu_paused
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
* executed from interrupt handling logic within the architecture-specific
* However, it is sometimes necessary to perform the pending
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
* This function performs the following operations:
*
* 1. It saves the current task state at the head of the current assigned
* task list.
* 2. It waits on a spinlock, then
* 3. Returns from interrupt, restoring the state of the new task at the
* head of the ready to run list.
*
* Input Parameters:
* cpu - The index of the CPU to be paused
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
* the nature of the failure is returned.
*
****************************************************************************/
int up_cpu_paused(int cpu)
{
/* Fistly, check if this IPI is to enable/disable IRQ */
if (handle_irqreq(cpu))
{
return OK;
}
/* Wait for the spinlock to be released */
spin_unlock(&g_cpu_paused[cpu]);
/* Ensure the CPU has been resumed to avoid causing a deadlock */
spin_lock(&g_cpu_resumed[cpu]);
spin_lock(&g_cpu_wait[cpu]);
spin_unlock(&g_cpu_wait[cpu]);
spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
/****************************************************************************
* Name: up_cpu_paused_restore
*
* Description:
* Restore the state of the CPU after it was paused via up_cpu_pause(),
* and resume normal tasking.
*
* Input Parameters:
* None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
* the nature of the failure is returned.
*
****************************************************************************/
int up_cpu_paused_restore(void)
{
struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
sched_note_cpu_resumed(tcb);
#endif
/* Reset scheduler parameters */
nxsched_resume_scheduler(tcb);
/* Then switch contexts. Any necessary address environment changes
* will be made when the interrupt returns.
*/
arm_restorestate(tcb->xcp.regs);
return OK;
}
/****************************************************************************
* Name: arm_pause_handler
*
* Description:
* Inter-CPU interrupt handler
*
* Input Parameters:
* Standard interrupt handler inputs
*
* Returned Value:
* Should always return OK
*
****************************************************************************/
int arm_pause_handler(int irq, void *c, void *arg)
{
int cpu = this_cpu();
int ret = OK;
nxsched_smp_call_handler(irq, c, arg);
DPRINTF("cpu%d will be paused\n", cpu);
/* Clear SW_INT for APP_DSP(cpu) */
putreg32(0, CXD56_CPU_P2_INT + (4 * cpu));
/* Check for false alarms. Such false could occur as a consequence of
* some deadlock breaking logic that might have already serviced the SG2
* interrupt by calling up_cpu_paused.
*/
if (up_cpu_pausereq(cpu))
{
/* NOTE: The following enter_critical_section() would call
* up_cpu_paused() to process a pause request to break a deadlock
* because the caller held a critical section. Once up_cpu_paused()
* finished, the caller will proceed and release the g_cpu_irqlock.
* Then this CPU will acquire g_cpu_irqlock in the function.
*/
irqstate_t flags = enter_critical_section();
/* NOTE: Normally, we do not call up_cpu_paused() here because
* the above enter_critical_setion() would call up_cpu_paused()
* inside because the caller holds a crtical section.
* However, cxd56's remote IRQ control logic also uses this handler
* and a caller might not take a critical section to avoid a deadlock
* during up_enable_irq() and up_disable_irq(). This is allowed
* because IRQ control logic does not interact wtih the scheduler.
* This means that if the request was not handled above, we need
* to call up_cpu_paused() here again.
*/
if (up_cpu_pausereq(cpu))
{
ret = up_cpu_paused(cpu);
}
leave_critical_section(flags);
}
return ret;
}
/****************************************************************************
* Name: up_cpu_pause_async
*
* Description:
* pause task execution on the CPU
* check whether there are tasks delivered to specified cpu
* and try to run them.
*
* Input Parameters:
* cpu - The index of the CPU to be paused.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
* Assumptions:
* Called from within a critical section;
*
****************************************************************************/
inline_function int up_cpu_pause_async(int cpu)
{
/* Generate IRQ for CPU(cpu) */
putreg32(1, CXD56_CPU_P2_INT + (4 * cpu));
return OK;
}
/****************************************************************************
* Name: up_send_smp_call
*
* Description:
* Send smp call to target cpu.
*
* Input Parameters:
* cpuset - The set of CPUs to receive the SGI.
*
* Returned Value:
* None.
*
****************************************************************************/
void up_send_smp_call(cpu_set_t cpuset)
{
int cpu;
for (; cpuset != 0; cpuset &= ~(1 << cpu))
{
cpu = ffs(cpuset) - 1;
up_cpu_pause_async(cpu);
}
}
/****************************************************************************
* Name: up_cpu_pause
*
* Description:
* Save the state of the current task at the head of the
* g_assignedtasks[cpu] task list and then pause task execution on the
* CPU.
*
* This function is called by the OS when the logic executing on one CPU
* needs to modify the state of the g_assignedtasks[cpu] list for another
* CPU.
*
* Input Parameters:
* cpu - The index of the CPU to be stopped/
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int up_cpu_pause(int cpu)
{
DPRINTF("cpu=%d\n", cpu);
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the pause event */
sched_note_cpu_pause(this_task(), cpu);
#endif
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the
* handler from returning until up_cpu_resume() is called; g_cpu_paused
* is a handshake that will prefent this function from returning until
* the CPU is actually paused.
* Note that we might spin before getting g_cpu_wait, this just means that
* the other CPU still hasn't finished responding to the previous resume
* request.
*/
DEBUGASSERT(!spin_is_locked(&g_cpu_paused[cpu]));
spin_lock(&g_cpu_wait[cpu]);
spin_lock(&g_cpu_paused[cpu]);
/* Generate IRQ for CPU(cpu) */
up_cpu_pause_async(cpu);
/* Wait for the other CPU to unlock g_cpu_paused meaning that
* it is fully paused and ready for up_cpu_resume();
*/
spin_lock(&g_cpu_paused[cpu]);
spin_unlock(&g_cpu_paused[cpu]);
/* On successful return g_cpu_wait will be locked, the other CPU will be
* spinning on g_cpu_wait and will not continue until g_cpu_resume() is
* called. g_cpu_paused will be unlocked in any case.
*/
return OK;
}
/****************************************************************************
* Name: up_cpu_resume
*
* Description:
* Restart the cpu after it was paused via up_cpu_pause(), restoring the
* state of the task at the head of the g_assignedtasks[cpu] list, and
* resume normal tasking.
*
* This function is called after up_cpu_pause in order resume operation of
* the CPU after modifying its g_assignedtasks[cpu] list.
*
* Input Parameters:
* cpu - The index of the CPU being re-started.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int up_cpu_resume(int cpu)
{
DPRINTF("cpu=%d\n", cpu);
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the resume event */
sched_note_cpu_resume(this_task(), cpu);
#endif
/* Release the spinlock. Releasing the spinlock will cause the SGI2
* handler on 'cpu' to continue and return from interrupt to the newly
* established thread.
*/
DEBUGASSERT(spin_is_locked(&g_cpu_wait[cpu]) &&
!spin_is_locked(&g_cpu_paused[cpu]));
spin_unlock(&g_cpu_wait[cpu]);
/* Ensure the CPU has been resumed to avoid causing a deadlock */
spin_lock(&g_cpu_resumed[cpu]);
spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
/****************************************************************************
* Name: up_send_irqreq()
*
* Description:
* Send up_enable_irq() / up_disable_irq() request to the specified cpu
*
* This function is called from up_enable_irq() or up_disable_irq()
* to be handled on specified CPU. Locking protocol in the sequence is
* the same as up_pause_cpu() plus up_resume_cpu().
*
* Input Parameters:
* idx - The request index (0: enable, 1: disable)
* irq - The IRQ number to be handled
* cpu - The index of the CPU which will handle the request
*
****************************************************************************/
void up_send_irqreq(int idx, int irq, int cpu)
{
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
/* Wait for the spinlocks to be released */
spin_lock(&g_cpu_wait[cpu]);
spin_lock(&g_cpu_paused[cpu]);
/* Set irq for the cpu */
g_irq_to_handle[cpu][idx] = irq;
/* Generate IRQ for CPU(cpu) */
putreg32(1, CXD56_CPU_P2_INT + (4 * cpu));
/* Wait for the handler is executed on cpu */
spin_lock(&g_cpu_paused[cpu]);
spin_unlock(&g_cpu_paused[cpu]);
/* Finally unlock the spinlock to proceed the handler */
spin_unlock(&g_cpu_wait[cpu]);
/* Ensure the CPU has been resumed to avoid causing a deadlock */
spin_lock(&g_cpu_resumed[cpu]);
spin_unlock(&g_cpu_resumed[cpu]);
}
#endif /* CONFIG_SMP */

Some files were not shown because too many files have changed in this diff Show more