diff options
Diffstat (limited to 'core/cortex-m0')
-rw-r--r-- | core/cortex-m0/__builtin.c | 16 | ||||
-rw-r--r-- | core/cortex-m0/atomic.h | 73 | ||||
-rw-r--r-- | core/cortex-m0/build.mk | 36 | ||||
-rw-r--r-- | core/cortex-m0/config_core.h | 20 | ||||
-rw-r--r-- | core/cortex-m0/cpu.c | 20 | ||||
-rw-r--r-- | core/cortex-m0/cpu.h | 58 | ||||
l--------- | core/cortex-m0/curve25519 | 1 | ||||
l--------- | core/cortex-m0/debug.c | 1 | ||||
l--------- | core/cortex-m0/debug.h | 1 | ||||
l--------- | core/cortex-m0/div.S | 1 | ||||
-rw-r--r-- | core/cortex-m0/ec.lds.S | 360 | ||||
-rw-r--r-- | core/cortex-m0/include/fpu.h | 11 | ||||
-rw-r--r-- | core/cortex-m0/init.S | 129 | ||||
-rw-r--r-- | core/cortex-m0/irq_handler.h | 44 | ||||
l--------- | core/cortex-m0/ldivmod.S | 1 | ||||
l--------- | core/cortex-m0/lmul.S | 1 | ||||
-rw-r--r-- | core/cortex-m0/mula.S | 81 | ||||
-rw-r--r-- | core/cortex-m0/panic-internal.h | 13 | ||||
-rw-r--r-- | core/cortex-m0/panic.c | 227 | ||||
-rw-r--r-- | core/cortex-m0/switch.S | 116 | ||||
-rw-r--r-- | core/cortex-m0/task.c | 691 | ||||
-rw-r--r-- | core/cortex-m0/thumb_case.S | 96 | ||||
l--------- | core/cortex-m0/uldivmod.S | 1 | ||||
-rw-r--r-- | core/cortex-m0/vecttable.c | 136 | ||||
-rw-r--r-- | core/cortex-m0/watchdog.c | 53 |
25 files changed, 0 insertions, 2187 deletions
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 : ®name[(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(¤t_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(); -} |