Changeset a71c158 in mainline for kernel/arch/ia64/src/drivers/ski.c


Ignore:
Timestamp:
2009-08-21T14:12:45Z (15 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0e6dce8, b50b5af2, e5792d1
Parents:
90c8b8d
Message:

kernel output devices now suport multiple instances (except ski and sgcn, which respect the same interface, but behave as singletons)
if more than one output device gets initialized, the output is cloned to all of them
get rid of arch_grab_console() and arch_release_console() (output devices can implement a generic "redraw" method, input devices respect the "silent" global variable)
related cleanups and modifications

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia64/src/drivers/ski.c

    r90c8b8d ra71c158  
    4747enum {
    4848        /** Interval between polling in microseconds */
    49         POLL_INTERVAL =  10000,  /* 0.01 s */
    50 
     49        POLL_INTERVAL = 10000,  /* 0.01 s */
     50       
    5151        /** Max. number of characters to pull out at a time */
    52         POLL_LIMIT    =    30,
    53 
    54         SKI_INIT_CONSOLE  = 20,
    55         SKI_GETCHAR       = 21,
    56         SKI_PUTCHAR       = 31
     52        POLL_LIMIT = 30,
     53       
     54        SKI_INIT_CONSOLE = 20,
     55        SKI_GETCHAR      = 21,
     56        SKI_PUTCHAR      = 31
    5757};
    5858
    5959static void ski_putchar(outdev_t *, const wchar_t, bool);
    6060
    61 static outdev_operations_t skiout_ops = {
    62         .write = ski_putchar
     61static outdev_operations_t skidev_ops = {
     62        .write = ski_putchar,
     63        .redraw = NULL
    6364};
    6465
    65 static outdev_t skiout;            /**< Ski output device. */
    66 static bool initialized = false;
    67 static bool kbd_disabled = false;
     66static ski_instance_t *instance = NULL;
     67
     68/** Ask debug console if a key was pressed.
     69 *
     70 * Use SSC (Simulator System Call) to
     71 * get character from debug console.
     72 *
     73 * This call is non-blocking.
     74 *
     75 * @return ASCII code of pressed key or 0 if no key pressed.
     76 *
     77 */
     78static wchar_t ski_getchar(void)
     79{
     80        uint64_t ch;
     81       
     82        asm volatile (
     83                "mov r15 = %1\n"
     84                "break 0x80000;;\n"  /* modifies r8 */
     85                "mov %0 = r8;;\n"
     86               
     87                : "=r" (ch)
     88                : "i" (SKI_GETCHAR)
     89                : "r15", "r8"
     90        );
     91       
     92        return (wchar_t) ch;
     93}
     94
     95/** Ask keyboard if a key was pressed.
     96 *
     97 * If so, it will repeat and pull up to POLL_LIMIT characters.
     98 */
     99static void poll_keyboard(ski_instance_t *instance)
     100{
     101        if (silent)
     102                return;
     103       
     104        int count = POLL_LIMIT;
     105       
     106        while (count > 0) {
     107                wchar_t ch = ski_getchar();
     108               
     109                if (ch == '\0')
     110                        break;
     111               
     112                indev_push_character(instance->srlnin, ch);
     113                --count;
     114        }
     115}
     116
     117/** Kernel thread for polling keyboard. */
     118static void kskipoll(void *arg)
     119{
     120        ski_instance_t *instance = (ski_instance_t *) arg;
     121       
     122        while (true) {
     123                if (!silent)
     124                        poll_keyboard(instance);
     125               
     126                thread_usleep(POLL_INTERVAL);
     127        }
     128}
    68129
    69130/** Initialize debug console
     
    75136static void ski_init(void)
    76137{
    77         if (initialized)
     138        if (instance)
    78139                return;
    79140       
     
    86147        );
    87148       
    88         initialized = true;
     149        instance = malloc(sizeof(ski_instance_t), FRAME_ATOMIC);
     150       
     151        if (instance) {
     152                instance->thread = thread_create(kskipoll, instance, TASK, 0,
     153                    "kskipoll", true);
     154               
     155                if (!instance->thread) {
     156                        free(instance);
     157                        instance = NULL;
     158                        return;
     159                }
     160               
     161                instance->srlnin = NULL;
     162        }
    89163}
    90164
     
    124198}
    125199
    126 void skiout_init(void)
     200outdev_t *skiout_init(void)
    127201{
    128202        ski_init();
    129        
    130         outdev_initialize("skiout", &skiout, &skiout_ops);
    131         stdout_wire(&skiout);
    132        
    133         sysinfo_set_item_val("fb", NULL, false);
    134 }
    135 
    136 /** Ask debug console if a key was pressed.
    137  *
    138  * Use SSC (Simulator System Call) to
    139  * get character from debug console.
    140  *
    141  * This call is non-blocking.
    142  *
    143  * @return ASCII code of pressed key or 0 if no key pressed.
    144  *
    145  */
    146 static wchar_t ski_getchar(void)
    147 {
    148         uint64_t ch;
    149        
    150         asm volatile (
    151                 "mov r15 = %1\n"
    152                 "break 0x80000;;\n"  /* modifies r8 */
    153                 "mov %0 = r8;;\n"
    154                
    155                 : "=r" (ch)
    156                 : "i" (SKI_GETCHAR)
    157                 : "r15", "r8"
    158         );
    159        
    160         return (wchar_t) ch;
    161 }
    162 
    163 /** Ask keyboard if a key was pressed.
    164  *
    165  * If so, it will repeat and pull up to POLL_LIMIT characters.
    166  */
    167 static void poll_keyboard(ski_instance_t *instance)
    168 {
    169         wchar_t ch;
    170         int count;
    171 
    172         if (kbd_disabled)
    173                 return;
    174 
    175         count = POLL_LIMIT;
    176 
    177         while (count > 0) {
    178                 ch = ski_getchar();
    179 
    180                 if (ch == '\0')
    181                         break;
    182 
    183                 indev_push_character(instance->srlnin, ch);
    184                 --count;
    185         }
    186 }
    187 
    188 /** Kernel thread for polling keyboard. */
    189 static void kskipoll(void *arg)
    190 {
    191         ski_instance_t *instance = (ski_instance_t *) arg;
    192        
    193         while (true) {
    194                 if (!silent)
    195                         poll_keyboard(instance);
    196                
    197                 thread_usleep(POLL_INTERVAL);
    198         }
     203        if (!instance)
     204                return NULL;
     205       
     206        outdev_t *skidev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
     207        if (!skidev)
     208                return NULL;
     209       
     210        outdev_initialize("skidev", skidev, &skidev_ops);
     211        skidev->data = instance;
     212       
     213        if (!fb_exported) {
     214                /*
     215                 * This is the necessary evil until the userspace driver is entirely
     216                 * self-sufficient.
     217                 */
     218                sysinfo_set_item_val("fb", NULL, false);
     219               
     220                fb_exported = true;
     221        }
     222       
     223        return skidev;
    199224}
    200225
     
    202227{
    203228        ski_init();
    204        
    205         ski_instance_t *instance =
    206             malloc(sizeof(ski_instance_t), FRAME_ATOMIC);
    207        
    208         if (instance) {
    209                 instance->thread = thread_create(kskipoll, instance, TASK, 0,
    210                     "kskipoll", true);
    211                
    212                 if (!instance->thread) {
    213                         free(instance);
    214                         return NULL;
    215                 }
    216                
    217                 instance->srlnin = NULL;
    218         }
    219        
    220229        return instance;
    221230}
     
    233242}
    234243
    235 void ski_kbd_grab(void)
    236 {
    237         kbd_disabled = false;
    238 }
    239 
    240 void ski_kbd_release(void)
    241 {
    242         kbd_disabled = true;
    243 }
    244 
    245244/** @}
    246245 */
Note: See TracChangeset for help on using the changeset viewer.