summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@chromium.org>2020-12-22 09:37:55 +1100
committerCommit Bot <commit-bot@chromium.org>2020-12-22 21:02:14 +0000
commitdbc7c310f5babec6fd2b6a382b8a49b011296a12 (patch)
tree8cef0a0a753a01e803c93920a2f0970959f67685
parentdbe87fb73f561bfa7ae62da17cbf979eb00732a4 (diff)
downloadchrome-ec-factory-dalboz-13695.B-cr50_stab.tar.gz
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 <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2600300 Reviewed-by: Namyoon Woo <namyoon@chromium.org>
-rw-r--r--core/nds32/__builtin.c16
-rw-r--r--core/nds32/__divdi3.S372
-rw-r--r--core/nds32/__libsoftfpu.S195
-rw-r--r--core/nds32/__muldi3.S40
-rw-r--r--core/nds32/__udivdi3.S15
-rw-r--r--core/nds32/atomic.h57
-rw-r--r--core/nds32/build.mk26
-rw-r--r--core/nds32/config_core.h22
-rw-r--r--core/nds32/cpu.c16
-rw-r--r--core/nds32/cpu.h60
-rw-r--r--core/nds32/ec.lds.S268
-rw-r--r--core/nds32/include/math.h14
-rw-r--r--core/nds32/init.S269
-rw-r--r--core/nds32/irq_chip.h59
-rw-r--r--core/nds32/irq_handler.h25
-rw-r--r--core/nds32/math.c116
-rw-r--r--core/nds32/panic.c203
-rw-r--r--core/nds32/switch.S102
-rw-r--r--core/nds32/task.c809
19 files changed, 0 insertions, 2684 deletions
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<zB
- slli $ta, $ta, 16 ! (zA<zB)<<16
- maddr32 $ta, P2H, P1H ! zh=ah*bh+((zA<zB)<<16)
- srli P1H, W1, 16 ! 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<zA
- add P1H, P1H, $ta ! zh+=(zl<zA)
- ret
- .size umul_ppmm, .-umul_ppmm
-
- .text
- .align 2
- .type fudiv_qrnnd, @function
- ! =====================================================================
- ! uint64_t fudiv_qrnnd(uint64_t n, uint32_t d)
- !
- ! This function divides 64-bit numerator n by 32-bit denominator d. The
- ! 64-bit return value contains remainder (low-part at P1L) and quotient
- ! (high-part at P1H).
- ! This function uses a custom calling convention,
- ! with register DHI ($r10) call-clobbered instead of callee-saved.
- ! =====================================================================
-fudiv_qrnnd:
- srli DHI, D, 16 ! d1 = ll_highpart (d)
- zeh W1, NLO ! ll_lowpart (n0)
- srli T2, NLO, 16 ! ll_highpart (n0)
- divr QHI, RHI, NHI, DHI ! q1 = n1 / __d1, r1 = n1 % __d1
- zeh DLO, D ! d0 = ll_lowpart (d)
- slli RHI, RHI, 16 ! r1 << 16
- or RHI, RHI, T2 ! __r1 = (__r1 << 16) | ll_highpart(n0)
- mul M, QHI, DLO ! m = __q1*__d0
- slt $ta, RHI, M ! __r1 < __m
- beqz $ta, .L2 ! if no, skip
- addi QHI, QHI, -1 ! __q1--
- add RHI, RHI, D ! __r1 += d
- slt $ta, RHI, D ! __r1 < d
- bnez $ta, .L2 ! if yes, skip
- slt $ta, RHI, M ! __r1 < __m
- beqz $ta, .L2 ! if no, skip
- addi QHI, QHI, -1 ! __q1--
- add RHI, RHI, D ! __r1 += d
-.L2:
- sub RHI, RHI, M ! __r1 -= __m
- divr Q, T2, RHI, DHI ! __q0 = r1 / __d1, __r0 = r1 % __d1
- slli T2, T2, 16 ! __r0 << 16
- or R, T2, W1 ! __r0 = (__r0 << 16) | ll_lowpart(n0)
- mul M2, DLO, Q ! __m = __q0 * __d0
- slt $ta, R, M2 ! __r0 < __m
- beqz $ta, .L5 ! if no, skip
- add R, R, D ! __r0 += d
- addi Q, Q, -1 ! __q0--
- slt $ta, R, D ! __r0 < d
- bnez $ta, .L5 ! if yes, skip
- slt $ta, R, M2 ! __r0 < __m
- beqz $ta, .L5 ! if no, skip
- add R, R, D ! __r0 += d
- addi Q, Q, -1 ! __q0--
-
-.L5:
- sub R, R, M2 ! r = r0 = __r0 - __m
- slli QHI, QHI, 16 ! __q1 << 16
- or Q, Q, QHI ! q = (__q1 << 16) | __q0
- ret
- .size fudiv_qrnnd, .-fudiv_qrnnd
-
- .align 2
- .globl __udivmoddi4
- .type __udivmoddi4, @function
- ! =====================================================================
- ! uint64_t __udivmoddi4(uint64_t n, uint64_t d, uint64_t *r)
- !
- ! This function divides 64-bit numerator n by 64-bit denominator d. The
- ! quotient is returned as 64-bit return value and the 64-bit remainder
- ! is stored at the input address r.
- ! stack allocation:
- ! sp+40 +------------------+
- ! | q |
- ! sp+32 +------------------+
- ! | bm |
- ! sp+28 +------------------+
- ! | $lp |
- ! sp+24 +------------------+
- ! | $fp |
- ! sp+20 +------------------+
- ! | $r10 |
- ! sp+16 +------------------+
- ! | $r6 - $r9 |
- ! sp +------------------+
- ! =====================================================================
-__udivmoddi4:
- addi $sp, $sp, -40
- smw.bi $r6, [$sp], $r10 , 10
- movd44 NREGS, $r0 ! (n1,n0)
- movd44 DREGS, $r2 ! (d1,d0)
- move $fp, $r4 ! rp
- bnez P2H, .L9 ! if d1 != 0, skip
- slt $ta, NUMHI, DENLO ! n1 < d0
- beqz $ta, .L10 ! if no, skip
- move $r0, DENLO
- bal __clzsi2
- swi $r0, [$sp+(28)] ! bm
- beqz $r0, .LZskipnorm1 ! if bm == 0, skip
- sll DENLO, DENLO, $r0 ! d0 <<= bm
- subri W1, $r0, 32 ! 32 - bm
- srl W1, NUMLO, W1 ! n0 >> (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<zB
- slli $ta, $ta, 16 ! (zA<zB)<<16
- slli P2L, P1L, 16 ! zA<<16
- maddr32 $ta, P1H, P2H ! zh=alh*blh+((zA<zB)<<16)
- srli P1H, P1L, 16 ! zA>>16
- add P1H, P1H, $ta ! zh+=(zA>>16)
- add P1L, $r4, P2L ! zl+=(zA<<16)
- slt $ta, P1L, $r4 ! zl<zA
- add P1H, P1H, $ta ! zh+=(zl<zA)
- add P1H, P1H, $r5 ! zh+=ah*bl+bh*al
- ret
- .size __muldi3, .-__muldi3
diff --git a/core/nds32/__udivdi3.S b/core/nds32/__udivdi3.S
deleted file mode 100644
index 4cb3b058fe..0000000000
--- a/core/nds32/__udivdi3.S
+++ /dev/null
@@ -1,15 +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.
- *
- * __udivdi3.S: unsigned 64 bit division
- */
-
- .text
- .align 2
- .globl __udivdi3
- .type __udivdi3, @function
-__udivdi3:
- movi $r4, 0 ! ignore remainder
- b __udivmoddi4
- .size __udivdi3, .-__udivdi3
diff --git a/core/nds32/atomic.h b/core/nds32/atomic.h
deleted file mode 100644
index 8928fe3373..0000000000
--- a/core/nds32/atomic.h
+++ /dev/null
@@ -1,57 +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.
- */
-
-/* Atomic operations for Andes */
-
-#ifndef __CROS_EC_ATOMIC_H
-#define __CROS_EC_ATOMIC_H
-
-#include "common.h"
-#include "cpu.h"
-#include "task.h"
-
-static inline void atomic_clear(uint32_t volatile *addr, uint32_t bits)
-{
- uint32_t int_mask = get_int_mask();
- interrupt_disable();
- *addr &= ~bits;
- set_int_mask(int_mask);
-}
-
-static inline void atomic_or(uint32_t volatile *addr, uint32_t bits)
-{
- uint32_t int_mask = get_int_mask();
- interrupt_disable();
- *addr |= bits;
- set_int_mask(int_mask);
-}
-
-static inline void atomic_add(uint32_t volatile *addr, uint32_t value)
-{
- uint32_t int_mask = get_int_mask();
- interrupt_disable();
- *addr += value;
- set_int_mask(int_mask);
-}
-
-static inline void atomic_sub(uint32_t volatile *addr, uint32_t value)
-{
- uint32_t int_mask = get_int_mask();
- interrupt_disable();
- *addr -= value;
- set_int_mask(int_mask);
-}
-
-static inline uint32_t atomic_read_clear(uint32_t volatile *addr)
-{
- uint32_t val;
- uint32_t int_mask = get_int_mask();
- interrupt_disable();
- val = *addr;
- *addr = 0;
- set_int_mask(int_mask);
- return val;
-}
-#endif /* __CROS_EC_ATOMIC_H */
diff --git a/core/nds32/build.mk b/core/nds32/build.mk
deleted file mode 100644
index ddd65c680b..0000000000
--- a/core/nds32/build.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- makefile -*-
-# 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.
-#
-# Andestar v3m architecture core OS files build
-#
-
-# Set coreboot-sdk as the default toolchain for nds32
-NDS32_DEFAULT_COMPILE=/opt/coreboot-sdk/bin/nds32le-elf-
-
-# Select Andes bare-metal toolchain
-$(call set-option,CROSS_COMPILE,$(CROSS_COMPILE_nds32),$(NDS32_DEFAULT_COMPILE))
-
-# CPU specific compilation flags
-CFLAGS_CPU+=-march=v3m -Os
-LDFLAGS_EXTRA+=-mrelax
-
-ifneq ($(CONFIG_LTO),)
-CFLAGS_CPU+=-flto
-LDFLAGS_EXTRA+=-flto
-endif
-
-core-y=cpu.o init.o panic.o task.o switch.o __muldi3.o math.o __builtin.o
-core-y+=__divdi3.o __udivdi3.o
-core-$(CONFIG_FPU)+=__libsoftfpu.o
diff --git a/core/nds32/config_core.h b/core/nds32/config_core.h
deleted file mode 100644
index 7670e5cfad..0000000000
--- a/core/nds32/config_core.h
+++ /dev/null
@@ -1,22 +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.
- */
-
-#ifndef __CROS_EC_CONFIG_CORE_H
-#define __CROS_EC_CONFIG_CORE_H
-
-/* Linker binary architecture and format */
-#define BFD_ARCH nds32
-#define BFD_FORMAT "elf32-nds32le"
-
-#define CONFIG_SOFTWARE_PANIC
-
-/*
- * The Andestar v3m architecture has no CLZ/CTZ instructions (contrary to v3),
- * so let's use the software implementation.
- */
-#define CONFIG_SOFTWARE_CLZ
-#define CONFIG_SOFTWARE_CTZ
-
-#endif /* __CROS_EC_CONFIG_CORE_H */
diff --git a/core/nds32/cpu.c b/core/nds32/cpu.c
deleted file mode 100644
index 6a3f3b5bc4..0000000000
--- a/core/nds32/cpu.c
+++ /dev/null
@@ -1,16 +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.
- *
- * Set up the N8 core
- */
-
-#include "cpu.h"
-#include "registers.h"
-
-void cpu_init(void)
-{
- /* DLM initialization is done in init.S */
- /* Global interrupt enable */
- asm volatile ("setgie.e");
-}
diff --git a/core/nds32/cpu.h b/core/nds32/cpu.h
deleted file mode 100644
index eeacaf4c07..0000000000
--- a/core/nds32/cpu.h
+++ /dev/null
@@ -1,60 +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.
- *
- * Registers map and definitions for Andes cores
- */
-
-#ifndef __CROS_EC_CPU_H
-#define __CROS_EC_CPU_H
-
-#include <stdint.h>
-
-/* 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<irq> */
-
-.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(&current_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<<i)) ? 'R' : ' ';
- uint32_t *sp;
-
- int stackused = tasks_init[i].stack_size;
-
- for (sp = tasks[i].stack;
- sp < (uint32_t *)tasks[i].sp && *sp == STACK_UNUSED_VALUE;
- sp++)
- stackused -= sizeof(uint32_t);
-
- ccprintf("%4d %c %-16s %08x %11.6lld %3d/%3d\n", i, is_ready,
- task_names[i], tasks[i].events, tasks[i].runtime,
- stackused, tasks_init[i].stack_size);
- cflush();
- }
-}
-
-int command_task_info(int argc, char **argv)
-{
-#ifdef CONFIG_TASK_PROFILING
- int total = 0;
- int i;
-#endif
-
- task_print_list();
-
-#ifdef CONFIG_TASK_PROFILING
- ccputs("IRQ counts by type:\n");
- cflush();
- for (i = 0; i < ARRAY_SIZE(irq_dist); i++) {
- if (irq_dist[i]) {
- ccprintf("%4d %8d\n", i, irq_dist[i]);
- total += irq_dist[i];
- }
- }
-
- ccprintf("Service calls: %11d\n", svc_calls);
- ccprintf("Total exceptions: %11d\n", total + svc_calls);
- ccprintf("Task switches: %11d\n", task_switches);
- ccprintf("Task switching started: %11.6lld s\n", task_start_time);
- ccprintf("Time in tasks: %11.6lld s\n",
- get_time().val - task_start_time);
- ccprintf("Time in exceptions: %11.6lld s\n", exc_total_time);
-#endif
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(taskinfo, command_task_info,
- NULL,
- "Print task info");
-
-static int command_task_ready(int argc, char **argv)
-{
- if (argc < 2) {
- ccprintf("tasks_ready: 0x%08x\n", tasks_ready);
- } else {
- tasks_ready = strtoi(argv[1], NULL, 16);
- ccprintf("Setting tasks_ready to 0x%08x\n", tasks_ready);
- __schedule(0, 0, 0);
- }
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(taskready, command_task_ready,
- "[setmask]",
- "Print/set ready tasks");
-
-void task_pre_init(void)
-{
- uint32_t *stack_next = (uint32_t *)task_stacks;
- int i;
-
- /* Fill the task memory with initial values */
- for (i = 0; i < TASK_ID_COUNT; i++) {
- uint32_t *sp;
- /* Stack size in words */
- uint32_t ssize = tasks_init[i].stack_size / 4;
-
- tasks[i].stack = stack_next;
-
- /*
- * Update stack used by first frame: 15 regs + PC + PSW
- */
- sp = stack_next + ssize - 17;
- tasks[i].sp = (uint32_t)sp;
-
- /* Initial context on stack (see __switchto()) */
- sp[7] = tasks_init[i].r0; /* r0 */
- sp[15] = (uint32_t)task_exit_trap; /* lr */
- sp[1] = tasks_init[i].pc; /* pc */
- sp[0] = 0x70009; /* psw */
- sp[16] = (uint32_t)(sp + 17); /* sp */
-
- /* Fill unused stack; also used to detect stack overflow. */
- for (sp = stack_next; sp < (uint32_t *)tasks[i].sp; sp++)
- *sp = STACK_UNUSED_VALUE;
-
- stack_next += ssize;
- }
-
- /*
- * Fill in guard value in scratchpad to prevent stack overflow
- * detection failure on the first context switch. This works because
- * the first word in the scratchpad is where the switcher will store
- * sp, so it's ok to blow away.
- */
- ((task_ *)scratchpad)->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();
-}