Subversion Repositories HelenOS

Rev

Rev 1923 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2006 Ondrej Palkovsky
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup genericklog
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <mm/frame.h>
  36. #include <sysinfo/sysinfo.h>
  37. #include <console/klog.h>
  38. #include <print.h>
  39. #include <ddi/device.h>
  40. #include <ddi/irq.h>
  41. #include <ipc/irq.h>
  42.  
  43. /*
  44.  * For now, we use 0 as INR.
  45.  * However, on some architectures 0 is the clock interrupt (e.g. amd64 and ia32).
  46.  * It is therefore desirable to have architecture specific definition of KLOG_VIRT_INR
  47.  * in the future.
  48.  */
  49. #define KLOG_VIRT_INR   0
  50.  
  51. /* Order of frame to be allocated for klog communication */
  52. #define KLOG_ORDER  0
  53.  
  54. static char *klog;
  55. static int klogsize;
  56. static int klogpos;
  57.  
  58. SPINLOCK_INITIALIZE(klog_lock);
  59.  
  60. static irq_t klog_irq;
  61.  
  62. static irq_ownership_t klog_claim(void);
  63.  
  64. /** Initialize kernel logging facility
  65.  *
  66.  * Allocate pages that are to be shared with uspace for console data.
  67.  * The shared area is a circular buffer. Userspace application may
  68.  * be notified on new data with indication of position and size
  69.  * of the data within the circular buffer.
  70.  */
  71. void klog_init(void)
  72. {
  73.     void *faddr;
  74.  
  75.     faddr = frame_alloc(KLOG_ORDER, FRAME_ATOMIC);
  76.     if (!faddr)
  77.         panic("Cannot allocate page for klog");
  78.     klog = (char *)PA2KA(faddr);
  79.    
  80.     devno_t devno = device_assign_devno();
  81.    
  82.     sysinfo_set_item_val("klog.faddr", NULL, (unative_t)faddr);
  83.     sysinfo_set_item_val("klog.pages", NULL, 1 << KLOG_ORDER);
  84.     sysinfo_set_item_val("klog.devno", NULL, devno);
  85.     sysinfo_set_item_val("klog.inr", NULL, KLOG_VIRT_INR);
  86.  
  87.     irq_initialize(&klog_irq);
  88.     klog_irq.devno = devno;
  89.     klog_irq.inr = KLOG_VIRT_INR;
  90.     klog_irq.claim = klog_claim;
  91.     irq_register(&klog_irq);
  92.  
  93.     klogsize = PAGE_SIZE << KLOG_ORDER;
  94.     klogpos = 0;
  95. }
  96.  
  97. /** Allways refuse IRQ ownership.
  98.  *
  99.  * This is not a real IRQ, so we always decline.
  100.  *
  101.  * @return Always returns IRQ_DECLINE.
  102.  */
  103. irq_ownership_t klog_claim(void)
  104. {
  105.     return IRQ_DECLINE;
  106. }
  107.  
  108. static void klog_vprintf(const char *fmt, va_list args)
  109. {
  110.     int ret;
  111.     va_list atst;
  112.  
  113.     va_copy(atst, args);
  114.     spinlock_lock(&klog_lock);
  115.  
  116.     ret = vsnprintf(klog+klogpos, klogsize-klogpos, fmt, atst);
  117.     if (ret >= klogsize-klogpos) {
  118.         klogpos = 0;
  119.         if (ret >= klogsize)
  120.             goto out;
  121.     }
  122.     ipc_irq_send_msg(&klog_irq, klogpos, ret, 0);
  123.     klogpos += ret;
  124.     if (klogpos >= klogsize)
  125.         klogpos = 0;
  126. out:
  127.     spinlock_unlock(&klog_lock);
  128.     va_end(atst);
  129. }
  130.  
  131. /** Printf a message to kernel-uspace log */
  132. void klog_printf(const char *fmt, ...)
  133. {
  134.     va_list args;
  135.    
  136.     va_start(args, fmt);
  137.    
  138.     klog_vprintf(fmt, args);
  139.  
  140.     va_end(args);
  141. }
  142.  
  143. /** @}
  144.  */
  145.