coreboot-libre-fam15h-rdimm/3rdparty/chromeec/chip/ish/system.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);