Ignore:
Timestamp:
2011-07-08T17:01:01Z (13 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cc1a727
Parents:
4e36219 (diff), 026793d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/src/drivers/niagara.c

    r4e36219 rc028b22  
    3232/**
    3333 * @file
    34  * @brief       Niagara input/output driver based on hypervisor calls.
     34 * @brief Niagara input/output driver based on hypervisor calls.
    3535 */
    3636
     
    5252#include <genarch/srln/srln.h>
    5353
    54 /* polling interval in miliseconds */
     54/* Polling interval in miliseconds */
    5555#define POLL_INTERVAL  10000
    5656
    57 /* device instance */
     57/* Device instance */
    5858static niagara_instance_t *instance = NULL;
    5959
    60 static void niagara_putchar(outdev_t *, const wchar_t, bool);
    61 
    62 /** character device operations */
     60static void niagara_putchar(outdev_t *, const wchar_t);
     61
     62/** Character device operations */
    6363static outdev_operations_t niagara_ops = {
    6464        .write = niagara_putchar,
     
    6666};
    6767
    68 /*
     68/**
    6969 * The driver uses hypercalls to print characters to the console. Since the
    7070 * hypercall cannot be performed from the userspace, we do this:
    71  * The kernel "little brother" driver (which will be present no matter what the
    72  * DDI architecture is - as we need the kernel part for the kconsole)
     71 *
     72 * The kernel "little brother" driver (which will be present no matter what
     73 * the DDI architecture is -- as we need the kernel part for the kconsole)
    7374 * defines a shared buffer. Kernel walks through the buffer (in the same thread
    7475 * which is used for polling the keyboard) and prints any pending characters
    75  * to the console (using hypercalls). The userspace fb server maps this shared
    76  * buffer to its address space and output operation it does is performed using
    77  * the mapped buffer. The shared buffer definition follows.
    78  */
    79 #define OUTPUT_BUFFER_SIZE      ((PAGE_SIZE) - 2 * 8)
     76 * to the console (using hypercalls).
     77 *
     78 * The userspace fb server maps this shared buffer to its address space and
     79 * output operation it does is performed using the mapped buffer. The shared
     80 * buffer definition follows.
     81 */
     82#define OUTPUT_BUFFER_SIZE  ((PAGE_SIZE) - 2 * 8)
     83
    8084static volatile struct {
    8185        uint64_t read_ptr;
    8286        uint64_t write_ptr;
    8387        char data[OUTPUT_BUFFER_SIZE];
    84 }
    85         __attribute__ ((packed))
    86         __attribute__ ((aligned(PAGE_SIZE)))
    87         output_buffer;
     88} __attribute__ ((packed)) __attribute__ ((aligned(PAGE_SIZE))) output_buffer;
     89
     90static parea_t outbuf_parea;
    8891
    8992/**
    9093 * Analogous to the output_buffer, see the previous definition.
    9194 */
    92 #define INPUT_BUFFER_SIZE       ((PAGE_SIZE) - 2 * 8)
     95#define INPUT_BUFFER_SIZE  ((PAGE_SIZE) - 2 * 8)
     96
    9397static volatile struct {
    9498        uint64_t write_ptr;
    9599        uint64_t read_ptr;
    96100        char data[INPUT_BUFFER_SIZE];
    97 }
    98         __attribute__ ((packed))
    99         __attribute__ ((aligned(PAGE_SIZE)))
    100         input_buffer;
    101 
    102 
    103 /** Writes a single character to the standard output. */
     101} __attribute__ ((packed)) __attribute__ ((aligned(PAGE_SIZE))) input_buffer;
     102
     103static parea_t inbuf_parea;
     104
     105/** Write a single character to the standard output. */
    104106static inline void do_putchar(const char c) {
    105         /* repeat until the buffer is non-full */
    106         while (__hypercall_fast1(CONS_PUTCHAR, c) == HV_EWOULDBLOCK)
    107                 ;
    108 }
    109 
    110 /** Writes a single character to the standard output. */
    111 static void niagara_putchar(outdev_t *dev, const wchar_t ch, bool silent)
    112 {
    113         if (silent)
    114             return;
    115 
    116         do_putchar(ch);
    117         if (ch == '\n')
    118                 do_putchar('\r');
    119 }
    120 
    121 /**
    122  * Function regularly called by the keyboard polling thread. Asks the
    123  * hypervisor whether there is any unread character. If so, it picks it up
    124  * and sends it to the upper layers of HelenOS.
    125  *
    126  * Apart from that, it also checks whether the userspace output driver has
    127  * pushed any characters to the output buffer. If so, it prints them.
    128  */
    129 static void niagara_poll(niagara_instance_t *instance)
    130 {
    131         /* print any pending characters from the shared buffer to the console */
     107        /* Repeat until the buffer is non-full */
     108        while (__hypercall_fast1(CONS_PUTCHAR, c) == HV_EWOULDBLOCK);
     109}
     110
     111/** Write a single character to the standard output. */
     112static void niagara_putchar(outdev_t *dev, const wchar_t ch)
     113{
     114        if ((!outbuf_parea.mapped) || (console_override)) {
     115                do_putchar(ch);
     116                if (ch == '\n')
     117                        do_putchar('\r');
     118        }
     119}
     120
     121/** Poll keyboard and print pending characters.
     122 *
     123 * Ask the hypervisor whether there is any unread character. If so,
     124 * pick it up and send it to the indev layer.
     125 *
     126 * Check whether the userspace output driver has pushed any
     127 * characters to the output buffer and eventually print them.
     128 *
     129 */
     130static void niagara_poll(void)
     131{
     132        /*
     133         * Print any pending characters from the
     134         * shared buffer to the console.
     135         */
     136       
    132137        while (output_buffer.read_ptr != output_buffer.write_ptr) {
    133138                do_putchar(output_buffer.data[output_buffer.read_ptr]);
    134139                output_buffer.read_ptr =
    135                         ((output_buffer.read_ptr) + 1) % OUTPUT_BUFFER_SIZE;
    136         }
    137 
     140                    ((output_buffer.read_ptr) + 1) % OUTPUT_BUFFER_SIZE;
     141        }
     142       
     143        /*
     144         * Read character from keyboard.
     145         */
     146       
    138147        uint64_t c;
    139 
    140         /* read character from keyboard, send it to upper layers of HelenOS */
    141148        if (__hypercall_fast_ret1(0, 0, 0, 0, 0, CONS_GETCHAR, &c) == HV_EOK) {
    142                 if (!silent) {
    143                         /* kconsole active, send the character to kernel */
     149                if ((!inbuf_parea.mapped) || (console_override)) {
     150                        /*
     151                         * Kernel console is active, send
     152                         * the character to kernel.
     153                         */
    144154                        indev_push_character(instance->srlnin, c);
    145155                } else {
    146                         /* kconsole inactive, send the character to uspace driver */
     156                        /*
     157                         * Kernel console is inactive, send
     158                         * the character to uspace driver.
     159                         */
    147160                        input_buffer.data[input_buffer.write_ptr] = (char) c;
    148161                        input_buffer.write_ptr =
    149                                 ((input_buffer.write_ptr) + 1) % INPUT_BUFFER_SIZE;
     162                            ((input_buffer.write_ptr) + 1) % INPUT_BUFFER_SIZE;
    150163                }
    151164        }
    152165}
    153166
    154 /**
    155  * Polling thread function.
    156  */
    157 static void kniagarapoll(void *instance) {
     167/** Polling thread function.
     168 *
     169 */
     170static void kniagarapoll(void *arg) {
    158171        while (true) {
    159                 niagara_poll(instance);
     172                niagara_poll();
    160173                thread_usleep(POLL_INTERVAL);
    161174        }
    162175}
    163176
    164 /**
    165  * Initializes the input/output subsystem so that the Niagara standard
    166  * input/output is used.
     177/** Initialize the input/output subsystem
     178 *
    167179 */
    168180static void niagara_init(void)
     
    172184       
    173185        instance = malloc(sizeof(niagara_instance_t), FRAME_ATOMIC);
    174        
    175         if (instance) {
    176                 instance->thread = thread_create(kniagarapoll, instance, TASK, 0,
    177                         "kniagarapoll", true);
    178                
    179                 if (!instance->thread) {
    180                         free(instance);
    181                         instance = NULL;
    182                         return;
    183                 }
    184         }
    185 
     186        instance->thread = thread_create(kniagarapoll, NULL, TASK, 0,
     187            "kniagarapoll", true);
     188       
     189        if (!instance->thread) {
     190                free(instance);
     191                instance = NULL;
     192                return;
     193        }
     194       
    186195        instance->srlnin = NULL;
    187 
     196       
    188197        output_buffer.read_ptr = 0;
    189198        output_buffer.write_ptr = 0;
    190199        input_buffer.write_ptr = 0;
    191200        input_buffer.read_ptr = 0;
    192 
     201       
    193202        /*
    194203         * Set sysinfos and pareas so that the userspace counterpart of the
    195204         * niagara fb and kbd driver can communicate with kernel using shared
    196205         * buffers.
    197          */
    198 
     206         */
     207       
    199208        sysinfo_set_item_val("fb.kind", NULL, 5);
    200 
     209       
    201210        sysinfo_set_item_val("niagara.outbuf.address", NULL,
    202                 KA2PA(&output_buffer));
     211            KA2PA(&output_buffer));
    203212        sysinfo_set_item_val("niagara.outbuf.size", NULL,
    204                 PAGE_SIZE);
     213            PAGE_SIZE);
    205214        sysinfo_set_item_val("niagara.outbuf.datasize", NULL,
    206                 OUTPUT_BUFFER_SIZE);
    207 
     215            OUTPUT_BUFFER_SIZE);
     216       
    208217        sysinfo_set_item_val("niagara.inbuf.address", NULL,
    209                 KA2PA(&input_buffer));
     218            KA2PA(&input_buffer));
    210219        sysinfo_set_item_val("niagara.inbuf.size", NULL,
    211                 PAGE_SIZE);
     220            PAGE_SIZE);
    212221        sysinfo_set_item_val("niagara.inbuf.datasize", NULL,
    213                 INPUT_BUFFER_SIZE);
    214 
    215         static parea_t outbuf_parea;
     222           INPUT_BUFFER_SIZE);
     223       
    216224        outbuf_parea.pbase = (uintptr_t) (KA2PA(&output_buffer));
    217225        outbuf_parea.frames = 1;
    218226        outbuf_parea.unpriv = false;
     227        outbuf_parea.mapped = false;
    219228        ddi_parea_register(&outbuf_parea);
    220 
    221         static parea_t inbuf_parea;
     229       
    222230        inbuf_parea.pbase = (uintptr_t) (KA2PA(&input_buffer));
    223231        inbuf_parea.frames = 1;
    224232        inbuf_parea.unpriv = false;
     233        inbuf_parea.mapped = false;
    225234        ddi_parea_register(&inbuf_parea);
    226 
     235       
    227236        outdev_t *niagara_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
    228237        outdev_initialize("niagara_dev", niagara_dev, &niagara_ops);
     
    230239}
    231240
    232 /**
    233  * A public function which initializes input from the Niagara console.
     241/** Initialize input from the Niagara console.
     242 *
    234243 */
    235244niagara_instance_t *niagarain_init(void)
    236245{
    237246        niagara_init();
    238 
     247       
    239248        if (instance) {
    240249                srln_instance_t *srln_instance = srln_init();
     
    242251                        indev_t *sink = stdin_wire();
    243252                        indev_t *srln = srln_wire(srln_instance, sink);
    244 
    245                         // wire std. input to niagara
     253                       
    246254                        instance->srlnin = srln;
    247255                        thread_ready(instance->thread);
    248256                }
    249257        }
     258       
    250259        return instance;
    251260}
Note: See TracChangeset for help on using the changeset viewer.