diff options
author | Andrey Petrov <andrey.petrov@intel.com> | 2017-06-05 18:09:51 -0700 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2017-07-13 21:04:47 +0000 |
commit | fed4303b45aa3c8ba98cd2ab90cf5bf023fc6aae (patch) | |
tree | e47018a118754d564e7ac00403e744136f7ca968 /src/soc | |
parent | 6a00113de8b9060a7227bcfa79b3786e3e592a33 (diff) |
soc/intel/cannonlake: Add reset.c
Add reset functionality. This implementation relies on CSE to trigger
global reset.
Change-Id: I7e6ae07a48f1cdc3d2f4cdb74246627d27253adf
Signed-off-by: Andrey Petrov <andrey.petrov@intel.com>
Reviewed-on: https://review.coreboot.org/20070
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/intel/cannonlake/reset.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/soc/intel/cannonlake/reset.c b/src/soc/intel/cannonlake/reset.c new file mode 100644 index 0000000000..93714d3b9a --- /dev/null +++ b/src/soc/intel/cannonlake/reset.c @@ -0,0 +1,100 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corporation. + * + * 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 <console/console.h> +#include <intelblocks/cse.h> +#include <fsp/util.h> +#include <reset.h> +#include <timer.h> + +/* Reset Request */ +#define MKHI_GLOBAL_RESET 0x0b + +#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; + } __attribute__ ((packed)) reply; + struct reset_message { + u8 group_id; + u8 cmd; + u8 reserved; + u8 result; + u8 req_origin; + u8 reset_type; + } __attribute__ ((packed)); + struct reset_message msg = { + .cmd = MKHI_GLOBAL_RESET, + .group_id = 0, + .reserved = 0, + .result = 0, + .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); + heci_receive(&reply, &reply_size); + /* get reply result from HECI MSG */ + if (reply.result != 0) { + printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__); + return -1; + } + printk(BIOS_DEBUG, "%s: Exit with Success\n", __func__); + return 0; +} + +void do_global_reset(void) +{ + /* Ask CSE to do the global reset */ + send_heci_reset_message(); + /* + * TODO: Presumbily we shouldn't return. But if we did, fallback to + * alternative way of triggered global reset provided by pmclib. + */ +} + +void chipset_handle_reset(uint32_t status) +{ + switch (status) { + case FSP_STATUS_RESET_REQUIRED_3: /* Global Reset */ + printk(BIOS_DEBUG, "GLOBAL RESET!!\n"); + do_global_reset(); + break; + default: + printk(BIOS_ERR, "unhandled reset type %x\n", status); + die("unknown reset type"); + break; + } +} |