summaryrefslogtreecommitdiff
path: root/core/host
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/host
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-release-R98-14388.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/host')
-rw-r--r--core/host/atomic.h40
-rw-r--r--core/host/build.mk11
-rw-r--r--core/host/cpu.h13
-rw-r--r--core/host/disabled.c10
-rw-r--r--core/host/host_exe.lds136
-rw-r--r--core/host/host_task.h37
-rw-r--r--core/host/irq_handler.h30
-rw-r--r--core/host/main.c108
-rw-r--r--core/host/panic.c22
-rw-r--r--core/host/stack_trace.c97
-rw-r--r--core/host/task.c564
-rw-r--r--core/host/timer.c105
12 files changed, 0 insertions, 1173 deletions
diff --git a/core/host/atomic.h b/core/host/atomic.h
deleted file mode 100644
index 83786de904..0000000000
--- a/core/host/atomic.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Atomic operations for emulator */
-
-#ifndef __CROS_EC_ATOMIC_H
-#define __CROS_EC_ATOMIC_H
-
-#include "common.h"
-
-typedef int atomic_t;
-typedef atomic_t atomic_val_t;
-
-static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits)
-{
- return __atomic_fetch_and(addr, ~bits, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_or(atomic_t *addr, atomic_val_t bits)
-{
- return __atomic_fetch_or(addr, bits, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_add(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_add(addr, value, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_sub(atomic_t *addr, atomic_val_t value)
-{
- return __atomic_fetch_sub(addr, value, __ATOMIC_SEQ_CST);
-}
-
-static inline atomic_val_t atomic_clear(atomic_t *addr)
-{
- return __atomic_exchange_n(addr, 0, __ATOMIC_SEQ_CST);
-}
-#endif /* __CROS_EC_ATOMIC_H */
diff --git a/core/host/build.mk b/core/host/build.mk
deleted file mode 100644
index 503aa5538a..0000000000
--- a/core/host/build.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- makefile -*-
-# Copyright 2013 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# emulator specific files build
-#
-
-CFLAGS_CPU=-fno-builtin
-
-core-y=main.o task.o timer.o panic.o disabled.o stack_trace.o
diff --git a/core/host/cpu.h b/core/host/cpu.h
deleted file mode 100644
index d990e06afa..0000000000
--- a/core/host/cpu.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* CPU specific header file */
-
-#ifndef __CROS_EC_CPU_H
-#define __CROS_EC_CPU_H
-
-static inline void cpu_init(void) { }
-
-#endif /* __CROS_EC_CPU_H */
diff --git a/core/host/disabled.c b/core/host/disabled.c
deleted file mode 100644
index 759c215ebd..0000000000
--- a/core/host/disabled.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Disabled functions */
-
-#define DISABLED(proto) proto { }
-
-DISABLED(void clock_init(void));
diff --git a/core/host/host_exe.lds b/core/host/host_exe.lds
deleted file mode 100644
index ab8d352ecc..0000000000
--- a/core/host/host_exe.lds
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-SECTIONS {
- .rodata.ec_sections : {
- /* Symbols defined here are declared in link_defs.h */
- __irqprio = .;
- *(.rodata.irqprio)
- __irqprio_end = .;
-
- . = ALIGN(8);
- __cmds = .;
- *(SORT(.rodata.cmds*))
- __cmds_end = .;
-
- . = ALIGN(8);
- __hcmds = .;
- *(SORT(.rodata.hcmds*))
- __hcmds_end = .;
-
- . = ALIGN(4);
- __mkbp_evt_srcs = .;
- KEEP(*(.rodata.evtsrcs))
- __mkbp_evt_srcs_end = .;
-
- . = ALIGN(8);
- __hooks_init = .;
- *(.rodata.HOOK_INIT)
- __hooks_init_end = .;
-
- __hooks_pre_freq_change = .;
- *(.rodata.HOOK_PRE_FREQ_CHANGE)
- __hooks_pre_freq_change_end = .;
-
- __hooks_freq_change = .;
- *(.rodata.HOOK_FREQ_CHANGE)
- __hooks_freq_change_end = .;
-
- __hooks_sysjump = .;
- *(.rodata.HOOK_SYSJUMP)
- __hooks_sysjump_end = .;
-
- __hooks_chipset_pre_init = .;
- *(.rodata.HOOK_CHIPSET_PRE_INIT)
- __hooks_chipset_pre_init_end = .;
-
- __hooks_chipset_startup = .;
- *(.rodata.HOOK_CHIPSET_STARTUP)
- __hooks_chipset_startup_end = .;
-
- __hooks_chipset_resume = .;
- *(.rodata.HOOK_CHIPSET_RESUME)
- __hooks_chipset_resume_end = .;
-
- __hooks_chipset_suspend = .;
- *(.rodata.HOOK_CHIPSET_SUSPEND)
- __hooks_chipset_suspend_end = .;
-
- __hooks_chipset_shutdown = .;
- *(.rodata.HOOK_CHIPSET_SHUTDOWN)
- __hooks_chipset_shutdown_end = .;
-
- __hooks_chipset_shutdown_complete = .;
- *(.rodata.HOOK_CHIPSET_SHUTDOWN_COMPLETE)
- __hooks_chipset_shutdown_complete_end = .;
-
- __hooks_chipset_hard_off = .;
- KEEP(*(.rodata.HOOK_CHIPSET_HARD_OFF))
- __hooks_chipset_hard_off_end = .;
-
- __hooks_chipset_reset = .;
- *(.rodata.HOOK_CHIPSET_RESET)
- __hooks_chipset_reset_end = .;
-
- __hooks_ac_change = .;
- *(.rodata.HOOK_AC_CHANGE)
- __hooks_ac_change_end = .;
-
- __hooks_lid_change = .;
- *(.rodata.HOOK_LID_CHANGE)
- __hooks_lid_change_end = .;
-
- __hooks_tablet_mode_change = .;
- KEEP(*(.rodata.HOOK_TABLET_MODE_CHANGE))
- __hooks_tablet_mode_change_end = .;
-
- __hooks_base_attached_change = .;
- KEEP(*(.rodata.HOOK_BASE_ATTACHED_CHANGE))
- __hooks_base_attached_change_end = .;
-
- __hooks_pwrbtn_change = .;
- *(.rodata.HOOK_POWER_BUTTON_CHANGE)
- __hooks_pwrbtn_change_end = .;
-
- __hooks_battery_soc_change = .;
- *(.rodata.HOOK_BATTERY_SOC_CHANGE)
- __hooks_battery_soc_change_end = .;
-
- __hooks_tick = .;
- *(.rodata.HOOK_TICK)
- __hooks_tick_end = .;
-
- __hooks_second = .;
- *(.rodata.HOOK_SECOND)
- __hooks_second_end = .;
-
- __hooks_usb_pd_disconnect = .;
- *(.rodata.HOOK_USB_PD_DISCONNECT)
- __hooks_usb_pd_disconnect_end = .;
-
- __hooks_usb_pd_connect = .;
- KEEP(*(.rodata.HOOK_USB_PD_CONNECT))
- __hooks_usb_pd_connect_end = .;
-
- __deferred_funcs = .;
- *(.rodata.deferred)
- __deferred_funcs_end = .;
-
- __test_i2c_xfer = .;
- *(.rodata.test_i2c.xfer)
- __test_i2c_xfer_end = .;
- }
-}
-INSERT BEFORE .rodata;
-
-SECTIONS {
- .bss.ec_sections : {
- /* Symbols defined here are declared in link_defs.h */
- . = ALIGN(8);
- __deferred_until = .;
- . += (__deferred_funcs_end - __deferred_funcs) * (8 / 4);
- __deferred_until_end = .;
- }
-}
-INSERT BEFORE .bss;
diff --git a/core/host/host_task.h b/core/host/host_task.h
deleted file mode 100644
index 30cd2ff594..0000000000
--- a/core/host/host_task.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Emulator task scheduling module */
-
-#ifndef __CROS_EC_HOST_TASK_H
-#define __CROS_EC_HOST_TASK_H
-
-#include <pthread.h>
-
-#include "task.h"
-
-/**
- * Returns the thread corresponding to the task.
- */
-pthread_t task_get_thread(task_id_t tskid);
-
-/**
- * Returns the ID of the active task, regardless of current thread
- * context.
- */
-task_id_t task_get_running(void);
-
-/**
- * Initializes the interrupt semaphore and associates a signal handler with
- * SIGNAL_INTERRUPT.
- */
-void task_register_interrupt(void);
-
-/**
- * Returns the process ID of the calling process.
- */
-pid_t getpid(void);
-
-#endif /* __CROS_EC_HOST_TASK_H */
diff --git a/core/host/irq_handler.h b/core/host/irq_handler.h
deleted file mode 100644
index f905f463c1..0000000000
--- a/core/host/irq_handler.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Copyright 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Helper to declare IRQ handling routines */
-
-#ifndef __CROS_EC_IRQ_HANDLER_H
-#define __CROS_EC_IRQ_HANDLER_H
-
-/* Helper macros to build the IRQ handler and priority struct names */
-#define IRQ_HANDLER(irqname) CONCAT3(irq_, irqname, _handler)
-#define IRQ_PRIORITY(irqname) CONCAT2(prio_, irqname)
-/*
- * Macro to connect the interrupt handler "routine" to the irq number "irq" and
- * ensure it is enabled in the interrupt controller with the right priority.
- */
-#define DECLARE_IRQ(irq, routine, priority) \
- void routine(void); \
- void IRQ_HANDLER(irq)(void) \
- { \
- void *ret = __builtin_return_address(0); \
- task_start_irq_handler(ret); \
- routine(); \
- task_resched_if_needed(ret); \
- } \
- const struct irq_priority __keep IRQ_PRIORITY(irq) \
- __attribute__((section(".rodata.irqprio"))) \
- = {irq, priority}
-#endif /* __CROS_EC_IRQ_HANDLER_H */
diff --git a/core/host/main.c b/core/host/main.c
deleted file mode 100644
index ed7032eb63..0000000000
--- a/core/host/main.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Entry point of unit test executable */
-
-#include "console.h"
-#include "flash.h"
-#include "hooks.h"
-#include "host_task.h"
-#include "keyboard_scan.h"
-#include "stack_trace.h"
-#include "system.h"
-#include "task.h"
-#include "test_util.h"
-#include "timer.h"
-#include "uart.h"
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
-#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
-
-const char *__prog_name;
-
-const char *__get_prog_name(void)
-{
- return __prog_name;
-}
-
-static int test_main(void)
-{
- /*
- * In order to properly service IRQs before task switching is enabled,
- * we must set up our signal handler for the main thread.
- */
- task_register_interrupt();
-
- task_register_tracedump();
-
- register_test_end_hook();
-
- crec_flash_pre_init();
- system_pre_init();
- system_common_pre_init();
-
- test_init();
-
- timer_init();
-#ifdef HAS_TASK_KEYSCAN
- keyboard_scan_init();
-#endif
- uart_init();
-
- if (system_jumped_to_this_image()) {
- CPRINTS("Emulator initialized after sysjump");
- } else {
- CPUTS("\n\n--- Emulator initialized after reboot ---\n");
- CPUTS("[Reset cause: ");
- system_print_reset_flags();
- CPUTS("]\n");
- }
-
- task_start();
-
- return 0;
-}
-
-#ifdef TEST_FUZZ
-/*
- * Fuzzing tests need to start the main function in a thread, so that
- * LLVMFuzzerTestOneInput can run freely.
- */
-void *_main_thread(void *a)
-{
- test_main();
- return NULL;
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
-{
- static int initialized;
- static pthread_t main_t;
- /*
- * We lose the program name as LLVM fuzzer takes over main function:
- * make up one.
- */
- static const char *name = STRINGIFY(PROJECT)".exe";
-
- if (!initialized) {
- __prog_name = name;
- pthread_create(&main_t, NULL, _main_thread, NULL);
- initialized = 1;
- /* We can't sleep yet, busy loop waiting for tasks to start. */
- wait_for_task_started_nosleep();
- /* Let tasks settle. */
- msleep(50 * MSEC);
- }
-
- return test_fuzz_one_input(data, size);
-}
-#else
-int main(int argc, char **argv)
-{
- __prog_name = argv[0];
- return test_main();
-}
-#endif
diff --git a/core/host/panic.c b/core/host/panic.c
deleted file mode 100644
index 7b0829989d..0000000000
--- a/core/host/panic.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "stack_trace.h"
-
-void panic_assert_fail(const char *msg, const char *func, const char *fname,
- int linenum)
-{
- fprintf(stderr, "ASSERTION FAIL: %s:%d:%s - %s\n",
- fname, linenum, func, msg);
- task_dump_trace();
-
- puts("Fail!"); /* Inform test runner */
- fflush(stdout);
-
- exit(1);
-}
diff --git a/core/host/stack_trace.c b/core/host/stack_trace.c
deleted file mode 100644
index adef66dd44..0000000000
--- a/core/host/stack_trace.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <execinfo.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "host_task.h"
-#include "host_test.h"
-#include "timer.h"
-
-#define SIGNAL_TRACE_DUMP SIGTERM
-#define MAX_TRACE 30
-/*
- * When trace dump is requested from signal handler, skip:
- * _task_dump_trace_impl
- * _task_dump_trace_dispath
- * A function in libc
- */
-#define SIGNAL_TRACE_OFFSET 3
-/*
- * When trace dump is requested from task_dump_trace(), skip:
- * task_dump_trace
- * _task_dump_trace_impl
- */
-#define DIRECT_TRACE_OFFSET 2
-
-static pthread_t main_thread;
-
-static void __attribute__((noinline)) _task_dump_trace_impl(int offset)
-{
- void *trace[MAX_TRACE];
- size_t sz;
- char **messages;
- char buf[256];
- FILE *file;
- int i, nb;
-
- sz = backtrace(trace, MAX_TRACE);
- messages = backtrace_symbols(trace + offset, sz - offset);
-
- for (i = 0; i < sz - offset; ++i) {
- fprintf(stderr, "#%-2d %s\n", i, messages[i]);
- /* %p is correct (as opposed to %pP) since this is the host */
- sprintf(buf, "addr2line %p -e %s",
- trace[i + offset], __get_prog_name());
- file = popen(buf, "r");
- if (file) {
- nb = fread(buf, 1, sizeof(buf) - 1, file);
- buf[nb] = '\0';
- fprintf(stderr, " %s", buf);
- pclose(file);
- }
- }
- fflush(stderr);
- free(messages);
-}
-
-void __attribute__((noinline)) task_dump_trace(void)
-{
- _task_dump_trace_impl(DIRECT_TRACE_OFFSET);
-}
-
-static void __attribute__((noinline)) _task_dump_trace_dispatch(int sig)
-{
- int need_dispatch = 1;
- task_id_t running = task_get_running();
-
- if (!pthread_equal(pthread_self(), main_thread)) {
- need_dispatch = 0;
- } else if (!task_start_called()) {
- fprintf(stderr, "Stack trace of main thread:\n");
- need_dispatch = 0;
- } else if (in_interrupt_context()) {
- fprintf(stderr, "Stack trace of ISR:\n");
- } else {
- fprintf(stderr, "Stack trace of task %d (%s):\n",
- running, task_get_name(running));
- }
-
- if (need_dispatch) {
- pthread_kill(task_get_thread(running), SIGNAL_TRACE_DUMP);
- } else {
- _task_dump_trace_impl(SIGNAL_TRACE_OFFSET);
- exit(1);
- }
-}
-
-void task_register_tracedump(void)
-{
- /* Trace dumper MUST be registered from main thread */
- main_thread = pthread_self();
- signal(SIGNAL_TRACE_DUMP, _task_dump_trace_dispatch);
-}
diff --git a/core/host/task.c b/core/host/task.c
deleted file mode 100644
index be7ed3c579..0000000000
--- a/core/host/task.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Task scheduling / events module for Chrome EC operating system */
-
-#include <malloc.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "atomic.h"
-#include "common.h"
-#include "console.h"
-#include "host_task.h"
-#include "task.h"
-#include "task_id.h"
-#include "test_util.h"
-#include "timer.h"
-
-#define SIGNAL_INTERRUPT SIGUSR1
-
-struct emu_task_t {
- pthread_t thread;
- pthread_cond_t resume;
- uint32_t event;
- timestamp_t wake_time;
- uint8_t started;
-};
-
-struct task_args {
- void (*routine)(void *);
- void *d;
-};
-
-static struct emu_task_t tasks[TASK_ID_COUNT];
-static pthread_cond_t scheduler_cond;
-static pthread_mutex_t run_lock;
-static task_id_t running_task_id;
-static int task_started;
-
-static sem_t interrupt_sem;
-static pthread_mutex_t interrupt_lock;
-static pthread_t interrupt_thread;
-static int in_interrupt;
-static int interrupt_disabled;
-static void (*pending_isr)(void);
-static int generator_sleeping;
-static timestamp_t generator_sleep_deadline;
-static int has_interrupt_generator = 1;
-
-/* thread local task id */
-static __thread task_id_t my_task_id = TASK_ID_INVALID;
-
-static void task_enable_all_tasks_callback(void);
-
-#define TASK(n, r, d, s) void r(void *);
-CONFIG_TASK_LIST
-CONFIG_TEST_TASK_LIST
-CONFIG_CTS_TASK_LIST
-#undef TASK
-
-/* usleep that uses OS functions, instead of emulated timer. */
-void _usleep(int usec)
-{
- struct timespec req;
-
- req.tv_sec = usec / 1000000;
- req.tv_nsec = (usec % 1000000) * 1000;
-
- nanosleep(&req, NULL);
-}
-
-/* msleep that uses OS functions, instead of emulated timer. */
-void _msleep(int msec)
-{
- _usleep(1000 * msec);
-}
-
-/* Idle task */
-void __idle(void *d)
-{
- while (1)
- task_wait_event(-1);
-}
-
-void _run_test(void *d)
-{
- run_test(0, NULL);
-}
-
-#define TASK(n, r, d, s) {r, d},
-const struct task_args task_info[TASK_ID_COUNT] = {
- {__idle, NULL},
- CONFIG_TASK_LIST
- CONFIG_TEST_TASK_LIST
- CONFIG_CTS_TASK_LIST
- {_run_test, NULL},
-};
-#undef TASK
-
-#define TASK(n, r, d, s) #n,
-static const char * const task_names[] = {
- "<< idle >>",
- CONFIG_TASK_LIST
- CONFIG_TEST_TASK_LIST
- CONFIG_CTS_TASK_LIST
- "<< test runner >>",
-};
-#undef TASK
-
-void task_pre_init(void)
-{
- /* Nothing */
-}
-
-int in_interrupt_context(void)
-{
- return !!in_interrupt;
-}
-
-test_mockable void interrupt_disable(void)
-{
- pthread_mutex_lock(&interrupt_lock);
- interrupt_disabled = 1;
- pthread_mutex_unlock(&interrupt_lock);
-}
-
-test_mockable void interrupt_enable(void)
-{
- pthread_mutex_lock(&interrupt_lock);
- interrupt_disabled = 0;
- pthread_mutex_unlock(&interrupt_lock);
-}
-
-inline int is_interrupt_enabled(void)
-{
- return !interrupt_disabled;
-}
-
-static void _task_execute_isr(int sig)
-{
- in_interrupt = 1;
- pending_isr();
- sem_post(&interrupt_sem);
- in_interrupt = 0;
-}
-
-void task_register_interrupt(void)
-{
- sem_init(&interrupt_sem, 0, 0);
- signal(SIGNAL_INTERRUPT, _task_execute_isr);
-}
-
-void task_trigger_test_interrupt(void (*isr)(void))
-{
- pid_t main_pid;
- pthread_mutex_lock(&interrupt_lock);
- if (interrupt_disabled) {
- pthread_mutex_unlock(&interrupt_lock);
- return;
- }
-
- /* Suspend current task and excute ISR */
- pending_isr = isr;
- if (task_started) {
- pthread_kill(tasks[running_task_id].thread, SIGNAL_INTERRUPT);
- } else {
- main_pid = getpid();
- kill(main_pid, SIGNAL_INTERRUPT);
- }
-
- /* Wait for ISR to complete */
- sem_wait(&interrupt_sem);
- while (in_interrupt)
- _usleep(10);
- pending_isr = NULL;
-
- pthread_mutex_unlock(&interrupt_lock);
-}
-
-void interrupt_generator_udelay(unsigned us)
-{
- generator_sleep_deadline.val = get_time().val + us;
- generator_sleeping = 1;
- while (get_time().val < generator_sleep_deadline.val)
- ;
- generator_sleeping = 0;
-}
-
-const char *task_get_name(task_id_t tskid)
-{
- return task_names[tskid];
-}
-
-pthread_t task_get_thread(task_id_t tskid)
-{
- return tasks[tskid].thread;
-}
-
-uint32_t task_set_event(task_id_t tskid, uint32_t event)
-{
- atomic_or(&tasks[tskid].event, event);
- return 0;
-}
-
-uint32_t *task_get_event_bitmap(task_id_t tskid)
-{
- return &tasks[tskid].event;
-}
-
-uint32_t task_wait_event(int timeout_us)
-{
- int tid = task_get_current();
- int ret;
- pthread_mutex_lock(&interrupt_lock);
- if (timeout_us > 0)
- tasks[tid].wake_time.val = get_time().val + timeout_us;
-
- /* Transfer control to scheduler */
- pthread_cond_signal(&scheduler_cond);
- pthread_cond_wait(&tasks[tid].resume, &run_lock);
-
- /* Resume */
- ret = atomic_clear(&tasks[tid].event);
- pthread_mutex_unlock(&interrupt_lock);
- return ret;
-}
-
-uint32_t task_wait_event_mask(uint32_t event_mask, int timeout_us)
-{
- uint64_t deadline = get_time().val + timeout_us;
- uint32_t events = 0;
- int time_remaining_us = timeout_us;
-
- /* Add the timer event to the mask so we can indicate a timeout */
- event_mask |= TASK_EVENT_TIMER;
-
- while (!(events & event_mask)) {
- /* Collect events to re-post later */
- events |= task_wait_event(time_remaining_us);
-
- time_remaining_us = deadline - get_time().val;
- if (timeout_us > 0 && time_remaining_us <= 0) {
- /* Ensure we return a TIMER event if we timeout */
- events |= TASK_EVENT_TIMER;
- break;
- }
- }
-
- /* Re-post any other events collected */
- if (events & ~event_mask)
- atomic_or(&tasks[task_get_current()].event,
- events & ~event_mask);
-
- return events & event_mask;
-}
-
-void mutex_lock(struct mutex *mtx)
-{
- int value = 0;
- int id = 1 << task_get_current();
-
- mtx->waiters |= id;
-
- do {
- if (mtx->lock == 0) {
- mtx->lock = 1;
- value = 1;
- }
-
- if (!value)
- task_wait_event_mask(TASK_EVENT_MUTEX, 0);
- } while (!value);
-
- mtx->waiters &= ~id;
-}
-
-void mutex_unlock(struct mutex *mtx)
-{
- int v;
- mtx->lock = 0;
-
- for (v = 31; v >= 0; --v)
- if ((1ul << v) & mtx->waiters) {
- mtx->waiters &= ~(1ul << v);
- task_set_event(v, TASK_EVENT_MUTEX);
- break;
- }
-}
-
-task_id_t task_get_current(void)
-{
- return my_task_id;
-}
-
-task_id_t task_get_running(void)
-{
- return running_task_id;
-}
-
-void task_print_list(void)
-{
- int i;
-
- ccputs("Name Events\n");
-
- for (i = 0; i < TASK_ID_COUNT; i++) {
- ccprintf("%4d %-16s %08x\n", i, task_names[i], tasks[i].event);
- cflush();
- }
-}
-
-int command_task_info(int argc, char **argv)
-{
- task_print_list();
-
- return EC_SUCCESS;
-}
-DECLARE_SAFE_CONSOLE_COMMAND(taskinfo, command_task_info,
- NULL,
- "Print task info");
-
-static void _wait_for_task_started(int can_sleep)
-{
- int i, ok;
-
- while (1) {
- ok = 1;
- for (i = 0; i < TASK_ID_COUNT - 1; ++i) {
- if (!tasks[i].started) {
- if (can_sleep)
- msleep(10);
- else
- _msleep(10);
- ok = 0;
- break;
- }
- }
- if (ok)
- return;
- }
-}
-
-void wait_for_task_started(void)
-{
- _wait_for_task_started(1);
-}
-
-void wait_for_task_started_nosleep(void)
-{
- _wait_for_task_started(0);
-}
-
-static task_id_t task_get_next_wake(void)
-{
- int i;
- timestamp_t min_time;
- int which_task = TASK_ID_INVALID;
-
- min_time.val = ~0ull;
-
- for (i = TASK_ID_COUNT - 1; i >= 0; --i)
- if (min_time.val >= tasks[i].wake_time.val) {
- min_time.val = tasks[i].wake_time.val;
- which_task = i;
- }
-
- return which_task;
-}
-
-static int fast_forward(void)
-{
- /*
- * No task has event pending, and thus the next time we have an
- * event to process must be either of:
- * 1. Interrupt generator triggers an interrupt
- * 2. The next wake alarm is reached
- * So we should check whether an interrupt may happen, and fast
- * forward to the nearest among:
- * 1. When interrupt generator wakes up
- * 2. When the next task wakes up
- */
- int task_id = task_get_next_wake();
-
- if (!has_interrupt_generator) {
- if (task_id == TASK_ID_INVALID) {
- return TASK_ID_IDLE;
- } else {
- force_time(tasks[task_id].wake_time);
- return task_id;
- }
- }
-
- if (!generator_sleeping)
- return TASK_ID_IDLE;
-
- if (task_id != TASK_ID_INVALID &&
- tasks[task_id].thread != (pthread_t)NULL &&
- tasks[task_id].wake_time.val < generator_sleep_deadline.val) {
- force_time(tasks[task_id].wake_time);
- return task_id;
- } else {
- force_time(generator_sleep_deadline);
- return TASK_ID_IDLE;
- }
-}
-
-int task_start_called(void)
-{
- return task_started;
-}
-
-void task_scheduler(void)
-{
- int i;
- timestamp_t now;
-
- task_started = 1;
-
- while (1) {
- now = get_time();
- i = TASK_ID_COUNT - 1;
- while (i >= 0) {
- /*
- * Only tasks with spawned threads are valid to be
- * resumed.
- */
- if (tasks[i].thread) {
- if (tasks[i].event ||
- now.val >= tasks[i].wake_time.val)
- break;
- }
- --i;
- }
- if (i < 0)
- i = fast_forward();
-
- now = get_time();
- if (now.val >= tasks[i].wake_time.val)
- tasks[i].event |= TASK_EVENT_TIMER;
- tasks[i].wake_time.val = ~0ull;
- running_task_id = i;
- tasks[i].started = 1;
- pthread_cond_signal(&tasks[i].resume);
- pthread_cond_wait(&scheduler_cond, &run_lock);
- }
-}
-
-void *_task_start_impl(void *a)
-{
- long tid = (long)a;
- const struct task_args *arg = task_info + tid;
- my_task_id = tid;
- pthread_mutex_lock(&run_lock);
-
- /* Wait for scheduler */
- task_wait_event(1);
- tasks[tid].event = 0;
-
- /* Start the task routine */
- (arg->routine)(arg->d);
-
- /* Catch exited routine */
- while (1)
- task_wait_event(-1);
-}
-
-test_mockable void interrupt_generator(void)
-{
- has_interrupt_generator = 0;
-}
-
-void *_task_int_generator_start(void *d)
-{
- my_task_id = TASK_ID_INT_GEN;
- interrupt_generator();
- return NULL;
-}
-
-int task_start(void)
-{
- int i = TASK_ID_HOOKS;
-
- pthread_mutex_init(&run_lock, NULL);
- pthread_mutex_init(&interrupt_lock, NULL);
- pthread_cond_init(&scheduler_cond, NULL);
-
- pthread_mutex_lock(&run_lock);
-
- /*
- * Initialize the hooks task first. After its init, it will callback to
- * enable the remaining tasks.
- */
- tasks[i].event = TASK_EVENT_WAKE;
- tasks[i].wake_time.val = ~0ull;
- tasks[i].started = 0;
- pthread_cond_init(&tasks[i].resume, NULL);
- pthread_create(&tasks[i].thread, NULL, _task_start_impl,
- (void *)(uintptr_t)i);
- pthread_cond_wait(&scheduler_cond, &run_lock);
- /*
- * Interrupt lock is grabbed by the task which just started.
- * Let's unlock it so the next task can be started.
- */
- pthread_mutex_unlock(&interrupt_lock);
-
- /*
- * The hooks task is waiting in task_wait_event(). Lock interrupt_lock
- * here so the first task chosen sees it locked.
- */
- pthread_mutex_lock(&interrupt_lock);
-
- pthread_create(&interrupt_thread, NULL,
- _task_int_generator_start, NULL);
-
- /*
- * Tell the hooks task to continue so that it can call back to enable
- * the other tasks.
- */
- pthread_cond_signal(&tasks[i].resume);
- pthread_cond_wait(&scheduler_cond, &run_lock);
- task_enable_all_tasks_callback();
-
- task_scheduler();
-
- return 0;
-}
-
-static void task_enable_all_tasks_callback(void)
-{
- int i;
-
- /* Initialize the remaning tasks. */
- for (i = 0; i < TASK_ID_COUNT; ++i) {
- if (tasks[i].thread != (pthread_t)NULL)
- continue;
-
- tasks[i].event = TASK_EVENT_WAKE;
- tasks[i].wake_time.val = ~0ull;
- tasks[i].started = 0;
- pthread_cond_init(&tasks[i].resume, NULL);
- pthread_create(&tasks[i].thread, NULL, _task_start_impl,
- (void *)(uintptr_t)i);
- /*
- * Interrupt lock is grabbed by the task which just started.
- * Let's unlock it so the next task can be started.
- */
- pthread_mutex_unlock(&interrupt_lock);
- pthread_cond_wait(&scheduler_cond, &run_lock);
- }
-
-}
-
-void task_enable_all_tasks(void)
-{
- /* Signal to the scheduler to enable the remaining tasks. */
- pthread_cond_signal(&scheduler_cond);
-}
diff --git a/core/host/timer.c b/core/host/timer.c
deleted file mode 100644
index 3c3695cad4..0000000000
--- a/core/host/timer.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Timer module */
-
-#include <stdint.h>
-#include <stdio.h>
-
-#include "task.h"
-#include "test_util.h"
-#include "timer.h"
-#include "util.h"
-
-static timestamp_t boot_time;
-static int time_set;
-
-void usleep(unsigned us)
-{
- if (!task_start_called() || task_get_current() == TASK_ID_INVALID) {
- udelay(us);
- return;
- }
-
- ASSERT(!in_interrupt_context() &&
- task_get_current() != TASK_ID_INT_GEN);
-
- task_wait_event(us);
-}
-
-timestamp_t _get_time(void)
-{
- static timestamp_t time;
-
- /*
- * We just monotonically increase the microsecond every time we check
- * the time. Do not depend on host system time as this introduces
- * flakyness in tests. The time is periodically fast forwarded with
- * force_time() during the host's task scheduler implementation.
- */
- ++time.val;
- return time;
-}
-
-test_mockable timestamp_t get_time(void)
-{
- timestamp_t ret = _get_time();
- ret.val -= boot_time.val;
- return ret;
-}
-
-uint32_t __hw_clock_source_read(void)
-{
- return get_time().le.lo;
-}
-
-void force_time(timestamp_t ts)
-{
- timestamp_t now = _get_time();
- boot_time.val = now.val - ts.val;
- time_set = 1;
-}
-
-void udelay(unsigned us)
-{
- timestamp_t deadline;
-
- if (!in_interrupt_context() && task_get_current() == TASK_ID_INT_GEN) {
- interrupt_generator_udelay(us);
- return;
- }
-
- deadline.val = get_time().val + us;
- while (get_time().val < deadline.val)
- ;
-}
-
-int timestamp_expired(timestamp_t deadline, const timestamp_t *now)
-{
- timestamp_t now_val;
-
- if (!now) {
- now_val = get_time();
- now = &now_val;
- }
-
- return ((int64_t)(now->val - deadline.val) >= 0);
-}
-
-void timer_init(void)
-{
-
- if (!time_set) {
- /*
- * Start the timer just before the 64-bit rollover to try
- * and catch 32-bit rollover/truncation bugs.
- */
- timestamp_t ts = {
- .val = 0xFFFFFFF0
- };
-
- force_time(ts);
- }
-}