Subversion Repositories HelenOS

Rev

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

Rev 3022 Rev 4055
Line 32... Line 32...
32
/** @file
32
/** @file
33
 *  @brief GXemul drivers.
33
 *  @brief GXemul drivers.
34
 */
34
 */
35
 
35
 
36
#include <interrupt.h>
36
#include <interrupt.h>
37
#include <ipc/irq.h>
-
 
38
#include <console/chardev.h>
37
#include <console/chardev.h>
39
#include <arch/drivers/gxemul.h>
38
#include <arch/drivers/gxemul.h>
40
#include <console/console.h>
39
#include <console/console.h>
41
#include <sysinfo/sysinfo.h>
40
#include <sysinfo/sysinfo.h>
42
#include <print.h>
41
#include <print.h>
Line 70... Line 69...
70
 
69
 
71
static bool hw_map_init_called = false;
70
static bool hw_map_init_called = false;
72
 
71
 
73
static void gxemul_kbd_enable(chardev_t *dev);
72
static void gxemul_kbd_enable(chardev_t *dev);
74
static void gxemul_kbd_disable(chardev_t *dev);
73
static void gxemul_kbd_disable(chardev_t *dev);
75
static void gxemul_write(chardev_t *dev, const char ch);
74
static void gxemul_write(chardev_t *dev, const char ch, bool silent);
76
static char gxemul_do_read(chardev_t *dev);
75
static char gxemul_do_read(chardev_t *dev);
77
 
76
 
78
static chardev_operations_t gxemul_ops = {
77
static chardev_operations_t gxemul_ops = {
79
    .resume = gxemul_kbd_enable,
78
    .resume = gxemul_kbd_enable,
80
    .suspend = gxemul_kbd_disable,
79
    .suspend = gxemul_kbd_disable,
Line 131... Line 130...
131
/** Putchar that works with gxemul.
130
/** Putchar that works with gxemul.
132
 *
131
 *
133
 * @param dev Not used.
132
 * @param dev Not used.
134
 * @param ch Characted to be printed.
133
 * @param ch Characted to be printed.
135
 */
134
 */
136
static void gxemul_write(chardev_t *dev, const char ch)
135
static void gxemul_write(chardev_t *dev, const char ch, bool silent)
137
{
136
{
-
 
137
    if (!silent)
138
    *((char *) gxemul_hw_map.videoram) = ch;
138
        *((char *) gxemul_hw_map.videoram) = ch;
139
}
139
}
140
 
140
 
141
/** Enables gxemul keyboard (interrupt unmasked).
141
/** Enables gxemul keyboard (interrupt unmasked).
142
 *
142
 *
143
 * @param dev Not used.
143
 * @param dev Not used.
Line 181... Line 181...
181
}
181
}
182
 
182
 
183
/** Process keyboard interrupt.
183
/** Process keyboard interrupt.
184
 *  
184
 *  
185
 *  @param irq IRQ information.
185
 *  @param irq IRQ information.
186
 *  @param arg Not used.
-
 
187
 */
186
 */
188
static void gxemul_irq_handler(irq_t *irq, void *arg, ...)
187
static void gxemul_irq_handler(irq_t *irq)
189
{
188
{
190
    if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) {
-
 
191
        ipc_irq_send_notif(irq);
-
 
192
    } else {
-
 
193
        char ch = 0;
189
    char ch = 0;
194
       
190
       
195
        ch = *((char *) gxemul_hw_map.kbd);
191
    ch = *((char *) gxemul_hw_map.kbd);
196
        if (ch == '\r') {
192
    if (ch == '\r') {
197
            ch = '\n';
193
        ch = '\n';
198
        }
-
 
199
        if (ch == 0x7f) {
-
 
200
            ch = '\b';
-
 
201
        }
-
 
202
        chardev_push_character(&console, ch);
-
 
203
    }
194
    }
-
 
195
    if (ch == 0x7f) {
-
 
196
        ch = '\b';
-
 
197
    }
-
 
198
    chardev_push_character(&console, ch);
204
}
199
}
205
 
200
 
206
static irq_ownership_t gxemul_claim(void)
201
static irq_ownership_t gxemul_claim(irq_t *irq)
207
{
202
{
208
    return IRQ_ACCEPT;
203
    return IRQ_ACCEPT;
209
}
204
}
210
 
205
 
211
 
-
 
212
/** Acquire console back for kernel. */
-
 
213
void gxemul_grab_console(void)
-
 
214
{
-
 
215
    ipl_t ipl = interrupts_disable();
-
 
216
    spinlock_lock(&gxemul_console_irq.lock);
-
 
217
    gxemul_console_irq.notif_cfg.notify = false;
-
 
218
    spinlock_unlock(&gxemul_console_irq.lock);
-
 
219
    interrupts_restore(ipl);
-
 
220
}
-
 
221
 
-
 
222
/** Return console to userspace. */
-
 
223
void gxemul_release_console(void)
-
 
224
{
-
 
225
    ipl_t ipl = interrupts_disable();
-
 
226
    spinlock_lock(&gxemul_console_irq.lock);
-
 
227
    if (gxemul_console_irq.notif_cfg.answerbox) {
-
 
228
        gxemul_console_irq.notif_cfg.notify = true;
-
 
229
    }
-
 
230
    spinlock_unlock(&gxemul_console_irq.lock);
-
 
231
    interrupts_restore(ipl);
-
 
232
}
-
 
233
 
-
 
234
/** Initializes console object representing gxemul console.
206
/** Initializes console object representing gxemul console.
235
 *
207
 *
236
 *  @param devno device number.
208
 *  @param devno device number.
237
 */
209
 */
238
void gxemul_console_init(devno_t devno)
210
void gxemul_console_init(devno_t devno)
Line 263... Line 235...
263
static void gxemul_timer_start(uint32_t frequency)
235
static void gxemul_timer_start(uint32_t frequency)
264
{
236
{
265
    *((uint32_t*) gxemul_hw_map.rtc_freq) = frequency;
237
    *((uint32_t*) gxemul_hw_map.rtc_freq) = frequency;
266
}
238
}
267
 
239
 
268
static irq_ownership_t gxemul_timer_claim(void)
240
static irq_ownership_t gxemul_timer_claim(irq_t *irq)
269
{
241
{
270
    return IRQ_ACCEPT;
242
    return IRQ_ACCEPT;
271
}
243
}
272
 
244
 
273
/** Timer interrupt handler.
245
/** Timer interrupt handler.
274
 *
246
 *
275
 * @param irq Interrupt information.
247
 * @param irq Interrupt information.
276
 * @param arg Not used.
248
 * @param arg Not used.
277
 */
249
 */
278
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...)
250
static void gxemul_timer_irq_handler(irq_t *irq)
279
{
251
{
280
    /*
252
    /*
281
    * We are holding a lock which prevents preemption.
253
    * We are holding a lock which prevents preemption.
282
    * Release the lock, call clock() and reacquire the lock again.
254
    * Release the lock, call clock() and reacquire the lock again.
283
    */
255
    */
Line 367... Line 339...
367
    for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
339
    for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
368
        if (sources & (1 << i)) {
340
        if (sources & (1 << i)) {
369
            irq_t *irq = irq_dispatch_and_lock(i);
341
            irq_t *irq = irq_dispatch_and_lock(i);
370
            if (irq) {
342
            if (irq) {
371
                /* The IRQ handler was found. */
343
                /* The IRQ handler was found. */
372
                irq->handler(irq, irq->arg);
344
                irq->handler(irq);
373
                spinlock_unlock(&irq->lock);
345
                spinlock_unlock(&irq->lock);
374
            } else {
346
            } else {
375
                /* Spurious interrupt.*/
347
                /* Spurious interrupt.*/
376
                dprintf("cpu%d: spurious interrupt (inum=%d)\n",
348
                dprintf("cpu%d: spurious interrupt (inum=%d)\n",
377
                    CPU->id, i);
349
                    CPU->id, i);