From dbc7c310f5babec6fd2b6a382b8a49b011296a12 Mon Sep 17 00:00:00 2001 From: Mary Ruthven Date: Tue, 22 Dec 2020 09:37:55 +1100 Subject: coil: remove nds32 core/nds uses words we're removing for coil. Remove it, because cr50 doesn't use it. BUG=b:175244613 TEST=make buildall -j Change-Id: I9621ed67347241b2c847d4005e714a0051ab0274 Signed-off-by: Mary Ruthven Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2600300 Reviewed-by: Namyoon Woo --- core/nds32/__builtin.c | 16 - core/nds32/__divdi3.S | 372 --------------------- core/nds32/__libsoftfpu.S | 195 ----------- core/nds32/__muldi3.S | 40 --- core/nds32/__udivdi3.S | 15 - core/nds32/atomic.h | 57 ---- core/nds32/build.mk | 26 -- core/nds32/config_core.h | 22 -- core/nds32/cpu.c | 16 - core/nds32/cpu.h | 60 ---- core/nds32/ec.lds.S | 268 --------------- core/nds32/include/math.h | 14 - core/nds32/init.S | 269 --------------- core/nds32/irq_chip.h | 59 ---- core/nds32/irq_handler.h | 25 -- core/nds32/math.c | 116 ------- core/nds32/panic.c | 203 ------------ core/nds32/switch.S | 102 ------ core/nds32/task.c | 809 ---------------------------------------------- 19 files changed, 2684 deletions(-) delete mode 100644 core/nds32/__builtin.c delete mode 100644 core/nds32/__divdi3.S delete mode 100644 core/nds32/__libsoftfpu.S delete mode 100644 core/nds32/__muldi3.S delete mode 100644 core/nds32/__udivdi3.S delete mode 100644 core/nds32/atomic.h delete mode 100644 core/nds32/build.mk delete mode 100644 core/nds32/config_core.h delete mode 100644 core/nds32/cpu.c delete mode 100644 core/nds32/cpu.h delete mode 100644 core/nds32/ec.lds.S delete mode 100644 core/nds32/include/math.h delete mode 100644 core/nds32/init.S delete mode 100644 core/nds32/irq_chip.h delete mode 100644 core/nds32/irq_handler.h delete mode 100644 core/nds32/math.c delete mode 100644 core/nds32/panic.c delete mode 100644 core/nds32/switch.S delete mode 100644 core/nds32/task.c diff --git a/core/nds32/__builtin.c b/core/nds32/__builtin.c deleted file mode 100644 index 7b1d5eea62..0000000000 --- a/core/nds32/__builtin.c +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright 2017 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. - */ - -#include "common.h" - -/* - * __builtin_ffs: - * Returns one plus the index of the least significant 1-bit of x, - * or if x is zero, returns zero. - */ -int __keep __ffssi2(int x) -{ - return 32 - __builtin_clz(x & -x); -} diff --git a/core/nds32/__divdi3.S b/core/nds32/__divdi3.S deleted file mode 100644 index d86e8f6273..0000000000 --- a/core/nds32/__divdi3.S +++ /dev/null @@ -1,372 +0,0 @@ -/* Copyright 2018 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. - * - * __divdi3.S: signed 64 bit division - */ - -#define NREGS $r6 -#define DREGS $r8 -#define P1H $r1 -#define P1L $r0 -#define P2H $r3 -#define P2L $r2 -#define NUMHI $r7 -#define NUMLO $r6 -#define DENHI $r9 -#define DENLO $r8 -#define OFFSET_L 0 -#define OFFSET_H 4 -#define MHI P1H -#define MLO P1L -#define W2 $r3 -#define W1 $r5 -#define W0 $r4 -#define T2 P1L -#define NHI P1H -#define NLO P1L -#define D $r2 -#define DLO $r3 -#define DHI $r10 -#define Q NHI -#define QHI W0 -#define R NLO -#define RHI NHI -#define M T2 -#define M2 DLO - - .text - .align 2 - .globl umul_ppmm - .type umul_ppmm, @function - ! ===================================================================== - ! uint64_t umul_ppmm(uint32_t a, uint32_t b) - ! - ! This function multiplies `a' by `b' to obtain a 64-bit product. The - ! product is broken into two 32-bit pieces which are stored in the zl - ! (low-part at P1L) and zh (high-part at P1H). - ! ===================================================================== -umul_ppmm: - zeh P2L, $r0 ! al=a&0xffff - srli P2H, $r0, 16 ! ah=a>>16 - zeh P1L, $r1 ! bl=b&0xffff - srli P1H, $r1, 16 ! bh=b>>16 - mul W1, P2L, P1H ! zA=al*bh - mul P2L, P2L, P1L ! zl=al*bl - mul P1L, P2H, P1L ! zB=ah*bl - add W1, W1, P1L ! zA+=zB - slt $ta, W1, P1L ! zA>16 - add P1H, P1H, $ta ! zh+=(zA>>16) - slli P1L, W1, 16 ! zA<<=16 - add P1L, P1L, P2L ! zl+=zA - slt $ta, P1L, P2L ! zl> (32 - bm) - sll NUMHI, NUMHI, $r0 ! n1 << bm - or NUMHI, NUMHI, W1 ! n1 = (n1 << bm) | (n0 >> (32 - bm)) - sll NUMLO, NUMLO, $r0 ! n0 <<= bm -.LZskipnorm1: - movd44 $r0, NREGS ! (n1,n0) - move $r2, DENLO ! d0 - bal fudiv_qrnnd ! calculate q0 n0 - swi P1H, [$sp+(32+OFFSET_L)]! q0 - move NUMLO, P1L ! n0 - move W1, 0 - swi W1, [$sp+(32+OFFSET_H)] ! q1 = 0 - b .L19 -.L10: - beqz P2L, .LZdivzero ! if d0 != 0, skip - move $r0, DENLO - bal __clzsi2 - swi $r0, [$sp+(28)] ! bm - bnez $r0, .LZnorm1 ! if bm != 0, skip - sub NUMHI, NUMHI, DENLO ! n1 -= d0 - movi W1, 1 - swi W1, [$sp+(32+OFFSET_H)] ! q1 = 1 - b .L29 - - ! to eliminate unaligned branch target - .align 2 -.LZnorm1: - subri $ta, $r0, 32 ! b = 32 - bm - sll DENLO, DENLO, $r0 ! d0 <<= bm - move $r2, DENLO - srl W0, NUMLO, $ta ! n0 >> b - sll W1, NUMHI, $r0 ! n1 << bm - sll NUMLO, NUMLO, $r0 ! n0 <<= bm - or P1L, W1, W0 ! n1 = (n1 << bm) | (n0 >> b) - srl P1H, NUMHI, $ta ! n2 = n1 >> b - bal fudiv_qrnnd ! caculate q1, n1 - swi P1H, [$sp+(32+OFFSET_H)]! q1 - move NUMHI, P1L ! n1 -.L29: - movd44 $r0, NREGS ! (n1,n0) - move $r2, DENLO ! d0 - bal fudiv_qrnnd ! calcuate q0, n0 - swi P1H, [$sp+(32+OFFSET_L)] - move NUMLO, P1L - - ! to eliminate unaligned branch target - .align 2 -.L19: - beqz $fp, .LZsetq ! if rp == 0, skip - lwi W2, [$sp+(28)] ! bm - movi NUMHI, 0 - srl NUMLO, NUMLO, W2 ! n0 >> bm - b .LZsetr - - ! to eliminate unaligned branch target - .align 2 -.LZdivzero: - ! divide-by-zero exception or quotient = 0 and remainder = 0 returned - divr NUMHI, NUMLO, DENLO, DENLO -.LZqzero: - movi P1H, 0 - movi P1L, 0 - beqz $fp, .LZret ! if rp == NULL, skip - swi NUMLO, [$fp+OFFSET_L] ! *rp - swi NUMHI, [$fp+OFFSET_H] - b .LZret -.L9: - slt $ta, NUMHI, DENHI ! n1 < d1 - bnez $ta, .LZqzero ! if yes, skip - move $r0, DENHI - bal __clzsi2 - swi $r0, [$sp+(28)] ! bm - beqz $r0, .LZskipnorm2 ! if bm == 0, skip - subri W0, $r0, 32 ! b = 32 - bm - srl W1, DENLO, W0 ! d0 >> b - sll $r2, DENHI, $r0 ! d1 << bm - or $r2, $r2, W1 ! d1 = (d0 >> b) | (d1 << bm) - move DENHI, $r2 - sll DENLO, DENLO, $r0 ! d0 <<= bm - srl W2, NUMLO, W0 ! n0 >> b - sll NUMLO, NUMLO, $r0 ! n0 <<= bm - sll P1L, NUMHI, $r0 ! n1 << bm - srl P1H, NUMHI, W0 ! n2 = n1 >> b - or P1L, P1L, W2 ! n1 = (n0 >> b) | (n1 << bm) - bal fudiv_qrnnd ! calculate q0, n1 - swi P1H, [$sp+(32+OFFSET_L)] - move NUMHI, P1L - move P1L, DENLO ! d0 - bal umul_ppmm - slt $ta, NUMHI, MHI ! n1 < m1 - bnez $ta, .L46 ! if yes, skip - bne MHI, NUMHI, .L45 ! if m1 != n1, skip - slt $ta, NUMLO, MLO ! n0 < m0 - beqz $ta, .L45 ! if no, skip -.L46: - lwi W2, [$sp+(32+OFFSET_L)] - sub MHI, MHI, DENHI ! m1 - d1 - addi W2, W2, -1 ! q0-- - swi W2, [$sp+(32+OFFSET_L)] - sub W2, MLO, DENLO ! __x = m0 - d0 - slt $ta, MLO, W2 ! m0 < __x - sub MHI, MHI, $ta ! m1 = m1 - d1 - (__x > m0) - move MLO, W2 ! m0 = __x -.L45: - movi W2, 0 - swi W2, [$sp+(32+OFFSET_H)] ! q1 = 0 - beqz $fp, .LZsetq ! if yes, skip - sub P1L, NUMLO, MLO ! __x = n0 - m0 - sub P1H, NUMHI, MHI ! n1 - m1 - slt $ta, NUMLO, P1L ! n0 < __x - sub P1H, P1H, $ta ! n1 = n1 - m1 - (__x > n0) - lwi W2, [$sp+(28)] ! bm - subri W0, W2, 32 ! b - sll NUMHI, P1H, W0 ! n1 << b - srl NUMLO, P1L, W2 ! n0 >> bm - or NUMLO, NUMLO, NUMHI ! (n1 << b) | (n0 >> bm) - srl NUMHI, P1H, W2 ! n1 >> bm -.LZsetr: - swi NUMLO, [$fp+OFFSET_L] ! remainder - swi NUMHI, [$fp+OFFSET_H] -.LZsetq: - lwi P1L, [$sp+(32+OFFSET_L)]! quotient - lwi P1H, [$sp+(32+OFFSET_H)] - - ! to eliminate unaligned branch target - .align 2 -.LZret: - lmw.bi $r6, [$sp], $r10 , 10 - addi $sp, $sp, 40 - ret - -.LZskipnorm2: - move W2, 0 - slt $ta, DENHI, NUMHI ! n1 > d1 - bnez $ta, .L52 ! if yes, skip - slt $ta, NUMLO, DENLO ! n0 < d0 - bnez $ta, .L51 ! if yes, skip -.L52: - move W1, 1 - swi W1, [$sp+(32+OFFSET_L)] ! q0 = 1 - sub W0, NUMLO, DENLO ! __x = n0 - d0 - sub NUMHI, NUMHI, DENHI ! n1 - d1 - slt $ta, NUMLO, W0 ! n0 < __x - sub NUMHI, NUMHI, $ta ! n1 = n1 -d1 - (_-x > n0) - move NUMLO, W0 ! n0 = __x - b .L54 -.L51: - swi W2, [$sp+(32+OFFSET_L)] ! q0 = 0 -.L54: - swi W2, [$sp+(32+OFFSET_H)] ! q1 = 0 - bnez $fp, .LZsetr - b .LZsetq - .size __udivmoddi4, .-__udivmoddi4 - - .text - .align 2 - .globl __divdi3 - .type __divdi3, @function -__divdi3: - ! ===================================================================== - ! uint64_t __divdi3(uint64_t n, uint64-t d) - ! - ! This function divides n by d and returns the quotient. - ! - ! stack allocation: - ! sp+8 +-----------------------+ - ! | $lp | - ! sp+4 +-----------------------+ - ! | $r6 | - ! sp +-----------------------+ - ! ===================================================================== - smw.adm $r6, [$sp], $r6, 2 - - xor $r6, P1H, P2H - srai45 $r6, 31 ! signof(numerator xor denominator) - ! abs(denominator) - bgez P2H, .L80 - neg P2H, P2H - beqz P2L, .L80 - neg P2L, P2L - addi P2H, P2H, -1 - -.L80: - ! abs(numerator) - bgez P1H, .L81 - neg P1H, P1H - beqz P1L, .L81 - neg P1L, P1L - addi P1H, P1H, -1 - -.L81: - ! abs(numerator) / abs(denominator) - movi $r4, 0 ! ignore remainder - bal __udivmoddi4 - ! numerator / denominator - beqz $r6, .L82 - or $r4, P1H, P1L - beqz $r4, .L82 - neg P1H, P1H - beqz P1L, .L82 - neg P1L, P1L - addi P1H, P1H, -1 - - ! to eliminate unaligned branch target - .align 2 -.L82: - lmw.bim $r6, [$sp], $r6, 2 - ret - .size __divdi3, .-__divdi3 diff --git a/core/nds32/__libsoftfpu.S b/core/nds32/__libsoftfpu.S deleted file mode 100644 index 672e6bbb3d..0000000000 --- a/core/nds32/__libsoftfpu.S +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright 2017 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. - */ - .text - .align 2 - .global __gtsf2 - .type __gtsf2, @function -__gtsf2: - ! --------------------------------------------------------------------- - ! int __gtsf2(float a, float b): - ! This function returns a value greater than zero if neither argument - ! is NaN and a is strictly greater than b. - ! --------------------------------------------------------------------- - .global __gesf2 - .type __gesf2, @function -__gesf2: - ! --------------------------------------------------------------------- - ! int __gesf2(float a, float b): - ! This function returns a value greater than or equal to zero if - ! neither argument is NaN and a is greater than or equal to b. - ! --------------------------------------------------------------------- - move $r4, #-1 - b .LA - - .global __eqsf2 - .type __eqsf2, @function -__eqsf2: - ! --------------------------------------------------------------------- - ! int __eqsf2(float a, float b): - ! This function returns zero value if neither argument is NaN, - ! and a and b are equal. - ! --------------------------------------------------------------------- - .global __nesf2 - .type __nesf2, @function -__nesf2: - ! --------------------------------------------------------------------- - ! int __nesf2(float a, float b): - ! This function returns a nonzero value if either argument is NaN or if - ! a and b are unequal. - ! --------------------------------------------------------------------- - .global __lesf2 - .type __lesf2, @function -__lesf2: - ! --------------------------------------------------------------------- - ! int __lesf2(float a, float b): - ! This function returns a value less than or equal to zero if neither - ! argument is NaN and a is less than b. - ! --------------------------------------------------------------------- - .global __ltsf2 - .type __ltsf2, @function -__ltsf2: - ! --------------------------------------------------------------------- - ! int __ltsf2(float a, float b): - ! This function returns a value less than zero if neither argument is - ! NaN and a is strictly less than b. - ! --------------------------------------------------------------------- - .global __cmpsf2 - .type __cmpsf2, @function -__cmpsf2: - ! --------------------------------------------------------------------- - ! int __cmpsf2(float a, float b); - ! This function calculates a <=> b. That is, if a is less than b, it - ! returns -1; if a if greater than b, it returns 1; and if a and b are - ! equal, it returns 0. If either argument is NaN, it returns 1, But you - ! should not rely on this; If NaN is a possibility, use higher-level - ! comparison function __unordsf2(). - ! --------------------------------------------------------------------- - move $r4, #1 - - .align 2 -.LA: - move $r5, #0xff000000 - slli $r2, $r0, #1 - slt $r15, $r5, $r2 - bnez $r15, .LMnan ! a is NaN - slli $r3, $r1, #1 - slt $r15, $r5, $r3 - bnez $r15, .LMnan ! b is NaN - xor $r5, $r0, $r1 ! a and b have same sign? - bgez $r5, .LSameSign -.LDiffSign: - or $r2, $r2, $r3 - beqz $r2, .LMequ ! 0.0f and -0.0f are equal - move $r2, #1 ! when a==0.0f, return 1 - cmovz $r0, $r2, $r0 ! otherwise, simply return a - ret5 $lp -.LSameSign: - sltsi $r15, $r0, 0 ! a < 0 ? - bnez $r15, .LSameSignNeg -.LSameSignPos: - ! a >= 0 && b >= 0, return a - b - sub $r0, $r0, $r1 - ret5 $lp -.LSameSignNeg: - ! a < 0 && b < 0, return b - a - sub $r0, $r1, $r0 - ret5 $lp -.LMequ: - move $r0, #0 - ret5 $lp -.LMnan: - move $r0, $r4 - ret5 $lp - .size __cmpsf2, .-__cmpsf2 - .size __ltsf2, .-__ltsf2 - .size __lesf2, .-__lesf2 - .size __nesf2, .-__nesf2 - .size __eqsf2, .-__eqsf2 - .size __gesf2, .-__gesf2 - .size __gtsf2, .-__gtsf2 - -#define MANTA $r0 -#define EXPOA $r1 - .text - .align 2 - .global __floatsisf - .type __floatsisf, @function -__floatsisf: - beqz $r0, .LKzero ! A is zero - move $r4, #0x80000000 - and $r2, $r0, $r4 ! sign(A) - beqz $r2, .LKcont - subri $r0, $r0, #0 - ! abs(A) -.LKcont: - move EXPOA, #0x9e - move $r5, 16 - move $r3, 0 -.LKloop: - add $r3, $r3, $r5 - srl $r15, MANTA, $r3 - bnez $r15, .LKloop2 - sll MANTA, MANTA, $r5 - sub EXPOA, EXPOA, $r5 -.LKloop2: - srli $r5, $r5, #1 - bnez $r5, .LKloop - ! do rounding - srli $r4, $r4, #24 ! 0x80 - add MANTA, MANTA, $r4 - slt $r15, MANTA, $r4 - add EXPOA, EXPOA, $r15 - srai $r4, MANTA, #8 - andi $r4, $r4, #1 - sub MANTA, MANTA, $r4 - slli MANTA, MANTA, #1 ! shift out implied 1 - ! pack - srli MANTA, MANTA, #9 - slli $r4, EXPOA, #23 - or $r0, MANTA, $r4 - or $r0, $r0, $r2 -.LKzero: - ret5 $lp - .size __floatsisf, .-__floatsisf - -#undef EXPOA -#undef MANTA -#define VALUA $r1 -#define EXPOA VALUA -#define MANTA $r2 -#define W0 $r4 -#define W1 $r5 - .text - .align 2 - .global __fixsfsi - .type __fixsfsi, @function -__fixsfsi: - slli VALUA, $r0, #1 - slli MANTA, VALUA, #7 - srli EXPOA, VALUA, #24 - subri EXPOA, EXPOA, #0x9e - move W1, #0x80000000 - blez EXPOA, .LJover ! number is too big - sltsi $r15, EXPOA, #0x20 - beqz $r15, .LJzero ! number is too small - or MANTA, MANTA, W1 - srl MANTA, MANTA, EXPOA - sltsi $r15, $r0, #0 - subri $r0, MANTA, #0 - cmovz $r0, MANTA, $r15 - ret5 $lp -.LJzero: - move $r0, #0 - ret5 $lp -.LJover: - move W0, #0x7f800000 - slt $r15, W0, $r0 - beqzs8 .LJnan - move $r0, W1 - ret5 $lp -.LJnan: - addi $r0, W1, -1 - ret5 $lp - .size __fixsfsi, .-__fixsfsi diff --git a/core/nds32/__muldi3.S b/core/nds32/__muldi3.S deleted file mode 100644 index ef4a491183..0000000000 --- a/core/nds32/__muldi3.S +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2015 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. - * - * __muldi3.S: signed 64 bit multiplication - */ - -#define P1H $r1 -#define P1L $r0 -#define P2H $r3 -#define P2L $r2 - - .text - .align 2 - .globl __muldi3 - .type __muldi3, @function -__muldi3: - mul $r5, P1H, P2L ! (ah=a>>31)*(bl=b&0xffffffff) - srli P1H, P1L, 16 ! alh=al>>16 - maddr32 $r5, P1L, P2H ! ah*bl+(bh=b>>31)*(al=a&0xffffffff) - zeh P1L, P1L ! all=al&0xffff - srli P2H, P2L, 16 ! blh=bl>>16 - zeh P2L, P2L ! bll=bl&0xffff - - mul $ta, P1L, P2H ! zA=all*blh - mul $r4, P1L, P2L ! zl=all*bll - mul P2L, P1H, P2L ! zB=alh*bll - add P1L, $ta, P2L ! zA+=zB - slt $ta, P1L, P2L ! zA>16 - add P1H, P1H, $ta ! zh+=(zA>>16) - add P1L, $r4, P2L ! zl+=(zA<<16) - slt $ta, P1L, $r4 ! zl - -/* Process Status Word bits */ -#define PSW_GIE BIT(0) /* Global Interrupt Enable */ -#define PSW_INTL_SHIFT 1 /* Interrupt Stack Level */ -#define PSW_INTL_MASK (0x3 << PSW_INTL_SHIFT) - -/* write Process Status Word privileged register */ -static inline void set_psw(uint32_t val) -{ - asm volatile ("mtsr %0, $PSW" : : "r"(val)); -} - -/* read Process Status Word privileged register */ -static inline uint32_t get_psw(void) -{ - uint32_t ret; - asm volatile ("mfsr %0, $PSW" : "=r"(ret)); - return ret; -} - -/* write Interruption Program Counter privileged register */ -static inline void set_ipc(uint32_t val) -{ - asm volatile ("mtsr %0, $IPC" : : "r"(val)); -} - -/* read Interruption Program Counter privileged register */ -static inline uint32_t get_ipc(void) -{ - uint32_t ret; - asm volatile ("mfsr %0, $IPC" : "=r"(ret)); - return ret; -} - -/* read Interruption Type privileged register */ -static inline uint32_t get_itype(void) -{ - uint32_t ret; - asm volatile ("mfsr %0, $ITYPE" : "=r"(ret)); - return ret; -} - -/* Generic CPU core initialization */ -void cpu_init(void); - -extern uint32_t ilp; -extern uint32_t ec_reset_lp; - -#endif /* __CROS_EC_CPU_H */ diff --git a/core/nds32/ec.lds.S b/core/nds32/ec.lds.S deleted file mode 100644 index f5e2882222..0000000000 --- a/core/nds32/ec.lds.S +++ /dev/null @@ -1,268 +0,0 @@ -/* Copyright 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. - */ -#include "config.h" - -#define STRINGIFY0(name) #name -#define STRINGIFY(name) STRINGIFY0(name) - -#define FW_OFF_(section) CONFIG_##section##_MEM_OFF -#define FW_OFF(section) (CONFIG_PROGRAM_MEMORY_BASE + FW_OFF_(section)) - -#define FW_SIZE_(section) CONFIG_##section##_SIZE -#define FW_SIZE(section) FW_SIZE_(section) - - -OUTPUT_FORMAT(BFD_FORMAT, BFD_FORMAT, BFD_FORMAT) -OUTPUT_ARCH(BFD_ARCH) -ENTRY(reset) -MEMORY -{ - FLASH (rx) : ORIGIN = FW_OFF(SECTION), LENGTH = FW_SIZE(SECTION) - IRAM (rw) : ORIGIN = CONFIG_RAM_BASE, LENGTH = CONFIG_RAM_SIZE -#if defined(CONFIG_HOSTCMD_X86) || defined(CONFIG_I2C_SLAVE) - H2RAM (rw) : ORIGIN = CONFIG_H2RAM_BASE, LENGTH = CONFIG_H2RAM_SIZE -#endif -} -SECTIONS -{ - .text : { - /* We put "__flash_dma_start" at the beginning of the text section - * to avoid gap. - */ - __flash_dma_start = .; - ASSERT((__flash_dma_start == 0), - "__flash_dma_start has to be 4k-byte aligned"); - KEEP(STRINGIFY(OUTDIR/core/CORE/init.o) (.text.vecttable)) - . = ALIGN(4); - __image_data_offset = .; - KEEP(*(.rodata.ver)) - . = ALIGN(4); - KEEP(STRINGIFY(OUTDIR/core/CORE/init.o) (.text.vectirq)) - KEEP(STRINGIFY(OUTDIR/core/CORE/init.o) (.text)) - KEEP(*(.flash_direct_map)) - . = ALIGN(16); - KEEP(*(.ram_code)) - __flash_dma_size = . - __flash_dma_start; - ASSERT((__flash_dma_size < IT83XX_ILM_BLOCK_SIZE), - "__flash_dma_size < IT83XX_ILM_BLOCK_SIZE"); - . = ALIGN(IT83XX_ILM_BLOCK_SIZE); - __flash_text_start = .; - *(.text*) - } > FLASH - . = ALIGN(4); - .rodata : { - /* Symbols defined here are declared in link_defs.h */ - __irqprio = .; - KEEP(*(.rodata.irqprio)) - __irqprio_end = .; - - . = ALIGN(4); - __irqhandler = .; - KEEP(STRINGIFY(OUTDIR/core/CORE/init.o) (.rodata.vecthandlers)) - - . = ALIGN(4); - __cmds = .; - KEEP(*(SORT(.rodata.cmds*))) - __cmds_end = .; - - . = ALIGN(4); - __hcmds = .; - KEEP(*(SORT(.rodata.hcmds*))) - __hcmds_end = .; - - . = ALIGN(4); - __mkbp_evt_srcs = .; - KEEP(*(.rodata.evtsrcs)) - __mkbp_evt_srcs_end = .; - - . = ALIGN(4); - __hooks_init = .; - KEEP(*(.rodata.HOOK_INIT)) - __hooks_init_end = .; - - __hooks_pre_freq_change = .; - KEEP(*(.rodata.HOOK_PRE_FREQ_CHANGE)) - __hooks_pre_freq_change_end = .; - - __hooks_freq_change = .; - KEEP(*(.rodata.HOOK_FREQ_CHANGE)) - __hooks_freq_change_end = .; - - __hooks_sysjump = .; - KEEP(*(.rodata.HOOK_SYSJUMP)) - __hooks_sysjump_end = .; - - __hooks_chipset_pre_init = .; - KEEP(*(.rodata.HOOK_CHIPSET_PRE_INIT)) - __hooks_chipset_pre_init_end = .; - - __hooks_chipset_startup = .; - KEEP(*(.rodata.HOOK_CHIPSET_STARTUP)) - __hooks_chipset_startup_end = .; - - __hooks_chipset_resume = .; - KEEP(*(.rodata.HOOK_CHIPSET_RESUME)) - __hooks_chipset_resume_end = .; - - __hooks_chipset_suspend = .; - KEEP(*(.rodata.HOOK_CHIPSET_SUSPEND)) - __hooks_chipset_suspend_end = .; - - __hooks_chipset_shutdown = .; - KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN)) - __hooks_chipset_shutdown_end = .; - - __hooks_chipset_reset = .; - KEEP(*(.rodata.HOOK_CHIPSET_RESET)) - __hooks_chipset_reset_end = .; - - __hooks_ac_change = .; - KEEP(*(.rodata.HOOK_AC_CHANGE)) - __hooks_ac_change_end = .; - - __hooks_lid_change = .; - KEEP(*(.rodata.HOOK_LID_CHANGE)) - __hooks_lid_change_end = .; - - __hooks_tablet_mode_change = .; - KEEP(*(.rodata.HOOK_TABLET_MODE_CHANGE)) - __hooks_tablet_mode_change_end = .; - - __hooks_base_attached_change = .; - KEEP(*(.rodata.HOOK_BASE_ATTACHED_CHANGE)) - __hooks_base_attached_change_end = .; - - __hooks_pwrbtn_change = .; - KEEP(*(.rodata.HOOK_POWER_BUTTON_CHANGE)) - __hooks_pwrbtn_change_end = .; - - __hooks_battery_soc_change = .; - KEEP(*(.rodata.HOOK_BATTERY_SOC_CHANGE)) - __hooks_battery_soc_change_end = .; - -#ifdef CONFIG_USB_SUSPEND - __hooks_usb_change = .; - KEEP(*(.rodata.HOOK_USB_PM_CHANGE)) - __hooks_usb_change_end = .; -#endif - - __hooks_tick = .; - KEEP(*(.rodata.HOOK_TICK)) - __hooks_tick_end = .; - - __hooks_second = .; - KEEP(*(.rodata.HOOK_SECOND)) - __hooks_second_end = .; - - __hooks_usb_pd_disconnect = .; - KEEP(*(.rodata.HOOK_USB_PD_DISCONNECT)) - __hooks_usb_pd_disconnect_end = .; - - __hooks_usb_pd_connect = .; - KEEP(*(.rodata.HOOK_USB_PD_CONNECT)) - __hooks_usb_pd_connect_end = .; - - __deferred_funcs = .; - KEEP(*(.rodata.deferred)) - __deferred_funcs_end = .; - - . = ALIGN(4); - *(.rodata*) - -#if defined(SECTION_IS_RO) && defined(CONFIG_FLASH) - . = ALIGN(64); - KEEP(*(.google)) -#endif - . = ALIGN(4); - } >FLASH - __data_lma_start = . ; - - .data : { - . = ALIGN(4); - __data_start = .; - *(.data.tasks) - *(.data) -#ifdef CONFIG_MPU - /* It has to be aligned by 32 bytes to be a valid MPU region. */ - . = ALIGN(32); - __iram_text_start = .; -#else - . = ALIGN(4); -#endif - *(.iram.text) -#ifdef CONFIG_MPU - . = ALIGN(32); - __iram_text_end = .; -#else - . = ALIGN(4); -#endif - __data_end = .; - - } > IRAM AT>FLASH - - .bss : { - /* Stacks must be 64-bit aligned */ - . = ALIGN(8); - __bss_start = .; - *(.bss.tasks) - *(.bss.task_scratchpad) - . = ALIGN(8); - *(.bss.system_stack) - /* Rest of .bss takes care of its own alignment */ - *(.bss) - *(.bss.slow) - - /* - * Reserve space for deferred function firing times. Each time is a - * uint64_t, each func is a 32-bit pointer, thus the scaling factor of - * two. - */ - . = ALIGN(8); - __deferred_until = .; - . += (__deferred_funcs_end - __deferred_funcs) * (8 / 4); - __deferred_until_end = .; - - . = ALIGN(4); - __bss_end = .; - - /* Shared memory buffer must be at the end of preallocated RAM, so it - * can expand to use all the remaining RAM. */ - __shared_mem_buf = .; - - } > IRAM - - ASSERT((__shared_mem_buf + CONFIG_SHAREDMEM_MINIMUM_SIZE) <= - (CONFIG_RAM_BASE + CONFIG_RAM_SIZE), - "Not enough space for shared memory.") - __ram_free = (CONFIG_RAM_BASE + CONFIG_RAM_SIZE) - - (__shared_mem_buf + CONFIG_SHAREDMEM_MINIMUM_SIZE); - - __image_size = LOADADDR(.data) + SIZEOF(.data) - FW_OFF(SECTION); - -#if defined(CONFIG_HOSTCMD_X86) || defined(CONFIG_I2C_SLAVE) - .h2ram (NOLOAD) : { - . += CONFIG_H2RAM_HOST_LPC_IO_BASE; - *(.h2ram.pool.hostcmd) - . = ALIGN(256); - *(.h2ram.pool.acpiec) -#ifdef CONFIG_I2C_SLAVE - . = ALIGN(256); - *(.h2ram.pool.i2cslv) -#endif - __h2ram_end = .; - } > H2RAM - - ASSERT((__h2ram_end) <= (CONFIG_H2RAM_BASE + CONFIG_H2RAM_SIZE), - "Not enough space for h2ram section.") -#endif - -#if !(defined(SECTION_IS_RO) && defined(CONFIG_FLASH)) - /DISCARD/ : { - *(.google) - } -#endif - - /DISCARD/ : { *(.ARM.*) } -} diff --git a/core/nds32/include/math.h b/core/nds32/include/math.h deleted file mode 100644 index 49d5585657..0000000000 --- a/core/nds32/include/math.h +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright 2017 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. - */ - -/* Math utility functions for N8 */ - -#ifndef __CROS_EC_MATH_H -#define __CROS_EC_MATH_H - -float sqrtf(float x); -float fabsf(float x); - -#endif /* __CROS_EC_MATH_H */ diff --git a/core/nds32/init.S b/core/nds32/init.S deleted file mode 100644 index f817aef346..0000000000 --- a/core/nds32/init.S +++ /dev/null @@ -1,269 +0,0 @@ -/* Copyright 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. - * - * N8 CPU initialization - */ - -#include "config.h" - -/* magic macro to implement IRQ prefix / exit */ -.macro vector name, entry_number -.weak \name\()_handler -.set \name\()_handler, unhandled_irq -j __entry_\()\name -.pushsection .text.vectirq -.global __entry_\()\name -__entry_\()\name: - /* the context is stored on the current task stack*/ - /* save r15, fp, lp and sp */ - smw.adm $r15, [$sp], $r15, 0xb - /* r0-r5 are caller saved */ - smw.adm $r0, [$sp], $r5, 0 - /* store link pointer register */ - swi.gp $lp, [ + ilp] - /* switch to system stack if we are called from process stack */ - la $r3, stack_end - mov55 $fp, $sp - slt45 $r3, $sp /* if sp > end of system stack, then r15 = 1 and */ - cmovn $sp, $r3, $r15 /* point sp to the top of the system stack */ - /* save entry number of HW interrupt */ - movi55 $r3, \entry_number\() - swi.gp $r3, [ + cpu_int_entry_number] - /* isr entry */ - jal start_irq_handler - /* C routine handler */ - jal \name\()_handler - /* check whether we need to change the scheduled task */ - lwi.gp $r2, [ + need_resched] - bnez $r2, __switch_task - /* 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 -.popsection -.pushsection .rodata.vecthandlers -.long \name\()_handler -.popsection -.endm - -.section .text.vecttable - -/* Exceptions vector */ -vectors: -j reset /* reset / NMI */ -j excep_handler /* TLB fill */ -j excep_handler /* PTE not present */ -j excep_handler /* TLB misc */ -j excep_handler /* TLB VLPT miss */ -j excep_handler /* Machine error */ -j excep_handler /* Debug related */ -j excep_handler /* General exception */ -vector syscall, -1 /* Syscall */ -vector irq_0, 0 /* HW 0 */ -vector irq_1, 1 /* HW 1 */ -vector irq_2, 2 /* HW 2 */ -vector irq_3, 3 /* HW 3 */ -vector irq_4, 4 /* HW 4 */ -vector irq_5, 5 /* HW 5 */ -vector irq_6, 6 /* HW 6 */ -vector irq_7, 7 /* HW 7 */ -vector irq_8, 8 /* HW 8 */ -vector irq_9, 9 /* HW 9 */ -vector irq_10, 10 /* HW 10 */ -vector irq_11, 11 /* HW 11 */ -vector irq_12, 12 /* HW 12 */ -vector irq_13, 13 /* HW 13 */ -vector irq_14, 14 /* HW 14 */ -vector irq_15, 15 /* HW 15 */ - -/* E-flash signature */ -.org 0x80 -.balign 16 -.global eflash_sig -eflash_sig: -.byte 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5 -#ifdef CONFIG_HOSTCMD_ESPI -.byte 0xA4 /* eSPI */ -#else -.byte 0xA5 /* LPC */ -#endif -.byte 0xB4 /* flag of signature */ -.byte 0x85, 0x12, 0x5A, 0x5A, 0xAA, 0xAA, 0x55, 0x55 -/* flags: internal oscillator + implicit location */ - -.text - -.global reset -reset: - /* - * GIE (global interrupt) is always disabled here. the first - * "iret" instruction of syscall interrupt (triggered by __task_start) - * will restore PSW from IPSW, and will enable GIE. - * Firmware will not change GIE settings (set/clear) until the next - * reset, unless there's an interrupt event. - * When there is an interrupt event, N8 CPU will save PSW register to - * IPSW register and clear GIE then jump to interrupt service routine. - * N8 will restore PSW from IPSW after "iret" instruction. - */ - setgie.d - dsb - - /* GP register is used to access .data and .bss */ - la $gp, _SDA_BASE_ - - /* Set system stack pointer. */ - la $sp, stack_end - - /* - * move content of lp into r5 and then store the content - * into variable "ec_reset_lp" later after memory initialization. - */ - mov55 $r5, $lp - - /* map/enable the 16kB of DLM at 0x00080000 */ - li $r0, 0x00080005 - mtsr $r0, $mr7 - - /* Set ROM address at 0x80000 (disabled). */ - li $r1, 0x00F0109B - movi $r0, #0x8 - sbi $r0, [$r1] - - /* Enable DLM 8k~12K(bit2) and DLM 12k~16k(bit3) */ - li $r1, 0x00F02030 - lbi $r0, [$r1] - ori $r0, $r0, 0x0C - sbi $r0, [$r1] - - /* Enable DLM 16k~36K bit[2-6] */ - li $r1, 0x00F0203E - lbi $r0, [$r1] - ori $r0, $r0, 0x7C - sbi $r0, [$r1] - - /* Enable DLM 36k~48K bit[0-2] */ - li $r1, 0x00F02044 - lbi $r0, [$r1] - ori $r0, $r0, 0x7 - sbi $r0, [$r1] - - /* Clear BSS */ - la $r0, _bss_start - lwi $r1, [$r0] - la $r0, _bss_end - lwi $r2, [$r0] - movi $r0, #0 -bss_loop: - swi.bi $r0, [$r1], 4 - bne $r1, $r2, bss_loop - - /* Copy initialized data to DLM */ - la $r0, _data_start - lwi $r1, [$r0] - la $r0, _data_end - lwi $r2, [$r0] - la $r0, _data_lma_start - lwi $r0, [$r0] -data_loop: - lwi.bi $r3, [$r0], 4 - swi.bi $r3, [$r1], 4 - bne $r1, $r2, data_loop - - /* store the content of r5 (lp after reset) into "ec_reset_lp" */ - swi.gp $r5, [ + ec_reset_lp] - - /* we switch to our own exception vectors */ - /* go back to it level 0 with HW interrupts globally disabled */ - li $r4, 0x70008 - mtsr $r4, $PSW - /* IT8380 specific: set vectors at 0 */ - li $r5, 0x0F02041 /* IVTBAR in GCTRL */ - movi $r15, 0 - sbi $r15, [$r5] - /* Interrupt vectors are every 4 bytes */ - li $r5, 0x00000007 - mtsr $r5, $IVB - - /* clear BRAM if it is not valid */ - jal chip_bram_valid - /* Jump to C routine */ - jal main - - /* That should not return. If it does, loop forever. */ - j . - -.global unhandled_irq -unhandled_irq: - mfsr $gp, $ITYPE - sethi $r15, 0xBAD0 - or $r15, $r15, $gp - mtsr $r15, $ITYPE - dsb - j excep_handler /* display exception with ITYPE=bad00 */ - -.global excep_handler -excep_handler: -#ifdef CONFIG_FPU - /* - * We have to restore ALU so that we can continue the next - * sequence if arithmetic instructions are used. - * (Apply to floating point division by zero) - */ - sethi $gp, 0x80 - ori $gp, $gp,0x9 - mtsr $gp, $dlmb - dsb -#endif - /* safety: reload GP even though it should be already set */ - la $gp, _SDA_BASE_ - /* save r0 to free one register */ - swi.gp $r0, [ + saved_regs] - /* save the remaining 15 registers */ - la $r0, saved_regs + 4 - smw.bim $r1, [$r0], $r10, 0 - smw.bim $r15,[$r0], $r15, 0xF - /* put a sane stack pointer */ - la $sp, stack_end - /* add IPC, IPSW to the context */ - mfsr $r1, $IPC - mfsr $r2, $IPSW - smw.bi $r1, [$r0], $r2, 0 - /* pass ir6/ITYPE as the second parameter */ - mfsr $r1, $ITYPE - /* exception context pointer as first parameter */ - addi $r0, $r0, -16*4 - /* jump to panic dump C routine */ - jal report_panic - /* we never return: exceptions are fatal */ - j . - -.align 2 -_bss_start: -.long __bss_start -_bss_end: -.long __bss_end -_data_start: -.long __data_start -_data_end: -.long __data_end -_data_lma_start: -.long __data_lma_start - -/* Reserve space for system stack */ -.section .bss.system_stack -stack_start: -.space CONFIG_STACK_SIZE, 0 -stack_end: -.global stack_end -/* registers state at exception entry */ -.global saved_regs -saved_regs: -.long 0, 0, 0, 0, 0, 0, 0, 0 -.long 0, 0, 0, 0, 0, 0, 0, 0 -/* IPC, IPSW for convenient access */ -.long 0, 0 diff --git a/core/nds32/irq_chip.h b/core/nds32/irq_chip.h deleted file mode 100644 index fc9f64c250..0000000000 --- a/core/nds32/irq_chip.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 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. - * - * Chip-specific part of the IRQ handling. - */ - -#ifndef __CROS_EC_IRQ_CHIP_H -#define __CROS_EC_IRQ_CHIP_H - -/** - * Enable an IRQ in the chip interrupt controller. - * - * @param irq interrupt request index. - * @return CPU interrupt number to enable if any, -1 else. - */ -int chip_enable_irq(int irq); - -/** - * Disable an IRQ in the chip interrupt controller. - * - * @param irq interrupt request index. - * @return CPU interrupt number to disable if any, -1 else. - */ -int chip_disable_irq(int irq); - -/** - * Clear a pending IRQ in the chip interrupt controller. - * - * @param irq interrupt request index. - * @return CPU interrupt number to clear if any, -1 else. - * - * Note that most interrupts can be removed from the pending state simply by - * handling whatever caused the interrupt in the first place. This only needs - * to be called if an interrupt handler disables itself without clearing the - * reason for the interrupt, and then the interrupt is re-enabled from a - * different context. - */ -int chip_clear_pending_irq(int irq); - -/** - * Software-trigger an IRQ in the chip interrupt controller. - * - * @param irq interrupt request index. - * @return CPU interrupt number to trigger if any, -1 else. - */ -int chip_trigger_irq(int irq); - -/** - * Initialize chip interrupt controller. - */ -void chip_init_irqs(void); - -/** - * Return interrupt number of software interrupt. - */ -int get_sw_int(void); - -#endif /* __CROS_EC_IRQ_CHIP_H */ diff --git a/core/nds32/irq_handler.h b/core/nds32/irq_handler.h deleted file mode 100644 index b37b7927ef..0000000000 --- a/core/nds32/irq_handler.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright 2014 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. - */ - -/* Helper to declare IRQ handling routines */ - -#ifndef __CROS_EC_IRQ_HANDLER_H -#define __CROS_EC_IRQ_HANDLER_H - -/* Helper macros to build the IRQ handler and priority struct names */ -#define IRQ_HANDLER(irqname) CONCAT3(irq_, irqname, _handler) -#define IRQ_PRIORITY(irqname) CONCAT2(prio_, irqname) -/* - * Macro to connect the interrupt handler "routine" to the irq number "irq" and - * ensure it is enabled in the interrupt controller with the right priority. - */ -#define DECLARE_IRQ(irq, routine, priority) \ - void IRQ_HANDLER(CPU_INT(irq))(void) \ - __attribute__ ((alias(STRINGIFY(routine)))); \ - const struct irq_priority __keep IRQ_PRIORITY(CPU_INT(irq)) \ - __attribute__((section(".rodata.irqprio"))) \ - = {CPU_INT(irq), priority} - -#endif /* __CROS_EC_IRQ_HANDLER_H */ diff --git a/core/nds32/math.c b/core/nds32/math.c deleted file mode 100644 index 496fcc0e5d..0000000000 --- a/core/nds32/math.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright 2017 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. - */ - -#include "common.h" - -#ifdef CONFIG_FPU -union ieee_float_shape_type { - float value; - uint32_t word; -}; - -/* Get a 32 bit int from a float. */ -#define GET_FLOAT_WORD(i, d) \ - do { \ - union ieee_float_shape_type gf_u; \ - gf_u.value = (d); \ - (i) = gf_u.word; \ - } while (0) - -/* Set a float from a 32 bit int. */ -#define SET_FLOAT_WORD(d, i) \ - do { \ - union ieee_float_shape_type sf_u; \ - sf_u.word = (i); \ - (d) = sf_u.value; \ - } while (0) - -float fabsf(float x) -{ - uint32_t ix; - - GET_FLOAT_WORD(ix, x); - SET_FLOAT_WORD(x, (ix & 0x7fffffff)); - - return x; -} - -#define FLT_UWORD_IS_ZERO(x) ((x) == 0) -#define FLT_UWORD_IS_SUBNORMAL(x) ((x) < 0x00800000L) -#define FLT_UWORD_IS_FINITE(x) ((x) < 0x7f800000L) - -static const float one = 1.0f, tiny = 1.0e-30f; -static float __ieee754_sqrtf(float x) -{ - float z; - uint32_t r, hx; - int32_t ix, s, q, m, t, i; - - GET_FLOAT_WORD(ix, x); - hx = ix & 0x7fffffff; - - /* - * take care of Inf and NaN - * sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN - */ - if (!FLT_UWORD_IS_FINITE(hx)) - return x * x + x; - /* take care of zero and -ves */ - if (FLT_UWORD_IS_ZERO(hx)) - return x; - if (ix < 0) - return (x - x) / (x - x); - - m = (ix >> 23); - if (FLT_UWORD_IS_SUBNORMAL(hx)) { - for (i = 0; (ix & 0x00800000L) == 0; i++) - ix <<= 1; - m -= i - 1; - } - - m -= 127; - ix = (ix & 0x007fffffL) | 0x00800000L; - if (m & 1) - ix += ix; - - m >>= 1; - ix += ix; - q = s = 0; - r = 0x01000000L; - - while (r != 0) { - t = s + r; - if (t <= ix) { - s = t + r; - ix -= t; - q += r; - } - ix += ix; - r >>= 1; - } - - if (ix != 0) { - z = one - tiny; - if (z >= one) { - z = one + tiny; - if (z > one) - q += 2; - else - q += (q & 1); - } - } - - ix = (q >> 1) + 0x3f000000L; - ix += (m << 23); - SET_FLOAT_WORD(z, ix); - - return z; -} - -float sqrtf(float x) -{ - return __ieee754_sqrtf(x); -} -#endif diff --git a/core/nds32/panic.c b/core/nds32/panic.c deleted file mode 100644 index 37f4ac77e1..0000000000 --- a/core/nds32/panic.c +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright 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. - */ - -#include "common.h" -#include "console.h" -#include "cpu.h" -#include "panic.h" -#include "printf.h" -#include "software_panic.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* General purpose register (r6) for saving software panic reason */ -#define SOFT_PANIC_GPR_REASON 6 -/* General purpose register (r7) for saving software panic information */ -#define SOFT_PANIC_GPR_INFO 7 - -/* Panic data goes at the end of RAM. */ -static struct panic_data * const pdata_ptr = PANIC_DATA_PTR; - -#ifdef CONFIG_DEBUG_EXCEPTIONS -/** - * bit[4] @ ITYPE, Indicates if an exception is caused by an instruction fetch - * or a data memory access for the following exceptions: - * -TLB fill - * -TLB VLPT miss - * -TLB read protection - * -TLB write protection - * -TLB non-executable page - * -TLB page modified - * -TLB Access bit - * -PTE not present (all) - * -Reserved PTE Attribute - * -Alignment check - * -Branch target alignment - * -Machine error - * -Precise bus error - * -Imprecise bus error - * -Nonexistent local memory address - * -MPZIU Control - * -Cache locking error - * -TLB locking error - * -TLB multiple hit - * -Parity/ECC error - * All other exceptions not in the abovetable should have the INST field of - * the ITYPE register set to 0. - */ -static const char * const itype_inst[2] = { - "a data memory access", - "an instruction fetch access", -}; - -/** - * bit[3-0] @ ITYPE, general exception type information. - */ -static const char * const itype_exc_type[16] = { - "Alignment check", - "Reserved instruction", - "Trap", - "Arithmetic", - "Precise bus error", - "Imprecise bus error", - "Coprocessor", - "Privileged instruction", - - "Reserved value", - "Nonexistent local memory address", - "MPZIU Control", - NULL, - NULL, - NULL, - NULL, - NULL, -}; -#endif /* CONFIG_DEBUG_EXCEPTIONS */ - -#ifdef CONFIG_SOFTWARE_PANIC -void software_panic(uint32_t reason, uint32_t info) -{ - asm volatile ("mov55 $r6, %0" : : "r"(reason)); - asm volatile ("mov55 $r7, %0" : : "r"(info)); - if (in_interrupt_context()) - asm("j excep_handler"); - else - asm("break 0"); - __builtin_unreachable(); -} - -void panic_set_reason(uint32_t reason, uint32_t info, uint8_t exception) -{ - uint32_t *regs = pdata_ptr->nds_n8.regs; - uint32_t warning_ipc; - - /* Setup panic data structure */ - if (reason != PANIC_SW_WATCHDOG) { - memset(pdata_ptr, 0, sizeof(*pdata_ptr)); - } else { - warning_ipc = pdata_ptr->nds_n8.ipc; - memset(pdata_ptr, 0, sizeof(*pdata_ptr)); - pdata_ptr->nds_n8.ipc = warning_ipc; - } - pdata_ptr->magic = PANIC_DATA_MAGIC; - pdata_ptr->struct_size = sizeof(*pdata_ptr); - pdata_ptr->struct_version = 2; - pdata_ptr->arch = PANIC_ARCH_NDS32_N8; - - /* Log panic cause */ - pdata_ptr->nds_n8.itype = exception; - regs[SOFT_PANIC_GPR_REASON] = reason; - regs[SOFT_PANIC_GPR_INFO] = info; -} - -void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception) -{ - uint32_t *regs = pdata_ptr->nds_n8.regs; - - if (pdata_ptr->magic == PANIC_DATA_MAGIC && - pdata_ptr->struct_version == 2) { - *exception = pdata_ptr->nds_n8.itype; - *reason = regs[SOFT_PANIC_GPR_REASON]; - *info = regs[SOFT_PANIC_GPR_INFO]; - } else { - *exception = *reason = *info = 0; - } -} -#endif /* CONFIG_SOFTWARE_PANIC */ - -static void print_panic_information(uint32_t *regs, uint32_t itype, - uint32_t ipc, uint32_t ipsw) -{ - panic_printf("=== EXCEP: ITYPE=%x ===\n", itype); - panic_printf("R0 %08x R1 %08x R2 %08x R3 %08x\n", - regs[0], regs[1], regs[2], regs[3]); - panic_printf("R4 %08x R5 %08x R6 %08x R7 %08x\n", - regs[4], regs[5], regs[6], regs[7]); - panic_printf("R8 %08x R9 %08x R10 %08x R15 %08x\n", - regs[8], regs[9], regs[10], regs[11]); - panic_printf("FP %08x GP %08x LP %08x SP %08x\n", - regs[12], regs[13], regs[14], regs[15]); - panic_printf("IPC %08x IPSW %05x\n", ipc, ipsw); - if ((ipsw & PSW_INTL_MASK) == (2 << PSW_INTL_SHIFT)) { - /* 2nd level exception */ - uint32_t oipc; - - asm volatile("mfsr %0, $OIPC" : "=r"(oipc)); - panic_printf("OIPC %08x\n", oipc); - } - -#ifdef CONFIG_DEBUG_EXCEPTIONS - panic_printf("SWID of ITYPE: %x\n", ((itype >> 16) & 0x7fff)); - if (panic_sw_reason_is_valid(regs[SOFT_PANIC_GPR_REASON])) { -#ifdef CONFIG_SOFTWARE_PANIC - panic_printf("Software panic reason %s\n", - panic_sw_reasons[(regs[SOFT_PANIC_GPR_REASON] - - PANIC_SW_BASE)]); - panic_printf("Software panic info 0x%x\n", - regs[SOFT_PANIC_GPR_INFO]); -#endif - } else { - panic_printf("Exception type: General exception [%s]\n", - itype_exc_type[(itype & 0xf)]); - panic_printf("Exception is caused by %s\n", - itype_inst[(itype & BIT(4))]); - } -#endif -} - -void report_panic(uint32_t *regs, uint32_t itype) -{ - int i; - struct panic_data *pdata = pdata_ptr; - - pdata->magic = PANIC_DATA_MAGIC; - pdata->struct_size = sizeof(*pdata); - pdata->struct_version = 2; - pdata->arch = PANIC_ARCH_NDS32_N8; - pdata->flags = 0; - pdata->reserved = 0; - - pdata->nds_n8.itype = itype; - for (i = 0; i < 16; i++) - pdata->nds_n8.regs[i] = regs[i]; - pdata->nds_n8.ipc = regs[16]; - pdata->nds_n8.ipsw = regs[17]; - - print_panic_information(regs, itype, regs[16], regs[17]); - panic_reboot(); -} - -void panic_data_print(const struct panic_data *pdata) -{ - uint32_t itype, *regs, ipc, ipsw; - itype = pdata->nds_n8.itype; - regs = (uint32_t *)pdata->nds_n8.regs; - ipc = pdata->nds_n8.ipc; - ipsw = pdata->nds_n8.ipsw; - - print_panic_information(regs, itype, ipc, ipsw); -} diff --git a/core/nds32/switch.S b/core/nds32/switch.S deleted file mode 100644 index 95a94e63e5..0000000000 --- a/core/nds32/switch.S +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright 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 * 18 - /* we are ready to re-schedule */ - swi.gp $r4, [ + need_resched] - swi.gp $r4, [ + start_called] - - /* 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 - diff --git a/core/nds32/task.c b/core/nds32/task.c deleted file mode 100644 index f86ef61ea1..0000000000 --- a/core/nds32/task.c +++ /dev/null @@ -1,809 +0,0 @@ -/* Copyright 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. - */ - -/* Task scheduling / events module for Chrome EC operating system */ - -#include "atomic.h" -#include "common.h" -#include "console.h" -#include "cpu.h" -#include "hwtimer_chip.h" -#include "intc.h" -#include "irq_chip.h" -#include "link_defs.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -typedef union { - struct { - /* - * Note that sp must be the first element in the task struct - * for __switchto() to work. - */ - uint32_t sp; /* Saved stack pointer for context switch */ - uint32_t events; /* Bitmaps of received events */ - uint64_t runtime; /* Time spent in task */ - uint32_t *stack; /* Start of stack */ - }; -} task_; - -/* Value to store in unused stack */ -#define STACK_UNUSED_VALUE 0xdeadd00d - -/* declare task routine prototypes */ -#define TASK(n, r, d, s) void r(void *); -void __idle(void); -CONFIG_TASK_LIST -CONFIG_TEST_TASK_LIST -#undef TASK - -/* Task names for easier debugging */ -#define TASK(n, r, d, s) #n, -static const char * const task_names[] = { - "<< idle >>", - CONFIG_TASK_LIST - CONFIG_TEST_TASK_LIST -}; -#undef TASK - -#ifdef CONFIG_TASK_PROFILING -static int task_will_switch; -static uint64_t exc_sub_time; -static uint64_t task_start_time; /* Time task scheduling started */ -static uint64_t exc_start_time; /* Time of task->exception transition */ -static uint64_t exc_end_time; /* Time of exception->task transition */ -static uint64_t exc_total_time; /* Total time in exceptions */ -static uint32_t svc_calls; /* Number of service calls */ -static uint32_t task_switches; /* Number of times active task changed */ -static uint32_t irq_dist[CONFIG_IRQ_COUNT]; /* Distribution of IRQ calls */ -#endif - -extern int __task_start(void); - -#ifndef CONFIG_LOW_POWER_IDLE -/* Idle task. Executed when no tasks are ready to be scheduled. */ -void __idle(void) -{ - /* - * Print when the idle task starts. This is the lowest priority task, - * so this only starts once all other tasks have gotten a chance to do - * their task inits and have gone to sleep. - */ - cprints(CC_TASK, "idle task started"); - - while (1) { -#ifdef CHIP_FAMILY_IT83XX - /* doze mode */ - IT83XX_ECPM_PLLCTRL = EC_PLL_DOZE; -#endif - asm volatile ("dsb"); - /* - * Wait for the next irq event. This stops the CPU clock - * (sleep / deep sleep, depending on chip config). - */ - asm("standby wake_grant"); - } -} -#endif /* !CONFIG_LOW_POWER_IDLE */ - -static void task_exit_trap(void) -{ - int i = task_get_current(); - cprints(CC_TASK, "Task %d (%s) exited!", i, task_names[i]); - /* Exited tasks simply sleep forever */ - while (1) - task_wait_event(-1); -} - -/* Startup parameters for all tasks. */ -#define TASK(n, r, d, s) { \ - .r0 = (uint32_t)d, \ - .pc = (uint32_t)r, \ - .stack_size = s, \ -}, -static const struct { - uint32_t r0; - uint32_t pc; - uint16_t stack_size; -} tasks_init[] = { - TASK(IDLE, __idle, 0, IDLE_TASK_STACK_SIZE) - CONFIG_TASK_LIST - CONFIG_TEST_TASK_LIST -}; -#undef TASK - -/* Contexts for all tasks */ -static task_ tasks[TASK_ID_COUNT]; -/* Sanity checks about static task invariants */ -BUILD_ASSERT(TASK_ID_COUNT <= sizeof(unsigned) * 8); -BUILD_ASSERT(TASK_ID_COUNT < (1 << (sizeof(task_id_t) * 8))); - - -/* Stacks for all tasks */ -#define TASK(n, r, d, s) + s -uint8_t task_stacks[0 - TASK(IDLE, __idle, 0, IDLE_TASK_STACK_SIZE) - CONFIG_TASK_LIST - CONFIG_TEST_TASK_LIST -] __aligned(8); - -#undef TASK - -/* Reserve space to discard context on first context switch. */ -uint32_t scratchpad[19]; - -task_ *current_task = (task_ *)scratchpad; - -/* - * Should IRQs chain to svc_handler()? This should be set if either of the - * following is true: - * - * 1) Task scheduling has started, and task profiling is enabled. Task - * profiling does its tracking in svc_handler(). - * - * 2) An event was set by an interrupt; this could result in a higher-priority - * task unblocking. After checking for a task switch, svc_handler() will clear - * the flag (unless profiling is also enabled; then the flag remains set). - */ -int need_resched; - -/* - * Bitmap of all tasks ready to be run. - * - * Start off with only the hooks task marked as ready such that all the modules - * can do their init within a task switching context. The hooks task will then - * make a call to enable all tasks. - */ -static uint32_t tasks_ready = BIT(TASK_ID_HOOKS); -/* - * Initially allow only the HOOKS and IDLE task to run, regardless of ready - * status, in order for HOOK_INIT to complete before other tasks. - * task_enable_all_tasks() will open the flood gates. - */ -static uint32_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); - -int start_called; /* Has task swapping started */ - -/* interrupt number of sw interrupt */ -static int sw_int_num; - -/* Number of CPU hardware interrupts (HW0 ~ HW15) */ -int cpu_int_entry_number; - -/* - * This variable is used to save link pointer register, - * and it is updated at the beginning of each ISR. - */ -uint32_t ilp; - -/* This variable is used to save link pointer register at EC reset. */ -uint32_t ec_reset_lp; - -static inline task_ *__task_id_to_ptr(task_id_t id) -{ - return tasks + id; -} - -/* - * We use INT_MASK to enable (interrupt_enable)/ - * disable (interrupt_disable) all maskable interrupts. - * And, EC modules share HW2 ~ HW15 interrupts. If corresponding - * bit of INT_MASK is set, it will never be cleared - * (see chip_disable_irq()). To enable/disable individual - * interrupt of EC module, we can use corresponding EXT_IERx registers. - * - * ------------ ----------- - * | | | ------- | - * |EC modules| | | HW2 | | - * | | | ------- | - * | INT 0 | | ------- | ------- ------- - * | ~ | --> | | HW3 | | -> | GIE | -> | CPU | - * | INT 167 | | ------- | ------- ------- - * | | | ... | | - * | | | ... | - clear by HW while - * | | | ------- | interrupt occur and - * | | | | HW15| | restore from IPSW after - * | | | ------- | instruction "iret". - * | EXT_IERx | | INT_MASK| - * ------------ ----------- - */ -void __ram_code interrupt_disable(void) -{ - /* Mask all interrupts, only keep division by zero exception */ - uint32_t val = BIT(30); - asm volatile ("mtsr %0, $INT_MASK" : : "r"(val)); - asm volatile ("dsb"); -} - -void __ram_code interrupt_enable(void) -{ - /* Enable HW2 ~ HW15 and division by zero exception interrupts */ - uint32_t val = (BIT(30) | 0xFFFC); - asm volatile ("mtsr %0, $INT_MASK" : : "r"(val)); -} - -inline int in_interrupt_context(void) -{ - /* check INTL (Interrupt Stack Level) bits */ - return get_psw() & PSW_INTL_MASK; -} - -task_id_t task_get_current(void) -{ -#ifdef CONFIG_DEBUG_BRINGUP - /* If we haven't done a context switch then our task ID isn't valid */ - ASSERT(current_task != (task_ *)scratchpad); -#endif - return current_task - tasks; -} - -uint32_t *task_get_event_bitmap(task_id_t tskid) -{ - task_ *tsk = __task_id_to_ptr(tskid); - return &tsk->events; -} - -int task_start_called(void) -{ - return start_called; -} - -int get_sw_int(void) -{ - /* If this is a SW interrupt */ - if (get_itype() & 8) - return sw_int_num; - return 0; -} - -/** - * Scheduling system call - * - * Also includes emulation of software triggering interrupt vector - */ -void __ram_code __keep syscall_handler(int desched, task_id_t resched, - int swirq) -{ - /* are we emulating an interrupt ? */ - if (swirq) { - void (*handler)(void) = __irqhandler[swirq + 1]; - /* adjust IPC to return *after* the syscall instruction */ - set_ipc(get_ipc() + 4); - /* call the regular IRQ handler */ - handler(); - sw_int_num = 0; - return; - } - - if (desched && !current_task->events) { - /* - * Remove our own ready bit (current - tasks is same as - * task_get_current()) - */ - tasks_ready &= ~(1 << (current_task - tasks)); - } - tasks_ready |= 1 << resched; - - /* trigger a re-scheduling on exit */ - need_resched = 1; - -#ifdef CONFIG_TASK_PROFILING - svc_calls++; -#endif - - /* adjust IPC to return *after* the syscall instruction */ - set_ipc(get_ipc() + 4); -} - -task_ *next_sched_task(void) -{ - task_ *new_task = __task_id_to_ptr(__fls(tasks_ready & tasks_enabled)); - -#ifdef CONFIG_TASK_PROFILING - if (current_task != new_task) { - if ((current_task - tasks) < TASK_ID_COUNT) { - current_task->runtime += - (exc_start_time - exc_end_time - exc_sub_time); - } - task_will_switch = 1; - } -#endif - -#ifdef CONFIG_DEBUG_STACK_OVERFLOW - if (*current_task->stack != STACK_UNUSED_VALUE) { - int i = task_get_current(); - if (i < TASK_ID_COUNT) { - panic_printf("\n\nStack overflow in %s task!\n", - task_names[i]); -#ifdef CONFIG_SOFTWARE_PANIC - software_panic(PANIC_SW_STACK_OVERFLOW, i); -#endif - } - } -#endif - - return new_task; -} - -static inline void __schedule(int desched, int resched, int swirq) -{ - register int p0 asm("$r0") = desched; - register int p1 asm("$r1") = resched; - register int p2 asm("$r2") = swirq; - - asm("syscall 0" : : "r"(p0), "r"(p1), "r"(p2)); -} - -void update_exc_start_time(void) -{ -#ifdef CONFIG_TASK_PROFILING - exc_start_time = get_time().val; -#endif -} - -/* Interrupt number of EC modules */ -static volatile int ec_int; - -#ifdef CHIP_FAMILY_IT83XX -int __ram_code intc_get_ec_int(void) -{ - return ec_int; -} -#endif - -void __ram_code start_irq_handler(void) -{ - /* save r0, r1, and r2 for syscall */ - asm volatile ("smw.adm $r0, [$sp], $r2, 0"); - /* If this is a SW interrupt */ - if (get_itype() & 8) { - ec_int = get_sw_int(); - } else { -#ifdef CHIP_FAMILY_IT83XX - int i; - - for (i = 0; i < IT83XX_IRQ_COUNT; i++) { - ec_int = IT83XX_INTC_IVCT(cpu_int_entry_number); - /* - * WORKAROUND: when the interrupt vector register isn't - * latched in a load operation, - * we read it again to make sure the value we got - * is the correct value. - */ - if (ec_int == IT83XX_INTC_IVCT(cpu_int_entry_number)) - break; - } - /* Determine interrupt number */ - ec_int -= 16; -#endif - } - -#if defined(CONFIG_LOW_POWER_IDLE) && defined(CHIP_FAMILY_IT83XX) - clock_sleep_mode_wakeup_isr(); -#endif -#ifdef CONFIG_TASK_PROFILING - update_exc_start_time(); - - /* - * Track IRQ distribution. No need for atomic add, because an IRQ - * can't pre-empt itself. - */ - if ((ec_int > 0) && (ec_int < ARRAY_SIZE(irq_dist))) - irq_dist[ec_int]++; -#endif - /* restore r0, r1, and r2 */ - asm volatile ("lmw.bim $r0, [$sp], $r2, 0"); -} - -void end_irq_handler(void) -{ -#ifdef CONFIG_TASK_PROFILING - uint64_t t, p; - /* - * save r0 and fp (fp for restore r0-r5, r15, fp, lp and sp - * while interrupt exit. - */ - asm volatile ("smw.adm $r0, [$sp], $r0, 8"); - - t = get_time().val; - p = t - exc_start_time; - - exc_total_time += p; - exc_sub_time += p; - if (task_will_switch) { - task_will_switch = 0; - exc_sub_time = 0; - exc_end_time = t; - task_switches++; - } - - /* restore r0 and fp */ - asm volatile ("lmw.bim $r0, [$sp], $r0, 8"); -#endif -} - -static uint32_t __ram_code __wait_evt(int timeout_us, task_id_t resched) -{ - task_ *tsk = current_task; - task_id_t me = tsk - tasks; - uint32_t evt; - int ret; - - ASSERT(!in_interrupt_context()); - - if (timeout_us > 0) { - timestamp_t deadline = get_time(); - deadline.val += timeout_us; - ret = timer_arm(deadline, me); - ASSERT(ret == EC_SUCCESS); - } - while (!(evt = atomic_read_clear(&tsk->events))) { - /* Remove ourself and get the next task in the scheduler */ - __schedule(1, resched, 0); - resched = TASK_ID_IDLE; - } - if (timeout_us > 0) { - timer_cancel(me); - /* Ensure timer event is clear, we no longer care about it */ - atomic_clear(&tsk->events, TASK_EVENT_TIMER); - } - return evt; -} - -uint32_t __ram_code task_set_event(task_id_t tskid, uint32_t event, int wait) -{ - task_ *receiver = __task_id_to_ptr(tskid); - ASSERT(receiver); - - /* Set the event bit in the receiver message bitmap */ - atomic_or(&receiver->events, event); - - /* Re-schedule if priorities have changed */ - if (in_interrupt_context()) { - /* The receiver might run again */ - atomic_or(&tasks_ready, 1 << tskid); - if (start_called) - need_resched = 1; - } else { - if (wait) - return __wait_evt(-1, tskid); - else - __schedule(0, tskid, 0); - } - - return 0; -} - -uint32_t __ram_code task_wait_event(int timeout_us) -{ - return __wait_evt(timeout_us, TASK_ID_IDLE); -} - -uint32_t __ram_code task_wait_event_mask(uint32_t event_mask, int timeout_us) -{ - uint64_t deadline = get_time().val + timeout_us; - uint32_t events = 0; - int time_remaining_us = timeout_us; - - /* Add the timer event to the mask so we can indicate a timeout */ - event_mask |= TASK_EVENT_TIMER; - - while (!(events & event_mask)) { - /* Collect events to re-post later */ - events |= __wait_evt(time_remaining_us, TASK_ID_IDLE); - - time_remaining_us = deadline - get_time().val; - if (timeout_us > 0 && time_remaining_us <= 0) { - /* Ensure we return a TIMER event if we timeout */ - events |= TASK_EVENT_TIMER; - break; - } - } - - /* Re-post any other events collected */ - if (events & ~event_mask) - atomic_or(¤t_task->events, events & ~event_mask); - - return events & event_mask; -} - -uint32_t __ram_code get_int_mask(void) -{ - uint32_t ret; - asm volatile ("mfsr %0, $INT_MASK" : "=r"(ret)); - return ret; -} - -void __ram_code set_int_mask(uint32_t val) -{ - asm volatile ("mtsr %0, $INT_MASK" : : "r"(val)); -} - -static void set_int_priority(uint32_t val) -{ - asm volatile ("mtsr %0, $INT_PRI" : : "r"(val)); -} - -uint32_t get_int_ctrl(void) -{ - uint32_t ret; - - asm volatile ("mfsr %0, $INT_CTRL" : "=r"(ret)); - return ret; -} - -void set_int_ctrl(uint32_t val) -{ - asm volatile ("mtsr %0, $INT_CTRL" : : "r"(val)); -} - -void task_enable_all_tasks(void) -{ - /* Mark all tasks as ready and able to run. */ - tasks_ready = tasks_enabled = BIT(TASK_ID_COUNT) - 1; - /* Reschedule the highest priority task. */ - __schedule(0, 0, 0); -} - -void task_enable_task(task_id_t tskid) -{ - atomic_or(&tasks_enabled, BIT(tskid)); -} - -void task_disable_task(task_id_t tskid) -{ - atomic_clear(&tasks_enabled, BIT(tskid)); - - if (!in_interrupt_context() && tskid == task_get_current()) - __schedule(0, 0, 0); -} - -void __ram_code task_enable_irq(int irq) -{ - uint32_t int_mask = get_int_mask(); - - interrupt_disable(); - chip_enable_irq(irq); - set_int_mask(int_mask); -} - -void __ram_code task_disable_irq(int irq) -{ - uint32_t int_mask = get_int_mask(); - - interrupt_disable(); - chip_disable_irq(irq); - set_int_mask(int_mask); -} - -void __ram_code task_clear_pending_irq(int irq) -{ - chip_clear_pending_irq(irq); -} - -void __ram_code task_trigger_irq(int irq) -{ - int cpu_int = chip_trigger_irq(irq); - - if (cpu_int > 0) { - sw_int_num = irq; - __schedule(0, 0, cpu_int); - } -} - -/* - * Initialize IRQs in the IVIC and set their priorities as defined by the - * DECLARE_IRQ statements. - */ -static void ivic_init_irqs(void) -{ - /* Get the IRQ priorities section from the linker */ - int exc_calls = __irqprio_end - __irqprio; - int i; - uint32_t all_priorities = 0; - - /* chip-specific interrupt controller initialization */ - chip_init_irqs(); - - /* - * bit0 @ INT_CTRL = 0, - * Interrupts still keep programmable priority level. - */ - set_int_ctrl((get_int_ctrl() & ~BIT(0))); - - /* - * Re-enable global interrupts in case they're disabled. On a reboot, - * they're already enabled; if we've jumped here from another image, - * they're not. - */ - interrupt_enable(); - - /* Set priorities */ - for (i = 0; i < exc_calls; i++) { - uint8_t irq = __irqprio[i].irq; - uint8_t prio = __irqprio[i].priority; - all_priorities |= (prio & 0x3) << (irq * 2); - } - set_int_priority(all_priorities); -} - -void __ram_code mutex_lock(struct mutex *mtx) -{ - uint32_t id = 1 << task_get_current(); - - ASSERT(id != TASK_ID_INVALID); - - /* critical section with interrupts off */ - interrupt_disable(); - mtx->waiters |= id; - while (1) { - if (!mtx->lock) { /* we got it ! */ - mtx->lock = 2; - mtx->waiters &= ~id; - /* end of critical section : re-enable interrupts */ - interrupt_enable(); - return; - } else { /* Contention on the mutex */ - /* end of critical section : re-enable interrupts */ - interrupt_enable(); - /* Sleep waiting for our turn */ - task_wait_event_mask(TASK_EVENT_MUTEX, 0); - /* re-enter critical section */ - interrupt_disable(); - } - } -} - -void __ram_code mutex_unlock(struct mutex *mtx) -{ - uint32_t waiters; - task_ *tsk = current_task; - - waiters = mtx->waiters; - /* give back the lock */ - mtx->lock = 0; - - while (waiters) { - task_id_t id = __fls(waiters); - waiters &= ~BIT(id); - - /* Somebody is waiting on the mutex */ - task_set_event(id, TASK_EVENT_MUTEX, 0); - } - - /* Ensure no event is remaining from mutex wake-up */ - atomic_clear(&tsk->events, TASK_EVENT_MUTEX); -} - -void task_print_list(void) -{ - int i; - - ccputs("Task Ready Name Events Time (s) StkUsed\n"); - - for (i = 0; i < TASK_ID_COUNT; i++) { - char is_ready = (tasks_ready & (1<stack = (uint32_t *)scratchpad; - *(uint32_t *)scratchpad = STACK_UNUSED_VALUE; - - /* Initialize IRQs */ - ivic_init_irqs(); -} - -int task_start(void) -{ -#ifdef CONFIG_TASK_PROFILING - task_start_time = exc_end_time = get_time().val; -#endif - - return __task_start(); -} -- cgit v1.2.1