34,19 → 34,26 |
|
#include <arch/drivers/kbd.h> |
#include <genarch/ofw/ofw_tree.h> |
|
#ifdef CONFIG_SUN_KBD |
#include <genarch/kbrd/kbrd.h> |
#endif |
#ifdef CONFIG_Z8530 |
#include <genarch/kbd/z8530.h> |
#include <genarch/drivers/z8530/z8530.h> |
#endif |
#ifdef CONFIG_NS16550 |
#include <genarch/kbd/ns16550.h> |
#include <genarch/drivers/ns16550/ns16550.h> |
#endif |
|
#include <console/console.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <arch/mm/page.h> |
#include <arch/types.h> |
#include <align.h> |
#include <func.h> |
#include <string.h> |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
|
kbd_type_t kbd_type = KBD_UNKNOWN; |
|
63,7 → 70,16 |
uintptr_t aligned_addr; |
ofw_tree_property_t *prop; |
const char *name; |
cir_t cir; |
void *cir_arg; |
|
#ifdef CONFIG_NS16550 |
ns16550_t *ns16550; |
#endif |
#ifdef CONFIG_Z8530 |
z8530_t *z8530; |
#endif |
|
name = ofw_tree_node_name(node); |
|
/* |
84,8 → 100,8 |
*/ |
uint32_t interrupts; |
prop = ofw_tree_getprop(node, "interrupts"); |
if (!prop || !prop->value) |
panic("Can't find \"interrupts\" property.\n"); |
if ((!prop) || (!prop->value)) |
panic("Cannot find 'interrupt' property."); |
interrupts = *((uint32_t *) prop->value); |
|
/* |
92,22 → 108,25 |
* Read 'reg' property. |
*/ |
prop = ofw_tree_getprop(node, "reg"); |
if (!prop || !prop->value) |
panic("Can't find \"reg\" property.\n"); |
if ((!prop) || (!prop->value)) |
panic("Cannot find 'reg' property."); |
|
uintptr_t pa; |
size_t size; |
devno_t devno; |
inr_t inr; |
devno_t devno = device_assign_devno(); |
|
switch (kbd_type) { |
case KBD_Z8530: |
size = ((ofw_fhc_reg_t *) prop->value)->size; |
if (!ofw_fhc_apply_ranges(node->parent, ((ofw_fhc_reg_t *) prop->value) , &pa)) { |
if (!ofw_fhc_apply_ranges(node->parent, |
((ofw_fhc_reg_t *) prop->value), &pa)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_fhc_map_interrupt(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) { |
if (!ofw_fhc_map_interrupt(node->parent, |
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
} |
115,18 → 134,20 |
|
case KBD_NS16550: |
size = ((ofw_ebus_reg_t *) prop->value)->size; |
if (!ofw_ebus_apply_ranges(node->parent, ((ofw_ebus_reg_t *) prop->value) , &pa)) { |
if (!ofw_ebus_apply_ranges(node->parent, |
((ofw_ebus_reg_t *) prop->value), &pa)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_ebus_map_interrupt(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) { |
if (!ofw_ebus_map_interrupt(node->parent, |
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
}; |
break; |
|
default: |
panic("Unexpected type.\n"); |
panic("Unexpected keyboard type."); |
} |
|
/* |
137,21 → 158,53 |
*/ |
aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
offset = pa - aligned_addr; |
uintptr_t vaddr = hw_map(aligned_addr, offset + size) + offset; |
|
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530_init(devno, inr, vaddr); |
devno = device_assign_devno(); |
z8530 = (z8530_t *) hw_map(aligned_addr, offset + size) + |
offset; |
kbrd_init(stdin); |
(void) z8530_init(z8530, devno, inr, cir, cir_arg, &kbrdin); |
|
/* |
* This is the necessary evil until the userspace drivers are |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_Z8530); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) z8530); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_init(devno, inr, vaddr); |
devno = device_assign_devno(); |
ns16550 = (ns16550_t *) hw_map(aligned_addr, offset + size) + |
offset; |
kbrd_init(stdin); |
(void) ns16550_init(ns16550, devno, inr, cir, cir_arg, &kbrdin); |
|
/* |
* This is the necessary evil until the userspace driver is |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) ns16550); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
break; |
#endif |
default: |
printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n"); |
printf("Kernel is not compiled with the necessary keyboard " |
"driver this machine requires.\n"); |
} |
} |
|