[Midnightbsd-cvs] src [11120] trunk/sbin/mca: add mca

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Tue Jun 19 15:32:07 EDT 2018


Revision: 11120
          http://svnweb.midnightbsd.org/src/?rev=11120
Author:   laffer1
Date:     2018-06-19 15:32:07 -0400 (Tue, 19 Jun 2018)
Log Message:
-----------
add mca

Added Paths:
-----------
    trunk/sbin/mca/
    trunk/sbin/mca/Makefile
    trunk/sbin/mca/mca.8
    trunk/sbin/mca/mca.c

Added: trunk/sbin/mca/Makefile
===================================================================
--- trunk/sbin/mca/Makefile	                        (rev 0)
+++ trunk/sbin/mca/Makefile	2018-06-19 19:32:07 UTC (rev 11120)
@@ -0,0 +1,6 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/sbin/mca/Makefile 236355 2012-05-31 08:22:02Z eadler $
+PROG=	mca
+MAN=	mca.8
+
+.include <bsd.prog.mk>


Property changes on: trunk/sbin/mca/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sbin/mca/mca.8
===================================================================
--- trunk/sbin/mca/mca.8	                        (rev 0)
+++ trunk/sbin/mca/mca.8	2018-06-19 19:32:07 UTC (rev 11120)
@@ -0,0 +1,74 @@
+.\" $MidnightBSD$
+.\" Copyright (c) 2006 Marcel Moolenaar
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD: stable/10/sbin/mca/mca.8 162844 2006-09-30 11:12:36Z ru $
+.\"
+.Dd February 11, 2006
+.Dt MCA 8
+.Os
+.Sh NAME
+.Nm mca
+.Nd "Machine Check Architecture control utility"
+.Sh SYNOPSIS
+.Nm
+.Op Fl d
+.Op Fl f Ar filename
+.Sh DESCRIPTION
+The
+.Nm
+utility provides minimal functionality to dump or display MCA records
+that were saved by the kernel during boot.
+The default behaviour of the
+.Nm
+utility is to display all new MCA records on stdout.
+When the
+.Fl d
+option is given, the records are dumped in binary form.
+The default file to which records are dumped is
+.Pa /var/log/mca.log .
+This can be changed by specifying the
+.Fl f
+option.
+New records are appended to the dump file.
+.Pp
+Previously dumped records can be displayed by giving the name of
+the dump file with the
+.Fl f
+option.
+.Sh FILES
+.Bl -tag -width ".Pa /var/log/mca.log" -compact
+.It Pa /var/log/mca.log
+default dump file
+.El
+.Sh HISTORY
+The
+.Nm
+utility appeared in
+.Fx 5.0
+for ia64.
+.Sh BUGS
+The development of the
+.Nm
+utility is still a work in progress.


Property changes on: trunk/sbin/mca/mca.8
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sbin/mca/mca.c
===================================================================
--- trunk/sbin/mca/mca.c	                        (rev 0)
+++ trunk/sbin/mca/mca.c	2018-06-19 19:32:07 UTC (rev 11120)
@@ -0,0 +1,548 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2002 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sbin/mca/mca.c 236355 2012-05-31 08:22:02Z eadler $");
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/sysctl.h>
+#include <sys/uuid.h>
+
+/*
+ * Hack to make this compile on non-ia64 machines.
+ */
+#ifdef __ia64__
+#include <machine/mca.h>
+#else
+#include "../../sys/ia64/include/mca.h"
+#endif
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <uuid.h>
+
+#define	BCD(x)	((x >> 4) * 10 + (x & 15))
+
+#define	HW_MCA_MAX_CPUID	255
+
+static const char hw_mca_count[] = "hw.mca.count";
+static const char hw_mca_first[] = "hw.mca.first";
+static const char hw_mca_last[] = "hw.mca.last";
+static const char hw_mca_recid[] = "hw.mca.%d.%u";
+
+static char default_dumpfile[] = "/var/log/mca.log";
+
+int fl_dump;
+char *file;
+
+static const char *
+severity(int error)
+{
+
+	switch (error) {
+	case MCA_RH_ERROR_RECOVERABLE:
+		return ("recoverable");
+	case MCA_RH_ERROR_FATAL:
+		return ("fatal");
+	case MCA_RH_ERROR_CORRECTED:
+		return ("corrected");
+	}
+
+	return ("unknown");
+}
+
+static const char *
+uuid(uuid_t *id)
+{
+	static char buffer[64];
+	char *s;
+
+	uuid_to_string(id, &s, NULL);
+	strcpy(buffer, s);
+	free(s);
+	return (buffer);
+}
+
+static int
+show_value(int indent, const char *var, const char *fmt, ...)
+{
+	va_list ap;
+	int len;
+
+	len = indent;
+	while (indent--)
+		putchar(' ');
+	len += printf("<%s>", var);
+	va_start(ap, fmt);
+	len += vprintf(fmt, ap);
+	len += printf("</%s>\n", var);
+	return (len);
+}
+
+static size_t
+show_header(struct mca_record_header *rh)
+{
+
+	printf("  <header>\n");
+	show_value(4, "seqnr", "%lld", (long long)rh->rh_seqnr);
+	show_value(4, "revision", "%d.%d", BCD(rh->rh_major),
+	    BCD(rh->rh_minor));
+	show_value(4, "severity", "%s", severity(rh->rh_error));
+	show_value(4, "length", "%lld", (long long)rh->rh_length);
+	show_value(4, "date", "%d%02d/%02d/%02d",
+	    BCD(rh->rh_time[MCA_RH_TIME_CENT]),
+	    BCD(rh->rh_time[MCA_RH_TIME_YEAR]),
+	    BCD(rh->rh_time[MCA_RH_TIME_MON]),
+	    BCD(rh->rh_time[MCA_RH_TIME_MDAY]));
+	show_value(4, "time", "%02d:%02d:%02d",
+	    BCD(rh->rh_time[MCA_RH_TIME_HOUR]),
+	    BCD(rh->rh_time[MCA_RH_TIME_MIN]),
+	    BCD(rh->rh_time[MCA_RH_TIME_SEC]));
+	if (rh->rh_flags & MCA_RH_FLAGS_PLATFORM_ID)
+		show_value(4, "platform", "%s", uuid(&rh->rh_platform));
+	printf("  </header>\n");
+	return (rh->rh_length);
+}
+
+static void
+show_cpu_mod(const char *what, int idx, struct mca_cpu_mod *cpu_mod)
+{
+	printf("      <%s-%d>\n", what, idx);
+	if (cpu_mod->cpu_mod_flags & MCA_CPU_MOD_FLAGS_INFO)
+		show_value(8, "info", "0x%016llx",
+		    (long long)cpu_mod->cpu_mod_info);
+	if (cpu_mod->cpu_mod_flags & MCA_CPU_MOD_FLAGS_REQID)
+		show_value(8, "requester", "0x%016llx",
+		    (long long)cpu_mod->cpu_mod_reqid);
+	if (cpu_mod->cpu_mod_flags & MCA_CPU_MOD_FLAGS_RSPID)
+		show_value(8, "responder", "0x%016llx",
+		    (long long)cpu_mod->cpu_mod_rspid);
+	if (cpu_mod->cpu_mod_flags & MCA_CPU_MOD_FLAGS_TGTID)
+		show_value(8, "target", "0x%016llx",
+		    (long long)cpu_mod->cpu_mod_tgtid);
+	if (cpu_mod->cpu_mod_flags & MCA_CPU_MOD_FLAGS_IP)
+		show_value(8, "ip", "0x%016llx",
+		    (long long)cpu_mod->cpu_mod_ip);
+	printf("      </%s-%d>\n", what, idx);
+}
+
+static void
+show_cpu(struct mca_cpu_record *cpu)
+{
+	char var[16];
+	struct mca_cpu_mod *mod;
+	struct mca_cpu_cpuid *cpuid;
+#ifdef notyet
+	struct mca_cpu_psi *psi;
+#endif
+	int i, n;
+
+	printf("    <cpu>\n");
+
+	if (cpu->cpu_flags & MCA_CPU_FLAGS_ERRMAP)
+		show_value(6, "errmap", "0x%016llx",
+		    (long long)cpu->cpu_errmap);
+	if (cpu->cpu_flags & MCA_CPU_FLAGS_STATE)
+		show_value(6, "state", "0x%016llx",
+		    (long long)cpu->cpu_state);
+	if (cpu->cpu_flags & MCA_CPU_FLAGS_CR_LID)
+		show_value(6, "cr_lid", "0x%016llx",
+		    (long long)cpu->cpu_cr_lid);
+
+	mod = (struct mca_cpu_mod*)(cpu + 1);
+	n = MCA_CPU_FLAGS_CACHE(cpu->cpu_flags);
+	for (i = 0; i < n; i++)
+		show_cpu_mod("cache", i, mod++);
+	n = MCA_CPU_FLAGS_TLB(cpu->cpu_flags);
+	for (i = 0; i < n; i++)
+		show_cpu_mod("tlb", i, mod++);
+	n = MCA_CPU_FLAGS_BUS(cpu->cpu_flags);
+	for (i = 0; i < n; i++)
+		show_cpu_mod("bus", i, mod++);
+	n = MCA_CPU_FLAGS_REG(cpu->cpu_flags);
+	for (i = 0; i < n; i++)
+		show_cpu_mod("reg", i, mod++);
+	n = MCA_CPU_FLAGS_MS(cpu->cpu_flags);
+	for (i = 0; i < n; i++)
+		show_cpu_mod("ms", i, mod++);
+
+	cpuid = (struct mca_cpu_cpuid*)mod;
+	for (i = 0; i < 6; i++) {
+		sprintf(var, "cpuid-%d", i);
+		show_value(6, var, "0x%016llx", (long long)cpuid->cpuid[i]);
+	}
+
+#ifdef notyet
+	 psi = (struct mca_cpu_psi*)(cpuid + 1);
+#endif
+	 /* TODO: Dump PSI */
+
+	printf("    </cpu>\n");
+}
+
+static void
+show_memory(struct mca_mem_record *mem)
+{
+	printf("    <memory>\n");
+
+	if (mem->mem_flags & MCA_MEM_FLAGS_STATUS)
+		show_value(6, "status", "0x%016llx",
+		    (long long)mem->mem_status);
+	if (mem->mem_flags & MCA_MEM_FLAGS_ADDR)
+		show_value(6, "address", "0x%016llx",
+		    (long long)mem->mem_addr);
+	if (mem->mem_flags & MCA_MEM_FLAGS_ADDRMASK)
+		show_value(6, "mask", "0x%016llx",
+		    (long long)mem->mem_addrmask);
+	if (mem->mem_flags & MCA_MEM_FLAGS_NODE)
+		show_value(6, "node", "0x%04x", mem->mem_node);
+	if (mem->mem_flags & MCA_MEM_FLAGS_CARD)
+		show_value(6, "card", "0x%04x", mem->mem_card);
+	if (mem->mem_flags & MCA_MEM_FLAGS_MODULE)
+		show_value(6, "module", "0x%04x", mem->mem_module);
+	if (mem->mem_flags & MCA_MEM_FLAGS_BANK)
+		show_value(6, "bank", "0x%04x", mem->mem_bank);
+	if (mem->mem_flags & MCA_MEM_FLAGS_DEVICE)
+		show_value(6, "device", "0x%04x", mem->mem_device);
+	if (mem->mem_flags & MCA_MEM_FLAGS_ROW)
+		show_value(6, "row", "0x%04x", mem->mem_row);
+	if (mem->mem_flags & MCA_MEM_FLAGS_COLUMN)
+		show_value(6, "column", "0x%04x", mem->mem_column);
+	if (mem->mem_flags & MCA_MEM_FLAGS_BITPOS)
+		show_value(6, "bit", "0x%04x", mem->mem_bitpos);
+	if (mem->mem_flags & MCA_MEM_FLAGS_REQID)
+		show_value(6, "requester", "0x%016llx",
+		    (long long)mem->mem_reqid);
+	if (mem->mem_flags & MCA_MEM_FLAGS_RSPID)
+		show_value(6, "responder", "0x%016llx",
+		    (long long)mem->mem_rspid);
+	if (mem->mem_flags & MCA_MEM_FLAGS_TGTID)
+		show_value(6, "target", "0x%016llx",
+		    (long long)mem->mem_tgtid);
+	if (mem->mem_flags & MCA_MEM_FLAGS_BUSDATA)
+		show_value(6, "status", "0x%016llx",
+		    (long long)mem->mem_busdata);
+	if (mem->mem_flags & MCA_MEM_FLAGS_OEM_ID)
+		show_value(6, "oem", "%s", uuid(&mem->mem_oem_id));
+	/* TODO: Dump OEM data */
+
+	printf("    </memory>\n");
+}
+
+static void
+show_sel(void)
+{
+	printf("    # SEL\n");
+}
+
+static void
+show_pci_bus(struct mca_pcibus_record *pcibus)
+{
+	printf("    <pci-bus>\n");
+
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_STATUS)
+		show_value(6, "status", "0x%016llx",
+		    (long long)pcibus->pcibus_status);
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_ERROR)
+		show_value(6, "error", "0x%04x", pcibus->pcibus_error);
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_BUS)
+		show_value(6, "bus", "0x%04x", pcibus->pcibus_bus);
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_ADDR)
+		show_value(6, "address", "0x%016llx",
+		    (long long)pcibus->pcibus_addr);
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_DATA)
+		show_value(6, "data", "0x%016llx",
+		    (long long)pcibus->pcibus_data);
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_CMD)
+		show_value(6, "cmd", "0x%016llx",
+		    (long long)pcibus->pcibus_cmd);
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_REQID)
+		show_value(6, "requester", "0x%016llx",
+		    (long long)pcibus->pcibus_reqid);
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_RSPID)
+		show_value(6, "responder", "0x%016llx",
+		    (long long)pcibus->pcibus_rspid);
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_TGTID)
+		show_value(6, "target", "0x%016llx",
+		    (long long)pcibus->pcibus_tgtid);
+	if (pcibus->pcibus_flags & MCA_PCIBUS_FLAGS_OEM_ID)
+		show_value(6, "oem", "%s", uuid(&pcibus->pcibus_oem_id));
+	/* TODO: Dump OEM data */
+
+	printf("    </pci-bus>\n");
+}
+
+static void
+show_smbios(void)
+{
+	printf("    # SMBIOS\n");
+}
+
+static void
+show_pci_dev(struct mca_pcidev_record *pcidev)
+{
+	printf("    <pci-dev>\n");
+
+	if (pcidev->pcidev_flags & MCA_PCIDEV_FLAGS_STATUS)
+		show_value(6, "status", "0x%016llx",
+		    (long long)pcidev->pcidev_status);
+	if (pcidev->pcidev_flags & MCA_PCIDEV_FLAGS_INFO) {
+		show_value(6, "vendor", "0x%04x",
+		    pcidev->pcidev_info.info_vendor);
+		show_value(6, "device", "0x%04x",
+		    pcidev->pcidev_info.info_device);
+		show_value(6, "class", "0x%06x",
+		    MCA_PCIDEV_INFO_CLASS(pcidev->pcidev_info.info_ccfn));
+		show_value(6, "function", "0x%02x",
+		    MCA_PCIDEV_INFO_FUNCTION(pcidev->pcidev_info.info_ccfn));
+		show_value(6, "slot", "0x%02x", pcidev->pcidev_info.info_slot);
+		show_value(6, "bus", "0x%04x", pcidev->pcidev_info.info_bus);
+		show_value(6, "segment", "0x%04x",
+		    pcidev->pcidev_info.info_segment);
+	}
+	/* TODO: dump registers */
+	/* TODO: Dump OEM data */
+
+	printf("    </pci-dev>\n");
+}
+
+static void
+show_generic(void)
+{
+	printf("    # GENERIC\n");
+}
+
+static size_t
+show_section(struct mca_section_header *sh)
+{
+	static uuid_t uuid_cpu = MCA_UUID_CPU;
+	static uuid_t uuid_memory = MCA_UUID_MEMORY;
+	static uuid_t uuid_sel = MCA_UUID_SEL;
+	static uuid_t uuid_pci_bus = MCA_UUID_PCI_BUS;
+	static uuid_t uuid_smbios = MCA_UUID_SMBIOS;
+	static uuid_t uuid_pci_dev = MCA_UUID_PCI_DEV;
+	static uuid_t uuid_generic = MCA_UUID_GENERIC;
+
+	printf("  <section>\n");
+	show_value(4, "uuid", "%s", uuid(&sh->sh_uuid));
+	show_value(4, "revision", "%d.%d", BCD(sh->sh_major),
+	    BCD(sh->sh_minor));
+
+	if (uuid_equal(&sh->sh_uuid, &uuid_cpu, NULL))
+		show_cpu((void*)(sh + 1));
+	else if (uuid_equal(&sh->sh_uuid, &uuid_memory, NULL))
+		show_memory((void*)(sh + 1));
+	else if (uuid_equal(&sh->sh_uuid, &uuid_sel, NULL))
+		show_sel();
+	else if (uuid_equal(&sh->sh_uuid, &uuid_pci_bus, NULL))
+		show_pci_bus((void*)(sh + 1));
+	else if (uuid_equal(&sh->sh_uuid, &uuid_smbios, NULL))
+		show_smbios();
+	else if (uuid_equal(&sh->sh_uuid, &uuid_pci_dev, NULL))
+		show_pci_dev((void*)(sh + 1));
+	else if (uuid_equal(&sh->sh_uuid, &uuid_generic, NULL))
+		show_generic();
+
+	printf("  </section>\n");
+	return (sh->sh_length);
+}
+
+static void
+show(char *data, const char *mib)
+{
+	size_t reclen, seclen;
+
+	if (mib != NULL)
+		printf("<!-- MIB: %s -->\n", mib);
+
+	printf("<record>\n");
+	reclen = show_header((void*)data) - sizeof(struct mca_record_header);
+	data += sizeof(struct mca_record_header);
+	while (reclen > sizeof(struct mca_section_header)) {
+		seclen = show_section((void*)data);
+		reclen -= seclen;
+		data += seclen;
+	}
+	printf("</record>\n");
+}
+
+static void
+showall(char *buf, size_t buflen)
+{
+	struct mca_record_header *rh;
+	size_t reclen;
+
+	do {
+		if (buflen < sizeof(struct mca_record_header))
+			return;
+
+		rh = (void*)buf;
+		reclen = rh->rh_length;
+		if (buflen < reclen)
+			return;
+
+		show(buf, NULL);
+
+		buf += reclen;
+		buflen -= reclen;
+	}
+	while (1);
+}
+
+static void
+dump(char *data)
+{
+	struct mca_record_header *rh;
+	const char *fn;
+	int fd;
+
+	rh = (void*)data;
+	fn = (file) ? file : default_dumpfile;
+	fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0660);
+	if (fd == -1)
+		err(2, "open(%s)", fn);
+	if (write(fd, (void*)rh, rh->rh_length) == -1)
+		err(2, "write(%s)", fn);
+	close(fd);
+}
+
+static void
+usage(void)
+{
+
+	fprintf(stderr, "usage: mca [-df]\n");
+	exit (1);
+}
+
+int
+main(int argc, char **argv)
+{
+	char mib[32];
+	char *buf;
+	size_t len;
+	int ch, error, fd;
+	int count, first, last, cpuid;
+
+	while ((ch = getopt(argc, argv, "df:")) != -1) {
+		switch(ch) {
+		case 'd':	/* dump */
+			fl_dump = 1;
+			break;
+		case 'f':
+			if (file)
+				free(file);		/* XXX complain! */
+			file = strdup(optarg);
+			break;
+		default:
+			usage();
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (file == NULL || fl_dump) {
+		len = sizeof(count);
+		if (sysctlbyname(hw_mca_count, &count, &len, NULL, 0) == -1)
+			err(1, hw_mca_count);
+
+		if (count == 0)
+			errx(0, "no error records found");
+
+		len = sizeof(first);
+		if (sysctlbyname(hw_mca_first, &first, &len, NULL, 0) == -1)
+			err(1, hw_mca_first);
+
+		len = sizeof(last);
+		if (sysctlbyname(hw_mca_last, &last, &len, NULL, 0) == -1)
+			err(1, hw_mca_last);
+
+		cpuid = 0;
+		error = 0;
+		while (count && first <= last) {
+			do {
+				sprintf(mib, hw_mca_recid, first, cpuid);
+				len = 0;
+				ch = sysctlbyname(mib, NULL, &len, NULL, 0);
+				error = (ch == -1) ? errno : 0;
+				if (error != ENOENT)
+					break;
+				cpuid++;
+			} while (cpuid <= HW_MCA_MAX_CPUID);
+			if (error == ENOENT && cpuid > HW_MCA_MAX_CPUID) {
+				first++;
+				cpuid = 0;
+				continue;
+			}
+			if (error)
+				errc(1, error, "%s(1)", mib);
+
+			buf = malloc(len);
+			if (buf == NULL)
+				err(1, "buffer");
+
+			if (sysctlbyname(mib, buf, &len, NULL, 0) == -1)
+				err(1, "%s(2)", mib);
+
+			if (fl_dump)
+				dump(buf);
+			else
+				show(buf, mib);
+
+			free(buf);
+			count--;
+			if (cpuid == HW_MCA_MAX_CPUID) {
+				first++;
+				cpuid = 0;
+			} else
+				cpuid++;
+		}
+	} else {
+		fd = open(file, O_RDONLY);
+		if (fd == -1)
+			err(1, "open(%s)", file);
+
+		len = lseek(fd, 0LL, SEEK_END);
+		buf = mmap(NULL, len, PROT_READ, 0U, fd, 0LL);
+		if (buf == MAP_FAILED)
+			err(1, "mmap(%s)", file);
+
+		showall(buf, len);
+
+		munmap(buf, len);
+		close(fd);
+	}
+
+	return (0);
+}


Property changes on: trunk/sbin/mca/mca.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list