/trunk/kernel/genarch/src/fb/fb.c |
---|
184,11 → 184,12 |
/** Hide logo and refresh screen |
* |
*/ |
static void logo_hide(void) |
static void logo_hide(bool silent) |
{ |
ylogo = 0; |
ytrim = yres; |
rowtrim = rows; |
if (!silent) |
fb_redraw(); |
} |
196,7 → 197,7 |
/** Draw character at given position |
* |
*/ |
static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row) |
static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row, bool silent) |
{ |
unsigned int x = COL2X(col); |
unsigned int y = ROW2Y(row); |
203,14 → 204,16 |
unsigned int yd; |
if (y >= ytrim) |
logo_hide(); |
logo_hide(silent); |
backbuf[BB_POS(col, row)] = glyph; |
if (!silent) { |
for (yd = 0; yd < FONT_SCANLINES; yd++) |
memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)], |
&glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
} |
} |
/** Scroll screen down by one row |
217,13 → 220,14 |
* |
* |
*/ |
static void screen_scroll(void) |
static void screen_scroll(bool silent) |
{ |
if (ylogo > 0) { |
logo_hide(); |
logo_hide(silent); |
return; |
} |
if (!silent) { |
unsigned int row; |
for (row = 0; row < rows; row++) { |
253,6 → 257,7 |
} |
} |
} |
} |
memmove(backbuf, backbuf + cols, cols * (rows - 1)); |
memsetb(&backbuf[BB_POS(0, rows - 1)], cols, 0); |
259,15 → 264,15 |
} |
static void cursor_put(void) |
static void cursor_put(bool silent) |
{ |
glyph_draw(CURSOR, position % cols, position / cols); |
glyph_draw(CURSOR, position % cols, position / cols, silent); |
} |
static void cursor_remove(void) |
static void cursor_remove(bool silent) |
{ |
glyph_draw(0, position % cols, position / cols); |
glyph_draw(0, position % cols, position / cols, silent); |
} |
276,44 → 281,45 |
* Emulate basic terminal commands. |
* |
*/ |
static void fb_putchar(chardev_t *dev, char ch) |
static void fb_putchar(chardev_t *dev, char ch, bool silent) |
{ |
spinlock_lock(&fb_lock); |
switch (ch) { |
case '\n': |
cursor_remove(); |
cursor_remove(silent); |
position += cols; |
position -= position % cols; |
break; |
case '\r': |
cursor_remove(); |
cursor_remove(silent); |
position -= position % cols; |
break; |
case '\b': |
cursor_remove(); |
cursor_remove(silent); |
if (position % cols) |
position--; |
break; |
case '\t': |
cursor_remove(); |
cursor_remove(silent); |
do { |
glyph_draw((uint8_t) ' ', position % cols, |
position / cols); |
position / cols, silent); |
position++; |
} while ((position % 8) && (position < cols * rows)); |
break; |
default: |
glyph_draw((uint8_t) ch, position % cols, position / cols); |
glyph_draw((uint8_t) ch, position % cols, |
position / cols, silent); |
position++; |
} |
if (position >= cols * rows) { |
position -= cols; |
screen_scroll(); |
screen_scroll(silent); |
} |
cursor_put(); |
cursor_put(silent); |
spinlock_unlock(&fb_lock); |
} |
/trunk/kernel/genarch/src/drivers/ega/ega.c |
---|
62,54 → 62,8 |
static uint8_t *backbuf; |
static ioport_t ega_base; |
static void ega_putchar(chardev_t *d, const char ch); |
chardev_t ega_console; |
static chardev_operations_t ega_ops = { |
.write = ega_putchar |
}; |
static void ega_move_cursor(void); |
void ega_init(ioport_t base, uintptr_t videoram_phys) |
{ |
/* Initialize the software structure. */ |
ega_base = base; |
backbuf = (uint8_t *) malloc(SCREEN * 2, 0); |
if (!backbuf) |
panic("Unable to allocate backbuffer."); |
videoram = (uint8_t *) hw_map(videoram_phys, SCREEN * 2); |
/* Clear the screen and set the cursor position. */ |
memsetw(videoram, SCREEN, 0x0720); |
memsetw(backbuf, SCREEN, 0x0720); |
ega_move_cursor(); |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
ega_parea.pbase = videoram_phys; |
ega_parea.vbase = (uintptr_t) videoram; |
ega_parea.frames = 1; |
ega_parea.cacheable = false; |
ddi_parea_register(&ega_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 2); |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.blinking", NULL, true); |
sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys); |
} |
static void ega_display_char(char ch) |
{ |
videoram[ega_cursor * 2] = ch; |
backbuf[ega_cursor * 2] = ch; |
} |
/* |
* This function takes care of scrolling. |
*/ |
127,8 → 81,24 |
ega_cursor = ega_cursor - ROW; |
} |
void ega_putchar(chardev_t *d __attribute__((unused)), const char ch) |
static void ega_move_cursor(void) |
{ |
outb(ega_base + EGA_INDEX_REG, 0xe); |
outb(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff)); |
outb(ega_base + EGA_INDEX_REG, 0xf); |
outb(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff)); |
} |
static void ega_display_char(char ch, bool silent) |
{ |
backbuf[ega_cursor * 2] = ch; |
if (!silent) |
videoram[ega_cursor * 2] = ch; |
} |
static void ega_putchar(chardev_t *d __attribute__((unused)), const char ch, bool silent) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
146,11 → 116,13 |
ega_cursor--; |
break; |
default: |
ega_display_char(ch); |
ega_display_char(ch, silent); |
ega_cursor++; |
break; |
} |
ega_check_cursor(); |
if (!silent) |
ega_move_cursor(); |
spinlock_unlock(&egalock); |
157,12 → 129,41 |
interrupts_restore(ipl); |
} |
void ega_move_cursor(void) |
static chardev_operations_t ega_ops = { |
.write = ega_putchar |
}; |
void ega_init(ioport_t base, uintptr_t videoram_phys) |
{ |
outb(ega_base + EGA_INDEX_REG, 0xe); |
outb(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff)); |
outb(ega_base + EGA_INDEX_REG, 0xf); |
outb(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff)); |
/* Initialize the software structure. */ |
ega_base = base; |
backbuf = (uint8_t *) malloc(SCREEN * 2, 0); |
if (!backbuf) |
panic("Unable to allocate backbuffer."); |
videoram = (uint8_t *) hw_map(videoram_phys, SCREEN * 2); |
/* Clear the screen and set the cursor position. */ |
memsetw(videoram, SCREEN, 0x0720); |
memsetw(backbuf, SCREEN, 0x0720); |
ega_move_cursor(); |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
ega_parea.pbase = videoram_phys; |
ega_parea.vbase = (uintptr_t) videoram; |
ega_parea.frames = 1; |
ega_parea.cacheable = false; |
ddi_parea_register(&ega_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 2); |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.blinking", NULL, true); |
sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys); |
} |
void ega_redraw(void) |
/trunk/kernel/generic/include/console/chardev.h |
---|
50,7 → 50,7 |
/** Resume pushing characters. */ |
void (* resume)(struct chardev *); |
/** Write character to stream. */ |
void (* write)(struct chardev *, char c); |
void (* write)(struct chardev *, char c, bool silent); |
/** Read character directly from device, assume interrupts disabled. */ |
char (* read)(struct chardev *); |
} chardev_operations_t; |
/trunk/kernel/generic/include/console/console.h |
---|
49,6 → 49,9 |
extern count_t gets(chardev_t *chardev, char *buf, size_t buflen); |
extern void putchar(char c); |
extern void grab_console(void); |
extern void release_console(void); |
extern void arch_grab_console(void); |
extern void arch_release_console(void); |
/trunk/kernel/generic/include/syscall/syscall.h |
---|
79,6 → 79,7 |
SYS_SYSINFO_VALUE, |
SYS_DEBUG_ENABLE_CONSOLE, |
SYS_DEBUG_DISABLE_CONSOLE, |
SYS_IPC_CONNECT_KBOX, |
SYSCALL_END |
} syscall_t; |
/trunk/kernel/generic/src/console/console.c |
---|
65,6 → 65,9 |
/**< Number of stored kernel log characters for uspace */ |
static size_t klog_uspace = 0; |
/**< Silent output */ |
static bool silent = false; |
/**< Kernel log spinlock */ |
SPINLOCK_INITIALIZE(klog_lock); |
144,6 → 147,18 |
spinlock_unlock(&klog_lock); |
} |
void grab_console(void) |
{ |
silent = false; |
arch_grab_console(); |
} |
void release_console(void) |
{ |
silent = true; |
arch_release_console(); |
} |
/** Get character from character device. Do not echo character. |
* |
* @param chardev Character device. |
253,7 → 268,7 |
/* Print charaters stored in kernel log */ |
index_t i; |
for (i = klog_len - klog_stored; i < klog_len; i++) |
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_SIZE]); |
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_SIZE], silent); |
klog_stored = 0; |
} |
265,7 → 280,7 |
klog_start = (klog_start + 1) % KLOG_SIZE; |
if (stdout->op->write) |
stdout->op->write(stdout, c); |
stdout->op->write(stdout, c, silent); |
else { |
/* The character is just in the kernel log */ |
if (klog_stored < klog_len) |
/trunk/kernel/generic/src/console/cmd.c |
---|
976,7 → 976,7 |
int cmd_continue(cmd_arg_t *argv) |
{ |
printf("The kernel will now relinquish the console.\n"); |
arch_release_console(); |
release_console(); |
if ((kconsole_notify) && (kconsole_irq.notif_cfg.notify)) |
ipc_irq_send_msg_0(&kconsole_irq); |
/trunk/kernel/generic/src/syscall/syscall.c |
---|
92,7 → 92,7 |
static unative_t sys_debug_enable_console(void) |
{ |
#ifdef CONFIG_KCONSOLE |
arch_grab_console(); |
grab_console(); |
return true; |
#else |
return false; |
99,6 → 99,13 |
#endif |
} |
/** Tell kernel to relinquish keyboard/console access */ |
static unative_t sys_debug_disable_console(void) |
{ |
release_console(); |
return true; |
} |
/** Dispatch system call */ |
unative_t syscall_handler(unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5, unative_t a6, unative_t id) |
184,6 → 191,7 |
/* Debug calls */ |
(syshandler_t) sys_debug_enable_console, |
(syshandler_t) sys_debug_disable_console, |
(syshandler_t) sys_ipc_connect_kbox |
}; |
/trunk/kernel/arch/sparc64/src/drivers/sgcn.c |
---|
295,17 → 295,18 |
* feed character is written ('\n'), the carriage return character ('\r') is |
* written straight away. |
*/ |
static void sgcn_putchar(struct chardev * cd, const char c) |
static void sgcn_putchar(struct chardev * cd, const char c, bool silent) |
{ |
if (!silent) { |
spinlock_lock(&sgcn_output_lock); |
sgcn_do_putchar(c); |
if (c == '\n') { |
if (c == '\n') |
sgcn_do_putchar('\r'); |
} |
spinlock_unlock(&sgcn_output_lock); |
} |
} |
/** |
* Called when actively reading the character. Not implemented yet. |
/trunk/kernel/arch/ia64/src/ski/ski.c |
---|
56,9 → 56,6 |
static bool kbd_disabled; |
static void ski_putchar(chardev_t *d, const char ch); |
static int32_t ski_getchar(void); |
/** Display character on debug console |
* |
* Use SSC (Simulator System Call) to |
67,8 → 64,9 |
* @param d Character device. |
* @param ch Character to be printed. |
*/ |
void ski_putchar(chardev_t *d, const char ch) |
static void ski_putchar(chardev_t *d, const char ch, bool silent) |
{ |
if (!silent) { |
asm volatile ( |
"mov r15 = %0\n" |
"mov r32 = %1\n" /* r32 is in0 */ |
81,6 → 79,7 |
if (ch == '\n') |
ski_putchar(d, '\r'); |
} |
} |
/** Ask debug console if a key was pressed. |
* |
91,7 → 90,7 |
* |
* @return ASCII code of pressed key or 0 if no key pressed. |
*/ |
int32_t ski_getchar(void) |
static int32_t ski_getchar(void) |
{ |
uint64_t ch; |
/trunk/kernel/arch/arm32/include/machine.h |
---|
111,8 → 111,7 |
#define machine_cpu_halt gxemul_cpu_halt |
#define machine_get_memory_size gxemul_get_memory_size |
#define machine_debug_putc(ch) gxemul_debug_putc(ch) |
#define machine_irq_exception(exc_no, istate) \ |
gxemul_irq_exception(exc_no, istate) |
#define machine_irq_exception(exc_no, istate) gxemul_irq_exception(exc_no, istate) |
#define machine_get_fb_address gxemul_get_fb_address |
#endif |
/trunk/kernel/arch/arm32/src/drivers/gxemul.c |
---|
133,8 → 133,9 |
* @param dev Not used. |
* @param ch Characted to be printed. |
*/ |
static void gxemul_write(chardev_t *dev, const char ch) |
static void gxemul_write(chardev_t *dev, const char ch, bool silent) |
{ |
if (!silent) |
*((char *) gxemul_hw_map.videoram) = ch; |
} |
/trunk/kernel/arch/ppc32/src/ppc32.c |
---|
147,8 → 147,7 |
(uintptr_t) kernel_uarg->uspace_entry); |
/* Unreachable */ |
for (;;) |
; |
while (true); |
} |
/** Acquire console back for kernel |
/trunk/kernel/arch/ia32xen/src/drivers/xconsole.c |
---|
55,8 → 55,9 |
stdout = &xen_console; |
} |
void xen_putchar(chardev_t *d, const char ch) |
void xen_putchar(chardev_t *d, const char ch, bool silent) |
{ |
if (!silent) { |
if (start_info.console.domU.evtchn != 0) { |
uint32_t cons = console_page.out_cons; |
uint32_t prod = console_page.out_prod; |
78,6 → 79,7 |
} else |
xen_console_io(CONSOLE_IO_WRITE, 1, &ch); |
} |
} |
/** @} |
*/ |
/trunk/kernel/arch/mips32/src/drivers/serial.c |
---|
46,17 → 46,19 |
static serial_t sconf[SERIAL_MAX]; |
static bool kb_enabled; |
static void serial_write(chardev_t *d, const char ch) |
static void serial_write(chardev_t *d, const char ch, bool silent) |
{ |
if (!silent) { |
serial_t *sd = (serial_t *)d->data; |
if (ch == '\n') |
serial_write(d, '\r'); |
/* Wait until transmit buffer empty */ |
while (! (SERIAL_READ_LSR(sd->port) & (1<<TRANSMIT_EMPTY_BIT))) |
; |
while (!(SERIAL_READ_LSR(sd->port) & (1 << TRANSMIT_EMPTY_BIT))); |
SERIAL_WRITE(sd->port, ch); |
} |
} |
static void serial_enable(chardev_t *d) |
{ |
134,7 → 136,6 |
{ |
serial_t *sd = &sconf[0]; |
chardev_initialize("serial_console", &console, &serial_ops); |
console.data = sd; |
kb_enabled = true; |
147,8 → 148,7 |
irq_register(&serial_irq); |
/* I don't know why, but the serial interrupts simply |
* don't work on simics |
*/ |
don't work on simics */ |
virtual_timer_fnc = &serial_handler; |
stdin = &console; |
/trunk/kernel/arch/mips32/src/drivers/msim.c |
---|
58,8 → 58,9 |
}; |
/** Putchar that works with MSIM & gxemul */ |
void msim_write(chardev_t *dev, const char ch) |
void msim_write(chardev_t *dev, const char ch, bool silent) |
{ |
if (!silent) |
*((char *) MSIM_VIDEORAM) = ch; |
} |
/trunk/uspace/srv/console/console.c |
---|
500,7 → 500,6 |
async_set_client_connection(client_connection); |
/* Connect to keyboard driver */ |
kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0, 0); |
while (kbd_phone < 0) { |
usleep(10000); |
518,6 → 517,9 |
fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0); |
} |
/* Disable kernel output to the console */ |
__SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE); |
/* Initialize gcons */ |
gcons_init(fb_info.phone); |
/* Synchronize, the gcons can have something in queue */ |