| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708 |
- /* Copyright Statement:
- *
- * This software/firmware and related documentation ("MediaTek Software") are
- * protected under relevant copyright laws. The information contained herein
- * is confidential and proprietary to MediaTek Inc. and/or its licensors.
- * Without the prior written permission of MediaTek inc. and/or its licensors,
- * any reproduction, modification, use or disclosure of MediaTek Software,
- * and information contained herein, in whole or in part, shall be strictly prohibited.
- */
- /* MediaTek Inc. (C) 2016. All rights reserved.
- *
- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
- */
- #include <malloc.h>
- #include <printf.h>
- #include <stdarg.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <lib/zlib.h>
- #include <video.h>
- #include <part_interface.h>
- #include <platform/mt_typedefs.h>
- #include <dev/mrdump.h>
- #include <platform/mtk_key.h>
- #include <platform/mtk_wdt.h>
- #include <platform/mt_gpt.h>
- #include <target/board.h>
- #include <target/cust_key.h>
- #include <platform/boot_mode.h>
- #include <bootimg.h>
- #include <platform/ram_console.h>
- #include <arch/ops.h>
- #include <platform.h>
- #include <mt_boot.h>
- #include <platform/errno.h>
- #include "aee.h"
- #include "mrdump_private.h"
- #ifdef MTK_3LEVEL_PAGETABLE
- #include <target.h>
- #endif
- #define MRDUMP_DELAY_TIME 10
- extern BOOT_ARGUMENT *g_boot_arg;
- extern BOOTMODE g_boot_mode;
- static struct mrdump_control_block *mrdump_cb = NULL;
- static struct mrdump_cblock_result cblock_result;
- static unsigned int log_size;
- static int output_device;
- int mrdump_get_env(const char *name, char *out, int out_len)
- {
- struct mrdump_expdb_config mrdump_config;
- struct mrdump_dev *blkpart = mrdump_dev_blkpart(AEE_IPANIC_LABEL);
- if (blkpart == NULL) {
- dprintf(CRITICAL, "%s partition does not exist\n", AEE_IPANIC_LABEL);
- return -ENODEV;
- }
- off_t part_total_size = partition_get_size_by_name(AEE_IPANIC_LABEL);
- off_t offset;
- bool status;
- offset = part_total_size - MRDUMP_CONFIG_EXPDB_OFFSET;
- status = blkpart->read(blkpart, offset, (uint8_t *)&mrdump_config, sizeof(struct mrdump_expdb_config));
- free(blkpart);
- if (!status) {
- dprintf(CRITICAL, "%s: bio_read fail\n", __func__);
- return -EIO;
- }
- if (!strncmp(name, MRDUMP_OUTPUT, sizeof(MRDUMP_OUTPUT))) {
- if (strlcpy(out, mrdump_config.output_dev, out_len) >= out_len) {
- dprintf(CRITICAL, "%s: mrdump_config.output_dev too long\n", __func__);
- return -1;
- }
- dprintf(CRITICAL, "%s: %s\n", MRDUMP_OUTPUT, out);
- } else if (!strncmp(name, MRDUMP_ALLOCATE_SIZE, 20)) {
- if (strlcpy(out, mrdump_config.allocate_size, out_len) >= out_len) {
- dprintf(CRITICAL, "%s: mrdump_config.allocate_size too long\n", __func__);
- return -1;
- }
- dprintf(CRITICAL, "%s: %s\n", MRDUMP_ALLOCATE_SIZE, out);
- } else if (!strncmp(name, MRDUMP_MEM_SIZE, sizeof(MRDUMP_MEM_SIZE))) {
- if (strlcpy(out, mrdump_config.mem_size, out_len) >= out_len) {
- dprintf(CRITICAL, "%s: mrdump_config.mem_size too long\n", __func__);
- return -1;
- }
- } else if (!strncmp(name, MRDUMP_LBAOOO, sizeof(MRDUMP_LBAOOO))) {
- if (strlcpy(out, mrdump_config.lbaooo, out_len) >= out_len) {
- dprintf(CRITICAL, "%s: mrdump_config.lbaooo too long\n", __func__);
- return -1;
- }
- } else if (!strncmp(name, MRDUMP_DUMP_TYPE, sizeof(MRDUMP_DUMP_TYPE))) {
- if (strlcpy(out, mrdump_config.dump_type, out_len) >= out_len) {
- dprintf(CRITICAL, "%s: mrdump_config.dump_type too long\n", __func__);
- return -1;
- }
- } else {
- dprintf(CRITICAL, "unknown mrdump config %s\n", name);
- return -1;
- }
- dprintf(CRITICAL, "%s: %s\n", name, out);
- return 0;
- }
- int mrdump_set_env(const char *name, const char *value)
- {
- struct mrdump_expdb_config mrdump_config;
- off_t part_total_size;
- off_t offset;
- bool status;
- memset(&mrdump_config, 0, sizeof(mrdump_config));
- struct mrdump_dev *blkpart = mrdump_dev_blkpart(AEE_IPANIC_LABEL);
- if (blkpart == NULL) {
- dprintf(CRITICAL, "%s partition does not exist\n", AEE_IPANIC_LABEL);
- return -ENODEV;
- }
- part_total_size = partition_get_size_by_name(AEE_IPANIC_LABEL);
- offset = part_total_size - MRDUMP_CONFIG_EXPDB_OFFSET;
- status = blkpart->read(blkpart, offset, (uint8_t *)&mrdump_config, sizeof(struct mrdump_expdb_config));
- if (!status) {
- dprintf(CRITICAL, "%s: bio_read fail\n", __func__);
- free(blkpart);
- return -EIO;
- }
- if (mrdump_config.sig != MRDUMP_CONFIG_SIG) {
- memset(&mrdump_config, 0, sizeof(struct mrdump_expdb_config));
- mrdump_config.sig = MRDUMP_CONFIG_SIG;
- }
- if (!strncmp(name, MRDUMP_OUTPUT, sizeof(MRDUMP_OUTPUT))) {
- memcpy(&mrdump_config.output_dev, value, sizeof(mrdump_config.output_dev));
- } else if (!strncmp(name, MRDUMP_ALLOCATE_SIZE, sizeof(MRDUMP_ALLOCATE_SIZE))) {
- memcpy(&mrdump_config.allocate_size, value, sizeof(mrdump_config.allocate_size));
- } else if (!strncmp(name, MRDUMP_MEM_SIZE, sizeof(MRDUMP_MEM_SIZE))) {
- memcpy(&mrdump_config.mem_size, value, sizeof(mrdump_config.mem_size));
- } else if (!strncmp(name, MRDUMP_LBAOOO, sizeof(MRDUMP_LBAOOO))) {
- memcpy(&mrdump_config.lbaooo, value, sizeof(mrdump_config.lbaooo));
- } else if (!strncmp(name, MRDUMP_DUMP_TYPE, sizeof(MRDUMP_DUMP_TYPE))) {
- memcpy(&mrdump_config.dump_type, value, sizeof(mrdump_config.dump_type));
- } else {
- dprintf(CRITICAL, "unknown mrdump config\n");
- free(blkpart);
- return -1;
- }
- dprintf(CRITICAL, "%s update to %s\n", name, value);
- status = blkpart->write(blkpart, offset, (uint8_t *)&mrdump_config, sizeof(struct mrdump_expdb_config));
- if (!status) {
- dprintf(CRITICAL, "%s: bio_write fail\n", __func__);
- free(blkpart);
- return -EIO;
- }
- free(blkpart);
- return 0;
- }
- void voprintf(char type, const char *msg, va_list ap)
- {
- char msgbuf[128], *p;
- p = msgbuf;
- if (msg[0] == '\r') {
- *p++ = msg[0];
- msg++;
- }
- *p++ = type;
- *p++ = ':';
- if (vsnprintf(p, sizeof(msgbuf) - (p - msgbuf), msg, ap) < 0) {
- strlcpy(p, "<Message format error>\n", p - msgbuf);
- }
- switch (type) {
- case 'I':
- case 'W':
- case 'E':
- video_printf("%s", msgbuf);
- break;
- }
- dprintf(CRITICAL,"[%s] %s", MRDUMP_GO_DUMP, msgbuf);
- /* Write log buffer */
- p = msgbuf;
- while ((*p != 0) && (log_size < sizeof(cblock_result.log_buf))) {
- cblock_result.log_buf[log_size] = *p++;
- log_size++;
- }
- }
- void voprintf_verbose(const char *msg, ...)
- {
- va_list ap;
- va_start(ap, msg);
- voprintf('V', msg, ap);
- va_end(ap);
- }
- void voprintf_debug(const char *msg, ...)
- {
- va_list ap;
- va_start(ap, msg);
- voprintf('D', msg, ap);
- va_end(ap);
- }
- void voprintf_info(const char *msg, ...)
- {
- va_list ap;
- va_start(ap, msg);
- voprintf('I', msg, ap);
- va_end(ap);
- }
- void voprintf_warning(const char *msg, ...)
- {
- va_list ap;
- va_start(ap, msg);
- voprintf('W', msg, ap);
- va_end(ap);
- }
- void voprintf_error(const char *msg, ...)
- {
- va_list ap;
- va_start(ap, msg);
- voprintf('E', msg, ap);
- va_end(ap);
- }
- void vo_show_progress(int sizeM)
- {
- video_set_cursor((video_get_rows() / 4) * 3, (video_get_colums() - 22)/ 2);
- video_printf("=====================\n");
- video_set_cursor((video_get_rows() / 4) * 3 + 1, (video_get_colums() - 22)/ 2);
- video_printf(">>> Written %4dM <<<\n", sizeM);
- video_set_cursor((video_get_rows() / 4) * 3 + 2, (video_get_colums() - 22)/ 2);
- video_printf("=====================\n");
- video_set_cursor(video_get_rows() - 1, 0);
- dprintf(CRITICAL,"... Written %dM\n", sizeM);
- }
- static void mrdump_status(const char *status, const char *fmt, va_list ap)
- {
- char *dest = cblock_result.status;
- dest += strlcpy(dest, status, sizeof(cblock_result.status));
- *dest++ = '\n';
- vsnprintf(dest, sizeof(cblock_result.status) - (dest - cblock_result.status), fmt, ap);
- }
- void mrdump_status_ok(const char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- mrdump_status("OK", fmt, ap);
- va_end(ap);
- }
- void mrdump_status_none(const char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- mrdump_status("NONE", fmt, ap);
- va_end(ap);
- }
- void mrdump_status_error(const char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- mrdump_status("FAILED", fmt, ap);
- va_end(ap);
- }
- const const char *mrdump_mode2string(uint8_t mode)
- {
- switch (mode) {
- case AEE_REBOOT_MODE_NORMAL:
- return "NORMAL-BOOT";
- case AEE_REBOOT_MODE_KERNEL_OOPS:
- return "KERNEL-OOPS";
- case AEE_REBOOT_MODE_KERNEL_PANIC:
- return "KERNEL-PANIC";
- case AEE_REBOOT_MODE_NESTED_EXCEPTION:
- return "NESTED-CPU-EXCEPTION";
- case AEE_REBOOT_MODE_WDT:
- return "HWT";
- case AEE_REBOOT_MODE_EXCEPTION_KDUMP:
- return "MANUALDUMP";
- case AEE_REBOOT_MODE_MRDUMP_KEY:
- return "MRDUMP_KEY";
- case AEE_REBOOT_MODE_HANG_DETECT:
- return "KERNEL-HANG-DETECT";
- default:
- return "UNKNOWN-BOOT";
- }
- }
- #define MRDUMP_EXPDB_OFFSET 3145728
- static void mrdump_write_result(void)
- {
- struct mrdump_dev *blkpart = mrdump_dev_blkpart("expdb");
- if (blkpart != NULL) {
- u64 part_size = blkpart->get_size(blkpart);
- if (part_size < MRDUMP_EXPDB_OFFSET + sizeof(cblock_result)) {
- dprintf(CRITICAL, "%s: partition size(%llx) is less then reserved (%x)\n",
- __func__, part_size, MRDUMP_EXPDB_OFFSET);
- free(blkpart);
- return;
- }
- blkpart->write(blkpart, part_size - MRDUMP_EXPDB_OFFSET,
- (uint8_t *) &cblock_result, sizeof(cblock_result));
- free(blkpart);
- }
- else {
- dprintf(CRITICAL, "%s: Cannot find expdb partition\n", __func__);
- }
- }
- #define SIZE_1MB 1048576ULL
- #define SIZE_64MB 67108864ULL
- static uint64_t mrdump_mem_size(void)
- {
- uint64_t total_dump_size = physical_memory_size();
- char mem_size_param[8] = {0};
- if (mrdump_get_env("mrdump_mem_size", mem_size_param, sizeof(mem_size_param)))
- dprintf(CRITICAL, "%s: mrdump_get_env fail\n", __func__);
- if (strcmp(mem_size_param, "")) {
- uint64_t mem_size = atoi(mem_size_param) * SIZE_1MB;
- voprintf_info("Memory dump size set to %uM\n", (unsigned int) (mem_size / SIZE_1MB));
- if (mem_size >= SIZE_64MB) {
- /* minimum 64m */
- total_dump_size = MIN(total_dump_size, mem_size);
- }
- }
- return total_dump_size;
- }
- int mrdump_set_output_device(const char *output_dev)
- {
- int retval = MRDUMP_DEV_UNKNOWN;
- if (strcmp(output_dev, "none") == 0) {
- retval = MRDUMP_DEV_NONE;
- }
- else if (strcmp(output_dev, "null") == 0) {
- retval = MRDUMP_DEV_NULL;
- }
- else if (strcmp(output_dev, "usb") == 0) {
- retval = MRDUMP_DEV_USB;
- }
- else if (strcmp(output_dev, "partition") == 0) {
- retval = MRDUMP_DEV_PARTITION;
- }
- else if (strcmp(output_dev, "internal-storage") == 0) {
- retval = MRDUMP_DEV_ISTORAGE;
- }
- if (retval != MRDUMP_DEV_UNKNOWN) {
- if (mrdump_set_env("mrdump_output", (char *)output_dev) == 0) {
- dprintf(CRITICAL, "%s: defaults: %s\n",__func__, output_dev);
- }
- else {
- dprintf(CRITICAL, "%s: fail to set default mrdump output device\n", __func__);
- }
- }
- else {
- dprintf(CRITICAL, "%s: unknown output device %s\n",__func__, output_dev);
- }
- return retval;
- }
- int mrdump_get_default_output_device(void)
- {
- char output_device_param[64] = "";
- if (mrdump_get_env("mrdump_output", output_device_param, sizeof(output_device_param)))
- dprintf(CRITICAL, "%s: mrdump_get_env fail\n", __func__);
- if (strcmp(output_device_param, "")) {
- if (strcmp(output_device_param, "none") == 0)
- return MRDUMP_DEV_NONE;
- if (strcmp(output_device_param, "null") == 0)
- return MRDUMP_DEV_NULL;
- if (strcmp(output_device_param, "internal-storage") == 0)
- return MRDUMP_DEV_ISTORAGE;
- if (strcmp(output_device_param, "usb") == 0)
- return MRDUMP_DEV_USB;
- if (strcmp(output_device_param, "partition") == 0)
- return MRDUMP_DEV_PARTITION;
- dprintf(CRITICAL, "%s: unknown output device %s\n",__func__,
- output_device_param);
- return MRDUMP_DEV_UNKNOWN;
- }
- #if defined(MRDUMP_DEFAULT_NONE)
- return mrdump_set_output_device("none");
- #elif defined(MRDUMP_DEFAULT_NULL)
- return mrdump_set_output_device("null");
- #elif defined(MRDUMP_DEFAULT_USB_DUMP)
- return mrdump_set_output_device("usb");
- #elif defined(MRDUMP_DEFAULT_MRDUMP_PARTITION)
- return mrdump_set_output_device("partition");
- #elif defined(MRDUMP_DEFAULT_DATA_PARTITION)
- return mrdump_set_output_device("internal-storage");
- #else
- #ifdef MRDUMP_PARTITION_ENABLE
- return mrdump_set_output_device("partition");
- #else
- return mrdump_set_output_device("internal-storage");
- #endif
- #endif
- }
- static struct kzip_addlist *mrdump_memlist_fill(struct mrdump_control_block *mrdump_cblock)
- {
- struct kzip_addlist *memlist = malloc(sizeof(struct kzip_addlist) * 4);
- if (memlist == NULL) {
- return NULL;
- }
- void *bufp = malloc(MRDUMP_CORE_HEADER_SIZE);
- if (bufp == NULL) {
- free(memlist);
- return NULL;
- }
- memset(bufp, 0, MRDUMP_CORE_HEADER_SIZE);
- memlist[0].address = (uint64_t)(uintptr_t) bufp;
- memlist[0].size = MRDUMP_CORE_HEADER_SIZE;
- memlist[0].type = MEM_NO_MAP;
- memlist[0].memmap = 0;
- memlist[0].pageflags = 0;
- memlist[0].struct_page_size = 0;
- memlist[1].address = (uint64_t)(uintptr_t) mrdump_cb_addr();
- memlist[1].size = mrdump_cb_size();
- memlist[1].type = MEM_NO_MAP;
- memlist[1].memmap = 0;
- memlist[1].pageflags = 0;
- memlist[1].struct_page_size = 0;
- memlist[2].address = DRAM_PHY_ADDR;
- memlist[2].size = mrdump_mem_size();
- memlist[2].type = MEM_DO_MAP;
- memlist[2].memmap = mrdump_cblock->machdesc.memmap;
- memlist[2].pageflags = mrdump_cblock->machdesc.pageflags;
- memlist[2].struct_page_size = mrdump_cblock->machdesc.struct_page_size;
- memlist[3].address = 0;
- memlist[3].size = 0;
- memlist[3].type = MEM_NO_MAP;
- memlist[3].memmap = 0;
- memlist[3].pageflags = 0;
- memlist[3].struct_page_size = 0;
- return memlist;
- }
- static void mrdump_memlist_free(struct kzip_addlist *memlist)
- {
- free((void *)(uintptr_t)memlist[0].address);
- free(memlist);
- }
- static void kdump_ui(struct mrdump_control_block *mrdump_cblock)
- {
- video_clear_image_by_color(0xFFFF7F00, 0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT);
- video_set_bgcolor(0xFFFF7F00);
- video_set_fgcolor(0xFFFF0000);
- video_set_cursor(0, 0);
- mrdump_status_error("Unknown error\n");
- voprintf_info("Kdump triggerd by '%s' (address:%x, size:%lluM)\n",
- mrdump_mode2string(mrdump_cblock->crash_record.reboot_mode),
- DRAM_PHY_ADDR, mrdump_mem_size() / 0x100000UL);
- /* check machdesc crc */
- uint32_t mcrc = crc32(0xffffffff, (const unsigned char*)&mrdump_cblock->machdesc,
- sizeof(struct mrdump_machdesc)) ^ 0xffffffff;
- if (mcrc != mrdump_cblock->machdesc_crc) {
- voprintf_error("Control block machdesc field CRC error (%08x, %08x).\n",
- mcrc, mrdump_cblock->machdesc_crc);
- return;
- }
- struct kzip_addlist *memlist_cmm = mrdump_memlist_fill_cmm(mrdump_cblock);
- struct kzip_addlist *memlist = mrdump_memlist_fill(mrdump_cblock);
- if (memlist == NULL) {
- voprintf_error("Cannot allcate memlist memory.\n");
- return;
- }
- mrdump_core_header_init(mrdump_cblock, memlist);
- struct aee_timer elapse_time;
- aee_timer_init(&elapse_time);
- aee_timer_start(&elapse_time);
- int dump_ok;
- switch (output_device) {
- case MRDUMP_DEV_NONE:
- mrdump_status_none("Output to None (disabled)\n");
- voprintf_info("Output to None (disabled)\n");
- dump_ok = 0;
- break;
- case MRDUMP_DEV_NULL:
- dump_ok = mrdump_null_output(mrdump_cblock, memlist, memlist_cmm);
- break;
- case MRDUMP_DEV_ISTORAGE:
- dump_ok = mrdump_ext4_output(mrdump_cblock, memlist, memlist_cmm, mrdump_dev_blkpart("userdata"));
- break;
- case MRDUMP_DEV_USB:
- dump_ok = mrdump_usb_output(mrdump_cblock, memlist, memlist_cmm);
- break;
- case MRDUMP_DEV_PARTITION:
- dump_ok = mrdump_partition_output(mrdump_cblock, memlist, memlist_cmm, mrdump_dev_blkpart("mrdump"));
- break;
- default:
- voprintf_error("Unsupport device id %d\n", output_device);
- dump_ok = -1;
- }
- mrdump_memlist_free(memlist);
- mrdump_memlist_free_cmm(memlist_cmm);
- aee_mrdump_flush_cblock(mrdump_cblock);
- aee_timer_stop(&elapse_time);
- voprintf_info("Dump finished.(%s, %d sec)\n", dump_ok == 0 ? "ok" : "failed", elapse_time.acc_ms / 1000);
- mtk_wdt_restart();
- video_clean_screen();
- video_set_cursor(0, 0);
- }
- int mrdump_detection(void)
- {
- if (mrdump_check_enable() > MRDUMP_ALWAYS_ENABLE)
- return 0;
- mrdump_key_secure_enable();
- output_device = mrdump_get_default_output_device();
- if (output_device == MRDUMP_DEV_UNKNOWN) {
- return 0;
- }
- if (!ram_console_is_abnormal_boot()) {
- dprintf(CRITICAL, "MT-RAMDUMP: No exception detected, skipped\n");
- return 0;
- }
- mrdump_cb = aee_mrdump_get_params();
- if (mrdump_cb == NULL) {
- dprintf(CRITICAL, "MT-RAMDUMP control block not found\n");
- return 0;
- }
- memset(&cblock_result, 0, sizeof(struct mrdump_cblock_result));
- log_size = 0;
- strlcpy(cblock_result.sig, MRDUMP_GO_DUMP, sizeof(cblock_result.sig));
- uint8_t reboot_mode = mrdump_cb->crash_record.reboot_mode;
- if (!g_boot_arg->ddr_reserve_enable) {
- voprintf_debug("DDR reserve mode disabled\n");
- mrdump_status_none("DDR reserve mode disabled\n");
- goto error;
- }
- if (!g_boot_arg->ddr_reserve_success) {
- voprintf_debug("DDR reserve mode failed\n");
- mrdump_status_none("DDR reserve mode failed\n");
- goto error;
- }
- if (mrdump_cb->enabled != MRDUMP_ENABLE_COOKIE) {
- voprintf_debug("Runtime disabled %x\n", mrdump_cb->enabled);
- mrdump_status_none("Runtime disabled\n");
- goto error;
- }
- voprintf_debug("sram record with mode %d\n", reboot_mode);
- switch (reboot_mode) {
- case AEE_REBOOT_MODE_GZ_WDT:
- case AEE_REBOOT_MODE_WDT: {
- goto end;
- }
- case AEE_REBOOT_MODE_NORMAL: {
- /* MRDUMP_KEY reboot*/
- if (ram_console_reboot_by_mrdump_key && ram_console_reboot_by_mrdump_key()) {
- mrdump_cb->crash_record.reboot_mode = AEE_REBOOT_MODE_MRDUMP_KEY;
- mrdump_status_none("set reboot_mode to MRDUMP_KEY\n");
- goto end;
- } else
- return 0;
- }
- case AEE_REBOOT_MODE_KERNEL_OOPS:
- case AEE_REBOOT_MODE_KERNEL_PANIC:
- case AEE_REBOOT_MODE_NESTED_EXCEPTION:
- case AEE_REBOOT_MODE_EXCEPTION_KDUMP:
- case AEE_REBOOT_MODE_MRDUMP_KEY:
- case AEE_REBOOT_MODE_GZ_KE:
- case AEE_REBOOT_MODE_HANG_DETECT:
- goto end;
- }
- voprintf_debug("Unsupport exception type\n");
- mrdump_status_none("Unsupport exception type\n");
- error:
- mrdump_write_result();
- return 0;
- end:
- if (output_device == MRDUMP_DEV_USB) {
- g_boot_mode = FASTBOOT;
- if (mrdump_set_env("mrdump_output", "usb")) {
- dprintf(CRITICAL, "%s: default usb dump\n",__func__);
- }
- else {
- dprintf(CRITICAL, "%s: fail to set default usb mrdump\n", __func__);
- }
- }
- return 1;
- }
- void mrdump_reboot(void)
- {
- #ifdef MTK_PMIC_FULL_RESET
- voprintf_debug("Ready for full pmic reset\n");
- mrdump_write_result();
- mtk_arch_full_reset();
- #else
- voprintf_debug("Ready for reset\n");
- mrdump_write_result();
- mtk_arch_reset(1);
- #endif
- }
- int mrdump_run2(void)
- {
- if (mrdump_cb != NULL) {
- kdump_ui(mrdump_cb);
- if (output_device != MRDUMP_DEV_USB) {
- mrdump_reboot();
- }
- mrdump_write_result();
- return 1;
- }
- return 0;
- }
- void aee_timer_init(struct aee_timer *t)
- {
- memset(t, 0, sizeof(struct aee_timer));
- }
- void aee_timer_start(struct aee_timer *t)
- {
- t->start_ms = get_timer_masked();
- }
- void aee_timer_stop(struct aee_timer *t)
- {
- t->acc_ms += (get_timer_masked() - t->start_ms);
- t->start_ms = 0;
- }
- #ifdef MTK_3LEVEL_PAGETABLE
- vaddr_t scratch_addr(void)
- {
- return (vaddr_t)target_get_scratch_address();
- }
- #endif
|