Ignore:
File:
1 edited

Legend:

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

    r11527051 r7ddc2c7  
    5252#include <errno.h>
    5353#include <str.h>
    54 #include <abi/klog.h>
    55 
    56 #define KLOG_PAGES    8
    57 #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))
    5858
    5959/** Kernel log cyclic buffer */
    60 wchar_t klog[KLOG_LENGTH] __attribute__((aligned(PAGE_SIZE)));
     60wchar_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
    6161
    6262/** Kernel log initialized */
    63 static atomic_t klog_inited = {false};
     63static atomic_t kio_inited = {false};
    6464
    6565/** First kernel log characters */
    66 static size_t klog_start = 0;
     66static size_t kio_start = 0;
    6767
    6868/** Number of valid kernel log characters */
    69 static size_t klog_len = 0;
     69static size_t kio_len = 0;
    7070
    7171/** Number of stored (not printed) kernel log characters */
    72 static size_t klog_stored = 0;
     72static size_t kio_stored = 0;
    7373
    7474/** Number of stored kernel log characters for uspace */
    75 static size_t klog_uspace = 0;
     75static size_t kio_uspace = 0;
    7676
    7777/** Kernel log spinlock */
    78 SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "klog_lock");
    79 
    80 /** Physical memory area used for klog buffer */
    81 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;
    8282
    8383static indev_t stdin_sink;
    8484static outdev_t stdout_source;
    8585
     86static void stdin_signal(indev_t *, indev_signal_t);
     87
    8688static indev_operations_t stdin_ops = {
    87         .poll = NULL
     89        .poll = NULL,
     90        .signal = stdin_signal
    8891};
    8992
    9093static void stdout_write(outdev_t *, wchar_t);
    9194static void stdout_redraw(outdev_t *);
     95static void stdout_scroll_up(outdev_t *);
     96static void stdout_scroll_down(outdev_t *);
    9297
    9398static outdev_operations_t stdout_ops = {
    9499        .write = stdout_write,
    95         .redraw = stdout_redraw
     100        .redraw = stdout_redraw,
     101        .scroll_up = stdout_scroll_up,
     102        .scroll_down = stdout_scroll_down
    96103};
    97104
     
    113120}
    114121
     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
    115136void stdout_wire(outdev_t *outdev)
    116137{
     
    125146static void stdout_write(outdev_t *dev, wchar_t ch)
    126147{
    127         list_foreach(dev->list, cur) {
    128                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     148        list_foreach(dev->list, link, outdev_t, sink) {
    129149                if ((sink) && (sink->op->write))
    130150                        sink->op->write(sink, ch);
     
    134154static void stdout_redraw(outdev_t *dev)
    135155{
    136         list_foreach(dev->list, cur) {
    137                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     156        list_foreach(dev->list, link, outdev_t, sink) {
    138157                if ((sink) && (sink->op->redraw))
    139158                        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);
    140175        }
    141176}
     
    148183 *
    149184 */
    150 void klog_init(void)
    151 {
    152         void *faddr = (void *) KA2PA(klog);
     185void kio_init(void)
     186{
     187        void *faddr = (void *) KA2PA(kio);
    153188       
    154189        ASSERT((uintptr_t) faddr % FRAME_SIZE == 0);
    155190       
    156         klog_parea.pbase = (uintptr_t) faddr;
    157         klog_parea.frames = SIZE2FRAMES(sizeof(klog));
    158         klog_parea.unpriv = false;
    159         klog_parea.mapped = false;
    160         ddi_parea_register(&klog_parea);
    161        
    162         sysinfo_set_item_val("klog.faddr", NULL, (sysarg_t) faddr);
    163         sysinfo_set_item_val("klog.pages", NULL, KLOG_PAGES);
    164        
    165         event_set_unmask_callback(EVENT_KLOG, klog_update);
    166         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);
    167202}
    168203
     
    231266                        }
    232267                }
     268               
    233269                if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
    234270                        putchar(ch);
     
    249285}
    250286
    251 void klog_update(void *event)
    252 {
    253         if (!atomic_get(&klog_inited))
     287void kio_update(void *event)
     288{
     289        if (!atomic_get(&kio_inited))
    254290                return;
    255291       
    256         spinlock_lock(&klog_lock);
    257        
    258         if (klog_uspace > 0) {
    259                 if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len,
    260                     klog_uspace) == EOK)
    261                         klog_uspace = 0;
    262         }
    263        
    264         spinlock_unlock(&klog_lock);
     292        spinlock_lock(&kio_lock);
     293       
     294        if (kio_uspace > 0) {
     295                if (event_notify_3(EVENT_KIO, true, kio_start, kio_len,
     296                    kio_uspace) == EOK)
     297                        kio_uspace = 0;
     298        }
     299       
     300        spinlock_unlock(&kio_lock);
     301}
     302
     303/** Flush characters that are stored in the output buffer
     304 *
     305 */
     306void kio_flush(void)
     307{
     308        bool ordy = ((stdout) && (stdout->op->write));
     309       
     310        if (!ordy)
     311                return;
     312
     313        spinlock_lock(&kio_lock);
     314
     315        /* Print characters that weren't printed earlier */
     316        while (kio_stored > 0) {
     317                wchar_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
     318                kio_stored--;
     319
     320                /*
     321                 * We need to give up the spinlock for
     322                 * the physical operation of writing out
     323                 * the character.
     324                 */
     325                spinlock_unlock(&kio_lock);
     326                stdout->op->write(stdout, tmp);
     327                spinlock_lock(&kio_lock);
     328        }
     329
     330        spinlock_unlock(&kio_lock);
     331}
     332
     333/** Put a character into the output buffer.
     334 *
     335 * The caller is required to hold kio_lock
     336 */
     337void kio_push_char(const wchar_t ch)
     338{
     339        kio[(kio_start + kio_len) % KIO_LENGTH] = ch;
     340        if (kio_len < KIO_LENGTH)
     341                kio_len++;
     342        else
     343                kio_start = (kio_start + 1) % KIO_LENGTH;
     344       
     345        if (kio_stored < kio_len)
     346                kio_stored++;
     347       
     348        /* The character is stored for uspace */
     349        if (kio_uspace < kio_len)
     350                kio_uspace++;
    265351}
    266352
     
    269355        bool ordy = ((stdout) && (stdout->op->write));
    270356       
    271         spinlock_lock(&klog_lock);
    272        
    273         /* Print charaters stored in kernel log */
    274         if (ordy) {
    275                 while (klog_stored > 0) {
    276                         wchar_t tmp = klog[(klog_start + klog_len - klog_stored) % KLOG_LENGTH];
    277                         klog_stored--;
    278                        
    279                         /*
    280                          * We need to give up the spinlock for
    281                          * the physical operation of writting out
    282                          * the character.
    283                          */
    284                         spinlock_unlock(&klog_lock);
    285                         stdout->op->write(stdout, tmp);
    286                         spinlock_lock(&klog_lock);
    287                 }
    288         }
    289        
    290         /* Store character in the cyclic kernel log */
    291         klog[(klog_start + klog_len) % KLOG_LENGTH] = ch;
    292         if (klog_len < KLOG_LENGTH)
    293                 klog_len++;
    294         else
    295                 klog_start = (klog_start + 1) % KLOG_LENGTH;
     357        spinlock_lock(&kio_lock);
     358        kio_push_char(ch);
     359        spinlock_unlock(&kio_lock);
     360       
     361        /* Output stored characters */
     362        kio_flush();
    296363       
    297364        if (!ordy) {
    298                 if (klog_stored < klog_len)
    299                         klog_stored++;
    300         }
    301        
    302         /* The character is stored for uspace */
    303         if (klog_uspace < klog_len)
    304                 klog_uspace++;
    305        
    306         spinlock_unlock(&klog_lock);
    307        
    308         if (ordy) {
    309                 /*
    310                  * Output the character. In this case
    311                  * it should be no longer buffered.
    312                  */
    313                 stdout->op->write(stdout, ch);
    314         } else {
    315365                /*
    316366                 * No standard output routine defined yet.
     
    328378        /* Force notification on newline */
    329379        if (ch == '\n')
    330                 klog_update(NULL);
     380                kio_update(NULL);
    331381}
    332382
     
    336386 *
    337387 */
    338 sysarg_t sys_klog(int cmd, const void *buf, size_t size)
     388sysarg_t sys_kio(int cmd, const void *buf, size_t size)
    339389{
    340390        char *data;
     
    342392
    343393        switch (cmd) {
    344         case KLOG_UPDATE:
    345                 klog_update(NULL);
     394        case KIO_UPDATE:
     395                kio_update(NULL);
    346396                return EOK;
    347         case KLOG_WRITE:
    348         case KLOG_COMMAND:
     397        case KIO_WRITE:
     398        case KIO_COMMAND:
    349399                break;
    350400        default:
     
    368418               
    369419                switch (cmd) {
    370                 case KLOG_WRITE:
     420                case KIO_WRITE:
    371421                        printf("%s", data);
    372422                        break;
    373                 case KLOG_COMMAND:
     423                case KIO_COMMAND:
    374424                        if (!stdin)
    375425                                break;
Note: See TracChangeset for help on using the changeset viewer.