summaryrefslogtreecommitdiff
path: root/core/riscv-rv32i
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /core/riscv-rv32i
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14469.8.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'core/riscv-rv32i')
-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
15 files changed, 0 insertions, 2289 deletions
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();
-}