189 lines
3.6 KiB
C
189 lines
3.6 KiB
C
|
/* Copyright 2016 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 "clock.h"
|
||
|
#include "common.h"
|
||
|
#include "console.h"
|
||
|
#include "cpu.h"
|
||
|
#include "gpio.h"
|
||
|
#include "hooks.h"
|
||
|
#include "host_command.h"
|
||
|
#include "interrupts.h"
|
||
|
#include "ish_fwst.h"
|
||
|
#include "ish_persistent_data.h"
|
||
|
#include "power_mgt.h"
|
||
|
#include "registers.h"
|
||
|
#include "shared_mem.h"
|
||
|
#include "spi.h"
|
||
|
#include "system.h"
|
||
|
#include "task.h"
|
||
|
#include "timer.h"
|
||
|
#include "util.h"
|
||
|
|
||
|
#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
|
||
|
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
|
||
|
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
|
||
|
|
||
|
int system_is_reboot_warm(void)
|
||
|
{
|
||
|
return !(system_get_reset_flags() &
|
||
|
(EC_RESET_FLAG_POWER_ON | EC_RESET_FLAG_HARD));
|
||
|
}
|
||
|
|
||
|
void system_pre_init(void)
|
||
|
{
|
||
|
ish_fwst_set_fw_status(FWSTS_FW_IS_RUNNING);
|
||
|
task_enable_irq(ISH_FABRIC_IRQ);
|
||
|
ish_pm_init();
|
||
|
ish_persistent_data_init();
|
||
|
}
|
||
|
|
||
|
void chip_save_reset_flags(uint32_t flags)
|
||
|
{
|
||
|
ish_persistent_data.reset_flags = flags;
|
||
|
}
|
||
|
|
||
|
uint32_t chip_read_reset_flags(void)
|
||
|
{
|
||
|
return ish_persistent_data.reset_flags;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Kill the Minute-IA core and don't come back alive.
|
||
|
*
|
||
|
* Used when the watchdog timer exceeds max retries and we want to
|
||
|
* disable ISH completely.
|
||
|
*/
|
||
|
__attribute__((noreturn))
|
||
|
static void system_halt(void)
|
||
|
{
|
||
|
cflush();
|
||
|
|
||
|
while (1) {
|
||
|
disable_all_interrupts();
|
||
|
WDT_CONTROL = 0;
|
||
|
CCU_TCG_EN = 1;
|
||
|
__asm__ volatile (
|
||
|
"cli\n"
|
||
|
"hlt\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void system_reset(int flags)
|
||
|
{
|
||
|
uint32_t save_flags;
|
||
|
|
||
|
/*
|
||
|
* We can't save any data when we do an ish_mia_reset(). Take
|
||
|
* the quick path out.
|
||
|
*/
|
||
|
if (!IS_ENABLED(CONFIG_ISH_PM_AONTASK) || flags & SYSTEM_RESET_HARD) {
|
||
|
ish_mia_reset();
|
||
|
__builtin_unreachable();
|
||
|
}
|
||
|
|
||
|
system_encode_save_flags(flags, &save_flags);
|
||
|
|
||
|
if (flags & SYSTEM_RESET_AP_WATCHDOG) {
|
||
|
save_flags |= EC_RESET_FLAG_WATCHDOG;
|
||
|
ish_persistent_data.watchdog_counter += 1;
|
||
|
if (ish_persistent_data.watchdog_counter
|
||
|
>= CONFIG_WATCHDOG_MAX_RETRIES) {
|
||
|
CPRINTS("Halting ISH due to max watchdog resets");
|
||
|
system_halt();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
chip_save_reset_flags(save_flags);
|
||
|
|
||
|
ish_persistent_data_commit();
|
||
|
ish_pm_reset(ISH_PM_STATE_RESET);
|
||
|
__builtin_unreachable();
|
||
|
}
|
||
|
|
||
|
const char *system_get_chip_vendor(void)
|
||
|
{
|
||
|
return "intel";
|
||
|
}
|
||
|
|
||
|
const char *system_get_chip_name(void)
|
||
|
{
|
||
|
return "intel";
|
||
|
}
|
||
|
|
||
|
static char to_hex(int x)
|
||
|
{
|
||
|
if (x >= 0 && x <= 9)
|
||
|
return '0' + x;
|
||
|
return 'a' + x - 10;
|
||
|
}
|
||
|
|
||
|
const char *system_get_chip_revision(void)
|
||
|
{
|
||
|
static char buf[3];
|
||
|
uint8_t rev = 0x86;
|
||
|
|
||
|
buf[0] = to_hex(rev / 16);
|
||
|
buf[1] = to_hex(rev & 0xf);
|
||
|
buf[2] = '\0';
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
int system_get_bbram(enum system_bbram_idx idx, uint8_t *value)
|
||
|
{
|
||
|
return EC_ERROR_UNIMPLEMENTED;
|
||
|
}
|
||
|
|
||
|
int system_set_bbram(enum system_bbram_idx idx, uint8_t value)
|
||
|
{
|
||
|
return EC_ERROR_UNIMPLEMENTED;
|
||
|
}
|
||
|
|
||
|
int system_set_scratchpad(uint32_t value)
|
||
|
{
|
||
|
return EC_SUCCESS;
|
||
|
}
|
||
|
|
||
|
uint32_t system_get_scratchpad(void)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void system_hibernate(uint32_t seconds, uint32_t microseconds)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void htimer_interrupt(void)
|
||
|
{
|
||
|
/* Time to wake up */
|
||
|
}
|
||
|
|
||
|
enum system_image_copy_t system_get_shrspi_image_copy(void)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
uint32_t system_get_lfw_address(void)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void system_set_image_copy(enum system_image_copy_t copy)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
static void fabric_isr(void)
|
||
|
{
|
||
|
/**
|
||
|
* clear fabric error status, otherwise it will wakeup ISH immediately
|
||
|
* when entered low power mode.
|
||
|
* TODO(b:130740646): figure out why this issue happens.
|
||
|
*/
|
||
|
if (FABRIC_AGENT_STATUS & FABRIC_MIA_STATUS_BIT_ERR)
|
||
|
FABRIC_AGENT_STATUS = FABRIC_AGENT_STATUS;
|
||
|
}
|
||
|
|
||
|
DECLARE_IRQ(ISH_FABRIC_IRQ, fabric_isr);
|