summaryrefslogtreecommitdiff
path: root/core/riscv-rv32i
diff options
context:
space:
mode:
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();
-}