Rev 3647 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3647 | Rev 3649 | ||
---|---|---|---|
Line 38... | Line 38... | ||
38 | #include <arch/trap/interrupt.h> |
38 | #include <arch/trap/interrupt.h> |
39 | #include <mm/page.h> |
39 | #include <mm/page.h> |
40 | #include <mm/slab.h> |
40 | #include <mm/slab.h> |
41 | #include <arch/types.h> |
41 | #include <arch/types.h> |
42 | #include <genarch/ofw/ofw_tree.h> |
42 | #include <genarch/ofw/ofw_tree.h> |
- | 43 | #include <byteorder.h> |
|
43 | 44 | ||
44 | #define PSYCHO_IGN 0x7c0 |
45 | #define PSYCHO_INTERNAL_REG 2 |
- | 46 | ||
- | 47 | #define PSYCHO_OBIO_IMR_BASE (0x1000 / sizeof(uint64_t)) |
|
- | 48 | #define PSYCHO_OBIO_IMR(ino) (PSYCHO_OBIO_IMR_BASE + ((ino) & INO_MASK)) |
|
- | 49 | ||
45 | #define PSYCHO_KEYBOARD_INR 0x29 |
50 | #define PSYCHO_OBIO_CIR_BASE (0x1800 / sizeof(uint64_t)) |
- | 51 | #define PSYCHO_OBIO_CIR(ino) (PSYCHO_OBIO_CIR_BASE + ((ino) & INO_MASK)) |
|
46 | 52 | ||
47 | psycho_t *psycho_a = NULL; |
53 | psycho_t *psycho_a = NULL; |
48 | psycho_t *psycho_b = NULL; |
54 | psycho_t *psycho_b = NULL; |
49 | 55 | ||
50 | psycho_t *psycho_init(ofw_tree_node_t *node) |
56 | psycho_t *psycho_init(ofw_tree_node_t *node) |
Line 54... | Line 60... | ||
54 | 60 | ||
55 | prop = ofw_tree_getprop(node, "reg"); |
61 | prop = ofw_tree_getprop(node, "reg"); |
56 | 62 | ||
57 | if (!prop || !prop->value) |
63 | if (!prop || !prop->value) |
58 | return NULL; |
64 | return NULL; |
- | 65 | ||
- | 66 | count_t regs = prop->size / sizeof(ofw_upa_reg_t); |
|
- | 67 | if (regs < PSYCHO_INTERNAL_REG + 1) |
|
- | 68 | return NULL; |
|
59 | 69 | ||
- | 70 | ofw_upa_reg_t *reg = |
|
60 | ofw_upa_reg_t *reg = &((ofw_upa_reg_t *) prop->value)[0]; /* XXX */ |
71 | &((ofw_upa_reg_t *) prop->value)[PSYCHO_INTERNAL_REG]; |
61 | 72 | ||
62 | uintptr_t paddr; |
73 | uintptr_t paddr; |
63 | if (!ofw_upa_apply_ranges(node->parent, reg, &paddr)) |
74 | if (!ofw_upa_apply_ranges(node->parent, reg, &paddr)) |
64 | return NULL; |
75 | return NULL; |
65 | 76 | ||
Line 72... | Line 83... | ||
72 | return psycho; |
83 | return psycho; |
73 | } |
84 | } |
74 | 85 | ||
75 | void psycho_enable_interrupt(psycho_t *psycho, int inr) |
86 | void psycho_enable_interrupt(psycho_t *psycho, int inr) |
76 | { |
87 | { |
77 | inr -= PSYCHO_IGN; |
88 | int ino = inr & ~IGN_MASK; |
78 | switch (inr) { |
- | |
79 | case PSYCHO_KEYBOARD_INR: |
89 | uint64_t imr = psycho->regs[PSYCHO_OBIO_IMR(ino)]; |
80 | psycho->regs[0] = 1; /* XXX */ |
90 | imr |= host2uint64_t_le(IMAP_V_MASK); |
81 | break; |
- | |
82 | default: |
- | |
83 | panic("Unexpected INR (%d)\n", inr); |
91 | psycho->regs[PSYCHO_OBIO_IMR(ino)] = imr; |
84 | break; |
- | |
85 | } |
- | |
86 | } |
92 | } |
87 | 93 | ||
88 | void psycho_clear_interrupt(psycho_t *psycho, int inr) |
94 | void psycho_clear_interrupt(psycho_t *psycho, int inr) |
89 | { |
95 | { |
90 | inr -= PSYCHO_IGN; |
96 | int ino = inr & ~IGN_MASK; |
91 | switch (inr) { |
- | |
92 | case PSYCHO_KEYBOARD_INR: |
97 | uint64_t idle = host2uint64_t_le(0); |
93 | psycho->regs[0] = 0; /* XXX */ |
98 | psycho->regs[PSYCHO_OBIO_CIR(ino)] = idle; |
94 | break; |
- | |
95 | default: |
- | |
96 | panic("Unexpected INR (%d)\n", inr); |
- | |
97 | break; |
- | |
98 | } |
- | |
99 | } |
99 | } |
100 | 100 | ||
101 | /** @} |
101 | /** @} |
102 | */ |
102 | */ |