Subversion Repositories HelenOS

Rev

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

Rev 3386 Rev 4153
Line 24... Line 24...
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup sparc64
29
/** @addtogroup sparc64
30
 * @{
30
 * @{
31
 */
31
 */
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
 
43
#include <ddi/device.h>
48
#include <console/console.h>
44
#include <ddi/irq.h>
49
#include <ddi/irq.h>
45
#include <arch/mm/page.h>
50
#include <arch/mm/page.h>
46
#include <arch/types.h>
51
#include <arch/types.h>
47
#include <align.h>
52
#include <align.h>
48
#include <func.h>
53
#include <string.h>
49
#include <print.h>
54
#include <print.h>
-
 
55
#include <sysinfo/sysinfo.h>
50
 
56
 
51
kbd_type_t kbd_type = KBD_UNKNOWN;
57
kbd_type_t kbd_type = KBD_UNKNOWN;
52
 
58
 
-
 
59
#ifdef CONFIG_SUN_KBD
-
 
60
 
53
/** Initialize keyboard.
61
/** Initialize keyboard.
54
 *
62
 *
55
 * Traverse OpenFirmware device tree in order to find necessary
63
 * Traverse OpenFirmware device tree in order to find necessary
56
 * info about the keyboard device.
64
 * info about the keyboard device.
57
 *
65
 *
Line 61... Line 69...
61
{
69
{
62
    size_t offset;
70
    size_t offset;
63
    uintptr_t aligned_addr;
71
    uintptr_t aligned_addr;
64
    ofw_tree_property_t *prop;
72
    ofw_tree_property_t *prop;
65
    const char *name;
73
    const char *name;
-
 
74
    cir_t cir;
-
 
75
    void *cir_arg;
-
 
76
   
-
 
77
#ifdef CONFIG_NS16550
-
 
78
    ns16550_t *ns16550;
-
 
79
#endif
-
 
80
#ifdef CONFIG_Z8530
-
 
81
    z8530_t *z8530;
-
 
82
#endif
66
   
83
   
67
    name = ofw_tree_node_name(node);
84
    name = ofw_tree_node_name(node);
68
   
85
   
69
    /*
86
    /*
70
     * Determine keyboard serial controller type.
87
     * Determine keyboard serial controller type.
Line 82... Line 99...
82
    /*
99
    /*
83
     * Read 'interrupts' property.
100
     * Read 'interrupts' property.
84
     */
101
     */
85
    uint32_t interrupts;
102
    uint32_t interrupts;
86
    prop = ofw_tree_getprop(node, "interrupts");
103
    prop = ofw_tree_getprop(node, "interrupts");
87
    if (!prop || !prop->value)
104
    if ((!prop) || (!prop->value))
88
        panic("Can't find \"interrupts\" property.\n");
105
        panic("Cannot find 'interrupt' property.");
89
    interrupts = *((uint32_t *) prop->value);
106
    interrupts = *((uint32_t *) prop->value);
90
 
107
   
91
    /*
108
    /*
92
     * Read 'reg' property.
109
     * Read 'reg' property.
93
     */
110
     */
94
    prop = ofw_tree_getprop(node, "reg");
111
    prop = ofw_tree_getprop(node, "reg");
95
    if (!prop || !prop->value)
112
    if ((!prop) || (!prop->value))
96
        panic("Can't find \"reg\" property.\n");
113
        panic("Cannot find 'reg' property.");
97
   
114
   
98
    uintptr_t pa;
115
    uintptr_t pa;
99
    size_t size;
116
    size_t size;
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
        z8530 = (z8530_t *) hw_map(aligned_addr, offset + size) +
-
 
166
            offset;
-
 
167
       
-
 
168
        indev_t *kbrdin_z8530 = z8530_init(z8530, inr, cir, cir_arg);
-
 
169
        if (kbrdin_z8530)
145
        z8530_init(devno, inr, vaddr);
170
            kbrd_init(kbrdin_z8530);
-
 
171
       
-
 
172
        /*
-
 
173
         * This is the necessary evil until the userspace drivers are
-
 
174
         * entirely self-sufficient.
-
 
175
         */
-
 
176
        sysinfo_set_item_val("kbd", NULL, true);
-
 
177
        sysinfo_set_item_val("kbd.type", NULL, KBD_Z8530);
-
 
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
        ns16550 = (ns16550_t *) hw_map(aligned_addr, offset + size) +
-
 
187
            offset;
-
 
188
       
-
 
189
        indev_t *kbrdin_ns16550 = ns16550_init(ns16550, inr, cir, cir_arg);
-
 
190
        if (kbrdin_ns16550)
150
        ns16550_init(devno, inr, vaddr);
191
            kbrd_init(kbrdin_ns16550);
-
 
192
       
-
 
193
        /*
-
 
194
         * This is the necessary evil until the userspace driver is
-
 
195
         * entirely self-sufficient.
-
 
196
         */
-
 
197
        sysinfo_set_item_val("kbd", NULL, true);
-
 
198
        sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
-
 
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
 
-
 
211
#endif
-
 
212
 
158
/** @}
213
/** @}
159
 */
214
 */