Ignore:
File:
1 edited

Legend:

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

    rd7533c7 rb366a6f4  
    5353#include <str.h>
    5454
    55 #define KLOG_PAGES    4
     55#define KLOG_PAGES    8
    5656#define KLOG_LENGTH   (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t))
    57 #define KLOG_LATENCY  8
    5857
    5958/** Kernel log cyclic buffer */
     
    6160
    6261/** Kernel log initialized */
    63 static bool klog_inited = false;
     62static atomic_t klog_inited = {false};
    6463
    6564/** First kernel log characters */
     
    7675
    7776/** Kernel log spinlock */
    78 SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "*klog_lock");
     77SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "klog_lock");
    7978
    8079/** Physical memory area used for klog buffer */
     
    8887};
    8988
    90 static void stdout_write(outdev_t *, wchar_t, bool);
     89static void stdout_write(outdev_t *, wchar_t);
    9190static void stdout_redraw(outdev_t *);
    9291
     
    9695};
    9796
    98 /** Silence output */
    99 bool silent = false;
     97/** Override kernel console lockout */
     98bool console_override = false;
    10099
    101100/** Standard input and output character devices */
     
    123122}
    124123
    125 static void stdout_write(outdev_t *dev, wchar_t ch, bool silent)
    126 {
    127         link_t *cur;
    128        
    129         for (cur = dev->list.next; cur != &dev->list; cur = cur->next) {
     124static void stdout_write(outdev_t *dev, wchar_t ch)
     125{
     126        list_foreach(dev->list, cur) {
    130127                outdev_t *sink = list_get_instance(cur, outdev_t, link);
    131128                if ((sink) && (sink->op->write))
    132                         sink->op->write(sink, ch, silent);
     129                        sink->op->write(sink, ch);
    133130        }
    134131}
     
    136133static void stdout_redraw(outdev_t *dev)
    137134{
    138         link_t *cur;
    139        
    140         for (cur = dev->list.next; cur != &dev->list; cur = cur->next) {
     135        list_foreach(dev->list, cur) {
    141136                outdev_t *sink = list_get_instance(cur, outdev_t, link);
    142137                if ((sink) && (sink->op->redraw))
     
    161156        klog_parea.frames = SIZE2FRAMES(sizeof(klog));
    162157        klog_parea.unpriv = false;
     158        klog_parea.mapped = false;
    163159        ddi_parea_register(&klog_parea);
    164160       
     
    166162        sysinfo_set_item_val("klog.pages", NULL, KLOG_PAGES);
    167163       
    168         spinlock_lock(&klog_lock);
    169         klog_inited = true;
    170         spinlock_unlock(&klog_lock);
     164        event_set_unmask_callback(EVENT_KLOG, klog_update);
     165        atomic_set(&klog_inited, true);
    171166}
    172167
    173168void grab_console(void)
    174169{
    175         bool prev = silent;
    176        
    177         silent = false;
     170        bool prev = console_override;
     171       
     172        console_override = true;
    178173        if ((stdout) && (stdout->op->redraw))
    179174                stdout->op->redraw(stdout);
    180175       
    181         if ((stdin) && (prev)) {
     176        if ((stdin) && (!prev)) {
    182177                /*
    183178                 * Force the console to print the prompt.
     
    189184void release_console(void)
    190185{
    191         // FIXME arch_release_console
    192         silent = true;
    193 }
    194 
    195 /** Tell kernel to get keyboard/console access again */
    196 sysarg_t sys_debug_enable_console(void)
     186        console_override = false;
     187}
     188
     189/** Activate kernel console override */
     190sysarg_t sys_debug_activate_console(void)
    197191{
    198192#ifdef CONFIG_KCONSOLE
     
    202196        return false;
    203197#endif
    204 }
    205 
    206 /** Tell kernel to relinquish keyboard/console access */
    207 sysarg_t sys_debug_disable_console(void)
    208 {
    209         release_console();
    210         return true;
    211198}
    212199
     
    263250void klog_update(void)
    264251{
     252        if (!atomic_get(&klog_inited))
     253                return;
     254       
    265255        spinlock_lock(&klog_lock);
    266256       
    267         if ((klog_inited) && (event_is_subscribed(EVENT_KLOG)) && (klog_uspace > 0)) {
    268                 event_notify_3(EVENT_KLOG, klog_start, klog_len, klog_uspace);
    269                 klog_uspace = 0;
     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;
    270261        }
    271262       
     
    275266void putchar(const wchar_t ch)
    276267{
     268        bool ordy = ((stdout) && (stdout->op->write));
     269       
    277270        spinlock_lock(&klog_lock);
    278271       
    279         if ((klog_stored > 0) && (stdout) && (stdout->op->write)) {
    280                 /* Print charaters stored in kernel log */
    281                 size_t i;
    282                 for (i = klog_len - klog_stored; i < klog_len; i++)
    283                         stdout->op->write(stdout, klog[(klog_start + i) % KLOG_LENGTH], silent);
    284                 klog_stored = 0;
     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                }
    285287        }
    286288       
     
    292294                klog_start = (klog_start + 1) % KLOG_LENGTH;
    293295       
    294         if ((stdout) && (stdout->op->write))
    295                 stdout->op->write(stdout, ch, silent);
    296         else {
     296        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 {
    297314                /*
    298315                 * No standard output routine defined yet.
     
    304321                 * Note that the early_putc() function might be
    305322                 * a no-op on certain hardware configurations.
    306                  *
    307323                 */
    308324                early_putchar(ch);
    309                
    310                 if (klog_stored < klog_len)
    311                         klog_stored++;
    312         }
    313        
    314         /* The character is stored for uspace */
    315         if (klog_uspace < klog_len)
    316                 klog_uspace++;
    317        
    318         /* Check notify uspace to update */
    319         bool update;
    320         if ((klog_uspace > KLOG_LATENCY) || (ch == '\n'))
    321                 update = true;
    322         else
    323                 update = false;
    324        
    325         spinlock_unlock(&klog_lock);
    326        
    327         if (update)
     325        }
     326       
     327        /* Force notification on newline */
     328        if (ch == '\n')
    328329                klog_update();
    329330}
Note: See TracChangeset for help on using the changeset viewer.