Ignore:
File:
1 edited

Legend:

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

    re3a050c7 r593e023  
    5252#include <errno.h>
    5353#include <str.h>
    54 
    55 #define KLOG_PAGES    8
    56 #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))
    5758
    5859/** Kernel log cyclic buffer */
    59 wchar_t klog[KLOG_LENGTH] __attribute__((aligned(PAGE_SIZE)));
     60wchar_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
    6061
    6162/** Kernel log initialized */
    62 static atomic_t klog_inited = {false};
     63static atomic_t kio_inited = {false};
    6364
    6465/** First kernel log characters */
    65 static size_t klog_start = 0;
     66static size_t kio_start = 0;
    6667
    6768/** Number of valid kernel log characters */
    68 static size_t klog_len = 0;
     69static size_t kio_len = 0;
    6970
    7071/** Number of stored (not printed) kernel log characters */
    71 static size_t klog_stored = 0;
     72static size_t kio_stored = 0;
    7273
    7374/** Number of stored kernel log characters for uspace */
    74 static size_t klog_uspace = 0;
     75static size_t kio_uspace = 0;
    7576
    7677/** Kernel log spinlock */
    77 SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "klog_lock");
    78 
    79 /** Physical memory area used for klog buffer */
    80 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;
    8182
    8283static indev_t stdin_sink;
    8384static outdev_t stdout_source;
    8485
     86static void stdin_signal(indev_t *, indev_signal_t);
     87
    8588static indev_operations_t stdin_ops = {
    86         .poll = NULL
     89        .poll = NULL,
     90        .signal = stdin_signal
    8791};
    8892
    8993static void stdout_write(outdev_t *, wchar_t);
    9094static void stdout_redraw(outdev_t *);
     95static void stdout_scroll_up(outdev_t *);
     96static void stdout_scroll_down(outdev_t *);
    9197
    9298static outdev_operations_t stdout_ops = {
    9399        .write = stdout_write,
    94         .redraw = stdout_redraw
     100        .redraw = stdout_redraw,
     101        .scroll_up = stdout_scroll_up,
     102        .scroll_down = stdout_scroll_down
    95103};
    96104
     
    112120}
    113121
     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
    114136void stdout_wire(outdev_t *outdev)
    115137{
     
    124146static void stdout_write(outdev_t *dev, wchar_t ch)
    125147{
    126         list_foreach(dev->list, cur) {
    127                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     148        list_foreach(dev->list, link, outdev_t, sink) {
    128149                if ((sink) && (sink->op->write))
    129150                        sink->op->write(sink, ch);
     
    133154static void stdout_redraw(outdev_t *dev)
    134155{
    135         list_foreach(dev->list, cur) {
    136                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     156        list_foreach(dev->list, link, outdev_t, sink) {
    137157                if ((sink) && (sink->op->redraw))
    138158                        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);
    139175        }
    140176}
     
    147183 *
    148184 */
    149 void klog_init(void)
    150 {
    151         void *faddr = (void *) KA2PA(klog);
     185void kio_init(void)
     186{
     187        void *faddr = (void *) KA2PA(kio);
    152188       
    153189        ASSERT((uintptr_t) faddr % FRAME_SIZE == 0);
    154190       
    155         klog_parea.pbase = (uintptr_t) faddr;
    156         klog_parea.frames = SIZE2FRAMES(sizeof(klog));
    157         klog_parea.unpriv = false;
    158         klog_parea.mapped = false;
    159         ddi_parea_register(&klog_parea);
    160        
    161         sysinfo_set_item_val("klog.faddr", NULL, (sysarg_t) faddr);
    162         sysinfo_set_item_val("klog.pages", NULL, KLOG_PAGES);
    163        
    164         event_set_unmask_callback(EVENT_KLOG, klog_update);
    165         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);
    166202}
    167203
    168204void grab_console(void)
    169205{
     206        event_notify_1(EVENT_KCONSOLE, false, true);
    170207        bool prev = console_override;
    171208       
     
    185222{
    186223        console_override = false;
     224        event_notify_1(EVENT_KCONSOLE, false, false);
    187225}
    188226
    189227/** Activate kernel console override */
    190 sysarg_t sys_debug_activate_console(void)
     228sysarg_t sys_debug_console(void)
    191229{
    192230#ifdef CONFIG_KCONSOLE
     
    230268                        }
    231269                }
     270               
    232271                if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
    233272                        putchar(ch);
     
    248287}
    249288
    250 void klog_update(void *event)
    251 {
    252         if (!atomic_get(&klog_inited))
     289void kio_update(void *event)
     290{
     291        if (!atomic_get(&kio_inited))
    253292                return;
    254293       
    255         spinlock_lock(&klog_lock);
    256        
    257         if (klog_uspace > 0) {
    258                 if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len,
    259                     klog_uspace) == EOK)
    260                         klog_uspace = 0;
    261         }
    262        
    263         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++;
    264353}
    265354
     
    268357        bool ordy = ((stdout) && (stdout->op->write));
    269358       
    270         spinlock_lock(&klog_lock);
    271        
    272         /* Print charaters stored in kernel log */
    273         if (ordy) {
    274                 while (klog_stored > 0) {
    275                         wchar_t tmp = klog[(klog_start + klog_len - klog_stored) % KLOG_LENGTH];
    276                         klog_stored--;
    277                        
    278                         /*
    279                          * We need to give up the spinlock for
    280                          * the physical operation of writting out
    281                          * the character.
    282                          */
    283                         spinlock_unlock(&klog_lock);
    284                         stdout->op->write(stdout, tmp);
    285                         spinlock_lock(&klog_lock);
    286                 }
    287         }
    288        
    289         /* Store character in the cyclic kernel log */
    290         klog[(klog_start + klog_len) % KLOG_LENGTH] = ch;
    291         if (klog_len < KLOG_LENGTH)
    292                 klog_len++;
    293         else
    294                 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();
    295365       
    296366        if (!ordy) {
    297                 if (klog_stored < klog_len)
    298                         klog_stored++;
    299         }
    300        
    301         /* The character is stored for uspace */
    302         if (klog_uspace < klog_len)
    303                 klog_uspace++;
    304        
    305         spinlock_unlock(&klog_lock);
    306        
    307         if (ordy) {
    308                 /*
    309                  * Output the character. In this case
    310                  * it should be no longer buffered.
    311                  */
    312                 stdout->op->write(stdout, ch);
    313         } else {
    314367                /*
    315368                 * No standard output routine defined yet.
     
    327380        /* Force notification on newline */
    328381        if (ch == '\n')
    329                 klog_update(NULL);
     382                kio_update(NULL);
    330383}
    331384
     
    335388 *
    336389 */
    337 sysarg_t sys_klog(int fd, const void *buf, size_t size)
     390sysarg_t sys_kio(int cmd, const void *buf, size_t size)
    338391{
    339392        char *data;
    340393        int rc;
    341        
     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
    342406        if (size > PAGE_SIZE)
    343407                return (sysarg_t) ELIMIT;
     
    355419                data[size] = 0;
    356420               
    357                 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
    358434                free(data);
    359         } else
    360                 klog_update(NULL);
    361        
     435        }
     436
    362437        return size;
    363438}
Note: See TracChangeset for help on using the changeset viewer.