2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2323 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2424 */
25+ #include <apic.h>
2526#include <drivers/keyboard.h>
2627#include <drivers/pic.h>
28+ #include <ioapic.h>
2729#include <lib.h>
2830#include <string.h>
2931
30- static struct {
31- int shift , caps , ctrl , alt ;
32+ /* clang-format off */
33+ static const unsigned char key_map [] = { /* map scan code to key */
34+ 0xff , SCAN_ESC , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0' , '-' , '=' ,
35+ '\b' , '\t' , 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , 'o' , 'p' , '[' , ']' ,
36+ SCAN_ENTER , SCAN_CTRL , 'a' , 's' , 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , '\'' , '`' ,
37+ SCAN_LSHIFT , '\\' , 'z' , 'x' , 'c' , 'v' , 'b' , 'n' , 'm' , ',' , '.' , '/' ,
38+ SCAN_RSHIFT , 0x37 , SCAN_ALT , ' ' , SCAN_CAPS ,
39+ SCAN_F1 , SCAN_F2 , SCAN_F3 , SCAN_F4 , SCAN_F5 , SCAN_F6 , SCAN_F7 , SCAN_F8 , SCAN_F9 , SCAN_F10 ,
40+ SCAN_NUMLOCK , SCAN_SCROLLLOCK , SCAN_HOME , SCAN_UP , SCAN_PAGEUP , 0x4a , SCAN_LEFT ,
41+ SCAN_KEYPAD5 , SCAN_RIGHT , 0x4e , SCAN_END , SCAN_DOWN , SCAN_PAGEDOWN , SCAN_INS , SCAN_DEL ,
42+ 0x54 , SCAN_F11 , 0x56 , 0x57 , SCAN_F12
43+ };
44+
45+ static const unsigned char key_map_up [] = { /* map scan code to upper key */
46+ 0xff , SCAN_ESC , '!' , '@' , '#' , '$' , '%' , '^' , '&' , '*' , '(' , ')' , '_' , '+' ,
47+ '\b' , '\t' , 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , 'O' , 'P' , '{' , '}' ,
48+ SCAN_ENTER , SCAN_CTRL , 'A' , 'S' , 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , '"' , '~' ,
49+ SCAN_LSHIFT , '|' , 'Z' , 'X' , 'C' , 'V' , 'B' , 'N' , 'M' , '<' , '>' , '?' };
50+ /* clang-format on */
51+
52+ struct keyboard_state {
53+ bool shift , caps , ctrl , alt ;
3254
3355 char buf [KEY_BUF ];
3456 unsigned curr ;
3557 unsigned init ;
36- } keyboard_state ;
58+ };
59+ typedef struct keyboard_state keyboard_state_t ;
3760
38- void init_keyboard () {
61+ static keyboard_state_t keyboard_state ;
62+
63+ void init_keyboard (uint8_t dst_cpus ) {
3964 printk ("Initializing keyboard driver\n" );
4065
4166 /* Disable devices */
42- outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_DISABLE_PORT_0 );
4367 outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_DISABLE_PORT_1 );
68+ outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_DISABLE_PORT_2 );
4469
4570 /* Flush output buffer */
4671 while (inb (KEYBOARD_PORT_DATA ) & KEYBOARD_STATUS_OUT_FULL )
4772 ; /* discard leftover bytes */
4873
4974 /* Controller configuration */
50- char current_status ;
51- int dual_channel ;
75+ keyboard_controller_config_t current_status ;
76+ bool dual_channel ;
5277
5378 /* Read controller config */
5479 outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_READ_CONFIGURATION );
55- current_status = inb (KEYBOARD_PORT_DATA );
80+ current_status .config = inb (KEYBOARD_PORT_DATA );
81+
82+ dual_channel = current_status .clock2 == 0 ? 1 : 0 ; /* second channel enabled if 0 */
83+
84+ printk ("Current PS/2 status before: %x\n" , current_status .config );
5685
57- dual_channel = !!(current_status & (1 << KEYBOARD_CONTROLLER_CONFIG_BIT_CLOCK_1 ));
58- printk ("Current PS/2 status before: %x\n" , current_status );
5986 /* Disable IRQs and translation */
60- current_status = current_status &
61- ~( 1 << KEYBOARD_CONTROLLER_CONFIG_BIT_PORT_0_INTERRUPT ) &
62- ~( 1 << KEYBOARD_CONTROLLER_CONFIG_BIT_PORT_1_INTERRUPT ) &
63- ~( 1 << KEYBOARD_CONTROLLER_CONFIG_BIT_TRANSLATION );
87+ current_status . port1_int = 0 ;
88+ current_status . port2_int = 0 ;
89+ current_status . translation = 0 ;
90+
6491 /* Write controller config */
6592 outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_WRITE_CONFIGURATION );
66- outb (KEYBOARD_PORT_DATA , current_status );
93+ outb (KEYBOARD_PORT_DATA , current_status . config );
6794
68- printk ("Current PS/2 status after mods: %x\n" , current_status );
95+ printk ("Current PS/2 status after mods: %x\n" , current_status . config );
6996 printk ("PS/2 dual channel? %d\n" , dual_channel );
7097
7198 /* Controller self test */
7299 outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_SELF_TEST );
73100 if (inb (KEYBOARD_PORT_DATA ) != KEYBOARD_RES_SELF_TEST ) {
74- printk ("Self test did not succed \n" );
101+ printk ("Self test did not succeed \n" );
75102 return ;
76103 }
77104
78105 /* Determine whether second channel exists */
79106 if (dual_channel ) {
80- printk ("Enabling second PS/2 port\n" );
81- outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_ENABLE_PORT_1 );
107+ outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_ENABLE_PORT_2 );
82108 outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_READ_CONFIGURATION );
83- current_status = inb (KEYBOARD_PORT_DATA );
84- dual_channel =
85- (current_status & (1 << KEYBOARD_CONTROLLER_CONFIG_BIT_CLOCK_1 )) == 0 ;
109+ current_status .config = inb (KEYBOARD_PORT_DATA );
110+ dual_channel = current_status .clock2 == 0 ? 1 : 0 ;
86111 }
87112 if (dual_channel )
88- outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_DISABLE_PORT_1 );
113+ outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_DISABLE_PORT_2 );
89114
90115 /* Interface tests */
91116 int port1 , port2 = 0 ;
92- outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_TEST_PORT_0 );
93- port1 = inb (KEYBOARD_PORT_DATA ) == 0 ;
117+ outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_TEST_PORT_1 );
118+ port1 = inb (KEYBOARD_PORT_DATA ) == 0 ? 1 : 0 ;
94119 if (dual_channel ) {
95- outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_TEST_PORT_1 );
96- port2 = inb (KEYBOARD_PORT_DATA ) == 0 ;
120+ outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_TEST_PORT_2 );
121+ port2 = inb (KEYBOARD_PORT_DATA ) == 0 ? 1 : 0 ;
97122 }
98123
99124 printk ("Port1 available? %d - port2 available? %d\n" , port1 , port2 );
@@ -105,25 +130,25 @@ void init_keyboard() {
105130 /* Enable devices */
106131 if (port1 ) {
107132 printk ("Keyboard: enabling first channel\n" );
108- current_status = current_status |
109- (1 << KEYBOARD_CONTROLLER_CONFIG_BIT_PORT_0_INTERRUPT ) |
110- (1 << KEYBOARD_CONTROLLER_CONFIG_BIT_CLOCK_1 ) |
111- (1 << KEYBOARD_CONTROLLER_CONFIG_BIT_TRANSLATION );
133+ current_status .port1_int = 1 ;
134+ current_status .clock2 = 1 ; /* disable second port clock */
135+ current_status .translation = 1 ;
112136 outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_WRITE_CONFIGURATION );
113- outb (KEYBOARD_PORT_DATA , current_status );
137+ outb (KEYBOARD_PORT_DATA , current_status . config );
114138
115- pic_enable_irq (PIC1_DEVICE_SEL , KEYBOARD_IRQ );
116- outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_ENABLE_PORT_0 );
139+ configure_isa_irq (KEYBOARD_PORT1_IRQ , KEYBOARD_PORT1_IRQ0_OFFSET ,
140+ IOAPIC_DEST_MODE_PHYSICAL , dst_cpus );
141+ outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_ENABLE_PORT_1 );
117142 }
118143 else {
119144 printk ("Keyboard: enabling second channel\n" );
120- current_status =
121- current_status | (1 << KEYBOARD_CONTROLLER_CONFIG_BIT_PORT_1_INTERRUPT );
145+ current_status .port2_int = 1 ;
122146 outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_WRITE_CONFIGURATION );
123- outb (KEYBOARD_PORT_DATA , current_status );
147+ outb (KEYBOARD_PORT_DATA , current_status . config );
124148
125- pic_enable_irq (PIC1_DEVICE_SEL , KEYBOARD_IRQ_2 );
126- outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_ENABLE_PORT_1 );
149+ configure_isa_irq (KEYBOARD_PORT2_IRQ , KEYBOARD_PORT2_IRQ0_OFFSET ,
150+ IOAPIC_DEST_MODE_PHYSICAL , dst_cpus );
151+ outb (KEYBOARD_PORT_CMD , KEYBOARD_CMD_ENABLE_PORT_2 );
127152 }
128153
129154 memset (& keyboard_state , 0 , sizeof (keyboard_state ));
@@ -164,13 +189,12 @@ unsigned int keyboard_process_keys(void) {
164189
165190void keyboard_interrupt_handler (void ) {
166191 unsigned char status ;
167- int released ;
168192
169193 status = inb (KEYBOARD_PORT_CMD );
170194 if (status & KEYBOARD_STATUS_OUT_FULL ) {
171195 char scan = inb (KEYBOARD_PORT_DATA );
196+ int released = !!(scan & SCAN_RELEASE_MASK );
172197
173- released = !!(scan & SCAN_RELEASE_MASK );
174198 scan = scan & (SCAN_RELEASE_MASK - 1 );
175199
176200 switch (scan ) {
@@ -199,5 +223,5 @@ void keyboard_interrupt_handler(void) {
199223 }
200224 }
201225
202- outb ( PIC1_PORT_CMD , PIC_EOI );
226+ apic_EOI ( );
203227}
0 commit comments