summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
l---------core/cortex-m/aes.S1
-rw-r--r--core/cortex-m/atomic.h41
-rw-r--r--core/cortex-m/build.mk34
-rw-r--r--core/cortex-m/cache.S76
-rw-r--r--core/cortex-m/config_core.h15
-rw-r--r--core/cortex-m/cpu.c65
-rw-r--r--core/cortex-m/cpu.h103
-rw-r--r--core/cortex-m/debug.c12
-rw-r--r--core/cortex-m/debug.h37
-rw-r--r--core/cortex-m/ec.lds.S721
l---------core/cortex-m/ghash.S1
-rw-r--r--core/cortex-m/include/fpu.h35
-rw-r--r--core/cortex-m/include/mpu.h144
-rw-r--r--core/cortex-m/include/mpu_private.h25
-rw-r--r--core/cortex-m/init.S135
-rw-r--r--core/cortex-m/irq_handler.h44
l---------core/cortex-m/ldivmod.S1
-rw-r--r--core/cortex-m/llsr.c65
-rw-r--r--core/cortex-m/mpu.c457
-rw-r--r--core/cortex-m/panic-internal.h11
-rw-r--r--core/cortex-m/panic.c475
-rw-r--r--core/cortex-m/switch.S101
-rw-r--r--core/cortex-m/task.c1088
l---------core/cortex-m/uldivmod.S1
-rw-r--r--core/cortex-m/vecttable.c400
-rw-r--r--core/cortex-m/watchdog.c58
-rw-r--r--core/cortex-m0/__builtin.c16
-rw-r--r--core/cortex-m0/atomic.h73
-rw-r--r--core/cortex-m0/build.mk36
-rw-r--r--core/cortex-m0/config_core.h20
-rw-r--r--core/cortex-m0/cpu.c20
-rw-r--r--core/cortex-m0/cpu.h58
l---------core/cortex-m0/curve255191
l---------core/cortex-m0/debug.c1
l---------core/cortex-m0/debug.h1
l---------core/cortex-m0/div.S1
-rw-r--r--core/cortex-m0/ec.lds.S360
-rw-r--r--core/cortex-m0/include/fpu.h11
-rw-r--r--core/cortex-m0/init.S129
-rw-r--r--core/cortex-m0/irq_handler.h44
l---------core/cortex-m0/ldivmod.S1
l---------core/cortex-m0/lmul.S1
-rw-r--r--core/cortex-m0/mula.S81
-rw-r--r--core/cortex-m0/panic-internal.h13
-rw-r--r--core/cortex-m0/panic.c227
-rw-r--r--core/cortex-m0/switch.S116
-rw-r--r--core/cortex-m0/task.c691
-rw-r--r--core/cortex-m0/thumb_case.S96
l---------core/cortex-m0/uldivmod.S1
-rw-r--r--core/cortex-m0/vecttable.c136
-rw-r--r--core/cortex-m0/watchdog.c53
-rw-r--r--core/host/atomic.h40
-rw-r--r--core/host/build.mk11
-rw-r--r--core/host/cpu.h13
-rw-r--r--core/host/disabled.c10
-rw-r--r--core/host/host_exe.lds136
-rw-r--r--core/host/host_task.h37
-rw-r--r--core/host/irq_handler.h30
-rw-r--r--core/host/main.c108
-rw-r--r--core/host/panic.c22
-rw-r--r--core/host/stack_trace.c97
-rw-r--r--core/host/task.c564
-rw-r--r--core/host/timer.c105
-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.h78
-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.h70
-rw-r--r--core/nds32/ec.lds.S321
-rw-r--r--core/nds32/include/fpu.h14
-rw-r--r--core/nds32/init.S269
-rw-r--r--core/nds32/irq_chip.h61
-rw-r--r--core/nds32/irq_handler.h26
-rw-r--r--core/nds32/math.c116
-rw-r--r--core/nds32/panic.c209
-rw-r--r--core/nds32/switch.S109
-rw-r--r--core/nds32/task.c794
-rw-r--r--core/riscv-rv32i/__builtin.c16
-rw-r--r--core/riscv-rv32i/atomic.h53
-rw-r--r--core/riscv-rv32i/build.mk29
-rw-r--r--core/riscv-rv32i/config_core.h21
-rw-r--r--core/riscv-rv32i/cpu.c14
-rw-r--r--core/riscv-rv32i/cpu.h55
-rw-r--r--core/riscv-rv32i/ec.lds.S458
-rw-r--r--core/riscv-rv32i/include/fpu.h13
-rw-r--r--core/riscv-rv32i/init.S454
-rw-r--r--core/riscv-rv32i/irq_chip.h61
-rw-r--r--core/riscv-rv32i/irq_handler.h31
-rw-r--r--core/riscv-rv32i/math.c19
-rw-r--r--core/riscv-rv32i/panic.c169
-rw-r--r--core/riscv-rv32i/switch.S171
-rw-r--r--core/riscv-rv32i/task.c725
97 files changed, 0 insertions, 12564 deletions
diff --git a/core/cortex-m/aes.S b/core/cortex-m/aes.S
deleted file mode 120000
index 39d1286943..0000000000
--- a/core/cortex-m/aes.S
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/boringssl/core/cortex-m/aes.S \ No newline at end of file
diff --git a/core/cortex-m/atomic.h b/core/cortex-m/atomic.h
deleted file mode 100644
index e9b96f6fd5..0000000000
--- a/core/cortex-m/atomic.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright 2012 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 ARMv7 */
-
-#ifndef __CROS_EC_ATOMIC_H
-#define __CROS_EC_ATOMIC_H
-
-#include "common.h"
-
-typedef int atomic_t;
-typedef atomic_t atomic_val_t;
-
-static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits)
-{
- return __atomic_fetch_and(addr, ~bits, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_or(atomic_t *addr, atomic_val_t bits)
-{
- return __atomic_fetch_or(addr, bits, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_add(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_add(addr, value, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_sub(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_sub(addr, value, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_clear(atomic_t *addr)
-{
- return __atomic_exchange_n(addr, 0, __ATOMIC_SEQ_CST);
-}
-
-#endif /* __CROS_EC_ATOMIC_H */
diff --git a/core/cortex-m/build.mk b/core/cortex-m/build.mk
deleted file mode 100644
index ad7ab6eacc..0000000000
--- a/core/cortex-m/build.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- makefile -*-
-# Copyright 2012 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.
-#
-# Cortex-M4 core OS files build
-#
-
-# Use coreboot-sdk
-$(call set-option,CROSS_COMPILE,\
- $(CROSS_COMPILE_arm),\
- /opt/coreboot-sdk/bin/arm-eabi-)
-
-# FPU compilation flags
-CFLAGS_FPU-$(CONFIG_FPU)=-mfpu=fpv4-sp-d16 -mfloat-abi=hard
-
-# CPU specific compilation flags
-CFLAGS_CPU+=-mthumb -Os -mno-sched-prolog
-CFLAGS_CPU+=-mno-unaligned-access
-CFLAGS_CPU+=$(CFLAGS_FPU-y)
-
-ifneq ($(CONFIG_LTO),)
-CFLAGS_CPU+=-flto
-LDFLAGS_EXTRA+=-flto
-endif
-
-core-y=cpu.o debug.o init.o ldivmod.o llsr.o uldivmod.o vecttable.o
-core-$(CONFIG_AES)+=aes.o
-core-$(CONFIG_AES_GCM)+=ghash.o
-core-$(CONFIG_ARMV7M_CACHE)+=cache.o
-core-$(CONFIG_COMMON_PANIC_OUTPUT)+=panic.o
-core-$(CONFIG_COMMON_RUNTIME)+=switch.o task.o
-core-$(CONFIG_WATCHDOG)+=watchdog.o
-core-$(CONFIG_MPU)+=mpu.o
diff --git a/core/cortex-m/cache.S b/core/cortex-m/cache.S
deleted file mode 100644
index 0a3d3bb67d..0000000000
--- a/core/cortex-m/cache.S
+++ /dev/null
@@ -1,76 +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.
- *
- * ARMv7-M architectural caches maintenance operations.
- */
-
-.syntax unified
-.text
-.thumb
-
-/* System Control Block: cache registers */
-#define SCB_CCSIDR 0xe000ed80
-#define SCB_CCSELR 0xe000ed84
-#define SCB_DCISW 0xe000ef60
-#define SCB_DCCISW 0xe000ef74
-
-.macro dcache_set_way_op name register
-@
-@ Perform an operation on all D-cache sets/ways.
-@
-@ Note: implemented in assembly to guarantee that we are not touching the
-@ D-cache in the middle of the loop.
-@
-.thumb_func
-.section .text.\name
-.global \name
-\name:
- /* Select Level-1 Data cache (for operations on CCSIDR). */
- ldr r1, =SCB_CCSELR
- movs r0, #0
- ldr r2, =SCB_CCSIDR
- str r0, [r1] /* set CCSELR = 0 */
-
- /* Ensure the CCSELR write is effective before reading CCSIDR. */
- dsb
- /* CCSIDR contains the cache geometry. */
- ldr r3, [r2] /* [27:13] Number of sets -1 [12:3] Number of ways -1 */
-
- /* register used to do the set/way cache operation. */
- ldr r0, =\register
- /* r2 is the number of cache 'sets' - 1 */
- ubfx r2, r3, #13, #15
- /* r12 is the number of cache 'ways' - 1 */
- ubfx r12, r3, #3, #10
-
-1:
- mov r1, r12 /* reset way index */
-2:
- /*
- * Build address Set/Way operation e.g DC(C)ISW
- * [31:30] way index [13:5] set index
- */
- lsls r3, r2, #5 /* set index */
- /* TODO(crbug.com/848704) remove cache geometry assumptions */
- orr r3, r3, r1, lsl #30 /* way index */
- /* Perform operation (e.g invalidate) on a D-cache line */
- str r3, [r0]
- /* go to previous way */
- subs r1, #1
- bcs 2b
- /* go to previous set */
- subs r2, #1
- bcs 1b
-
- /* Ensure everything has propagated and return. */
- dsb
- isb
- bx lr
-.endm
-
-/* D-cache Invalidate by set-way */
-dcache_set_way_op cpu_invalidate_dcache SCB_DCISW
-
-/* D-cache Clean and Invalidate by set-way, to Point of Coherency */
-dcache_set_way_op cpu_clean_invalidate_dcache SCB_DCCISW
diff --git a/core/cortex-m/config_core.h b/core/cortex-m/config_core.h
deleted file mode 100644
index 0665b28852..0000000000
--- a/core/cortex-m/config_core.h
+++ /dev/null
@@ -1,15 +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 arm
-#define BFD_FORMAT "elf32-littlearm"
-
-#define CONFIG_SOFTWARE_PANIC
-
-#endif /* __CROS_EC_CONFIG_CORE_H */
diff --git a/core/cortex-m/cpu.c b/core/cortex-m/cpu.c
deleted file mode 100644
index 7c31892c18..0000000000
--- a/core/cortex-m/cpu.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright 2012 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 Cortex-M core
- */
-
-#include "common.h"
-#include "cpu.h"
-#include "hooks.h"
-
-void cpu_init(void)
-{
- /* Catch divide by 0 and unaligned access */
- CPU_NVIC_CCR |= CPU_NVIC_CCR_DIV_0_TRAP | CPU_NVIC_CCR_UNALIGN_TRAP;
-
- /* Enable reporting of memory faults, bus faults and usage faults */
- CPU_NVIC_SHCSR |= CPU_NVIC_SHCSR_MEMFAULTENA |
- CPU_NVIC_SHCSR_BUSFAULTENA | CPU_NVIC_SHCSR_USGFAULTENA;
-}
-
-#ifdef CONFIG_ARMV7M_CACHE
-static void cpu_invalidate_icache(void)
-{
- /*
- * Invalidates the entire instruction cache to the point of
- * unification.
- */
- CPU_SCB_ICIALLU = 0;
- asm volatile("dsb; isb");
-}
-
-void cpu_enable_caches(void)
-{
- /* Check whether the I-cache is already enabled */
- if (!(CPU_NVIC_CCR & CPU_NVIC_CCR_ICACHE)) {
- /* Invalidate the I-cache first */
- cpu_invalidate_icache();
- /* Turn on the caching */
- CPU_NVIC_CCR |= CPU_NVIC_CCR_ICACHE;
- asm volatile("dsb; isb");
- }
- /* Check whether the D-cache is already enabled */
- if (!(CPU_NVIC_CCR & CPU_NVIC_CCR_DCACHE)) {
- /* Invalidate the D-cache first */
- cpu_invalidate_dcache();
- /* Turn on the caching */
- CPU_NVIC_CCR |= CPU_NVIC_CCR_DCACHE;
- asm volatile("dsb; isb");
- }
-}
-
-void cpu_disable_caches(void)
-{
- /*
- * Disable the I-cache and the D-cache
- * The I-cache will be invalidated after the reboot/sysjump if needed
- * (e.g after a flash update).
- */
- cpu_clean_invalidate_dcache();
- CPU_NVIC_CCR &= ~(CPU_NVIC_CCR_ICACHE | CPU_NVIC_CCR_DCACHE);
- asm volatile("dsb; isb");
-}
-DECLARE_HOOK(HOOK_SYSJUMP, cpu_disable_caches, HOOK_PRIO_LAST);
-#endif /* CONFIG_ARMV7M_CACHE */
diff --git a/core/cortex-m/cpu.h b/core/cortex-m/cpu.h
deleted file mode 100644
index 0b03302bfc..0000000000
--- a/core/cortex-m/cpu.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright 2012 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 Cortex-MLM4x processor
- */
-
-#ifndef __CROS_EC_CPU_H
-#define __CROS_EC_CPU_H
-
-#include <stdint.h>
-#include "compile_time_macros.h"
-
-/* Macro to access 32-bit registers */
-#define CPUREG(addr) (*(volatile uint32_t*)(addr))
-
-#define CPU_NVIC_ST_CTRL CPUREG(0xE000E010)
-#define ST_ENABLE BIT(0)
-#define ST_TICKINT BIT(1)
-#define ST_CLKSOURCE BIT(2)
-#define ST_COUNTFLAG BIT(16)
-
-/* Nested Vectored Interrupt Controller */
-#define CPU_NVIC_EN(x) CPUREG(0xe000e100 + 4 * (x))
-#define CPU_NVIC_DIS(x) CPUREG(0xe000e180 + 4 * (x))
-#define CPU_NVIC_UNPEND(x) CPUREG(0xe000e280 + 4 * (x))
-#define CPU_NVIC_PRI(x) CPUREG(0xe000e400 + 4 * (x))
-/* SCB AIRCR : Application interrupt and reset control register */
-#define CPU_NVIC_APINT CPUREG(0xe000ed0c)
-#define CPU_NVIC_APINT_SYSRST BIT(2) /* System reset request */
-#define CPU_NVIC_APINT_PRIOGRP (BIT(8)|BIT(9)|BIT(10))
-#define CPU_NVIC_APINT_ENDIAN BIT(15) /* Endianness */
-#define CPU_NVIC_APINT_KEY_RD (0xFA05U << 16)
-#define CPU_NVIC_APINT_KEY_WR (0x05FAU << 16)
-/* NVIC STIR : Software Trigger Interrupt Register */
-#define CPU_NVIC_SWTRIG CPUREG(0xe000ef00)
-/* SCB SCR : System Control Register */
-#define CPU_SCB_SYSCTRL CPUREG(0xe000ed10)
-
-#define CPU_NVIC_CCR CPUREG(0xe000ed14)
-#define CPU_NVIC_SHCSR CPUREG(0xe000ed24)
-#define CPU_NVIC_CFSR CPUREG(0xe000ed28)
-#define CPU_NVIC_HFSR CPUREG(0xe000ed2c)
-#define CPU_NVIC_DFSR CPUREG(0xe000ed30)
-#define CPU_NVIC_MFAR CPUREG(0xe000ed34)
-#define CPU_NVIC_BFAR CPUREG(0xe000ed38)
-
-enum {
- CPU_NVIC_CFSR_BFARVALID = BIT(15),
- CPU_NVIC_CFSR_MFARVALID = BIT(7),
-
- CPU_NVIC_CCR_ICACHE = BIT(17),
- CPU_NVIC_CCR_DCACHE = BIT(16),
- CPU_NVIC_CCR_DIV_0_TRAP = BIT(4),
- CPU_NVIC_CCR_UNALIGN_TRAP = BIT(3),
-
- CPU_NVIC_HFSR_DEBUGEVT = 1UL << 31,
- CPU_NVIC_HFSR_FORCED = BIT(30),
- CPU_NVIC_HFSR_VECTTBL = BIT(1),
-
- CPU_NVIC_SHCSR_MEMFAULTENA = BIT(16),
- CPU_NVIC_SHCSR_BUSFAULTENA = BIT(17),
- CPU_NVIC_SHCSR_USGFAULTENA = BIT(18),
-};
-
-/* System Control Block: cache registers */
-#define CPU_SCB_CCSIDR CPUREG(0xe000ed80)
-#define CPU_SCB_CCSELR CPUREG(0xe000ed84)
-#define CPU_SCB_ICIALLU CPUREG(0xe000ef50)
-#define CPU_SCB_DCISW CPUREG(0xe000ef60)
-#define CPU_SCB_DCCISW CPUREG(0xe000ef74)
-
-/* Set up the cpu to detect faults */
-void cpu_init(void);
-/* Enable the CPU I-cache and D-cache if they are not already enabled */
-void cpu_enable_caches(void);
-/* Disable the CPU I-cache and D-cache */
-void cpu_disable_caches(void);
-/* Invalidate the D-cache */
-void cpu_invalidate_dcache(void);
-/* Clean and Invalidate the D-cache to the Point of Coherency */
-void cpu_clean_invalidate_dcache(void);
-
-/* Invalidate a single range of the D-cache */
-void cpu_invalidate_dcache_range(uintptr_t base, unsigned int length);
-/* Clean and Invalidate a single range of the D-cache */
-void cpu_clean_invalidate_dcache_range(uintptr_t base, unsigned int length);
-
-/* Set the priority of the given IRQ in the NVIC (0 is highest). */
-static inline void cpu_set_interrupt_priority(uint8_t irq, uint8_t priority)
-{
- const uint32_t prio_shift = irq % 4 * 8 + 5;
-
- if (priority > 7)
- priority = 7;
-
- CPU_NVIC_PRI(irq / 4) =
- (CPU_NVIC_PRI(irq / 4) &
- ~(7 << prio_shift)) |
- (priority << prio_shift);
-}
-
-#endif /* __CROS_EC_CPU_H */
diff --git a/core/cortex-m/debug.c b/core/cortex-m/debug.c
deleted file mode 100644
index db8891b5d8..0000000000
--- a/core/cortex-m/debug.c
+++ /dev/null
@@ -1,12 +0,0 @@
-/* Copyright 2021 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 "debug.h"
-#include "stdbool.h"
-
-bool debugger_is_connected(void)
-{
- return CPU_DHCSR & DHCSR_C_DEBUGEN;
-}
diff --git a/core/cortex-m/debug.h b/core/cortex-m/debug.h
deleted file mode 100644
index ae5ef08d06..0000000000
--- a/core/cortex-m/debug.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2021 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_DEBUG_H
-#define __CROS_EC_DEBUG_H
-
-#include "common.h"
-#include "stdbool.h"
-
-/* For Cortex-M0, see "C1.6.3 Debug Halting Control and Status Register, DHCSR"
- * in the ARMv6-M Architecture Reference Manual.
- *
- * For other Cortex-M, see
- * "C1.6.2 Debug Halting Control and Status Register, DHCSR" in the ARMv7-M
- * Architecture Reference Manual or
- * https://developer.arm.com/documentation/ddi0337/e/core-debug/core-debug-registers/debug-halting-control-and-status-register.
- */
-#define CPU_DHCSR REG32(0xE000EDF0)
-#define DHCSR_C_DEBUGEN BIT(0)
-#define DHCSR_C_HALT BIT(1)
-#define DHCSR_C_STEP BIT(2)
-#define DHCSR_C_MASKINTS BIT(3)
-#ifndef CHIP_CORE_CORTEX_M0
-#define DHCSR_C_SNAPSTALL BIT(5) /* Not available on Cortex-M0 */
-#endif
-#define DHCSR_S_REGRDY BIT(16)
-#define DHCSR_S_HALT BIT(17)
-#define DHCSR_S_SLEEP BIT(18)
-#define DHCSR_S_LOCKUP BIT(19)
-#define DHCSR_S_RETIRE_ST BIT(24)
-#define DHCSR_S_RESET_ST BIT(25)
-
-bool debugger_is_connected(void);
-
-#endif /* __CROS_EC_DEBUG_H */
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S
deleted file mode 100644
index 7b08be81a6..0000000000
--- a/core/cortex-m/ec.lds.S
+++ /dev/null
@@ -1,721 +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"
-#include "rwsig.h"
-
-#define CONCAT_STAGE_1(w, x, y, z) w ## x ## y ## z
-#define CONCAT2(w, x) CONCAT_STAGE_1(w, x, , )
-#define CONCAT3(w, x, y) CONCAT_STAGE_1(w, x, y, )
-#define CONCAT4(w, x, y, z) CONCAT_STAGE_1(w, x, y, z)
-
-#define STRINGIFY0(name) #name
-#define STRINGIFY(name) STRINGIFY0(name)
-
-#ifdef RW_B_LDS
-#define FW_MEM_OFF_(section) CONFIG_##section##_B_MEM_OFF
-#else
-#define FW_MEM_OFF_(section) CONFIG_##section##_MEM_OFF
-#endif
-#define FW_MEM_OFF(section) (FW_MEM_OFF_(section))
-#define FW_OFF(section) (CONFIG_PROGRAM_MEMORY_BASE + FW_MEM_OFF(section))
-
-#define FW_SIZE_(section) CONFIG_##section##_SIZE
-#define FW_SIZE(section) FW_SIZE_(section)
-
-/*
- * Define the VMA (virtual memory address) of the ROM_RESIDENT region within
- * the EC image. This is full 32-bit address starting from
- * CONFIG_PROGRAM_MEMORY_BASE.
- */
-#define ROM_RES_OFF(section) FW_OFF(CONCAT2(section, _ROM_RESIDENT))
-#define ROM_RES_SIZE(section) FW_SIZE(CONCAT2(section, _ROM_RESIDENT))
-
-/*
- * Define the VMA (virtual memory address) of the ROM_RESIDENT region. Instead
- * of a full 32-bit address, set the VMA to be an offset within the flash memory
- * section. Objects linked into this section can pass the address of the
- * object unmodified to the public APIs of the flash and init_rom modules.
- */
-#ifdef SECTION_IS_RO
-#define ROM_RES_FLASH_OFF(section) \
- FW_MEM_OFF(CONCAT2(section, _ROM_RESIDENT)) + \
- CONFIG_EC_PROTECTED_STORAGE_OFF
-#else
-#define ROM_RES_FLASH_OFF(section) \
- FW_MEM_OFF(CONCAT2(section, _ROM_RESIDENT)) + \
- CONFIG_EC_WRITABLE_STORAGE_OFF
-#endif
-
-/* Indicates where .data LMA should reside. */
-#undef DATA_LMA_MEM_REGION
-
-OUTPUT_FORMAT(BFD_FORMAT, BFD_FORMAT, BFD_FORMAT)
-OUTPUT_ARCH(BFD_ARCH)
-ENTRY(reset)
-
-MEMORY
-{
-#if !defined(CONFIG_FLASH_PHYSICAL)
- IROM (rx) : ORIGIN = CONFIG_ROM_BASE, LENGTH = CONFIG_ROM_SIZE
-#else
-#if defined(SECTION_IS_RO) && defined(NPCX_RO_HEADER)
- /*
- * Header structure used by npcx booter in RO region.
- * Please notice the location of header must be in front of FW
- * which needs copy. But header itself won't be copied to code ram
- * by booter.
- */
- FLASH_HDR (rx) : ORIGIN = FW_OFF(RO_HDR), LENGTH = FW_SIZE(RO_HDR)
- FLASH (rx) : ORIGIN = FW_OFF(SECTION) + FW_SIZE(RO_HDR), \
- LENGTH = FW_SIZE(SECTION) - FW_SIZE(RO_HDR)
-#else
- FLASH (rx) : ORIGIN = FW_OFF(SECTION), LENGTH = FW_SIZE(SECTION)
-#endif
-#ifdef CONFIG_CHIP_INIT_ROM_REGION
- ROM_RESIDENT (r) : \
- ORIGIN = ROM_RES_OFF(SECTION), \
- LENGTH = ROM_RES_SIZE(SECTION)
-
- ROM_RESIDENT_VMA (r) : \
- ORIGIN = ROM_RES_FLASH_OFF(SECTION), \
- LENGTH = ROM_RES_SIZE(SECTION)
-#endif /* CONFIG_CHIP_INIT_ROM_REGION */
-#ifdef CONFIG_SHAREDLIB
- SHARED_LIB (rx) : ORIGIN = FW_OFF(SHAREDLIB), \
- LENGTH = FW_SIZE(SHAREDLIB)
-#endif
-#endif /* !CONFIG_FLASH_PHYSICAL */
- IRAM (rw) : ORIGIN = CONFIG_RAM_BASE, LENGTH = CONFIG_RAM_SIZE
-
-#ifdef CONFIG_EXTERNAL_STORAGE
- CDRAM (rx) : \
- ORIGIN = CONFIG_PROGRAM_MEMORY_BASE + FW_MEM_OFF(SECTION), \
- LENGTH = FW_SIZE(SECTION)
-#endif /* CONFIG_EXTERNAL_STORAGE */
-
-#ifdef CONFIG_CHIP_MEMORY_REGIONS
-#define REGION(name, attr, start, size) \
- name(attr) : ORIGIN = (start), LENGTH = (size)
-#define REGION_LOAD REGION
-#include "memory_regions.inc"
-#undef REGION
-#undef REGION_LOAD
-#endif /* CONFIG_MEMORY_REGIONS */
-
-#ifdef CONFIG_DRAM_BASE
- DRAM (rwx) : ORIGIN = CONFIG_DRAM_BASE, LENGTH = CONFIG_DRAM_SIZE
-#endif
-}
-
-/*
- * Convenience macros for determining the correct output memory section.
- */
-#if !defined(CONFIG_FLASH_PHYSICAL)
- #define EC_IMAGE_LMA_MEM_REGION IROM
- #define EC_IMAGE_VMA_MEM_REGION IROM
- #define DATA_LMA_MEM_REGION IROM
-#else
- #define EC_IMAGE_LMA_MEM_REGION FLASH
- #ifdef CONFIG_EXTERNAL_STORAGE
- #define EC_IMAGE_VMA_MEM_REGION CDRAM
- #else
- #define EC_IMAGE_VMA_MEM_REGION FLASH
- #endif
-
- #ifdef CONFIG_CHIP_DATA_IN_INIT_ROM
- #define DATA_LMA_MEM_REGION ROM_RESIDENT
- #else
- #define DATA_LMA_MEM_REGION FLASH
- #endif
-#endif
-
-SECTIONS
-{
-#if defined(SECTION_IS_RO) && defined(NPCX_RO_HEADER)
- .header : {
- KEEP(*(.header))
- } > FLASH_HDR
-#endif
-#ifdef CONFIG_SHAREDLIB
- .roshared : {
- KEEP(*(.roshared*))
- } > SHARED_LIB
-#endif
- .text : {
-#ifdef SECTION_IS_RO
- . = . + CONFIG_RO_HEAD_ROOM;
-#endif
-#ifdef SECTION_IS_RW
- . = . + CONFIG_RW_HEAD_ROOM;
-#endif
- *(.text.vecttable)
- . = ALIGN(4);
- __image_data_offset = .;
- KEEP(*(.rodata.ver))
-
- . = ALIGN(4);
- KEEP(*(.rodata.pstate))
-
- . = ALIGN(4);
- STRINGIFY(OUTDIR/core/CORE/init.o) (.text)
-#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 && !defined(CONFIG_HIBERNATE_PSL)
- /* Keep hibernate utility in last code ram block */
- . = ALIGN(4);
- KEEP(*(.after_init))
- __after_init_end = .;
-#endif
- *(.text*)
-#ifdef CONFIG_EXTERNAL_STORAGE
- . = ALIGN(4);
- __flash_lpfw_start = .;
- /* Entering deep idle FW for better power consumption */
- KEEP(*(.lowpower_ram))
- . = ALIGN(4);
- __flash_lpfw_end = .;
- __flash_lplfw_start = .;
- /* GDMA utilities for better FW download speed */
- KEEP(*(.lowpower_ram2))
- . = ALIGN(4);
- __flash_lplfw_end = .;
-#endif /* CONFIG_EXTERNAL_STORAGE */
- } > EC_IMAGE_VMA_MEM_REGION AT > EC_IMAGE_LMA_MEM_REGION
-
- . = ALIGN(4);
- .rodata : {
- /* Symbols defined here are declared in link_defs.h */
- __irqprio = .;
- KEEP(*(.rodata.irqprio))
- __irqprio_end = .;
-
- . = ALIGN(4);
- __cmds = .;
- KEEP(*(SORT(.rodata.cmds*)))
- __cmds_end = .;
-
- . = ALIGN(4);
- __extension_cmds = .;
- KEEP(*(.rodata.extensioncmds))
- __extension_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 = .;
-
-#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK
- __hooks_chipset_resume_init = .;
- KEEP(*(.rodata.HOOK_CHIPSET_RESUME_INIT))
- __hooks_chipset_resume_init_end = .;
-
- __hooks_chipset_suspend_complete = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SUSPEND_COMPLETE))
- __hooks_chipset_suspend_complete_end = .;
-#endif
-
- __hooks_chipset_shutdown = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN))
- __hooks_chipset_shutdown_end = .;
-
- __hooks_chipset_shutdown_complete = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN_COMPLETE))
- __hooks_chipset_shutdown_complete_end = .;
-
- __hooks_chipset_hard_off = .;
- KEEP(*(.rodata.HOOK_CHIPSET_HARD_OFF))
- __hooks_chipset_hard_off_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 = .;
-
- __usb_desc = .;
- KEEP(*(.rodata.usb_desc_conf))
- KEEP(*(SORT(.rodata.usb_desc*)))
- __usb_desc_end = .;
- . = ALIGN(4);
- KEEP(*(.rodata.usb_ep))
- KEEP(*(.rodata.usb_ep.usb_ep_tx))
- KEEP(*(.rodata.usb_ep.usb_ep_rx))
- KEEP(*(.rodata.usb_ep.usb_ep_reset))
- KEEP(*(.rodata.usb_ep.usb_iface_request))
-
- . = ALIGN(4);
- *(.rodata*)
-
-#ifndef CONFIG_CHIP_INIT_ROM_REGION
- /*
- * When a separate ROM resident section isn't enabled, ensure
- * the corresponding data objects are linked into the .rodata
- * section.
- */
- . = ALIGN(4);
- __init_rom_start = .;
- *(.init.rom)
- __init_rom_end = .;
-#endif /* CONFIG_CHIP_INIT_ROM_REGION */
-
-#if defined(SECTION_IS_RO) && defined(CONFIG_FLASH_CROS)
- . = ALIGN(64);
- KEEP(*(.google))
-#endif
-
- . = ALIGN(4);
- } > EC_IMAGE_VMA_MEM_REGION AT > EC_IMAGE_LMA_MEM_REGION
-
-#ifdef CONFIG_CHIP_DATA_IN_INIT_ROM
- __data_lma_start = ORIGIN(ROM_RESIDENT_VMA);
- #define INIT_ROM_LMA (ORIGIN(ROM_RESIDENT_VMA) + SIZEOF(.data))
-#else
- __data_lma_start = .;
- #define INIT_ROM_LMA ORIGIN(ROM_RESIDENT_VMA)
-#endif
-
-#ifdef CONFIG_PRESERVE_LOGS
- .preserve_logs(NOLOAD) : {
- . = ALIGN(8);
- *(SORT(.preserved_logs.*))
- . = ALIGN(8);
- __preserved_logs_end = .;
- } > IRAM
-
- ASSERT((SIZEOF(.preserve_logs) + CONFIG_RAM_BASE) ==
- __preserved_logs_end,
- "preserve_logs must be at CONFIG_RAM_BASE.")
-#endif
-
- .bss : {
- /*
- * Align to 512 bytes. This is convenient when some memory block
- * needs big alignment. This is the beginning of the RAM,
- * so there is usually no penalty on aligning this.
- */
- . = ALIGN(512);
- __bss_start = .;
- *(.bss.big_align)
- /* Stacks must be 64-bit aligned */
- . = ALIGN(8);
- *(.bss.system_stack)
- /* Rest of .bss takes care of its own alignment */
-
- /* Group libtpm2 data so it can be cleared on system reset */
- __bss_libtpm2_start = .;
- /* TPM registers should be cleared at the same time */
- STRINGIFY(OUTDIR/common/tpm_registers.o*)(.bss)
- *(.bss.Tpm2_common)
- __bss_libtpm2_end = .;
-
- *(.bss)
-
- /*
- * 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. The 8 byte alignment of
- * uint64_t is required by the ARM ABI.
- */
- . = ALIGN(8);
- __deferred_until = .;
- . += (__deferred_funcs_end - __deferred_funcs) * (8 / 4);
- __deferred_until_end = .;
- } > IRAM
-
- .bss.slow : {
- /* Region of RAM reclaimed from the little firmware(LFW). */
- *(.bss.slow)
- /*
- * Not replacing the loader, so .bss.slow is part of .bss.
- * It needs to be followed by __bss_end so that .bss.slow
- * will be zeroed by init.
- */
- . = ALIGN(4);
- __bss_end = .;
- } > IRAM
-
- .data : {
- . = ALIGN(4);
- __data_start = .;
- *(.data.tasks)
-
- /*
- * Group libtpm2 data so it can be reinitialized on
- * system reset
- */
- __data_libtpm2_start = .;
- Tpm2_*(.data)
- /* TPM registers should be reinitialized at the same time */
- STRINGIFY(OUTDIR/common/tpm_registers.o*)(.data)
- __data_libtpm2_end = .;
-
- /*
- * TPM reset currently only clears BSS for the TPM library.
- * It does not reset any initialized variables in data.
- * So, make sure there aren't any.
- */
- ASSERT(__data_libtpm2_start == __data_libtpm2_end,
- "libtpm2 .data section is nonzero");
-
- *(.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 = .;
-
- /*
- * Shared memory buffer must be at the end of preallocated
- * RAM, so it can expand to use all the remaining RAM.
- */
- __shared_mem_buf = .;
-
- /* NOTHING MAY GO AFTER THIS! */
- } > IRAM AT > DATA_LMA_MEM_REGION
-
- 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);
-
-#ifdef CONFIG_CHIP_DATA_IN_INIT_ROM
- /*
- * .data is ROM resident, last section in the EC image is the .rodata
- * section.
- */
- #define FLASH_USED_END (LOADADDR(.rodata) + SIZEOF(.rodata))
-#else
- /*
- * .data is included in the EC image and copied to RAM by the loader.
- */
- #define FLASH_USED_END (LOADADDR(.data) + SIZEOF(.data))
-#endif
-
- /*
- * __flash_used is used in flash free calculations by the makefile.
- * __image_size is stored in the struct image_data header and used
- * in hash calcuations.
- */
- __flash_used = FLASH_USED_END - ORIGIN(EC_IMAGE_LMA_MEM_REGION);
-#ifndef CONFIG_CHIP_INIT_ROM_REGION
-#if !(defined(SECTION_IS_RW) && (CONFIG_FLASH_WRITE_SIZE > 4))
- __image_size = __flash_used;
-#else
- .rw_image_size_alignment :
- {
- . = ORIGIN(FLASH) + __flash_used;
- BYTE(0xFF);
- . = ALIGN (CONFIG_FLASH_WRITE_SIZE);
- } > FLASH = 0xFF
-
- __image_size = __flash_used + SIZEOF(.rw_image_size_alignment);
-#endif
-#endif /* CONFIG_CHIP_INIT_ROM_REGION */
-
-#ifdef CONFIG_FLASH_CROS
- /*
- * These linker labels are just for analysis and not used in the code.
- */
- __config_flash_size = CONFIG_FLASH_SIZE_BYTES;
- __config_ro_size = CONFIG_RO_SIZE;
- __config_ec_protected_storage_size = CONFIG_EC_PROTECTED_STORAGE_SIZE;
- __config_rw_size = CONFIG_RW_SIZE;
- __config_ec_writable_storage_size = CONFIG_EC_WRITABLE_STORAGE_SIZE;
-#endif
-
- /*
- * The linker won't notice if the .data section is too big to fit,
- * apparently because we're sending it into IRAM, not FLASH.
- * Verify that all sections linked into the FLASH region will fit.
- */
- ASSERT((LENGTH(EC_IMAGE_LMA_MEM_REGION)
-#if defined(CONFIG_RWSIG) && defined(SECTION_IS_RO)
- - CONFIG_RO_PUBKEY_SIZE
-#endif
-#if defined(CONFIG_RWSIG) && defined(SECTION_IS_RW)
- - CONFIG_RW_SIG_SIZE
-#endif
- ) >= __flash_used,
- "No room left in the flash")
-
-#ifdef CONFIG_CHIP_INIT_ROM_REGION
- /*
- * Image layout when ROM_RESIDENT region is used (lower addresses
- * at the top). This layout is setup by the LMA assignment.
- *
- * EC image layout (LMA) VMA
- * .header (if RO image) none
- * .text code RAM
- * .rodata code RAM + .text size
- * .data data RAM
- * .fill none
- * .init_rom flash offset
- *
- * The loader code copies the .text, .rodata, and .data sections into
- * the code RAM of the EC. The .header and .init_rom sections are not
- * copied by the loader.
- *
- * Image layout when ROM_RESIDENT region is used, and
- * CONFIG_CHIP_DATA_IN_INIT_ROM is enabled.
- *
- * EC image layout (LMA) VMA
- * .header (if RO image) none
- * .text code RAM
- * .rodata code RAM + .text size
- * .fill none
- * .data data RAM
- * .init_rom flash offset
- *
- * The loader code copies the .text and .rodata sections into the code
- * RAM of the EC. The .header, .data, and .init_rom sections are not
- * copied by the loader.
- *
- * EC initialization code copies the .data directly from flash to
- * data RAM at runtime.
- */
-
- /*
- * The layout assumes the ROM_RESIDENT region follows the FLASH
- * region.
- */
- ASSERT((ORIGIN(FLASH) + LENGTH(FLASH)) == ORIGIN(ROM_RESIDENT),
- ".init_rom section must follow the flash section")
-
- .init_rom INIT_ROM_LMA : {
- . = ALIGN(4);
- __init_rom_start = .;
- *(.init.rom)
- __init_rom_end = .;
- } > ROM_RESIDENT_VMA AT > ROM_RESIDENT
-
- /*
- * The ROM_RESIDENT section is assumed to be in the same physical
- * flash as the FLASH section. Fill the space between.
- */
- .fill : {
- . = FLASH_USED_END;
- . = ALIGN(4);
- __fill_start = .;
- FILL(0xFF);
- . = ORIGIN(FLASH) + LENGTH(FLASH) - 1;
- /* Need at least one byte so section is not omitted */
- BYTE(0xFF);
- __fill_end = .;
- } > FLASH
-
- /*
- * The end of the .fill region should also be the start of the ROM
- * resident region.
- */
- ASSERT(__fill_end == ORIGIN(ROM_RESIDENT),
- ".fill region end not aligned to start of ROM_RESIDENT region")
-
- /*
- * __image_size is used for hash calculation. When
- * CONFIG_CHIP_INIT_ROM_REGION is enabled, this includes the entire
- * FLASH region and the bytes used in the .init_rom section.
- */
-#ifdef CONFIG_CHIP_DATA_IN_INIT_ROM
- __image_size = LENGTH(FLASH) + SIZEOF(.init_rom) + SIZEOF(.data);
-#else
- __image_size = LENGTH(FLASH) + SIZEOF(.init_rom);
-#endif /* CONFIG_CHIP_DATA_IN_INIT_ROM */
-#endif /* CONFIG_CHIP_INIT_ROM_REGION */
-
-#ifdef CONFIG_CHIP_MEMORY_REGIONS
-#define REGION(name, attr, start, size) \
- .name(NOLOAD) : { \
- __##name##_start = .; \
- KEEP(*(SORT(.name.keep.*))) \
- *(SORT(.name.*)) \
- } > name
-#define REGION_LOAD(name, attr, start, size) \
- .name : { \
- __##name##_start = .; \
- KEEP(*(SORT(.name.keep.*))) \
- *(SORT(.name.*)) \
- } > name
-#include "memory_regions.inc"
-#undef REGION
-#undef REGION_LOAD
-#endif /* CONFIG_CHIP_MEMORY_REGIONS */
-
-#ifdef CONFIG_DRAM_BASE
-
- /*
- * Sections in DRAM region are constructed as like in non-DRAM regions:
- * .dram.data LMA is for preserving initialized data across resets.
- * The only difference is that they are all in the DRAM region:
- * .dram.text | LOAD
- * .dram.rodata | LOAD
- * .dram.data LMA | LOAD
- * .dram.data VMA |
- * .dram.bss | NOLOAD
- * TODO(b:123269246): Enable MPU protectable DRAM section. This might
- * introduce a RO-DRAM section for .dram.text, .dram.rodata and
- * .dram.data LMA.
- */
-
- .dram.text : {
- . = ALIGN(4);
- KEEP(*(SORT(.dram.text.keep.*)))
- *(SORT(.dram.text.*))
- . = ALIGN(4);
- } > DRAM
-
- .dram.rodata : {
- . = ALIGN(4);
- KEEP(*(SORT(.dram.rodata.keep.*)))
- *(SORT(.dram.rodata.*))
- . = ALIGN(4);
- } > DRAM
-
- __dram_data_lma_start = ADDR(.dram.rodata) + SIZEOF(.dram.rodata);
-
- /* Place .dram.data LMA in between .dram.rodata and .dram.data VMA. */
-#ifdef __clang__
- /*
- * The evaluation timing for SIZEOF() and symbols are different in
- * ld and lld.
- */
- .dram.data __dram_data_lma_start + SIZEOF(.dram.data) : {
-#else
- .dram.data __dram_data_lma_start +
- (__dram_data_end - __dram_data_start) : {
-#endif /* __clang__ */
- . = ALIGN(4);
- __dram_data_start = .;
- *(.dram.data*)
- . = ALIGN(4);
- __dram_data_end = .;
-
- /*
- * Normally, '> DRAM AT > DRAM' should be the same as '> DRAM',
- * and they will be at the same address. However, if the address
- * of VMA specified, LMA and VMA might have different addresses:
- * '> DRAM' places VMA at the address where section declaration
- * specified.
- * 'AT > DRAM' places LMA at the location counter's address.
- */
- } > DRAM AT > DRAM
-
- /*
- * ld assigns correct attribute for .bss, but not for other .*.bss,
- * we need an explicltly NOLOAD.
- */
- .dram.bss(NOLOAD) : {
- . = ALIGN(4);
- __dram_bss_start = .;
- *(SORT(.dram.bss*))
- . = ALIGN(4);
- __dram_bss_end = .;
- } > DRAM
-#endif
-
-#if !(defined(SECTION_IS_RO) && defined(CONFIG_FLASH_CROS))
- /DISCARD/ : { *(.google) }
-#endif
- /DISCARD/ : { *(.ARM.*) }
-}
diff --git a/core/cortex-m/ghash.S b/core/cortex-m/ghash.S
deleted file mode 120000
index e9acbf4b25..0000000000
--- a/core/cortex-m/ghash.S
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/boringssl/core/cortex-m/ghash.S \ No newline at end of file
diff --git a/core/cortex-m/include/fpu.h b/core/cortex-m/include/fpu.h
deleted file mode 100644
index 0949d336e2..0000000000
--- a/core/cortex-m/include/fpu.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright 2012 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 ARMv7 */
-
-#ifndef __CROS_EC_FPU_H
-#define __CROS_EC_FPU_H
-
-#ifdef CONFIG_FPU
-static inline float sqrtf(float v)
-{
- float root;
- asm volatile(
- "fsqrts %0, %1"
- : "=w" (root)
- : "w" (v)
- );
- return root;
-}
-
-static inline float fabsf(float v)
-{
- float root;
- asm volatile(
- "fabss %0, %1"
- : "=w" (root)
- : "w" (v)
- );
- return root;
-}
-#endif /* CONFIG_FPU */
-
-#endif /* __CROS_EC_FPU_H */
diff --git a/core/cortex-m/include/mpu.h b/core/cortex-m/include/mpu.h
deleted file mode 100644
index 610728b501..0000000000
--- a/core/cortex-m/include/mpu.h
+++ /dev/null
@@ -1,144 +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.
- */
-
-/* MPU module for Cortex-M3 */
-
-#ifndef __CROS_EC_MPU_H
-#define __CROS_EC_MPU_H
-
-#include "common.h"
-#include "config.h" /* chips might override MPU attribute settings */
-
-/*
- * ARMv7-M SRAM region
- */
-#define CORTEX_M_SRAM_BASE 0x20000000
-
-/*
- * Region assignment. 7 as the highest, a higher index has a higher priority.
- * For example, using 7 for .iram.text allows us to mark entire RAM XN except
- * .iram.text, which is used for hibernation.
- * Region assignment is currently wasteful and can be changed if more
- * regions are needed in the future. For example, a second region may not
- * be necessary for all types, and REGION_CODE_RAM / REGION_STORAGE can be
- * made mutually exclusive.
- */
-enum mpu_region {
- REGION_DATA_RAM = 0, /* For internal data RAM */
- REGION_DATA_RAM2 = 1, /* Second region for unaligned size */
- REGION_CODE_RAM = 2, /* For internal code RAM */
- REGION_CODE_RAM2 = 3, /* Second region for unaligned size */
- REGION_STORAGE = 4, /* For mapped internal storage */
- REGION_STORAGE2 = 5, /* Second region for unaligned size */
- REGION_DATA_RAM_TEXT = 6, /* Exempt region of data RAM */
- REGION_CHIP_RESERVED = 7, /* Reserved for use in chip/ */
- /* only for chips with MPU supporting 16 regions */
- REGION_UNCACHED_RAM = 8, /* For uncached data RAM */
- REGION_UNCACHED_RAM2 = 9, /* Second region for unaligned size */
- REGION_ROLLBACK = 10, /* For rollback */
-};
-
-#define MPU_TYPE REG32(0xe000ed90)
-#define MPU_CTRL REG32(0xe000ed94)
-#define MPU_NUMBER REG32(0xe000ed98)
-#define MPU_BASE REG32(0xe000ed9c)
-#define MPU_SIZE REG16(0xe000eda0)
-#define MPU_ATTR REG16(0xe000eda2)
-
-/*
- * See ARM v7-M Architecture Reference Manual
- * Section B3.5.5 MPU Type Register, MPU_TYPE
- */
-#define MPU_TYPE_UNIFIED_MASK 0x00FF0001
-#define MPU_TYPE_REG_COUNT(t) (((t) >> 8) & 0xFF)
-
-#define MPU_CTRL_PRIVDEFEN BIT(2)
-#define MPU_CTRL_HFNMIENA BIT(1)
-#define MPU_CTRL_ENABLE BIT(0)
-
-/*
- * Minimum region size is 32 bytes, 5 bits of address space
- */
-#define MPU_SIZE_BITS_MIN 5
-
-/*
- * XN (execute never) bit. It's bit 12 if accessed by halfword.
- * 0: XN off
- * 1: XN on
- */
-#define MPU_ATTR_XN BIT(12)
-
-/* AP bit. See table 3-5 of Stellaris LM4F232H5QC datasheet for details */
-#define MPU_ATTR_NO_NO (0 << 8) /* previleged no access, unprev no access */
-#define MPU_ATTR_RW_NO (1 << 8) /* previleged ReadWrite, unprev no access */
-#define MPU_ATTR_RW_RO (2 << 8) /* previleged ReadWrite, unprev Read-only */
-#define MPU_ATTR_RW_RW (3 << 8) /* previleged ReadWrite, unprev ReadWrite */
-#define MPU_ATTR_RO_NO (5 << 8) /* previleged Read-only, unprev no access */
-
-/* Suggested value for TEX S/C/B bit. See table 3-6 of Stellaris LM4F232H5QC
- * datasheet and table 38 of STM32F10xxx Cortex-M3 programming manual. */
-#ifndef MPU_ATTR_INTERNAL_SRAM
-#define MPU_ATTR_INTERNAL_SRAM 6 /* for Internal SRAM */
-#endif
-#ifndef MPU_ATTR_FLASH_MEMORY
-#define MPU_ATTR_FLASH_MEMORY 2 /* for flash memory */
-#endif
-
-/* Represent RW with at most 2 MPU regions. */
-#define MAX_RW_REGIONS 2
-struct mpu_rw_regions {
- int num_regions;
- uint32_t addr[MAX_RW_REGIONS];
- uint32_t size[MAX_RW_REGIONS];
-};
-
-/**
- * Enable MPU
- */
-void mpu_enable(void);
-
-/**
- * Returns the value of MPU type register
- *
- * Bit fields:
- * [15:8] Number of the data regions implemented or 0 if MPU is not present.
- * [1] 0: unified (no distinction between instruction and data)
- * 1: separated
- */
-uint32_t mpu_get_type(void);
-
-/* Location of iram.text */
-extern char __iram_text_start;
-extern char __iram_text_end;
-
-/**
- * Protect RAM from code execution
- */
-int mpu_protect_data_ram(void);
-
-/**
- * Protect code RAM from being overwritten
- */
-int mpu_protect_code_ram(void);
-
-/**
- * Protect internal mapped flash memory from code execution
- */
-int mpu_lock_ro_flash(void);
-int mpu_lock_rw_flash(void);
-
-/**
- * Protect/unprotect rollback region readback.
- */
-int mpu_lock_rollback(int lock);
-
-/**
- * Initialize MPU.
- * It disables all regions if MPU is implemented. Otherwise, returns
- * EC_ERROR_UNIMPLEMENTED.
- */
-int mpu_pre_init(void);
-
-#endif /* __CROS_EC_MPU_H */
diff --git a/core/cortex-m/include/mpu_private.h b/core/cortex-m/include/mpu_private.h
deleted file mode 100644
index e6030114c2..0000000000
--- a/core/cortex-m/include/mpu_private.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright 2020 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.
- */
-
-/**
- * @file
- *
- * @brief Private header file. Not meant to be used outside of mpu.c and tests.
- */
-
-#ifndef __CROS_EC_MPU_PRIVATE_H
-#define __CROS_EC_MPU_PRIVATE_H
-
-int mpu_num_regions(void);
-bool has_mpu(void);
-bool mpu_is_unified(void);
-void mpu_disable(void);
-int mpu_update_region(uint8_t region, uint32_t addr, uint8_t size_bit,
- uint16_t attr, uint8_t enable, uint8_t srd);
-int mpu_config_region(uint8_t region, uint32_t addr, uint32_t size,
- uint16_t attr, uint8_t enable);
-struct mpu_rw_regions mpu_get_rw_regions(void);
-
-#endif /* __CROS_EC_MPU_PRIVATE_H */
diff --git a/core/cortex-m/init.S b/core/cortex-m/init.S
deleted file mode 100644
index bc650c4c64..0000000000
--- a/core/cortex-m/init.S
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copyright 2011 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.
- *
- * Cortex-M CPU initialization
- */
-
-#include "config.h"
-
-.text
-.syntax unified
-.code 16
-
-.global reset
-.thumb_func
-reset:
- /*
- * Ensure we're in privileged mode with main stack. Necessary if
- * we've jumped directly here from another image after task_start().
- */
-#ifdef CONFIG_FPU
- mov r0, #(1 << 2) @ priv. mode / main stack / floating point on
-#else
- mov r0, #0 @ priv. mode / main stack / no floating point
-#endif
- msr control, r0
- isb @ ensure the write is done
-
- /* Set the vector table on our current code */
- ldr r1, =vectors
- ldr r2, =0xE000ED08 /* VTABLE register in SCB*/
- str r1, [r2]
-
- /* Clear BSS */
- mov r0, #0
- ldr r1,_bss_start
- ldr r2,_bss_end
-bss_loop:
- cmp r1, r2
- it lt
- strlt r0, [r1], #4
- blt bss_loop
-
- /* Copy initialized data to Internal RAM */
- ldr r0,_data_lma_start
-
- /*
- * When the .data section is linked into the .init_rom section,
- * _data_lma_start is defined as a flash offset instead of a full
- * 32-bit address by the linker script. Add the 32-bit flash base
- * address to get a full 32-bit address.
- *
- * Flash locking isn't needed here as no tasks have been started.
- */
-#ifdef CONFIG_CHIP_DATA_IN_INIT_ROM
- ldr r1, =CONFIG_MAPPED_STORAGE_BASE
- add r0, r0, r1
-#endif
-
- ldr r1,_data_start
- ldr r2,_data_end
-data_loop:
- ldr r3, [r0], #4
- cmp r1, r2
- it lt
- strlt r3, [r1], #4
- blt data_loop
-
- /*
- * Set stack pointer. Already done by Cortex-M hardware, but re-doing
- * this here allows software to jump directly to the reset vector.
- */
- ldr r0, =stack_end
- mov sp, r0
-
-#ifdef CONFIG_FPU
- /* Enable FPU */
- /* CPACR is located at address 0xE000ED88 */
- ldr r0, =0xE000ED88
- /* Read CPACR */
- ldr r1, [r0]
- /* Set bits 20-23 to enable CP10 and CP11 coprocessors */
- orr r1, r1, #(0xF << 20)
- /* Write back the modified value to the CPACR */
- str r1, [r0] /* wait for store to complete */
- dsb
- /* reset pipeline now the FPU is enabled */
- isb
-#endif /* CONFIG_FPU */
-
-#ifdef CONFIG_DEBUG_DISABLE_WRITE_BUFFER
- /* Disable write buffer used for default memory map accesses */
- ldr r0, =0xE000E008 /* Load address of ACTLR */
- ldr r1, [r0] /* Read ACTLR */
- orr r1, r1, #2 /* Set DISDEFWBUF bit */
- str r1, [r0] /* Write back ACTLR */
- dsb /* Wait for store to complete */
- isb /* Reset pipeline */
-#endif /* CONFIG_DEBUG_DISABLE_WRITE_BUFFER */
-
- /* Jump to C code */
- bl main
-
- /* That should not return. If it does, loop forever. */
-fini_loop:
- b fini_loop
-
-.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
-
-/* Mock functions to avoid linker complaints */
-.global __aeabi_unwind_cpp_pr0
-.global __aeabi_unwind_cpp_pr1
-.global __aeabi_unwind_cpp_pr2
-__aeabi_unwind_cpp_pr0:
-__aeabi_unwind_cpp_pr1:
-__aeabi_unwind_cpp_pr2:
- bx lr
-
-/* Reserve space for system stack */
-.section .bss.system_stack
-stack_start:
-.space CONFIG_STACK_SIZE, 0
-stack_end:
-.global stack_end
-
diff --git a/core/cortex-m/irq_handler.h b/core/cortex-m/irq_handler.h
deleted file mode 100644
index ae5d95cd94..0000000000
--- a/core/cortex-m/irq_handler.h
+++ /dev/null
@@ -1,44 +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
-
-#ifdef CONFIG_TASK_PROFILING
-#define bl_task_start_irq_handler "bl task_start_irq_handler\n"
-#else
-#define bl_task_start_irq_handler ""
-#endif
-
-/* 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) DECLARE_IRQ_(irq, routine, priority)
-#define DECLARE_IRQ_(irq, routine, priority) \
- void IRQ_HANDLER(irq)(void) __attribute__((naked)); \
- typedef struct { \
- int fake[irq >= CONFIG_IRQ_COUNT ? -1 : 1]; \
- } irq_num_check_##irq; \
- void __keep routine(void); \
- void IRQ_HANDLER(irq)(void) \
- { \
- asm volatile("mov r0, lr\n" \
- "push {r0, lr}\n" \
- bl_task_start_irq_handler \
- "bl "#routine"\n" \
- "pop {r0, lr}\n" \
- "b task_resched_if_needed\n" \
- ); \
- } \
- const struct irq_priority __keep IRQ_PRIORITY(irq) \
- __attribute__((section(".rodata.irqprio"))) \
- = {irq, priority}
-#endif /* __CROS_EC_IRQ_HANDLER_H */
diff --git a/core/cortex-m/ldivmod.S b/core/cortex-m/ldivmod.S
deleted file mode 120000
index afdeb4ec1f..0000000000
--- a/core/cortex-m/ldivmod.S
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/libaeabi-cortexm0/core/cortex-m/ldivmod.S \ No newline at end of file
diff --git a/core/cortex-m/llsr.c b/core/cortex-m/llsr.c
deleted file mode 100644
index 0827121e97..0000000000
--- a/core/cortex-m/llsr.c
+++ /dev/null
@@ -1,65 +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.
- */
-
-/* Enable the use of right shift for uint64_t. */
-
-#include <console.h>
-#include <compile_time_macros.h>
-#include <stdint.h>
-
-union words {
- uint64_t u64;
- uint32_t w[2];
-};
-
-uint64_t __attribute__((used)) __aeabi_llsr(uint64_t v, uint32_t shift)
-{
- union words val;
- union words res;
-
- val.u64 = v;
- res.w[1] = val.w[1] >> shift;
- res.w[0] = val.w[0] >> shift;
- res.w[0] |= val.w[1] >> (shift - 32); /* Handle shift >= 32*/
- res.w[0] |= val.w[1] << (32 - shift); /* Handle shift <= 32*/
- return res.u64;
-}
-
-#ifdef CONFIG_LLSR_TEST
-
-static int command_llsr(int argc, char **argv)
-{
- /* Volatile to prevent compilier optimization from interfering. */
- volatile uint64_t start = 0x123456789ABCDEF0ull;
- uint32_t x;
-
- const struct {
- uint32_t shift_by;
- uint64_t result;
- } cases[] = {
- {0, start},
- {16, 0x123456789ABCull},
- {32, 0x12345678u},
- {48, 0x1234u},
- {64, 0u}
- };
-
- for (x = 0; x < ARRAY_SIZE(cases); ++x) {
- if ((start >> cases[x].shift_by) != cases[x].result) {
- ccprintf("FAILED %d\n", cases[x].shift_by);
- return EC_ERROR_UNKNOWN;
- }
- }
-
- ccprintf("SUCCESS\n");
- return EC_SUCCESS;
-}
-
-DECLARE_CONSOLE_COMMAND(
- llsrtest, command_llsr,
- "",
- "Run tests against the LLSR ABI. Prints SUCCESS or FAILURE.");
-
-#endif /* CONFIG_LLSR_TEST */
diff --git a/core/cortex-m/mpu.c b/core/cortex-m/mpu.c
deleted file mode 100644
index 29da931a28..0000000000
--- a/core/cortex-m/mpu.c
+++ /dev/null
@@ -1,457 +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.
- */
-
-/* MPU module for Chrome EC */
-
-#include "mpu.h"
-#include "console.h"
-#include "cpu.h"
-#include "registers.h"
-#include "task.h"
-#include "util.h"
-
-/**
- * @return Number of regions supported by the MPU. 0 means the processor does
- * not implement an MPU.
- */
-int mpu_num_regions(void)
-{
- return MPU_TYPE_REG_COUNT(mpu_get_type());
-}
-
-/**
- * @return true if processor has MPU, false otherwise
- */
-bool has_mpu(void)
-{
- return mpu_num_regions() != 0;
-}
-
-/**
- * @return true if MPU has unified instruction and data maps, false otherwise
- */
-bool mpu_is_unified(void)
-{
- return (mpu_get_type() & MPU_TYPE_UNIFIED_MASK) == 0;
-}
-
-
-/**
- * Update a memory region.
- *
- * region: index of the region to update
- * addr: base address of the region
- * size_bit: size of the region in power of two.
- * attr: attribute bits. Current value will be overwritten if enable is true.
- * enable: enables the region if non zero. Otherwise, disables the region.
- * srd: subregion mask to partition region into 1/8ths, 0 = subregion enabled.
- *
- * Based on 3.1.4.1 'Updating an MPU Region' of Stellaris LM4F232H5QC Datasheet
- */
-int mpu_update_region(uint8_t region, uint32_t addr, uint8_t size_bit,
- uint16_t attr, uint8_t enable, uint8_t srd)
-{
- /*
- * Note that on the Cortex-M3, Cortex-M4, and Cortex-M7, the base
- * address used for an MPU region must be aligned to the size of the
- * region:
- *
- * https://developer.arm.com/docs/dui0553/a/cortex-m4-peripherals/optional-memory-protection-unit/mpu-region-base-address-register
- * https://developer.arm.com/docs/dui0552/a/cortex-m3-peripherals/optional-memory-protection-unit/mpu-region-base-address-register
- * https://developer.arm.com/docs/dui0646/a/cortex-m7-peripherals/optional-memory-protection-unit/mpu-region-base-address-register#BABDAHJG
- */
- if (!is_aligned(addr, BIT(size_bit)))
- return -EC_ERROR_INVAL;
-
- if (region >= mpu_num_regions())
- return -EC_ERROR_INVAL;
-
- if (size_bit < MPU_SIZE_BITS_MIN)
- return -EC_ERROR_INVAL;
-
- asm volatile("isb; dsb;");
-
- MPU_NUMBER = region;
- MPU_SIZE &= ~1; /* Disable */
- if (enable) {
- MPU_BASE = addr;
- /*
- * MPU_ATTR = attr;
- * MPU_SIZE = (srd << 8) | ((size_bit - 1) << 1) | 1;
- *
- * WORKAROUND: the 2 half-word accesses above should work
- * according to the doc, but they don't ..., do a single 32-bit
- * one.
- */
- REG32(&MPU_SIZE) = ((uint32_t)attr << 16)
- | (srd << 8) | ((size_bit - 1) << 1) | 1;
- }
-
- asm volatile("isb; dsb;");
-
- return EC_SUCCESS;
-}
-
-/*
- * Greedily configure the largest possible part of the given region from the
- * base address.
- *
- * Returns EC_SUCCESS on success and sets *consumed to the number of bytes
- * mapped from the base address. In case of error, the value of *consumed is
- * unpredictable.
- *
- * For instance, if addr is 0x10070000 and size is 0x30000 then memory in the
- * range 0x10070000-0x10080000 will be configured and *consumed will be set to
- * 0x10000.
- */
-static int mpu_config_region_greedy(uint8_t region, uint32_t addr,
- uint32_t size, uint16_t attr,
- uint8_t enable, uint32_t *consumed)
-{
- /*
- * Compute candidate alignment to be used for the MPU region.
- *
- * This is the minimum of the base address and size alignment, since
- * regions must be naturally aligned to their size.
- */
- uint8_t natural_alignment = MIN(addr == 0 ? 32 : alignment_log2(addr),
- alignment_log2(size));
- uint8_t subregion_disable = 0;
-
- if (natural_alignment >= 5) {
- int sr_idx;
- uint32_t subregion_base, subregion_size;
- /*
- * For MPU regions larger than 256 bytes we can use subregions,
- * (which are a minimum of 32 bytes in size) making the actual
- * MPU region 8x larger. Depending on the address alignment this
- * can allow us to cover a larger area (and never a smaller
- * one).
- */
- natural_alignment += 3;
- /* Region size cannot exceed 4GB. */
- if (natural_alignment > 32)
- natural_alignment = 32;
-
- /*
- * Generate the subregion mask by walking through each,
- * disabling if it is not completely contained in the requested
- * range.
- */
- subregion_base = addr & ~((1 << natural_alignment) - 1);
- subregion_size = 1 << (natural_alignment - 3);
- *consumed = 0;
- for (sr_idx = 0; sr_idx < 8; sr_idx++) {
- if (subregion_base < addr ||
- (subregion_base + subregion_size) > (addr + size))
- /* lsb of subregion mask is lowest address */
- subregion_disable |= 1 << sr_idx;
- else
- /* not disabled means consumed */
- *consumed += subregion_size;
-
- subregion_base += subregion_size;
- }
- } else {
- /* Not using subregions; all enabled */
- *consumed = 1 << natural_alignment;
- }
-
- return mpu_update_region(region,
- addr & ~((1 << natural_alignment) - 1),
- natural_alignment,
- attr, enable, subregion_disable);
-}
-
-/**
- * Configure a region
- *
- * region: index of the region to update
- * addr: Base address of the region
- * size: Size of the region in bytes
- * attr: Attribute bits. Current value will be overwritten if enable is set.
- * enable: Enables the region if non zero. Otherwise, disables the region.
- *
- * Returns EC_SUCCESS on success, -EC_ERROR_OVERFLOW if it is not possible to
- * fully configure the given region, or -EC_ERROR_INVAL if a parameter is
- * invalid (such as the address or size having unsupported alignment).
- */
-int mpu_config_region(uint8_t region, uint32_t addr, uint32_t size,
- uint16_t attr, uint8_t enable)
-{
- int rv;
- uint32_t consumed;
-
- /* Zero size doesn't require configuration */
- if (size == 0)
- return EC_SUCCESS;
-
- rv = mpu_config_region_greedy(region, addr, size,
- attr, enable, &consumed);
- if (rv != EC_SUCCESS)
- return rv;
- ASSERT(consumed <= size);
- addr += consumed;
- size -= consumed;
-
- /* Regions other than DATA_RAM_TEXT may use two MPU regions */
- if (size > 0 && region != REGION_DATA_RAM_TEXT) {
- rv = mpu_config_region_greedy(region + 1, addr, size,
- attr, enable, &consumed);
- if (rv != EC_SUCCESS)
- return rv;
- ASSERT(consumed <= size);
- addr += consumed;
- size -= consumed;
- }
-
- if (size > 0)
- return EC_ERROR_OVERFLOW;
- return EC_SUCCESS;
-}
-
-/**
- * Set a region executable and read-write.
- *
- * region: index of the region
- * addr: base address of the region
- * size: size of the region in bytes
- * texscb: TEX and SCB bit field
- */
-static int mpu_unlock_region(uint8_t region, uint32_t addr, uint32_t size,
- uint8_t texscb)
-{
- return mpu_config_region(region, addr, size,
- MPU_ATTR_RW_RW | texscb, 1);
-}
-
-void mpu_enable(void)
-{
- MPU_CTRL |= MPU_CTRL_PRIVDEFEN | MPU_CTRL_HFNMIENA | MPU_CTRL_ENABLE;
-}
-
-void mpu_disable(void)
-{
- MPU_CTRL &= ~(MPU_CTRL_PRIVDEFEN | MPU_CTRL_HFNMIENA | MPU_CTRL_ENABLE);
-}
-
-uint32_t mpu_get_type(void)
-{
- return MPU_TYPE;
-}
-
-int mpu_protect_data_ram(void)
-{
- int ret;
-
- /* Prevent code execution from data RAM */
- ret = mpu_config_region(REGION_DATA_RAM,
- CONFIG_RAM_BASE,
- CONFIG_DATA_RAM_SIZE,
- MPU_ATTR_XN |
- MPU_ATTR_RW_RW |
- MPU_ATTR_INTERNAL_SRAM,
- 1);
- if (ret != EC_SUCCESS)
- return ret;
-
- /* Exempt the __iram_text section */
- return mpu_unlock_region(
- REGION_DATA_RAM_TEXT, (uint32_t)&__iram_text_start,
- (uint32_t)(&__iram_text_end - &__iram_text_start),
- MPU_ATTR_INTERNAL_SRAM);
-}
-
-#if defined(CONFIG_EXTERNAL_STORAGE) || !defined(CONFIG_FLASH_PHYSICAL)
-int mpu_protect_code_ram(void)
-{
- /* Prevent write access to code RAM */
- return mpu_config_region(REGION_STORAGE,
- CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RO_MEM_OFF,
- CONFIG_CODE_RAM_SIZE,
- MPU_ATTR_RO_NO | MPU_ATTR_INTERNAL_SRAM,
- 1);
-}
-#else
-int mpu_lock_ro_flash(void)
-{
- /* Prevent execution from internal mapped RO flash */
- return mpu_config_region(REGION_STORAGE,
- CONFIG_MAPPED_STORAGE_BASE + CONFIG_RO_MEM_OFF,
- CONFIG_RO_SIZE,
- MPU_ATTR_XN | MPU_ATTR_RW_RW |
- MPU_ATTR_FLASH_MEMORY, 1);
-}
-
-/* Represent RW with at most 2 MPU regions. */
-struct mpu_rw_regions mpu_get_rw_regions(void)
-{
- int aligned_size_bit;
- struct mpu_rw_regions regions = {};
-
- regions.addr[0] = CONFIG_MAPPED_STORAGE_BASE + CONFIG_RW_MEM_OFF;
-
- /*
- * Least significant set bit of the address determines the max size of
- * the region because on the Cortex-M3, Cortex-M4 and Cortex-M7, the
- * address used for an MPU region must be aligned to the size.
- */
- aligned_size_bit =
- __fls(regions.addr[0] & -regions.addr[0]);
- regions.size[0] = MIN(BIT(aligned_size_bit), CONFIG_RW_SIZE);
- regions.addr[1] = regions.addr[0] + regions.size[0];
- regions.size[1] = CONFIG_RW_SIZE - regions.size[0];
- regions.num_regions = (regions.size[1] == 0) ? 1 : 2;
-
- return regions;
-}
-
-int mpu_lock_rw_flash(void)
-{
- /* Prevent execution from internal mapped RW flash */
- const uint16_t mpu_attr = MPU_ATTR_XN | MPU_ATTR_RW_RW |
- MPU_ATTR_FLASH_MEMORY;
- const struct mpu_rw_regions regions = mpu_get_rw_regions();
- int rv;
-
- rv = mpu_config_region(REGION_STORAGE, regions.addr[0], regions.size[0],
- mpu_attr, 1);
- if ((rv != EC_SUCCESS) || (regions.num_regions == 1))
- return rv;
-
- /* If this fails then it's impossible to represent with two regions. */
- return mpu_config_region(REGION_STORAGE2, regions.addr[1],
- regions.size[1], mpu_attr, 1);
-}
-#endif /* !CONFIG_EXTERNAL_STORAGE */
-
-#ifdef CONFIG_ROLLBACK_MPU_PROTECT
-int mpu_lock_rollback(int lock)
-{
- int rv;
- int num_mpu_regions = mpu_num_regions();
-
- const uint32_t rollback_region_start_address =
- CONFIG_MAPPED_STORAGE_BASE + CONFIG_ROLLBACK_OFF;
- const uint32_t rollback_region_total_size = CONFIG_ROLLBACK_SIZE;
- const uint16_t mpu_attr =
- MPU_ATTR_XN /* Execute never */ |
- MPU_ATTR_NO_NO /* No access (privileged or unprivileged */;
-
- /*
- * Originally rollback MPU support was added on Cortex-M7, which
- * supports 16 MPU regions and has rollback region aligned in a way
- * that we can use a single region.
- */
- uint8_t rollback_mpu_region = REGION_ROLLBACK;
-
- if (rollback_mpu_region < num_mpu_regions) {
- rv = mpu_config_region(rollback_mpu_region,
- rollback_region_start_address,
- rollback_region_total_size, mpu_attr,
- lock);
- return rv;
- }
-
- /*
- * If we get here, we can't use REGION_ROLLBACK because our MPU doesn't
- * have enough regions. Instead, we choose unused MPU regions.
- *
- * Note that on the Cortex-M3, Cortex-M4, and Cortex-M7, the base
- * address used for an MPU region must be aligned to the size of the
- * region, so it's not possible to use a single region to protect the
- * entire rollback flash on the STM32F412 (bloonchipper); we have to
- * use two.
- *
- * See mpu_update_region for alignment details.
- */
-
- rollback_mpu_region = REGION_CHIP_RESERVED;
- rv = mpu_config_region(rollback_mpu_region,
- rollback_region_start_address,
- rollback_region_total_size / 2, mpu_attr, lock);
- if (rv != EC_SUCCESS)
- return rv;
-
- rollback_mpu_region = REGION_CODE_RAM;
- rv = mpu_config_region(rollback_mpu_region,
- rollback_region_start_address +
- (rollback_region_total_size / 2),
- rollback_region_total_size / 2, mpu_attr, lock);
- return rv;
-}
-#endif
-
-#ifdef CONFIG_CHIP_UNCACHED_REGION
-/* Store temporarily the regions ranges to use them for the MPU configuration */
-#define REGION(_name, _flag, _start, _size) \
- static const uint32_t CONCAT2(_region_start_, _name) \
- __attribute__((unused, section(".unused"))) = _start; \
- static const uint32_t CONCAT2(_region_size_, _name) \
- __attribute__((unused, section(".unused"))) = _size;
-#include "memory_regions.inc"
-#undef REGION
-#endif /* CONFIG_CHIP_UNCACHED_REGION */
-
-int mpu_pre_init(void)
-{
- int i;
- int num_mpu_regions;
- int rv;
-
- if (!has_mpu())
- return EC_ERROR_HW_INTERNAL;
-
- num_mpu_regions = mpu_num_regions();
-
- /* Supports MPU with 8 or 16 unified regions */
- if (!mpu_is_unified() ||
- (num_mpu_regions != 8 && num_mpu_regions != 16))
- return EC_ERROR_UNIMPLEMENTED;
-
- mpu_disable();
-
- for (i = 0; i < num_mpu_regions; ++i) {
- /*
- * Disable all regions.
- *
- * We use the smallest possible size (32 bytes), but it
- * doesn't really matter since the regions are disabled.
- *
- * Use the fixed SRAM region base to ensure base is aligned
- * to the region size.
- */
- rv = mpu_update_region(i, CORTEX_M_SRAM_BASE, MPU_SIZE_BITS_MIN,
- 0, 0, 0);
- if (rv != EC_SUCCESS)
- return rv;
- }
-
- if (IS_ENABLED(CONFIG_ROLLBACK_MPU_PROTECT)) {
- rv = mpu_lock_rollback(1);
- if (rv != EC_SUCCESS)
- return rv;
- }
-
- if (IS_ENABLED(CONFIG_ARMV7M_CACHE)) {
-#ifdef CONFIG_CHIP_UNCACHED_REGION
- rv = mpu_config_region(
- REGION_UNCACHED_RAM,
- CONCAT2(_region_start_, CONFIG_CHIP_UNCACHED_REGION),
- CONCAT2(_region_size_, CONFIG_CHIP_UNCACHED_REGION),
- MPU_ATTR_XN | MPU_ATTR_RW_RW, 1);
- if (rv != EC_SUCCESS)
- return rv;
-
-#endif
- }
-
- mpu_enable();
-
- if (IS_ENABLED(CONFIG_ARMV7M_CACHE))
- cpu_enable_caches();
-
- return EC_SUCCESS;
-}
diff --git a/core/cortex-m/panic-internal.h b/core/cortex-m/panic-internal.h
deleted file mode 100644
index 1a58afa8a2..0000000000
--- a/core/cortex-m/panic-internal.h
+++ /dev/null
@@ -1,11 +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.
- */
-
-#ifndef __CROS_EC_PANIC_INTERNAL_H
-#define __CROS_EC_PANIC_INTERNAL_H
-
-void exception_panic(void) __attribute__((naked));
-
-#endif /* __CROS_EC_PANIC_INTERNAL_H */
diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c
deleted file mode 100644
index da6900b1b9..0000000000
--- a/core/cortex-m/panic.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/* Copyright 2012 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 "host_command.h"
-#include "panic.h"
-#include "panic-internal.h"
-#include "printf.h"
-#include "system.h"
-#include "task.h"
-#include "timer.h"
-#include "uart.h"
-#include "util.h"
-#include "watchdog.h"
-
-/* Whether bus fault is ignored */
-static int bus_fault_ignored;
-
-
-/* Panic data goes at the end of RAM. */
-static struct panic_data * const pdata_ptr = PANIC_DATA_PTR;
-
-/* Preceded by stack, rounded down to nearest 64-bit-aligned boundary */
-static const uint32_t pstack_addr = (CONFIG_RAM_BASE + CONFIG_RAM_SIZE
- - sizeof(struct panic_data)) & ~7;
-
-/**
- * Print the name and value of a register
- *
- * This is a convenient helper function for displaying a register value.
- * It shows the register name in a 3 character field, followed by a colon.
- * The register value is regs[index], and this is shown in hex. If regs is
- * NULL, then we display spaces instead.
- *
- * After displaying the value, either a space or \n is displayed depending
- * on the register number, so that (assuming the caller passes all 16
- * registers in sequence) we put 4 values per line like this
- *
- * r0 :0000000b r1 :00000047 r2 :60000000 r3 :200012b5
- * r4 :00000000 r5 :08004e64 r6 :08004e1c r7 :200012a8
- * r8 :08004e64 r9 :00000002 r10:00000000 r11:00000000
- * r12:0000003f sp :200009a0 lr :0800270d pc :0800351a
- *
- * @param regnum Register number to display (0-15)
- * @param regs Pointer to array holding the registers, or NULL
- * @param index Index into array where the register value is present
- */
-static void print_reg(int regnum, const uint32_t *regs, int index)
-{
- static const char regname[] = "r10r11r12sp lr pc ";
- static char rname[3] = "r ";
- const char *name;
-
- rname[1] = '0' + regnum;
- name = regnum < 10 ? rname : &regname[(regnum - 10) * 3];
- panic_printf("%c%c%c:", name[0], name[1], name[2]);
- if (regs)
- panic_printf("%08x", regs[index]);
- else
- panic_puts(" ");
- panic_puts((regnum & 3) == 3 ? "\n" : " ");
-}
-
-/*
- * Returns non-zero if the exception frame was created on the main stack, or
- * zero if it's on the process stack.
- *
- * See B1.5.8 "Exception return behavior" of ARM DDI 0403D for details.
- */
-static int32_t is_frame_in_handler_stack(const uint32_t exc_return)
-{
- return (exc_return & 0xf) == 1 || (exc_return & 0xf) == 9;
-}
-
-#ifdef CONFIG_DEBUG_EXCEPTIONS
-/* Names for each of the bits in the cfs register, starting at bit 0 */
-static const char * const cfsr_name[32] = {
- /* MMFSR */
- [0] = "Instruction access violation",
- [1] = "Data access violation",
- [3] = "Unstack from exception violation",
- [4] = "Stack from exception violation",
-
- /* BFSR */
- [8] = "Instruction bus error",
- [9] = "Precise data bus error",
- [10] = "Imprecise data bus error",
- [11] = "Unstack from exception bus fault",
- [12] = "Stack from exception bus fault",
-
- /* UFSR */
- [16] = "Undefined instructions",
- [17] = "Invalid state",
- [18] = "Invalid PC",
- [19] = "No coprocessor",
- [24] = "Unaligned",
- [25] = "Divide by 0",
-};
-
-/* Names for the first 5 bits in the DFSR */
-static const char * const dfsr_name[] = {
- "Halt request",
- "Breakpoint",
- "Data watchpoint/trace",
- "Vector catch",
- "External debug request",
-};
-
-/**
- * Helper function to display a separator after the previous item
- *
- * If items have been displayed already, we display a comma separator.
- * In any case, the count of items displayed is incremeneted.
- *
- * @param count Number of items displayed so far (0 for none)
- */
-static void do_separate(int *count)
-{
- if (*count)
- panic_puts(", ");
- (*count)++;
-}
-
-/**
- * Show a textual representaton of the fault registers
- *
- * A list of detected faults is shown, with no trailing newline.
- *
- * @param cfsr Value of Configurable Fault Status
- * @param hfsr Value of Hard Fault Status
- * @param dfsr Value of Debug Fault Status
- */
-static void show_fault(uint32_t cfsr, uint32_t hfsr, uint32_t dfsr)
-{
- unsigned int upto;
- int count = 0;
-
- for (upto = 0; upto < 32; upto++) {
- if ((cfsr & BIT(upto)) && cfsr_name[upto]) {
- do_separate(&count);
- panic_puts(cfsr_name[upto]);
- }
- }
-
- if (hfsr & CPU_NVIC_HFSR_DEBUGEVT) {
- do_separate(&count);
- panic_puts("Debug event");
- }
- if (hfsr & CPU_NVIC_HFSR_FORCED) {
- do_separate(&count);
- panic_puts("Forced hard fault");
- }
- if (hfsr & CPU_NVIC_HFSR_VECTTBL) {
- do_separate(&count);
- panic_puts("Vector table bus fault");
- }
-
- for (upto = 0; upto < 5; upto++) {
- if ((dfsr & BIT(upto))) {
- do_separate(&count);
- panic_puts(dfsr_name[upto]);
- }
- }
-}
-
-/*
- * Returns the size of the exception frame.
- *
- * See B1.5.7 "Stack alignment on exception entry" of ARM DDI 0403D for details.
- * In short, the exception frame size can be either 0x20, 0x24, 0x68, or 0x6c
- * depending on FPU context and padding for 8-byte alignment.
- */
-static uint32_t get_exception_frame_size(const struct panic_data *pdata)
-{
- uint32_t frame_size = 0;
-
- /* base exception frame */
- frame_size += 8 * sizeof(uint32_t);
-
- /* CPU uses xPSR[9] to indicate whether it padded the stack for
- * alignment or not. */
- if (pdata->cm.frame[7] & BIT(9))
- frame_size += sizeof(uint32_t);
-
-#ifdef CONFIG_FPU
- /* CPU uses EXC_RETURN[4] to indicate whether it stored extended
- * frame for FPU or not. */
- if (!(pdata->cm.regs[11] & BIT(4)))
- frame_size += 18 * sizeof(uint32_t);
-#endif
-
- return frame_size;
-}
-
-/*
- * Returns the position of the process stack before the exception frame.
- * It computes the size of the exception frame and adds it to psp.
- * If the exception happened in the exception context, it returns psp as is.
- */
-static uint32_t get_process_stack_position(const struct panic_data *pdata)
-{
- uint32_t psp = pdata->cm.regs[0];
-
- if (!is_frame_in_handler_stack(pdata->cm.regs[11]))
- psp += get_exception_frame_size(pdata);
-
- return psp;
-}
-
-/*
- * Show extra information that might be useful to understand a panic()
- *
- * We show fault register information, including the fault address registers
- * if valid.
- */
-static void panic_show_extra(const struct panic_data *pdata)
-{
- show_fault(pdata->cm.cfsr, pdata->cm.hfsr, pdata->cm.dfsr);
- if (pdata->cm.cfsr & CPU_NVIC_CFSR_BFARVALID)
- panic_printf(", bfar = %x", pdata->cm.bfar);
- if (pdata->cm.cfsr & CPU_NVIC_CFSR_MFARVALID)
- panic_printf(", mfar = %x", pdata->cm.mfar);
- panic_printf("\ncfsr = %x, ", pdata->cm.cfsr);
- panic_printf("shcsr = %x, ", pdata->cm.shcsr);
- panic_printf("hfsr = %x, ", pdata->cm.hfsr);
- panic_printf("dfsr = %x\n", pdata->cm.dfsr);
-}
-
-/*
- * Prints process stack contents stored above the exception frame.
- */
-static void panic_show_process_stack(const struct panic_data *pdata)
-{
- panic_printf("\n=========== Process Stack Contents ===========");
- if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID) {
- uint32_t psp = get_process_stack_position(pdata);
- int i;
- for (i = 0; i < 16; i++) {
- if (psp + sizeof(uint32_t) >
- CONFIG_RAM_BASE + CONFIG_RAM_SIZE)
- break;
- if (i % 4 == 0)
- panic_printf("\n%08x:", psp);
- panic_printf(" %08x", *(uint32_t *)psp);
- psp += sizeof(uint32_t);
- }
- } else {
- panic_printf("\nBad psp");
- }
-}
-#endif /* CONFIG_DEBUG_EXCEPTIONS */
-
-/*
- * Print panic data
- */
-void panic_data_print(const struct panic_data *pdata)
-{
- const uint32_t *lregs = pdata->cm.regs;
- const uint32_t *sregs = NULL;
- const int32_t in_handler =
- is_frame_in_handler_stack(pdata->cm.regs[11]);
- int i;
-
- if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID)
- sregs = pdata->cm.frame;
-
- panic_printf("\n=== %s EXCEPTION: %02x ====== xPSR: %08x ===\n",
- in_handler ? "HANDLER" : "PROCESS",
- lregs[1] & 0xff, sregs ? sregs[7] : -1);
- for (i = 0; i < 4; i++)
- print_reg(i, sregs, i);
- for (i = 4; i < 10; i++)
- print_reg(i, lregs, i - 1);
- print_reg(10, lregs, 9);
- print_reg(11, lregs, 10);
- print_reg(12, sregs, 4);
- print_reg(13, lregs, in_handler ? 2 : 0);
- print_reg(14, sregs, 5);
- print_reg(15, sregs, 6);
-
-#ifdef CONFIG_DEBUG_EXCEPTIONS
- panic_show_extra(pdata);
-#endif
-}
-
-void __keep report_panic(void)
-{
- /*
- * Don't need to get pointer via get_panic_data_write()
- * because memory below pdata_ptr is stack now (see exception_panic())
- */
- struct panic_data *pdata = pdata_ptr;
- uint32_t sp;
-
- pdata->magic = PANIC_DATA_MAGIC;
- pdata->struct_size = sizeof(*pdata);
- pdata->struct_version = 2;
- pdata->arch = PANIC_ARCH_CORTEX_M;
- pdata->flags = 0;
- pdata->reserved = 0;
-
- /* Choose the right sp (psp or msp) based on EXC_RETURN value */
- sp = is_frame_in_handler_stack(pdata->cm.regs[11])
- ? pdata->cm.regs[2] : pdata->cm.regs[0];
- /* If stack is valid, copy exception frame to pdata */
- if ((sp & 3) == 0 &&
- sp >= CONFIG_RAM_BASE &&
- sp <= CONFIG_RAM_BASE + CONFIG_RAM_SIZE - 8 * sizeof(uint32_t)) {
- const uint32_t *sregs = (const uint32_t *)sp;
- int i;
-
- /* Skip r0-r3 and r12 registers if necessary */
- for (i = CORTEX_PANIC_FRAME_REGISTER_R0;
- i <= CORTEX_PANIC_FRAME_REGISTER_R12; i++)
- if (IS_ENABLED(CONFIG_PANIC_STRIP_GPR))
- pdata->cm.frame[i] = 0;
- else
- pdata->cm.frame[i] = sregs[i];
-
- for (i = CORTEX_PANIC_FRAME_REGISTER_LR;
- i < NUM_CORTEX_PANIC_FRAME_REGISTERS; i++)
- pdata->cm.frame[i] = sregs[i];
-
- pdata->flags |= PANIC_DATA_FLAG_FRAME_VALID;
- }
-
- /* Save extra information */
- pdata->cm.cfsr = CPU_NVIC_CFSR;
- pdata->cm.bfar = CPU_NVIC_BFAR;
- pdata->cm.mfar = CPU_NVIC_MFAR;
- pdata->cm.shcsr = CPU_NVIC_SHCSR;
- pdata->cm.hfsr = CPU_NVIC_HFSR;
- pdata->cm.dfsr = CPU_NVIC_DFSR;
-
-#ifdef CONFIG_UART_PAD_SWITCH
- uart_reset_default_pad_panic();
-#endif
- panic_data_print(pdata);
-#ifdef CONFIG_DEBUG_EXCEPTIONS
- panic_show_process_stack(pdata);
- /*
- * TODO(crosbug.com/p/23760): Dump main stack contents as well if the
- * exception happened in a handler's context.
- */
-#endif
-
- /* Make sure that all changes are saved into RAM */
- if (IS_ENABLED(CONFIG_ARMV7M_CACHE))
- cpu_clean_invalidate_dcache();
-
- panic_reboot();
-}
-
-/**
- * Default exception handler, which reports a panic.
- *
- * Declare this as a naked call so we can extract raw LR and IPSR values.
- */
-void exception_panic(void)
-{
- /* Save registers and branch directly to panic handler */
- asm volatile(
- "mov r0, %[pregs]\n"
- "mrs r1, psp\n"
- "mrs r2, ipsr\n"
- "mov r3, sp\n"
-#ifdef CONFIG_PANIC_STRIP_GPR
- /*
- * Check if we are in exception. This is similar to
- * in_interrupt_context(). Exception bits are 9 LSB, so
- * we can perform left shift for 23 bits and check if result
- * is 0 (lsls instruction is setting appropriate flags).
- */
- "lsls r6, r2, #23\n"
- /*
- * If this is software panic (shift result == 0) then register
- * r4 and r5 contain additional info about panic.
- * Clear r6-r11 always and r4, r5 only if this is exception
- * panic. To clear r4 and r5, 'movne' conditional instruction
- * is used. It works only when flags contain information that
- * result was != 0. Itt is pseudo instruction which is used
- * to make sure we are using correct conditional instructions.
- */
- "itt ne\n"
- "movne r4, #0\n"
- "movne r5, #0\n"
- "mov r6, #0\n"
- "mov r7, #0\n"
- "mov r8, #0\n"
- "mov r9, #0\n"
- "mov r10, #0\n"
- "mov r11, #0\n"
-#endif
- "stmia r0, {r1-r11, lr}\n"
- "mov sp, %[pstack]\n"
- "bl report_panic\n" : :
- [pregs] "r" (pdata_ptr->cm.regs),
- [pstack] "r" (pstack_addr) :
- /* Constraints protecting these from being clobbered.
- * Gcc should be using r0 & r12 for pregs and pstack. */
- "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
- "r10", "r11", "cc", "memory"
- );
-}
-
-#ifdef CONFIG_SOFTWARE_PANIC
-void software_panic(uint32_t reason, uint32_t info)
-{
- __asm__("mov " STRINGIFY(SOFTWARE_PANIC_INFO_REG) ", %0\n"
- "mov " STRINGIFY(SOFTWARE_PANIC_REASON_REG) ", %1\n"
- "bl exception_panic\n"
- : : "r"(info), "r"(reason));
- __builtin_unreachable();
-}
-
-void panic_set_reason(uint32_t reason, uint32_t info, uint8_t exception)
-{
- struct panic_data * const pdata = get_panic_data_write();
- uint32_t *lregs;
-
- lregs = pdata->cm.regs;
-
- /* Setup panic data structure */
- memset(pdata, 0, CONFIG_PANIC_DATA_SIZE);
- pdata->magic = PANIC_DATA_MAGIC;
- pdata->struct_size = CONFIG_PANIC_DATA_SIZE;
- pdata->struct_version = 2;
- pdata->arch = PANIC_ARCH_CORTEX_M;
-
- /* Log panic cause */
- lregs[1] = exception;
- lregs[3] = reason;
- lregs[4] = info;
-}
-
-void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception)
-{
- struct panic_data * const pdata = panic_get_data();
- uint32_t *lregs;
-
- if (pdata && pdata->struct_version == 2) {
- lregs = pdata->cm.regs;
- *exception = lregs[1];
- *reason = lregs[3];
- *info = lregs[4];
- } else {
- *exception = *reason = *info = 0;
- }
-}
-#endif
-
-void bus_fault_handler(void)
-{
- if (!bus_fault_ignored)
- exception_panic();
-}
-
-void ignore_bus_fault(int ignored)
-{
- if (IS_ENABLED(CHIP_FAMILY_STM32H7)) {
- if (ignored == 0)
- asm volatile("dsb; isb");
- }
-
- /*
- * Flash code might call this before cpu_init(),
- * ensure that the bus faults really go through our handler.
- */
- CPU_NVIC_SHCSR |= CPU_NVIC_SHCSR_BUSFAULTENA;
- bus_fault_ignored = ignored;
-}
diff --git a/core/cortex-m/switch.S b/core/cortex-m/switch.S
deleted file mode 100644
index f56c5e4c74..0000000000
--- a/core/cortex-m/switch.S
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright 2012 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 swtching
- */
-
-#include "config.h"
-
-.text
-
-.syntax unified
-.code 16
-
-/**
- * Task context switching
- *
- * Change the task scheduled after returning from the exception.
- *
- * Save the registers of the current task below the exception 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
- *
- * must be called from interrupt context
- *
- * the structure of the saved context on the stack is :
- * r0, r1, r2, r3, r12, lr, pc, psr, r4, r5, r6, r7, r8, r9, r10, r11
- * exception frame <|> additional registers
- *
- * if using the FPU, then to store FPU context, add FP regs to the stack. in
- * this case the exception frame by default contains:
- * r0, r1, r2, r3, r12, lr, pc, psr,
- * s0 - s15, FPSCR, +1 word for 64-bit alignment
- * then in addition we store the following registers:
- * r4, r5, r6, r7, r8, r9, r10, r11
- * s16 - s31 (stored iff FP was used by the task (see EXC_RETURN[4]))
- * note that for the context switch to know if the next task has the extra FP
- * regs on the stack or not, we make use of the least significant bit of the
- * stack pointer. lsb of stack pointer is 1 if task has FP regs on stack, and
- * 0 otherwise.
- *
- */
-.global __switchto
-.thumb_func
-__switchto:
- mrs r3, psp @ get the task stack where the context has been saved
- ldr r2, [r1] @ get the new scheduled task stack pointer
- stmdb r3!, {r4-r11} @ save additional r4-r11 in the task stack
-
-#ifdef CONFIG_FPU
- tst lr, #(1<<4) @ test EXC_RETURN[4] for old task
- itt eq @ if EXC_RETURN[4] is zero, add FP regs to stack
- vstmdbeq r3!, {s16-s31}@ save additional FP s16-s31 in the task stack.
- @ if using lazy stacking, this will trigger saving
- @ s0-s15 in the reserved stack space.
- orreq r3, #1 @ set lsb of old stack pointer high to represent this
- @ task uses FPU. note stack pointer should be 64-bit
- @ aligned, so using this bit should be safe.
-
- tst r2, #1 @ test lsb of next stack pointer
- ittte ne @ if lsb is 1, then next task has FP regs on stack
- bicne r2, #1 @ clear lsb of new stack pointer
- bicne lr, #(1<<4) @ clear EXC_RETURN[4] for next task
- vldmiane r2!, {s16-s31}@ restore s16-s31 for the next task context
- orreq lr, #(1<<4) @ else if new stack doesn't use FP, set EXC_RETURN[4]
-#endif
-
- ldmia r2!, {r4-r11} @ restore r4-r11 for the next task context
- str r3, [r0] @ save the task stack pointer in its context
- msr psp, r2 @ set the process stack pointer to exception context
- bx lr @ return from exception
-
-/**
- * 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
-.thumb_func
-__task_start:
- ldr r2,=scratchpad @ area used as thread stack for the first switch
- mov r3, #2 @ use : priv. mode / thread stack / no floating point
- @ setting FP to unused here means first context switch
- @ will not store FP regs
- add r2, #17*4 @ put the pointer at the top of the stack
- mov r1, #0 @ __Schedule parameter : re-schedule nothing
- msr psp, r2 @ setup a thread stack up to the first context switch
- mov r2, #1
- isb @ ensure the write is done
- msr control, r3
- mov r3, r0
- mov r0, #0 @ __Schedule parameter : de-schedule nothing
- isb @ ensure the write is done
- str r2, [r3] @ Task scheduling is now active
- bl __schedule @ execute the task with the highest priority
- /* we should never return here */
- mov r0, #1 @ set to EC_ERROR_UNKNOWN
- bx lr
-
diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c
deleted file mode 100644
index bf0eb5b397..0000000000
--- a/core/cortex-m/task.c
+++ /dev/null
@@ -1,1088 +0,0 @@
-/* Copyright 2012 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 "link_defs.h"
-#include "panic.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
-CONFIG_CTS_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
- CONFIG_CTS_TASK_LIST
-};
-#undef TASK
-
-#ifdef CONFIG_TASK_PROFILING
-static uint64_t task_start_time; /* Time task scheduling started */
-/*
- * We only keep 32-bit values for exception start/end time, to avoid
- * accounting errors when we service interrupt when the timer wraps around.
- */
-static uint32_t exc_start_time; /* Time of task->exception transition */
-static uint32_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 void __switchto(task_ *from, task_ *to);
-extern int __task_start(int *task_stack_ready);
-
-#ifndef CONFIG_LOW_POWER_IDLE
-/* Idle task. Executed when no tasks are ready to be scheduled. */
-void __idle(void)
-{
- while (1) {
-#ifdef CHIP_NPCX
-
- /*
- * Using host access to make sure M4 core clock will
- * return when the eSPI accesses the Host modules if
- * CSAE bit is set. Please notice this symptom only
- * occurs at npcx5.
- */
-#if defined(CHIP_FAMILY_NPCX5) && defined(CONFIG_HOSTCMD_ESPI)
- /* Enable Host access wakeup */
- SET_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6);
-#endif
-
- /*
- * TODO (ML): A interrupt that occurs shortly before entering
- * idle mode starts getting services while the Core transitions
- * into idle mode. The results in a hard fault when the Core,
- * shortly therefore, resumes execution on exiting idle mode.
- * Workaround: Replace the idle function with the followings
- */
- asm (
- "cpsid i\n" /* Disable interrupt */
- "push {r0-r5}\n" /* Save needed registers */
- "wfi\n" /* Wait for int to enter idle */
- "ldm %0, {r0-r5}\n" /* Add a delay after WFI */
- "pop {r0-r5}\n" /* Restore regs before enabling ints */
- "isb\n" /* Flush the cpu pipeline */
- "cpsie i\n" :: "r" (0x100A8000) /* Enable interrupts */
- );
-#else
- /*
- * Wait for the next irq event. This stops the CPU clock
- * (sleep / deep sleep, depending on chip config).
- */
- asm("wfi");
-#endif
- }
-}
-#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
- CONFIG_CTS_TASK_LIST
-};
-#undef TASK
-
-/* Contexts for all tasks */
-static task_ tasks[TASK_ID_COUNT];
-
-/* Reset constants and state for all tasks */
-#define TASK_RESET_SUPPORTED BIT(31)
-#define TASK_RESET_LOCK BIT(30)
-#define TASK_RESET_STATE_MASK (TASK_RESET_SUPPORTED | TASK_RESET_LOCK)
-#define TASK_RESET_WAITERS_MASK ~TASK_RESET_STATE_MASK
-#define TASK_RESET_UNSUPPORTED 0
-#define TASK_RESET_STATE_LOCKED (TASK_RESET_SUPPORTED | TASK_RESET_LOCK)
-#define TASK_RESET_STATE_UNLOCKED TASK_RESET_SUPPORTED
-
-#ifdef CONFIG_TASK_RESET_LIST
-#define ENABLE_RESET(n) \
- [TASK_ID_##n] = TASK_RESET_SUPPORTED,
-static uint32_t task_reset_state[TASK_ID_COUNT] = {
-#ifdef CONFIG_TASK_RESET_LIST
- CONFIG_TASK_RESET_LIST
-#endif
-};
-#undef ENABLE_RESET
-#endif /* CONFIG_TASK_RESET_LIST */
-
-/* Validity checks about static task invariants */
-BUILD_ASSERT(TASK_ID_COUNT <= sizeof(unsigned) * 8);
-BUILD_ASSERT(TASK_ID_COUNT < (1 << (sizeof(task_id_t) * 8)));
-BUILD_ASSERT(BIT(TASK_ID_COUNT) < TASK_RESET_LOCK);
-
-/* 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
- CONFIG_CTS_TASK_LIST
-] __aligned(8);
-
-#undef TASK
-
-/* Reserve space to discard context on first context switch. */
-uint32_t scratchpad[17];
-
-static 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).
- */
-static int need_resched_or_profiling;
-
-/*
- * 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);
-
-static int start_called; /* Has task swapping started */
-
-static inline task_ *__task_id_to_ptr(task_id_t id)
-{
- return tasks + id;
-}
-
-void interrupt_disable(void)
-{
- asm("cpsid i");
-}
-
-void interrupt_enable(void)
-{
- asm("cpsie i");
-}
-
-inline int is_interrupt_enabled(void)
-{
- int primask;
-
- /* Interrupts are enabled when PRIMASK bit is 0 */
- asm("mrs %0, primask":"=r"(primask));
-
- return !(primask & 0x1);
-}
-
-inline int in_interrupt_context(void)
-{
- int ret;
- asm("mrs %0, ipsr \n" /* read exception number */
- "lsl %0, #23 \n":"=r"(ret)); /* exception bits are the 9 LSB */
- return ret;
-}
-
-#ifdef CONFIG_TASK_PROFILING
-static inline int get_interrupt_context(void)
-{
- int ret;
- asm("mrs %0, ipsr \n":"=r"(ret)); /* read exception number */
- return ret & 0x1ff; /* exception bits are the 9 LSB */
-}
-#endif
-
-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;
-}
-
-/**
- * Scheduling system call
- */
-void svc_handler(int desched, task_id_t resched)
-{
- task_ *current, *next;
-#ifdef CONFIG_TASK_PROFILING
- int exc = get_interrupt_context();
- uint32_t t;
-#endif
-
- /*
- * Push the priority to -1 until the return, to avoid being
- * interrupted.
- */
- asm volatile("cpsid f\n"
- "isb\n");
-
-#ifdef CONFIG_TASK_PROFILING
- /*
- * SVCall isn't triggered via DECLARE_IRQ(), so it needs to track its
- * start time explicitly.
- */
- if (exc == 0xb) {
- exc_start_time = get_time().le.lo;
- svc_calls++;
- }
-#endif
-
- current = current_task;
-
-#ifdef CONFIG_DEBUG_STACK_OVERFLOW
- if (*current->stack != STACK_UNUSED_VALUE) {
- panic_printf("\n\nStack overflow in %s task!\n",
- task_names[current - tasks]);
-#ifdef CONFIG_SOFTWARE_PANIC
- software_panic(PANIC_SW_STACK_OVERFLOW, current - tasks);
-#endif
- }
-#endif
-
- if (desched && !current->events) {
- /*
- * Remove our own ready bit (current - tasks is same as
- * task_get_current())
- */
- tasks_ready &= ~(1 << (current - tasks));
- }
- ASSERT(resched <= TASK_ID_COUNT);
- tasks_ready |= 1 << resched;
-
- ASSERT(tasks_ready & tasks_enabled);
- next = __task_id_to_ptr(__fls(tasks_ready & tasks_enabled));
-
-#ifdef CONFIG_TASK_PROFILING
- /* Track time in interrupts */
- t = get_time().le.lo;
- exc_total_time += (t - exc_start_time);
-
- /*
- * Bill the current task for time between the end of the last interrupt
- * and the start of this one.
- */
- current->runtime += (exc_start_time - exc_end_time);
- exc_end_time = t;
-#else
- /*
- * Don't chain here from interrupts until the next time an interrupt
- * sets an event.
- */
- need_resched_or_profiling = 0;
-#endif
-
- /* Nothing to do */
- if (next == current)
- return;
-
- /* Switch to new task */
-#ifdef CONFIG_TASK_PROFILING
- task_switches++;
-#endif
- current_task = next;
- __switchto(current, next);
-}
-
-void __schedule(int desched, int resched)
-{
- register int p0 asm("r0") = desched;
- register int p1 asm("r1") = resched;
-
- asm("svc 0"::"r"(p0),"r"(p1));
-}
-
-#ifdef CONFIG_TASK_PROFILING
-void __keep task_start_irq_handler(void *excep_return)
-{
- /*
- * Get time before checking depth, in case this handler is
- * pre-empted.
- */
- uint32_t t = get_time().le.lo;
- int irq = get_interrupt_context() - 16;
-
- /*
- * Track IRQ distribution. No need for atomic add, because an IRQ
- * can't pre-empt itself.
- */
- if (irq < ARRAY_SIZE(irq_dist))
- irq_dist[irq]++;
-
- /*
- * Continue iff a rescheduling event happened or profiling is active,
- * and we are not called from another exception (this must match the
- * logic for when we chain to svc_handler() below).
- */
- if (!need_resched_or_profiling || (((uint32_t)excep_return & 0xf) == 1))
- return;
-
- exc_start_time = t;
-}
-#endif
-
-void __keep task_resched_if_needed(void *excep_return)
-{
- /*
- * Continue iff a rescheduling event happened or profiling is active,
- * and we are not called from another exception.
- */
- if (!need_resched_or_profiling || (((uint32_t)excep_return & 0xf) == 1))
- return;
-
- svc_handler(0, 0);
-}
-
-static uint32_t __wait_evt(int timeout_us, task_id_t resched)
-{
- task_ *tsk = current_task;
- task_id_t me = tsk - tasks;
- uint32_t evt;
- int ret __attribute__((unused));
-
- /*
- * Scheduling task when interrupts are disabled will result in Forced
- * Hard Fault because:
- * - Disabling interrupt using 'cpsid i' also disables SVCall handler
- * (because it has configurable priority)
- * - Escalation to Hard Fault (also known as 'priority escalation')
- * occurs when handler for that fault is not enabled
- */
- ASSERT(is_interrupt_enabled());
- 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_clear(&tsk->events))) {
- /* Remove ourself and get the next task in the scheduler */
- __schedule(1, resched);
- resched = TASK_ID_IDLE;
- }
- if (timeout_us > 0) {
- timer_cancel(me);
- /* Ensure timer event is clear, we no longer care about it */
- atomic_clear_bits(&tsk->events, TASK_EVENT_TIMER);
- }
- return evt;
-}
-
-uint32_t task_set_event(task_id_t tskid, uint32_t event)
-{
- 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() || !is_interrupt_enabled()) {
- /* The receiver might run again */
- atomic_or(&tasks_ready, 1 << tskid);
-#ifndef CONFIG_TASK_PROFILING
- if (start_called)
- need_resched_or_profiling = 1;
-#endif
- } else {
- __schedule(0, tskid);
- }
-
- return 0;
-}
-
-uint32_t task_wait_event(int timeout_us)
-{
- return __wait_evt(timeout_us, TASK_ID_IDLE);
-}
-
-uint32_t 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;
-}
-
-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. */
- if (is_interrupt_enabled())
- __schedule(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_bits(&tasks_enabled, BIT(tskid));
-
- if (!in_interrupt_context() && is_interrupt_enabled() &&
- tskid == task_get_current())
- __schedule(0, 0);
-}
-
-void task_enable_irq(int irq)
-{
- CPU_NVIC_EN(irq / 32) = 1 << (irq % 32);
-}
-
-void __keep task_disable_irq(int irq)
-{
- CPU_NVIC_DIS(irq / 32) = 1 << (irq % 32);
-}
-
-void task_clear_pending_irq(int irq)
-{
- CPU_NVIC_UNPEND(irq / 32) = 1 << (irq % 32);
-}
-
-void task_trigger_irq(int irq)
-{
- CPU_NVIC_SWTRIG = irq;
-}
-
-static uint32_t init_task_context(task_id_t id)
-{
- uint32_t *sp;
- /* Stack size in words */
- uint32_t ssize = tasks_init[id].stack_size / 4;
-
- /*
- * Update stack used by first frame: 8 words for the normal
- * stack, plus 8 for R4-R11. Even if using FPU, the first frame
- * does not store FP regs.
- */
- sp = tasks[id].stack + ssize - 16;
- tasks[id].sp = (uint32_t)sp;
-
- /* Initial context on stack (see __switchto()) */
- sp[8] = tasks_init[id].r0; /* r0 */
- sp[13] = (uint32_t)task_exit_trap; /* lr */
- sp[14] = tasks_init[id].pc; /* pc */
- sp[15] = 0x01000000; /* psr */
-
- /* Fill unused stack; also used to detect stack overflow. */
- for (sp = tasks[id].stack; sp < (uint32_t *)tasks[id].sp; sp++)
- *sp = STACK_UNUSED_VALUE;
-
- return ssize;
-}
-
-#ifdef CONFIG_TASK_RESET_LIST
-
-/*
- * Re-initializes a task stack to its initial state, and marks it ready.
- * The task reset lock must be held prior to calling this function.
- */
-static void do_task_reset(task_id_t id)
-{
- interrupt_disable();
- init_task_context(id);
- tasks_ready |= 1 << id;
- /* TODO: Clear all pending events? */
- interrupt_enable();
-}
-
-/* We can't pass a parameter to a deferred call. Use this instead. */
-/* Mask of task IDs waiting to be reset. */
-static uint32_t deferred_reset_task_ids;
-
-/* Tasks may call this function if they want to reset themselves. */
-static void deferred_task_reset(void)
-{
- while (deferred_reset_task_ids) {
- task_id_t reset_id = __fls(deferred_reset_task_ids);
-
- atomic_clear_bits(&deferred_reset_task_ids, 1 << reset_id);
- do_task_reset(reset_id);
- }
-}
-DECLARE_DEFERRED(deferred_task_reset);
-
-/*
- * Helper for updating task_reset state atomically. Checks the current state,
- * and if it matches if_value, updates the state to new_value, and returns
- * TRUE.
- */
-static int update_reset_state(uint32_t *state,
- uint32_t if_value,
- uint32_t to_value)
-{
- int update;
-
- interrupt_disable();
- update = *state == if_value;
- if (update)
- *state = to_value;
- interrupt_enable();
-
- return update;
-}
-
-/*
- * Helper that acquires the reset lock iff it is not currently held.
- * Returns TRUE if the lock was acquired.
- */
-static inline int try_acquire_reset_lock(uint32_t *state)
-{
- return update_reset_state(state,
- /* if the lock is not held */
- TASK_RESET_STATE_UNLOCKED,
- /* acquire it */
- TASK_RESET_STATE_LOCKED);
-}
-
-/*
- * Helper that releases the reset lock iff it is currently held, and there
- * are no pending resets. Returns TRUE if the lock was released.
- */
-static inline int try_release_reset_lock(uint32_t *state)
-{
- return update_reset_state(state,
- /* if the lock is held, with no waiters */
- TASK_RESET_STATE_LOCKED,
- /* release it */
- TASK_RESET_STATE_UNLOCKED);
-}
-
-/*
- * Helper to cause the current task to sleep indefinitely; useful if the
- * calling task just needs to block until it is reset.
- */
-static inline void sleep_forever(void)
-{
- while (1)
- usleep(-1);
-}
-
-void task_enable_resets(void)
-{
- task_id_t id = task_get_current();
- uint32_t *state = &task_reset_state[id];
-
- if (*state == TASK_RESET_UNSUPPORTED) {
- cprints(CC_TASK,
- "%s called from non-resettable task, id: %d",
- __func__, id);
- return;
- }
-
- /*
- * A correctly written resettable task will only call this function
- * if resets are currently disabled; this implies that this task
- * holds the reset lock.
- */
-
- if (*state == TASK_RESET_STATE_UNLOCKED) {
- cprints(CC_TASK,
- "%s called, but resets already enabled, id: %d",
- __func__, id);
- return;
- }
-
- /*
- * Attempt to release the lock. If we cannot, it means there are tasks
- * waiting for a reset.
- */
- if (try_release_reset_lock(state))
- return;
-
- /* People are waiting for us to reset; schedule a reset. */
- atomic_or(&deferred_reset_task_ids, 1 << id);
- /*
- * This will always trigger a deferred call after our new ID was
- * written. If the hook call is currently executing, it will run
- * again.
- */
- hook_call_deferred(&deferred_task_reset_data, 0);
- /* Wait to be reset. */
- sleep_forever();
-}
-
-void task_disable_resets(void)
-{
- task_id_t id = task_get_current();
- uint32_t *state = &task_reset_state[id];
-
- if (*state == TASK_RESET_UNSUPPORTED) {
- cprints(CC_TASK,
- "%s called from non-resettable task, id %d",
- __func__, id);
- return;
- }
-
- /*
- * A correctly written resettable task will only call this function
- * if resets are currently enabled; this implies that this task does
- * not hold the reset lock.
- */
-
- if (try_acquire_reset_lock(state))
- return;
-
- /*
- * If we can't acquire the lock, we are about to be reset by another
- * task.
- */
- sleep_forever();
-}
-
-int task_reset_cleanup(void)
-{
- task_id_t id = task_get_current();
- uint32_t *state = &task_reset_state[id];
-
- /*
- * If the task has never started before, state will be
- * TASK_RESET_ENABLED.
- *
- * If the task was reset, the TASK_RESET_LOCK bit will be set, and
- * there may additionally be bits representing tasks we must notify
- * that we have reset.
- */
-
- /*
- * Only this task can unset the lock bit so we can read this safely,
- * even though other tasks may be modifying the state to add themselves
- * as waiters.
- */
- int cleanup_req = *state & TASK_RESET_LOCK;
-
- /*
- * Attempt to release the lock. We can only do this when there are no
- * tasks waiting to be notified that we have been reset, so we loop
- * until no tasks are waiting.
- *
- * Other tasks may still be trying to reset us at this point; if they
- * do, they will add themselves to the list of tasks we must notify. We
- * will simply notify them (multiple times if necessary) until we are
- * free to unlock.
- */
- if (cleanup_req) {
- while (!try_release_reset_lock(state)) {
- /* Find the first waiter to notify. */
- task_id_t notify_id = __fls(
- *state & TASK_RESET_WAITERS_MASK);
- /*
- * Remove the task from waiters first, so that
- * when it wakes after being notified, it is in
- * a consistent state (it should not be waiting
- * to be notified and running).
- * After being notified, the task may try to
- * reset us again; if it does, it will just add
- * itself back to the list of tasks to notify,
- * and we will notify it again.
- */
- atomic_clear_bits(state, 1 << notify_id);
- /*
- * Skip any invalid ids set by tasks that
- * requested a non-blocking reset.
- */
- if (notify_id < TASK_ID_COUNT)
- task_set_event(notify_id,
- TASK_EVENT_RESET_DONE);
- }
- }
-
- return cleanup_req;
-}
-
-int task_reset(task_id_t id, int wait)
-{
- task_id_t current = task_get_current();
- uint32_t *state = &task_reset_state[id];
- uint32_t waiter_id;
- int resets_disabled;
-
- if (id == current)
- return EC_ERROR_INVAL;
-
- /*
- * This value is only set at compile time, and will never be modified.
- */
- if (*state == TASK_RESET_UNSUPPORTED)
- return EC_ERROR_INVAL;
-
- /*
- * If we are not blocking for reset, we use an invalid task id to notify
- * the task that _someone_ wanted it to reset, but didn't want to be
- * notified when the reset is complete.
- */
- waiter_id = 1 << (wait ? current : TASK_ID_COUNT);
-
- /*
- * Try and take the lock. If we can't have it, just notify the task we
- * tried; it will reset itself when it next tries to release the lock.
- */
- interrupt_disable();
- resets_disabled = *state & TASK_RESET_LOCK;
- if (resets_disabled)
- *state |= waiter_id;
- else
- *state |= TASK_RESET_LOCK;
- interrupt_enable();
-
- if (!resets_disabled) {
- /* We got the lock, do the reset immediately. */
- do_task_reset(id);
- } else if (wait) {
- /*
- * We couldn't get the lock, and have been asked to block for
- * reset. We have asked the task to reset itself; it will notify
- * us when it has.
- */
- task_wait_event_mask(TASK_EVENT_RESET_DONE, -1);
- }
-
- return EC_SUCCESS;
-}
-
-#endif /* CONFIG_TASK_RESET_LIST */
-
-/*
- * Initialize IRQs in the NVIC and set their priorities as defined by the
- * DECLARE_IRQ statements.
- */
-static void __nvic_init_irqs(void)
-{
- /* Get the IRQ priorities section from the linker */
- int exc_calls = __irqprio_end - __irqprio;
- int i;
-
- /* Mask and clear all pending interrupts */
- for (i = 0; i < 5; i++) {
- CPU_NVIC_DIS(i) = 0xffffffff;
- CPU_NVIC_UNPEND(i) = 0xffffffff;
- }
-
- /*
- * 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++) {
- cpu_set_interrupt_priority(__irqprio[i].irq,
- __irqprio[i].priority);
- }
-}
-
-void mutex_lock(struct mutex *mtx)
-{
- uint32_t value;
- uint32_t id;
-
- /*
- * mutex_lock() must not be used in interrupt context (because we wait
- * if there is contention).
- */
- ASSERT(!in_interrupt_context());
-
- /*
- * Task ID is not valid before task_start() (since current_task is
- * scratchpad), and no need for mutex locking before task switching has
- * begun.
- */
- if (!task_start_called())
- return;
-
- id = 1 << task_get_current();
-
- atomic_or(&mtx->waiters, id);
-
- do {
- /* Try to get the lock (set 1 into the lock field) */
- __asm__ __volatile__(" ldrex %0, [%1]\n"
- " teq %0, #0\n"
- " it eq\n"
- " strexeq %0, %2, [%1]\n"
- : "=&r" (value)
- : "r" (&mtx->lock), "r" (2) : "cc");
- /*
- * "value" is equals to 1 if the store conditional failed,
- * 2 if somebody else owns the mutex, 0 else.
- */
- if (value == 2)
- /* Contention on the mutex */
- task_wait_event_mask(TASK_EVENT_MUTEX, 0);
- } while (value);
-
- atomic_clear_bits(&mtx->waiters, id);
-}
-
-void mutex_unlock(struct mutex *mtx)
-{
- uint32_t waiters;
- task_ *tsk = current_task;
-
- /*
- * Add a critical section to keep the unlock and the snapshotting of
- * waiters atomic in case a task switching occurs between them.
- */
- interrupt_disable();
- waiters = mtx->waiters;
- mtx->lock = 0;
- interrupt_enable();
-
- while (waiters) {
- task_id_t id = __fls(waiters);
- waiters &= ~BIT(id);
-
- /* Somebody is waiting on the mutex */
- task_set_event(id, TASK_EVENT_MUTEX);
- }
-
- /* Ensure no event is remaining from mutex wake-up */
- atomic_clear_bits(&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_SAFE_CONSOLE_COMMAND(taskinfo, command_task_info,
- NULL,
- "Print task info");
-
-#ifdef CONFIG_CMD_TASKREADY
-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);
- }
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(taskready, command_task_ready,
- "[setmask]",
- "Print/set ready tasks");
-#endif
-
-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++) {
- tasks[i].stack = stack_next;
- stack_next += init_task_context(i);
- }
-
- /*
- * 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 */
- __nvic_init_irqs();
-}
-
-void task_clear_fp_used(void)
-{
- int ctrl;
-
- /* Clear the CONTROL.FPCA bit, which represents FP context active. */
- asm volatile("mrs %0, control" : "=r"(ctrl));
- ctrl &= ~0x4;
- asm volatile("msr control, %0" : : "r"(ctrl));
-
- /* Flush pipeline before returning. */
- asm volatile("isb");
-}
-
-int task_start(void)
-{
-#ifdef CONFIG_TASK_PROFILING
- timestamp_t t = get_time();
-
- task_start_time = t.val;
- exc_end_time = t.le.lo;
-#endif
- start_called = 1;
-
- return __task_start(&need_resched_or_profiling);
-}
-
-#ifdef CONFIG_CMD_TASK_RESET
-static int command_task_reset(int argc, char **argv)
-{
- task_id_t id;
- char *e;
-
- if (argc == 2) {
- id = strtoi(argv[1], &e, 10);
- if (*e)
- return EC_ERROR_PARAM1;
- ccprintf("Resetting task %d\n", id);
- return task_reset(id, 1);
- }
-
- return EC_ERROR_PARAM_COUNT;
-}
-DECLARE_CONSOLE_COMMAND(taskreset, command_task_reset,
- "task_id",
- "Reset a task");
-#endif /* CONFIG_CMD_TASK_RESET */
diff --git a/core/cortex-m/uldivmod.S b/core/cortex-m/uldivmod.S
deleted file mode 120000
index 7047a8c5d4..0000000000
--- a/core/cortex-m/uldivmod.S
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/libaeabi-cortexm0/core/cortex-m/uldivmod.S \ No newline at end of file
diff --git a/core/cortex-m/vecttable.c b/core/cortex-m/vecttable.c
deleted file mode 100644
index 10b4b22422..0000000000
--- a/core/cortex-m/vecttable.c
+++ /dev/null
@@ -1,400 +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.
- *
- * Cortex-M CPU vector table
- */
-
-#ifndef ___INIT
-#define ___INIT
-#include "config.h"
-#include <task.h>
-#endif
-
-typedef void (*func)(void);
-
-#ifndef PASS
-#define PASS 1
-#endif
-
-#if PASS == 1
-/* Default exception handler */
-void __attribute__((used, naked)) default_handler(void);
-void default_handler()
-{
- asm(
- ".thumb_func\n"
- " b exception_panic"
- );
-}
-
-#define table(x) x
-
-#define weak_with_default __attribute__((used,weak,alias("default_handler")))
-
-#define vec(name) extern void weak_with_default name ## _handler(void);
-#define irq(num) vec(irq_ ## num)
-
-#define item(name) extern void name(void);
-#define null
-
-extern void stack_end(void); /* not technically correct, it's just a pointer */
-extern void reset(void);
-
-#pragma GCC diagnostic push
-#if __GNUC__ >= 8
-#pragma GCC diagnostic ignored "-Wattribute-alias"
-#endif
-/* Call default_handler if svc_handler is not found (task.c is not built) */
-void weak_with_default svc_handler(int desched, task_id_t resched);
-#pragma GCC diagnostic pop
-
-/*
- * SVC handler helper
- *
- * Work around issue where a late exception can corrupt r0 to r3,
- * see section 2.7 (svc) of Cortex-M3 Application Note 179:
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0179b/AppsNote179.pdf
- *
- * This approach differs slightly from the one in the document,
- * it only loads r0 (desched) and r1 (resched) for svc_handler.
- */
-void __attribute__((used,naked)) svc_helper_handler(void);
-void svc_helper_handler()
-{
- asm(
- ".thumb_func\n"
- " tst lr, #4 /* see if called from supervisor mode */\n"
- " mrs r2, msp /* get the correct stack pointer into r2 */\n"
- " it ne\n"
- " mrsne r2, psp\n"
- " ldr r1, [r2, #4] /* get regs from stack frame */\n"
- " ldr r0, [r2]\n"
- " b %0 /* call svc_handler */\n"
- :
- : "i"(svc_handler)
- );
-}
-
-#endif /* PASS 1 */
-
-#if PASS == 2
-#undef table
-#undef vec
-#undef irq
-#undef item
-#undef null
-
-/* number of elements before the first irq vector */
-#define IRQ_OFFSET 16
-/* element in the table that is null: extra IRQs are routed there,
- * then finally overwritten
- */
-#define IRQ_UNUSED_OFFSET 8
-
-/* Disable warning that "initializer overrides prior initialization of this
- * subobject", since we are explicitly doing this to handle the unused IRQs.
- */
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Winitializer-overrides"
-#endif /* __clang__ */
-
-#define table(x) \
- const func vectors[] __attribute__((section(".text.vecttable"))) = { \
- x \
- [IRQ_UNUSED_OFFSET] = null \
- };
-
-#define vec(name) name ## _handler,
-#define irq(num) [num < CONFIG_IRQ_COUNT ? num + IRQ_OFFSET : IRQ_UNUSED_OFFSET] = vec(irq_ ## num)
-
-#define item(name) name,
-#define null (void*)0,
-#endif /* PASS 2 */
-
-table(
- item(stack_end)
- item(reset)
- vec(nmi)
- vec(hard_fault)
- vec(mpu_fault)
- vec(bus_fault)
- vec(usage_fault)
- null
- null
- null
- null
- item(svc_helper_handler)
- vec(debug)
- null
- vec(pendsv)
- vec(sys_tick)
- irq(0)
- irq(1)
- irq(2)
- irq(3)
- irq(4)
- irq(5)
- irq(6)
- irq(7)
- irq(8)
- irq(9)
- irq(10)
- irq(11)
- irq(12)
- irq(13)
- irq(14)
- irq(15)
- irq(16)
- irq(17)
- irq(18)
- irq(19)
- irq(20)
- irq(21)
- irq(22)
- irq(23)
- irq(24)
- irq(25)
- irq(26)
- irq(27)
- irq(28)
- irq(29)
- irq(30)
- irq(31)
- irq(32)
- irq(33)
- irq(34)
- irq(35)
- irq(36)
- irq(37)
- irq(38)
- irq(39)
- irq(40)
- irq(41)
- irq(42)
- irq(43)
- irq(44)
- irq(45)
- irq(46)
- irq(47)
- irq(48)
- irq(49)
- irq(50)
- irq(51)
- irq(52)
- irq(53)
- irq(54)
- irq(55)
- irq(56)
- irq(57)
- irq(58)
- irq(59)
- irq(60)
- irq(61)
- irq(62)
- irq(63)
- irq(64)
- irq(65)
- irq(66)
- irq(67)
- irq(68)
- irq(69)
- irq(70)
- irq(71)
- irq(72)
- irq(73)
- irq(74)
- irq(75)
- irq(76)
- irq(77)
- irq(78)
- irq(79)
- irq(80)
- irq(81)
- irq(82)
- irq(83)
- irq(84)
- irq(85)
- irq(86)
- irq(87)
- irq(88)
- irq(89)
- irq(90)
- irq(91)
- irq(92)
- irq(93)
- irq(94)
- irq(95)
- irq(96)
- irq(97)
- irq(98)
- irq(99)
- irq(100)
- irq(101)
- irq(102)
- irq(103)
- irq(104)
- irq(105)
- irq(106)
- irq(107)
- irq(108)
- irq(109)
- irq(110)
- irq(111)
- irq(112)
- irq(113)
- irq(114)
- irq(115)
- irq(116)
- irq(117)
- irq(118)
- irq(119)
- irq(120)
- irq(121)
- irq(122)
- irq(123)
- irq(124)
- irq(125)
- irq(126)
- irq(127)
- irq(128)
- irq(129)
- irq(130)
- irq(131)
- irq(132)
- irq(133)
- irq(134)
- irq(135)
- irq(136)
- irq(137)
- irq(138)
- irq(139)
- irq(140)
- irq(141)
- irq(142)
- irq(143)
- irq(144)
- irq(145)
- irq(146)
- irq(147)
- irq(148)
- irq(149)
- irq(150)
- irq(151)
- irq(152)
- irq(153)
- irq(154)
- irq(155)
- irq(156)
- irq(157)
- irq(158)
- irq(159)
- irq(160)
- irq(161)
- irq(162)
- irq(163)
- irq(164)
- irq(165)
- irq(166)
- irq(167)
- irq(168)
- irq(169)
- irq(170)
- irq(171)
- irq(172)
- irq(173)
- irq(174)
- irq(175)
- irq(176)
- irq(177)
- irq(178)
- irq(179)
- irq(180)
- irq(181)
- irq(182)
- irq(183)
- irq(184)
- irq(185)
- irq(186)
- irq(187)
- irq(188)
- irq(189)
- irq(190)
- irq(191)
- irq(192)
- irq(193)
- irq(194)
- irq(195)
- irq(196)
- irq(197)
- irq(198)
- irq(199)
- irq(200)
- irq(201)
- irq(202)
- irq(203)
- irq(204)
- irq(205)
- irq(206)
- irq(207)
- irq(208)
- irq(209)
- irq(210)
- irq(211)
- irq(212)
- irq(213)
- irq(214)
- irq(215)
- irq(216)
- irq(217)
- irq(218)
- irq(219)
- irq(220)
- irq(221)
- irq(222)
- irq(223)
- irq(224)
- irq(225)
- irq(226)
- irq(227)
- irq(228)
- irq(229)
- irq(230)
- irq(231)
- irq(232)
- irq(233)
- irq(234)
- irq(235)
- irq(236)
- irq(237)
- irq(238)
- irq(239)
- irq(240)
- irq(241)
- irq(242)
- irq(243)
- irq(244)
- irq(245)
- irq(246)
- irq(247)
- irq(248)
- irq(249)
- irq(250)
- irq(251)
- irq(252)
- irq(253)
- irq(254)
-)
-
-#if PASS == 2
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif /* __clang__ */
-#endif
-
-#if PASS == 1
-#undef PASS
-#define PASS 2
-#include "vecttable.c"
-#endif
diff --git a/core/cortex-m/watchdog.c b/core/cortex-m/watchdog.c
deleted file mode 100644
index c9faf54b2b..0000000000
--- a/core/cortex-m/watchdog.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright 2012 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.
- */
-
-/* Watchdog common code */
-
-#include "common.h"
-#include "cpu.h"
-#include "panic.h"
-#include "task.h"
-#include "timer.h"
-#include "watchdog.h"
-
-/*
- * As defined by Armv7-M Reference Manual B1.5.6 "Exception Entry Behavior",
- * the structure of the saved context on the stack is:
- * r0, r1, r2, r3, r12, lr, pc, psr, ...
- */
-#define STACK_IDX_REG_LR 5
-#define STACK_IDX_REG_PC 6
-
-void __keep watchdog_trace(uint32_t excep_lr, uint32_t excep_sp)
-{
- uint32_t psp;
- uint32_t *stack;
-
- asm("mrs %0, psp" : "=r"(psp));
- if ((excep_lr & 0xf) == 1) {
- /* we were already in exception context */
- stack = (uint32_t *)excep_sp;
- } else {
- /* we were in task context */
- stack = (uint32_t *)psp;
- }
-
- panic_set_reason(PANIC_SW_WATCHDOG, stack[STACK_IDX_REG_PC],
- (excep_lr & 0xf) == 1 ? 0xff : task_get_current());
-
- /*
- * This is our last breath, the last opportunity to sort out all
- * matters. Flush and invalidate D-cache if cache enabled.
- */
- if (IS_ENABLED(CONFIG_ARMV7M_CACHE))
- cpu_clean_invalidate_dcache();
-
- panic_printf("### WATCHDOG PC=%08x / LR=%08x / pSP=%08x ",
- stack[STACK_IDX_REG_PC], stack[STACK_IDX_REG_LR], psp);
- if ((excep_lr & 0xf) == 1)
- panic_puts("(exc) ###\n");
- else
- panic_printf("(task %d) ###\n", task_get_current());
-
- /* If we are blocked in a high priority IT handler, the following debug
- * messages might not appear but they are useless in that situation. */
- timer_print_info();
- task_print_list();
-}
diff --git a/core/cortex-m0/__builtin.c b/core/cortex-m0/__builtin.c
deleted file mode 100644
index 4bf495a011..0000000000
--- a/core/cortex-m0/__builtin.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright 2019 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/cortex-m0/atomic.h b/core/cortex-m0/atomic.h
deleted file mode 100644
index 0c58e71e41..0000000000
--- a/core/cortex-m0/atomic.h
+++ /dev/null
@@ -1,73 +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.
- */
-
-/* Atomic operations for ARMv6-M */
-
-#ifndef __CROS_EC_ATOMIC_H
-#define __CROS_EC_ATOMIC_H
-
-#include "common.h"
-
-typedef int atomic_t;
-typedef atomic_t atomic_val_t;
-
-/**
- * Implements atomic arithmetic operations on 32-bit integers.
- *
- * There is no load/store exclusive on ARMv6-M, just disable interrupts
- */
-#define ATOMIC_OP(asm_op, a, v) \
-({ \
- uint32_t reg0, reg1; \
- \
- __asm__ __volatile__(" cpsid i\n" \
- " ldr %0, [%2]\n" \
- " mov %1, %0\n" \
- #asm_op" %0, %0, %3\n" \
- " str %0, [%2]\n" \
- " cpsie i\n" \
- : "=&l"(reg0), "=&l"(reg1) \
- : "l"(a), "r"(v) \
- : "cc", "memory"); \
- reg1; \
-})
-
-static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits)
-{
- return ATOMIC_OP(bic, addr, bits);
-}
-
-static inline atomic_val_t atomic_or(atomic_t *addr, atomic_val_t bits)
-{
- return ATOMIC_OP(orr, addr, bits);
-}
-
-static inline atomic_val_t atomic_add(atomic_t *addr, atomic_val_t value)
-{
- return ATOMIC_OP(add, addr, value);
-}
-
-static inline atomic_val_t atomic_sub(atomic_t *addr, atomic_val_t value)
-{
- return ATOMIC_OP(sub, addr, value);
-}
-
-static inline atomic_val_t atomic_clear(atomic_t *addr)
-{
- atomic_t ret;
-
- __asm__ __volatile__(" mov %2, #0\n"
- " cpsid i\n"
- " ldr %0, [%1]\n"
- " str %2, [%1]\n"
- " cpsie i\n"
- : "=&l" (ret)
- : "l" (addr), "r" (0)
- : "cc", "memory");
-
- return ret;
-}
-
-#endif /* __CROS_EC_ATOMIC_H */
diff --git a/core/cortex-m0/build.mk b/core/cortex-m0/build.mk
deleted file mode 100644
index b0136f347e..0000000000
--- a/core/cortex-m0/build.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- makefile -*-
-# 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.
-#
-# Cortex-M0 core OS files build
-#
-
-# Use coreboot-sdk
-$(call set-option,CROSS_COMPILE,\
- $(CROSS_COMPILE_arm),\
- /opt/coreboot-sdk/bin/arm-eabi-)
-
-# CPU specific compilation flags
-CFLAGS_CPU+=-mthumb -Os -mno-sched-prolog
-CFLAGS_CPU+=-mno-unaligned-access
-
-ifneq ($(CONFIG_LTO),)
-CFLAGS_CPU+=-flto
-LDFLAGS_EXTRA+=-flto
-endif
-
-core-y=cpu.o debug.o init.o thumb_case.o div.o lmul.o ldivmod.o mula.o uldivmod.o
-core-y+=vecttable.o __builtin.o
-core-$(CONFIG_COMMON_PANIC_OUTPUT)+=panic.o
-core-$(CONFIG_COMMON_RUNTIME)+=switch.o task.o
-
-dirs-y += core/$(CORE)/curve25519
-
-core-$(CONFIG_CURVE25519)+=curve25519/mpy121666.o
-core-$(CONFIG_CURVE25519)+=curve25519/reduce25519.o
-core-$(CONFIG_CURVE25519)+=curve25519/mul.o
-core-$(CONFIG_CURVE25519)+=curve25519/scalarmult.o
-core-$(CONFIG_CURVE25519)+=curve25519/sqr.o
-
-core-$(CONFIG_WATCHDOG)+=watchdog.o
diff --git a/core/cortex-m0/config_core.h b/core/cortex-m0/config_core.h
deleted file mode 100644
index c31adc471c..0000000000
--- a/core/cortex-m0/config_core.h
+++ /dev/null
@@ -1,20 +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.
- */
-
-#ifndef __CROS_EC_CONFIG_CORE_H
-#define __CROS_EC_CONFIG_CORE_H
-
-/* Linker binary architecture and format */
-#define BFD_ARCH arm
-#define BFD_FORMAT "elf32-littlearm"
-
-/* Emulate the CLZ/CTZ instructions since the CPU core is lacking support */
-#define CONFIG_SOFTWARE_CLZ
-#define CONFIG_SOFTWARE_CTZ
-#define CONFIG_SOFTWARE_PANIC
-
-#define CONFIG_ASSEMBLY_MULA32
-
-#endif /* __CROS_EC_CONFIG_CORE_H */
diff --git a/core/cortex-m0/cpu.c b/core/cortex-m0/cpu.c
deleted file mode 100644
index b354cc03e2..0000000000
--- a/core/cortex-m0/cpu.c
+++ /dev/null
@@ -1,20 +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.
- *
- * Set up the Cortex-M0 core
- */
-
-#include "cpu.h"
-
-void cpu_init(void)
-{
- /* Catch unaligned access */
- CPU_NVIC_CCR |= CPU_NVIC_CCR_UNALIGN_TRAP;
-
- /* Set supervisor call (SVC) to priority 0 */
- CPU_NVIC_SHCSR2 = 0;
-
- /* Set lowest priority for PendSV */
- CPU_NVIC_SHCSR3 = (0xff << 16);
-}
diff --git a/core/cortex-m0/cpu.h b/core/cortex-m0/cpu.h
deleted file mode 100644
index ac184090f9..0000000000
--- a/core/cortex-m0/cpu.h
+++ /dev/null
@@ -1,58 +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.
- *
- * Registers map and definitions for Cortex-M0 processor
- */
-
-#ifndef __CROS_EC_CPU_H
-#define __CROS_EC_CPU_H
-
-#include <stdint.h>
-#include "compile_time_macros.h"
-
-/* Macro to access 32-bit registers */
-#define CPUREG(addr) (*(volatile uint32_t*)(addr))
-
-/* Nested Vectored Interrupt Controller */
-#define CPU_NVIC_EN(x) CPUREG(0xe000e100)
-#define CPU_NVIC_DIS(x) CPUREG(0xe000e180)
-#define CPU_NVIC_UNPEND(x) CPUREG(0xe000e280)
-#define CPU_NVIC_ISPR(x) CPUREG(0xe000e200)
-#define CPU_NVIC_PRI(x) CPUREG(0xe000e400 + 4 * (x))
-
-/* System Control Block */
-#define CPU_SCB_ICSR CPUREG(0xe000ed04)
-
-/* SCB AIRCR : Application interrupt and reset control register */
-#define CPU_NVIC_APINT CPUREG(0xe000ed0c)
-#define CPU_NVIC_APINT_SYSRST BIT(2) /* System reset request */
-#define CPU_NVIC_APINT_ENDIAN BIT(15) /* Endianness */
-#define CPU_NVIC_APINT_KEY_RD (0U)
-#define CPU_NVIC_APINT_KEY_WR (0x05FAU << 16)
-/* SCB SCR : System Control Register */
-#define CPU_SCB_SYSCTRL CPUREG(0xe000ed10)
-#define CPU_NVIC_CCR CPUREG(0xe000ed14)
-#define CPU_NVIC_SHCSR2 CPUREG(0xe000ed1c)
-#define CPU_NVIC_SHCSR3 CPUREG(0xe000ed20)
-
-#define CPU_NVIC_CCR_UNALIGN_TRAP BIT(3)
-
-/* Set up the cpu to detect faults */
-void cpu_init(void);
-
-/* Set the priority of the given IRQ in the NVIC (0 is highest). */
-static inline void cpu_set_interrupt_priority(uint8_t irq, uint8_t priority)
-{
- const uint32_t prio_shift = irq % 4 * 8 + 6;
-
- if (priority > 3)
- priority = 3;
-
- CPU_NVIC_PRI(irq / 4) =
- (CPU_NVIC_PRI(irq / 4) &
- ~(3 << prio_shift)) |
- (priority << prio_shift);
-}
-
-#endif /* __CROS_EC_CPU_H */
diff --git a/core/cortex-m0/curve25519 b/core/cortex-m0/curve25519
deleted file mode 120000
index ee9cb3b4a9..0000000000
--- a/core/cortex-m0/curve25519
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/unacl-curve25519/core/cortex-m0/curve25519 \ No newline at end of file
diff --git a/core/cortex-m0/debug.c b/core/cortex-m0/debug.c
deleted file mode 120000
index 3cada87897..0000000000
--- a/core/cortex-m0/debug.c
+++ /dev/null
@@ -1 +0,0 @@
-../cortex-m/debug.c \ No newline at end of file
diff --git a/core/cortex-m0/debug.h b/core/cortex-m0/debug.h
deleted file mode 120000
index d79be16190..0000000000
--- a/core/cortex-m0/debug.h
+++ /dev/null
@@ -1 +0,0 @@
-../cortex-m/debug.h \ No newline at end of file
diff --git a/core/cortex-m0/div.S b/core/cortex-m0/div.S
deleted file mode 120000
index 776b7d2405..0000000000
--- a/core/cortex-m0/div.S
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/libaeabi-cortexm0/core/cortex-m0/div.S \ No newline at end of file
diff --git a/core/cortex-m0/ec.lds.S b/core/cortex-m0/ec.lds.S
deleted file mode 100644
index bc461b90de..0000000000
--- a/core/cortex-m0/ec.lds.S
+++ /dev/null
@@ -1,360 +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.
- */
-
-#include "config.h"
-#include "rwsig.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
-{
-#ifdef CONFIG_SHAREDLIB
- SHARED_LIB (rx) : ORIGIN = FW_OFF(SHAREDLIB),
- LENGTH = FW_SIZE(SHAREDLIB)
-#endif
- FLASH (rx) : ORIGIN = FW_OFF(SECTION), LENGTH = FW_SIZE(SECTION)
- IRAM (rw) : ORIGIN = CONFIG_RAM_BASE, LENGTH = CONFIG_RAM_SIZE
-
-#ifdef CONFIG_CHIP_MEMORY_REGIONS
-#define REGION(name, attr, start, size) \
- name(attr) : ORIGIN = (start), LENGTH = (size)
-#include "memory_regions.inc"
-#undef REGION
-#endif /* CONFIG_MEMORY_REGIONS */
-}
-
-SECTIONS
-{
-#ifdef CONFIG_SHAREDLIB
- .roshared : {
- KEEP(*(.roshared*))
- } > SHARED_LIB
-#endif
- .text : {
- *(.text.vecttable)
- . = ALIGN(4);
- __image_data_offset = .;
- KEEP(*(.rodata.ver))
-
- . = ALIGN(4);
- KEEP(*(.rodata.pstate))
-
- . = ALIGN(4);
- STRINGIFY(OUTDIR/core/CORE/init.o) (.text)
- *(.text*)
- } > FLASH
-
- . = ALIGN(4);
- .rodata : {
- /* Symbols defined here are declared in link_defs.h */
- __irqprio = .;
- KEEP(*(.rodata.irqprio))
- __irqprio_end = .;
-
- . = ALIGN(4);
- __cmds = .;
- KEEP(*(SORT(.rodata.cmds*)))
- __cmds_end = .;
-
- . = ALIGN(4);
- __extension_cmds = .;
- KEEP(*(.rodata.extensioncmds))
- __extension_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 = .;
-
-#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK
- __hooks_chipset_resume_init = .;
- KEEP(*(.rodata.HOOK_CHIPSET_RESUME_INIT))
- __hooks_chipset_resume_init_end = .;
-
- __hooks_chipset_suspend_complete = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SUSPEND_COMPLETE))
- __hooks_chipset_suspend_complete_end = .;
-#endif
-
- __hooks_chipset_shutdown = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN))
- __hooks_chipset_shutdown_end = .;
-
- __hooks_chipset_shutdown_complete = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN_COMPLETE))
- __hooks_chipset_shutdown_complete_end = .;
-
- __hooks_chipset_hard_off = .;
- KEEP(*(.rodata.HOOK_CHIPSET_HARD_OFF))
- __hooks_chipset_hard_off_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 = .;
-
- __usb_desc = .;
- KEEP(*(.rodata.usb_desc_conf))
- KEEP(*(SORT(.rodata.usb_desc*)))
- __usb_desc_end = .;
- . = ALIGN(4);
- KEEP(*(.rodata.usb_ep))
- KEEP(*(.rodata.usb_ep.usb_ep_tx))
- KEEP(*(.rodata.usb_ep.usb_ep_rx))
- KEEP(*(.rodata.usb_ep.usb_ep_event))
- KEEP(*(.rodata.usb_ep.usb_iface_request))
-
- . = ALIGN(4);
- *(.rodata*)
-
-#ifdef CONFIG_CHIP_INIT_ROM_REGION
- ASSERT(0, "CONFIG_CHIP_INIT_ROM_REGION not supported by linker script")
-#endif /* CONFIG_CHIP_INIT_ROM_REGION */
- /*
- * This linker file does not yet support a separate ROM resident
- * section. Ensure the corresponding data objects are linked
- * into the .rodata section.
- */
- . = ALIGN(4);
- __init_rom_start = .;
- *(.init.rom)
- __init_rom_end = .;
-
-#if defined(SECTION_IS_RO) && defined(CONFIG_FLASH_CROS)
- . = ALIGN(64);
- KEEP(*(.google))
-#endif
- . = ALIGN(4);
- } > FLASH
-
- __data_lma_start = . ;
- .vtable : {
- /*
- * Vector table must be at the base of SRAM. The vector
- * table section contains a RAM copy of the vector table used on
- * STM chips for relocating the vector table.
- */
- . = ALIGN(8);
- *(.bss.vector_table)
- . = ALIGN(8);
- } > IRAM
-
-#ifdef CONFIG_PRESERVE_LOGS
- .preserve_logs(NOLOAD) : {
- /*
- * The size of the vector table is fixed. Thus, the address of
- * the preserved logs is also fixed.
- */
- . = ALIGN(8);
- *(SORT(.preserved_logs.*))
- . = ALIGN(8);
- __preserved_logs_end = .;
- } > IRAM
-
- ASSERT((SIZEOF(.vtable) + SIZEOF(.preserve_logs) + CONFIG_RAM_BASE) ==
- __preserved_logs_end,
- "preserve_logs must be right after vtable")
-#endif
-
- .bss : {
- . = ALIGN(8);
- __bss_start = .;
- /* Stacks must be 64-bit aligned */
- . = 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. The 8 byte alignment of
- * uint64_t is required by the ARM ABI.
- */
- . = ALIGN(8);
- __deferred_until = .;
- . += (__deferred_funcs_end - __deferred_funcs) * (8 / 4);
- __deferred_until_end = .;
-
- . = ALIGN(4);
- __bss_end = .;
- } > IRAM
-
- .data : AT(ADDR(.rodata) + SIZEOF(.rodata)) {
- . = ALIGN(4);
- __data_start = .;
- *(.data.tasks)
- *(.data)
- . = ALIGN(4);
- *(.iram.text)
- . = ALIGN(4);
- __data_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 = .;
-
- /* NOTHING MAY GO AFTER THIS! */
- } > 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);
-
- /*
- * __flash_used is used in flash free calculations by the makefile.
- * __image_size is stored in the struct image_data header and used
- * in hash calcuations.
- */
- __flash_used = LOADADDR(.data) + SIZEOF(.data) - ORIGIN(FLASH);
- __image_size = __flash_used;
-
-#ifdef CONFIG_FLASH_CROS
- /*
- * These linker labels are just for analysis and not used in the code.
- */
- __config_flash_size = CONFIG_FLASH_SIZE_BYTES;
- __config_ro_size = CONFIG_RO_SIZE;
- __config_ec_protected_storage_size = CONFIG_EC_PROTECTED_STORAGE_SIZE;
- __config_rw_size = CONFIG_RW_SIZE;
- __config_ec_writable_storage_size = CONFIG_EC_WRITABLE_STORAGE_SIZE;
-#endif
-
- /*
- * The linker won't notice if the .data section is too big to fit,
- * apparently because we're sending it into IRAM, not FLASH.
- * Verify that all sections linked into the FLASH region will fit.
- */
- ASSERT((LENGTH(FLASH)
-#if defined(CONFIG_RWSIG) && defined(SECTION_IS_RO)
- - CONFIG_RO_PUBKEY_SIZE
-#endif
-#if defined(CONFIG_RWSIG) && defined(SECTION_IS_RW)
- - CONFIG_RW_SIG_SIZE
-#endif
- ) >= __flash_used,
- "No room left in the flash")
-
- __image_size = __flash_used;
-
-#ifdef CONFIG_CHIP_MEMORY_REGIONS
-#define REGION(name, attr, start, size) \
- .name(NOLOAD) : { \
- __##name##_start = .; \
- *(SORT(.name.*)) \
- } > name
-#include "memory_regions.inc"
-#undef REGION
-#endif /* CONFIG_CHIP_MEMORY_REGIONS */
-
-#if !(defined(SECTION_IS_RO) && defined(CONFIG_FLASH_CROS))
- /DISCARD/ : { *(.google) }
-#endif
- /DISCARD/ : { *(.ARM.*) }
-}
diff --git a/core/cortex-m0/include/fpu.h b/core/cortex-m0/include/fpu.h
deleted file mode 100644
index 3acec557a7..0000000000
--- a/core/cortex-m0/include/fpu.h
+++ /dev/null
@@ -1,11 +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 ARMv6-M */
-
-#ifndef __CROS_EC_FPU_H
-#define __CROS_EC_FPU_H
-
-#endif /* __CROS_EC_FPU_H */
diff --git a/core/cortex-m0/init.S b/core/cortex-m0/init.S
deleted file mode 100644
index 5047d18380..0000000000
--- a/core/cortex-m0/init.S
+++ /dev/null
@@ -1,129 +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.
- *
- * Cortex-M0 CPU initialization
- */
-
-#include "config.h"
-
-#ifdef CHIP_FAMILY_STM32F0
-/* Allocate space for SRAM vector table at SRAM based address */
-.section .bss.vector_table
-sram_vtable: .skip (48*4)
-#endif
-
-.text
-.syntax unified
-.code 16
-
-.global reset
-.thumb_func
-reset:
- /*
- * Ensure we're in privileged mode with main stack. Necessary if
- * we've jumped directly here from another image after task_start().
- */
- movs r0, #0 @ priv. mode / main stack / no floating point
- msr control, r0
- isb @ ensure the write is done
-
- /* Clear BSS */
- movs r0, #0
- ldr r1,_bss_start
- ldr r2,_bss_end
-bss_loop:
- str r0, [r1]
- adds r1, #4
- cmp r1, r2
- blt bss_loop
-
-#ifdef CHIP_FAMILY_STM32F0
- /*
- * STM32F0 parts don't have the VTOR register for relocating
- * the vector table. Instead, we must copy the vector table from
- * flash into SRAM.
- */
- ldr r1, =vectors
- ldr r2, =sram_vtable
- movs r0, #0
-vtable_loop:
- ldr r3, [r1]
- str r3, [r2]
- adds r1, #4
- adds r2, #4
- adds r0, #1
- cmp r0, #48
- blt vtable_loop
-
- /* Set SYSCFG_CFGR1 mem_mode to load vector table from SRAM */
- movs r0, #3
- ldr r1, =0x40010000
- str r0, [r1]
-#else
- /* Set the vector table on our current code */
- ldr r1, =vectors
- ldr r2, =0xE000ED08 /* VTOR register in SCB*/
- str r1, [r2]
-#endif
-
- /* Copy initialized data to Internal RAM */
- ldr r0,_data_lma_start
- ldr r1,_data_start
- ldr r2,_data_end
-data_loop:
- ldr r3, [r0]
- adds r0, #4
- str r3, [r1]
- adds r1, #4
- cmp r1, r2
- blt data_loop
-
- /*
- * Set stack pointer. Already done by Cortex-M hardware, but re-doing
- * this here allows software to jump directly to the reset vector.
- */
- ldr r0, =stack_end
- mov sp, r0
-
- /* Jump to C code */
- bl main
-
- /* That should not return. If it does, loop forever. */
-fini_loop:
- b fini_loop
-
-/* Default exception handler */
-.thumb_func
-default_handler:
- ldr r0, =exception_panic
- bx r0
-
-.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
-
-/* Mock functions to avoid linker complaints */
-.global __aeabi_unwind_cpp_pr0
-.global __aeabi_unwind_cpp_pr1
-.global __aeabi_unwind_cpp_pr2
-__aeabi_unwind_cpp_pr0:
-__aeabi_unwind_cpp_pr1:
-__aeabi_unwind_cpp_pr2:
- bx lr
-
-/* Reserve space for system stack */
-.section .bss.system_stack
-stack_start:
-.space CONFIG_STACK_SIZE, 0
-stack_end:
-.global stack_end
-
diff --git a/core/cortex-m0/irq_handler.h b/core/cortex-m0/irq_handler.h
deleted file mode 100644
index de36ef7623..0000000000
--- a/core/cortex-m0/irq_handler.h
+++ /dev/null
@@ -1,44 +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
-
-#include "cpu.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) DECLARE_IRQ_(irq, routine, priority)
-#ifdef CONFIG_TASK_PROFILING
-#define DECLARE_IRQ_(irq, routine, priority) \
- void routine(void); \
- void IRQ_HANDLER(irq)(void) \
- { \
- void *ret = __builtin_return_address(0); \
- task_start_irq_handler(ret); \
- routine(); \
- task_end_irq_handler(ret); \
- } \
- const struct irq_priority __keep IRQ_PRIORITY(irq) \
- __attribute__((section(".rodata.irqprio"))) \
- = {irq, priority}
-#else /* CONFIG_TASK_PROFILING */
-/* No Profiling : connect directly the IRQ vector */
-#define DECLARE_IRQ_(irq, routine, priority) \
- void routine(void); \
- void IRQ_HANDLER(irq)(void) __attribute__((alias(STRINGIFY(routine))));\
- const struct irq_priority __keep IRQ_PRIORITY(irq) \
- __attribute__((section(".rodata.irqprio"))) \
- = {irq, priority}
-#endif /* CONFIG_TASK_PROFILING */
-#endif /* __CROS_EC_IRQ_HANDLER_H */
diff --git a/core/cortex-m0/ldivmod.S b/core/cortex-m0/ldivmod.S
deleted file mode 120000
index 603ea316c8..0000000000
--- a/core/cortex-m0/ldivmod.S
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/libaeabi-cortexm0/core/cortex-m0/ldivmod.S \ No newline at end of file
diff --git a/core/cortex-m0/lmul.S b/core/cortex-m0/lmul.S
deleted file mode 120000
index ab5bfc3cb2..0000000000
--- a/core/cortex-m0/lmul.S
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/libaeabi-cortexm0/core/cortex-m0/lmul.S \ No newline at end of file
diff --git a/core/cortex-m0/mula.S b/core/cortex-m0/mula.S
deleted file mode 100644
index 02e617c328..0000000000
--- a/core/cortex-m0/mula.S
+++ /dev/null
@@ -1,81 +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.
- *
- * Cortex-M0 multiply-accumulate[-accumulate] functions
- */
-
- .syntax unified
- .text
- .thumb
-
-@ uint64_t mula32(uint32_t a, uint32_t b, uint32_t c)
-@
-@ Multiply a (r0) and b (r1), add c (r2) and return the product in r1:r0
-@
- .thumb_func
- .section .text.mula32
- .global mula32
-mula32:
-
- push {r4, r5}
- uxth r4, r0 /* r4 = a.lo16 */
- uxth r5, r1 /* r5 = b.lo16 */
- uxth r3, r2 /* r3 = c.lo16 */
- muls r4, r5 /* r4 = a.lo16 * b.lo16 */
- adds r4, r3 /* r4 = a.lo16 * b.lo16 + c.lo16 == r.lo32 */
- lsrs r3, r0, 16 /* r3 = a.hi16 */
- lsrs r2, r2, 16 /* r2 = c.hi16 */
- muls r5, r3 /* r5 = a.hi16 * b.lo16 */
- adds r5, r2 /* r5 = a.hi16 * b.lo16 + c.hi16 == r.mid32.1 */
- uxth r2, r0 /* r2 = a.lo16 */
- lsrs r1, r1, 16 /* r1 = b.hi16 */
- muls r2, r1 /* r2 = a.lo16 * b.hi16 == r.mid32.2 */
- muls r1, r3 /* r1 = b.hi16 * a.hi16 == r.hi32 */
- movs r3, 0 /* r3 = 0 */
- adds r5, r2 /* r5 = (r.mid32.1 + r.mid32.2).lo32 == r.mid.lo32 */
- adcs r3, r3 /* r3 = (r.mid32.1 + r.mid32.2).hi32 == r.mid.hi32 */
- lsls r0, r5, 16 /* r0 = r.mid.lo32.lo16 << 16 == r.mid.inpos.lo32 */
- lsrs r5, r5, 16 /* r5 = r.mid.lo32.hi16 >> 16 */
- lsls r3, r3, 16 /* r3 = r.mid.hi.lo16 << 16 */
- adds r3, r5 /* r3 = r5 + r3 = r.mid.inpos.hi32 */
- adds r0, r4 /* r0 = r.lo32 */
- adcs r1, r3 /* r1 = r.hi32 */
- pop {r4, r5}
- bx lr
-
-@ uint64_t mulaa32(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
-@
-@ Multiply a (r0) and b (r1), add c (r2), add d (r3) and return the product in
-@ r1:r0
- .thumb_func
- .section .text.mulaa32
- .global mulaa32
-mulaa32:
-
- push {r4, r5, r6}
- uxth r5, r0 /* r5 = a.lo16 */
- uxth r6, r1 /* r6 = b.lo16 */
- uxth r4, r2 /* r4 = c.lo16 */
- muls r5, r6 /* r5 = a.lo16 * b.lo16 */
- adds r5, r4 /* r5 = a.lo16 * b.lo16 + c.lo16 == r.lo32 */
- lsrs r4, r0, 16 /* r4 = a.hi16 */
- lsrs r2, r2, 16 /* r2 = c.hi16 */
- muls r6, r4 /* r6 = a.hi16 * b.lo16 */
- adds r6, r2 /* r6 = a.hi16 * b.lo16 + c.hi16 == r.mid32.1 */
- uxth r2, r0 /* r2 = a.lo16 */
- lsrs r1, r1, 16 /* r1 = b.hi16 */
- muls r2, r1 /* r2 = a.lo16 * b.hi16 == r.mid32.2 */
- muls r1, r4 /* r1 = b.hi16 * a.hi16 == r.hi32 */
- movs r4, 0 /* r4 = 0 */
- adds r6, r2 /* r6 = (r.mid32.1 + r.mid32.2).lo32 == r.mid.lo32 */
- adcs r4, r4 /* r4 = (r.mid32.1 + r.mid32.2).hi32 == r.mid.hi32 */
- lsls r0, r6, 16 /* r0 = r.mid.lo32.lo16 << 16 == r.mid.inpos.lo32 */
- lsrs r6, r6, 16 /* r6 = r.mid.lo32.hi16 >> 16 */
- lsls r4, r4, 16 /* r4 = r.mid.hi.lo16 << 16 */
- adds r0, r3 /* r0 = r.mid.inposition.lo32 + d */
- adcs r4, r6 /* r4 = r6 + r4 + carry = r.mid.inpos.hi32 */
- adds r0, r5 /* r0 = r.lo32 */
- adcs r1, r4 /* r1 = r.hi32 */
- pop {r4, r5, r6}
- bx lr
diff --git a/core/cortex-m0/panic-internal.h b/core/cortex-m0/panic-internal.h
deleted file mode 100644
index 51c12f65b2..0000000000
--- a/core/cortex-m0/panic-internal.h
+++ /dev/null
@@ -1,13 +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.
- */
-
-#ifndef __CROS_EC_PANIC_INTERNAL_H
-#define __CROS_EC_PANIC_INTERNAL_H
-
-#include <stdnoreturn.h>
-
-noreturn void exception_panic(void) __attribute__((naked));
-
-#endif /* __CROS_EC_PANIC_INTERNAL_H */
diff --git a/core/cortex-m0/panic.c b/core/cortex-m0/panic.c
deleted file mode 100644
index 4fe69fddb1..0000000000
--- a/core/cortex-m0/panic.c
+++ /dev/null
@@ -1,227 +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.
- */
-
-#include "common.h"
-#include "console.h"
-#include "cpu.h"
-#include "host_command.h"
-#include "panic.h"
-#include "panic-internal.h"
-#include "printf.h"
-#include "system.h"
-#include "task.h"
-#include "timer.h"
-#include "util.h"
-#include "watchdog.h"
-
-/* Whether bus fault is ignored */
-static int bus_fault_ignored;
-
-
-/* Panic data goes at the end of RAM. */
-static struct panic_data * const pdata_ptr = PANIC_DATA_PTR;
-
-/* Preceded by stack, rounded down to nearest 64-bit-aligned boundary */
-static const uint32_t pstack_addr = (CONFIG_RAM_BASE + CONFIG_RAM_SIZE
- - sizeof(struct panic_data)) & ~7;
-
-/**
- * Print the name and value of a register
- *
- * This is a convenient helper function for displaying a register value.
- * It shows the register name in a 3 character field, followed by a colon.
- * The register value is regs[index], and this is shown in hex. If regs is
- * NULL, then we display spaces instead.
- *
- * After displaying the value, either a space or \n is displayed depending
- * on the register number, so that (assuming the caller passes all 16
- * registers in sequence) we put 4 values per line like this
- *
- * r0 :0000000b r1 :00000047 r2 :60000000 r3 :200012b5
- * r4 :00000000 r5 :08004e64 r6 :08004e1c r7 :200012a8
- * r8 :08004e64 r9 :00000002 r10:00000000 r11:00000000
- * r12:0000003f sp :200009a0 lr :0800270d pc :0800351a
- *
- * @param regnum Register number to display (0-15)
- * @param regs Pointer to array holding the registers, or NULL
- * @param index Index into array where the register value is present
- */
-static void print_reg(int regnum, const uint32_t *regs, int index)
-{
- static const char regname[] = "r10r11r12sp lr pc ";
- static char rname[3] = "r ";
- const char *name;
-
- rname[1] = '0' + regnum;
- name = regnum < 10 ? rname : &regname[(regnum - 10) * 3];
- panic_printf("%c%c%c:", name[0], name[1], name[2]);
- if (regs)
- panic_printf("%08x", regs[index]);
- else
- panic_puts(" ");
- panic_puts((regnum & 3) == 3 ? "\n" : " ");
-}
-
-/*
- * Returns non-zero if the exception frame was created on the main stack, or
- * zero if it's on the process stack.
- *
- * See B1.5.8 "Exception return behavior" of ARM DDI 0403D for details.
- */
-static int32_t is_frame_in_handler_stack(const uint32_t exc_return)
-{
- return (exc_return & 0xf) == 1 || (exc_return & 0xf) == 9;
-}
-
-/*
- * Print panic data
- */
-void panic_data_print(const struct panic_data *pdata)
-{
- const uint32_t *lregs = pdata->cm.regs;
- const uint32_t *sregs = NULL;
- const int32_t in_handler =
- is_frame_in_handler_stack(pdata->cm.regs[11]);
- int i;
-
- if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID)
- sregs = pdata->cm.frame;
-
- panic_printf("\n=== %s EXCEPTION: %02x ====== xPSR: %08x ===\n",
- in_handler ? "HANDLER" : "PROCESS",
- lregs[1] & 0xff, sregs ? sregs[7] : -1);
- for (i = 0; i < 4; i++)
- print_reg(i, sregs, i);
- for (i = 4; i < 10; i++)
- print_reg(i, lregs, i - 1);
- print_reg(10, lregs, 9);
- print_reg(11, lregs, 10);
- print_reg(12, sregs, 4);
- print_reg(13, lregs, in_handler ? 2 : 0);
- print_reg(14, sregs, 5);
- print_reg(15, sregs, 6);
-}
-
-void __keep report_panic(void)
-{
- /*
- * Don't need to get pointer via get_panic_data_write()
- * because memory below pdata_ptr is stack now (see exception_panic())
- */
- struct panic_data *pdata = pdata_ptr;
- uint32_t sp;
-
- pdata->magic = PANIC_DATA_MAGIC;
- pdata->struct_size = sizeof(*pdata);
- pdata->struct_version = 2;
- pdata->arch = PANIC_ARCH_CORTEX_M;
- pdata->flags = 0;
- pdata->reserved = 0;
-
- /* Choose the right sp (psp or msp) based on EXC_RETURN value */
- sp = is_frame_in_handler_stack(pdata->cm.regs[11])
- ? pdata->cm.regs[2] : pdata->cm.regs[0];
- /* If stack is valid, copy exception frame to pdata */
- if ((sp & 3) == 0 &&
- sp >= CONFIG_RAM_BASE &&
- sp <= CONFIG_RAM_BASE + CONFIG_RAM_SIZE - 8 * sizeof(uint32_t)) {
- const uint32_t *sregs = (const uint32_t *)sp;
- int i;
- for (i = 0; i < 8; i++)
- pdata->cm.frame[i] = sregs[i];
- pdata->flags |= PANIC_DATA_FLAG_FRAME_VALID;
- }
-
- panic_data_print(pdata);
- panic_reboot();
-}
-
-/**
- * Default exception handler, which reports a panic.
- *
- * Declare this as a naked call so we can extract raw LR and IPSR values.
- */
-void exception_panic(void)
-{
- /* Save registers and branch directly to panic handler */
- asm volatile(
- "mov r0, %[pregs]\n"
- "mrs r1, psp\n"
- "mrs r2, ipsr\n"
- "mov r3, sp\n"
- "stmia r0!, {r1-r7}\n"
- "mov r1, r8\n"
- "mov r2, r9\n"
- "mov r3, r10\n"
- "mov r4, r11\n"
- "mov r5, lr\n"
- "stmia r0!, {r1-r5}\n"
- "mov sp, %[pstack]\n"
- "bl report_panic\n" : :
- [pregs] "r" (pdata_ptr->cm.regs),
- [pstack] "r" (pstack_addr) :
- /* Constraints protecting these from being clobbered.
- * Gcc should be using r0 & r12 for pregs and pstack. */
- "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
- "r10", "r11", "cc", "memory"
- );
-}
-
-#ifdef CONFIG_SOFTWARE_PANIC
-void software_panic(uint32_t reason, uint32_t info)
-{
- __asm__("mov " STRINGIFY(SOFTWARE_PANIC_INFO_REG) ", %0\n"
- "mov " STRINGIFY(SOFTWARE_PANIC_REASON_REG) ", %1\n"
- "bl exception_panic\n"
- : : "r"(info), "r"(reason));
- __builtin_unreachable();
-}
-
-void panic_set_reason(uint32_t reason, uint32_t info, uint8_t exception)
-{
- struct panic_data * const pdata = get_panic_data_write();
- uint32_t *lregs;
-
- lregs = pdata->cm.regs;
-
- /* Setup panic data structure */
- memset(pdata, 0, CONFIG_PANIC_DATA_SIZE);
- pdata->magic = PANIC_DATA_MAGIC;
- pdata->struct_size = CONFIG_PANIC_DATA_SIZE;
- pdata->struct_version = 2;
- pdata->arch = PANIC_ARCH_CORTEX_M;
-
- /* Log panic cause */
- lregs[1] = exception;
- lregs[3] = reason;
- lregs[4] = info;
-}
-
-void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception)
-{
- struct panic_data * const pdata = panic_get_data();
- uint32_t *lregs;
-
- if (pdata && pdata->struct_version == 2) {
- lregs = pdata->cm.regs;
- *exception = lregs[1];
- *reason = lregs[3];
- *info = lregs[4];
- } else {
- *exception = *reason = *info = 0;
- }
-}
-#endif
-
-void bus_fault_handler(void)
-{
- if (!bus_fault_ignored)
- exception_panic();
-}
-
-void ignore_bus_fault(int ignored)
-{
- bus_fault_ignored = ignored;
-}
diff --git a/core/cortex-m0/switch.S b/core/cortex-m0/switch.S
deleted file mode 100644
index a75daad939..0000000000
--- a/core/cortex-m0/switch.S
+++ /dev/null
@@ -1,116 +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.
- *
- * Context swtching
- */
-
-#include "config.h"
-
-#define CPU_SCB_ICSR 0xe000ed04
-
-.text
-
-.syntax unified
-.code 16
-
-/**
- * Task context switching
- *
- * Change the task scheduled after returning from the exception.
- *
- * Save the registers of the current task below the exception 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
- *
- * must be called from interrupt context
- *
- * the structure of the saved context on the stack is :
- * r8, r9, r10, r11, r4, r5, r6, r7, r0, r1, r2, r3, r12, lr, pc, psr
- * additional registers <|> exception frame
- */
-.global __switchto
-.thumb_func
-__switchto:
- mrs r2, psp @ get the task stack where the context has been saved
- mov r3, sp
- mov sp, r2
- push {r4-r7} @ save additional r4-r7 in the task stack
- mov r4, r8
- mov r5, r9
- mov r6, r10
- mov r7, r11
- push {r4-r7} @ save additional r8-r11 in the task stack
- mov r2, sp @ prepare to save former task stack pointer
- mov sp, r3 @ restore system stack pointer
- str r2, [r0] @ save the task stack pointer in its context
- ldr r2, [r1] @ get the new scheduled task stack pointer
- ldmia r2!, {r4-r7} @ restore r8-r11 for the next task context
- mov r8, r4
- mov r9, r5
- mov r10, r6
- mov r11, r7
- ldmia r2!, {r4-r7} @ restore r4-r7 for the next task context
- msr psp, r2 @ set the process stack pointer to exception context
- bx lr @ return from exception
-
-/**
- * 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
-.thumb_func
-__task_start:
- ldr r2,=scratchpad @ area used as thread stack for the first switch
- movs r3, #2 @ use : priv. mode / thread stack / no floating point
- adds r2, #17*4 @ put the pointer at the top of the stack
- movs r1, #0 @ __Schedule parameter : re-schedule nothing
- msr psp, r2 @ setup a thread stack up to the first context switch
- movs r2, #1 @ r2 = TASK_SCHEDULER_INIT
- isb @ ensure the write is done
- msr control, r3
- movs r3, r0
- movs r0, #0 @ __Schedule parameter : de-schedule nothing
- isb @ ensure the write is done
- str r2, [r3] @ Task scheduling is now active
- bl __schedule @ execute the task with the highest priority
- /* we should never return here */
- movs r0, #1 @ set to EC_ERROR_UNKNOWN
- bx lr
-
-/**
- * SVC exception handler
- */
-.global svc_handler
-.thumb_func
-svc_handler:
- push {r3, lr} @ save link register and keep stack aligned
- bl __svc_handler @ call svc handler helper
- ldr r3,=current_task @ load the current task's address
- ldr r1, [r3] @ load the current task
- cmp r0, r1 @ compare with previous task returned by helper
- beq svc_handler_return @ return if they are the same
- bl __switchto @ context switch to the next task
-svc_handler_return:
- pop {r3, pc} @ return from exception or return to caller
-
-/**
- * PendSVC exception handler
- */
-.global pendsv_handler
-.thumb_func
-pendsv_handler:
- push {r3, lr} @ save link register and keep stack aligned
- ldr r0, =CPU_SCB_ICSR @ load CPU_SCB_ICSR's address
- movs r1, #1 @ prepare left shift (1 << 27)
- lsls r1, #27 @ shift the bit
- str r1, [r0] @ clear pending flag
- cpsid i @ ensure we have priority 0 during re-scheduling
- movs r1, #0 @ desched nothing
- movs r0, #0 @ resched nothing
- bl svc_handler @ re-schedule the highest priority task
- cpsie i @ leave priority 0
- pop {r3, pc} @ return from exception
diff --git a/core/cortex-m0/task.c b/core/cortex-m0/task.c
deleted file mode 100644
index ba40b667b6..0000000000
--- a/core/cortex-m0/task.c
+++ /dev/null
@@ -1,691 +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.
- */
-
-/* Task scheduling / events module for Chrome EC operating system */
-
-#include "atomic.h"
-#include "common.h"
-#include "console.h"
-#include "cpu.h"
-#include "link_defs.h"
-#include "panic.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
-CONFIG_CTS_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
- CONFIG_CTS_TASK_LIST
-};
-#undef TASK
-
-#ifdef CONFIG_TASK_PROFILING
-static uint64_t task_start_time; /* Time task scheduling started */
-/*
- * We only keep 32-bit values for exception start/end time, to avoid
- * accounting errors when we service interrupt when the timer wraps around.
- */
-static uint32_t exc_start_time; /* Time of task->exception transition */
-static uint32_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(int *task_stack_ready);
-
-#ifndef CONFIG_LOW_POWER_IDLE
-/* Idle task. Executed when no tasks are ready to be scheduled. */
-void __idle(void)
-{
- while (1) {
- /*
- * Wait for the next irq event. This stops the CPU clock
- * (sleep / deep sleep, depending on chip config).
- */
- asm("wfi");
- }
-}
-#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
- CONFIG_CTS_TASK_LIST
-};
-#undef TASK
-
-/* Contexts for all tasks */
-static task_ tasks[TASK_ID_COUNT];
-/* Validity 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
- CONFIG_CTS_TASK_LIST
-] __aligned(8);
-
-#undef TASK
-
-/* Reserve space to discard context on first context switch. */
-uint32_t scratchpad[17];
-
-task_ *current_task = (task_ *)scratchpad;
-
-/*
- * 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);
-
-static int start_called; /* Has task swapping started */
-
-static inline task_ *__task_id_to_ptr(task_id_t id)
-{
- return tasks + id;
-}
-
-void interrupt_disable(void)
-{
- asm("cpsid i");
-}
-
-void interrupt_enable(void)
-{
- asm("cpsie i");
-}
-
-inline int is_interrupt_enabled(void)
-{
- int primask;
-
- /* Interrupts are enabled when PRIMASK bit is 0 */
- asm("mrs %0, primask":"=r"(primask));
-
- return !(primask & 0x1);
-}
-
-inline int in_interrupt_context(void)
-{
- int ret;
- asm("mrs %0, ipsr\n" /* read exception number */
- "lsl %0, #23\n" : "=r"(ret)); /* exception bits are the 9 LSB */
- return ret;
-}
-
-static inline int get_interrupt_context(void)
-{
- int ret;
- asm("mrs %0, ipsr\n" : "=r"(ret)); /* read exception number */
- return ret & 0x1ff; /* exception bits are the 9 LSB */
-}
-
-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;
-}
-
-/**
- * Scheduling system call
- */
-task_ __attribute__((noinline)) *__svc_handler(int desched, task_id_t resched)
-{
- task_ *current, *next;
-#ifdef CONFIG_TASK_PROFILING
- int exc = get_interrupt_context();
- uint32_t t;
-#endif
-
- /* Priority is already at 0 we cannot be interrupted */
-
-#ifdef CONFIG_TASK_PROFILING
- /*
- * SVCall isn't triggered via DECLARE_IRQ(), so it needs to track its
- * start time explicitly.
- */
- if (exc == 0xb) {
- t = get_time().le.lo;
- current_task->runtime += (t - exc_end_time);
- exc_end_time = t;
- svc_calls++;
- }
-#endif
-
- current = current_task;
-
-#ifdef CONFIG_DEBUG_STACK_OVERFLOW
- if (*current->stack != STACK_UNUSED_VALUE) {
- panic_printf("\n\nStack overflow in %s task!\n",
- task_names[current - tasks]);
-#ifdef CONFIG_SOFTWARE_PANIC
- software_panic(PANIC_SW_STACK_OVERFLOW, current - tasks);
-#endif
- }
-#endif
-
- if (desched && !current->events) {
- /*
- * Remove our own ready bit (current - tasks is same as
- * task_get_current())
- */
- tasks_ready &= ~(1 << (current - tasks));
- }
- tasks_ready |= 1 << resched;
-
- ASSERT(tasks_ready & tasks_enabled);
- next = __task_id_to_ptr(__fls(tasks_ready & tasks_enabled));
-
-#ifdef CONFIG_TASK_PROFILING
- /* Track additional time in re-sched exception context */
- t = get_time().le.lo;
- exc_total_time += (t - exc_end_time);
-
- exc_end_time = t;
-#endif
-
- /* Switch to new task */
-#ifdef CONFIG_TASK_PROFILING
- if (next != current)
- task_switches++;
-#endif
- current_task = next;
- return current;
-}
-
-void __schedule(int desched, int resched)
-{
- register int p0 asm("r0") = desched;
- register int p1 asm("r1") = resched;
-
- asm("svc 0" : : "r"(p0), "r"(p1));
-}
-
-#ifdef CONFIG_TASK_PROFILING
-void task_start_irq_handler(void *excep_return)
-{
- /*
- * Get time before checking depth, in case this handler is
- * pre-empted.
- */
- uint32_t t = get_time().le.lo;
- int irq = get_interrupt_context() - 16;
-
- /*
- * Track IRQ distribution. No need for atomic add, because an IRQ
- * can't pre-empt itself.
- */
- if (irq < ARRAY_SIZE(irq_dist))
- irq_dist[irq]++;
-
- /*
- * Continue iff the tasks are ready and we are not called from another
- * exception (as the time accouting is done in the outer irq).
- */
- if (!start_called || ((uint32_t)excep_return & 0xf) == 1)
- return;
-
- exc_start_time = t;
- /*
- * Bill the current task for time between the end of the last interrupt
- * and the start of this one.
- */
- current_task->runtime += (exc_start_time - exc_end_time);
-}
-
-void task_end_irq_handler(void *excep_return)
-{
- uint32_t t = get_time().le.lo;
- /*
- * Continue iff the tasks are ready and we are not called from another
- * exception (as the time accouting is done in the outer irq).
- */
- if (!start_called || ((uint32_t)excep_return & 0xf) == 1)
- return;
-
- /* Track time in interrupts */
- exc_total_time += (t - exc_start_time);
- exc_end_time = t;
-}
-#endif
-
-static uint32_t __wait_evt(int timeout_us, task_id_t resched)
-{
- task_ *tsk = current_task;
- task_id_t me = tsk - tasks;
- uint32_t evt;
- int ret __attribute__((unused));
-
- /*
- * Scheduling task when interrupts are disabled will result in Forced
- * Hard Fault because disabling interrupt using 'cpsid i' also disables
- * SVCall handler (because it has configurable priority)
- */
- ASSERT(is_interrupt_enabled());
- 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_clear(&tsk->events))) {
- /*
- * We need to ensure that the execution priority is actually
- * decreased after the "cpsie i" in the atomic operation above
- * else the "svc" in the __schedule call below will trigger
- * a HardFault. Use a barrier to force it at that point.
- */
- asm volatile("isb");
- /* Remove ourself and get the next task in the scheduler */
- __schedule(1, resched);
- resched = TASK_ID_IDLE;
- }
- if (timeout_us > 0) {
- timer_cancel(me);
- /* Ensure timer event is clear, we no longer care about it */
- atomic_clear_bits(&tsk->events, TASK_EVENT_TIMER);
- }
- return evt;
-}
-
-uint32_t task_set_event(task_id_t tskid, uint32_t event)
-{
- 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() || !is_interrupt_enabled()) {
- /* The receiver might run again */
- atomic_or(&tasks_ready, 1 << tskid);
- if (start_called) {
- /*
- * Trigger the scheduler when there's
- * no other irqs happening.
- */
- CPU_SCB_ICSR = BIT(28);
- }
- } else {
- /*
- * We need to ensure that the execution priority is
- * actually decreased after the "cpsie i" in the atomic
- * operation above else the "svc" in the __schedule
- * call below will trigger a HardFault.
- * Use a barrier to force it at that point.
- */
- asm volatile("isb");
- __schedule(0, tskid);
- }
-
- return 0;
-}
-
-uint32_t task_wait_event(int timeout_us)
-{
- return __wait_evt(timeout_us, TASK_ID_IDLE);
-}
-
-uint32_t 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;
-}
-
-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. */
- if (is_interrupt_enabled())
- __schedule(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_bits(&tasks_enabled, BIT(tskid));
-
- if (!in_interrupt_context() && is_interrupt_enabled() &&
- tskid == task_get_current())
- __schedule(0, 0);
-}
-
-void task_enable_irq(int irq)
-{
- CPU_NVIC_EN(0) = 1 << irq;
-}
-
-void task_disable_irq(int irq)
-{
- CPU_NVIC_DIS(0) = 1 << irq;
-}
-
-void task_clear_pending_irq(int irq)
-{
- CPU_NVIC_UNPEND(0) = 1 << irq;
-}
-
-void task_trigger_irq(int irq)
-{
- CPU_NVIC_ISPR(0) = 1 << irq;
-}
-
-/*
- * Initialize IRQs in the NVIC and set their priorities as defined by the
- * DECLARE_IRQ statements.
- */
-static void __nvic_init_irqs(void)
-{
- /* Get the IRQ priorities section from the linker */
- int exc_calls = __irqprio_end - __irqprio;
- int i;
-
- /* Mask and clear all pending interrupts */
- CPU_NVIC_DIS(0) = 0xffffffff;
- CPU_NVIC_UNPEND(0) = 0xffffffff;
-
- /*
- * 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++) {
- cpu_set_interrupt_priority(__irqprio[i].irq,
- __irqprio[i].priority);
- }
-}
-
-void mutex_lock(struct mutex *mtx)
-{
- uint32_t id = 1 << task_get_current();
-
- ASSERT(id != TASK_ID_INVALID);
- atomic_or(&mtx->waiters, id);
-
- while (1) {
- /* Try to get the lock (set 2 into the lock field) */
- __asm__ __volatile__("cpsid i");
- if (mtx->lock == 0)
- break;
- __asm__ __volatile__("cpsie i");
- /* Contention on the mutex */
- task_wait_event_mask(TASK_EVENT_MUTEX, 0);
- }
- mtx->lock = 2;
- __asm__ __volatile__("cpsie i");
-
- atomic_clear_bits(&mtx->waiters, id);
-}
-
-void mutex_unlock(struct mutex *mtx)
-{
- uint32_t waiters;
- task_ *tsk = current_task;
-
- /*
- * Add a critical section to keep the unlock and the snapshotting of
- * waiters atomic in case a task switching occurs between them.
- */
- interrupt_disable();
- waiters = mtx->waiters;
- mtx->lock = 0;
- interrupt_enable();
-
- while (waiters) {
- task_id_t id = __fls(waiters);
- waiters &= ~BIT(id);
-
- /* Somebody is waiting on the mutex */
- task_set_event(id, TASK_EVENT_MUTEX);
- }
-
- /* Ensure no event is remaining from mutex wake-up */
- atomic_clear_bits(&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");
-
-#ifdef CONFIG_CMD_TASKREADY
-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);
- }
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(taskready, command_task_ready,
- "[setmask]",
- "Print/set ready tasks");
-#endif
-
-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: 8 words for the normal
- * stack, plus 8 for R4-R11. With FP enabled, we need another
- * 18 words for S0-S15 and FPCSR and to align to 64-bit.
- */
- sp = stack_next + ssize - 16;
- tasks[i].sp = (uint32_t)sp;
-
- /* Initial context on stack (see __switchto()) */
- sp[8] = tasks_init[i].r0; /* r0 */
- sp[13] = (uint32_t)task_exit_trap; /* lr */
- sp[14] = tasks_init[i].pc; /* pc */
- sp[15] = 0x01000000; /* psr */
-
- /* 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 */
- __nvic_init_irqs();
-}
-
-int task_start(void)
-{
-#ifdef CONFIG_TASK_PROFILING
- timestamp_t t = get_time();
-
- task_start_time = t.val;
- exc_end_time = t.le.lo;
-#endif
-
- return __task_start(&start_called);
-}
diff --git a/core/cortex-m0/thumb_case.S b/core/cortex-m0/thumb_case.S
deleted file mode 100644
index 5628361a94..0000000000
--- a/core/cortex-m0/thumb_case.S
+++ /dev/null
@@ -1,96 +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.
- *
- * Thumb mode toolchain helpers for compact switch/case statement.
- */
-
-#include "config.h"
-
-.text
-
-.syntax unified
-.code 16
-
-/*
- * Helpers for compact switch
- *
- * r0: the table index
- * lr: the table base address (need to clear bit 0)
- *
- * r0 and lr must be PRESERVED.
- * r12 can be clobbered.
- */
-.section .text.__gnu_thumb1_case_uqi
-.global __gnu_thumb1_case_uqi
-.thumb_func
-__gnu_thumb1_case_uqi:
- mov r12, r1
- mov r1, lr
- lsrs r1, r1, #1
- lsls r1, r1, #1
- ldrb r1, [r1, r0]
- lsls r1, r1, #1
- add lr, lr, r1
- mov r1, r12
- bx lr
-
-.section .text.__gnu_thumb1_case_sqi
-.global __gnu_thumb1_case_sqi
-.thumb_func
-__gnu_thumb1_case_sqi:
- mov r12, r1
- mov r1, lr
- lsrs r1, r1, #1
- lsls r1, r1, #1
- ldrsb r1, [r1, r0]
- lsls r1, r1, #1
- add lr, lr, r1
- mov r1, r12
- bx lr
-
-.section .text.__gnu_thumb1_case_uhi
-.global __gnu_thumb1_case_uhi
-.thumb_func
-__gnu_thumb1_case_uhi:
- push {r0, r1}
- mov r1, lr
- lsrs r1, r1, #1
- lsls r0, r0, #1
- lsls r1, r1, #1
- ldrh r1, [r1, r0]
- lsls r1, r1, #1
- add lr, lr, r1
- pop {r0, r1}
- bx lr
-
-.section .text.__gnu_thumb1_case_shi
-.global __gnu_thumb1_case_shi
-.thumb_func
-__gnu_thumb1_case_shi:
- push {r0, r1}
- mov r1, lr
- lsrs r1, r1, #1
- lsls r0, r0, #1
- lsls r1, r1, #1
- ldrsh r1, [r1, r0]
- lsls r1, r1, #1
- add lr, lr, r1
- pop {r0, r1}
- bx lr
-
-.section .text.__gnu_thumb1_case_si
-.global __gnu_thumb1_case_si
-.thumb_func
-__gnu_thumb1_case_si:
- push {r0, r1}
- mov r1, lr
- adds.n r1, r1, #2
- lsrs r1, r1, #2
- lsls r0, r0, #2
- lsls r1, r1, #2
- ldr r0, [r1, r0]
- adds r0, r0, r1
- mov lr, r0
- pop {r0, r1}
- mov pc, lr
diff --git a/core/cortex-m0/uldivmod.S b/core/cortex-m0/uldivmod.S
deleted file mode 120000
index 6d1e5e1998..0000000000
--- a/core/cortex-m0/uldivmod.S
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/libaeabi-cortexm0/core/cortex-m0/uldivmod.S \ No newline at end of file
diff --git a/core/cortex-m0/vecttable.c b/core/cortex-m0/vecttable.c
deleted file mode 100644
index b1eaa957e0..0000000000
--- a/core/cortex-m0/vecttable.c
+++ /dev/null
@@ -1,136 +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.
- *
- * Cortex-M CPU vector table
- */
-
-#ifndef ___INIT
-#define ___INIT
-#include <stddef.h>
-#include <stdint.h>
-
-#include "config.h"
-#include "panic-internal.h"
-#include "task.h"
-#endif /* __INIT */
-
-typedef void (*func)(void);
-
-#ifndef PASS
-#define PASS 1
-#endif
-
-#if PASS == 1
-
-void __attribute__((naked)) default_handler(void)
-{
- /*
- * An (enforced) long tail call to preserve exn_return in lr without
- * restricting the relative placement of default_handler and
- * exception_panic.
- */
- asm volatile("bx %0\n" : : "r" (exception_panic));
-}
-
-#define table(x) x
-
-/* Note: the alias target must be defined in this translation unit */
-#define weak_with_default __attribute__((used, weak, alias("default_handler")))
-
-#define vec(name) extern void weak_with_default name ## _handler(void);
-#define irq(num) vec(irq_ ## num)
-
-#define item(name) extern void name(void);
-#define null
-
-extern void stack_end(void); /* not technically correct, it's just a pointer */
-extern void reset(void);
-
-#pragma GCC diagnostic push
-#if __GNUC__ >= 8
-#pragma GCC diagnostic ignored "-Wattribute-alias"
-#endif
-#pragma GCC diagnostic pop
-
-#endif /* PASS 1 */
-
-#if PASS == 2
-#undef table
-#undef vec
-#undef irq
-#undef item
-#undef null
-
-/* number of elements before the first irq vector */
-#define IRQ_OFFSET 16
-/* element in the table that is null: extra IRQs are routed there,
- * then finally overwritten
- */
-#define IRQ_UNUSED_OFFSET 8
-
-#define table(x) func vectors[] __attribute__((section(".text.vecttable,\"a\" @"))) = { x[IRQ_UNUSED_OFFSET] = null };
-
-#define vec(name) name ## _handler,
-#define irq(num) [num < CONFIG_IRQ_COUNT ? num + IRQ_OFFSET : IRQ_UNUSED_OFFSET] = vec(irq_ ## num)
-
-#define item(name) name,
-#define null (void *)0,
-#endif /* PASS 2 */
-
-table(
- item(stack_end)
- item(reset)
- vec(nmi)
- vec(hard_fault)
- vec(mpu_fault)
- vec(bus_fault)
- vec(usage_fault)
- null
- null
- null
- null
- vec(svc)
- vec(debug)
- null
- vec(pendsv)
- vec(sys_tick)
- irq(0)
- irq(1)
- irq(2)
- irq(3)
- irq(4)
- irq(5)
- irq(6)
- irq(7)
- irq(8)
- irq(9)
- irq(10)
- irq(11)
- irq(12)
- irq(13)
- irq(14)
- irq(15)
- irq(16)
- irq(17)
- irq(18)
- irq(19)
- irq(20)
- irq(21)
- irq(22)
- irq(23)
- irq(24)
- irq(25)
- irq(26)
- irq(27)
- irq(28)
- irq(29)
- irq(30)
- irq(31)
-)
-
-#if PASS == 1
-#undef PASS
-#define PASS 2
-#include "vecttable.c"
-#endif
diff --git a/core/cortex-m0/watchdog.c b/core/cortex-m0/watchdog.c
deleted file mode 100644
index 9961922ee5..0000000000
--- a/core/cortex-m0/watchdog.c
+++ /dev/null
@@ -1,53 +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.
- */
-
-/* Watchdog common code */
-
-#include "common.h"
-#include "panic.h"
-#include "task.h"
-#include "timer.h"
-#include "watchdog.h"
-
-/*
- * As defined by Armv7-M Reference Manual B1.5.6 "Exception Entry Behavior",
- * the structure of the saved context on the stack is:
- * r0, r1, r2, r3, r12, lr, pc, psr, ...
- */
-#define STACK_IDX_REG_LR 5
-#define STACK_IDX_REG_PC 6
-
-void watchdog_trace(uint32_t excep_lr, uint32_t excep_sp)
-{
- uint32_t psp;
- uint32_t *stack;
-
- asm("mrs %0, psp" : "=r"(psp));
- if ((excep_lr & 0xf) == 1) {
- /* we were already in exception context */
- stack = (uint32_t *)excep_sp;
- } else {
- /* we were in task context */
- stack = (uint32_t *)psp;
- }
-
- /* Log PC. If we were in task context, log task id too. */
-#ifdef CONFIG_SOFTWARE_PANIC
- panic_set_reason(PANIC_SW_WATCHDOG, stack[STACK_IDX_REG_PC],
- (excep_lr & 0xf) == 1 ? 0xff : task_get_current());
-#endif
-
- panic_printf("### WATCHDOG PC=%08x / LR=%08x / pSP=%08x ",
- stack[STACK_IDX_REG_PC], stack[STACK_IDX_REG_LR], psp);
- if ((excep_lr & 0xf) == 1)
- panic_puts("(exc) ###\n");
- else
- panic_printf("(task %d) ###\n", task_get_current());
-
- /* If we are blocked in a high priority IT handler, the following debug
- * messages might not appear but they are useless in that situation. */
- timer_print_info();
- task_print_list();
-}
diff --git a/core/host/atomic.h b/core/host/atomic.h
deleted file mode 100644
index 83786de904..0000000000
--- a/core/host/atomic.h
+++ /dev/null
@@ -1,40 +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 emulator */
-
-#ifndef __CROS_EC_ATOMIC_H
-#define __CROS_EC_ATOMIC_H
-
-#include "common.h"
-
-typedef int atomic_t;
-typedef atomic_t atomic_val_t;
-
-static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits)
-{
- return __atomic_fetch_and(addr, ~bits, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_or(atomic_t *addr, atomic_val_t bits)
-{
- return __atomic_fetch_or(addr, bits, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_add(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_add(addr, value, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_sub(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_sub(addr, value, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_clear(atomic_t *addr)
-{
- return __atomic_exchange_n(addr, 0, __ATOMIC_SEQ_CST);
-}
-#endif /* __CROS_EC_ATOMIC_H */
diff --git a/core/host/build.mk b/core/host/build.mk
deleted file mode 100644
index 503aa5538a..0000000000
--- a/core/host/build.mk
+++ /dev/null
@@ -1,11 +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.
-#
-# emulator specific files build
-#
-
-CFLAGS_CPU=-fno-builtin
-
-core-y=main.o task.o timer.o panic.o disabled.o stack_trace.o
diff --git a/core/host/cpu.h b/core/host/cpu.h
deleted file mode 100644
index d990e06afa..0000000000
--- a/core/host/cpu.h
+++ /dev/null
@@ -1,13 +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.
- */
-
-/* CPU specific header file */
-
-#ifndef __CROS_EC_CPU_H
-#define __CROS_EC_CPU_H
-
-static inline void cpu_init(void) { }
-
-#endif /* __CROS_EC_CPU_H */
diff --git a/core/host/disabled.c b/core/host/disabled.c
deleted file mode 100644
index 759c215ebd..0000000000
--- a/core/host/disabled.c
+++ /dev/null
@@ -1,10 +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.
- */
-
-/* Disabled functions */
-
-#define DISABLED(proto) proto { }
-
-DISABLED(void clock_init(void));
diff --git a/core/host/host_exe.lds b/core/host/host_exe.lds
deleted file mode 100644
index ab8d352ecc..0000000000
--- a/core/host/host_exe.lds
+++ /dev/null
@@ -1,136 +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.
- */
-SECTIONS {
- .rodata.ec_sections : {
- /* Symbols defined here are declared in link_defs.h */
- __irqprio = .;
- *(.rodata.irqprio)
- __irqprio_end = .;
-
- . = ALIGN(8);
- __cmds = .;
- *(SORT(.rodata.cmds*))
- __cmds_end = .;
-
- . = ALIGN(8);
- __hcmds = .;
- *(SORT(.rodata.hcmds*))
- __hcmds_end = .;
-
- . = ALIGN(4);
- __mkbp_evt_srcs = .;
- KEEP(*(.rodata.evtsrcs))
- __mkbp_evt_srcs_end = .;
-
- . = ALIGN(8);
- __hooks_init = .;
- *(.rodata.HOOK_INIT)
- __hooks_init_end = .;
-
- __hooks_pre_freq_change = .;
- *(.rodata.HOOK_PRE_FREQ_CHANGE)
- __hooks_pre_freq_change_end = .;
-
- __hooks_freq_change = .;
- *(.rodata.HOOK_FREQ_CHANGE)
- __hooks_freq_change_end = .;
-
- __hooks_sysjump = .;
- *(.rodata.HOOK_SYSJUMP)
- __hooks_sysjump_end = .;
-
- __hooks_chipset_pre_init = .;
- *(.rodata.HOOK_CHIPSET_PRE_INIT)
- __hooks_chipset_pre_init_end = .;
-
- __hooks_chipset_startup = .;
- *(.rodata.HOOK_CHIPSET_STARTUP)
- __hooks_chipset_startup_end = .;
-
- __hooks_chipset_resume = .;
- *(.rodata.HOOK_CHIPSET_RESUME)
- __hooks_chipset_resume_end = .;
-
- __hooks_chipset_suspend = .;
- *(.rodata.HOOK_CHIPSET_SUSPEND)
- __hooks_chipset_suspend_end = .;
-
- __hooks_chipset_shutdown = .;
- *(.rodata.HOOK_CHIPSET_SHUTDOWN)
- __hooks_chipset_shutdown_end = .;
-
- __hooks_chipset_shutdown_complete = .;
- *(.rodata.HOOK_CHIPSET_SHUTDOWN_COMPLETE)
- __hooks_chipset_shutdown_complete_end = .;
-
- __hooks_chipset_hard_off = .;
- KEEP(*(.rodata.HOOK_CHIPSET_HARD_OFF))
- __hooks_chipset_hard_off_end = .;
-
- __hooks_chipset_reset = .;
- *(.rodata.HOOK_CHIPSET_RESET)
- __hooks_chipset_reset_end = .;
-
- __hooks_ac_change = .;
- *(.rodata.HOOK_AC_CHANGE)
- __hooks_ac_change_end = .;
-
- __hooks_lid_change = .;
- *(.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 = .;
- *(.rodata.HOOK_POWER_BUTTON_CHANGE)
- __hooks_pwrbtn_change_end = .;
-
- __hooks_battery_soc_change = .;
- *(.rodata.HOOK_BATTERY_SOC_CHANGE)
- __hooks_battery_soc_change_end = .;
-
- __hooks_tick = .;
- *(.rodata.HOOK_TICK)
- __hooks_tick_end = .;
-
- __hooks_second = .;
- *(.rodata.HOOK_SECOND)
- __hooks_second_end = .;
-
- __hooks_usb_pd_disconnect = .;
- *(.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 = .;
- *(.rodata.deferred)
- __deferred_funcs_end = .;
-
- __test_i2c_xfer = .;
- *(.rodata.test_i2c.xfer)
- __test_i2c_xfer_end = .;
- }
-}
-INSERT BEFORE .rodata;
-
-SECTIONS {
- .bss.ec_sections : {
- /* Symbols defined here are declared in link_defs.h */
- . = ALIGN(8);
- __deferred_until = .;
- . += (__deferred_funcs_end - __deferred_funcs) * (8 / 4);
- __deferred_until_end = .;
- }
-}
-INSERT BEFORE .bss;
diff --git a/core/host/host_task.h b/core/host/host_task.h
deleted file mode 100644
index 30cd2ff594..0000000000
--- a/core/host/host_task.h
+++ /dev/null
@@ -1,37 +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.
- */
-
-/* Emulator task scheduling module */
-
-#ifndef __CROS_EC_HOST_TASK_H
-#define __CROS_EC_HOST_TASK_H
-
-#include <pthread.h>
-
-#include "task.h"
-
-/**
- * Returns the thread corresponding to the task.
- */
-pthread_t task_get_thread(task_id_t tskid);
-
-/**
- * Returns the ID of the active task, regardless of current thread
- * context.
- */
-task_id_t task_get_running(void);
-
-/**
- * Initializes the interrupt semaphore and associates a signal handler with
- * SIGNAL_INTERRUPT.
- */
-void task_register_interrupt(void);
-
-/**
- * Returns the process ID of the calling process.
- */
-pid_t getpid(void);
-
-#endif /* __CROS_EC_HOST_TASK_H */
diff --git a/core/host/irq_handler.h b/core/host/irq_handler.h
deleted file mode 100644
index f905f463c1..0000000000
--- a/core/host/irq_handler.h
+++ /dev/null
@@ -1,30 +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 routine(void); \
- void IRQ_HANDLER(irq)(void) \
- { \
- void *ret = __builtin_return_address(0); \
- task_start_irq_handler(ret); \
- routine(); \
- task_resched_if_needed(ret); \
- } \
- const struct irq_priority __keep IRQ_PRIORITY(irq) \
- __attribute__((section(".rodata.irqprio"))) \
- = {irq, priority}
-#endif /* __CROS_EC_IRQ_HANDLER_H */
diff --git a/core/host/main.c b/core/host/main.c
deleted file mode 100644
index ed7032eb63..0000000000
--- a/core/host/main.c
+++ /dev/null
@@ -1,108 +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.
- */
-
-/* Entry point of unit test executable */
-
-#include "console.h"
-#include "flash.h"
-#include "hooks.h"
-#include "host_task.h"
-#include "keyboard_scan.h"
-#include "stack_trace.h"
-#include "system.h"
-#include "task.h"
-#include "test_util.h"
-#include "timer.h"
-#include "uart.h"
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
-#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
-
-const char *__prog_name;
-
-const char *__get_prog_name(void)
-{
- return __prog_name;
-}
-
-static int test_main(void)
-{
- /*
- * In order to properly service IRQs before task switching is enabled,
- * we must set up our signal handler for the main thread.
- */
- task_register_interrupt();
-
- task_register_tracedump();
-
- register_test_end_hook();
-
- crec_flash_pre_init();
- system_pre_init();
- system_common_pre_init();
-
- test_init();
-
- timer_init();
-#ifdef HAS_TASK_KEYSCAN
- keyboard_scan_init();
-#endif
- uart_init();
-
- if (system_jumped_to_this_image()) {
- CPRINTS("Emulator initialized after sysjump");
- } else {
- CPUTS("\n\n--- Emulator initialized after reboot ---\n");
- CPUTS("[Reset cause: ");
- system_print_reset_flags();
- CPUTS("]\n");
- }
-
- task_start();
-
- return 0;
-}
-
-#ifdef TEST_FUZZ
-/*
- * Fuzzing tests need to start the main function in a thread, so that
- * LLVMFuzzerTestOneInput can run freely.
- */
-void *_main_thread(void *a)
-{
- test_main();
- return NULL;
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
-{
- static int initialized;
- static pthread_t main_t;
- /*
- * We lose the program name as LLVM fuzzer takes over main function:
- * make up one.
- */
- static const char *name = STRINGIFY(PROJECT)".exe";
-
- if (!initialized) {
- __prog_name = name;
- pthread_create(&main_t, NULL, _main_thread, NULL);
- initialized = 1;
- /* We can't sleep yet, busy loop waiting for tasks to start. */
- wait_for_task_started_nosleep();
- /* Let tasks settle. */
- msleep(50 * MSEC);
- }
-
- return test_fuzz_one_input(data, size);
-}
-#else
-int main(int argc, char **argv)
-{
- __prog_name = argv[0];
- return test_main();
-}
-#endif
diff --git a/core/host/panic.c b/core/host/panic.c
deleted file mode 100644
index 7b0829989d..0000000000
--- a/core/host/panic.c
+++ /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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "stack_trace.h"
-
-void panic_assert_fail(const char *msg, const char *func, const char *fname,
- int linenum)
-{
- fprintf(stderr, "ASSERTION FAIL: %s:%d:%s - %s\n",
- fname, linenum, func, msg);
- task_dump_trace();
-
- puts("Fail!"); /* Inform test runner */
- fflush(stdout);
-
- exit(1);
-}
diff --git a/core/host/stack_trace.c b/core/host/stack_trace.c
deleted file mode 100644
index adef66dd44..0000000000
--- a/core/host/stack_trace.c
+++ /dev/null
@@ -1,97 +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.
- */
-
-#include <execinfo.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "host_task.h"
-#include "host_test.h"
-#include "timer.h"
-
-#define SIGNAL_TRACE_DUMP SIGTERM
-#define MAX_TRACE 30
-/*
- * When trace dump is requested from signal handler, skip:
- * _task_dump_trace_impl
- * _task_dump_trace_dispath
- * A function in libc
- */
-#define SIGNAL_TRACE_OFFSET 3
-/*
- * When trace dump is requested from task_dump_trace(), skip:
- * task_dump_trace
- * _task_dump_trace_impl
- */
-#define DIRECT_TRACE_OFFSET 2
-
-static pthread_t main_thread;
-
-static void __attribute__((noinline)) _task_dump_trace_impl(int offset)
-{
- void *trace[MAX_TRACE];
- size_t sz;
- char **messages;
- char buf[256];
- FILE *file;
- int i, nb;
-
- sz = backtrace(trace, MAX_TRACE);
- messages = backtrace_symbols(trace + offset, sz - offset);
-
- for (i = 0; i < sz - offset; ++i) {
- fprintf(stderr, "#%-2d %s\n", i, messages[i]);
- /* %p is correct (as opposed to %pP) since this is the host */
- sprintf(buf, "addr2line %p -e %s",
- trace[i + offset], __get_prog_name());
- file = popen(buf, "r");
- if (file) {
- nb = fread(buf, 1, sizeof(buf) - 1, file);
- buf[nb] = '\0';
- fprintf(stderr, " %s", buf);
- pclose(file);
- }
- }
- fflush(stderr);
- free(messages);
-}
-
-void __attribute__((noinline)) task_dump_trace(void)
-{
- _task_dump_trace_impl(DIRECT_TRACE_OFFSET);
-}
-
-static void __attribute__((noinline)) _task_dump_trace_dispatch(int sig)
-{
- int need_dispatch = 1;
- task_id_t running = task_get_running();
-
- if (!pthread_equal(pthread_self(), main_thread)) {
- need_dispatch = 0;
- } else if (!task_start_called()) {
- fprintf(stderr, "Stack trace of main thread:\n");
- need_dispatch = 0;
- } else if (in_interrupt_context()) {
- fprintf(stderr, "Stack trace of ISR:\n");
- } else {
- fprintf(stderr, "Stack trace of task %d (%s):\n",
- running, task_get_name(running));
- }
-
- if (need_dispatch) {
- pthread_kill(task_get_thread(running), SIGNAL_TRACE_DUMP);
- } else {
- _task_dump_trace_impl(SIGNAL_TRACE_OFFSET);
- exit(1);
- }
-}
-
-void task_register_tracedump(void)
-{
- /* Trace dumper MUST be registered from main thread */
- main_thread = pthread_self();
- signal(SIGNAL_TRACE_DUMP, _task_dump_trace_dispatch);
-}
diff --git a/core/host/task.c b/core/host/task.c
deleted file mode 100644
index be7ed3c579..0000000000
--- a/core/host/task.c
+++ /dev/null
@@ -1,564 +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 <malloc.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "atomic.h"
-#include "common.h"
-#include "console.h"
-#include "host_task.h"
-#include "task.h"
-#include "task_id.h"
-#include "test_util.h"
-#include "timer.h"
-
-#define SIGNAL_INTERRUPT SIGUSR1
-
-struct emu_task_t {
- pthread_t thread;
- pthread_cond_t resume;
- uint32_t event;
- timestamp_t wake_time;
- uint8_t started;
-};
-
-struct task_args {
- void (*routine)(void *);
- void *d;
-};
-
-static struct emu_task_t tasks[TASK_ID_COUNT];
-static pthread_cond_t scheduler_cond;
-static pthread_mutex_t run_lock;
-static task_id_t running_task_id;
-static int task_started;
-
-static sem_t interrupt_sem;
-static pthread_mutex_t interrupt_lock;
-static pthread_t interrupt_thread;
-static int in_interrupt;
-static int interrupt_disabled;
-static void (*pending_isr)(void);
-static int generator_sleeping;
-static timestamp_t generator_sleep_deadline;
-static int has_interrupt_generator = 1;
-
-/* thread local task id */
-static __thread task_id_t my_task_id = TASK_ID_INVALID;
-
-static void task_enable_all_tasks_callback(void);
-
-#define TASK(n, r, d, s) void r(void *);
-CONFIG_TASK_LIST
-CONFIG_TEST_TASK_LIST
-CONFIG_CTS_TASK_LIST
-#undef TASK
-
-/* usleep that uses OS functions, instead of emulated timer. */
-void _usleep(int usec)
-{
- struct timespec req;
-
- req.tv_sec = usec / 1000000;
- req.tv_nsec = (usec % 1000000) * 1000;
-
- nanosleep(&req, NULL);
-}
-
-/* msleep that uses OS functions, instead of emulated timer. */
-void _msleep(int msec)
-{
- _usleep(1000 * msec);
-}
-
-/* Idle task */
-void __idle(void *d)
-{
- while (1)
- task_wait_event(-1);
-}
-
-void _run_test(void *d)
-{
- run_test(0, NULL);
-}
-
-#define TASK(n, r, d, s) {r, d},
-const struct task_args task_info[TASK_ID_COUNT] = {
- {__idle, NULL},
- CONFIG_TASK_LIST
- CONFIG_TEST_TASK_LIST
- CONFIG_CTS_TASK_LIST
- {_run_test, NULL},
-};
-#undef TASK
-
-#define TASK(n, r, d, s) #n,
-static const char * const task_names[] = {
- "<< idle >>",
- CONFIG_TASK_LIST
- CONFIG_TEST_TASK_LIST
- CONFIG_CTS_TASK_LIST
- "<< test runner >>",
-};
-#undef TASK
-
-void task_pre_init(void)
-{
- /* Nothing */
-}
-
-int in_interrupt_context(void)
-{
- return !!in_interrupt;
-}
-
-test_mockable void interrupt_disable(void)
-{
- pthread_mutex_lock(&interrupt_lock);
- interrupt_disabled = 1;
- pthread_mutex_unlock(&interrupt_lock);
-}
-
-test_mockable void interrupt_enable(void)
-{
- pthread_mutex_lock(&interrupt_lock);
- interrupt_disabled = 0;
- pthread_mutex_unlock(&interrupt_lock);
-}
-
-inline int is_interrupt_enabled(void)
-{
- return !interrupt_disabled;
-}
-
-static void _task_execute_isr(int sig)
-{
- in_interrupt = 1;
- pending_isr();
- sem_post(&interrupt_sem);
- in_interrupt = 0;
-}
-
-void task_register_interrupt(void)
-{
- sem_init(&interrupt_sem, 0, 0);
- signal(SIGNAL_INTERRUPT, _task_execute_isr);
-}
-
-void task_trigger_test_interrupt(void (*isr)(void))
-{
- pid_t main_pid;
- pthread_mutex_lock(&interrupt_lock);
- if (interrupt_disabled) {
- pthread_mutex_unlock(&interrupt_lock);
- return;
- }
-
- /* Suspend current task and excute ISR */
- pending_isr = isr;
- if (task_started) {
- pthread_kill(tasks[running_task_id].thread, SIGNAL_INTERRUPT);
- } else {
- main_pid = getpid();
- kill(main_pid, SIGNAL_INTERRUPT);
- }
-
- /* Wait for ISR to complete */
- sem_wait(&interrupt_sem);
- while (in_interrupt)
- _usleep(10);
- pending_isr = NULL;
-
- pthread_mutex_unlock(&interrupt_lock);
-}
-
-void interrupt_generator_udelay(unsigned us)
-{
- generator_sleep_deadline.val = get_time().val + us;
- generator_sleeping = 1;
- while (get_time().val < generator_sleep_deadline.val)
- ;
- generator_sleeping = 0;
-}
-
-const char *task_get_name(task_id_t tskid)
-{
- return task_names[tskid];
-}
-
-pthread_t task_get_thread(task_id_t tskid)
-{
- return tasks[tskid].thread;
-}
-
-uint32_t task_set_event(task_id_t tskid, uint32_t event)
-{
- atomic_or(&tasks[tskid].event, event);
- return 0;
-}
-
-uint32_t *task_get_event_bitmap(task_id_t tskid)
-{
- return &tasks[tskid].event;
-}
-
-uint32_t task_wait_event(int timeout_us)
-{
- int tid = task_get_current();
- int ret;
- pthread_mutex_lock(&interrupt_lock);
- if (timeout_us > 0)
- tasks[tid].wake_time.val = get_time().val + timeout_us;
-
- /* Transfer control to scheduler */
- pthread_cond_signal(&scheduler_cond);
- pthread_cond_wait(&tasks[tid].resume, &run_lock);
-
- /* Resume */
- ret = atomic_clear(&tasks[tid].event);
- pthread_mutex_unlock(&interrupt_lock);
- return ret;
-}
-
-uint32_t 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 |= task_wait_event(time_remaining_us);
-
- 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(&tasks[task_get_current()].event,
- events & ~event_mask);
-
- return events & event_mask;
-}
-
-void mutex_lock(struct mutex *mtx)
-{
- int value = 0;
- int id = 1 << task_get_current();
-
- mtx->waiters |= id;
-
- do {
- if (mtx->lock == 0) {
- mtx->lock = 1;
- value = 1;
- }
-
- if (!value)
- task_wait_event_mask(TASK_EVENT_MUTEX, 0);
- } while (!value);
-
- mtx->waiters &= ~id;
-}
-
-void mutex_unlock(struct mutex *mtx)
-{
- int v;
- mtx->lock = 0;
-
- for (v = 31; v >= 0; --v)
- if ((1ul << v) & mtx->waiters) {
- mtx->waiters &= ~(1ul << v);
- task_set_event(v, TASK_EVENT_MUTEX);
- break;
- }
-}
-
-task_id_t task_get_current(void)
-{
- return my_task_id;
-}
-
-task_id_t task_get_running(void)
-{
- return running_task_id;
-}
-
-void task_print_list(void)
-{
- int i;
-
- ccputs("Name Events\n");
-
- for (i = 0; i < TASK_ID_COUNT; i++) {
- ccprintf("%4d %-16s %08x\n", i, task_names[i], tasks[i].event);
- cflush();
- }
-}
-
-int command_task_info(int argc, char **argv)
-{
- task_print_list();
-
- return EC_SUCCESS;
-}
-DECLARE_SAFE_CONSOLE_COMMAND(taskinfo, command_task_info,
- NULL,
- "Print task info");
-
-static void _wait_for_task_started(int can_sleep)
-{
- int i, ok;
-
- while (1) {
- ok = 1;
- for (i = 0; i < TASK_ID_COUNT - 1; ++i) {
- if (!tasks[i].started) {
- if (can_sleep)
- msleep(10);
- else
- _msleep(10);
- ok = 0;
- break;
- }
- }
- if (ok)
- return;
- }
-}
-
-void wait_for_task_started(void)
-{
- _wait_for_task_started(1);
-}
-
-void wait_for_task_started_nosleep(void)
-{
- _wait_for_task_started(0);
-}
-
-static task_id_t task_get_next_wake(void)
-{
- int i;
- timestamp_t min_time;
- int which_task = TASK_ID_INVALID;
-
- min_time.val = ~0ull;
-
- for (i = TASK_ID_COUNT - 1; i >= 0; --i)
- if (min_time.val >= tasks[i].wake_time.val) {
- min_time.val = tasks[i].wake_time.val;
- which_task = i;
- }
-
- return which_task;
-}
-
-static int fast_forward(void)
-{
- /*
- * No task has event pending, and thus the next time we have an
- * event to process must be either of:
- * 1. Interrupt generator triggers an interrupt
- * 2. The next wake alarm is reached
- * So we should check whether an interrupt may happen, and fast
- * forward to the nearest among:
- * 1. When interrupt generator wakes up
- * 2. When the next task wakes up
- */
- int task_id = task_get_next_wake();
-
- if (!has_interrupt_generator) {
- if (task_id == TASK_ID_INVALID) {
- return TASK_ID_IDLE;
- } else {
- force_time(tasks[task_id].wake_time);
- return task_id;
- }
- }
-
- if (!generator_sleeping)
- return TASK_ID_IDLE;
-
- if (task_id != TASK_ID_INVALID &&
- tasks[task_id].thread != (pthread_t)NULL &&
- tasks[task_id].wake_time.val < generator_sleep_deadline.val) {
- force_time(tasks[task_id].wake_time);
- return task_id;
- } else {
- force_time(generator_sleep_deadline);
- return TASK_ID_IDLE;
- }
-}
-
-int task_start_called(void)
-{
- return task_started;
-}
-
-void task_scheduler(void)
-{
- int i;
- timestamp_t now;
-
- task_started = 1;
-
- while (1) {
- now = get_time();
- i = TASK_ID_COUNT - 1;
- while (i >= 0) {
- /*
- * Only tasks with spawned threads are valid to be
- * resumed.
- */
- if (tasks[i].thread) {
- if (tasks[i].event ||
- now.val >= tasks[i].wake_time.val)
- break;
- }
- --i;
- }
- if (i < 0)
- i = fast_forward();
-
- now = get_time();
- if (now.val >= tasks[i].wake_time.val)
- tasks[i].event |= TASK_EVENT_TIMER;
- tasks[i].wake_time.val = ~0ull;
- running_task_id = i;
- tasks[i].started = 1;
- pthread_cond_signal(&tasks[i].resume);
- pthread_cond_wait(&scheduler_cond, &run_lock);
- }
-}
-
-void *_task_start_impl(void *a)
-{
- long tid = (long)a;
- const struct task_args *arg = task_info + tid;
- my_task_id = tid;
- pthread_mutex_lock(&run_lock);
-
- /* Wait for scheduler */
- task_wait_event(1);
- tasks[tid].event = 0;
-
- /* Start the task routine */
- (arg->routine)(arg->d);
-
- /* Catch exited routine */
- while (1)
- task_wait_event(-1);
-}
-
-test_mockable void interrupt_generator(void)
-{
- has_interrupt_generator = 0;
-}
-
-void *_task_int_generator_start(void *d)
-{
- my_task_id = TASK_ID_INT_GEN;
- interrupt_generator();
- return NULL;
-}
-
-int task_start(void)
-{
- int i = TASK_ID_HOOKS;
-
- pthread_mutex_init(&run_lock, NULL);
- pthread_mutex_init(&interrupt_lock, NULL);
- pthread_cond_init(&scheduler_cond, NULL);
-
- pthread_mutex_lock(&run_lock);
-
- /*
- * Initialize the hooks task first. After its init, it will callback to
- * enable the remaining tasks.
- */
- tasks[i].event = TASK_EVENT_WAKE;
- tasks[i].wake_time.val = ~0ull;
- tasks[i].started = 0;
- pthread_cond_init(&tasks[i].resume, NULL);
- pthread_create(&tasks[i].thread, NULL, _task_start_impl,
- (void *)(uintptr_t)i);
- pthread_cond_wait(&scheduler_cond, &run_lock);
- /*
- * Interrupt lock is grabbed by the task which just started.
- * Let's unlock it so the next task can be started.
- */
- pthread_mutex_unlock(&interrupt_lock);
-
- /*
- * The hooks task is waiting in task_wait_event(). Lock interrupt_lock
- * here so the first task chosen sees it locked.
- */
- pthread_mutex_lock(&interrupt_lock);
-
- pthread_create(&interrupt_thread, NULL,
- _task_int_generator_start, NULL);
-
- /*
- * Tell the hooks task to continue so that it can call back to enable
- * the other tasks.
- */
- pthread_cond_signal(&tasks[i].resume);
- pthread_cond_wait(&scheduler_cond, &run_lock);
- task_enable_all_tasks_callback();
-
- task_scheduler();
-
- return 0;
-}
-
-static void task_enable_all_tasks_callback(void)
-{
- int i;
-
- /* Initialize the remaning tasks. */
- for (i = 0; i < TASK_ID_COUNT; ++i) {
- if (tasks[i].thread != (pthread_t)NULL)
- continue;
-
- tasks[i].event = TASK_EVENT_WAKE;
- tasks[i].wake_time.val = ~0ull;
- tasks[i].started = 0;
- pthread_cond_init(&tasks[i].resume, NULL);
- pthread_create(&tasks[i].thread, NULL, _task_start_impl,
- (void *)(uintptr_t)i);
- /*
- * Interrupt lock is grabbed by the task which just started.
- * Let's unlock it so the next task can be started.
- */
- pthread_mutex_unlock(&interrupt_lock);
- pthread_cond_wait(&scheduler_cond, &run_lock);
- }
-
-}
-
-void task_enable_all_tasks(void)
-{
- /* Signal to the scheduler to enable the remaining tasks. */
- pthread_cond_signal(&scheduler_cond);
-}
diff --git a/core/host/timer.c b/core/host/timer.c
deleted file mode 100644
index 3c3695cad4..0000000000
--- a/core/host/timer.c
+++ /dev/null
@@ -1,105 +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.
- */
-
-/* Timer module */
-
-#include <stdint.h>
-#include <stdio.h>
-
-#include "task.h"
-#include "test_util.h"
-#include "timer.h"
-#include "util.h"
-
-static timestamp_t boot_time;
-static int time_set;
-
-void usleep(unsigned us)
-{
- if (!task_start_called() || task_get_current() == TASK_ID_INVALID) {
- udelay(us);
- return;
- }
-
- ASSERT(!in_interrupt_context() &&
- task_get_current() != TASK_ID_INT_GEN);
-
- task_wait_event(us);
-}
-
-timestamp_t _get_time(void)
-{
- static timestamp_t time;
-
- /*
- * We just monotonically increase the microsecond every time we check
- * the time. Do not depend on host system time as this introduces
- * flakyness in tests. The time is periodically fast forwarded with
- * force_time() during the host's task scheduler implementation.
- */
- ++time.val;
- return time;
-}
-
-test_mockable timestamp_t get_time(void)
-{
- timestamp_t ret = _get_time();
- ret.val -= boot_time.val;
- return ret;
-}
-
-uint32_t __hw_clock_source_read(void)
-{
- return get_time().le.lo;
-}
-
-void force_time(timestamp_t ts)
-{
- timestamp_t now = _get_time();
- boot_time.val = now.val - ts.val;
- time_set = 1;
-}
-
-void udelay(unsigned us)
-{
- timestamp_t deadline;
-
- if (!in_interrupt_context() && task_get_current() == TASK_ID_INT_GEN) {
- interrupt_generator_udelay(us);
- return;
- }
-
- deadline.val = get_time().val + us;
- while (get_time().val < deadline.val)
- ;
-}
-
-int timestamp_expired(timestamp_t deadline, const timestamp_t *now)
-{
- timestamp_t now_val;
-
- if (!now) {
- now_val = get_time();
- now = &now_val;
- }
-
- return ((int64_t)(now->val - deadline.val) >= 0);
-}
-
-void timer_init(void)
-{
-
- if (!time_set) {
- /*
- * Start the timer just before the 64-bit rollover to try
- * and catch 32-bit rollover/truncation bugs.
- */
- timestamp_t ts = {
- .val = 0xFFFFFFF0
- };
-
- force_time(ts);
- }
-}
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 b634c3a551..0000000000
--- a/core/nds32/atomic.h
+++ /dev/null
@@ -1,78 +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"
-
-typedef int atomic_t;
-typedef atomic_t atomic_val_t;
-
-static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits)
-{
- atomic_val_t ret;
- atomic_t volatile *ptr = addr;
- uint32_t int_mask = read_clear_int_mask();
-
- ret = *ptr;
- *ptr &= ~bits;
- set_int_mask(int_mask);
- return ret;
-}
-
-static inline atomic_val_t atomic_or(atomic_t *addr, atomic_val_t bits)
-{
- atomic_val_t ret;
- atomic_t volatile *ptr = addr;
- uint32_t int_mask = read_clear_int_mask();
-
- ret = *ptr;
- *ptr |= bits;
- set_int_mask(int_mask);
- return ret;
-}
-
-static inline atomic_val_t atomic_add(atomic_t *addr, atomic_val_t value)
-{
- atomic_val_t ret;
- atomic_t volatile *ptr = addr;
- uint32_t int_mask = read_clear_int_mask();
-
- ret = *ptr;
- *ptr += value;
- set_int_mask(int_mask);
- return ret;
-}
-
-static inline atomic_val_t atomic_sub(atomic_t *addr, atomic_val_t value)
-{
- atomic_val_t ret;
- atomic_t volatile *ptr = addr;
- uint32_t int_mask = read_clear_int_mask();
-
- ret = *ptr;
- *ptr -= value;
- set_int_mask(int_mask);
- return ret;
-}
-
-static inline atomic_val_t atomic_clear(atomic_t *addr)
-{
- atomic_val_t ret;
- atomic_t volatile *ptr = addr;
- uint32_t int_mask = read_clear_int_mask();
-
- ret = *ptr;
- *ptr = 0;
- set_int_mask(int_mask);
- return ret;
-}
-
-#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 3bd5a93efc..0000000000
--- a/core/nds32/cpu.h
+++ /dev/null
@@ -1,70 +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
-
-/*
- * This is the space required by both irq_x_ and __switch_task to store all
- * of the caller and callee registers for each task context before switching.
- */
-#define TASK_SCRATCHPAD_SIZE (18)
-
-/* 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)
-
-#ifndef __ASSEMBLER__
-
-#include <stdint.h>
-
-/* 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 /* !__ASSEMBLER__ */
-
-#endif /* __CROS_EC_CPU_H */
diff --git a/core/nds32/ec.lds.S b/core/nds32/ec.lds.S
deleted file mode 100644
index 2c21b94761..0000000000
--- a/core/nds32/ec.lds.S
+++ /dev/null
@@ -1,321 +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_PERIPHERAL)
- 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 = .;
-
-#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK
- __hooks_chipset_resume_init = .;
- KEEP(*(.rodata.HOOK_CHIPSET_RESUME_INIT))
- __hooks_chipset_resume_init_end = .;
-
- __hooks_chipset_suspend_complete = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SUSPEND_COMPLETE))
- __hooks_chipset_suspend_complete_end = .;
-#endif
-
- __hooks_chipset_shutdown = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN))
- __hooks_chipset_shutdown_end = .;
-
- __hooks_chipset_shutdown_complete = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN_COMPLETE))
- __hooks_chipset_shutdown_complete_end = .;
-
- __hooks_chipset_hard_off = .;
- KEEP(*(.rodata.HOOK_CHIPSET_HARD_OFF))
- __hooks_chipset_hard_off_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*)
-
-#ifdef CONFIG_CHIP_INIT_ROM_REGION
- ASSERT(0, "CONFIG_CHIP_INIT_ROM_REGION not supported by linker script")
-#endif /* CONFIG_CHIP_INIT_ROM_REGION */
- /*
- * This linker file does not yet support a separate ROM resident
- * section. Ensure the corresponding data objects are linked
- * into the .rodata section.
- */
- . = ALIGN(4);
- __init_rom_start = .;
- *(.init.rom)
- __init_rom_end = .;
-
-#if defined(SECTION_IS_RO) && defined(CONFIG_FLASH_CROS)
- . = 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)
- . = ALIGN(8);
- *(.bss.system_stack)
- . = ALIGN(8);
- *(.bss.task_scratchpad)
- /* 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);
-
- /*
- * __flash_used is used in flash free calculations by the makefile.
- * __image_size is stored in the struct image_data header and used
- * in hash calcuations.
- */
- __flash_used = LOADADDR(.data) + SIZEOF(.data) - FW_OFF(SECTION);
- __image_size = __flash_used;
-
-#ifdef CONFIG_FLASH_CROS
- /*
- * These linker labels are just for analysis and not used in the code.
- */
- __config_flash_size = CONFIG_FLASH_SIZE_BYTES;
- __config_ro_size = CONFIG_RO_SIZE;
- __config_ec_protected_storage_size = CONFIG_EC_PROTECTED_STORAGE_SIZE;
- __config_rw_size = CONFIG_RW_SIZE;
- __config_ec_writable_storage_size = CONFIG_EC_WRITABLE_STORAGE_SIZE;
-#endif
-
-#if defined(CONFIG_HOSTCMD_X86) || defined(CONFIG_I2C_PERIPHERAL)
- .h2ram (NOLOAD) : {
- . += CONFIG_H2RAM_HOST_LPC_IO_BASE;
- *(.h2ram.pool.hostcmd)
- . = ALIGN(256);
- *(.h2ram.pool.acpiec)
-#ifdef CONFIG_I2C_PERIPHERAL
- . = 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_CROS))
- /DISCARD/ : { *(.google) }
-#endif
-
- /DISCARD/ : { *(.ARM.*) }
-}
diff --git a/core/nds32/include/fpu.h b/core/nds32/include/fpu.h
deleted file mode 100644
index 4f3efc2e5a..0000000000
--- a/core/nds32/include/fpu.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_FPU_H
-#define __CROS_EC_FPU_H
-
-float sqrtf(float x);
-float fabsf(float x);
-
-#endif /* __CROS_EC_FPU_H */
diff --git a/core/nds32/init.S b/core/nds32/init.S
deleted file mode 100644
index b8e109c434..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 valid 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 ca517558b3..0000000000
--- a/core/nds32/irq_chip.h
+++ /dev/null
@@ -1,61 +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.
- */
-void chip_enable_irq(int irq);
-
-/**
- * Disable an IRQ in the chip interrupt controller.
- *
- * @param irq interrupt request index.
- */
-void chip_disable_irq(int irq);
-
-/**
- * Clear a pending IRQ in the chip interrupt controller.
- *
- * @param irq interrupt request index.
- *
- * 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.
- */
-void 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 external interrupt number.
- */
-int chip_get_ec_int(void);
-
-/**
- * Return group number of the given external interrupt number.
- */
-int chip_get_intc_group(int irq);
-
-#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 eb55d9e233..0000000000
--- a/core/nds32/irq_handler.h
+++ /dev/null
@@ -1,26 +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 routine(void); \
- 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 70e2cae3e0..0000000000
--- a/core/nds32/panic.c
+++ /dev/null
@@ -1,209 +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
-
-#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)
-{
- /*
- * It is safe to get pointer using get_panic_data_write().
- * If it was called earlier (eg. when saving nds_n8.ipc) calling it
- * once again won't remove any data
- */
- struct panic_data * const pdata = get_panic_data_write();
- uint32_t warning_ipc;
- uint32_t *regs;
-
- regs = pdata->nds_n8.regs;
-
- /* Setup panic data structure */
- if (reason != PANIC_SW_WATCHDOG) {
- memset(pdata, 0, CONFIG_PANIC_DATA_SIZE);
- } else {
- warning_ipc = pdata->nds_n8.ipc;
- memset(pdata, 0, CONFIG_PANIC_DATA_SIZE);
- pdata->nds_n8.ipc = warning_ipc;
- }
- pdata->magic = PANIC_DATA_MAGIC;
- pdata->struct_size = CONFIG_PANIC_DATA_SIZE;
- pdata->struct_version = 2;
- pdata->arch = PANIC_ARCH_NDS32_N8;
-
- /* Log panic cause */
- pdata->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)
-{
- struct panic_data * const pdata = panic_get_data();
- uint32_t *regs;
-
- if (pdata && pdata->struct_version == 2) {
- regs = pdata->nds_n8.regs;
- *exception = pdata->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 * const pdata = get_panic_data_write();
-
- pdata->magic = PANIC_DATA_MAGIC;
- pdata->struct_size = CONFIG_PANIC_DATA_SIZE;
- 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 631b0e0fe2..0000000000
--- a/core/nds32/switch.S
+++ /dev/null
@@ -1,109 +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"
-#include "cpu.h"
-
-.section .ram_code
-
-/**
- * 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
-
-.text
-/**
- * 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:
- /*
- * Disable global interrupt here to ensure below sequence won't be
- * broken. The "iret" instruction of ISR will enable GIE again.
- */
- setgie.d
- /* area used as 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 stack pointer at the top of the stack in scratchpad */
- addi $sp, $r3, 4 * TASK_SCRATCHPAD_SIZE
- /* 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 edacb7975e..0000000000
--- a/core/nds32/task.c
+++ /dev/null
@@ -1,794 +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 uint32_t exc_sub_time;
-static uint64_t task_start_time; /* Time task scheduling started */
-static uint32_t exc_start_time; /* Time of task->exception transition */
-static uint32_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];
-/* Validity 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[TASK_SCRATCHPAD_SIZE] __attribute__
- ((section(".bss.task_scratchpad")));
-
-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;
-
-/*
- * 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 is_interrupt_enabled(void)
-{
- uint32_t val = 0;
-
- asm volatile ("mfsr %0, $INT_MASK" : "=r"(val));
-
- /* Interrupts are enabled if any of HW2 ~ HW15 is enabled */
- return !!(val & 0xFFFC);
-}
-
-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 invalid task id if task scheduling is not yet start */
- return start_called ? (current_task - tasks) : TASK_ID_INVALID;
-}
-
-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;
-}
-
-/**
- * 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) {
- 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();
-
- 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().le.lo;
-#endif
-}
-
-/* Interrupt number of EC modules */
-volatile int ec_int;
-
-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 = sw_int_num;
- else
- ec_int = chip_get_ec_int();
-
-#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
- uint32_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().le.lo;
- 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_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_bits(&tsk->events, TASK_EVENT_TIMER);
- }
- return evt;
-}
-
-uint32_t __ram_code task_set_event(task_id_t tskid, uint32_t event)
-{
- 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 {
- __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 read_clear_int_mask(void)
-{
- uint32_t int_mask, int_dis = BIT(30);
-
- asm volatile(
- "mfsr %0, $INT_MASK\n\t"
- "mtsr %1, $INT_MASK\n\t"
- "dsb\n\t"
- : "=&r"(int_mask)
- : "r"(int_dis));
-
- return int_mask;
-}
-
-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_bits(&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 = read_clear_int_mask();
-
- chip_enable_irq(irq);
- set_int_mask(int_mask);
-}
-
-void __ram_code task_disable_irq(int irq)
-{
- uint32_t int_mask = read_clear_int_mask();
-
- 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;
-
- /*
- * we need to read to waiters after giving the lock back
- * otherwise we might miss a waiter between the two calls.
- *
- * prevent compiler reordering
- */
- asm volatile(
- /* give back the lock */
- "movi %0, #0\n\t"
- "lwi %1, [%2]\n\t"
- : "=&r"(mtx->lock), "=&r"(waiters)
- : "r"(&mtx->waiters));
-
- while (waiters) {
- task_id_t id = __fls(waiters);
- waiters &= ~BIT(id);
-
- /* Somebody is waiting on the mutex */
- task_set_event(id, TASK_EVENT_MUTEX);
- }
-
- /* Ensure no event is remaining from mutex wake-up */
- atomic_clear_bits(&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 = get_time().val;
- exc_end_time = get_time().le.lo;
-#endif
-
- return __task_start();
-}
diff --git a/core/riscv-rv32i/__builtin.c b/core/riscv-rv32i/__builtin.c
deleted file mode 100644
index 4bf495a011..0000000000
--- a/core/riscv-rv32i/__builtin.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright 2019 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/riscv-rv32i/atomic.h b/core/riscv-rv32i/atomic.h
deleted file mode 100644
index e92beb2ca0..0000000000
--- a/core/riscv-rv32i/atomic.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright 2019 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 RISC_V */
-
-#ifndef __CROS_EC_ATOMIC_H
-#define __CROS_EC_ATOMIC_H
-
-#include "common.h"
-#include "cpu.h"
-#include "task.h"
-
-typedef int atomic_t;
-typedef atomic_t atomic_val_t;
-
-static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits)
-{
- return __atomic_fetch_and(addr, ~bits, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_or(atomic_t *addr, atomic_val_t bits)
-{
- return __atomic_fetch_or(addr, bits, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_add(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_add(addr, value, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_sub(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_sub(addr, value, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_clear(atomic_t *addr)
-{
- return __atomic_exchange_n(addr, 0, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_read_add(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_add(addr, value, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_read_sub(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_sub(addr, value, __ATOMIC_SEQ_CST);
-}
-
-#endif /* __CROS_EC_ATOMIC_H */
diff --git a/core/riscv-rv32i/build.mk b/core/riscv-rv32i/build.mk
deleted file mode 100644
index 34f059e70c..0000000000
--- a/core/riscv-rv32i/build.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- makefile -*-
-# Copyright 2019 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.
-#
-# RISC-V core OS files build
-#
-
-# Select RISC-V bare-metal toolchain
-$(call set-option,CROSS_COMPILE,$(CROSS_COMPILE_riscv),\
- /opt/coreboot-sdk/bin/riscv64-elf-)
-
-# Enable FPU extension if config option of FPU is enabled.
-_FPU_EXTENSION=$(if $(CONFIG_FPU),f,)
-# CPU specific compilation flags
-CFLAGS_CPU+=-march=rv32ima$(_FPU_EXTENSION)c -mabi=ilp32$(_FPU_EXTENSION) -Os
-# RISC-V does not trap division by zero, enable the sanitizer to check those.
-# With `-fsanitize-undefined-trap-on-error`, we lose a bit of specificity on the
-# exact issue, but the added code is as small as it gets.
-CFLAGS_CPU+=-fsanitize=integer-divide-by-zero -fsanitize-undefined-trap-on-error
-LDFLAGS_EXTRA+=-mrelax
-LDFLAGS_EXTRA+=-static-libgcc -lgcc
-
-ifneq ($(CONFIG_LTO),)
-CFLAGS_CPU+=-flto
-LDFLAGS_EXTRA+=-flto
-endif
-
-core-y=cpu.o init.o panic.o task.o switch.o __builtin.o math.o
diff --git a/core/riscv-rv32i/config_core.h b/core/riscv-rv32i/config_core.h
deleted file mode 100644
index fe6135683d..0000000000
--- a/core/riscv-rv32i/config_core.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright 2019 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 riscv
-#define BFD_FORMAT "elf32-littleriscv"
-
-/*
- * The hardware doesn't support the risc-v bit manipulation
- * extension (CLZ/CTZ instructions) so let's use the software implementation.
- */
-#define CONFIG_SOFTWARE_CLZ
-#define CONFIG_SOFTWARE_CTZ
-#define CONFIG_SOFTWARE_PANIC
-
-#endif /* __CROS_EC_CONFIG_CORE_H */
diff --git a/core/riscv-rv32i/cpu.c b/core/riscv-rv32i/cpu.c
deleted file mode 100644
index fd18896846..0000000000
--- a/core/riscv-rv32i/cpu.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Copyright 2019 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 RISC-V core
- */
-
-#include "cpu.h"
-
-void cpu_init(void)
-{
- /* bit3: Global interrupt enable (M-mode) */
- asm volatile ("csrsi mstatus, 0x8");
-}
diff --git a/core/riscv-rv32i/cpu.h b/core/riscv-rv32i/cpu.h
deleted file mode 100644
index e46b893ad6..0000000000
--- a/core/riscv-rv32i/cpu.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright 2019 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 RISC-V cores
- */
-
-#ifndef __CROS_EC_CPU_H
-#define __CROS_EC_CPU_H
-
-/*
- * This is the space required by both __irq_isr and __switch_task to store all
- * of the caller and callee registers for each task context before switching.
- */
-#ifdef CONFIG_FPU
-/* additional space to save FP registers (fcsr, ft0-11, fa0-7, fs0-11) */
-#define TASK_SCRATCHPAD_SIZE (62)
-#else
-#define TASK_SCRATCHPAD_SIZE (29)
-#endif
-
-#ifndef __ASSEMBLER__
-#include <stdint.h>
-
-/* write Exception Program Counter register */
-static inline void set_mepc(uint32_t val)
-{
- asm volatile ("csrw mepc, %0" : : "r"(val));
-}
-
-/* read Exception Program Counter register */
-static inline uint32_t get_mepc(void)
-{
- uint32_t ret;
-
- asm volatile ("csrr %0, mepc" : "=r"(ret));
- return ret;
-}
-
-/* read Trap cause register */
-static inline uint32_t get_mcause(void)
-{
- uint32_t ret;
-
- asm volatile ("csrr %0, mcause" : "=r"(ret));
- return ret;
-}
-
-/* Generic CPU core initialization */
-void cpu_init(void);
-extern uint32_t ec_reset_lp;
-extern uint32_t ira;
-#endif
-
-#endif /* __CROS_EC_CPU_H */
diff --git a/core/riscv-rv32i/ec.lds.S b/core/riscv-rv32i/ec.lds.S
deleted file mode 100644
index e8963c1b14..0000000000
--- a/core/riscv-rv32i/ec.lds.S
+++ /dev/null
@@ -1,458 +0,0 @@
-/* Copyright 2019 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
-{
-#if defined(CONFIG_FLASH_PHYSICAL)
- FLASH (rx) : ORIGIN = FW_OFF(SECTION) - CHIP_ILM_BASE, \
- LENGTH = FW_SIZE(SECTION)
-#else
- IROM (rx) : ORIGIN = CONFIG_ROM_BASE, LENGTH = CONFIG_ROM_SIZE
-#endif
-
-#if defined(CHIP_FAMILY_IT8XXX2)
- /*
- * On IT8XXX2 family, it reserves space for ramcode, h2ram, and
- * immu sections.
- */
- IRAM (rw) : ORIGIN = CONFIG_RAM_BASE + CHIP_RAM_SPACE_RESERVED,
- LENGTH = CONFIG_RAM_SIZE - CHIP_RAM_SPACE_RESERVED
- /*
- * ILM (Instruction Local Memory).
- * We connect ILM to internal flash so we are able to
- * boot from the flash.
- */
- ILM (rx) : ORIGIN = FW_OFF(SECTION), LENGTH = FW_SIZE(SECTION)
-
-#if defined(CONFIG_HOSTCMD_X86) || defined(CONFIG_I2C_PERIPHERAL)
- H2RAM (rw) : ORIGIN = CONFIG_H2RAM_BASE, LENGTH = CONFIG_H2RAM_SIZE
-#endif
-#else
- IRAM (rw) : ORIGIN = CONFIG_RAM_BASE, LENGTH = CONFIG_RAM_SIZE
-#endif /* CHIP_FAMILY_IT8XXX2 */
-
-#ifdef CONFIG_DRAM_BASE
- DRAM (rwx) : ORIGIN = CONFIG_DRAM_BASE, LENGTH = CONFIG_DRAM_SIZE
-#endif
-}
-
-SECTIONS
-{
- .text : {
-#if defined(CHIP_FAMILY_IT8XXX2)
- /*
- * 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");
-#endif
- 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))
-#if defined(CHIP_FAMILY_IT8XXX2)
- 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);
- __ilm0_ram_code = .;
- OUTDIR/chip/it83xx/i2c.o (.text*)
- OUTDIR/chip/it83xx/i2c.o (.rodata)
- OUTDIR/chip/it83xx/hwtimer.o (.text*)
- OUTDIR/chip/it83xx/hwtimer.o (.rodata)
- . = ALIGN(16);
-#endif
- *(.text*)
- . = ALIGN(4);
-#if defined(CONFIG_FLASH_PHYSICAL)
-# if defined(CHIP_FAMILY_IT8XXX2)
- } > ILM AT > FLASH
-# else
- } > FLASH
-# endif
-#else
- } > IROM
-#endif /* CONFIG_FLASH_PHYSICAL */
-
- . = 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 = .;
-
-#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK
- __hooks_chipset_resume_init = .;
- KEEP(*(.rodata.HOOK_CHIPSET_RESUME_INIT))
- __hooks_chipset_resume_init_end = .;
-
- __hooks_chipset_suspend_complete = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SUSPEND_COMPLETE))
- __hooks_chipset_suspend_complete_end = .;
-#endif
-
- __hooks_chipset_shutdown = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN))
- __hooks_chipset_shutdown_end = .;
-
- __hooks_chipset_shutdown_complete = .;
- KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN_COMPLETE))
- __hooks_chipset_shutdown_complete_end = .;
-
- __hooks_chipset_hard_off = .;
- KEEP(*(.rodata.HOOK_CHIPSET_HARD_OFF))
- __hooks_chipset_hard_off_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*)
-
-#ifdef CONFIG_CHIP_INIT_ROM_REGION
- ASSERT(0, "CONFIG_CHIP_INIT_ROM_REGION not supported by linker script")
-#endif /* CONFIG_CHIP_INIT_ROM_REGION */
- /*
- * This linker file does not yet support a separate ROM resident
- * section. Ensure the corresponding data objects are linked
- * into the .rodata section.
- */
- . = ALIGN(4);
- __init_rom_start = .;
- *(.init.rom)
- __init_rom_end = .;
-
- . = ALIGN(4);
- *(.srodata*)
-#if defined(SECTION_IS_RO) && defined(CONFIG_FLASH_CROS)
- . = ALIGN(64);
- KEEP(*(.google))
-#endif
- . = ALIGN(4);
-#if defined(CONFIG_FLASH_PHYSICAL)
-# if defined(CHIP_FAMILY_IT8XXX2)
- } > ILM AT > FLASH
-# else
- } > FLASH
-# endif
-#else
- } > IROM
-#endif /* CONFIG_FLASH_PHYSICAL */
-
- __data_lma_start = .;
-
-#ifdef CONFIG_PRESERVE_LOGS
- .preserve_logs(NOLOAD) : {
- /*
- * The address of the preserved logs is fixed at the beginning
- * of memory.
- */
- . = ALIGN(8);
- __preserved_logs_start = .;
- *(SORT(.preserved_logs.*))
- . = ALIGN(8);
- __preserved_logs_end = .;
- } > IRAM
- __preserved_logs_size = __preserved_logs_end - __preserved_logs_start;
-#ifdef CONFIG_IT83XX_HARD_RESET_BY_GPG1
- ASSERT(__preserved_logs_size <= CHIP_FLASH_PRESERVE_LOGS_SIZE,
- "Not enough flash space to save EC logs.")
-#endif
-#endif /* CONFIG_PRESERVE_LOGS */
-
- .data : {
- . = ALIGN(4);
- __data_start = .;
- *(.data)
- *(.sdata)
- . = ALIGN(4);
- __data_end = .;
-#if defined(CONFIG_FLASH_PHYSICAL)
- } > IRAM AT > FLASH
-#else
- } > IRAM AT > IROM
-#endif
-
- .bss : {
- /* Stacks must be 128-bit aligned */
- . = ALIGN(16);
- __bss_start = .;
- *(.bss.tasks)
- . = ALIGN(16);
- *(.bss.system_stack)
- . = ALIGN(16);
- *(.bss.task_scratchpad)
- . = ALIGN(16);
- __global_pointer$ = .;
- *(.sbss)
- . = ALIGN(4);
- /* 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);
-
- /*
- * __flash_used is used in flash free calculations by the makefile.
- * __image_size is stored in the struct image_data header and used
- * in hash calcuations.
- */
-#if defined(CHIP_FAMILY_IT8XXX2)
- __flash_used = LOADADDR(.data) + SIZEOF(.data) + \
- CHIP_ILM_BASE - FW_OFF(SECTION);
-#else
- __flash_used = LOADADDR(.data) + SIZEOF(.data) - FW_OFF(SECTION);
-#endif
- __image_size = __flash_used;
-
-#ifdef CONFIG_FLASH_CROS
- /*
- * These linker labels are just for analysis and not used in the code.
- */
- __config_flash_size = CONFIG_FLASH_SIZE_BYTES;
- __config_ro_size = CONFIG_RO_SIZE;
- __config_ec_protected_storage_size = CONFIG_EC_PROTECTED_STORAGE_SIZE;
- __config_rw_size = CONFIG_RW_SIZE;
- __config_ec_writable_storage_size = CONFIG_EC_WRITABLE_STORAGE_SIZE;
-#endif
-
-#if defined(CHIP_FAMILY_IT8XXX2)
-#if defined(CONFIG_HOSTCMD_X86) || defined(CONFIG_I2C_PERIPHERAL)
- .h2ram (NOLOAD) : {
- . += CONFIG_H2RAM_HOST_LPC_IO_BASE;
- *(.h2ram.pool.hostcmd)
- . = ALIGN(256);
- *(.h2ram.pool.acpiec)
-#ifdef CONFIG_I2C_PERIPHERAL
- . = 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
-#endif /* CHIP_FAMILY_IT8XXX2 */
-
-#ifdef CONFIG_DRAM_BASE
- /*
- * Sections in DRAM region are constructed as like in non-DRAM regions:
- * .dram.data LMA is for preserving initialized data across resets.
- * The only difference is that they are all in the DRAM region:
- * .dram.text | LOAD
- * .dram.rodata | LOAD
- * .dram.data LMA | LOAD
- * .dram.data VMA |
- * .dram.bss | NOLOAD
- */
-
- .dram.text : {
- . = ALIGN(4);
- KEEP(*(SORT(.dram.text.keep.*)))
- *(SORT(.dram.text.*))
- . = ALIGN(4);
- } > DRAM
-
- .dram.rodata : {
- . = ALIGN(4);
- KEEP(*(SORT(.dram.rodata.keep.*)))
- *(SORT(.dram.rodata.*))
- . = ALIGN(4);
- } > DRAM
-
- __dram_data_lma_start = ADDR(.dram.rodata) + SIZEOF(.dram.rodata);
-
- /* Place .dram.data LMA in between .dram.rodata and .dram.data VMA. */
- .dram.data __dram_data_lma_start +
- (__dram_data_end - __dram_data_start) : {
- . = ALIGN(4);
- __dram_data_start = .;
- *(.dram.data*)
- . = ALIGN(4);
- __dram_data_end = .;
-
- /*
- * Normally, '> DRAM AT > DRAM' should be the same as '> DRAM',
- * and they will be at the same address. However, if the address
- * of VMA specified, LMA and VMA might have different addresses:
- * '> DRAM' places VMA at the address where section declaration
- * specified.
- * 'AT > DRAM' places LMA at the location counter's address.
- */
- } > DRAM AT > DRAM
-
- /*
- * ld assigns correct attribute for .bss, but not for other .*.bss,
- * we need an explicltly NOLOAD.
- */
- .dram.bss(NOLOAD) : {
- . = ALIGN(4);
- __dram_bss_start = .;
- *(SORT(.dram.bss*))
- . = ALIGN(4);
- __dram_bss_end = .;
- } > DRAM
-#endif /* CONFIG_DRAM_BASE */
-
-#if !(defined(SECTION_IS_RO) && defined(CONFIG_FLASH_CROS))
- /DISCARD/ : { *(.google) }
-#endif
-
- /DISCARD/ : { *(.ARM.*) }
-}
diff --git a/core/riscv-rv32i/include/fpu.h b/core/riscv-rv32i/include/fpu.h
deleted file mode 100644
index 25d83f228f..0000000000
--- a/core/riscv-rv32i/include/fpu.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Copyright 2020 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 RISC-V */
-
-#ifndef __CROS_EC_FPU_H
-#define __CROS_EC_FPU_H
-
-float sqrtf(float x);
-
-#endif /* __CROS_EC_FPU_H */
diff --git a/core/riscv-rv32i/init.S b/core/riscv-rv32i/init.S
deleted file mode 100644
index 5715478356..0000000000
--- a/core/riscv-rv32i/init.S
+++ /dev/null
@@ -1,454 +0,0 @@
-/* Copyright 2019 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.
- *
- * RISC-V CPU initialization
- */
-
-#include "config.h"
-
-.macro vector name
-.set \name\()_handler, unhandled_ec_irq
-.weak \name\()_handler
-j __entry_\()\name
-.pushsection .text.vectirq
-.global __entry_\()\name
-__entry_\()\name:
- /* C routine handler */
- j \name\()_handler
-.popsection
-.pushsection .rodata.vecthandlers
-.long \name\()_handler
-.popsection
-.endm
-
-.section .text.vecttable
-.align 2
-__startup:
- j __reset /* reset */
-__irq:
- j __irq_isr /* interrupts / exceptions */
-
-.align 2
-__ec_intc:
- vector irq_0 /* INT GROUP 0 */
- vector irq_1 /* INT GROUP 1 */
- vector irq_2 /* INT GROUP 2 */
- vector irq_3 /* INT GROUP 3 */
- vector irq_4 /* INT GROUP 4 */
- vector irq_5 /* INT GROUP 5 */
- vector irq_6 /* INT GROUP 6 */
- vector irq_7 /* INT GROUP 7 */
- vector irq_8 /* INT GROUP 8 */
- vector irq_9 /* INT GROUP 9 */
- vector irq_10 /* INT GROUP 10 */
- vector irq_11 /* INT GROUP 11 */
- vector irq_12 /* INT GROUP 12 */
- vector irq_13 /* INT GROUP 13 */
- vector irq_14 /* INT GROUP 14 */
- vector irq_15 /* INT GROUP 15 */
- vector syscall /* system call (emulate INT GROUP 16) */
-
-#ifdef CHIP_FAMILY_IT8XXX2
-/*
- * E-flash signature used to enable specific function after power-on reset.
- * (HW mechanism)
- * The content of 16-bytes must be the following and at offset 0x80 of binary.
- * ----------------------------------------------------------------------------
- * 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th
- * ----------------------------------------------------------------------------
- * A5h A5h A5h A5h A5h A5h [host] [flag] 85h 12h 5Ah 5Ah AAh AAh 55h 55h
- * ----------------------------------------------------------------------------
- * [host]: A4h = enable eSPI, A5h = enable LPC
- * [flag]:
- * bit7: it must be 1b.
- * bit6: it must be 0b.
- * bit5: it must be 1b.
- * bit4: 1b = 32.768KHz is from the internal clock generator.
- * bit3: it must be 0b.
- * bit2: it must be 1b.
- * bit1: it must be 0b.
- * bit0: it must be 0b.
- */
-.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 */
-#endif /* CHIP_FAMILY_IT8XXX2 */
-
-
-.align 2
-.section .text.vectirq
-__irq_isr:
- /* save t2 to scratch register */
- csrw mscratch, t2
- /* save registers (sp, ra, t0, and t1) state at exception entry */
- la t2, excep_entry_saved_regs
- sw sp, 0*4(t2)
- sw ra, 1*4(t2)
- sw t0, 2*4(t2)
- sw t1, 3*4(t2)
- /* store return address register */
- la t2, ira
- sw ra, 0(t2)
- /* restore t2 */
- csrr t2, mscratch
- /* save ra, a0-7, t0-t6 (high memory address to low) */
- sw t6, -16*4(sp)
- sw t5, -15*4(sp)
- sw t4, -14*4(sp)
- sw t3, -13*4(sp)
- sw t2, -12*4(sp)
- sw t1, -11*4(sp)
- sw t0, -10*4(sp)
- sw a7, -9*4(sp)
- sw a6, -8*4(sp)
- sw a5, -7*4(sp)
- sw a4, -6*4(sp)
- sw a3, -5*4(sp)
- sw a2, -4*4(sp)
- sw a1, -3*4(sp)
- /* Don't change index of ra and a0 (see task_pre_init()) */
- sw a0, -2*4(sp)
- sw ra, -1*4(sp)
-#ifdef CONFIG_FPU
- /* save ft0-11, fa0-7, and fcsr. */
- csrr t0, fcsr
- sw t0, -37*4(sp)
- fsw fa7, -36*4(sp)
- fsw fa6, -35*4(sp)
- fsw fa5, -34*4(sp)
- fsw fa4, -33*4(sp)
- fsw fa3, -32*4(sp)
- fsw fa2, -31*4(sp)
- fsw fa1, -30*4(sp)
- fsw fa0, -29*4(sp)
- fsw ft11, -28*4(sp)
- fsw ft10, -27*4(sp)
- fsw ft9, -26*4(sp)
- fsw ft8, -25*4(sp)
- fsw ft7, -24*4(sp)
- fsw ft6, -23*4(sp)
- fsw ft5, -22*4(sp)
- fsw ft4, -21*4(sp)
- fsw ft3, -20*4(sp)
- fsw ft2, -19*4(sp)
- fsw ft1, -18*4(sp)
- fsw ft0, -17*4(sp)
- /*
- * Note: we never execute on this stack frame, so it does not need to
- * be 16-byte aligned.
- */
- addi sp, sp, -37*4
-#else
- /*
- * Note: we never execute on this stack frame, so it does not need to
- * be 16-byte aligned.
- */
- addi sp, sp, -16*4
-#endif
- /* Save sp to scratch register */
- csrw mscratch, sp
- /* Load top of system stack address into t0 for comparison */
- la t0, stack_end
- /*
- * Switch to system stack (which is in lower memory than task stack)
- * if we are not already operating with the system stack
- */
- bltu sp, t0, __sp_16byte_aligned
- mv sp, t0
-__sp_16byte_aligned:
- /* in_interrupt = 1 */
- li t0, 1
- la t1, in_interrupt
- sb t0, 0(t1)
- /*
- * This ensures sp is 16-byte aligned. This only applies to when there
- * is an interrupt before tasks start. Otherwise stack_end is already
- * 16-byte aligned.
- */
- andi sp, sp, -16
- /* read exception cause */
- csrr t0, mcause
- /* isolate exception cause */
- andi t1, t0, 0x1f
- /* mcause = 11: external interrupt or environment call from M-mode */
- addi t1, t1, -11
- beqz t1, __irq_handler
- /* branch if this is an exceptoin (the interrupt bit of mcause is 0) */
- bgez t0, excep_handler
- /* This interrupt is unhandled */
- j unhandled_interrupt
-__irq_handler:
- /* save a0, a1, and a2 for syscall */
- addi sp, sp, -4*3
- sw a0, 0(sp)
- sw a1, 1*4(sp)
- sw a2, 2*4(sp)
- jal start_irq_handler
- /* a0 = -1 if it cannot find the corresponding interrupt source */
- bltz a0, unhandled_interrupt
- /* restore a0, a1, and a2 */
- lw a0, 0(sp)
- lw a1, 1*4(sp)
- lw a2, 2*4(sp)
- addi sp, sp, 4*3
- /* get EC interrupt group 0-15 or 16:ecall */
- la t0, ec_int_group
- /* get corresponding isr */
- lw t1, 0(t0)
- slli t1, t1, 2
- la t0, __ec_intc
- add t0, t0, t1
- /* handle irq */
- jalr t0
- /* check whether we need to change the scheduled task */
- la t0, need_resched
- lw t1, 0(t0)
- bnez t1, __switch_task
-.global __irq_exit
-__irq_exit:
- jal end_irq_handler
- /* in_interrupt = 0 */
- la t0, in_interrupt
- sb zero, 0(t0)
- /* restore sp from scratch register */
- csrr sp, mscratch
-#ifdef CONFIG_FPU
- addi sp, sp, 37*4
- /* restore ft0-11, fa0-7, and fcsr. */
- lw t0, -37*4(sp)
- csrw fcsr, t0
- flw fa7, -36*4(sp)
- flw fa6, -35*4(sp)
- flw fa5, -34*4(sp)
- flw fa4, -33*4(sp)
- flw fa3, -32*4(sp)
- flw fa2, -31*4(sp)
- flw fa1, -30*4(sp)
- flw fa0, -29*4(sp)
- flw ft11, -28*4(sp)
- flw ft10, -27*4(sp)
- flw ft9, -26*4(sp)
- flw ft8, -25*4(sp)
- flw ft7, -24*4(sp)
- flw ft6, -23*4(sp)
- flw ft5, -22*4(sp)
- flw ft4, -21*4(sp)
- flw ft3, -20*4(sp)
- flw ft2, -19*4(sp)
- flw ft1, -18*4(sp)
- flw ft0, -17*4(sp)
-#else
- addi sp, sp, 16*4
-#endif
- /* restore ra, a0-a7, t0-t6 */
- lw t6, -16*4(sp)
- lw t5, -15*4(sp)
- lw t4, -14*4(sp)
- lw t3, -13*4(sp)
- lw t2, -12*4(sp)
- lw t1, -11*4(sp)
- lw t0, -10*4(sp)
- lw a7, -9*4(sp)
- lw a6, -8*4(sp)
- lw a5, -7*4(sp)
- lw a4, -6*4(sp)
- lw a3, -5*4(sp)
- lw a2, -4*4(sp)
- lw a1, -3*4(sp)
- lw a0, -2*4(sp)
- lw ra, -1*4(sp)
- mret
-
-.text
-.global __reset
-__reset:
- /* disable interrupts */
- csrw mie, zero
-.option push
-.option norelax
- /* GP register is used to access .data and .bss (address +/- 2048) */
- la gp, __global_pointer$
-.option pop
- /* Set system stack pointer. */
- la sp, stack_end
-#ifdef CONFIG_FPU
- li t0, 0x6000
- csrw mstatus, t0
- csrw fcsr, zero
-#else
- csrw mstatus, zero
-#endif
- /*
- * move content of return address(ra) into t5 and then store the content
- * into variable "ec_reset_lp" later after memory initialization.
- */
- mv t5, ra
- /* Clear the link register */
- li ra, 0
- /* Clear the thread pointer register */
- li tp, 0
- /* set machine trap-handler base address */
- la t0, __irq
- csrw mtvec, t0
- /* reset scratch register */
- csrw mscratch, zero
- /* The M-mode handles interrupt/exception */
- csrwi mideleg, 0
- csrwi medeleg, 0
-#if defined(IT83XX_CHIP_FLASH_SIZE_1MB) && defined(CHIP_FAMILY_IT8XXX2)
- /* ILM size is 1M bytes */
- la t0, IT83XX_GCTRL_EIDSR
- lb t1, 0(t0)
- andi t1, t1, 0xf0
- ori t1, t1, 0x8
- sb t1, 0(t0)
-#endif
- /* Clear BSS */
- la t0, __bss_start
- la t1, __bss_end
-bss_loop:
- sw zero, 0(t0)
- addi t0, t0, 4
- bltu t0, t1, bss_loop
- /* Copy initialized data to data section */
- la t0, __data_start
- la t1, __data_end
- la t2, __data_lma_start
-data_loop:
- lw t3, 0(t2)
- sw t3, 0(t0)
- addi t0, t0, 4
- addi t2, t2, 4
- bltu t0, t1, data_loop
- /* store the content of t5 (ra after reset) into "ec_reset_lp" */
- la t0, ec_reset_lp
- sw t5, 0(t0)
-#ifdef CHIP_FAMILY_IT8XXX2
- /* clear BRAM if it is not valid */
- jal chip_bram_valid
-#endif
- /* Jump to C routine */
- jal main
- /* That should not return. If it does, loop forever. */
- j .
-
-.global unhandled_ec_irq
-.global unhandled_interrupt
-unhandled_ec_irq:
- li tp, 0xBAD1
- j __unhandled_irq
-unhandled_interrupt:
- li tp, 0xBAD0
-__unhandled_irq:
- slli tp, tp, 16
- la t0, ec_int
- lw t0, 0(t0)
- add tp, tp, t0
- j excep_handler /* display exception with TP bad[0|1]<ec_int> */
-
-.global excep_handler
-excep_handler:
- /* save t2 */
- csrw mscratch, t2
- /* restore registers (sp, ra, t0, and t1) state */
- la t2, excep_entry_saved_regs
- lw sp, 0*4(t2)
- lw ra, 1*4(t2)
- lw t0, 2*4(t2)
- lw t1, 3*4(t2)
- /* restore t2 */
- csrr t2, mscratch
- /* save sp to scratch register */
- csrw mscratch, sp
- la sp, saved_regs
- /* save sp, ra, gp, tp , a0-a7, t0-t6, and s0-s11 registers */
- sw s11, 0*4(sp)
- sw s10, 1*4(sp)
- sw s9, 2*4(sp)
- sw s8, 3*4(sp)
- sw s7, 4*4(sp)
- sw s6, 5*4(sp)
- sw s5, 6*4(sp)
- sw s4, 7*4(sp)
- sw s3, 8*4(sp)
- sw s2, 9*4(sp)
- sw s1, 10*4(sp)
- sw s0, 11*4(sp)
- sw t6, 12*4(sp)
- sw t5, 13*4(sp)
- sw t4, 14*4(sp)
- sw t3, 15*4(sp)
- sw t2, 16*4(sp)
- sw t1, 17*4(sp)
- sw t0, 18*4(sp)
- sw a7, 19*4(sp)
- sw a6, 20*4(sp)
- sw a5, 21*4(sp)
- sw a4, 22*4(sp)
- sw a3, 23*4(sp)
- sw a2, 24*4(sp)
- sw a1, 25*4(sp)
- sw a0, 26*4(sp)
- sw tp, 27*4(sp)
- sw gp, 28*4(sp)
- sw ra, 29*4(sp)
- la a0, saved_regs
- csrr sp, mscratch
- sw sp, 30*4(a0)
- /* put a valid stack pointer */
- la sp, stack_end
- /* jump to panic dump C routine */
- jal report_panic
- 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.
- *
- * Main routine and ISR will share this space before tasks start.
- * This space is then dedicated to ISRs after tasks start.
- *
- * NOTE: Location of system stack (.bss.system_stack) must be less than
- * tasks stacks (task_stacks@.bss) and scratchpad for first context switch
- * (scratchpad[]@.bss.task_scratchpad).
- */
-.section .bss.system_stack
-stack_start:
-.space CONFIG_STACK_SIZE, 0
-stack_end:
-.global stack_end
-
-/* sp, ra, t0, t1 registers state at exception entry */
-.global excep_entry_saved_regs
-excep_entry_saved_regs:
-.long 0, 0, 0, 0
-
-/* 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
-.long 0, 0, 0, 0, 0, 0, 0, 0
-.long 0, 0, 0, 0, 0, 0, 0, 0
diff --git a/core/riscv-rv32i/irq_chip.h b/core/riscv-rv32i/irq_chip.h
deleted file mode 100644
index 45cabf346e..0000000000
--- a/core/riscv-rv32i/irq_chip.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright 2019 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.
- */
-void chip_enable_irq(int irq);
-
-/**
- * Disable an IRQ in the chip interrupt controller.
- *
- * @param irq interrupt request index.
- */
-void chip_disable_irq(int irq);
-
-/**
- * Clear a pending IRQ in the chip interrupt controller.
- *
- * @param irq interrupt request index.
- *
- * 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.
- */
-void 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 external interrupt number.
- */
-int chip_get_ec_int(void);
-
-/**
- * Return group number of the given external interrupt number.
- */
-int chip_get_intc_group(int irq);
-
-#endif /* __CROS_EC_IRQ_CHIP_H */
diff --git a/core/riscv-rv32i/irq_handler.h b/core/riscv-rv32i/irq_handler.h
deleted file mode 100644
index 6414f90c7f..0000000000
--- a/core/riscv-rv32i/irq_handler.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright 2019 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)
-
-#ifndef CPU_INT
-#define CPU_INT(irq) irq
-#endif
-
-/*
- * 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 routine(void); \
- 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/riscv-rv32i/math.c b/core/riscv-rv32i/math.c
deleted file mode 100644
index 591a67eb8f..0000000000
--- a/core/riscv-rv32i/math.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright 2020 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
-/* Single precision floating point square root. */
-float sqrtf(float x)
-{
- asm volatile (
- "fsqrt.s %0, %1"
- : "=f" (x)
- : "f" (x));
-
- return x;
-}
-#endif
diff --git a/core/riscv-rv32i/panic.c b/core/riscv-rv32i/panic.c
deleted file mode 100644
index b339fdf76c..0000000000
--- a/core/riscv-rv32i/panic.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* Copyright 2019 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 "cpu.h"
-#include "panic.h"
-#include "task.h"
-#include "util.h"
-
-#ifdef CONFIG_DEBUG_EXCEPTIONS
-/**
- * bit[3-0] @ mcause, general exception type information.
- */
-static const char * const exc_type[16] = {
- "Instruction address misaligned",
- "Instruction access fault",
- "Illegal instruction",
- "Breakpoint",
- "Load address misaligned",
- "Load access fault",
- "Store/AMO address misaligned",
- "Store/AMO access fault",
-
- NULL,
- NULL,
- NULL,
- "Environment call from M-mode",
- NULL,
- NULL,
- NULL,
- NULL,
-};
-#endif /* CONFIG_DEBUG_EXCEPTIONS */
-
-#ifdef CONFIG_SOFTWARE_PANIC
-/* General purpose register (s0) for saving software panic reason */
-#define SOFT_PANIC_GPR_REASON 11
-/* General purpose register (s1) for saving software panic information */
-#define SOFT_PANIC_GPR_INFO 10
-
-void software_panic(uint32_t reason, uint32_t info)
-{
- asm volatile ("mv s0, %0" : : "r"(reason) : "s0");
- asm volatile ("mv s1, %0" : : "r"(info) : "s1");
- if (in_interrupt_context())
- asm("j excep_handler");
- else
- asm("ebreak");
- __builtin_unreachable();
-}
-
-void panic_set_reason(uint32_t reason, uint32_t info, uint8_t exception)
-{
- /*
- * It is safe to get pointer using get_panic_data_write().
- * If it was called earlier (eg. when saving riscv.mepc) calling it
- * once again won't remove any data
- */
- struct panic_data * const pdata = get_panic_data_write();
- uint32_t warning_mepc;
- uint32_t *regs;
-
- regs = pdata->riscv.regs;
-
- /* Setup panic data structure */
- if (reason != PANIC_SW_WATCHDOG) {
- memset(pdata, 0, CONFIG_PANIC_DATA_SIZE);
- } else {
- warning_mepc = pdata->riscv.mepc;
- memset(pdata, 0, CONFIG_PANIC_DATA_SIZE);
- pdata->riscv.mepc = warning_mepc;
- }
- pdata->magic = PANIC_DATA_MAGIC;
- pdata->struct_size = CONFIG_PANIC_DATA_SIZE;
- pdata->struct_version = 2;
- pdata->arch = PANIC_ARCH_RISCV_RV32I;
-
- /* Log panic cause */
- pdata->riscv.mcause = 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)
-{
- struct panic_data * const pdata = panic_get_data();
- uint32_t *regs;
-
- if (pdata && pdata->struct_version == 2) {
- regs = pdata->riscv.regs;
- *exception = pdata->riscv.mcause;
- *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 mcause,
- uint32_t mepc)
-{
- panic_printf("=== EXCEPTION: MCAUSE=%x ===\n", mcause);
- panic_printf("S11 %08x S10 %08x S9 %08x S8 %08x\n",
- regs[0], regs[1], regs[2], regs[3]);
- panic_printf("S7 %08x S6 %08x S5 %08x S4 %08x\n",
- regs[4], regs[5], regs[6], regs[7]);
- panic_printf("S3 %08x S2 %08x S1 %08x S0 %08x\n",
- regs[8], regs[9], regs[10], regs[11]);
- panic_printf("T6 %08x T5 %08x T4 %08x T3 %08x\n",
- regs[12], regs[13], regs[14], regs[15]);
- panic_printf("T2 %08x T1 %08x T0 %08x A7 %08x\n",
- regs[16], regs[17], regs[18], regs[19]);
- panic_printf("A6 %08x A5 %08x A4 %08x A3 %08x\n",
- regs[20], regs[21], regs[22], regs[23]);
- panic_printf("A2 %08x A1 %08x A0 %08x TP %08x\n",
- regs[24], regs[25], regs[26], regs[27]);
- panic_printf("GP %08x RA %08x SP %08x MEPC %08x\n",
- regs[28], regs[29], regs[30], mepc);
-
-#ifdef CONFIG_DEBUG_EXCEPTIONS
- if ((regs[SOFT_PANIC_GPR_REASON] & 0xfffffff0) == PANIC_SW_BASE) {
-#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: %d\n",
- regs[SOFT_PANIC_GPR_INFO]);
-#endif
- } else {
- panic_printf("Exception type: %s\n", exc_type[(mcause & 0xf)]);
- }
-#endif
-}
-
-void report_panic(uint32_t *regs)
-{
- uint32_t i, mcause, mepc;
- struct panic_data * const pdata = get_panic_data_write();
-
- mepc = get_mepc();
- mcause = get_mcause();
-
- pdata->magic = PANIC_DATA_MAGIC;
- pdata->struct_size = CONFIG_PANIC_DATA_SIZE;
- pdata->struct_version = 2;
- pdata->arch = PANIC_ARCH_RISCV_RV32I;
- pdata->flags = 0;
- pdata->reserved = 0;
-
- pdata->riscv.mcause = mcause;
- pdata->riscv.mepc = mepc;
- for (i = 0; i < 31; i++)
- pdata->riscv.regs[i] = regs[i];
-
- print_panic_information(regs, mcause, mepc);
- panic_reboot();
-}
-
-void panic_data_print(const struct panic_data *pdata)
-{
- uint32_t *regs, mcause, mepc;
-
- regs = (uint32_t *)pdata->riscv.regs;
- mcause = pdata->riscv.mcause;
- mepc = pdata->riscv.mepc;
- print_panic_information(regs, mcause, mepc);
-}
diff --git a/core/riscv-rv32i/switch.S b/core/riscv-rv32i/switch.S
deleted file mode 100644
index 8760667c6b..0000000000
--- a/core/riscv-rv32i/switch.S
+++ /dev/null
@@ -1,171 +0,0 @@
-/* Copyright 2019 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"
-#include "cpu.h"
-
-#ifdef __RAM_CODE_SECTION_NAME
-.section __RAM_CODE_SECTION_NAME
-#endif
-
-/**
- * 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.
- *
- * the structure of the saved context on the stack is :
- * ra, a0-a7, t0-t6 (caller saved) , s0-s11 (callee saved), mepc
- * interrupt entry frame <|> additional registers
- * if enabling the FPU:
- * ra, a0-a7, t0-t6, ft0-ft11, fa0-fa7, and fcsr <|>
- * s0-s11, fs0-fs11, and mepc
- *
- */
-.global __switch_task
-__switch_task:
- /* get the (new) highest priority task pointer in a0 */
- jal next_sched_task
- /* pointer to the current task (which are switching from) */
- la t1, current_task
- lw t0, 0(t1)
- /* reset the re-scheduling request */
- la t2, need_resched
- sw zero, 0(t2)
- /* Nothing to do: let's return to keep the same task scheduled */
- beq a0, t0, __irq_exit
- /* save our new scheduled task */
- sw a0, 0(t1)
- /* save our current location in system stack so we can restore at end */
- add t3, sp, zero
- /* restore current process stack pointer */
- csrr sp, mscratch
- /* get the task program counter saved at exception entry */
- csrr t5, mepc
- /* save s0-s11 on the current process stack */
- sw s11, -12*4(sp)
- sw s10, -11*4(sp)
- sw s9, -10*4(sp)
- sw s8, -9*4(sp)
- sw s7, -8*4(sp)
- sw s6, -7*4(sp)
- sw s5, -6*4(sp)
- sw s4, -5*4(sp)
- sw s3, -4*4(sp)
- sw s2, -3*4(sp)
- sw s1, -2*4(sp)
- sw s0, -1*4(sp)
-#ifdef CONFIG_FPU
- /* save fs0-fs11 on the current process stack */
- fsw fs11, -24*4(sp)
- fsw fs10, -23*4(sp)
- fsw fs9, -22*4(sp)
- fsw fs8, -21*4(sp)
- fsw fs7, -20*4(sp)
- fsw fs6, -19*4(sp)
- fsw fs5, -18*4(sp)
- fsw fs4, -17*4(sp)
- fsw fs3, -16*4(sp)
- fsw fs2, -15*4(sp)
- fsw fs1, -14*4(sp)
- fsw fs0, -13*4(sp)
- /* save program counter on the current process stack */
- sw t5, -25*4(sp)
- /*
- * Note: we never execute on this stack frame, so it does not need to
- * be 16-byte aligned.
- */
- addi sp, sp, -25*4
-#else
- /* save program counter on the current process stack */
- sw t5, -13*4(sp)
- /*
- * Note: we never execute on this stack frame, so it does not need to
- * be 16-byte aligned.
- */
- addi sp, sp, -13*4
-#endif
- /* save the task stack pointer in its context */
- sw sp, 0(t0)
- /* get the new scheduled task stack pointer */
- lw sp, 0(a0)
-#ifdef CONFIG_FPU
- addi sp, sp, 25*4
- /* get mepc */
- lw t0, -25*4(sp)
- /* restore FP registers (fs0-fs11) from the next stack context */
- flw fs11, -24*4(sp)
- flw fs10, -23*4(sp)
- flw fs9, -22*4(sp)
- flw fs8, -21*4(sp)
- flw fs7, -20*4(sp)
- flw fs6, -19*4(sp)
- flw fs5, -18*4(sp)
- flw fs4, -17*4(sp)
- flw fs3, -16*4(sp)
- flw fs2, -15*4(sp)
- flw fs1, -14*4(sp)
- flw fs0, -13*4(sp)
-#else
- addi sp, sp, 13*4
- /* get mepc */
- lw t0, -13*4(sp)
-#endif
- /* restore program counter from the next stack context */
- csrw mepc, t0
- /* restore registers from the next stack context */
- lw s11, -12*4(sp)
- lw s10, -11*4(sp)
- lw s9, -10*4(sp)
- lw s8, -9*4(sp)
- lw s7, -8*4(sp)
- lw s6, -7*4(sp)
- lw s5, -6*4(sp)
- lw s4, -5*4(sp)
- lw s3, -4*4(sp)
- lw s2, -3*4(sp)
- lw s1, -2*4(sp)
- lw s0, -1*4(sp)
- /*
- * save sp to scratch register and switch to system stack.
- * __irq_exit will restore sp from scratch register again before mret.
- */
- csrw mscratch, sp
- /* restore system stack */
- add sp, t3, zero
- j __irq_exit
-
-.text
-/**
- * Start the task scheduling.
- */
-.global __task_start
-__task_start:
- csrci mstatus, 0x8
- /* area used as thread stack for the first switch */
- la a3, scratchpad
- li a4, 1
- li a2, 0 /* system call 3rd parameter : not an IRQ emulation */
- li a1, 0 /* system call 2nd parameter : re-schedule nothing */
- li a0, 0 /* system call 1st parameter : de-schedule nothing */
- /* put the stack pointer at the top of the stack in scratchpad */
- addi sp, a3, 4 * TASK_SCRATCHPAD_SIZE
- /* we are ready to re-schedule */
- la t0, need_resched
- sw a4, 0(t0)
- la t0, start_called
- sw a4, 0(t0)
- csrsi mstatus, 0x8
- /* trigger scheduling to execute the task with the highest priority */
- ecall
- /* we should never return here */
- j .
diff --git a/core/riscv-rv32i/task.c b/core/riscv-rv32i/task.c
deleted file mode 100644
index 558177e969..0000000000
--- a/core/riscv-rv32i/task.c
+++ /dev/null
@@ -1,725 +0,0 @@
-/* Copyright 2019 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 "console.h"
-#include "cpu.h"
-#include "irq_chip.h"
-#include "link_defs.h"
-#include "task.h"
-#include "timer.h"
-#include "util.h"
-
-typedef 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 uint32_t exc_sub_time;
-static uint64_t task_start_time; /* Time task scheduling started */
-static uint32_t exc_start_time; /* Time of task->exception transition */
-static uint32_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);
-
-#if defined(CHIP_FAMILY_IT83XX)
-extern void clock_sleep_mode_wakeup_isr(void);
-#endif
-
-#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) {
-#if defined(CHIP_FAMILY_IT83XX)
- /* doze mode */
- IT83XX_ECPM_PLLCTRL = EC_PLL_DOZE;
- clock_cpu_standby();
-#else
- asm("wfi");
-#endif
- }
-}
-#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) { \
- .a0 = (uint32_t)d, \
- .pc = (uint32_t)r, \
- .stack_size = s, \
-},
-static const struct {
- uint32_t a0;
- 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] __attribute__ ((section(".bss.tasks")));
-/* Validity 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[TASK_SCRATCHPAD_SIZE] __attribute__
- ((section(".bss.task_scratchpad")));
-
-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 */
-
-/* in interrupt context */
-volatile bool in_interrupt;
-/* Interrupt number of EC modules */
-volatile int ec_int;
-/* Interrupt group of EC INTC modules */
-volatile int ec_int_group;
-/* interrupt number of sw interrupt */
-static int sw_int_num;
-/* This variable is used to save return address register at EC reset. */
-uint32_t ec_reset_lp;
-/*
- * This variable is used to save return address register,
- * and it is updated at the beginning of each ISR.
- */
-uint32_t ira;
-
-static inline task_ *__task_id_to_ptr(task_id_t id)
-{
- return tasks + id;
-}
-
-void __ram_code interrupt_disable(void)
-{
- /* bit11: disable MEIE */
- asm volatile ("li t0, 0x800");
- asm volatile ("csrc mie, t0");
-}
-
-void __ram_code interrupt_enable(void)
-{
- /* bit11: enable MEIE */
- asm volatile ("li t0, 0x800");
- asm volatile ("csrs mie, t0");
-}
-
-inline int is_interrupt_enabled(void)
-{
- int mie = 0;
-
- asm volatile ("csrr %0, mie" : "=r"(mie));
-
- /* Check if MEIE bit is set in MIE register */
- return !!(mie & 0x800);
-}
-
-inline int in_interrupt_context(void)
-{
- return in_interrupt;
-}
-
-int in_soft_interrupt_context(void)
-{
- /* group 16 is reserved for soft-irq */
- return in_interrupt_context() && ec_int_group == 16;
-}
-
-task_id_t __ram_code 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 * __ram_code 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;
-}
-
-/**
- * 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];
- /* adjust IPC to return *after* the syscall instruction */
- set_mepc(get_mepc() + 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_mepc(get_mepc() + 4);
-}
-
-task_ * __ram_code 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) {
- 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();
-
- 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("a0") = desched;
- register int p1 asm("a1") = resched;
- register int p2 asm("a2") = swirq;
-
- asm("ecall" : : "r"(p0), "r"(p1), "r"(p2));
-}
-
-void __ram_code update_exc_start_time(void)
-{
-#ifdef CONFIG_TASK_PROFILING
- exc_start_time = get_time().le.lo;
-#endif
-}
-
-/**
- * The beginning of interrupt handler of c language code.
- *
- * @param none
- * @return -1 if it cannot find the corresponding interrupt source.
- */
-int __ram_code start_irq_handler(void)
-{
- /* If this is a SW interrupt */
- if (get_mcause() == 11) {
- ec_int = sw_int_num;
- ec_int_group = 16;
- } else {
- /*
- * Determine interrupt number.
- * -1 if it cannot find the corresponding interrupt source.
- */
- if (chip_get_ec_int() == -1)
- return -1;
- ec_int_group = chip_get_intc_group(ec_int);
- }
-
-#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
-
- return EC_SUCCESS;
-}
-
-void __ram_code end_irq_handler(void)
-{
-#ifdef CONFIG_TASK_PROFILING
- uint32_t t, p;
-
- t = get_time().le.lo;
- 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++;
- }
-#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_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_bits(&tsk->events, TASK_EVENT_TIMER);
- }
- return evt;
-}
-
-uint32_t __ram_code task_set_event(task_id_t tskid, uint32_t event)
-{
- 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 {
- __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 read_clear_int_mask(void)
-{
- uint32_t mie, meie = BIT(11);
-
- /* Read and clear MEIE bit of MIE register. */
- asm volatile ("csrrc %0, mie, %1" : "=r"(mie) : "r"(meie));
-
- return mie;
-}
-
-void __ram_code set_int_mask(uint32_t val)
-{
- asm volatile ("csrw mie, %0" : : "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_bits(&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 = read_clear_int_mask();
-
- chip_enable_irq(irq);
- set_int_mask(int_mask);
-}
-
-void __ram_code task_disable_irq(int irq)
-{
- uint32_t int_mask = read_clear_int_mask();
-
- 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)
-{
- /* chip-specific interrupt controller initialization */
- chip_init_irqs();
- /*
- * 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();
-}
-
-void __ram_code mutex_lock(struct mutex *mtx)
-{
- uint32_t locked;
- uint32_t id = 1 << task_get_current();
-
- ASSERT(id != TASK_ID_INVALID);
- atomic_or(&mtx->waiters, id);
-
- while (1) {
- asm volatile (
- /* set lock value */
- "li %0, 2\n\t"
- /* attempt to acquire lock */
- "amoswap.w.aq %0, %0, %1\n\t"
- : "=&r" (locked), "+A" (mtx->lock));
- /* we got it ! */
- if (!locked)
- break;
- /* Contention on the mutex */
- /* Sleep waiting for our turn */
- task_wait_event_mask(TASK_EVENT_MUTEX, 0);
- }
-
- atomic_clear_bits(&mtx->waiters, id);
-}
-
-void __ram_code mutex_unlock(struct mutex *mtx)
-{
- uint32_t waiters;
- task_ *tsk = current_task;
-
- /* give back the lock */
- asm volatile (
- "amoswap.w.aqrl zero, zero, %0\n\t"
- : "+A" (mtx->lock));
- waiters = mtx->waiters;
-
- while (waiters) {
- task_id_t id = __fls(waiters);
-
- waiters &= ~BIT(id);
-
- /* Somebody is waiting on the mutex */
- task_set_event(id, TASK_EVENT_MUTEX);
- }
-
- /* Ensure no event is remaining from mutex wake-up */
- atomic_clear_bits(&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
- unsigned 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: %11u\n", svc_calls);
- ccprintf("Total exceptions: %11u\n", total + svc_calls);
- ccprintf("Task switches: %11u\n", task_switches);
- ccprintf("Task switching started: %11.6llu s\n", task_start_time);
- ccprintf("Time in tasks: %11.6llu s\n",
- get_time().val - task_start_time);
- ccprintf("Time in exceptions: %11.6llu 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: 28 regs + MEPC + (FP regs)
- */
- sp = stack_next + ssize - TASK_SCRATCHPAD_SIZE;
- tasks[i].sp = (uint32_t)sp;
-
- /* Initial context on stack (see __switchto()) */
- sp[TASK_SCRATCHPAD_SIZE-2] = tasks_init[i].a0; /* a0 */
- sp[TASK_SCRATCHPAD_SIZE-1] = (uint32_t)task_exit_trap; /* ra */
- sp[0] = tasks_init[i].pc; /* pc/mepc */
-
- /* 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 = get_time().val;
- exc_end_time = get_time().le.lo;
-#endif
-
- return __task_start();
-}