blob: 470b5f4fde7e2a5e9ee1ecfbfaaff1693b2b6eae [file] [log] [blame]
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2018 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <cf9_reset.h>
#include <console/console.h>
#include <intelblocks/cse.h>
#include <intelblocks/pmclib.h>
#include <fsp/util.h>
#include <soc/intel/common/reset.h>
#include <string.h>
#include <soc/pci_devs.h>
/* Reset Request */
#define MKHI_GLOBAL_RESET 0x0b
#define MKHI_STATUS_SUCCESS 0
#define GR_ORIGIN_BIOS_MEM_INIT 0x01
#define GR_ORIGIN_BIOS_POST 0x02
#define GR_ORIGIN_MEBX 0x03
#define GLOBAL_RST_TYPE 0x01
#define BIOS_HOST_ADD 0x00
#define HECI_MKHI_ADD 0x07
static int send_heci_reset_message(void)
{
int status;
struct reset_reply {
u8 group_id;
u8 command;
u8 reserved;
u8 result;
} __packed reply;
struct reset_message {
u8 group_id;
u8 cmd;
u8 reserved;
u8 result;
u8 req_origin;
u8 reset_type;
} __packed;
struct reset_message msg = {
.cmd = MKHI_GLOBAL_RESET,
.req_origin = GR_ORIGIN_BIOS_POST,
.reset_type = GLOBAL_RST_TYPE
};
size_t reply_size;
heci_reset();
status = heci_send(&msg, sizeof(msg), BIOS_HOST_ADD, HECI_MKHI_ADD);
if (status != 1)
return -1;
reply_size = sizeof(reply);
memset(&reply, 0, reply_size);
if (!heci_receive(&reply, &reply_size))
return -1;
if (reply.result != MKHI_STATUS_SUCCESS) {
printk(BIOS_DEBUG, "Returned Mkhi Status is not success!\n");
return -1;
}
printk(BIOS_DEBUG, "Heci receive success!\n");
return 0;
}
void do_global_reset(void)
{
/* Ask CSE to do the global reset */
if (!send_heci_reset_message())
return;
/* global reset if CSE fail to reset */
pmc_global_reset_enable(1);
do_full_reset();
}
void chipset_handle_reset(uint32_t status)
{
switch (status) {
case FSP_STATUS_RESET_REQUIRED_3: /* Global Reset */
printk(BIOS_DEBUG, "GLOBAL RESET!!\n");
global_reset();
break;
default:
printk(BIOS_ERR, "unhandled reset type %x\n", status);
die("unknown reset type");
break;
}
}