Subversion Repositories HelenOS

Rev

Rev 4346 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4346 Rev 4348
Line 29... Line 29...
29
/** @addtogroup sparc64
29
/** @addtogroup sparc64
30
 * @{
30
 * @{
31
 */
31
 */
32
/**
32
/**
33
 * @file
33
 * @file
34
 * @brief   SGCN driver.
34
 * @brief SGCN driver.
35
 */
35
 */
36
 
36
 
37
#include <arch.h>
37
#include <arch.h>
38
#include <arch/drivers/sgcn.h>
38
#include <arch/drivers/sgcn.h>
39
#include <arch/drivers/kbd.h>
39
#include <arch/drivers/kbd.h>
Line 99... Line 99...
99
    ((type *) (sgcn_buffer_begin + (offset)))
99
    ((type *) (sgcn_buffer_begin + (offset)))
100
 
100
 
101
/** Returns a pointer to the console buffer header. */
101
/** Returns a pointer to the console buffer header. */
102
#define SGCN_BUFFER_HEADER  (SGCN_BUFFER(sgcn_buffer_header_t, 0))
102
#define SGCN_BUFFER_HEADER  (SGCN_BUFFER(sgcn_buffer_header_t, 0))
103
 
103
 
104
/** defined in drivers/kbd.c */
-
 
105
extern kbd_type_t kbd_type;
-
 
106
 
-
 
107
/** starting address of SRAM, will be set by the init_sram_begin function */
104
/** starting address of SRAM, will be set by the init_sram_begin function */
108
static uintptr_t sram_begin;
105
static uintptr_t sram_begin;
109
 
106
 
110
/**
107
/**
111
 * starting address of the SGCN buffer, will be set by the
108
 * starting address of the SGCN buffer, will be set by the
Line 128... Line 125...
128
 */
125
 */
129
SPINLOCK_INITIALIZE(sgcn_input_lock);
126
SPINLOCK_INITIALIZE(sgcn_input_lock);
130
 
127
 
131
 
128
 
132
/* functions referenced from definitions of I/O operations structures */
129
/* functions referenced from definitions of I/O operations structures */
133
static void sgcn_putchar(outdev_t *, const char, bool);
130
static void sgcn_putchar(outdev_t *, const wchar_t, bool);
134
 
131
 
135
/** SGCN output device operations */
132
/** SGCN output device operations */
136
static outdev_operations_t sgcnout_ops = {
133
static outdev_operations_t sgcnout_ops = {
137
    .write = sgcn_putchar
134
    .write = sgcn_putchar
138
};
135
};
139
 
136
 
140
/** SGCN input device operations */
-
 
141
static indev_operations_t sgcnin_ops = {
-
 
142
    .poll = NULL
-
 
143
};
-
 
144
 
-
 
145
static indev_t sgcnin;      /**< SGCN input device. */
-
 
146
static outdev_t sgcnout;    /**< SGCN output device. */
137
static outdev_t sgcnout;    /**< SGCN output device. */
147
 
138
 
148
/**
139
/**
149
 * Set some sysinfo values (SRAM address and SRAM size).
140
 * Set some sysinfo values (SRAM address and SRAM size).
150
 */
141
 */
Line 205... Line 196...
205
    if (initialized)
196
    if (initialized)
206
        return;
197
        return;
207
 
198
 
208
    init_sram_begin();
199
    init_sram_begin();
209
       
200
       
210
    ASSERT(strcmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
201
    ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
211
   
202
   
212
    /* lookup TOC entry with the correct key */
203
    /* lookup TOC entry with the correct key */
213
    uint32_t i;
204
    uint32_t i;
214
    for (i = 0; i < MAX_TOC_ENTRIES; i++) {
205
    for (i = 0; i < MAX_TOC_ENTRIES; i++) {
215
        if (strcmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
206
        if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
216
            break;
207
            break;
217
    }
208
    }
218
    ASSERT(i < MAX_TOC_ENTRIES);
209
    ASSERT(i < MAX_TOC_ENTRIES);
219
   
210
   
220
    sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset;
211
    sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset;
Line 262... Line 253...
262
    *buf_ptr = c;
253
    *buf_ptr = c;
263
    *out_wrptr_ptr = new_wrptr;
254
    *out_wrptr_ptr = new_wrptr;
264
}
255
}
265
 
256
 
266
/**
257
/**
267
 * SGCN output operation. Prints a single character to the SGCN. If the line
258
 * SGCN output operation. Prints a single character to the SGCN. Newline
268
 * feed character is written ('\n'), the carriage return character ('\r') is
-
 
269
 * written straight away.
259
 * character is converted to CRLF.
270
 */
260
 */
271
static void sgcn_putchar(outdev_t *od, const char c, bool silent)
261
static void sgcn_putchar(outdev_t *od, const wchar_t ch, bool silent)
272
{
262
{
273
    if (!silent) {
263
    if (!silent) {
274
        spinlock_lock(&sgcn_output_lock);
264
        spinlock_lock(&sgcn_output_lock);
275
       
265
       
276
        sgcn_do_putchar(c);
266
        if (ascii_check(ch)) {
277
        if (c == '\n')
267
            if (ch == '\n')
278
            sgcn_do_putchar('\r');
268
                sgcn_do_putchar('\r');
-
 
269
            sgcn_do_putchar(ch);
-
 
270
        } else
-
 
271
            sgcn_do_putchar(U_SPECIAL);
279
       
272
       
280
        spinlock_unlock(&sgcn_output_lock);
273
        spinlock_unlock(&sgcn_output_lock);
281
    }
274
    }
282
}
275
}
283
 
276
 
284
/**
277
/**
285
 * Grabs the input for kernel.
278
 * Grabs the input for kernel.
286
 */
279
 */
287
void sgcn_grab(void)
280
void sgcn_grab(void)
288
{
281
{
289
    kbd_disabled = true;
282
    kbd_disabled = false;
290
}
283
}
291
 
284
 
292
/**
285
/**
293
 * Releases the input so that userspace can use it.
286
 * Releases the input so that userspace can use it.
294
 */
287
 */
Line 300... Line 293...
300
/**
293
/**
301
 * Function regularly called by the keyboard polling thread. Finds out whether
294
 * Function regularly called by the keyboard polling thread. Finds out whether
302
 * there are some unread characters in the input queue. If so, it picks them up
295
 * there are some unread characters in the input queue. If so, it picks them up
303
 * and sends them to the upper layers of HelenOS.
296
 * and sends them to the upper layers of HelenOS.
304
 */
297
 */
305
static void sgcn_poll()
298
static void sgcn_poll(sgcn_instance_t *instance)
306
{
299
{
307
    uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
300
    uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
308
    uint32_t end = SGCN_BUFFER_HEADER->in_end;
301
    uint32_t end = SGCN_BUFFER_HEADER->in_end;
309
    uint32_t size = end - begin;
302
    uint32_t size = end - begin;
310
 
303
 
Line 318... Line 311...
318
        SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
311
        SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
319
    volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
312
    volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
320
    volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
313
    volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
321
   
314
   
322
    while (*in_rdptr_ptr != *in_wrptr_ptr) {
315
    while (*in_rdptr_ptr != *in_wrptr_ptr) {
323
       
-
 
324
        buf_ptr = (volatile char *)
316
        buf_ptr = (volatile char *)
325
            SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
317
            SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
326
        char c = *buf_ptr;
318
        char c = *buf_ptr;
327
        *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
319
        *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
328
           
320
           
329
        indev_push_character(&sgcnin, c);  
321
        indev_push_character(instance->srlnin, c); 
330
    }  
322
    }  
331
 
323
 
332
    spinlock_unlock(&sgcn_input_lock);
324
    spinlock_unlock(&sgcn_input_lock);
333
}
325
}
334
 
326
 
335
/**
327
/**
336
 * Polling thread function.
328
 * Polling thread function.
337
 */
329
 */
338
static void kkbdpoll(void *arg) {
330
static void ksgcnpoll(void *instance) {
339
    while (1) {
331
    while (1) {
340
        if (!silent) {
332
        if (!silent)
341
            sgcn_poll();
333
            sgcn_poll(instance);
342
        }
-
 
343
        thread_usleep(POLL_INTERVAL);
334
        thread_usleep(POLL_INTERVAL);
344
    }
335
    }
345
}
336
}
346
 
337
 
347
/**
338
/**
348
 * A public function which initializes input from the Serengeti console.
339
 * A public function which initializes input from the Serengeti console.
349
 */
340
 */
350
indev_t *sgcnin_init(void)
341
sgcn_instance_t *sgcnin_init(void)
351
{
342
{
352
    sgcn_buffer_begin_init();
343
    sgcn_buffer_begin_init();
-
 
344
   
-
 
345
    sgcn_instance_t *instance =
-
 
346
        malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC);
-
 
347
   
-
 
348
    if (instance) {
-
 
349
        instance->srlnin = NULL;
-
 
350
        instance->thread = thread_create(ksgcnpoll, instance, TASK, 0,
-
 
351
            "ksgcnpoll", true);
-
 
352
       
-
 
353
        if (!instance->thread) {
-
 
354
            free(instance);
-
 
355
            return NULL;
-
 
356
        }
-
 
357
    }
-
 
358
   
-
 
359
    return instance;
-
 
360
}
353
 
361
 
354
    kbd_type = KBD_SGCN;
362
void sgcnin_wire(sgcn_instance_t *instance, indev_t *srlnin)
355
 
363
{
356
    sysinfo_set_item_val("kbd", NULL, true);
364
    ASSERT(instance);
357
    sysinfo_set_item_val("kbd.type", NULL, KBD_SGCN);
365
    ASSERT(srlnin);
358
 
366
 
359
    thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
-
 
360
    if (!t)
-
 
361
        panic("Cannot create kkbdpoll.");
367
    instance->srlnin = srlnin;
362
    thread_ready(t);
368
    thread_ready(instance->thread);
363
   
-
 
364
    indev_initialize("sgcnin", &sgcnin, &sgcnin_ops);
-
 
365
 
369
 
366
    return &sgcnin;
370
    sysinfo_set_item_val("kbd", NULL, true);
367
}
371
}
368
 
372
 
369
/**
373
/**
370
 * A public function which initializes output to the Serengeti console.
374
 * A public function which initializes output to the Serengeti console.
371
 */
375
 */