helpers.cc revision 13893
15703SN/A/*
25703SN/A * Copyright (c) 2016 ARM Limited
35703SN/A * All rights reserved
49988Snilay@cs.wisc.edu *
58825Snilay@cs.wisc.edu * The license below extends only to copyright in the software and shall
69988Snilay@cs.wisc.edu * not be construed as granting a license to any other intellectual
77935SN/A * property including but not limited to intellectual property relating
87935SN/A * to a hardware implementation of the functionality of the software
97935SN/A * licensed hereunder.  You may use the software subject to the license
105703SN/A * terms below provided that you ensure that this notice is replicated
115703SN/A * unmodified and in its entirety in all distributions of the software,
125703SN/A * modified or unmodified, in source code or in binary form.
139885Sstever@gmail.com *
145703SN/A * Redistribution and use in source and binary forms, with or without
155703SN/A * modification, are permitted provided that the following conditions are
169885Sstever@gmail.com * met: redistributions of source code must retain the above copyright
179885Sstever@gmail.com * notice, this list of conditions and the following disclaimer;
1810242Ssteve.reinhardt@amd.com * redistributions in binary form must reproduce the above copyright
199988Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer in the
205703SN/A * documentation and/or other materials provided with the distribution;
2110242Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its
227670SN/A * contributors may be used to endorse or promote products derived from
2310242Ssteve.reinhardt@amd.com * this software without specific prior written permission.
245703SN/A *
259449SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
268464SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
278721SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810242Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910242Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
305703SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
315703SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
325703SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
337935SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
347935SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
357935SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
367935SN/A *
377935SN/A * Authors: Andreas Sandberg
387935SN/A */
397935SN/A
408983Snate@binkert.org#include "kern/linux/helpers.hh"
415703SN/A
425703SN/A#include "arch/isa_traits.hh"
435703SN/A#include "config/the_isa.hh"
449885Sstever@gmail.com#include "cpu/thread_context.hh"
455703SN/A#include "mem/fs_translating_port_proxy.hh"
469988Snilay@cs.wisc.edu#include "sim/byteswap.hh"
478721SN/A#include "sim/system.hh"
488721SN/A
498721SN/Astruct DmesgEntry {
508983Snate@binkert.org    uint64_t ts_nsec;
518983Snate@binkert.org    uint16_t len;
525703SN/A    uint16_t text_len;
539885Sstever@gmail.com    uint16_t dict_len;
549885Sstever@gmail.com    uint8_t facility;
559885Sstever@gmail.com    uint8_t flags;
569988Snilay@cs.wisc.edu} M5_ATTR_PACKED;
579885Sstever@gmail.com
589885Sstever@gmail.comstatic int
595703SN/AdumpDmesgEntry(const uint8_t *base, const uint8_t *end, std::ostream &os)
605703SN/A{
619481Snilay@cs.wisc.edu    const size_t max_length = end - base;
625703SN/A    DmesgEntry de;
635703SN/A
648241SN/A    if (max_length < sizeof(de)) {
658241SN/A        warn("Malformed dmesg entry\n");
665703SN/A        return -1;
675703SN/A    }
685703SN/A
695703SN/A    memcpy(&de, base, sizeof(de));
709481Snilay@cs.wisc.edu    de.ts_nsec = TheISA::gtoh(de.ts_nsec);
715703SN/A    de.len = TheISA::gtoh(de.len);
725876SN/A    de.text_len = TheISA::gtoh(de.text_len);
739885Sstever@gmail.com
745703SN/A    if (de.len < sizeof(de) ||
755703SN/A        max_length < de.len ||
765703SN/A        max_length < sizeof(DmesgEntry) + de.text_len) {
775703SN/A
785703SN/A        warn("Malformed dmesg entry:\n");
795703SN/A        warn("\tMax length: %i\n", max_length);
805703SN/A        warn("\tde.len: %i\n", de.len);
815703SN/A        warn("\tde.text_len: %i\n", de.text_len);
825703SN/A        return -1;
835703SN/A    }
845703SN/A
855703SN/A    ccprintf(os, "[%.6f] ", de.ts_nsec * 10e-9);
865703SN/A    os.write((char *)base + sizeof(de), de.text_len);
875703SN/A    os << std::endl;
889988Snilay@cs.wisc.edu
899988Snilay@cs.wisc.edu    return de.len;
905703SN/A}
915703SN/A
925703SN/Avoid
935703SN/ALinux::dumpDmesg(ThreadContext *tc, std::ostream &os)
945703SN/A{
955703SN/A    System *system = tc->getSystemPtr();
965703SN/A    const SymbolTable *symtab = system->kernelSymtab;
975703SN/A    FSTranslatingPortProxy proxy(tc);
985703SN/A
995703SN/A    Addr addr_lb = 0, addr_lb_len = 0, addr_first = 0, addr_next = 0;
1005703SN/A    const bool found_symbols =
1015703SN/A        symtab->findAddress("__log_buf", addr_lb) &&
1029348SAli.Saidi@ARM.com        symtab->findAddress("log_buf_len", addr_lb_len) &&
1035703SN/A        symtab->findAddress("log_first_idx", addr_first) &&
1045703SN/A        symtab->findAddress("log_next_idx", addr_next);
1055703SN/A
1065703SN/A    if (!found_symbols) {
1075703SN/A        warn("Failed to find kernel dmesg symbols.\n");
1085703SN/A        return;
1095703SN/A    }
1108825Snilay@cs.wisc.edu
1115703SN/A    uint32_t log_buf_len =
1129924Ssteve.reinhardt@amd.com        proxy.read<uint32_t>(addr_lb_len, TheISA::GuestByteOrder);
1135703SN/A    uint32_t log_first_idx =
1145703SN/A        proxy.read<uint32_t>(addr_first, TheISA::GuestByteOrder);
1155703SN/A    uint32_t log_next_idx =
1165703SN/A        proxy.read<uint32_t>(addr_next, TheISA::GuestByteOrder);
1175703SN/A
1185703SN/A    if (log_first_idx >= log_buf_len || log_next_idx >= log_buf_len) {
1195703SN/A        warn("dmesg pointers/length corrupted\n");
1205703SN/A        return;
1215703SN/A    }
1225703SN/A
1235703SN/A    // Normalize and read the dmesg ring buffer
1245703SN/A    std::vector<uint8_t> log_buf(log_buf_len);
1259661SAli.Saidi@ARM.com    int length;
1265703SN/A    if (log_first_idx < log_next_idx) {
1275703SN/A        length = log_next_idx - log_first_idx;
1285703SN/A        if (length < 0 || length > log_buf.size()) {
1295703SN/A            warn("Unexpected dmesg buffer length\n");
1305703SN/A            return;
1315703SN/A        }
1325703SN/A        proxy.readBlob(addr_lb + log_first_idx, log_buf.data(), length);
1335703SN/A    } else {
1345703SN/A        const int length_2 = log_buf_len - log_first_idx;
13510242Ssteve.reinhardt@amd.com        if (length_2 < 0 || length_2 + log_next_idx > log_buf.size()) {
1365703SN/A            warn("Unexpected dmesg buffer length\n");
1378521SN/A            return;
1389449SAli.Saidi@ARM.com        }
1395703SN/A        length = log_buf_len;
1405703SN/A        proxy.readBlob(addr_lb + log_first_idx, log_buf.data(), length_2);
1415703SN/A        proxy.readBlob(addr_lb, log_buf.data() + length_2, log_next_idx);
1425703SN/A    }
1435703SN/A
1448825Snilay@cs.wisc.edu    // Print dmesg buffer content
1455703SN/A    const uint8_t *cur = log_buf.data(), *end = log_buf.data() + length;
1465703SN/A    while (cur < end) {
1475703SN/A        int ret = dumpDmesgEntry(cur, end, os);
1489481Snilay@cs.wisc.edu        if (ret < 0)
1499481Snilay@cs.wisc.edu            return;
1509481Snilay@cs.wisc.edu        cur += ret;
1519481Snilay@cs.wisc.edu    }
1529481Snilay@cs.wisc.edu}
1539481Snilay@cs.wisc.edu