The way Cortex processors handle exceptions allows writing exception
routines directly in C, as return from exception is handled by providing
a special value for the link register.
However, it is not safe to do this when doing context switching. In
particular, C handlers may push some general-purpose registers that
are used by the handler and pop them later, even when context switch
has happened in the meantime. While the processor will restore {r0-r3}
from the stack when returning from an exception, the C handler code
may push, use and pop another register, such as r4.
It turns out that GCC 4.8 would generally only use r3 in svc_handler and
pendsv_handler, but newer versions tend to use r4, thus clobbering r4
that was restored from the context switch and leading up to a fault
when r4 is used by the task code.
An occurrence of this behaviour takes place with GCC > 4.8 in __wait_evt,
where "me" is stored in r4, which gets clobbered after an exception
triggers pendsv_handler. The exception handler uses r4 internally, does
a context switch and then restores the previous value of r4, which is
not restored by the processor's internal, thus clobbering r4.
This ends up with the following assertion failure:
'tskid < TASK_ID_COUNT' in timer_cancel() at common/timer.c:137
For this reason, it is safer to have assembly routines for exception
handlers that do context switching.
BUG=chromium:631514
BRANCH=None
TEST=Build and run speedy EC with a recent GCC version
Change-Id: Ib068bc12ce2204aee3e0f563efcb94f15aa87013
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
Reviewed-on: https://chromium-review.googlesource.com/362830
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Shawn N <shawnn@chromium.org>
Until HOOK_INIT has completed, do not allow any tasks other than HOOKS
or IDLE to be scheduled. Programmers often make the assumption that
a HOOK_INIT function is guaranteed to be run before task code that depends
on it, so let's make it so.
BUG=chromium:649398
BRANCH=None
TEST=Manual on kevin, compare boot without patch:
...
[0.004 power state 0 = G3, in 0x0008] <-- from chipset task
RTC: 0x00000000 (0.00 s)
[0.004 power state 4 = G3->S5, in 0x0008]
RTC: 0x00000000 (0.00 s)
[0.005 clear MKBP fifo]
[0.006 clear MKBP fifo]
[0.006 KB init state: ... <-- from keyscan task
[0.012 SW 0x05]
[0.155 hash start 0x00020000 0x00019a38]
[0.158 HOOK_INIT DONE!]
... to boot with patch:
...
RTC: 0x58cc614c (1489789260.00 s)
[0.004 clear MKBP fifo]
[0.005 clear MKBP fifo]
[0.010 SW 0x05]
[0.155 hash start 0x00020000 0x000198e0]
[0.157 HOOK_INIT DONE!]
...
Also, verify kevin boots to OS and is generally functional through
sysjump and basic tasks, and verify elm (stm32f0 / cortex-m0) boots.
Change-Id: If56fab05ce9b9650feb93c5cfc2d084aa281e622
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/456628
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
If there's a task switching occurred between loading waiter and
unlocking the lock, the task with higher priority won't wake up since
the local variable, waiter, doesn't contain its ID bit before task
switching. In this situation, the higher priority task only can be
awakened when the other tasks execute mutex_unlock() again.
But consider the following conditions: (For example, the driver of
charger bd9995x.)
1. There are more than one mutex for the usage path of i2c port.
2. There are more than one task access this usage path of i2c port and
one of these tasks, task A, met the situation above.
3. The other tasks have no chance to execute mutex_unlock() of i2c since
the task A still occupied the mutex of charger.
All the tasks used the same i2c port or the other hardware will sleep
forever. This CL makes loading waiter and unlocking the lock as atomic
to solve this issue.
BRANCH=none
BUG=chrome-os-partner:60617
TEST=make BOARD=snappy; make BOARD=oak; Executed charger factory test on
4 units of snappy for 3 days and no symptom occurred.
Change-Id: Id976fc47955b33ca83bb2182b197d9f2781c341b
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
Reviewed-on: https://chromium-review.googlesource.com/423285
Commit-Ready: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
In __wait_evt(), if a timer expiration occurs after we read event
status, before the timer is canceled, then TASK_EVENT_TIMER will be
propagated to the next task wait, likely leading to premature timeout.
Prevent this by clearing TASK_EVENT_TIMER after canceling our timer.
BUG=chrome-os-partner:58658
BRANCH=gru
TEST=Manual on gru, run 'pd # hard' for 12 hours with charger attached,
verify no TCPC I2C read errors occur.
Change-Id: Iac2f05a768b4ef29f82e7c3eb899f4c7dd5c3744
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/400968
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Since pretty much always, we've declared console commands to take
a "longhelp" argument with detailed explanations of what the
command does. But since almost as long, we've never actually used
that argument for anything - we just silently throw it away in
the macro. There's only one command (usbchargemode) that even
thinks it defines that argument.
We're never going to use this, let's just get rid of it.
BUG=none
BRANCH=none
CQ-DEPEND=CL:*279060
CQ-DEPEND=CL:*279158
CQ-DEPEND=CL:*279037
TEST=make buildall; tested on Cr50 hardware
Everything builds. Since we never used this arg anyway, there had
better not be any difference in the result.
Change-Id: Id3f71a53d02e3dc625cfcc12aa71ecb50e35eb9f
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/374163
Reviewed-by: Myles Watson <mylesgw@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
cts.tasklist contains tasks run only for CTS. These tasks are added to the
tasks registered in ec.tasklist with higher priority. This design allows
board directories to be free from CTS stuff.
cts.tasklist can be placed in each suite directory (cts/suite/cts.tasklist).
If a suite does not define its own cts.tasklist, the common list is used
(i.e. cts/cts.tasklist).
BUG=chromium:624520
BRANCH=none
TEST=Ran the followings:
make buildall
make CTS_MODULE=gpio BOARD=nucleo-f072rb
make CTS_MODULE=gpio BOARD=stm32l476g-eval
Change-Id: Ibb242297ee10a397a8fcb6ff73d8cbc560daa885
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/359445
Reviewed-by: Chris Chen <twothreecc@google.com>
On mutex contention, call task_wait_event_mask(), which will wait for
a mutex event without clearing other pending events.
BUG=chrome-os-partner:47918,chromium:435611,chromium:435612
BRANCH=None
TEST=Manual on snoball. Verify samus can successfully negotiate PD power
contract when attached to snoball.
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: I85cd32f2670246da9e4787025390aba2c93f9c36
Reviewed-on: https://chromium-review.googlesource.com/314492
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Returns the most significant bit set.
Replace 31 - __builtin_clz(x), so x must be different from 0.
Use get_next_bit when not on the performance path,
on performance path set the bit field just after reading it.
BRANCH=smaug
BUG=none
TEST=compile, check Ryu still works.
Change-Id: Ie1a4cda4188f45b4bf92d0549d5c8fb401a30e5d
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/301300
This commit changes the way in which tasks are started. Instead of
having all tasks marked as ready to run upon initialization, only the
hooks task is marked as ready to run. HOOK_INITs are now run at the
beginning of the hooks task. After the HOOK_INITs, the hooks task calls
back to enable the rest of the tasks, reschedules, and proceeds as
usual. This also allows the removal of checks for task_start_called().
BUG=chrome-os-partner:27226
BRANCH=None
TEST=Built and flash EC image for samus and verified that EC boot was
successful as well as AP boot. Additionally, verified that charging,
keyboard, tap-for-battery were all still functional.
TEST=make -j buildall tests
Change-Id: Iea53670222c803c2985e9c86c96974386888a4fe
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Reviewed-on: https://chromium-review.googlesource.com/283657
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Commit-Queue: Aseda Aboagye <aaboagye@chromium.org>
Tested-by: Aseda Aboagye <aaboagye@chromium.org>
If task_get_current() is called early during initialization when we have
not yet done a context switch, our current_task pointer is invalid. Add
an assert to detect this case and put it behind CONFIG_DEBUG_BRINGUP, a
new config that's intended to enable possibly-costly pre-production
debugging.
BUG=chrome-os-partner:40677
TEST=Manual on glados. Define CONFIG_DEBUG_BRINGUP, then call i2c_write from
board_init and verify the new assert fails. Remove the i2c_write and verify
the new assert passes.
BRANCH=None
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: I6014ccf739dcc4c8f4f960be2b89f01e423b65b5
Reviewed-on: https://chromium-review.googlesource.com/273541
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Add task_wait_event_mask() function to core/cortex-m0, core/host
and board/zinger/runtime in order to delay a task until a specific
event occurs.
BUG=none
BRANCH=smaug
TEST=make -j buildall
Change-Id: Ic89487fcae5352eec53b745179c7f0d5893ad3e0
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/276744
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Add CONFIG_LTO to use GCC Link-Time Optimizations to try to reduce the
flash footprint of the firmware.
Add additional protection to some functions/data to avoid removal by the
linker when their usage is not obvious.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=none
TEST=make buildall (with and without LTO enable on all boards)
Change-Id: I586b8c1eda4592b416c85383b65153c1d5ab0059
Reviewed-on: https://chromium-review.googlesource.com/271291
Trybot-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
On hard reset / hibernate, RAM will be erased and panic data will
normally be lost. When software panic data saving is enabled, try to
save this data just before hard reset and restore it when we come back
up.
BUG=chrome-os-partner:37380
TEST=Manual on Samus with WP + SW sync enabled. Boot AP, then run "crash
divzero" on console. After hard reset, verify that "panicinfo" dumps
data and shows divzero exception code.
BRANCH=Samus
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: I9516dd4b6db12ef35e512cc4710f9b97d7e663cb
Reviewed-on: https://chromium-review.googlesource.com/255912
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Make non-exception "software" panics such as stack overflow and assert
failure save a panic log. Log the panic type in r4, and misc. panic data
in r5 so that panic reasons can be distinguished.
BUG=chrome-os-partner:36744
TEST=Manual on samus_pd. Run 'crash divzero' then 'panicinfo' after
reboot. Verify that panic info is printed with "r4 :dead6660". Trigger
stack overflow, verify that panic info is printed with "r4 :dead6661".
BRANCH=Samus
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: I5f7a8eb0a5c2ac5799d29bb241deb24fabf38f68
Reviewed-on: https://chromium-review.googlesource.com/249912
Tested-by: Alec Berg <alecaberg@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
If 2 interrupts happen at the same time, there is a chance that the nested
interrupt will not call svc_handler when it needs to. In extreme cases this
could lead to tasks not getting woken up when they're supposed to and watchdog
resetting.
The reason stuff worked was because there were enough other interrupts
around to eventually call the scheduler and switch to the ready task.
This change modifies the interrupt calls to not call the scheduler directly
(because in nested interrupt situation this causes problems), but defer the
call to scheduling until after the irq finishes by triggering a low priority
interrupt which will for sure call svc_host at the end. The PendSV irq was
used for this purpose.
BUG=chrome-os-partner:36193
TEST=No more SPI errors caused by scheduler problems
TEST=usleeps now are more accurate, they're guaranteed to not take forever now
BRANCH=veyron
Change-Id: I42acde6b3eb7be2540a0de9a8562dee2ea2be7ab
Signed-off-by: Alexandru M Stan <amstan@chromium.org>
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/248902
Tested-by: Alec Berg <alecaberg@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Alec Berg <alecaberg@chromium.org>
Cortex-m0 we supports 2 bit priorities for the NVIC, yet we clear with 0x7 (3
bits). Change so we now clear with 0x3
Also limited priority to the max available (so we don't set extra bits we don't
want or modulus the priority, otherwise setting priority 8 will actual give you
priority 0) in both cortex-m and cortex-m0.
BUG=None, discovered while looking at the code
TEST=Should be no functional change, NVIC priorities should still work the same.
BRANCH=None
Change-Id: I31ba041449cae96983753b297e2631c310a406c4
Signed-off-by: Alexandru M Stan <amstan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/236086
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
When another task is holding the lock, mutex_lock() should call
task_wait_event_mask() to wait only for TASK_EVENT_MUTEX events.
If it calls task_wait_event(), any pending events are silently
discarded while its waiting for the the lock.
BUG=chromium:435611
BRANCH=ToT,samus
TEST=make buildall -j, and:
Before this change, I watched the EC console while shutting down
and rebooting Samus. I saw the request event arrive:
[37.576295 LB lightbar_resume() requests 5 S3S0]
[46.055725 LB_version]
But the lightbar task never saw it. Adding a bunch of debug
messages showed that it was being lost in mutex_lock().
After this change, the event is delivered:
[30.167670 LB lightbar_resume() requests 5 S3S0]
[30.171009 LB cur_seq 2 S3 returned pending msg 5 S3S0]
[30.173816 LB running cur_seq 5 S3S0. prev_seq 2 S3]
[32.410073 LB cur_seq 5 S3S0 returned value 0]
[32.410865 LB running cur_seq 3 S0. prev_seq 2 S3]
[39.938388 LB_version]
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Change-Id: I011838538960cc57171f0a3c4cdee113d156e9ff
Reviewed-on: https://chromium-review.googlesource.com/231370
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Do not allow rescheduling tasks if task_start() has not been called.
This fixes a bug in which if console input occurs between uart_init()
and task_start(), the MCU crashes because uart_init() enables uart
interrupts which attempts to wake up the console task when RX data
is received, which then tries to task switch before we initialized
task scheduling.
BUG=chrome-os-partner:32561
BRANCH=samus
TEST=add while(1) loop to adc_init() to simulate stalled ADC
initialization. When stalled, send console character and observe
that without this CL MCU crashes, and with this CL the MCU does
not crash.
Change-Id: I34418e88ebe0063acf1cc55ab5a57b5fddcd9d23
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/221599
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
'powerindebug' is only used when there is a problem with power
sequencing. 'taskready' is rarely used and the same info can be
retrieved by 'taskinfo'.
Put both behind config flags and disable 'taskready' by default. Also
disable 'powerindebug' for Ryu.
BUG=chrome-os-partner:32203
TEST=Build Ryu and check flash space used.
BRANCH=None
Change-Id: I753a1f5411d6e840a80aba03afc94f9640d381a8
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/219490
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Our code base contains a lot of debug messages in this pattern:
CPRINTF("[%T xxx]\n") or ccprintf("[%T xxx]\n")
The strings are taking up spaces in the EC binaries, so let's refactor
this by adding cprints() and ccprints().
cprints() is just like cprintf(), except that it adds the brackets
and the timestamp. ccprints() is equivalent to cprints(CC_CONSOLE, ...)
This saves us hundreds of bytes in EC binaries.
BUG=chromium:374575
TEST=Build and check flash size
BRANCH=None
Change-Id: Ifafe8dc1b80e698b28ed42b70518c7917b49ee51
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/200490
Reviewed-by: Randall Spangler <rspangler@chromium.org>
From time to time (usually under heavy interrupt load), the runtime on
Cortex-M0 was panic'ing at the "svc" instruction with a HardFault
exception (inside the wait_event() function).
The issue was probably the following :
the wait_event() code is doing an atomic_read_clear() whose critical
section disables interrupts and re-enables them using "cpsie i",
then do __schedule() call which is essentially a "svc" instruction.
According to ARMv6-m reference manual :
"If execution of a CPS instruction:
increases the execution priority, the CPS execution serializes that
change to the instruction stream.
decreases the execution priority, the architecture guarantees only that
the new priority is visible to instructions executed after either executing
an ISB instruction, or performing an exception entry or exception
return."
So, when we are executing the "svc", PRIMASK.PM can still be seen as 1
(while it was set to 0 by "cpsie i") and in that case the software
interrupt is replaced by a HardFault.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=chrome-os-partner:28296
TEST=run Firefly board under load for extended periods of time.
Change-Id: Ie355c36f06e6fe2fee5cca8998a469fa096badad
Reviewed-on: https://chromium-review.googlesource.com/196659
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
In order to achieve really tiny firmwares, make our runtime (tasks,
hooks, muxed timers, GPIO abstraction ...) optional.
Add 2 new build options for it : CONFIG_COMMON_RUNTIME and
CONFIG_COMMON_GPIO which are enabled by default, and ensure all the
source files are built according to the right configuration variable.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=none
TEST=make buildall
build a minimal board with no runtime.
Change-Id: Icb621cbe0a75b3a320cb53c3267d6e578cd3c32f
Reviewed-on: https://chromium-review.googlesource.com/189403
Reviewed-by: Vic Yang <victoryang@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>