Commit 41e1d4fd authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

Simple printk, adapted from Linux's vsprintf.

Updated liblcd and the microkernel. Doesn't support
all escapes, like %p.

Updated documentation. Stack protection should be turned off.
parent 71bacb46
......@@ -64,6 +64,11 @@ kernel source,
-- go into Virtualization (2) and select Lightweight Capability
Domains and Intel Support for LCDs
-- it is recommended you build them as modules, for debugging
-- ** important ** : go into Processor type and features, and
turn off the stack protector feature (-fstack-protector);
otherwise, gcc will compile kernel code (include the modules
that are going inside lcd's) to use a stack protector, and
the lcd's are not configured for that
[ 2 ] exit and save the configuration
......
......@@ -91,6 +91,7 @@ LCD_MK_SYSCALL(LCD_SYSCALL_SEND)
LCD_MK_SYSCALL(LCD_SYSCALL_RECV)
LCD_MK_SYSCALL(LCD_SYSCALL_CALL)
LCD_MK_SYSCALL(LCD_SYSCALL_REPLY)
LCD_MK_SYSCALL(LCD_SYSCALL_PUTCHAR)
#define __LCD_DO_SYSCALL(num) lcd_syscall_##num()
......
......@@ -5,3 +5,4 @@
extra-y += main.o
extra-y += liblcd.o
......@@ -242,6 +242,38 @@ void __noreturn lcd_exit(int retval)
LCD_DO_SYSCALL(LCD_SYSCALL_EXIT); /* doesn't return */
}
/* LOW-LEVEL CONSOLE -------------------------------------------------- */
int lcd_put_char(char c)
{
lcd_set_r0(c);
return LCD_DO_SYSCALL(LCD_SYSCALL_PUTCHAR);
}
#include "vsnprintf.c"
void lcd_printk(char *fmt, ...)
{
va_list args;
char buf[512]; /* this is probably a bit big ... */
char *p;
/*
* Convert fmt string to chars
*/
va_start(args, fmt);
lcd_vsnprintf(buf, 512, fmt, args);
va_end(args);
/*
* Write char by char
*/
for (p = buf; *p; p++)
lcd_put_char(*p);
/*
* Write null char
*/
lcd_put_char(0);
}
/* IPC -------------------------------------------------- */
......
This diff is collapsed.
......@@ -13,5 +13,6 @@
#define LCD_SYSCALL_RECV 2
#define LCD_SYSCALL_CALL 3
#define LCD_SYSCALL_REPLY 4
#define LCD_SYSCALL_PUTCHAR 5
#endif /* LCD_DOMAINS_SYSCALL_H */
......@@ -88,5 +88,14 @@ config LCD_TEST_MOD_IPC2_LCD2
depends on LCD_TEST_MOD_IPC2
default m
# --------------------------------------------------
config LCD_TEST_MOD_PRINTK
tristate "Basic test for lcd printk"
depends on LCD_DOMAINS
default m
---help---
Tests printk'ing a few messages.
endif
......@@ -215,6 +215,8 @@ enum lcd_xmit_status {
LCD_XMIT_FAILED = 2, /* when send/recv failed */
};
#define LCD_CONSOLE_BUFF_SIZE 512
struct lcd {
/*
* Lock
......@@ -276,6 +278,11 @@ struct lcd {
* then check if the lcd is in the queue.
*/
struct list_head endpoint_queue;
/*
* Console
*/
char console_buff[LCD_CONSOLE_BUFF_SIZE];
unsigned console_cursor;
};
/* similar to task structs */
......
......@@ -251,6 +251,10 @@ int __lcd_create__(struct lcd **out)
* Initialize send/recv queue list element
*/
INIT_LIST_HEAD(&lcd->endpoint_queue);
/*
* Initialize console cursor
*/
lcd->console_cursor = 0;
*out = lcd;
......@@ -802,6 +806,46 @@ lock_skip:
/* LCD EXECUTION -------------------------------------------------- */
static int __lcd_put_char(struct lcd *lcd)
{
char c;
/*
* Char is in r0
*/
c = __lcd_r0(lcd->utcb);
/*
* Put char in lcd's console buff
*/
lcd->console_buff[lcd->console_cursor] = c;
/*
* Bump cursor and check
*/
lcd->console_cursor++;
if (c == 0) {
/*
* End of string; printk to host and reset buff
*/
printk(KERN_INFO "message from lcd %p: %s\n",
lcd, lcd->console_buff);
lcd->console_cursor = 0;
return 0;
}
if (lcd->console_cursor >= LCD_CONSOLE_BUFF_SIZE - 1) {
/*
* Filled buffer; empty it.
*/
lcd->console_buff[LCD_CONSOLE_BUFF_SIZE - 1] = 0;
printk(KERN_INFO "(incomplete) message from lcd %p: %s\n",
lcd, lcd->console_buff);
lcd->console_cursor = 0;
return 0;
}
/*
* Otherwise, char stays buffered
*/
return 0;
}
static int lcd_handle_syscall(struct lcd *lcd, int *lcd_ret)
{
int syscall_id;
......@@ -819,6 +863,13 @@ static int lcd_handle_syscall(struct lcd *lcd, int *lcd_ret)
*lcd_ret = (int)__lcd_r0(lcd->utcb);
ret = 1;
break;
case LCD_SYSCALL_PUTCHAR:
/*
* Put char and possibly print on host
*/
ret = __lcd_put_char(lcd);
lcd_arch_set_syscall_ret(lcd->lcd_arch, ret);
break;
case LCD_SYSCALL_SEND:
/*
* Get endpoint
......
......@@ -7,3 +7,5 @@ obj-$(CONFIG_LCD_TEST_MOD_LOAD) += load/
obj-$(CONFIG_LCD_TEST_MOD_IPC1) += ipc1/
obj-$(CONFIG_LCD_TEST_MOD_IPC2) += ipc2/
obj-$(CONFIG_LCD_TEST_MOD_PRINTK) += printk/
# Main target
obj-$(CONFIG_LCD_TEST_MOD_PRINTK) += lcd-test-mod-printk.o
lcd-test-mod-printk-y += main.o
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/lcd-domains/liblcd.h>
#include "../../../../arch/x86/lcd-domains/liblcd.c"
static int __noreturn __init test_init(void)
{
int r = 0;
r = lcd_enter();
if (r)
goto out;
lcd_printk("message 1");
lcd_printk("message 2 with int %d", 5);
lcd_printk("message 3 with hex 0x%x", 255);
lcd_printk("message 4 with str %s", "hello");
out:
lcd_exit(r);
}
static void __exit test_exit(void)
{
return;
}
module_init(test_init);
module_exit(test_exit);
......@@ -331,7 +331,7 @@ static int test09(void)
/*
* Create a new lcd
*/
ret = lcd_create_module_lcd(&lcd, "lcd_test_mod_load",
ret = lcd_create_module_lcd(&lcd, "lcd_test_mod_printk",
LCD_CPTR_NULL, &mi);
if (ret) {
LCD_ERR("create module lcd");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment