/*
 * Copyright (C) 2003 ASANO Masahiro
 */

#include <sys/types.h>
#include <unistd.h>
#include "crash.h"

PRIVATE addr_t dmesg();
const commandtable_t command_dmesg =
	{"dmesg", dmesg, "", "print the kernel message ring buffer"};

#if defined(CONFIG_MULTIQUAD) || defined(CONFIG_IA64)
#define LOG_BUF_LEN	(65536)
#elif defined(CONFIG_ARCH_S390)
#define LOG_BUF_LEN	(131072)
#elif defined(CONFIG_SMP)
#define LOG_BUF_LEN	(32768)
#else
#define LOG_BUF_LEN	(16384)
#endif

addr_t log_buf_addr;
addr_t log_end_addr;

PRIVATE addr_t
dmesg()
{
	int i, c;
	unsigned char buf[LOG_BUF_LEN];
	unsigned long log_end;

	while ((c = getopt(argcnt, args, "")) != EOF) {
		switch (c) {
		default:
			THROW(usage);
		}
	}

	GETADDR(log_buf);
	GETADDR(log_end);
	memread(log_buf_addr, LOG_BUF_LEN, buf, "log_buf");
	memread(log_end_addr, sizeof(log_end), &log_end, "log_end");

	c = '\0';
	for (i = 0; i < LOG_BUF_LEN; i++) {
		c = buf[(i + log_end) & (LOG_BUF_LEN - 1)];
		if (c > 0 && c <= 0x7f) {
			mprintf("%c", c);
		} else if (c > 0) {
			mprintf("\\x%2x", c);
		}
	}
	if (c != '\n' && c != '\0') {
		mprintf("\n");
	}
	return log_end;
}
