Subversion Repositories HelenOS

Rev

Rev 3022 | Rev 4296 | 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
 */
33
 */
34
 
34
 
35
#include <arch/drivers/kbd.h>
35
#include <arch/drivers/kbd.h>
36
#include <genarch/ofw/ofw_tree.h>
36
#include <genarch/ofw/ofw_tree.h>
-
 
37
 
-
 
38
#ifdef CONFIG_SUN_KBD
-
 
39
#include <genarch/kbrd/kbrd.h>
-
 
40
#endif
37
#ifdef CONFIG_Z8530
41
#ifdef CONFIG_Z8530
38
#include <genarch/kbd/z8530.h>
42
#include <genarch/drivers/z8530/z8530.h>
39
#endif
43
#endif
40
#ifdef CONFIG_NS16550
44
#ifdef CONFIG_NS16550
41
#include <genarch/kbd/ns16550.h>
45
#include <genarch/drivers/ns16550/ns16550.h>
42
#endif
46
#endif
-
 
47
 
-
 
48
#include <console/console.h>
43
#include <ddi/device.h>
49
#include <ddi/device.h>
44
#include <ddi/irq.h>
50
#include <ddi/irq.h>
45
#include <arch/mm/page.h>
51
#include <arch/mm/page.h>
46
#include <arch/types.h>
52
#include <arch/types.h>
47
#include <align.h>
53
#include <align.h>
48
#include <func.h>
54
#include <string.h>
49
#include <print.h>
55
#include <print.h>
-
 
56
#include <sysinfo/sysinfo.h>
50
 
57
 
51
kbd_type_t kbd_type = KBD_UNKNOWN;
58
kbd_type_t kbd_type = KBD_UNKNOWN;
52
 
59
 
53
/** Initialize keyboard.
60
/** Initialize keyboard.
54
 *
61
 *
Line 61... Line 68...
61
{
68
{
62
    size_t offset;
69
    size_t offset;
63
    uintptr_t aligned_addr;
70
    uintptr_t aligned_addr;
64
    ofw_tree_property_t *prop;
71
    ofw_tree_property_t *prop;
65
    const char *name;
72
    const char *name;
-
 
73
    cir_t cir;
-
 
74
    void *cir_arg;
-
 
75
 
-
 
76
#ifdef CONFIG_NS16550
-
 
77
    ns16550_t *ns16550;
-
 
78
#endif
-
 
79
#ifdef CONFIG_Z8530
-
 
80
    z8530_t *z8530;
-
 
81
#endif
66
   
82
   
67
    name = ofw_tree_node_name(node);
83
    name = ofw_tree_node_name(node);
68
   
84
   
69
    /*
85
    /*
70
     * Determine keyboard serial controller type.
86
     * Determine keyboard serial controller type.
Line 82... Line 98...
82
    /*
98
    /*
83
     * Read 'interrupts' property.
99
     * Read 'interrupts' property.
84
     */
100
     */
85
    uint32_t interrupts;
101
    uint32_t interrupts;
86
    prop = ofw_tree_getprop(node, "interrupts");
102
    prop = ofw_tree_getprop(node, "interrupts");
87
    if (!prop || !prop->value)
103
    if ((!prop) || (!prop->value))
88
        panic("Can't find \"interrupts\" property.\n");
104
        panic("Cannot find 'interrupt' property.");
89
    interrupts = *((uint32_t *) prop->value);
105
    interrupts = *((uint32_t *) prop->value);
90
 
106
   
91
    /*
107
    /*
92
     * Read 'reg' property.
108
     * Read 'reg' property.
93
     */
109
     */
94
    prop = ofw_tree_getprop(node, "reg");
110
    prop = ofw_tree_getprop(node, "reg");
95
    if (!prop || !prop->value)
111
    if ((!prop) || (!prop->value))
96
        panic("Can't find \"reg\" property.\n");
112
        panic("Cannot find 'reg' property.");
97
   
113
   
98
    uintptr_t pa;
114
    uintptr_t pa;
99
    size_t size;
115
    size_t size;
-
 
116
    devno_t devno;
100
    inr_t inr;
117
    inr_t inr;
101
    devno_t devno = device_assign_devno();
-
 
102
   
118
   
103
    switch (kbd_type) {
119
    switch (kbd_type) {
104
    case KBD_Z8530:
120
    case KBD_Z8530:
105
        size = ((ofw_fhc_reg_t *) prop->value)->size;
121
        size = ((ofw_fhc_reg_t *) prop->value)->size;
-
 
122
        if (!ofw_fhc_apply_ranges(node->parent,
106
        if (!ofw_fhc_apply_ranges(node->parent, ((ofw_fhc_reg_t *) prop->value) , &pa)) {
123
            ((ofw_fhc_reg_t *) prop->value), &pa)) {
107
            printf("Failed to determine keyboard address.\n");
124
            printf("Failed to determine keyboard address.\n");
108
            return;
125
            return;
109
        }
126
        }
-
 
127
        if (!ofw_fhc_map_interrupt(node->parent,
110
        if (!ofw_fhc_map_interrupt(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) {
128
            ((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir,
-
 
129
            &cir_arg)) {
111
            printf("Failed to determine keyboard interrupt.\n");
130
            printf("Failed to determine keyboard interrupt.\n");
112
            return;
131
            return;
113
        }
132
        }
114
        break;
133
        break;
115
       
134
       
116
    case KBD_NS16550:
135
    case KBD_NS16550:
117
        size = ((ofw_ebus_reg_t *) prop->value)->size;
136
        size = ((ofw_ebus_reg_t *) prop->value)->size;
-
 
137
        if (!ofw_ebus_apply_ranges(node->parent,
118
        if (!ofw_ebus_apply_ranges(node->parent, ((ofw_ebus_reg_t *) prop->value) , &pa)) {
138
            ((ofw_ebus_reg_t *) prop->value), &pa)) {
119
            printf("Failed to determine keyboard address.\n");
139
            printf("Failed to determine keyboard address.\n");
120
            return;
140
            return;
121
        }
141
        }
-
 
142
        if (!ofw_ebus_map_interrupt(node->parent,
122
        if (!ofw_ebus_map_interrupt(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) {
143
            ((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir,
-
 
144
            &cir_arg)) {
123
            printf("Failed to determine keyboard interrupt.\n");
145
            printf("Failed to determine keyboard interrupt.\n");
124
            return;
146
            return;
125
        };
147
        };
126
        break;
148
        break;
127
 
-
 
128
    default:
149
    default:
129
        panic("Unexpected type.\n");
150
        panic("Unexpected keyboard type.");
130
    }
151
    }
131
   
152
   
132
    /*
153
    /*
133
     * We need to pass aligned address to hw_map().
154
     * We need to pass aligned address to hw_map().
134
     * However, the physical keyboard address can
155
     * However, the physical keyboard address can
135
     * be pretty much unaligned, depending on the
156
     * be pretty much unaligned, depending on the
136
     * underlying controller.
157
     * underlying controller.
137
     */
158
     */
138
    aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
159
    aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
139
    offset = pa - aligned_addr;
160
    offset = pa - aligned_addr;
140
    uintptr_t vaddr = hw_map(aligned_addr, offset + size) + offset;
-
 
141
 
161
   
142
    switch (kbd_type) {
162
    switch (kbd_type) {
143
#ifdef CONFIG_Z8530
163
#ifdef CONFIG_Z8530
144
    case KBD_Z8530:
164
    case KBD_Z8530:
-
 
165
        devno = device_assign_devno();
-
 
166
        z8530 = (z8530_t *) hw_map(aligned_addr, offset + size) +
-
 
167
            offset;
-
 
168
        kbrd_init(stdin);
145
        z8530_init(devno, inr, vaddr);
169
        (void) z8530_init(z8530, devno, inr, cir, cir_arg, &kbrdin);
-
 
170
       
-
 
171
        /*
-
 
172
         * This is the necessary evil until the userspace drivers are
-
 
173
         * entirely self-sufficient.
-
 
174
         */
-
 
175
        sysinfo_set_item_val("kbd", NULL, true);
-
 
176
        sysinfo_set_item_val("kbd.type", NULL, KBD_Z8530);
-
 
177
        sysinfo_set_item_val("kbd.devno", NULL, devno);
-
 
178
        sysinfo_set_item_val("kbd.inr", NULL, inr);
-
 
179
        sysinfo_set_item_val("kbd.address.kernel", NULL,
-
 
180
            (uintptr_t) z8530);
-
 
181
        sysinfo_set_item_val("kbd.address.physical", NULL, pa);
146
        break;
182
        break;
147
#endif
183
#endif
148
#ifdef CONFIG_NS16550
184
#ifdef CONFIG_NS16550
149
    case KBD_NS16550:
185
    case KBD_NS16550:
-
 
186
        devno = device_assign_devno();
-
 
187
        ns16550 = (ns16550_t *) hw_map(aligned_addr, offset + size) +
-
 
188
            offset;
-
 
189
        kbrd_init(stdin);
150
        ns16550_init(devno, inr, vaddr);
190
        (void) ns16550_init(ns16550, devno, inr, cir, cir_arg, &kbrdin);
-
 
191
       
-
 
192
        /*
-
 
193
         * This is the necessary evil until the userspace driver is
-
 
194
         * entirely self-sufficient.
-
 
195
         */
-
 
196
        sysinfo_set_item_val("kbd", NULL, true);
-
 
197
        sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
-
 
198
        sysinfo_set_item_val("kbd.devno", NULL, devno);
-
 
199
        sysinfo_set_item_val("kbd.inr", NULL, inr);
-
 
200
        sysinfo_set_item_val("kbd.address.kernel", NULL,
-
 
201
            (uintptr_t) ns16550);
-
 
202
        sysinfo_set_item_val("kbd.address.physical", NULL, pa);
151
        break;
203
        break;
152
#endif
204
#endif
153
    default:
205
    default:
154
        printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n");
206
        printf("Kernel is not compiled with the necessary keyboard "
-
 
207
            "driver this machine requires.\n");
155
    }
208
    }
156
}
209
}
157
 
210
 
158
/** @}
211
/** @}
159
 */
212
 */