Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/console/console.c

    r1066041 r593e023  
    5252#include <errno.h>
    5353#include <str.h>
    54 #include <mm/frame.h> /* SIZE2FRAMES */
    55 #include <mm/slab.h>  /* malloc */
    56 
    57 #define KLOG_PAGES    8
    58 #define KLOG_LENGTH   (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t))
     54#include <abi/kio.h>
     55
     56#define KIO_PAGES    8
     57#define KIO_LENGTH   (KIO_PAGES * PAGE_SIZE / sizeof(wchar_t))
    5958
    6059/** Kernel log cyclic buffer */
    61 wchar_t klog[KLOG_LENGTH] __attribute__((aligned(PAGE_SIZE)));
     60wchar_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
    6261
    6362/** Kernel log initialized */
    64 static atomic_t klog_inited = {false};
     63static atomic_t kio_inited = {false};
    6564
    6665/** First kernel log characters */
    67 static size_t klog_start = 0;
     66static size_t kio_start = 0;
    6867
    6968/** Number of valid kernel log characters */
    70 static size_t klog_len = 0;
     69static size_t kio_len = 0;
    7170
    7271/** Number of stored (not printed) kernel log characters */
    73 static size_t klog_stored = 0;
     72static size_t kio_stored = 0;
    7473
    7574/** Number of stored kernel log characters for uspace */
    76 static size_t klog_uspace = 0;
     75static size_t kio_uspace = 0;
    7776
    7877/** Kernel log spinlock */
    79 SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "klog_lock");
    80 
    81 /** Physical memory area used for klog buffer */
    82 static parea_t klog_parea;
     78SPINLOCK_INITIALIZE_NAME(kio_lock, "kio_lock");
     79
     80/** Physical memory area used for kio buffer */
     81static parea_t kio_parea;
    8382
    8483static indev_t stdin_sink;
    8584static outdev_t stdout_source;
    8685
     86static void stdin_signal(indev_t *, indev_signal_t);
     87
    8788static indev_operations_t stdin_ops = {
    88         .poll = NULL
     89        .poll = NULL,
     90        .signal = stdin_signal
    8991};
    9092
    9193static void stdout_write(outdev_t *, wchar_t);
    9294static void stdout_redraw(outdev_t *);
     95static void stdout_scroll_up(outdev_t *);
     96static void stdout_scroll_down(outdev_t *);
    9397
    9498static outdev_operations_t stdout_ops = {
    9599        .write = stdout_write,
    96         .redraw = stdout_redraw
     100        .redraw = stdout_redraw,
     101        .scroll_up = stdout_scroll_up,
     102        .scroll_down = stdout_scroll_down
    97103};
    98104
     
    114120}
    115121
     122static void stdin_signal(indev_t *indev, indev_signal_t signal)
     123{
     124        switch (signal) {
     125        case INDEV_SIGNAL_SCROLL_UP:
     126                if (stdout != NULL)
     127                        stdout_scroll_up(stdout);
     128                break;
     129        case INDEV_SIGNAL_SCROLL_DOWN:
     130                if (stdout != NULL)
     131                        stdout_scroll_down(stdout);
     132                break;
     133        }
     134}
     135
    116136void stdout_wire(outdev_t *outdev)
    117137{
     
    126146static void stdout_write(outdev_t *dev, wchar_t ch)
    127147{
    128         list_foreach(dev->list, cur) {
    129                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     148        list_foreach(dev->list, link, outdev_t, sink) {
    130149                if ((sink) && (sink->op->write))
    131150                        sink->op->write(sink, ch);
     
    135154static void stdout_redraw(outdev_t *dev)
    136155{
    137         list_foreach(dev->list, cur) {
    138                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     156        list_foreach(dev->list, link, outdev_t, sink) {
    139157                if ((sink) && (sink->op->redraw))
    140158                        sink->op->redraw(sink);
     159        }
     160}
     161
     162static void stdout_scroll_up(outdev_t *dev)
     163{
     164        list_foreach(dev->list, link, outdev_t, sink) {
     165                if ((sink) && (sink->op->scroll_up))
     166                        sink->op->scroll_up(sink);
     167        }
     168}
     169
     170static void stdout_scroll_down(outdev_t *dev)
     171{
     172        list_foreach(dev->list, link, outdev_t, sink) {
     173                if ((sink) && (sink->op->scroll_down))
     174                        sink->op->scroll_down(sink);
    141175        }
    142176}
     
    149183 *
    150184 */
    151 void klog_init(void)
    152 {
    153         void *faddr = (void *) KA2PA(klog);
     185void kio_init(void)
     186{
     187        void *faddr = (void *) KA2PA(kio);
    154188       
    155189        ASSERT((uintptr_t) faddr % FRAME_SIZE == 0);
    156190       
    157         klog_parea.pbase = (uintptr_t) faddr;
    158         klog_parea.frames = SIZE2FRAMES(sizeof(klog));
    159         klog_parea.unpriv = false;
    160         klog_parea.mapped = false;
    161         ddi_parea_register(&klog_parea);
    162        
    163         sysinfo_set_item_val("klog.faddr", NULL, (sysarg_t) faddr);
    164         sysinfo_set_item_val("klog.pages", NULL, KLOG_PAGES);
    165        
    166         event_set_unmask_callback(EVENT_KLOG, klog_update);
    167         atomic_set(&klog_inited, true);
     191        kio_parea.pbase = (uintptr_t) faddr;
     192        kio_parea.frames = SIZE2FRAMES(sizeof(kio));
     193        kio_parea.unpriv = false;
     194        kio_parea.mapped = false;
     195        ddi_parea_register(&kio_parea);
     196       
     197        sysinfo_set_item_val("kio.faddr", NULL, (sysarg_t) faddr);
     198        sysinfo_set_item_val("kio.pages", NULL, KIO_PAGES);
     199       
     200        event_set_unmask_callback(EVENT_KIO, kio_update);
     201        atomic_set(&kio_inited, true);
    168202}
    169203
    170204void grab_console(void)
    171205{
     206        event_notify_1(EVENT_KCONSOLE, false, true);
    172207        bool prev = console_override;
    173208       
     
    187222{
    188223        console_override = false;
     224        event_notify_1(EVENT_KCONSOLE, false, false);
    189225}
    190226
    191227/** Activate kernel console override */
    192 sysarg_t sys_debug_activate_console(void)
     228sysarg_t sys_debug_console(void)
    193229{
    194230#ifdef CONFIG_KCONSOLE
     
    232268                        }
    233269                }
     270               
    234271                if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
    235272                        putchar(ch);
     
    250287}
    251288
    252 void klog_update(void *event)
    253 {
    254         if (!atomic_get(&klog_inited))
     289void kio_update(void *event)
     290{
     291        if (!atomic_get(&kio_inited))
    255292                return;
    256293       
    257         spinlock_lock(&klog_lock);
    258        
    259         if (klog_uspace > 0) {
    260                 if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len,
    261                     klog_uspace) == EOK)
    262                         klog_uspace = 0;
    263         }
    264        
    265         spinlock_unlock(&klog_lock);
     294        spinlock_lock(&kio_lock);
     295       
     296        if (kio_uspace > 0) {
     297                if (event_notify_3(EVENT_KIO, true, kio_start, kio_len,
     298                    kio_uspace) == EOK)
     299                        kio_uspace = 0;
     300        }
     301       
     302        spinlock_unlock(&kio_lock);
     303}
     304
     305/** Flush characters that are stored in the output buffer
     306 *
     307 */
     308void kio_flush(void)
     309{
     310        bool ordy = ((stdout) && (stdout->op->write));
     311       
     312        if (!ordy)
     313                return;
     314
     315        spinlock_lock(&kio_lock);
     316
     317        /* Print characters that weren't printed earlier */
     318        while (kio_stored > 0) {
     319                wchar_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
     320                kio_stored--;
     321
     322                /*
     323                 * We need to give up the spinlock for
     324                 * the physical operation of writing out
     325                 * the character.
     326                 */
     327                spinlock_unlock(&kio_lock);
     328                stdout->op->write(stdout, tmp);
     329                spinlock_lock(&kio_lock);
     330        }
     331
     332        spinlock_unlock(&kio_lock);
     333}
     334
     335/** Put a character into the output buffer.
     336 *
     337 * The caller is required to hold kio_lock
     338 */
     339void kio_push_char(const wchar_t ch)
     340{
     341        kio[(kio_start + kio_len) % KIO_LENGTH] = ch;
     342        if (kio_len < KIO_LENGTH)
     343                kio_len++;
     344        else
     345                kio_start = (kio_start + 1) % KIO_LENGTH;
     346       
     347        if (kio_stored < kio_len)
     348                kio_stored++;
     349       
     350        /* The character is stored for uspace */
     351        if (kio_uspace < kio_len)
     352                kio_uspace++;
    266353}
    267354
     
    270357        bool ordy = ((stdout) && (stdout->op->write));
    271358       
    272         spinlock_lock(&klog_lock);
    273        
    274         /* Print charaters stored in kernel log */
    275         if (ordy) {
    276                 while (klog_stored > 0) {
    277                         wchar_t tmp = klog[(klog_start + klog_len - klog_stored) % KLOG_LENGTH];
    278                         klog_stored--;
    279                        
    280                         /*
    281                          * We need to give up the spinlock for
    282                          * the physical operation of writting out
    283                          * the character.
    284                          */
    285                         spinlock_unlock(&klog_lock);
    286                         stdout->op->write(stdout, tmp);
    287                         spinlock_lock(&klog_lock);
    288                 }
    289         }
    290        
    291         /* Store character in the cyclic kernel log */
    292         klog[(klog_start + klog_len) % KLOG_LENGTH] = ch;
    293         if (klog_len < KLOG_LENGTH)
    294                 klog_len++;
    295         else
    296                 klog_start = (klog_start + 1) % KLOG_LENGTH;
     359        spinlock_lock(&kio_lock);
     360        kio_push_char(ch);
     361        spinlock_unlock(&kio_lock);
     362       
     363        /* Output stored characters */
     364        kio_flush();
    297365       
    298366        if (!ordy) {
    299                 if (klog_stored < klog_len)
    300                         klog_stored++;
    301         }
    302        
    303         /* The character is stored for uspace */
    304         if (klog_uspace < klog_len)
    305                 klog_uspace++;
    306        
    307         spinlock_unlock(&klog_lock);
    308        
    309         if (ordy) {
    310                 /*
    311                  * Output the character. In this case
    312                  * it should be no longer buffered.
    313                  */
    314                 stdout->op->write(stdout, ch);
    315         } else {
    316367                /*
    317368                 * No standard output routine defined yet.
     
    329380        /* Force notification on newline */
    330381        if (ch == '\n')
    331                 klog_update(NULL);
     382                kio_update(NULL);
    332383}
    333384
     
    337388 *
    338389 */
    339 sysarg_t sys_klog(int fd, const void *buf, size_t size)
     390sysarg_t sys_kio(int cmd, const void *buf, size_t size)
    340391{
    341392        char *data;
    342393        int rc;
    343        
     394
     395        switch (cmd) {
     396        case KIO_UPDATE:
     397                kio_update(NULL);
     398                return EOK;
     399        case KIO_WRITE:
     400        case KIO_COMMAND:
     401                break;
     402        default:
     403                return ENOTSUP;
     404        }
     405
    344406        if (size > PAGE_SIZE)
    345407                return (sysarg_t) ELIMIT;
     
    357419                data[size] = 0;
    358420               
    359                 printf("%s", data);
     421                switch (cmd) {
     422                case KIO_WRITE:
     423                        printf("%s", data);
     424                        break;
     425                case KIO_COMMAND:
     426                        if (!stdin)
     427                                break;
     428                        for (unsigned int i = 0; i < size; i++)
     429                                indev_push_character(stdin, data[i]);
     430                        indev_push_character(stdin, '\n');
     431                        break;
     432                }
     433
    360434                free(data);
    361         } else
    362                 klog_update(NULL);
    363        
     435        }
     436
    364437        return size;
    365438}
Note: See TracChangeset for help on using the changeset viewer.