mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-06 23:51:28 +00:00
[chip config]
1. No hardware specific udelay().
2. Enable watchdog.
[watchdog]
3. Watchdog period is "CONFIG_WATCHDOG_PERIOD_MS" of config.h.
4. Watchdog auxiliary timer period is "CONFIG_AUX_TIMER_PERIOD_MS".
[task and irq]
5. Write 1 to clear interrupt pending status, no |.
6. A global variable for store interrupt number of software interrupt.
[uart]
7. Always reset UART module before config it.
[hwtimer]
8. Use more external timers for HW timer module.
[task]
9. Fix task profiling.
Signed-off-by: Dino Li <dino.li@ite.com.tw>
BRANCH=none
BUG=none
TEST=[watchdog]
1. console "waitms 1100", only pre-watchdog warning message.
2. console "waitms 1600", warning message and watchdog reset.
[hwtimer]
3. console commands "gettime", "timerinfo", and "forcetime".
4. enable hook debug and there is no delayed by more than 10%
warning message over 48 hours.
5. There is no watchdog reset too.
[task]
6. console 'taskinfo'
Task Ready Name Events Time (s) StkUsed
0 R << idle >> 00000000 32.927724 308/512
1 HOOKS 00000000 0.034267 372/768
2 R CONSOLE 00000000 0.116763 468/768
3 HOSTCMD 00000000 0.000641 372/512
4 KEYPROTO 00000000 0.000042 212/512
5 KEYSCAN 00000000 0.000908 356/512
IRQ counts by type:
38 2932
155 1
158 261
160 67
Service calls: 87
Total exceptions: 3348
Task switches: 167
Task switching started: 0.001999 s
Time in tasks: 33.282819 s
Time in exceptions: 0.164717 s
Change-Id: I234085cec231cd855d2a5e639ea1b0966c61d796
Reviewed-on: https://chromium-review.googlesource.com/296939
Commit-Ready: Dino Li <dino.li@ite.com.tw>
Tested-by: Dino Li <dino.li@ite.com.tw>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
102 lines
3.2 KiB
ArmAsm
102 lines
3.2 KiB
ArmAsm
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*
|
|
* Context switching
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
.text
|
|
|
|
/**
|
|
* Task context switching
|
|
*
|
|
* Change the task scheduled after returning from an interruption.
|
|
*
|
|
* This function must be called in interrupt context.
|
|
*
|
|
* Save the registers of the current task below the interrupt context on
|
|
* its task, then restore the live registers of the next task and set the
|
|
* process stack pointer to the new stack.
|
|
*
|
|
* $r0: pointer to the task to switch from
|
|
* $r1: pointer to the task to switch to
|
|
* $r2: pointer to the stack where the interrupt entry context is saved
|
|
*
|
|
* the structure of the saved context on the stack is :
|
|
* (top to bottom)
|
|
* sp, lp, fp, r15, r5, r4, r3, r2, r1, r0, r10, r9, r8, r7, r6, ipc, ipsw
|
|
* interrupt entry frame <|>
|
|
*/
|
|
.global __switch_task
|
|
__switch_task:
|
|
/* get the (new) highest priority task pointer in r0 */
|
|
jal next_sched_task
|
|
movi55 $r3, 0
|
|
/* pointer to the current task (which are switching from) */
|
|
lwi.gp $r1, [ + current_task]
|
|
/* reset the re-scheduling request */
|
|
swi.gp $r3, [ + need_resched]
|
|
/* Nothing to do: let's return to keep the same task scheduled */
|
|
beq $r1, $r0, 1f
|
|
/* save our new scheduled task */
|
|
swi.gp $r0, [ + current_task]
|
|
/* get the program status word saved at exception entry */
|
|
mfsr $r4, $IPSW /* to save SP_ADJ bit */
|
|
/* get the task program counter saved at exception entry */
|
|
mfsr $r5, $IPC
|
|
/* get the new scheduled task stack pointer */
|
|
lw $r3, [$r0]
|
|
/* save ipsw, ipc, r6, r7, r8, r9, r10 on the current process stack */
|
|
smw.adm $r4, [$fp], $r10, 0
|
|
/* restore ipsw, ipc, r6, r7, r8, r9, r10 from the next stack context */
|
|
lmw.bim $r4, [$r3], $r10, 0
|
|
/* set the program status word to restore SP_ADJ bit */
|
|
mtsr $r4, $IPSW
|
|
/* set the task program counter to restore at exception exit */
|
|
mtsr $r5, $IPC
|
|
/* save the task stack pointer in its context */
|
|
sw $fp, [$r1]
|
|
/* barrier: ensure IPC is taken into account before IRET */
|
|
dsb
|
|
/* exception frame pointer for the new task */
|
|
mov55 $fp, $r3
|
|
1: /* un-pile the interruption entry context */
|
|
/* isr exit */
|
|
jal end_irq_handler
|
|
/* restore r0-r5 */
|
|
lmw.bim $r0, [$fp], $r5, 0
|
|
/* restore r15, fp, lp and sp */
|
|
lmw.bi $r15, [$fp], $r15, 0xb
|
|
/* restore PC and PSW */
|
|
iret
|
|
|
|
/**
|
|
* Start the task scheduling.
|
|
*
|
|
* $r0 is a pointer to task_stack_ready, which is set to 1 after
|
|
* the task stack is set up.
|
|
*/
|
|
.global __task_start
|
|
__task_start:
|
|
/* area used as dummy thread stack for the first switch */
|
|
la $r3, scratchpad
|
|
|
|
movi55 $r4, 1
|
|
movi55 $r2, 0 /* syscall 3rd parameter : not an IRQ emulation */
|
|
movi55 $r1, 0 /* syscall 2nd parameter : re-schedule nothing */
|
|
movi55 $r0, 0 /* syscall 1st parameter : de-schedule nothing */
|
|
|
|
/* put the dummy stack pointer at the top of the stack in scratchpad */
|
|
addi $sp, $r3, 4 * 16
|
|
/* we are ready to re-schedule */
|
|
swi.gp $r4, [ + need_resched]
|
|
|
|
/* trigger scheduling to execute the task with the highest priority */
|
|
syscall 0
|
|
/* we should never return here: set code to EC_ERROR_UNKNOWN */
|
|
movi55 $r0, 0x1
|
|
ret5 $lp
|
|
|