diff --git a/arch/x86/tools/mcreboot-smp-x86.sh.in b/arch/x86/tools/mcreboot-smp-x86.sh.in index 786254e2..24861333 100644 --- a/arch/x86/tools/mcreboot-smp-x86.sh.in +++ b/arch/x86/tools/mcreboot-smp-x86.sh.in @@ -18,6 +18,42 @@ SBINDIR="@SBINDIR@" KMODDIR="@KMODDIR@" KERNDIR="@KERNDIR@" +INTERVAL=1 +LOGMODE=0 +while getopts :i:k: OPT +do + case ${OPT} in + i) INTERVAL=${OPTARG} + expr "${INTERVAL}" + 1 > /dev/null 2>&1 + if [ $? -ge 2 ] + then + echo "invalid -i value" + exit 1 + fi + if [ ${INTERVAL} -le 0 ] + then + echo "invalid -i value" + exit 1 + fi + ;; + k) LOGMODE=${OPTARG} + expr "${LOGMODE}" + 1 > /dev/null 2>&1 + if [ $? -ge 2 ] + then + echo "invalid -k value" + exit 1 + fi + if [ ${LOGMODE} -lt 0 -o ${LOGMODE} -gt 2 ] + then + echo "invalid -k value" + exit 1 + fi + ;; + *) echo "invalid option -${OPT}" + exit 1 + esac +done + mem="512M@0" cpus="" ihk_ikc_irq_core=0 @@ -105,7 +141,7 @@ if ! ${SBINDIR}/ihkconfig 0 create; then echo "error: create"; exit; fi if ! ${SBINDIR}/ihkosctl 0 assign cpu ${cpus}; then echo "error: assign CPUs"; exit; fi if ! ${SBINDIR}/ihkosctl 0 assign mem ${mem}; then echo "error: assign memory"; exit; fi if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then echo "error: loading kernel image"; exit; fi -if ! ${SBINDIR}/ihkosctl 0 kargs hidos; then echo "error: setting kernel arguments"; exit; fi +if ! ${SBINDIR}/ihkosctl 0 kargs "hidos ksyslogd=${LOGMODE}"; then echo "error: setting kernel arguments"; exit; fi if ! ${SBINDIR}/ihkosctl 0 boot; then echo "error: booting"; exit; fi if ! insmod ${KMODDIR}/mcctrl.ko; then echo "error: inserting mcctrl.ko"; exit; fi if ! chown `logname` /dev/mcd* /dev/mcos*; then echo "error: chowning device files"; exit; fi @@ -124,4 +160,7 @@ if [ "$enable_mcoverlay" != "" ]; then if ! mount -t mcoverlay mcoverlay -o lowerdir=/proc/mcos0:/proc,upperdir=/tmp/mcos/mcos0_proc_upper,workdir=/tmp/mcos/mcos0_proc_work,nocopyupw,nofscheck /tmp/mcos/mcos0_proc; then echo "error: mount /tmp/mcos/mcos0_proc"; exit; fi mount --make-rprivate /proc fi - +if [ ${LOGMODE} -ne 0 ] +then + SBINDIR=${SBINDIR} ${SBINDIR}/mcklogd -i ${INTERVAL} +fi diff --git a/kernel/debug.c b/kernel/debug.c index a58aff0d..6c9a8214 100644 --- a/kernel/debug.c +++ b/kernel/debug.c @@ -22,13 +22,44 @@ extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); extern int sprintf(char * buf, const char *fmt, ...); static ihk_spinlock_t kmsg_lock; +static unsigned long kprintf_lock_head(void); +static void kprintf_unlock_head(unsigned long irqflags); + +static void kprintf_wait(int len, unsigned long *flags_head, int *slide) { + int head, tail, buf_len, mode, adj; + + mode = kmsg_buf.mode; + while (1) { + adj = 0; + tail = kmsg_buf.tail; + buf_len = kmsg_buf.len; + head = kmsg_buf.head; + if (head < tail) head += buf_len; + if (tail + len > buf_len) adj = buf_len - tail; + if (head > tail && head <= tail + len + adj) { + if (mode != 1) { + *slide = 1; + break; + } else { + kprintf_unlock_head(*flags_head); + *flags_head = kprintf_lock_head(); + } + } else { + break; + } + } +} + /* TODO: lock */ void kputs(char *buf) { int len = strlen(buf); - unsigned long flags; + int slide = 0; + unsigned long flags_tail, flags_head; - flags = __ihk_mc_spinlock_lock(&kmsg_lock); + flags_tail = kprintf_lock(); + flags_head = kprintf_lock_head(); + kprintf_wait(len, &flags_head, &slide); if (len + kmsg_buf.tail > kmsg_buf.len) { kmsg_buf.tail = 0; @@ -39,8 +70,12 @@ void kputs(char *buf) memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len); kmsg_buf.tail += len; - - __ihk_mc_spinlock_unlock(&kmsg_lock, flags); + if (slide == 1) { + kmsg_buf.head = kmsg_buf.tail + 1; + if (kmsg_buf.head >= kmsg_buf.len) kmsg_buf.head = 0; + } + kprintf_unlock_head(flags_head); + kprintf_unlock(flags_tail); } #define KPRINTF_LOCAL_BUF_LEN 1024 @@ -55,11 +90,23 @@ void kprintf_unlock(unsigned long irqflags) __ihk_mc_spinlock_unlock(&kmsg_lock, irqflags); } +static unsigned long kprintf_lock_head(void) +{ + return __ihk_mc_spinlock_lock(&kmsg_buf.lock); +} + +static void kprintf_unlock_head(unsigned long irqflags) +{ + __ihk_mc_spinlock_unlock(&kmsg_buf.lock, irqflags); +} + /* Caller must hold kmsg_lock! */ int __kprintf(const char *format, ...) { int len = 0; + int slide = 0; va_list va; + unsigned long flags_head; char buf[KPRINTF_LOCAL_BUF_LEN]; /* Copy into the local buf */ @@ -67,6 +114,9 @@ int __kprintf(const char *format, ...) len += vsnprintf(buf + len, KPRINTF_LOCAL_BUF_LEN - len - 2, format, va); va_end(va); + flags_head = kprintf_lock_head(); + kprintf_wait(len, &flags_head, &slide); + /* Append to kmsg buffer */ if (kmsg_buf.tail + len > kmsg_buf.len) { kmsg_buf.tail = 0; @@ -74,25 +124,33 @@ int __kprintf(const char *format, ...) memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len); kmsg_buf.tail += len; + if (slide == 1) { + kmsg_buf.head = kmsg_buf.tail + 1; + if (kmsg_buf.head >= kmsg_buf.len) kmsg_buf.head = 0; + } + kprintf_unlock_head(flags_head); return len; } int kprintf(const char *format, ...) { int len = 0; + int slide = 0; va_list va; - unsigned long flags; + unsigned long flags_tail, flags_head; char buf[KPRINTF_LOCAL_BUF_LEN]; - flags = __ihk_mc_spinlock_lock(&kmsg_lock); - /* Copy into the local buf */ len = sprintf(buf, "[%3d]: ", ihk_mc_get_processor_id()); va_start(va, format); len += vsnprintf(buf + len, KPRINTF_LOCAL_BUF_LEN - len - 2, format, va); va_end(va); + flags_tail = kprintf_lock(); + flags_head = kprintf_lock_head(); + kprintf_wait(len, &flags_head, &slide); + /* Append to kmsg buffer */ if (kmsg_buf.tail + len > kmsg_buf.len) { kmsg_buf.tail = 0; @@ -100,16 +158,24 @@ int kprintf(const char *format, ...) memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len); kmsg_buf.tail += len; + if (slide == 1) { + kmsg_buf.head = kmsg_buf.tail + 1; + if (kmsg_buf.head >= kmsg_buf.len) kmsg_buf.head = 0; + } - __ihk_mc_spinlock_unlock(&kmsg_lock, flags); + kprintf_unlock_head(flags_head); + kprintf_unlock(flags_tail); return len; } -void kmsg_init(void) +void kmsg_init(int mode) { ihk_mc_spinlock_init(&kmsg_lock); kmsg_buf.tail = 0; kmsg_buf.len = sizeof(kmsg_buf.str); + kmsg_buf.head = 0; + kmsg_buf.mode = mode; + ihk_mc_spinlock_init(&kmsg_buf.lock); memset(kmsg_buf.str, 0, kmsg_buf.len); } diff --git a/kernel/include/init.h b/kernel/include/init.h index 31717f16..c36fd3c9 100644 --- a/kernel/include/init.h +++ b/kernel/include/init.h @@ -14,7 +14,7 @@ #define INIT_H extern void arch_init(void); -extern void kmsg_init(void); +extern void kmsg_init(int); extern void mem_init(void); extern void ikc_master_init(void); extern void ap_init(void); diff --git a/kernel/include/kmsg.h b/kernel/include/kmsg.h index db6da37f..75e82a0e 100644 --- a/kernel/include/kmsg.h +++ b/kernel/include/kmsg.h @@ -16,6 +16,6 @@ void kputs(char *buf); int kprintf(const char *format, ...); -void kmsg_init(void); +void kmsg_init(int); #endif diff --git a/kernel/init.c b/kernel/init.c index 1e651c0b..3313459c 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -298,7 +298,15 @@ extern void ibmic_cmd_init(void); int main(void) { - kmsg_init(); + char *ptr; + int mode = 0; + + ptr = find_command_line("ksyslogd="); + if (ptr) { + mode = ptr[9] - 0x30; + if (mode < 0 || mode > 2) mode = 0; + } + kmsg_init(mode); kputs("MCK started.\n"); diff --git a/lib/include/ihk/debug.h b/lib/include/ihk/debug.h index f7c09b57..6b64ccc7 100644 --- a/lib/include/ihk/debug.h +++ b/lib/include/ihk/debug.h @@ -13,12 +13,16 @@ #ifndef IHK_DEBUG_H #define IHK_DEBUG_H +#include #include struct ihk_kmsg_buf { int tail; int len; - char str[IHK_KMSG_SIZE - sizeof(int) * 2]; + int head; + int mode; + ihk_spinlock_t lock; + char str[IHK_KMSG_SIZE - sizeof(int) * 4 - sizeof(ihk_spinlock_t)]; }; extern int kprintf(const char *format, ...);