/branches/dd/uspace/app/bdsh/cmds/modules/kcon/kcon.h |
---|
0,0 → 1,8 |
#ifndef KCON_H |
#define KCON_H |
/* Prototypes for the kcon command, excluding entry points */ |
#endif /* KCON_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/kcon/entry.h |
---|
0,0 → 1,9 |
#ifndef KCON_ENTRY_H |
#define KCON_ENTRY_H |
/* Entry points for the kcon command */ |
extern int cmd_kcon(char **); |
extern void help_cmd_kcon(unsigned int); |
#endif /* KCON_ENTRY_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/kcon/kcon.c |
---|
0,0 → 1,72 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* 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. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 <stdio.h> |
#include <stdlib.h> |
#include <console.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "kcon.h" |
#include "cmds.h" |
static char *cmdname = "kcon"; |
/* Dispays help for kcon in various levels */ |
void help_cmd_kcon(unsigned int level) |
{ |
printf("`kcon' switches to the kernel debug console.\n"); |
if (level != HELP_SHORT) { |
printf("Usage: %s\n", cmdname); |
} |
return; |
} |
/* Main entry point for kcon, accepts an array of arguments */ |
int cmd_kcon(char **argv) |
{ |
unsigned int argc; |
argc = cli_count_args(argv); |
if (argc != 1) { |
printf("%s - incorrect number of arguments. Try `%s --help'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
console_kcon_enable(); |
return CMD_SUCCESS; |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/kcon/kcon_def.h |
---|
0,0 → 1,7 |
{ |
"kcon", |
"Switch to kernel console", |
&cmd_kcon, |
&help_cmd_kcon, |
}, |
/branches/dd/uspace/app/bdsh/cmds/modules/modules.h |
---|
26,6 → 26,7 |
#include "pwd/entry.h" |
#include "sleep/entry.h" |
#include "cp/entry.h" |
#include "kcon/entry.h" |
/* Each .def function fills the module_t struct with the individual name, entry |
* point, help entry point, etc. You can use config.h to control what modules |
41,6 → 42,7 |
#include "pwd/pwd_def.h" |
#include "sleep/sleep_def.h" |
#include "cp/cp_def.h" |
#include "kcon/kcon_def.h" |
{NULL, NULL, NULL, NULL} |
}; |
/branches/dd/uspace/app/bdsh/Makefile |
---|
57,6 → 57,7 |
cmds/modules/pwd/ \ |
cmds/modules/sleep/ \ |
cmds/modules/cp/ \ |
cmds/modules/kcon/ \ |
cmds/builtins/ \ |
cmds/builtins/exit/\ |
cmds/builtins/cd/ |
71,6 → 72,7 |
cmds/modules/pwd/pwd.c \ |
cmds/modules/sleep/sleep.c \ |
cmds/modules/cp/cp.c \ |
cmds/modules/kcon/kcon.c \ |
cmds/builtins/exit/exit.c \ |
cmds/builtins/cd/cd.c \ |
cmds/mod_cmds.c \ |
/branches/dd/uspace/app/tetris/input.c |
---|
115,7 → 115,7 |
if (!lastchar) { |
again: |
if (!getchar_inprog) { |
cons_phone = console_phone_get(); |
cons_phone = console_phone_get(true); |
getchar_inprog = async_send_2(cons_phone, |
CONSOLE_GETKEY, 0, 0, &charcall); |
} |
/branches/dd/uspace/app/tetris/screen.c |
---|
117,11 → 117,6 |
console_goto(r, c); |
} |
static void fflush(void) |
{ |
console_flush(); |
} |
winsize_t winsize; |
static int get_display_size(winsize_t *ws) |
274,7 → 269,7 |
} |
if (cur_so) |
resume_normal(); |
fflush(); |
fflush(stdout); |
} |
/* |
/branches/dd/uspace/app/tetris/tetris.c |
---|
390,7 → 390,7 |
scr_update(); |
scr_msg(key_msg, 0); |
scr_msg(msg, 1); |
// (void) fflush(stdout); |
(void) fflush(stdout); |
} while (rwait((struct timeval *)NULL) == -1); |
scr_msg(msg, 0); |
scr_msg(key_msg, 1); |
/branches/dd/uspace/app/klog/klog.c |
---|
42,6 → 42,7 |
#include <sysinfo.h> |
#include <io/stream.h> |
#include <console.h> |
#include <event.h> |
#include <errno.h> |
#define NAME "klog" |
82,11 → 83,10 |
return -1; |
} |
// int inr = sysinfo_value("klog.inr"); |
// if (ipc_register_irq(inr, devno, 0, NULL) != EOK) { |
// printf(NAME ": Error registering klog notifications\n"); |
// return -1; |
// } |
if (event_subscribe(EVENT_KLOG, 0) != EOK) { |
printf(NAME ": Error registering klog notifications\n"); |
return -1; |
} |
async_set_interrupt_received(interrupt_received); |
klog_update(); |
/branches/dd/uspace/app/trace/syscalls.c |
---|
65,6 → 65,8 |
[SYS_IPC_REGISTER_IRQ] = { "ipc_register_irq", 4, V_ERRNO }, |
[SYS_IPC_UNREGISTER_IRQ] = { "ipc_unregister_irq", 2, V_ERRNO }, |
[SYS_EVENT_SUBSCRIBE] = { "event_subscribe", 2, V_ERRNO }, |
[SYS_CAP_GRANT] = { "cap_grant", 2, V_ERRNO }, |
[SYS_CAP_REVOKE] = { "cap_revoke", 2, V_ERRNO }, |
[SYS_PHYSMEM_MAP] = { "physmem_map", 4, V_ERRNO }, |
/branches/dd/uspace/lib/libc/include/console.h |
---|
37,16 → 37,19 |
#include <console/style.h> |
#include <console/color.h> |
#include <bool.h> |
extern void console_open(void); |
extern void console_open(bool); |
extern void console_close(void); |
extern int console_phone_get(void); |
extern int console_phone_get(bool); |
extern void console_wait(void); |
extern void console_clear(void); |
extern void console_goto(int, int); |
extern void console_putchar(int); |
extern ssize_t console_write(const char *buf, size_t nbyte); |
extern void console_putstr(const char *s); |
extern void console_flush(void); |
extern int console_get_size(int *, int *); |
55,6 → 58,8 |
extern void console_set_rgb_color(int, int); |
extern void console_cursor_visibility(int); |
extern void console_kcon_enable(void); |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/stdio.h |
---|
69,6 → 69,7 |
extern int puts(const char *); |
extern int putchar(int); |
extern int fflush(FILE *); |
extern int printf(const char *, ...); |
extern int asprintf(char **, const char *, ...); |
/branches/dd/uspace/lib/libc/include/io/stream.h |
---|
44,6 → 44,7 |
extern ssize_t read_stdin(void *, size_t); |
extern ssize_t write_stdout(const void *, size_t); |
extern ssize_t write_stderr(const void *, size_t); |
extern int flush_stdout(void); |
#endif |
/branches/dd/uspace/lib/libc/include/event.h |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* 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. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_EVENT_H_ |
#define LIBC_EVENT_H_ |
#include <kernel/event/event_types.h> |
#include <ipc/ipc.h> |
extern int event_subscribe(event_type_t, ipcarg_t); |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/ipc/console.h |
---|
40,6 → 40,7 |
typedef enum { |
CONSOLE_GETKEY = IPC_FIRST_USER_METHOD, |
CONSOLE_PUTCHAR, |
CONSOLE_WRITE, |
CONSOLE_CLEAR, |
CONSOLE_GOTO, |
CONSOLE_GETSIZE, |
47,7 → 48,8 |
CONSOLE_SET_STYLE, |
CONSOLE_SET_COLOR, |
CONSOLE_SET_RGB_COLOR, |
CONSOLE_CURSOR_VISIBILITY |
CONSOLE_CURSOR_VISIBILITY, |
CONSOLE_KCON_ENABLE |
} console_request_t; |
#endif |
/branches/dd/uspace/lib/libc/generic/kbd.c |
---|
42,13 → 42,10 |
int kbd_get_event(kbd_event_t *ev) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(true); |
ipcarg_t r0, r1, r2, r3; |
int rc; |
if (cons_phone < 0) |
return -1; |
rc = async_req_0_4(cons_phone, CONSOLE_GETKEY, &r0, &r1, &r2, &r3); |
if (rc < 0) |
return -1; |
/branches/dd/uspace/lib/libc/generic/console.c |
---|
38,14 → 38,43 |
#include <io/stream.h> |
#include <ipc/console.h> |
#include <ipc/services.h> |
#include <errno.h> |
#include <string.h> |
#include <console.h> |
static int console_phone = -1; |
void console_open(void) |
/** Size of cbuffer. */ |
#define CBUFFER_SIZE 256 |
/** Buffer for writing characters to the console. */ |
static char cbuffer[CBUFFER_SIZE]; |
/** Pointer to end of cbuffer. */ |
static char *cbuffer_end = cbuffer + CBUFFER_SIZE; |
/** Pointer to first available field in cbuffer. */ |
static char *cbp = cbuffer; |
static ssize_t cons_write(const char *buf, size_t nbyte); |
static void cons_putchar(int c); |
static void cbuffer_flush(void); |
static void cbuffer_drain(void); |
static void cbuffer_putc(int c); |
void console_open(bool blocking) |
{ |
if (console_phone < 0) { |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0, 0); |
int phone; |
if (blocking) { |
phone = ipc_connect_me_to_blocking(PHONE_NS, |
SERVICE_CONSOLE, 0, 0); |
} else { |
phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0, |
0); |
} |
if (phone >= 0) |
console_phone = phone; |
} |
60,10 → 89,10 |
} |
} |
int console_phone_get(void) |
int console_phone_get(bool blocking) |
{ |
if (console_phone < 0) |
console_open(); |
console_open(blocking); |
return console_phone; |
} |
71,36 → 100,145 |
void console_wait(void) |
{ |
while (console_phone < 0) |
console_open(); |
console_open(true); |
} |
void console_clear(void) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(true); |
cbuffer_drain(); |
async_msg_0(cons_phone, CONSOLE_CLEAR); |
} |
void console_goto(int row, int col) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(true); |
cbuffer_flush(); |
async_msg_2(cons_phone, CONSOLE_GOTO, row, col); |
} |
void console_putchar(int c) |
{ |
int cons_phone = console_phone_get(); |
cbuffer_putc(c); |
} |
/** Write all data from output buffer to the console. */ |
static void cbuffer_flush(void) |
{ |
int rc; |
int len; |
len = cbp - cbuffer; |
while (len > 0) { |
rc = cons_write(cbuffer, cbp - cbuffer); |
if (rc < 0) |
return; |
len -= rc; |
} |
cbp = cbuffer; |
} |
/** Drop all data in console output buffer. */ |
static void cbuffer_drain(void) |
{ |
cbp = cbuffer; |
} |
/** Write one character to the output buffer. */ |
static inline void cbuffer_putc(int c) |
{ |
if (cbp == cbuffer_end) |
cbuffer_flush(); |
*cbp++ = c; |
if (c == '\n') |
cbuffer_flush(); |
} |
/** Write one character to the console via IPC. */ |
static void cons_putchar(int c) |
{ |
int cons_phone = console_phone_get(true); |
async_msg_1(cons_phone, CONSOLE_PUTCHAR, c); |
} |
/** Write characters to the console via IPC. */ |
static ssize_t cons_write(const char *buf, size_t nbyte) |
{ |
int cons_phone = console_phone_get(true); |
ipcarg_t rc; |
ipc_call_t answer; |
aid_t req; |
async_serialize_start(); |
req = async_send_0(cons_phone, CONSOLE_WRITE, &answer); |
rc = ipc_data_write_start(cons_phone, (void *) buf, nbyte); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
return (ssize_t) rc; |
} |
async_wait_for(req, &rc); |
async_serialize_end(); |
if (rc == EOK) |
return (ssize_t) IPC_GET_ARG1(answer); |
else |
return -1; |
} |
/** Write characters to the console. */ |
ssize_t console_write(const char *buf, size_t nbyte) |
{ |
size_t left; |
left = nbyte; |
while (left > 0) { |
cbuffer_putc(*buf++); |
--left; |
} |
return nbyte; |
} |
/** Write a NULL-terminated string to the console. */ |
void console_putstr(const char *s) |
{ |
size_t len; |
ssize_t rc; |
len = strlen(s); |
while (len > 0) { |
rc = console_write(s, len); |
if (rc < 0) |
return; /* Error */ |
s += rc; |
len -= rc; |
} |
} |
/** Flush all output to the console. */ |
void console_flush(void) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(false); |
cbuffer_flush(); |
async_msg_0(cons_phone, CONSOLE_FLUSH); |
} |
int console_get_size(int *rows, int *cols) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(true); |
ipcarg_t r, c; |
int rc; |
114,27 → 252,43 |
void console_set_style(int style) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(true); |
cbuffer_flush(); |
async_msg_1(cons_phone, CONSOLE_SET_STYLE, style); |
} |
void console_set_color(int fg_color, int bg_color, int flags) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(true); |
cbuffer_flush(); |
async_msg_3(cons_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags); |
} |
void console_set_rgb_color(int fg_color, int bg_color) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(true); |
cbuffer_flush(); |
async_msg_2(cons_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color); |
} |
void console_cursor_visibility(int show) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(true); |
cbuffer_flush(); |
async_msg_1(cons_phone, CONSOLE_CURSOR_VISIBILITY, show != 0); |
} |
void console_kcon_enable(void) |
{ |
int cons_phone = console_phone_get(true); |
cbuffer_flush(); |
async_msg_0(cons_phone, CONSOLE_KCON_ENABLE); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/event.c |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* 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. |
*/ |
/** @addtogroup libc |
* @{ |
* @} |
*/ |
/** @addtogroup libc |
*/ |
/** @file |
*/ |
#include <libc.h> |
#include <event.h> |
#include <kernel/event/event_types.h> |
#include <ipc/ipc.h> |
/** Subscribe for event notifications. |
* |
* @param e Event number. |
* @param method Use this method for notifying me. |
* |
* @return Value returned by the kernel. |
*/ |
int event_subscribe(event_type_t e, ipcarg_t method) |
{ |
return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) e, (sysarg_t) method); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/io/io.c |
---|
97,6 → 97,8 |
int getchar(void) |
{ |
unsigned char c; |
flush_stdout(); |
if (read_stdin((void *) &c, 1) == 1) |
return c; |
103,5 → 105,11 |
return EOF; |
} |
int fflush(FILE *f) |
{ |
(void) f; |
return flush_stdout(); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/io/stream.c |
---|
56,7 → 56,7 |
ssize_t read_stdin(void *buf, size_t count) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(false); |
if (cons_phone >= 0) { |
kbd_event_t ev; |
79,13 → 79,20 |
ssize_t write_stdout(const void *buf, size_t count) |
{ |
int cons_phone = console_phone_get(); |
int cons_phone = console_phone_get(false); |
int left, rc; |
if (cons_phone >= 0) { |
int i; |
for (i = 0; i < count; i++) |
console_putchar(((const char *) buf)[i]); |
left = count; |
while (left > 0) { |
rc = console_write(buf, left); |
if (rc < 0) |
break; |
buf += rc; |
left -= rc; |
} |
return count; |
} else |
92,6 → 99,12 |
return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, count); |
} |
int flush_stdout(void) |
{ |
console_flush(); |
return 0; |
} |
void klog_update(void) |
{ |
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0); |
/branches/dd/uspace/lib/libc/Makefile |
---|
47,6 → 47,7 |
generic/as.c \ |
generic/cap.c \ |
generic/console.c \ |
generic/event.c \ |
generic/mem.c \ |
generic/string.c \ |
generic/fibril.c \ |
/branches/dd/uspace/lib/libc/arch/sparc64/_link.ld.in |
---|
31,13 → 31,11 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
_tls_alignment = ALIGNOF(.tdata); |
.bss : { |
*(.sbss); |
*(COMMON); |
/branches/dd/uspace/lib/libc/arch/ia64/_link.ld.in |
---|
32,13 → 32,11 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
_tls_alignment = ALIGNOF(.tdata); |
.bss : { |
*(.sbss); |
*(.scommon); |
/branches/dd/uspace/lib/libc/arch/arm32/_link.ld.in |
---|
28,13 → 28,11 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
_tls_alignment = ALIGNOF(.tdata); |
.bss : { |
*(.sbss); |
*(.scommon); |
/branches/dd/uspace/lib/libc/arch/ppc32/_link.ld.in |
---|
27,13 → 27,11 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
_tls_alignment = ALIGNOF(.tdata); |
.bss : { |
*(.sbss); |
*(COMMON); |
/branches/dd/uspace/lib/libc/arch/amd64/_link.ld.in |
---|
26,13 → 26,11 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
_tls_alignment = ALIGNOF(.tdata); |
.bss : { |
*(COMMON); |
*(.bss); |
/branches/dd/uspace/lib/libc/arch/mips32/_link.ld.in |
---|
33,13 → 33,11 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
_tls_alignment = ALIGNOF(.tdata); |
.sbss : { |
*(.scommon); |
/branches/dd/uspace/lib/libc/arch/ia32/_link.ld.in |
---|
26,13 → 26,11 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
_tls_alignment = ALIGNOF(.tdata); |
.bss : { |
*(COMMON); |
*(.bss); |
/branches/dd/uspace/srv/console/console.c |
---|
49,6 → 49,7 |
#include <sys/mman.h> |
#include <stdio.h> |
#include <sysinfo.h> |
#include <event.h> |
#include "console.h" |
#include "gcons.h" |
62,8 → 63,7 |
int active_console = 0; |
int prev_console = 0; |
/** Information about framebuffer |
*/ |
/** Information about framebuffer */ |
struct { |
int phone; /**< Framebuffer phone */ |
ipcarg_t rows; /**< Framebuffer rows */ |
90,7 → 90,22 |
* faster virtual console |
* switching */ |
/** Information on row-span yet unsent to FB driver. */ |
struct { |
int row; /**< Row where the span lies. */ |
int col; /**< Leftmost column of the span. */ |
int n; /**< Width of the span. */ |
} fb_pending; |
/** Size of cwrite_buf. */ |
#define CWRITE_BUF_SIZE 256 |
/** Buffer for receiving data via the CONSOLE_WRITE call from the client. */ |
static char cwrite_buf[CWRITE_BUF_SIZE]; |
static void fb_putchar(char c, int row, int col); |
/** Find unused virtual console. |
* |
*/ |
158,21 → 173,99 |
} |
} |
static void prtchr(char c, int row, int col) |
/** Send an area of screenbuffer to the FB driver. */ |
static void fb_update_area(connection_t *conn, int x, int y, int w, int h) |
{ |
async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col); |
int i, j; |
int rc; |
attrs_t *attrs; |
keyfield_t *field; |
if (interbuffer) { |
for (j = 0; j < h; j++) { |
for (i = 0; i < w; i++) { |
interbuffer[i + j * w] = |
*get_field_at(&conn->screenbuffer, |
x + i, y + j); |
} |
} |
/** Check key and process special keys. |
rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA, |
x, y, w, h); |
} else { |
rc = ENOTSUP; |
} |
if (rc != 0) { |
attrs = &conn->screenbuffer.attrs; |
for (j = 0; j < h; j++) { |
for (i = 0; i < w; i++) { |
field = get_field_at(&conn->screenbuffer, |
x + i, y + j); |
if (!attrs_same(*attrs, field->attrs)) |
set_attrs(&field->attrs); |
attrs = &field->attrs; |
fb_putchar(field->character, y + j, x + i); |
} |
} |
} |
} |
/** Flush pending cells to FB. */ |
static void fb_pending_flush(void) |
{ |
screenbuffer_t *scr; |
scr = &(connections[active_console].screenbuffer); |
if (fb_pending.n > 0) { |
fb_update_area(&connections[active_console], fb_pending.col, |
fb_pending.row, fb_pending.n, 1); |
fb_pending.n = 0; |
} |
} |
/** Mark a character cell as changed. |
* |
* |
* This adds the cell to the pending rowspan if possible. Otherwise |
* the old span is flushed first. |
*/ |
static void cell_mark_changed(int row, int col) |
{ |
if (fb_pending.n != 0) { |
if (row != fb_pending.row || |
col != fb_pending.col + fb_pending.n) { |
fb_pending_flush(); |
} |
} |
if (fb_pending.n == 0) { |
fb_pending.row = row; |
fb_pending.col = col; |
} |
++fb_pending.n; |
} |
/** Print a character to the active VC with buffering. */ |
static void fb_putchar(char c, int row, int col) |
{ |
async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col); |
} |
/** Process a character from the client (TTY emulation). */ |
static void write_char(int console, char key) |
{ |
bool flush_cursor = false; |
screenbuffer_t *scr = &(connections[console].screenbuffer); |
switch (key) { |
case '\n': |
fb_pending_flush(); |
flush_cursor = true; |
scr->position_y++; |
scr->position_x = 0; |
break; |
187,20 → 280,24 |
break; |
scr->position_x--; |
if (console == active_console) |
prtchr(' ', scr->position_y, scr->position_x); |
cell_mark_changed(scr->position_y, scr->position_x); |
screenbuffer_putchar(scr, ' '); |
break; |
default: |
if (console == active_console) |
prtchr(key, scr->position_y, scr->position_x); |
cell_mark_changed(scr->position_y, scr->position_x); |
screenbuffer_putchar(scr, key); |
scr->position_x++; |
} |
scr->position_y += (scr->position_x >= scr->size_x); |
if (scr->position_x >= scr->size_x) { |
flush_cursor = true; |
scr->position_y++; |
} |
if (scr->position_y >= scr->size_y) { |
fb_pending_flush(); |
scr->position_y = scr->size_y - 1; |
screenbuffer_clear_line(scr, scr->top_line); |
scr->top_line = (scr->top_line + 1) % scr->size_y; |
210,9 → 307,8 |
scr->position_x = scr->position_x % scr->size_x; |
if (console == active_console) |
if (console == active_console && flush_cursor) |
curs_goto(scr->position_y, scr->position_x); |
} |
/** Switch to new console */ |
226,6 → 322,8 |
if (newcons == active_console) |
return; |
fb_pending_flush(); |
if (newcons == KERNEL_CONSOLE) { |
async_serialize_start(); |
curs_hide_sync(); |
252,16 → 350,19 |
set_attrs(&conn->screenbuffer.attrs); |
curs_visibility(false); |
if (interbuffer) { |
for (i = 0; i < conn->screenbuffer.size_x; i++) |
for (j = 0; j < conn->screenbuffer.size_y; j++) { |
for (i = 0; i < conn->screenbuffer.size_x; i++) { |
unsigned int size_x; |
size_x = conn->screenbuffer.size_x; |
interbuffer[i + j * size_x] = |
interbuffer[j * size_x + i] = |
*get_field_at(&conn->screenbuffer, i, j); |
} |
} |
/* This call can preempt, but we are already at the end */ |
rc = async_req_0_0(fb_info.phone, FB_DRAW_TEXT_DATA); |
rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA, |
0, 0, conn->screenbuffer.size_x, |
conn->screenbuffer.size_y); |
} |
if ((!interbuffer) || (rc != 0)) { |
280,7 → 381,7 |
conn->screenbuffer.attrs))) |
continue; |
prtchr(field->character, j, i); |
fb_putchar(field->character, j, i); |
} |
} |
360,6 → 461,31 |
} |
} |
/** Handle CONSOLE_WRITE call. */ |
static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request) |
{ |
ipc_callid_t callid; |
size_t len; |
size_t i; |
if (!ipc_data_write_receive(&callid, &len)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
} |
if (len > CWRITE_BUF_SIZE) |
len = CWRITE_BUF_SIZE; |
(void) ipc_data_write_finalize(callid, cwrite_buf, len); |
for (i = 0; i < len; i++) { |
write_char(consnum, cwrite_buf[i]); |
} |
gcons_notify_char(consnum); |
ipc_answer_1(rid, EOK, len); |
} |
/** Default thread for new connections */ |
static void client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
368,6 → 494,7 |
int consnum; |
ipcarg_t arg1, arg2, arg3, arg4; |
connection_t *conn; |
screenbuffer_t *scr; |
if ((consnum = find_free_connection()) == -1) { |
ipc_answer_0(iid, ELIMIT); |
411,6 → 538,9 |
write_char(consnum, IPC_GET_ARG1(call)); |
gcons_notify_char(consnum); |
break; |
case CONSOLE_WRITE: |
cons_write(consnum, callid, &call); |
continue; |
case CONSOLE_CLEAR: |
/* Send message to fb */ |
if (consnum == active_console) { |
432,10 → 562,16 |
arg2 = fb_info.cols; |
break; |
case CONSOLE_FLUSH: |
if (consnum == active_console) |
fb_pending_flush(); |
if (consnum == active_console) { |
async_req_0_0(fb_info.phone, FB_FLUSH); |
scr = &(connections[consnum].screenbuffer); |
curs_goto(scr->position_y, scr->position_x); |
} |
break; |
case CONSOLE_SET_STYLE: |
fb_pending_flush(); |
arg1 = IPC_GET_ARG1(call); |
screenbuffer_set_style(&conn->screenbuffer, arg1); |
if (consnum == active_console) |
442,6 → 578,7 |
set_style(arg1); |
break; |
case CONSOLE_SET_COLOR: |
fb_pending_flush(); |
arg1 = IPC_GET_ARG1(call); |
arg2 = IPC_GET_ARG2(call); |
arg3 = IPC_GET_ARG3(call); |
451,6 → 588,7 |
set_color(arg1, arg2, arg3); |
break; |
case CONSOLE_SET_RGB_COLOR: |
fb_pending_flush(); |
arg1 = IPC_GET_ARG1(call); |
arg2 = IPC_GET_ARG2(call); |
screenbuffer_set_rgb_color(&conn->screenbuffer, arg1, |
459,6 → 597,7 |
set_rgb_color(arg1, arg2); |
break; |
case CONSOLE_CURSOR_VISIBILITY: |
fb_pending_flush(); |
arg1 = IPC_GET_ARG1(call); |
conn->screenbuffer.is_cursor_visible = arg1; |
if (consnum == active_console) |
487,6 → 626,9 |
arg3 = ev.mods; |
arg4 = ev.c; |
break; |
case CONSOLE_KCON_ENABLE: |
change_console(KERNEL_CONSOLE); |
break; |
} |
ipc_answer_4(callid, EOK, arg1, arg2, arg3, arg4); |
} |
564,6 → 706,8 |
ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows; |
interbuffer = as_get_mappable_page(ib_size); |
fb_pending.n = 0; |
if (as_area_create(interbuffer, ib_size, AS_AREA_READ | |
AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer) { |
interbuffer = NULL; |
586,14 → 730,11 |
return -1; |
/* Receive kernel notifications */ |
// if (sysinfo_value("kconsole.present")) { |
// int inr = sysinfo_value("kconsole.inr"); |
// if (ipc_register_irq(inr, device_assign_devno(), 0, NULL) != EOK) |
// printf(NAME ": Error registering kconsole notifications\n"); |
// |
// async_set_interrupt_received(interrupt_received); |
// } |
if (event_subscribe(EVENT_KCONSOLE, 0) != EOK) |
printf(NAME ": Error registering kconsole notifications\n"); |
async_set_interrupt_received(interrupt_received); |
// FIXME: avoid connectiong to itself, keep using klog |
// printf(NAME ": Accepting connections\n"); |
async_manager(); |
/branches/dd/uspace/srv/fb/serial_console.c |
---|
223,26 → 223,48 |
} |
} |
static void draw_text_data(keyfield_t *data) |
/** Draw text data to viewport. |
* |
* @param vport Viewport id |
* @param data Text data. |
* @param x Leftmost column of the area. |
* @param y Topmost row of the area. |
* @param w Number of rows. |
* @param h Number of columns. |
*/ |
static void draw_text_data(keyfield_t *data, unsigned int x, |
unsigned int y, unsigned int w, unsigned int h) |
{ |
int i, j; |
unsigned int i, j; |
keyfield_t *field; |
attrs_t *a0, *a1; |
serial_goto(0, 0); |
serial_goto(y, x); |
a0 = &data[0].attrs; |
serial_set_attrs(a0); |
for (i = 0; i < scr_height; i++) { |
for (j = 0; j < scr_width; j++) { |
a1 = &data[i * scr_width + j].attrs; |
for (j = 0; j < h; j++) { |
if (j > 0 && w != scr_width) |
serial_goto(y, x); |
for (i = 0; i < w; i++) { |
unsigned int col = x + i; |
unsigned int row = y + j; |
field = &data[j * w + i]; |
a1 = &field->attrs; |
if (!attrs_same(*a0, *a1)) |
serial_set_attrs(a1); |
(*putc_function)(data[i * scr_width + j].character); |
(*putc_function)(field->character); |
a0 = a1; |
} |
} |
} |
int lastcol = 0; |
int lastrow = 0; |
/** |
* Main function of the thread serving client connections. |
*/ |
255,10 → 277,7 |
size_t intersize = 0; |
char c; |
int lastcol = 0; |
int lastrow = 0; |
int newcol; |
int newrow; |
int col, row, w, h; |
int fgcolor; |
int bgcolor; |
int flags; |
299,30 → 318,40 |
retval = EINVAL; |
break; |
case FB_DRAW_TEXT_DATA: |
col = IPC_GET_ARG1(call); |
row = IPC_GET_ARG2(call); |
w = IPC_GET_ARG3(call); |
h = IPC_GET_ARG4(call); |
if (!interbuf) { |
retval = EINVAL; |
break; |
} |
draw_text_data(interbuf); |
if (col + w > scr_width || row + h > scr_height) { |
retval = EINVAL; |
break; |
} |
draw_text_data(interbuf, col, row, w, h); |
lastrow = row + h - 1; |
lastcol = col + w; |
retval = 0; |
break; |
case FB_PUTCHAR: |
c = IPC_GET_ARG1(call); |
newrow = IPC_GET_ARG2(call); |
newcol = IPC_GET_ARG3(call); |
if ((lastcol != newcol) || (lastrow != newrow)) |
serial_goto(newrow, newcol); |
lastcol = newcol + 1; |
lastrow = newrow; |
row = IPC_GET_ARG2(call); |
col = IPC_GET_ARG3(call); |
if ((lastcol != col) || (lastrow != row)) |
serial_goto(row, col); |
lastcol = col + 1; |
lastrow = row; |
(*putc_function)(c); |
retval = 0; |
break; |
case FB_CURSOR_GOTO: |
newrow = IPC_GET_ARG1(call); |
newcol = IPC_GET_ARG2(call); |
serial_goto(newrow, newcol); |
lastrow = newrow; |
lastcol = newcol; |
row = IPC_GET_ARG1(call); |
col = IPC_GET_ARG2(call); |
serial_goto(row, col); |
lastrow = row; |
lastcol = col; |
retval = 0; |
break; |
case FB_GET_CSIZE: |
/branches/dd/uspace/srv/fb/msim.c |
---|
45,7 → 45,7 |
#include "msim.h" |
#define WIDTH 80 |
#define HEIGHT 25 |
#define HEIGHT 24 |
static char *virt_addr; |
/branches/dd/uspace/srv/fb/ski.c |
---|
47,7 → 47,7 |
#define SKI_PUTCHAR 31 |
#define WIDTH 80 |
#define HEIGHT 25 |
#define HEIGHT 24 |
/** Display character on ski debug console |
* |
/branches/dd/uspace/srv/fb/fb.c |
---|
866,36 → 866,41 |
cursor_show(vport); |
} |
/** Draw text data to viewport |
/** Draw text data to viewport. |
* |
* @param vport Viewport id |
* @param data Text data fitting exactly into viewport |
* |
* @param data Text data. |
* @param x Leftmost column of the area. |
* @param y Topmost row of the area. |
* @param w Number of rows. |
* @param h Number of columns. |
*/ |
static void draw_text_data(viewport_t *vport, keyfield_t *data) |
static void draw_text_data(viewport_t *vport, keyfield_t *data, unsigned int x, |
unsigned int y, unsigned int w, unsigned int h) |
{ |
unsigned int i; |
unsigned int i, j; |
bb_cell_t *bbp; |
attrs_t *a; |
attr_rgb_t rgb; |
for (i = 0; i < vport->cols * vport->rows; i++) { |
unsigned int col = i % vport->cols; |
unsigned int row = i / vport->cols; |
for (j = 0; j < h; j++) { |
for (i = 0; i < w; i++) { |
unsigned int col = x + i; |
unsigned int row = y + j; |
bbp = &vport->backbuf[BB_POS(vport, col, row)]; |
uint8_t glyph = bbp->glyph; |
a = &data[i].attrs; |
a = &data[j * w + i].attrs; |
rgb_from_attr(&rgb, a); |
bbp->glyph = data[i].character; |
bbp->glyph = data[j * w + i].character; |
bbp->fg_color = rgb.fg_color; |
bbp->bg_color = rgb.bg_color; |
draw_vp_glyph(vport, false, col, row); |
} |
} |
cursor_show(vport); |
} |
998,6 → 1003,8 |
viewport_t *vport = &viewports[vp]; |
unsigned int x; |
unsigned int y; |
unsigned int w; |
unsigned int h; |
switch (IPC_GET_METHOD(*call)) { |
case IPC_M_SHARE_OUT: |
1058,16 → 1065,24 |
IPC_GET_ARG2(*call), vport->width - x, vport->height - y, putpixel, (void *) vport); |
break; |
case FB_DRAW_TEXT_DATA: |
x = IPC_GET_ARG1(*call); |
y = IPC_GET_ARG2(*call); |
w = IPC_GET_ARG3(*call); |
h = IPC_GET_ARG4(*call); |
if (!interbuffer) { |
retval = EINVAL; |
break; |
} |
if (intersize < vport->cols * vport->rows * sizeof(*interbuffer)) { |
if (x + w > vport->cols || y + h > vport->rows) { |
retval = EINVAL; |
break; |
} |
draw_text_data(vport, interbuffer); |
if (intersize < w * h * sizeof(*interbuffer)) { |
retval = EINVAL; |
break; |
} |
draw_text_data(vport, interbuffer, x, y, w, h); |
break; |
default: |
handled = false; |
} |
/branches/dd/uspace/srv/fb/ega.c |
---|
78,7 → 78,7 |
static unsigned int scr_width; |
static unsigned int scr_height; |
static char *scr_addr; |
static uint8_t *scr_addr; |
static unsigned int style; |
151,15 → 151,32 |
cursor_goto(row, col + 1); |
} |
static void draw_text_data(keyfield_t *data) |
/** Draw text data to viewport. |
* |
* @param vport Viewport id |
* @param data Text data. |
* @param x Leftmost column of the area. |
* @param y Topmost row of the area. |
* @param w Number of rows. |
* @param h Number of columns. |
*/ |
static void draw_text_data(keyfield_t *data, unsigned int x, |
unsigned int y, unsigned int w, unsigned int h) |
{ |
int i; |
unsigned int i, j; |
keyfield_t *field; |
uint8_t *dp; |
for (i = 0; i < scr_width * scr_height; i++) { |
scr_addr[i * 2] = data[i].character; |
scr_addr[i * 2 + 1] = attr_to_ega_style(&data[i].attrs); |
for (j = 0; j < h; j++) { |
for (i = 0; i < w; i++) { |
field = &data[j * w + i]; |
dp = &scr_addr[2 * ((y + j) * scr_width + (x + i))]; |
dp[0] = field->character; |
dp[1] = attr_to_ega_style(&field->attrs); |
} |
} |
} |
static int save_screen(void) |
{ |
237,7 → 254,7 |
ipc_callid_t callid; |
ipc_call_t call; |
char c; |
unsigned int row, col; |
unsigned int row, col, w, h; |
int bg_color, fg_color, attr; |
uint32_t bg_rgb, fg_rgb; |
keyfield_t *interbuf = NULL; |
270,11 → 287,19 |
retval = EINVAL; |
break; |
case FB_DRAW_TEXT_DATA: |
col = IPC_GET_ARG1(call); |
row = IPC_GET_ARG2(call); |
w = IPC_GET_ARG3(call); |
h = IPC_GET_ARG4(call); |
if (!interbuf) { |
retval = EINVAL; |
break; |
} |
draw_text_data(interbuf); |
if (col + w > scr_width || row + h > scr_height) { |
retval = EINVAL; |
break; |
} |
draw_text_data(interbuf, col, row, w, h); |
retval = 0; |
break; |
case FB_GET_CSIZE: |
359,7 → 384,7 |
break; |
default: |
retval = ENOENT; |
retval = EINVAL; |
} |
ipc_answer_0(callid, retval); |
} |
/branches/dd/uspace/srv/vfs/vfs_ops.c |
---|
343,6 → 343,7 |
pr->callid = callid; |
pr->rid = rid; |
pr->dev_handle = dev_handle; |
link_initialize(&pr->link); |
list_append(&pr->link, &pending_req); |
return; |
} |