Subversion Repositories HelenOS

Rev

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

Rev 3941 Rev 3959
Line 38... Line 38...
38
#include <genarch/kbd/key.h>
38
#include <genarch/kbd/key.h>
39
#include <genarch/kbd/scanc.h>
39
#include <genarch/kbd/scanc.h>
40
#include <genarch/kbd/scanc_sun.h>
40
#include <genarch/kbd/scanc_sun.h>
41
#include <arch/drivers/kbd.h>
41
#include <arch/drivers/kbd.h>
42
#include <ddi/irq.h>
42
#include <ddi/irq.h>
43
#include <ipc/irq.h>
-
 
44
#include <cpu.h>
43
#include <cpu.h>
45
#include <arch/asm.h>
44
#include <arch/asm.h>
46
#include <arch.h>
45
#include <arch.h>
47
#include <console/chardev.h>
46
#include <console/chardev.h>
48
#include <console/console.h>
47
#include <console/console.h>
Line 52... Line 51...
52
#include <synch/spinlock.h>
51
#include <synch/spinlock.h>
53
#include <mm/slab.h>
52
#include <mm/slab.h>
54
 
53
 
55
#define LSR_DATA_READY  0x01
54
#define LSR_DATA_READY  0x01
56
 
55
 
57
static irq_t *ns16550_irq;
-
 
58
 
-
 
59
/*
56
/*
60
 * These codes read from ns16550 data register are silently ignored.
57
 * These codes read from ns16550 data register are silently ignored.
61
 */
58
 */
62
#define IGNORE_CODE 0x7f        /* all keys up */
59
#define IGNORE_CODE 0x7f        /* all keys up */
63
 
60
 
Line 67... Line 64...
67
static chardev_operations_t ops = {
64
static chardev_operations_t ops = {
68
    .suspend = ns16550_suspend,
65
    .suspend = ns16550_suspend,
69
    .resume = ns16550_resume,
66
    .resume = ns16550_resume,
70
};
67
};
71
 
68
 
72
/** Initialize keyboard and service interrupts using kernel routine */
-
 
73
void ns16550_grab(void)
-
 
74
{
-
 
75
    ipl_t ipl = interrupts_disable();
-
 
76
    spinlock_lock(&ns16550_irq->lock);
-
 
77
    ns16550_irq->notif_cfg.notify = false;
-
 
78
    spinlock_unlock(&ns16550_irq->lock);
-
 
79
    interrupts_restore(ipl);
-
 
80
}
-
 
81
 
-
 
82
/** Resume the former interrupt vector */
-
 
83
void ns16550_release(void)
-
 
84
{
-
 
85
    ipl_t ipl = interrupts_disable();
-
 
86
    spinlock_lock(&ns16550_irq->lock);
-
 
87
    if (ns16550_irq->notif_cfg.answerbox)
-
 
88
        ns16550_irq->notif_cfg.notify = true;
-
 
89
    spinlock_unlock(&ns16550_irq->lock);
-
 
90
    interrupts_restore(ipl);
-
 
91
}
-
 
92
 
-
 
93
/** Initialize ns16550.
69
/** Initialize ns16550.
94
 *
70
 *
95
 * @param dev       Addrress of the beginning of the device in I/O space.
71
 * @param dev       Addrress of the beginning of the device in I/O space.
96
 * @param devno     Device number.
72
 * @param devno     Device number.
97
 * @param inr       Interrupt number.
73
 * @param inr       Interrupt number.
Line 123... Line 99...
123
    instance->irq.instance = instance;
99
    instance->irq.instance = instance;
124
    instance->irq.cir = cir;
100
    instance->irq.cir = cir;
125
    instance->irq.cir_arg = cir_arg;
101
    instance->irq.cir_arg = cir_arg;
126
    irq_register(&instance->irq);
102
    irq_register(&instance->irq);
127
 
103
 
128
    ns16550_irq = &instance->irq;   /* TODO: remove me soon */
-
 
129
   
-
 
130
    while ((pio_read_8(&dev->lsr) & LSR_DATA_READY))
104
    while ((pio_read_8(&dev->lsr) & LSR_DATA_READY))
131
        (void) pio_read_8(&dev->rbr);
105
        (void) pio_read_8(&dev->rbr);
132
   
106
   
-
 
107
    /*
-
 
108
     * This is the necessary evil until the userspace driver is entirely
-
 
109
     * self-sufficient.
-
 
110
     */
133
    sysinfo_set_item_val("kbd", NULL, true);
111
    sysinfo_set_item_val("kbd", NULL, true);
134
    sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
112
    sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
135
    sysinfo_set_item_val("kbd.devno", NULL, devno);
113
    sysinfo_set_item_val("kbd.devno", NULL, devno);
136
    sysinfo_set_item_val("kbd.inr", NULL, inr);
114
    sysinfo_set_item_val("kbd.inr", NULL, inr);
137
    sysinfo_set_item_val("kbd.address.virtual", NULL, (uintptr_t) dev);
115
    sysinfo_set_item_val("kbd.address.virtual", NULL, (uintptr_t) dev);
Line 139... Line 117...
139
   
117
   
140
    /* Enable interrupts */
118
    /* Enable interrupts */
141
    pio_write_8(&dev->ier, IER_ERBFI);
119
    pio_write_8(&dev->ier, IER_ERBFI);
142
    pio_write_8(&dev->mcr, MCR_OUT2);
120
    pio_write_8(&dev->mcr, MCR_OUT2);
143
   
121
   
144
    ns16550_grab();
-
 
145
   
-
 
146
    return true;
122
    return true;
147
}
123
}
148
 
124
 
149
/* Called from getc(). */
125
/* Called from getc(). */
150
void ns16550_resume(chardev_t *d)
126
void ns16550_resume(chardev_t *d)
Line 167... Line 143...
167
        return IRQ_DECLINE;
143
        return IRQ_DECLINE;
168
}
144
}
169
 
145
 
170
void ns16550_irq_handler(irq_t *irq)
146
void ns16550_irq_handler(irq_t *irq)
171
{
147
{
172
    if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) {
-
 
173
        /*
-
 
174
         * This will hopefully go to the IRQ dispatch code soon.
-
 
175
         */
-
 
176
        ipc_irq_send_notif(irq);
-
 
177
        return;
-
 
178
    }
-
 
179
 
-
 
180
    ns16550_instance_t *ns16550_instance = irq->instance;
148
    ns16550_instance_t *ns16550_instance = irq->instance;
181
    ns16550_t *dev = ns16550_instance->ns16550;
149
    ns16550_t *dev = ns16550_instance->ns16550;
182
 
150
 
183
    if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
151
    if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
184
        uint8_t x;
152
        uint8_t x;