/* * 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 #include #include #include #include #include #include #include #include /* 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; } }