Ignore:
File:
1 edited

Legend:

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

    r11527051 r6afc9d7  
    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#include <mm/frame.h> /* SIZE2FRAMES */
     56#include <mm/slab.h>  /* malloc */
     57
     58#define KIO_PAGES    8
     59#define KIO_LENGTH   (KIO_PAGES * PAGE_SIZE / sizeof(wchar_t))
    5860
    5961/** Kernel log cyclic buffer */
    60 wchar_t klog[KLOG_LENGTH] __attribute__((aligned(PAGE_SIZE)));
     62wchar_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
    6163
    6264/** Kernel log initialized */
    63 static atomic_t klog_inited = {false};
     65static atomic_t kio_inited = {false};
    6466
    6567/** First kernel log characters */
    66 static size_t klog_start = 0;
     68static size_t kio_start = 0;
    6769
    6870/** Number of valid kernel log characters */
    69 static size_t klog_len = 0;
     71static size_t kio_len = 0;
    7072
    7173/** Number of stored (not printed) kernel log characters */
    72 static size_t klog_stored = 0;
     74static size_t kio_stored = 0;
    7375
    7476/** Number of stored kernel log characters for uspace */
    75 static size_t klog_uspace = 0;
     77static size_t kio_uspace = 0;
    7678
    7779/** 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;
     80SPINLOCK_INITIALIZE_NAME(kio_lock, "kio_lock");
     81
     82/** Physical memory area used for kio buffer */
     83static parea_t kio_parea;
    8284
    8385static indev_t stdin_sink;
    8486static outdev_t stdout_source;
    8587
     88static void stdin_signal(indev_t *, indev_signal_t);
     89
    8690static indev_operations_t stdin_ops = {
    87         .poll = NULL
     91        .poll = NULL,
     92        .signal = stdin_signal
    8893};
    8994
    9095static void stdout_write(outdev_t *, wchar_t);
    9196static void stdout_redraw(outdev_t *);
     97static void stdout_scroll_up(outdev_t *);
     98static void stdout_scroll_down(outdev_t *);
    9299
    93100static outdev_operations_t stdout_ops = {
    94101        .write = stdout_write,
    95         .redraw = stdout_redraw
     102        .redraw = stdout_redraw,
     103        .scroll_up = stdout_scroll_up,
     104        .scroll_down = stdout_scroll_down
    96105};
    97106
     
    113122}
    114123
     124static void stdin_signal(indev_t *indev, indev_signal_t signal)
     125{
     126        switch (signal) {
     127        case INDEV_SIGNAL_SCROLL_UP:
     128                if (stdout != NULL)
     129                        stdout_scroll_up(stdout);
     130                break;
     131        case INDEV_SIGNAL_SCROLL_DOWN:
     132                if (stdout != NULL)
     133                        stdout_scroll_down(stdout);
     134                break;
     135        }
     136}
     137
    115138void stdout_wire(outdev_t *outdev)
    116139{
     
    125148static void stdout_write(outdev_t *dev, wchar_t ch)
    126149{
    127         list_foreach(dev->list, cur) {
    128                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     150        list_foreach(dev->list, link, outdev_t, sink) {
    129151                if ((sink) && (sink->op->write))
    130152                        sink->op->write(sink, ch);
     
    134156static void stdout_redraw(outdev_t *dev)
    135157{
    136         list_foreach(dev->list, cur) {
    137                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     158        list_foreach(dev->list, link, outdev_t, sink) {
    138159                if ((sink) && (sink->op->redraw))
    139160                        sink->op->redraw(sink);
     161        }
     162}
     163
     164static void stdout_scroll_up(outdev_t *dev)
     165{
     166        list_foreach(dev->list, link, outdev_t, sink) {
     167                if ((sink) && (sink->op->scroll_up))
     168                        sink->op->scroll_up(sink);
     169        }
     170}
     171
     172static void stdout_scroll_down(outdev_t *dev)
     173{
     174        list_foreach(dev->list, link, outdev_t, sink) {
     175                if ((sink) && (sink->op->scroll_down))
     176                        sink->op->scroll_down(sink);
    140177        }
    141178}
     
    148185 *
    149186 */
    150 void klog_init(void)
    151 {
    152         void *faddr = (void *) KA2PA(klog);
     187void kio_init(void)
     188{
     189        void *faddr = (void *) KA2PA(kio);
    153190       
    154191        ASSERT((uintptr_t) faddr % FRAME_SIZE == 0);
    155192       
    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);
     193        kio_parea.pbase = (uintptr_t) faddr;
     194        kio_parea.frames = SIZE2FRAMES(sizeof(kio));
     195        kio_parea.unpriv = false;
     196        kio_parea.mapped = false;
     197        ddi_parea_register(&kio_parea);
     198       
     199        sysinfo_set_item_val("kio.faddr", NULL, (sysarg_t) faddr);
     200        sysinfo_set_item_val("kio.pages", NULL, KIO_PAGES);
     201       
     202        event_set_unmask_callback(EVENT_KIO, kio_update);
     203        atomic_set(&kio_inited, true);
    167204}
    168205
    169206void grab_console(void)
    170207{
     208        event_notify_1(EVENT_KCONSOLE, false, true);
    171209        bool prev = console_override;
    172210       
     
    186224{
    187225        console_override = false;
     226        event_notify_1(EVENT_KCONSOLE, false, false);
    188227}
    189228
    190229/** Activate kernel console override */
    191 sysarg_t sys_debug_activate_console(void)
     230sysarg_t sys_debug_console(void)
    192231{
    193232#ifdef CONFIG_KCONSOLE
     
    231270                        }
    232271                }
     272               
    233273                if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
    234274                        putchar(ch);
     
    249289}
    250290
    251 void klog_update(void *event)
    252 {
    253         if (!atomic_get(&klog_inited))
     291void kio_update(void *event)
     292{
     293        if (!atomic_get(&kio_inited))
    254294                return;
    255295       
    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);
     296        spinlock_lock(&kio_lock);
     297       
     298        if (kio_uspace > 0) {
     299                if (event_notify_3(EVENT_KIO, true, kio_start, kio_len,
     300                    kio_uspace) == EOK)
     301                        kio_uspace = 0;
     302        }
     303       
     304        spinlock_unlock(&kio_lock);
     305}
     306
     307/** Flush characters that are stored in the output buffer
     308 *
     309 */
     310void kio_flush(void)
     311{
     312        bool ordy = ((stdout) && (stdout->op->write));
     313       
     314        if (!ordy)
     315                return;
     316
     317        spinlock_lock(&kio_lock);
     318
     319        /* Print characters that weren't printed earlier */
     320        while (kio_stored > 0) {
     321                wchar_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
     322                kio_stored--;
     323
     324                /*
     325                 * We need to give up the spinlock for
     326                 * the physical operation of writing out
     327                 * the character.
     328                 */
     329                spinlock_unlock(&kio_lock);
     330                stdout->op->write(stdout, tmp);
     331                spinlock_lock(&kio_lock);
     332        }
     333
     334        spinlock_unlock(&kio_lock);
     335}
     336
     337/** Put a character into the output buffer.
     338 *
     339 * The caller is required to hold kio_lock
     340 */
     341void kio_push_char(const wchar_t ch)
     342{
     343        kio[(kio_start + kio_len) % KIO_LENGTH] = ch;
     344        if (kio_len < KIO_LENGTH)
     345                kio_len++;
     346        else
     347                kio_start = (kio_start + 1) % KIO_LENGTH;
     348       
     349        if (kio_stored < kio_len)
     350                kio_stored++;
     351       
     352        /* The character is stored for uspace */
     353        if (kio_uspace < kio_len)
     354                kio_uspace++;
    265355}
    266356
     
    269359        bool ordy = ((stdout) && (stdout->op->write));
    270360       
    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;
     361        spinlock_lock(&kio_lock);
     362        kio_push_char(ch);
     363        spinlock_unlock(&kio_lock);
     364       
     365        /* Output stored characters */
     366        kio_flush();
    296367       
    297368        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 {
    315369                /*
    316370                 * No standard output routine defined yet.
     
    328382        /* Force notification on newline */
    329383        if (ch == '\n')
    330                 klog_update(NULL);
     384                kio_update(NULL);
    331385}
    332386
     
    336390 *
    337391 */
    338 sysarg_t sys_klog(int cmd, const void *buf, size_t size)
     392sysarg_t sys_kio(int cmd, const void *buf, size_t size)
    339393{
    340394        char *data;
     
    342396
    343397        switch (cmd) {
    344         case KLOG_UPDATE:
    345                 klog_update(NULL);
     398        case KIO_UPDATE:
     399                kio_update(NULL);
    346400                return EOK;
    347         case KLOG_WRITE:
    348         case KLOG_COMMAND:
     401        case KIO_WRITE:
     402        case KIO_COMMAND:
    349403                break;
    350404        default:
     
    368422               
    369423                switch (cmd) {
    370                 case KLOG_WRITE:
     424                case KIO_WRITE:
    371425                        printf("%s", data);
    372426                        break;
    373                 case KLOG_COMMAND:
     427                case KIO_COMMAND:
    374428                        if (!stdin)
    375429                                break;
     
    383437        }
    384438
    385         return size;
     439        return EOK;
    386440}
    387441
Note: See TracChangeset for help on using the changeset viewer.