From 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 10 May 2024 07:44:59 +0000 Subject: [PATCH] gmac get mac form eeprom --- kernel/fs/pstore/ram.c | 539 +++++++++++++++++++++++++++++++++++------------------------ 1 files changed, 322 insertions(+), 217 deletions(-) diff --git a/kernel/fs/pstore/ram.c b/kernel/fs/pstore/ram.c index 86b61bd..4db798d 100644 --- a/kernel/fs/pstore/ram.c +++ b/kernel/fs/pstore/ram.c @@ -1,23 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * RAM Oops/Panic logger * * Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com> * Copyright (C) 2011 Kees Cook <keescook@chromium.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -35,6 +21,12 @@ #include <linux/pstore_ram.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_reserved_mem.h> +#include "internal.h" + +#if IS_REACHABLE(CONFIG_ROCKCHIP_MINIDUMP) +#include <soc/rockchip/rk_minidump.h> +#endif #define RAMOOPS_KERNMSG_HDR "====" #define MIN_MEM_SIZE 4096UL @@ -67,24 +59,63 @@ "size of reserved RAM used to store oops/panic logs"); static unsigned int mem_type; -module_param(mem_type, uint, 0600); +module_param(mem_type, uint, 0400); MODULE_PARM_DESC(mem_type, - "set to 1 to try to use unbuffered memory (default 0)"); + "memory type: 0=write-combined (default), 1=unbuffered, 2=cached"); -static int dump_oops = 1; -module_param(dump_oops, int, 0600); -MODULE_PARM_DESC(dump_oops, - "set to 1 to dump oopses, 0 to only dump panics (default 1)"); +static int ramoops_max_reason = -1; +module_param_named(max_reason, ramoops_max_reason, int, 0400); +MODULE_PARM_DESC(max_reason, + "maximum reason for kmsg dump (default 2: Oops and Panic) "); static int ramoops_ecc; -module_param_named(ecc, ramoops_ecc, int, 0600); +module_param_named(ecc, ramoops_ecc, int, 0400); MODULE_PARM_DESC(ramoops_ecc, "if non-zero, the option enables ECC support and specifies " "ECC buffer size in bytes (1 is a special value, means 16 " "bytes ECC)"); +static int ramoops_dump_oops = -1; +module_param_named(dump_oops, ramoops_dump_oops, int, 0400); +MODULE_PARM_DESC(dump_oops, + "(deprecated: use max_reason instead) set to 1 to dump oopses & panics, 0 to only dump panics"); + +struct ramoops_context { + struct persistent_ram_zone **dprzs; /* Oops dump zones */ + struct persistent_ram_zone *cprz; /* Console zone */ + struct persistent_ram_zone **fprzs; /* Ftrace zones */ + struct persistent_ram_zone *mprz; /* PMSG zone */ +#ifdef CONFIG_PSTORE_BOOT_LOG + struct persistent_ram_zone **boot_przs; /* BOOT log zones */ +#endif + phys_addr_t phys_addr; + unsigned long size; + unsigned int memtype; + size_t record_size; + size_t console_size; + size_t ftrace_size; + size_t pmsg_size; +#ifdef CONFIG_PSTORE_BOOT_LOG + size_t boot_log_size; +#endif + u32 flags; + struct persistent_ram_ecc_info ecc_info; + unsigned int max_dump_cnt; + unsigned int dump_write_cnt; + /* _read_cnt need clear on ramoops_pstore_open */ + unsigned int dump_read_cnt; + unsigned int console_read_cnt; + unsigned int max_ftrace_cnt; + unsigned int ftrace_read_cnt; + unsigned int pmsg_read_cnt; +#ifdef CONFIG_PSTORE_BOOT_LOG + unsigned int boot_log_read_cnt; + unsigned int max_boot_log_cnt; +#endif + struct pstore_info pstore; +}; + static struct platform_device *dummy; -static struct ramoops_platform_data *dummy_data; static int ramoops_pstore_open(struct pstore_info *psi) { @@ -98,31 +129,28 @@ } static struct persistent_ram_zone * -ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max, - u64 *id, - enum pstore_type_id *typep, enum pstore_type_id type, - bool update) +ramoops_get_next_prz(struct persistent_ram_zone *przs[], int id, + struct pstore_record *record) { struct persistent_ram_zone *prz; - int i = (*c)++; /* Give up if we never existed or have hit the end. */ - if (!przs || i >= max) + if (!przs) return NULL; - prz = przs[i]; + prz = przs[id]; if (!prz) return NULL; /* Update old/shadowed buffer. */ - if (update) + if (prz->type == PSTORE_TYPE_DMESG) persistent_ram_save_old(prz); if (!persistent_ram_old_size(prz)) return NULL; - *typep = type; - *id = i; + record->type = prz->type; + record->id = id; return prz; } @@ -160,57 +188,27 @@ persistent_ram_ecc_string(prz, NULL, 0)); } -static ssize_t ftrace_log_combine(struct persistent_ram_zone *dest, - struct persistent_ram_zone *src) +#ifdef CONFIG_PSTORE_BOOT_LOG +ssize_t ramoops_pstore_read_for_boot_log(struct pstore_record *record) { - size_t dest_size, src_size, total, dest_off, src_off; - size_t dest_idx = 0, src_idx = 0, merged_idx = 0; - void *merged_buf; - struct pstore_ftrace_record *drec, *srec, *mrec; - size_t record_size = sizeof(struct pstore_ftrace_record); + struct ramoops_context *cxt = record->psi->data; + struct persistent_ram_zone *prz; - dest_off = dest->old_log_size % record_size; - dest_size = dest->old_log_size - dest_off; + if (!cxt) + return 0; - src_off = src->old_log_size % record_size; - src_size = src->old_log_size - src_off; + prz = cxt->boot_przs[record->id]; - total = dest_size + src_size; - merged_buf = kmalloc(total, GFP_KERNEL); - if (!merged_buf) - return -ENOMEM; + if (!prz) + return 0; - drec = (struct pstore_ftrace_record *)(dest->old_log + dest_off); - srec = (struct pstore_ftrace_record *)(src->old_log + src_off); - mrec = (struct pstore_ftrace_record *)(merged_buf); - - while (dest_size > 0 && src_size > 0) { - if (pstore_ftrace_read_timestamp(&drec[dest_idx]) < - pstore_ftrace_read_timestamp(&srec[src_idx])) { - mrec[merged_idx++] = drec[dest_idx++]; - dest_size -= record_size; - } else { - mrec[merged_idx++] = srec[src_idx++]; - src_size -= record_size; - } - } - - while (dest_size > 0) { - mrec[merged_idx++] = drec[dest_idx++]; - dest_size -= record_size; - } - - while (src_size > 0) { - mrec[merged_idx++] = srec[src_idx++]; - src_size -= record_size; - } - - kfree(dest->old_log); - dest->old_log = merged_buf; - dest->old_log_size = total; - - return 0; + persistent_ram_free_old(prz); + persistent_ram_save_old(prz); + record->buf = prz->old_log; + record->size = prz->old_log_size; + return record->size; } +#endif static ssize_t ramoops_pstore_read(struct pstore_record *record) { @@ -231,10 +229,8 @@ /* Find the next valid persistent_ram_zone for DMESG */ while (cxt->dump_read_cnt < cxt->max_dump_cnt && !prz) { - prz = ramoops_get_next_prz(cxt->dprzs, &cxt->dump_read_cnt, - cxt->max_dump_cnt, &record->id, - &record->type, - PSTORE_TYPE_DMESG, 1); + prz = ramoops_get_next_prz(cxt->dprzs, cxt->dump_read_cnt++, + record); if (!prz_ok(prz)) continue; header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), @@ -248,22 +244,18 @@ } } - if (!prz_ok(prz)) - prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt, - 1, &record->id, &record->type, - PSTORE_TYPE_CONSOLE, 0); + if (!prz_ok(prz) && !cxt->console_read_cnt++) + prz = ramoops_get_next_prz(&cxt->cprz, 0 /* single */, record); - if (!prz_ok(prz)) - prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt, - 1, &record->id, &record->type, - PSTORE_TYPE_PMSG, 0); + if (!prz_ok(prz) && !cxt->pmsg_read_cnt++) + prz = ramoops_get_next_prz(&cxt->mprz, 0 /* single */, record); /* ftrace is last since it may want to dynamically allocate memory. */ if (!prz_ok(prz)) { - if (!(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)) { - prz = ramoops_get_next_prz(cxt->fprzs, - &cxt->ftrace_read_cnt, 1, &record->id, - &record->type, PSTORE_TYPE_FTRACE, 0); + if (!(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU) && + !cxt->ftrace_read_cnt++) { + prz = ramoops_get_next_prz(cxt->fprzs, 0 /* single */, + record); } else { /* * Build a new dummy record which combines all the @@ -280,11 +272,7 @@ while (cxt->ftrace_read_cnt < cxt->max_ftrace_cnt) { prz_next = ramoops_get_next_prz(cxt->fprzs, - &cxt->ftrace_read_cnt, - cxt->max_ftrace_cnt, - &record->id, - &record->type, - PSTORE_TYPE_FTRACE, 0); + cxt->ftrace_read_cnt++, record); if (!prz_ok(prz_next)) continue; @@ -293,7 +281,12 @@ tmp_prz->corrected_bytes += prz_next->corrected_bytes; tmp_prz->bad_blocks += prz_next->bad_blocks; - size = ftrace_log_combine(tmp_prz, prz_next); + + size = pstore_ftrace_combine_log( + &tmp_prz->old_log, + &tmp_prz->old_log_size, + prz_next->old_log, + prz_next->old_log_size); if (size) goto out; } @@ -301,13 +294,10 @@ } } -#ifdef CONFIG_PSTORE_MCU_LOG +#ifdef CONFIG_PSTORE_BOOT_LOG if (!prz_ok(prz)) { - while (cxt->mcu_log_read_cnt < cxt->max_mcu_log_cnt && !prz) { - prz = ramoops_get_next_prz(cxt->mcu_przs, &cxt->mcu_log_read_cnt, - cxt->max_mcu_log_cnt, &record->id, - &record->type, - PSTORE_TYPE_MCU_LOG, 0); + while (cxt->boot_log_read_cnt < cxt->max_boot_log_cnt && !prz) { + prz = ramoops_get_next_prz(cxt->boot_przs, cxt->boot_log_read_cnt++, record); if (!prz_ok(prz)) continue; } @@ -319,12 +309,15 @@ goto out; } - size = persistent_ram_old_size(prz) - header_length; -#ifdef CONFIG_PSTORE_MCU_LOG - /* don't copy mcu log */ - if (record->type == PSTORE_TYPE_MCU_LOG) - goto out; +#ifdef CONFIG_PSTORE_BOOT_LOG + if (record->type == PSTORE_TYPE_BOOT_LOG) { + persistent_ram_free_old(prz); + persistent_ram_save_old(prz); + } #endif + + size = persistent_ram_old_size(prz) - header_length; + /* ECC correction notice */ record->ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0); @@ -352,17 +345,15 @@ static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz, struct pstore_record *record) { - char *hdr; + char hdr[36]; /* "===="(4), %lld(20), "."(1), %06lu(6), "-%c\n"(3) */ size_t len; - hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lld.%06lu-%c\n", + len = scnprintf(hdr, sizeof(hdr), + RAMOOPS_KERNMSG_HDR "%lld.%06lu-%c\n", (time64_t)record->time.tv_sec, record->time.tv_nsec / 1000, record->compressed ? 'C' : 'D'); - WARN_ON_ONCE(!hdr); - len = hdr ? strlen(hdr) : 0; persistent_ram_write(prz, hdr, len); - kfree(hdr); return len; } @@ -403,16 +394,14 @@ return -EINVAL; /* - * Out of the various dmesg dump types, ramoops is currently designed - * to only store crash logs, rather than storing general kernel logs. + * We could filter on record->reason here if we wanted to (which + * would duplicate what happened before the "max_reason" setting + * was added), but that would defeat the purpose of a system + * changing printk.always_kmsg_dump, so instead log everything that + * the kmsg dumper sends us, since it should be doing the filtering + * based on the combination of printk.always_kmsg_dump and our + * requested "max_reason". */ - if (record->reason != KMSG_DUMP_OOPS && - record->reason != KMSG_DUMP_PANIC) - return -EINVAL; - - /* Skip Oopes when configured to do so. */ - if (record->reason == KMSG_DUMP_OOPS && !cxt->dump_oops) - return -EINVAL; /* * Explicitly only take the first part of any new crash. @@ -441,6 +430,9 @@ /* Build header and append record contents. */ hlen = ramoops_write_kmsg_hdr(prz, record); + if (!hlen) + return -ENOMEM; + size = record->size; if (size + hlen > prz->buffer_size) size = prz->buffer_size - hlen; @@ -529,13 +521,13 @@ kfree(cxt->fprzs); cxt->max_ftrace_cnt = 0; } -#ifdef CONFIG_PSTORE_MCU_LOG - /* Free mcu log PRZs */ - if (cxt->mcu_przs) { - for (i = 0; i < cxt->max_mcu_log_cnt; i++) - persistent_ram_free(cxt->mcu_przs[i]); - kfree(cxt->mcu_przs); - cxt->max_mcu_log_cnt = 0; +#ifdef CONFIG_PSTORE_BOOT_LOG + /* Free boot log PRZs */ + if (cxt->boot_przs) { + for (i = 0; i < cxt->max_boot_log_cnt; i++) + persistent_ram_free(cxt->boot_przs[i]); + kfree(cxt->boot_przs); + cxt->max_boot_log_cnt = 0; } #endif } @@ -600,9 +592,17 @@ goto fail; for (i = 0; i < *cnt; i++) { + char *label; + + if (*cnt == 1) + label = kasprintf(GFP_KERNEL, "ramoops:%s", name); + else + label = kasprintf(GFP_KERNEL, "ramoops:%s(%d/%d)", + name, i, *cnt - 1); prz_ar[i] = persistent_ram_new(*paddr, zone_sz, sig, - &cxt->ecc_info, - cxt->memtype, flags); + &cxt->ecc_info, + cxt->memtype, flags, label); + kfree(label); if (IS_ERR(prz_ar[i])) { err = PTR_ERR(prz_ar[i]); dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n", @@ -617,6 +617,7 @@ goto fail; } *paddr += zone_sz; + prz_ar[i]->type = pstore_name_to_type(name); } *przs = prz_ar; @@ -632,6 +633,8 @@ struct persistent_ram_zone **prz, phys_addr_t *paddr, size_t sz, u32 sig) { + char *label; + if (!sz) return 0; @@ -642,8 +645,10 @@ return -ENOMEM; } + label = kasprintf(GFP_KERNEL, "ramoops:%s", name); *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info, - cxt->memtype, 0); + cxt->memtype, PRZ_FLAG_ZAP_OLD, label); + kfree(label); if (IS_ERR(*prz)) { int err = PTR_ERR(*prz); @@ -652,26 +657,31 @@ return err; } - persistent_ram_zap(*prz); - *paddr += sz; + (*prz)->type = pstore_name_to_type(name); return 0; } -static int ramoops_parse_dt_size(struct platform_device *pdev, - const char *propname, u32 *value) +/* Read a u32 from a dt property and make sure it's safe for an int. */ +static int ramoops_parse_dt_u32(struct platform_device *pdev, + const char *propname, + u32 default_value, u32 *value) { u32 val32 = 0; int ret; ret = of_property_read_u32(pdev->dev.of_node, propname, &val32); - if (ret < 0 && ret != -EINVAL) { + if (ret == -EINVAL) { + /* field is missing, use default value. */ + val32 = default_value; + } else if (ret < 0) { dev_err(&pdev->dev, "failed to parse property %s: %d\n", propname, ret); return ret; } + /* Sanity check our results. */ if (val32 > INT_MAX) { dev_err(&pdev->dev, "%s %u > INT_MAX\n", propname, val32); return -EOVERFLOW; @@ -685,6 +695,8 @@ struct ramoops_platform_data *pdata) { struct device_node *of_node = pdev->dev.of_node; + struct device_node *parent_node; + struct reserved_mem *rmem; struct resource *res; u32 value; int ret; @@ -693,37 +705,124 @@ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { - dev_err(&pdev->dev, - "failed to locate DT /reserved-memory resource\n"); - return -EINVAL; + rmem = of_reserved_mem_lookup(of_node); + if (rmem) { + pdata->mem_size = rmem->size; + pdata->mem_address = rmem->base; + } else { + dev_err(&pdev->dev, + "failed to locate DT /reserved-memory resource\n"); + return -EINVAL; + } + } else { + pdata->mem_size = resource_size(res); + pdata->mem_address = res->start; } - pdata->mem_size = resource_size(res); - pdata->mem_address = res->start; + /* + * Setting "unbuffered" is deprecated and will be ignored if + * "mem_type" is also specified. + */ pdata->mem_type = of_property_read_bool(of_node, "unbuffered"); - pdata->dump_oops = !of_property_read_bool(of_node, "no-dump-oops"); + /* + * Setting "no-dump-oops" is deprecated and will be ignored if + * "max_reason" is also specified. + */ + if (of_property_read_bool(of_node, "no-dump-oops")) + pdata->max_reason = KMSG_DUMP_PANIC; + else + pdata->max_reason = KMSG_DUMP_OOPS; -#define parse_size(name, field) { \ - ret = ramoops_parse_dt_size(pdev, name, &value); \ +#define parse_u32(name, field, default_value) { \ + ret = ramoops_parse_dt_u32(pdev, name, default_value, \ + &value); \ if (ret < 0) \ return ret; \ field = value; \ } - parse_size("record-size", pdata->record_size); - parse_size("console-size", pdata->console_size); - parse_size("ftrace-size", pdata->ftrace_size); - parse_size("pmsg-size", pdata->pmsg_size); - parse_size("ecc-size", pdata->ecc_info.ecc_size); - parse_size("flags", pdata->flags); -#ifdef CONFIG_PSTORE_MCU_LOG - parse_size("mcu-log-size", pdata->mcu_log_size); - parse_size("mcu-log-count", pdata->max_mcu_log_cnt); + parse_u32("mem-type", pdata->mem_type, pdata->mem_type); + parse_u32("record-size", pdata->record_size, 0); + parse_u32("console-size", pdata->console_size, 0); + parse_u32("ftrace-size", pdata->ftrace_size, 0); + parse_u32("pmsg-size", pdata->pmsg_size, 0); + parse_u32("ecc-size", pdata->ecc_info.ecc_size, 0); + parse_u32("flags", pdata->flags, 0); + parse_u32("max-reason", pdata->max_reason, pdata->max_reason); +#ifdef CONFIG_PSTORE_BOOT_LOG + parse_u32("boot-log-size", pdata->boot_log_size, 0); + parse_u32("boot-log-count", pdata->max_boot_log_cnt, 0); #endif -#undef parse_size + +#undef parse_u32 + + /* + * Some old Chromebooks relied on the kernel setting the + * console_size and pmsg_size to the record size since that's + * what the downstream kernel did. These same Chromebooks had + * "ramoops" straight under the root node which isn't + * according to the current upstream bindings (though it was + * arguably acceptable under a prior version of the bindings). + * Let's make those old Chromebooks work by detecting that + * we're not a child of "reserved-memory" and mimicking the + * expected behavior. + */ + parent_node = of_get_parent(of_node); + if (!of_node_name_eq(parent_node, "reserved-memory") && + !pdata->console_size && !pdata->ftrace_size && + !pdata->pmsg_size && !pdata->ecc_info.ecc_size) { + pdata->console_size = pdata->record_size; + pdata->pmsg_size = pdata->record_size; + } + of_node_put(parent_node); return 0; } + +#if IS_REACHABLE(CONFIG_ROCKCHIP_MINIDUMP) +static void _ramoops_register_ram_zone_info_to_minidump(struct persistent_ram_zone *prz) +{ + struct md_region md_entry = {}; + + strscpy(md_entry.name, prz->label, sizeof(md_entry.name)); + + md_entry.virt_addr = (u64)prz->vaddr; + md_entry.phys_addr = prz->paddr; + md_entry.size = prz->size; + + if (rk_minidump_add_region(&md_entry) < 0) + pr_err("Failed to add %s in Minidump\n", prz->label); +} + +static void ramoops_register_ram_zone_info_to_minidump(struct ramoops_context *cxt) +{ + int i = 0; + struct persistent_ram_zone *prz = NULL; + +#ifdef CONFIG_PSTORE_BOOT_LOG + for (i = 0; i < cxt->max_boot_log_cnt; i++) { + prz = cxt->boot_przs[i]; + _ramoops_register_ram_zone_info_to_minidump(prz); + } +#endif + + for (i = 0; i < cxt->max_dump_cnt; i++) { + prz = cxt->dprzs[i]; + _ramoops_register_ram_zone_info_to_minidump(prz); + } + + for (i = 0; i < cxt->max_ftrace_cnt; i++) { + prz = cxt->fprzs[i]; + _ramoops_register_ram_zone_info_to_minidump(prz); + } + + prz = cxt->cprz; + _ramoops_register_ram_zone_info_to_minidump(prz); + + prz = cxt->mprz; + _ramoops_register_ram_zone_info_to_minidump(prz); +} +#endif static int ramoops_probe(struct platform_device *pdev) { @@ -736,15 +835,6 @@ int err = -EINVAL; int i = 0; - if (dev_of_node(dev) && !pdata) { - pdata = &pdata_local; - memset(pdata, 0, sizeof(*pdata)); - - err = ramoops_parse_dt(pdev, pdata); - if (err < 0) - goto fail_out; - } - /* * Only a single ramoops area allowed at a time, so fail extra * probes. @@ -754,15 +844,25 @@ goto fail_out; } + if (dev_of_node(dev) && !pdata) { + pdata = &pdata_local; + memset(pdata, 0, sizeof(*pdata)); + + err = ramoops_parse_dt(pdev, pdata); + if (err < 0) + goto fail_out; + } + /* Make sure we didn't get bogus platform data pointer. */ if (!pdata) { pr_err("NULL platform data\n"); + err = -EINVAL; goto fail_out; } -#ifdef CONFIG_PSTORE_MCU_LOG +#ifdef CONFIG_PSTORE_BOOT_LOG if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size && - !pdata->ftrace_size && !pdata->pmsg_size && !pdata->mcu_log_size)) { + !pdata->ftrace_size && !pdata->pmsg_size && !pdata->boot_log_size)) { pr_err("The memory size and the record/console size must be " "non-zero\n"); goto fail_out; @@ -772,6 +872,7 @@ !pdata->ftrace_size && !pdata->pmsg_size)) { pr_err("The memory size and the record/console size must be " "non-zero\n"); + err = -EINVAL; goto fail_out; } #endif @@ -794,23 +895,33 @@ cxt->console_size = pdata->console_size; cxt->ftrace_size = pdata->ftrace_size; cxt->pmsg_size = pdata->pmsg_size; - cxt->dump_oops = pdata->dump_oops; cxt->flags = pdata->flags; cxt->ecc_info = pdata->ecc_info; -#ifdef CONFIG_PSTORE_MCU_LOG - cxt->mcu_log_size = pdata->mcu_log_size; - cxt->max_mcu_log_cnt = pdata->max_mcu_log_cnt; +#ifdef CONFIG_PSTORE_BOOT_LOG + cxt->boot_log_size = pdata->boot_log_size; + cxt->max_boot_log_cnt = pdata->max_boot_log_cnt; #endif paddr = cxt->phys_addr; dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size - cxt->pmsg_size; -#ifdef CONFIG_PSTORE_MCU_LOG - dump_mem_sz -= cxt->mcu_log_size; +#ifdef CONFIG_PSTORE_BOOT_LOG + dump_mem_sz -= cxt->boot_log_size; #endif - err = ramoops_init_przs("dump", dev, cxt, &cxt->dprzs, &paddr, +#ifdef CONFIG_PSTORE_BOOT_LOG + err = ramoops_init_przs("boot-log", dev, cxt, &cxt->boot_przs, &paddr, + cxt->boot_log_size, -1, + &cxt->max_boot_log_cnt, 0, 0); + if (err) + goto fail_clear; + if (cxt->boot_log_size > 0) + for (i = 0; i < cxt->max_boot_log_cnt; i++) + pr_info("boot-log-%d\t0x%zx@%pa\n", i, cxt->boot_przs[i]->size, &cxt->boot_przs[i]->paddr); +#endif + + err = ramoops_init_przs("dmesg", dev, cxt, &cxt->dprzs, &paddr, dump_mem_sz, cxt->record_size, &cxt->max_dump_cnt, 0, 0); if (err) @@ -844,20 +955,8 @@ cxt->pmsg_size, 0); if (err) goto fail_init_mprz; - if (cxt->pmsg_size > 0) pr_info("pmsg\t0x%zx@%pa\n", cxt->mprz->size, &cxt->mprz->paddr); - -#ifdef CONFIG_PSTORE_MCU_LOG - err = ramoops_init_przs("mcu_log", dev, cxt, &cxt->mcu_przs, &paddr, - cxt->mcu_log_size, -1, - &cxt->max_mcu_log_cnt, 0, 0); - if (err) - goto fail_clear; - if (cxt->mcu_log_size > 0) - for (i = 0; i < cxt->max_mcu_log_cnt; i++) - pr_info("mcu-log-%d\t0x%zx@%pa\n", i, cxt->mcu_przs[i]->size, &cxt->mcu_przs[i]->paddr); -#endif cxt->pstore.data = cxt; /* @@ -867,17 +966,19 @@ * the single region size is how to check. */ cxt->pstore.flags = 0; - if (cxt->max_dump_cnt) + if (cxt->max_dump_cnt) { cxt->pstore.flags |= PSTORE_FLAGS_DMESG; + cxt->pstore.max_reason = pdata->max_reason; + } if (cxt->console_size) cxt->pstore.flags |= PSTORE_FLAGS_CONSOLE; if (cxt->max_ftrace_cnt) cxt->pstore.flags |= PSTORE_FLAGS_FTRACE; if (cxt->pmsg_size) cxt->pstore.flags |= PSTORE_FLAGS_PMSG; -#ifdef CONFIG_PSTORE_MCU_LOG - if (cxt->mcu_log_size) - cxt->pstore.flags |= PSTORE_FLAGS_MCU_LOG; +#ifdef CONFIG_PSTORE_BOOT_LOG + if (cxt->boot_log_size) + cxt->pstore.flags |= PSTORE_FLAGS_BOOT_LOG; #endif /* @@ -908,14 +1009,16 @@ mem_size = pdata->mem_size; mem_address = pdata->mem_address; record_size = pdata->record_size; - dump_oops = pdata->dump_oops; + ramoops_max_reason = pdata->max_reason; ramoops_console_size = pdata->console_size; ramoops_pmsg_size = pdata->pmsg_size; ramoops_ftrace_size = pdata->ftrace_size; - - pr_info("attached 0x%lx@0x%llx, ecc: %d/%d\n", +#if IS_REACHABLE(CONFIG_ROCKCHIP_MINIDUMP) + ramoops_register_ram_zone_info_to_minidump(cxt); +#endif + pr_info("using 0x%lx@0x%llx, ecc: %d\n", cxt->size, (unsigned long long)cxt->phys_addr, - cxt->ecc_info.ecc_size, cxt->ecc_info.block_size); + cxt->ecc_info.ecc_size); return 0; @@ -967,13 +1070,12 @@ { platform_device_unregister(dummy); dummy = NULL; - - kfree(dummy_data); - dummy_data = NULL; } static void __init ramoops_register_dummy(void) { + struct ramoops_platform_data pdata; + /* * Prepare a dummy platform data structure to carry the module * parameters. If mem_size isn't set, then there are no module @@ -984,35 +1086,38 @@ pr_info("using module parameters\n"); - dummy_data = kzalloc(sizeof(*dummy_data), GFP_KERNEL); - if (!dummy_data) { - pr_info("could not allocate pdata\n"); - return; - } - - dummy_data->mem_size = mem_size; - dummy_data->mem_address = mem_address; - dummy_data->mem_type = mem_type; - dummy_data->record_size = record_size; - dummy_data->console_size = ramoops_console_size; - dummy_data->ftrace_size = ramoops_ftrace_size; - dummy_data->pmsg_size = ramoops_pmsg_size; - dummy_data->dump_oops = dump_oops; - dummy_data->flags = RAMOOPS_FLAG_FTRACE_PER_CPU; + memset(&pdata, 0, sizeof(pdata)); + pdata.mem_size = mem_size; + pdata.mem_address = mem_address; + pdata.mem_type = mem_type; + pdata.record_size = record_size; + pdata.console_size = ramoops_console_size; + pdata.ftrace_size = ramoops_ftrace_size; + pdata.pmsg_size = ramoops_pmsg_size; + /* If "max_reason" is set, its value has priority over "dump_oops". */ + if (ramoops_max_reason >= 0) + pdata.max_reason = ramoops_max_reason; + /* Otherwise, if "dump_oops" is set, parse it into "max_reason". */ + else if (ramoops_dump_oops != -1) + pdata.max_reason = ramoops_dump_oops ? KMSG_DUMP_OOPS + : KMSG_DUMP_PANIC; + /* And if neither are explicitly set, use the default. */ + else + pdata.max_reason = KMSG_DUMP_OOPS; + pdata.flags = RAMOOPS_FLAG_FTRACE_PER_CPU; /* * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC * (using 1 byte for ECC isn't much of use anyway). */ - dummy_data->ecc_info.ecc_size = ramoops_ecc == 1 ? 16 : ramoops_ecc; + pdata.ecc_info.ecc_size = ramoops_ecc == 1 ? 16 : ramoops_ecc; dummy = platform_device_register_data(NULL, "ramoops", -1, - dummy_data, sizeof(struct ramoops_platform_data)); + &pdata, sizeof(pdata)); if (IS_ERR(dummy)) { pr_info("could not create platform device: %ld\n", PTR_ERR(dummy)); dummy = NULL; - ramoops_unregister_dummy(); } } -- Gitblit v1.6.2