Subversion Repositories HelenOS

Rev

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

Rev 1921 Rev 1931
Line 36... Line 36...
36
 
36
 
37
#include <genarch/kbd/ns16550.h>
37
#include <genarch/kbd/ns16550.h>
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/ns16550.h>
42
#include <arch/drivers/ns16550.h>
42
#include <ddi/irq.h>
43
#include <ddi/irq.h>
43
#include <arch/interrupt.h>
44
#include <ipc/irq.h>
44
#include <cpu.h>
45
#include <cpu.h>
45
#include <arch/asm.h>
46
#include <arch/asm.h>
46
#include <arch.h>
47
#include <arch.h>
47
#include <typedefs.h>
48
#include <typedefs.h>
48
#include <console/chardev.h>
49
#include <console/chardev.h>
49
#include <console/console.h>
50
#include <console/console.h>
50
#include <interrupt.h>
51
#include <interrupt.h>
-
 
52
#include <arch/interrupt.h>
51
#include <sysinfo/sysinfo.h>
53
#include <sysinfo/sysinfo.h>
-
 
54
#include <synch/spinlock.h>
52
 
55
 
53
#define LSR_DATA_READY  0x01
56
#define LSR_DATA_READY  0x01
54
 
57
 
55
/** Structure representing the ns16550. */
58
/** Structure representing the ns16550. */
56
static ns16550_t ns16550;
59
static ns16550_t ns16550;
57
 
60
 
58
/** Structure for ns16550's IRQ. */
61
/** Structure for ns16550's IRQ. */
59
static irq_t ns16550_irq;
62
static irq_t ns16550_irq;
60
 
63
 
-
 
64
static ipc_notif_cfg_t saved_notif_cfg;
-
 
65
 
61
/*
66
/*
62
 * These codes read from ns16550 data register are silently ignored.
67
 * These codes read from ns16550 data register are silently ignored.
63
 */
68
 */
64
#define IGNORE_CODE 0x7f        /* all keys up */
69
#define IGNORE_CODE 0x7f        /* all keys up */
65
 
70
 
Line 70... Line 75...
70
    .suspend = ns16550_suspend,
75
    .suspend = ns16550_suspend,
71
    .resume = ns16550_resume,
76
    .resume = ns16550_resume,
72
    .read = ns16550_key_read
77
    .read = ns16550_key_read
73
};
78
};
74
 
79
 
75
void ns16550_interrupt(int n, istate_t *istate);
-
 
76
void ns16550_wait(void);
80
void ns16550_interrupt(void);
77
 
81
 
78
/** Initialize keyboard and service interrupts using kernel routine */
82
/** Initialize keyboard and service interrupts using kernel routine */
79
void ns16550_grab(void)
83
void ns16550_grab(void)
80
{
84
{
-
 
85
    ns16550_ier_write(&ns16550, IER_ERBFI);     /* enable receiver interrupt */
-
 
86
   
-
 
87
    while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY)
-
 
88
        (void) ns16550_rbr_read(&ns16550);
-
 
89
 
-
 
90
    if (ns16550_irq.notif_cfg.answerbox) {
-
 
91
        saved_notif_cfg = ns16550_irq.notif_cfg;
-
 
92
        ns16550_irq.notif_cfg.answerbox = NULL;
-
 
93
        ns16550_irq.notif_cfg.code = NULL;
-
 
94
        ns16550_irq.notif_cfg.method = 0;
-
 
95
        ns16550_irq.notif_cfg.counter = 0;
81
    /* TODO */
96
    }
82
}
97
}
83
 
98
 
84
/** Resume the former interrupt vector */
99
/** Resume the former interrupt vector */
85
void ns16550_release(void)
100
void ns16550_release(void)
86
{
101
{
87
    /* TODO */
102
    if (saved_notif_cfg.answerbox)
-
 
103
        ns16550_irq.notif_cfg = saved_notif_cfg;
88
}
104
}
89
 
105
 
90
/** Initialize ns16550.
106
/** Initialize ns16550.
91
 *
107
 *
92
 * @param devno Device number.
108
 * @param devno Device number.
93
 * @param inr Interrupt number.
109
 * @param inr Interrupt number.
94
 * @param vaddr Virtual address of device's registers.
110
 * @param vaddr Virtual address of device's registers.
95
 */
111
 */
96
void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr)
112
void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr)
97
{
113
{
98
    ns16550_grab();
-
 
99
    chardev_initialize("ns16550_kbd", &kbrd, &ops);
114
    chardev_initialize("ns16550_kbd", &kbrd, &ops);
100
    stdin = &kbrd;
115
    stdin = &kbrd;
101
   
116
   
102
    ns16550.devno = devno;
117
    ns16550.devno = devno;
103
    ns16550.reg = (uint8_t *) vaddr;
118
    ns16550.reg = (uint8_t *) vaddr;
Line 108... Line 123...
108
    ns16550_irq.claim = ns16550_claim;
123
    ns16550_irq.claim = ns16550_claim;
109
    ns16550_irq.handler = ns16550_irq_handler;
124
    ns16550_irq.handler = ns16550_irq_handler;
110
    irq_register(&ns16550_irq);
125
    irq_register(&ns16550_irq);
111
   
126
   
112
    sysinfo_set_item_val("kbd", NULL, true);
127
    sysinfo_set_item_val("kbd", NULL, true);
-
 
128
    sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
113
    sysinfo_set_item_val("kbd.devno", NULL, devno);
129
    sysinfo_set_item_val("kbd.devno", NULL, devno);
114
    sysinfo_set_item_val("kbd.inr", NULL, inr);
130
    sysinfo_set_item_val("kbd.inr", NULL, inr);
115
    sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr);
131
    sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr);
116
   
132
   
117
    ns16550_ier_write(&ns16550, IER_ERBFI);     /* enable receiver interrupt */
-
 
118
   
-
 
119
    while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY)
-
 
120
        (void) ns16550_rbr_read(&ns16550);
133
    ns16550_grab();
121
}
-
 
122
 
-
 
123
/** Process ns16550 interrupt.
-
 
124
 *
-
 
125
 * @param n Interrupt vector.
-
 
126
 * @param istate Interrupted state.
-
 
127
 */
-
 
128
void ns16550_interrupt(int n, istate_t *istate)
-
 
129
{
-
 
130
    /* TODO */
-
 
131
}
134
}
132
 
135
 
133
/** Wait until the controller reads its data. */
136
/** Process ns16550 interrupt. */
134
void ns16550_wait(void)
137
void ns16550_interrupt(void)
135
{
138
{
-
 
139
    /* TODO
-
 
140
     *
-
 
141
     * ns16550 works in the polled mode so far.
-
 
142
     */
136
}
143
}
137
 
144
 
138
/* Called from getc(). */
145
/* Called from getc(). */
139
void ns16550_resume(chardev_t *d)
146
void ns16550_resume(chardev_t *d)
140
{
147
{
Line 168... Line 175...
168
 *
175
 *
169
 * This function can be used to implement keyboard polling.
176
 * This function can be used to implement keyboard polling.
170
 */
177
 */
171
void ns16550_poll(void)
178
void ns16550_poll(void)
172
{
179
{
173
    uint8_t x;
180
    ipl_t ipl;
-
 
181
 
-
 
182
    ipl = interrupts_disable();
-
 
183
    spinlock_lock(&ns16550_irq.lock);
-
 
184
 
-
 
185
    if (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
-
 
186
        if (ns16550_irq.notif_cfg.answerbox) {
-
 
187
            /*
-
 
188
             * Send IPC notification.
-
 
189
             */
-
 
190
            ipc_irq_send_notif(&ns16550_irq);
-
 
191
            spinlock_unlock(&ns16550_irq.lock);
-
 
192
            interrupts_restore(ipl);
-
 
193
            return;
-
 
194
        }
-
 
195
    }
-
 
196
 
-
 
197
    spinlock_unlock(&ns16550_irq.lock);
-
 
198
    interrupts_restore(ipl);
174
 
199
 
175
    while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
200
    while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
-
 
201
        uint8_t x;
-
 
202
       
176
        x = ns16550_rbr_read(&ns16550);
203
        x = ns16550_rbr_read(&ns16550);
177
        if (x != IGNORE_CODE) {
204
        if (x != IGNORE_CODE) {
178
            if (x & KEY_RELEASE)
205
            if (x & KEY_RELEASE)
179
                key_released(x ^ KEY_RELEASE);
206
                key_released(x ^ KEY_RELEASE);
180
            else
207
            else
Line 183... Line 210...
183
    }
210
    }
184
}
211
}
185
 
212
 
186
irq_ownership_t ns16550_claim(void)
213
irq_ownership_t ns16550_claim(void)
187
{
214
{
188
    /* TODO */
-
 
189
    return IRQ_ACCEPT;
215
    return (ns16550_lsr_read(&ns16550) & LSR_DATA_READY);
190
}
216
}
191
 
217
 
192
void ns16550_irq_handler(irq_t *irq, void *arg, ...)
218
void ns16550_irq_handler(irq_t *irq, void *arg, ...)
193
{
219
{
194
    panic("Not yet implemented.\n");
220
    panic("Not yet implemented, ns16550 works in polled mode.\n");
195
}
221
}
196
 
222
 
197
/** @}
223
/** @}
198
 */
224
 */