Subversion Repositories HelenOS

Rev

Rev 4220 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4220 Rev 4223
1
/*
1
/*
2
 * Copyright (c) 2005 Jakub Jermar
2
 * Copyright (c) 2005 Jakub Jermar
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
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
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.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup ia64   
29
/** @addtogroup ia64
30
 * @{
30
 * @{
31
 */
31
 */
32
/** @file
32
/** @file
33
 */
33
 */
34
 
34
 
35
#include <arch/ski/ski.h>
35
#include <arch/ski/ski.h>
36
#include <console/console.h>
36
#include <console/console.h>
37
#include <console/chardev.h>
37
#include <console/chardev.h>
38
#include <sysinfo/sysinfo.h>
38
#include <sysinfo/sysinfo.h>
39
#include <arch/types.h>
39
#include <arch/types.h>
40
#include <proc/thread.h>
40
#include <proc/thread.h>
41
#include <synch/spinlock.h>
41
#include <synch/spinlock.h>
42
#include <arch/asm.h>
42
#include <arch/asm.h>
43
#include <arch/drivers/kbd.h>
43
#include <arch/drivers/kbd.h>
44
#include <string.h>
44
#include <string.h>
45
#include <arch.h>
45
#include <arch.h>
46
 
46
 
47
static indev_t skiin;       /**< Ski input device. */
47
static indev_t skiin;       /**< Ski input device. */
48
static outdev_t skiout;     /**< Ski output device. */
48
static outdev_t skiout;     /**< Ski output device. */
49
 
49
 
50
static bool kbd_disabled;
50
static bool kbd_disabled;
51
 
51
 
52
static void ski_do_putchar(const wchar_t ch)
52
static void ski_do_putchar(const wchar_t ch)
53
{
53
{
54
    asm volatile (
54
    asm volatile (
55
        "mov r15 = %[cmd]\n"
55
        "mov r15 = %[cmd]\n"
56
        "mov r32 = %[ch]\n"   /* r32 is in0 */
56
        "mov r32 = %[ch]\n"   /* r32 is in0 */
57
        "break 0x80000\n"  /* modifies r8 */
57
        "break 0x80000\n"  /* modifies r8 */
58
        :
58
        :
59
        : [cmd] "i" (SKI_PUTCHAR), [ch] "r" (ch)
59
        : [cmd] "i" (SKI_PUTCHAR), [ch] "r" (ch)
60
        : "r15", "in0", "r8"
60
        : "r15", "in0", "r8"
61
    );
61
    );
62
}
62
}
63
 
63
 
64
/** Display character on debug console
64
/** Display character on debug console
65
 *
65
 *
66
 * Use SSC (Simulator System Call) to
66
 * Use SSC (Simulator System Call) to
67
 * display character on debug console.
67
 * display character on debug console.
68
 *
68
 *
69
 * @param d Character device.
69
 * @param d Character device.
70
 * @param ch Character to be printed.
70
 * @param ch Character to be printed.
71
 */
71
 */
72
static void ski_putchar(outdev_t *d, const wchar_t ch, bool silent)
72
static void ski_putchar(outdev_t *d, const wchar_t ch, bool silent)
73
{
73
{
74
    if (!silent) {
74
    if (!silent) {
75
        if (ascii_check(ch)) {
75
        if (ascii_check(ch)) {
76
            if (ch == '\n')
76
            if (ch == '\n')
77
                ski_do_putchar('\r');
77
                ski_do_putchar('\r');
78
           
78
           
79
            ski_do_putchar(ch);
79
            ski_do_putchar(ch);
80
        } else
80
        } else
81
            ski_do_putchar(invalch);
81
            ski_do_putchar(SPECIAL);
82
    }
82
    }
83
}
83
}
84
 
84
 
85
static indev_operations_t skiin_ops = {
85
static indev_operations_t skiin_ops = {
86
    .poll = NULL
86
    .poll = NULL
87
};
87
};
88
 
88
 
89
static outdev_operations_t skiout_ops = {
89
static outdev_operations_t skiout_ops = {
90
    .write = ski_putchar
90
    .write = ski_putchar
91
};
91
};
92
 
92
 
93
/** Ask debug console if a key was pressed.
93
/** Ask debug console if a key was pressed.
94
 *
94
 *
95
 * Use SSC (Simulator System Call) to
95
 * Use SSC (Simulator System Call) to
96
 * get character from debug console.
96
 * get character from debug console.
97
 *
97
 *
98
 * This call is non-blocking.
98
 * This call is non-blocking.
99
 *
99
 *
100
 * @return ASCII code of pressed key or 0 if no key pressed.
100
 * @return ASCII code of pressed key or 0 if no key pressed.
101
 */
101
 */
102
static int32_t ski_getchar(void)
102
static int32_t ski_getchar(void)
103
{
103
{
104
    uint64_t ch;
104
    uint64_t ch;
105
   
105
   
106
    asm volatile (
106
    asm volatile (
107
        "mov r15 = %1\n"
107
        "mov r15 = %1\n"
108
        "break 0x80000;;\n" /* modifies r8 */
108
        "break 0x80000;;\n" /* modifies r8 */
109
        "mov %0 = r8;;\n"      
109
        "mov %0 = r8;;\n"      
110
 
110
 
111
        : "=r" (ch)
111
        : "=r" (ch)
112
        : "i" (SKI_GETCHAR)
112
        : "i" (SKI_GETCHAR)
113
        : "r15", "r8"
113
        : "r15", "r8"
114
    );
114
    );
115
 
115
 
116
    return (int32_t) ch;
116
    return (int32_t) ch;
117
}
117
}
118
 
118
 
119
/** Ask keyboard if a key was pressed. */
119
/** Ask keyboard if a key was pressed. */
120
static void poll_keyboard(void)
120
static void poll_keyboard(void)
121
{
121
{
122
    char ch;
122
    char ch;
123
   
123
   
124
    if (kbd_disabled)
124
    if (kbd_disabled)
125
        return;
125
        return;
126
    ch = ski_getchar();
126
    ch = ski_getchar();
127
    if(ch == '\r')
127
    if(ch == '\r')
128
        ch = '\n';
128
        ch = '\n';
129
    if (ch) {
129
    if (ch) {
130
        indev_push_character(&skiin, ch);
130
        indev_push_character(&skiin, ch);
131
        return;
131
        return;
132
    }
132
    }
133
}
133
}
134
 
134
 
135
#define POLL_INTERVAL           10000           /* 10 ms */
135
#define POLL_INTERVAL           10000           /* 10 ms */
136
 
136
 
137
/** Kernel thread for polling keyboard. */
137
/** Kernel thread for polling keyboard. */
138
static void kkbdpoll(void *arg)
138
static void kkbdpoll(void *arg)
139
{
139
{
140
    while (1) {
140
    while (1) {
141
        if (!silent) {
141
        if (!silent) {
142
            poll_keyboard();
142
            poll_keyboard();
143
        }
143
        }
144
        thread_usleep(POLL_INTERVAL);
144
        thread_usleep(POLL_INTERVAL);
145
    }
145
    }
146
}
146
}
147
 
147
 
148
/** Initialize debug console
148
/** Initialize debug console
149
 *
149
 *
150
 * Issue SSC (Simulator System Call) to
150
 * Issue SSC (Simulator System Call) to
151
 * to open debug console.
151
 * to open debug console.
152
 */
152
 */
153
static void ski_init(void)
153
static void ski_init(void)
154
{
154
{
155
    static bool initialized;
155
    static bool initialized;
156
 
156
 
157
    if (initialized)
157
    if (initialized)
158
        return;
158
        return;
159
   
159
   
160
    asm volatile (
160
    asm volatile (
161
        "mov r15 = %0\n"
161
        "mov r15 = %0\n"
162
        "break 0x80000\n"
162
        "break 0x80000\n"
163
        :
163
        :
164
        : "i" (SKI_INIT_CONSOLE)
164
        : "i" (SKI_INIT_CONSOLE)
165
        : "r15", "r8"
165
        : "r15", "r8"
166
    );
166
    );
167
   
167
   
168
    initialized = true;
168
    initialized = true;
169
}
169
}
170
 
170
 
171
indev_t *skiin_init(void)
171
indev_t *skiin_init(void)
172
{
172
{
173
    ski_init();
173
    ski_init();
174
 
174
 
175
    indev_initialize("skiin", &skiin, &skiin_ops);
175
    indev_initialize("skiin", &skiin, &skiin_ops);
176
    thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
176
    thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
177
    if (t)
177
    if (t)
178
        thread_ready(t);
178
        thread_ready(t);
179
    else
179
    else
180
        return NULL;
180
        return NULL;
181
 
181
 
182
    sysinfo_set_item_val("kbd", NULL, true);
182
    sysinfo_set_item_val("kbd", NULL, true);
183
    sysinfo_set_item_val("kbd.type", NULL, KBD_SKI);
183
    sysinfo_set_item_val("kbd.type", NULL, KBD_SKI);
184
 
184
 
185
    return &skiin;
185
    return &skiin;
186
}
186
}
187
 
187
 
188
 
188
 
189
void skiout_init(void)
189
void skiout_init(void)
190
{
190
{
191
    ski_init();
191
    ski_init();
192
 
192
 
193
    outdev_initialize("skiout", &skiout, &skiout_ops);
193
    outdev_initialize("skiout", &skiout, &skiout_ops);
194
    stdout = &skiout;
194
    stdout = &skiout;
195
 
195
 
196
    sysinfo_set_item_val("fb", NULL, false);
196
    sysinfo_set_item_val("fb", NULL, false);
197
}
197
}
198
 
198
 
199
void ski_kbd_grab(void)
199
void ski_kbd_grab(void)
200
{
200
{
201
    kbd_disabled = true;
201
    kbd_disabled = true;
202
}
202
}
203
 
203
 
204
void ski_kbd_release(void)
204
void ski_kbd_release(void)
205
{
205
{
206
    kbd_disabled = false;
206
    kbd_disabled = false;
207
}
207
}
208
 
208
 
209
/** @}
209
/** @}
210
 */
210
 */
211
 
211