/branches/tracing/kernel/genarch/src/kbrd/kbrd.c |
---|
45,6 → 45,10 |
#include <genarch/kbrd/scanc_sun.h> |
#endif |
#ifdef CONFIG_MAC_KBD |
#include <genarch/kbrd/scanc_mac.h> |
#endif |
#include <synch/spinlock.h> |
#include <console/chardev.h> |
#include <console/console.h> |
/branches/tracing/kernel/genarch/src/kbrd/kbrd_pl050.c |
---|
0,0 → 1,209 |
/* |
* Copyright (c) 2009 Vineeth Pillai |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief pl050 Keyboard processing. |
*/ |
#include <genarch/kbrd/kbrd.h> |
#include <genarch/kbrd/scanc.h> |
#include <genarch/kbrd/scanc_pl050.h> |
#include <synch/spinlock.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <proc/thread.h> |
#include <arch.h> |
#include <macros.h> |
#define PRESSED_SHIFT (1 << 0) |
#define PRESSED_CAPSLOCK (1 << 1) |
#define LOCKED_CAPSLOCK (1 << 0) |
#define PL050_KEY_RELEASE 0xF0 |
#define PL050_ESC_KEY 0xE0 |
#define PL050_CAPS_SCAN_CODE 0x58 |
#define PL050_NUM_SCAN_CODE 0x77 |
#define PL050_SCROLL_SCAN_CODE 0x7E |
static bool is_lock_key(wchar_t); |
static indev_operations_t kbrd_raw_ops = { |
.poll = NULL |
}; |
/** Process release of key. |
* |
* @param sc Scancode of the key being released. |
*/ |
static void key_released(kbrd_instance_t *instance, wchar_t sc) |
{ |
spinlock_lock(&instance->keylock); |
switch (sc) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
instance->keyflags &= ~PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
instance->keyflags &= ~PRESSED_CAPSLOCK; |
if (instance->lockflags & LOCKED_CAPSLOCK) |
instance->lockflags &= ~LOCKED_CAPSLOCK; |
else |
instance->lockflags |= LOCKED_CAPSLOCK; |
break; |
default: |
break; |
} |
spinlock_unlock(&instance->keylock); |
} |
/** Process keypress. |
* |
* @param sc Scancode of the key being pressed. |
*/ |
static void key_pressed(kbrd_instance_t *instance, wchar_t sc) |
{ |
bool letter; |
bool shift; |
bool capslock; |
spinlock_lock(&instance->keylock); |
switch (sc) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
instance->keyflags |= PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
instance->keyflags |= PRESSED_CAPSLOCK; |
break; |
case SC_SCAN_ESCAPE: |
break; |
default: |
letter = islower(sc_primary_map[sc]); |
shift = instance->keyflags & PRESSED_SHIFT; |
capslock = (instance->keyflags & PRESSED_CAPSLOCK) || |
(instance->lockflags & LOCKED_CAPSLOCK); |
if ((letter) && (capslock)) |
shift = !shift; |
if (shift) |
indev_push_character(instance->sink, sc_secondary_map[sc]); |
else |
indev_push_character(instance->sink, sc_primary_map[sc]); |
break; |
} |
spinlock_unlock(&instance->keylock); |
} |
static void kkbrd(void *arg) |
{ |
static int key_released_flag = 0; |
static int is_locked = 0; |
kbrd_instance_t *instance = (kbrd_instance_t *) arg; |
while (true) { |
wchar_t sc = indev_pop_character(&instance->raw); |
if (sc == PL050_KEY_RELEASE) { |
key_released_flag = 1; |
} else { |
if (key_released_flag) { |
key_released_flag = 0; |
if (is_lock_key(sc)) { |
if (!is_locked) { |
is_locked = 1; |
} else { |
is_locked = 0; |
continue; |
} |
} |
key_released(instance, sc); |
} else { |
if (is_lock_key(sc) && is_locked) |
continue; |
key_pressed(instance, sc); |
} |
} |
} |
} |
kbrd_instance_t *kbrd_init(void) |
{ |
kbrd_instance_t *instance |
= malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC); |
if (instance) { |
instance->thread |
= thread_create(kkbrd, (void *) instance, TASK, 0, "kkbrd", false); |
if (!instance->thread) { |
free(instance); |
return NULL; |
} |
instance->sink = NULL; |
indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops); |
spinlock_initialize(&instance->keylock, "instance_keylock"); |
instance->keyflags = 0; |
instance->lockflags = 0; |
} |
return instance; |
} |
indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink) |
{ |
ASSERT(instance); |
ASSERT(sink); |
instance->sink = sink; |
thread_ready(instance->thread); |
return &instance->raw; |
} |
static bool is_lock_key(wchar_t sc) |
{ |
return ((sc == PL050_CAPS_SCAN_CODE) || (sc == PL050_NUM_SCAN_CODE) || |
(sc == PL050_SCROLL_SCAN_CODE)); |
} |
/** @} |
*/ |
/branches/tracing/kernel/genarch/src/kbrd/scanc_mac.c |
---|
0,0 → 1,306 |
/* |
* Copyright (c) 2009 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Scan codes for Macintosh ADB keyboards. |
*/ |
#include <genarch/kbrd/scanc.h> |
#include <typedefs.h> |
#include <string.h> |
/** Primary meaning of scancodes. */ |
wchar_t sc_primary_map[SCANCODES] = { |
[0x00] = 'a', |
[0x01] = 's', |
[0x02] = 'd', |
[0x03] = 'f', |
[0x04] = 'h', |
[0x05] = 'g', |
[0x06] = 'z', |
[0x07] = 'x', |
[0x08] = 'c', |
[0x09] = 'v', |
[0x0a] = U_SPECIAL, |
[0x0b] = 'b', |
[0x0c] = 'q', |
[0x0d] = 'w', |
[0x0e] = 'e', |
[0x0f] = 'r', |
[0x10] = 'y', |
[0x11] = 't', |
[0x12] = '1', |
[0x13] = '2', |
[0x14] = '3', |
[0x15] = '4', |
[0x16] = '6', |
[0x17] = '5', |
[0x18] = '=', |
[0x19] = '9', |
[0x1a] = '7', |
[0x1b] = '-', |
[0x1c] = '8', |
[0x1d] = '0', |
[0x1e] = ']', |
[0x1f] = 'o', |
[0x20] = 'u', |
[0x21] = '[', |
[0x22] = 'i', |
[0x23] = 'p', |
[0x24] = '\n', /* Enter */ |
[0x25] = 'l', |
[0x26] = 'j', |
[0x27] = '\'', |
[0x28] = 'k', |
[0x29] = ';', |
[0x2a] = '\\', |
[0x2b] = ',', |
[0x2c] = '/', |
[0x2d] = 'n', |
[0x2e] = 'm', |
[0x2f] = '.', |
[0x30] = '\t', /* Tab */ |
[0x31] = ' ', /* Space */ |
[0x32] = '`', |
[0x33] = '\b', /* Backspace */ |
[0x34] = U_SPECIAL, |
[0x35] = U_ESCAPE, |
[0x36] = U_SPECIAL, |
[0x37] = U_SPECIAL, |
[0x38] = U_SPECIAL, |
[0x39] = U_SPECIAL, |
[0x3a] = U_SPECIAL, |
[0x3b] = U_LEFT_ARROW, |
[0x3c] = U_RIGHT_ARROW, |
[0x3d] = U_DOWN_ARROW, |
[0x3e] = U_UP_ARROW, |
[0x3f] = U_SPECIAL, |
[0x40] = U_SPECIAL, |
[0x41] = '.', /* Num Separator */ |
[0x42] = U_SPECIAL, |
[0x43] = '*', /* Num Times */ |
[0x44] = U_SPECIAL, |
[0x45] = '+', /* Num Plus */ |
[0x46] = U_SPECIAL, |
[0x47] = U_SPECIAL, |
[0x48] = U_SPECIAL, |
[0x49] = U_SPECIAL, |
[0x4a] = U_SPECIAL, |
[0x4b] = '/', /* Num Divide */ |
[0x4c] = U_SPECIAL, |
[0x4d] = U_SPECIAL, |
[0x4e] = '-', /* Num Minus */ |
[0x4f] = U_SPECIAL, |
[0x50] = U_SPECIAL, |
[0x51] = U_SPECIAL, |
[0x52] = '0', /* Num Zero */ |
[0x53] = '1', /* Num One */ |
[0x54] = '2', /* Num Two */ |
[0x55] = '3', /* Num Three */ |
[0x56] = '4', /* Num Four */ |
[0x57] = '5', /* Num Five */ |
[0x58] = '6', /* Num Six */ |
[0x59] = '7', /* Num Seven */ |
[0x5a] = U_SPECIAL, |
[0x5b] = '8', /* Num Eight */ |
[0x5c] = '9', /* Num Nine */ |
[0x5d] = U_SPECIAL, |
[0x5e] = U_SPECIAL, |
[0x5f] = U_SPECIAL, |
[0x60] = U_SPECIAL, |
[0x61] = U_SPECIAL, |
[0x62] = U_SPECIAL, |
[0x63] = U_SPECIAL, |
[0x64] = U_SPECIAL, |
[0x65] = U_SPECIAL, |
[0x66] = U_SPECIAL, |
[0x67] = U_SPECIAL, |
[0x68] = U_SPECIAL, |
[0x69] = U_SPECIAL, |
[0x6a] = U_SPECIAL, |
[0x6b] = U_SPECIAL, |
[0x6c] = U_SPECIAL, |
[0x6d] = U_SPECIAL, |
[0x6e] = U_SPECIAL, |
[0x6f] = U_SPECIAL, |
[0x70] = U_SPECIAL, |
[0x71] = U_SPECIAL, |
[0x72] = U_SPECIAL, |
[0x73] = U_HOME_ARROW, |
[0x74] = U_PAGE_UP, |
[0x75] = U_DELETE, |
[0x76] = U_SPECIAL, |
[0x77] = U_SPECIAL, |
[0x78] = U_SPECIAL, |
[0x79] = U_PAGE_DOWN, |
[0x7a] = U_SPECIAL, |
[0x7b] = U_SPECIAL, |
[0x7c] = U_SPECIAL, |
[0x7d] = U_SPECIAL, |
[0x7e] = U_SPECIAL, |
[0x7f] = U_SPECIAL |
}; |
/** Secondary meaning of scancodes. */ |
wchar_t sc_secondary_map[SCANCODES] = { |
[0x00] = 'A', |
[0x01] = 'S', |
[0x02] = 'D', |
[0x03] = 'F', |
[0x04] = 'H', |
[0x05] = 'G', |
[0x06] = 'Z', |
[0x07] = 'X', |
[0x08] = 'C', |
[0x09] = 'V', |
[0x0a] = U_SPECIAL, |
[0x0b] = 'B', |
[0x0c] = 'Q', |
[0x0d] = 'W', |
[0x0e] = 'E', |
[0x0f] = 'R', |
[0x10] = 'Y', |
[0x11] = 'T', |
[0x12] = '!', |
[0x13] = '@', |
[0x14] = '#', |
[0x15] = '$', |
[0x16] = '^', |
[0x17] = '%', |
[0x18] = '+', |
[0x19] = '(', |
[0x1a] = '&', |
[0x1b] = '_', |
[0x1c] = '*', |
[0x1d] = ')', |
[0x1e] = '}', |
[0x1f] = 'O', |
[0x20] = 'U', |
[0x21] = '{', |
[0x22] = 'I', |
[0x23] = 'P', |
[0x24] = '\n', /* Enter */ |
[0x25] = 'L', |
[0x26] = 'J', |
[0x27] = '"', |
[0x28] = 'K', |
[0x29] = ':', |
[0x2a] = '|', |
[0x2b] = '<', |
[0x2c] = '?', |
[0x2d] = 'N', |
[0x2e] = 'M', |
[0x2f] = '>', |
[0x30] = '\t', /* Tab */ |
[0x31] = ' ', /* Space */ |
[0x32] = '~', |
[0x33] = '\b', /* Backspace */ |
[0x34] = U_SPECIAL, |
[0x35] = U_SPECIAL, |
[0x36] = U_SPECIAL, |
[0x37] = U_SPECIAL, |
[0x38] = U_SPECIAL, |
[0x39] = U_SPECIAL, |
[0x3a] = U_SPECIAL, |
[0x3b] = U_SPECIAL, |
[0x3c] = U_SPECIAL, |
[0x3d] = U_SPECIAL, |
[0x3e] = U_SPECIAL, |
[0x3f] = U_SPECIAL, |
[0x40] = U_SPECIAL, |
[0x41] = '.', /* Num Separator */ |
[0x42] = U_SPECIAL, |
[0x43] = '*', /* Num Times */ |
[0x44] = U_SPECIAL, |
[0x45] = '+', /* Num Plus */ |
[0x46] = U_SPECIAL, |
[0x47] = U_SPECIAL, |
[0x48] = U_SPECIAL, |
[0x49] = U_SPECIAL, |
[0x4a] = U_SPECIAL, |
[0x4b] = '/', /* Num Divide */ |
[0x4c] = U_SPECIAL, |
[0x4d] = U_SPECIAL, |
[0x4e] = '-', /* Num Minus */ |
[0x4f] = U_SPECIAL, |
[0x50] = U_SPECIAL, |
[0x51] = U_SPECIAL, |
[0x52] = '0', /* Num Zero */ |
[0x53] = '1', /* Num One */ |
[0x54] = '2', /* Num Two */ |
[0x55] = '3', /* Num Three */ |
[0x56] = '4', /* Num Four */ |
[0x57] = '5', /* Num Five */ |
[0x58] = '6', /* Num Six */ |
[0x59] = '7', /* Num Seven */ |
[0x5a] = U_SPECIAL, |
[0x5b] = '8', /* Num Eight */ |
[0x5c] = '9', /* Num Nine */ |
[0x5d] = U_SPECIAL, |
[0x5e] = U_SPECIAL, |
[0x5f] = U_SPECIAL, |
[0x60] = U_SPECIAL, |
[0x61] = U_SPECIAL, |
[0x62] = U_SPECIAL, |
[0x63] = U_SPECIAL, |
[0x64] = U_SPECIAL, |
[0x65] = U_SPECIAL, |
[0x66] = U_SPECIAL, |
[0x67] = U_SPECIAL, |
[0x68] = U_SPECIAL, |
[0x69] = U_SPECIAL, |
[0x6a] = U_SPECIAL, |
[0x6b] = U_SPECIAL, |
[0x6c] = U_SPECIAL, |
[0x6d] = U_SPECIAL, |
[0x6e] = U_SPECIAL, |
[0x6f] = U_SPECIAL, |
[0x70] = U_SPECIAL, |
[0x71] = U_SPECIAL, |
[0x72] = U_SPECIAL, |
[0x73] = U_SPECIAL, |
[0x74] = U_SPECIAL, |
[0x75] = U_SPECIAL, |
[0x76] = U_SPECIAL, |
[0x77] = U_SPECIAL, |
[0x78] = U_SPECIAL, |
[0x79] = U_SPECIAL, |
[0x7a] = U_SPECIAL, |
[0x7b] = U_SPECIAL, |
[0x7c] = U_SPECIAL, |
[0x7d] = U_SPECIAL, |
[0x7e] = U_SPECIAL, |
[0x7f] = U_SPECIAL |
}; |
/** @} |
*/ |
/branches/tracing/kernel/genarch/src/kbrd/scanc_pl050.c |
---|
0,0 → 1,234 |
/* |
* Copyright (c) 2009 Vineeth Pillai |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, U_SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Scan codes for pl050 keyboards. |
*/ |
#include <genarch/kbrd/scanc.h> |
#include <typedefs.h> |
#include <string.h> |
/** Primary meaning of scancodes. */ |
wchar_t sc_primary_map[] = { |
U_NULL, /* 0x00 */ |
U_SPECIAL, /* 0x01 - F9 */ |
U_SPECIAL, /* 0x02 - F7 */ |
U_SPECIAL, /* 0x03 - F5 */ |
U_SPECIAL, /* 0x04 - F3 */ |
U_SPECIAL, /* 0x05 - F1 */ |
U_SPECIAL, /* 0x06 - F2 */ |
U_SPECIAL, /* 0x07 - F12 */ |
U_SPECIAL, /* 0x08 - */ |
U_SPECIAL, /* 0x09 - F10 */ |
U_SPECIAL, /* 0x0A - F8 */ |
U_SPECIAL, /* 0x0B - F10 */ |
U_SPECIAL, /* 0x0C - F4 */ |
'\t', /* 0x0D - Tab */ |
'`', |
U_SPECIAL, /* 0x0F */ |
U_SPECIAL, /* 0x10 */ |
U_SPECIAL, /* 0x11 - LAlt */ |
U_SPECIAL, /* 0x12 - LShift */ |
U_SPECIAL, /* ox13 */ |
U_SPECIAL, /* 0x14 Ctrl */ |
'q', '1', |
U_SPECIAL, /* 0x17 */ |
U_SPECIAL, /* 0x18 */ |
U_SPECIAL, /* 0x19 */ |
'z', 's', 'a', 'w', '2', |
U_SPECIAL, /* 0x1F */ |
U_SPECIAL, /* 0x20 */ |
'c', 'x', 'd', 'e', '4', '3', |
U_SPECIAL, /* 0x27 */ |
U_SPECIAL, /* 0x28 */ |
' ', 'v', 'f', 't', 'r', '5', |
U_SPECIAL, /* 0x2F */ |
U_SPECIAL, /* 0x30 */ |
'n', 'b', 'h', 'g', 'y', '6', |
U_SPECIAL, /* 0x37 */ |
U_SPECIAL, /* 0x38 */ |
U_SPECIAL, /* 0x39 */ |
'm', 'j', 'u', '7', '8', |
U_SPECIAL, /* 0x3F */ |
U_SPECIAL, /* 0x40 */ |
',', 'k', 'i', 'o', '0', '9', |
U_SPECIAL, /* 0x47 */ |
U_SPECIAL, /* 0x48 */ |
'.', '/', 'l', ';', 'p', '-', |
U_SPECIAL, /* 0x4F */ |
U_SPECIAL, /* 0x50 */ |
U_SPECIAL, /* 0x51 */ |
'\'', |
U_SPECIAL, /* 0x53 */ |
'[', '=', |
U_SPECIAL, /* 0x56 */ |
U_SPECIAL, /* 0x57 */ |
U_SPECIAL, /* 0x58 - Caps Lock */ |
U_SPECIAL, /* 0x59 - RShift */ |
'\n', ']', |
U_SPECIAL, /* 0x5C */ |
'\\', |
U_SPECIAL, /* 0x5E */ |
U_SPECIAL, /* 0x5F */ |
U_SPECIAL, /* 0x60 */ |
U_SPECIAL, /* 0x61 */ |
U_SPECIAL, /* 0x62 */ |
U_SPECIAL, /* 0x63 */ |
U_SPECIAL, /* 0x64 */ |
U_SPECIAL, /* 0x65 */ |
'\b', /* 0x66 - backspace*/ |
U_SPECIAL, /* 0x67 */ |
U_SPECIAL, /* 0x68 */ |
U_END_ARROW, /* 0x69 */ |
U_SPECIAL, /* 0x6a */ |
U_LEFT_ARROW, /* 0x6b - Left Arrow */ |
U_SPECIAL, /* 0x6c */ |
U_SPECIAL, /* 0x6d */ |
U_SPECIAL, /* 0x6e */ |
U_SPECIAL, /* 0x6f */ |
U_SPECIAL, /* 0x70 */ |
U_DELETE, /* 0x71 - Del*/ |
U_DOWN_ARROW, /* 0x72 Down Arrow */ |
U_SPECIAL, /* 0x73 */ |
U_RIGHT_ARROW, /* 0x74 - Right Arrow */ |
U_UP_ARROW, /* 0x75 Up Arrow */ |
U_ESCAPE, /* 0x76 Esc */ |
U_SPECIAL, /* 0x77 - NumLock*/ |
U_SPECIAL, /* 0x78 F11*/ |
U_SPECIAL, /* 0x79 */ |
U_PAGE_DOWN, /* 0x7a */ |
U_SPECIAL, /* 0x7b */ |
U_SPECIAL, /* 0x7c */ |
U_PAGE_UP, /* 0x7d */ |
U_SPECIAL, /* 0x7e */ |
U_SPECIAL /* 0x7f */ |
}; |
/** Secondary meaning of scancodes. */ |
wchar_t sc_secondary_map[] = { |
U_NULL, /* 0x00 */ |
U_SPECIAL, /* 0x01 - F9 */ |
U_SPECIAL, /* 0x02 - F7 */ |
U_SPECIAL, /* 0x03 - F5 */ |
U_SPECIAL, /* 0x04 - F3 */ |
U_SPECIAL, /* 0x05 - F1 */ |
U_SPECIAL, /* 0x06 - F2 */ |
U_SPECIAL, /* 0x07 - F12 */ |
U_SPECIAL, /* 0x08 - */ |
U_SPECIAL, /* 0x09 - F10 */ |
U_SPECIAL, /* 0x0A - F8 */ |
U_SPECIAL, /* 0x0B - F10 */ |
U_SPECIAL, /* 0x0C - F4 */ |
'\t', /* 0x0D - Tab */ |
'~', |
U_SPECIAL, /* 0x0F */ |
U_SPECIAL, /* 0x10 */ |
U_SPECIAL, /* 0x11 - LAlt */ |
U_SPECIAL, /* 0x12 - LShift */ |
U_SPECIAL, /* ox13 */ |
U_SPECIAL, /* 0x14 Ctrl */ |
'Q', '!', |
U_SPECIAL, /* 0x17 */ |
U_SPECIAL, /* 0x18 */ |
U_SPECIAL, /* 0x19 */ |
'Z', 'S', 'A', 'W', '@', |
U_SPECIAL, /* 0x1F */ |
U_SPECIAL, /* 0x20 */ |
'C', 'X', 'D', 'E', '$', '#', |
U_SPECIAL, /* 0x27 */ |
U_SPECIAL, /* 0x28 */ |
' ', 'V', 'F', 'T', 'R', '%', |
U_SPECIAL, /* 0x2F */ |
U_SPECIAL, /* 0x30 */ |
'N', 'B', 'H', 'G', 'Y', '^', |
U_SPECIAL, /* 0x37 */ |
U_SPECIAL, /* 0x38 */ |
U_SPECIAL, /* 0x39 */ |
'M', 'J', 'U', '&', '*', |
U_SPECIAL, /* 0x3F */ |
U_SPECIAL, /* 0x40 */ |
'<', 'K', 'I', 'O', ')', '(', |
U_SPECIAL, /* 0x47 */ |
U_SPECIAL, /* 0x48 */ |
'>', '?', 'L', ':', 'P', '_', |
U_SPECIAL, /* 0x4F */ |
U_SPECIAL, /* 0x50 */ |
U_SPECIAL, /* 0x51 */ |
'"', |
U_SPECIAL, /* 0x53 */ |
'{', '+', |
U_SPECIAL, /* 0x56 */ |
U_SPECIAL, /* 0x57 */ |
U_SPECIAL, /* 0x58 - Caps Lock */ |
U_SPECIAL, /* 0x59 - RShift */ |
'\n', '}', |
U_SPECIAL, /* 0x5C */ |
'|', |
U_SPECIAL, /* 0x5E */ |
U_SPECIAL, /* 0x5F */ |
U_SPECIAL, /* 0x60 */ |
U_SPECIAL, /* 0x61 */ |
U_SPECIAL, /* 0x62 */ |
U_SPECIAL, /* 0x63 */ |
U_SPECIAL, /* 0x64 */ |
U_SPECIAL, /* 0x65 */ |
'\b', /* 0x66 - backspace*/ |
U_SPECIAL, /* 0x67 */ |
U_SPECIAL, /* 0x68 */ |
U_END_ARROW, /* 0x69 */ |
U_SPECIAL, /* 0x6a */ |
U_LEFT_ARROW, /* 0x6b - Left Arrow */ |
U_SPECIAL, /* 0x6c */ |
U_SPECIAL, /* 0x6d */ |
U_SPECIAL, /* 0x6e */ |
U_SPECIAL, /* 0x6f */ |
U_SPECIAL, /* 0x70 */ |
U_DELETE, /* 0x71 - Del*/ |
U_DOWN_ARROW, /* 0x72 Down Arrow */ |
U_SPECIAL, /* 0x73 */ |
U_RIGHT_ARROW, /* 0x74 - Right Arrow */ |
U_UP_ARROW, /* 0x75 Up Arrow */ |
U_ESCAPE, /* 0x76 Esc */ |
U_SPECIAL, /* 0x77 - NumLock*/ |
U_SPECIAL, /* 0x78 F11*/ |
U_SPECIAL, /* 0x79 */ |
U_PAGE_DOWN, /* 0x7a */ |
U_SPECIAL, /* 0x7b */ |
U_SPECIAL, /* 0x7c */ |
U_PAGE_UP, /* 0x7d */ |
U_SPECIAL, /* 0x7e */ |
U_SPECIAL /* 0x7f */ |
}; |
/** @} |
*/ |
/branches/tracing/kernel/genarch/src/fb/fb.c |
---|
50,6 → 50,7 |
#include <string.h> |
#include <ddi/ddi.h> |
#include <arch/types.h> |
#include <byteorder.h> |
SPINLOCK_INITIALIZE(fb_lock); |
80,9 → 81,9 |
#define FG_COLOR 0xffff00 |
#define INV_COLOR 0xaaaaaa |
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
#define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1)) |
#define GREEN(x, bits) (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1)) |
#define BLUE(x, bits) (((x) >> (8 - (bits))) & ((1 << (bits)) - 1)) |
#define COL2X(col) ((col) * FONT_WIDTH) |
#define ROW2Y(row) ((row) * FONT_SCANLINES) |
97,69 → 98,79 |
static void (*rgb_conv)(void *, uint32_t); |
/** ARGB 8:8:8:8 conversion |
/* |
* RGB conversion functions. |
* |
* These functions write an RGB value to some memory in some predefined format. |
* The naming convention corresponds to the format created by these functions. |
* The functions use the so called network order (i.e. big endian) with respect |
* to their names. |
*/ |
static void rgb_0888(void *dst, uint32_t rgb) |
{ |
*((uint32_t *) dst) = rgb & 0xffffff; |
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) | |
(RED(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (BLUE(rgb, 8))); |
} |
/** ABGR 8:8:8:8 conversion |
* |
*/ |
static void bgr_0888(void *dst, uint32_t rgb) |
{ |
*((uint32_t *) dst) |
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8); |
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) | |
(BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (RED(rgb, 8))); |
} |
static void rgb_8880(void *dst, uint32_t rgb) |
{ |
*((uint32_t *) dst) = host2uint32_t_be((RED(rgb, 8) << 24) | |
(GREEN(rgb, 8) << 16) | (BLUE(rgb, 8) << 8) | 0); |
} |
/** RGB 8:8:8 conversion |
* |
*/ |
static void bgr_8880(void *dst, uint32_t rgb) |
{ |
*((uint32_t *) dst) = host2uint32_t_be((BLUE(rgb, 8) << 24) | |
(GREEN(rgb, 8) << 16) | (RED(rgb, 8) << 8) | 0); |
} |
static void rgb_888(void *dst, uint32_t rgb) |
{ |
((uint8_t *) dst)[0] = BLUE(rgb, 8); |
((uint8_t *) dst)[0] = RED(rgb, 8); |
((uint8_t *) dst)[1] = GREEN(rgb, 8); |
((uint8_t *) dst)[2] = RED(rgb, 8); |
((uint8_t *) dst)[2] = BLUE(rgb, 8); |
} |
/** BGR 8:8:8 conversion |
* |
*/ |
static void bgr_888(void *dst, uint32_t rgb) |
{ |
((uint8_t *) dst)[0] = RED(rgb, 8); |
((uint8_t *) dst)[0] = BLUE(rgb, 8); |
((uint8_t *) dst)[1] = GREEN(rgb, 8); |
((uint8_t *) dst)[2] = BLUE(rgb, 8); |
((uint8_t *) dst)[2] = RED(rgb, 8); |
} |
static void rgb_555_be(void *dst, uint32_t rgb) |
{ |
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 10 | |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5)); |
} |
/** RGB 5:5:5 conversion |
* |
*/ |
static void rgb_555(void *dst, uint32_t rgb) |
static void rgb_555_le(void *dst, uint32_t rgb) |
{ |
*((uint16_t *) dst) |
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5); |
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 10 | |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5)); |
} |
static void rgb_565_be(void *dst, uint32_t rgb) |
{ |
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 11 | |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5)); |
} |
/** RGB 5:6:5 conversion |
* |
*/ |
static void rgb_565(void *dst, uint32_t rgb) |
static void rgb_565_le(void *dst, uint32_t rgb) |
{ |
*((uint16_t *) dst) |
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5); |
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 11 | |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5)); |
} |
/** RGB 3:2:3 |
/** BGR 3:2:3 |
* |
* Even though we try 3:2:3 color scheme here, an 8-bit framebuffer |
* will most likely use a color palette. The color appearance |
176,7 → 187,7 |
* 0 and 255 to other colors. |
* |
*/ |
static void rgb_323(void *dst, uint32_t rgb) |
static void bgr_323(void *dst, uint32_t rgb) |
{ |
*((uint8_t *) dst) |
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3)); |
450,17 → 461,25 |
{ |
switch (props->visual) { |
case VISUAL_INDIRECT_8: |
rgb_conv = rgb_323; |
rgb_conv = bgr_323; |
pixelbytes = 1; |
break; |
case VISUAL_RGB_5_5_5: |
rgb_conv = rgb_555; |
case VISUAL_RGB_5_5_5_LE: |
rgb_conv = rgb_555_le; |
pixelbytes = 2; |
break; |
case VISUAL_RGB_5_6_5: |
rgb_conv = rgb_565; |
case VISUAL_RGB_5_5_5_BE: |
rgb_conv = rgb_555_be; |
pixelbytes = 2; |
break; |
case VISUAL_RGB_5_6_5_LE: |
rgb_conv = rgb_565_le; |
pixelbytes = 2; |
break; |
case VISUAL_RGB_5_6_5_BE: |
rgb_conv = rgb_565_be; |
pixelbytes = 2; |
break; |
case VISUAL_RGB_8_8_8: |
rgb_conv = rgb_888; |
pixelbytes = 3; |
470,7 → 489,7 |
pixelbytes = 3; |
break; |
case VISUAL_RGB_8_8_8_0: |
rgb_conv = rgb_888; |
rgb_conv = rgb_8880; |
pixelbytes = 4; |
break; |
case VISUAL_RGB_0_8_8_8: |
481,6 → 500,10 |
rgb_conv = bgr_0888; |
pixelbytes = 4; |
break; |
case VISUAL_BGR_8_8_8_0: |
rgb_conv = bgr_8880; |
pixelbytes = 4; |
break; |
default: |
panic("Unsupported visual."); |
} |
/branches/tracing/kernel/genarch/src/mm/asid.c |
---|
65,7 → 65,7 |
#include <adt/list.h> |
#include <debug.h> |
static count_t asids_allocated = 0; |
static size_t asids_allocated = 0; |
/** Allocate free address space identifier. |
* |
120,7 → 120,7 |
* of TLB entries (e.g. TSB on sparc64), the |
* cache must be invalidated as well. |
*/ |
as_invalidate_translation_cache(as, 0, (count_t) -1); |
as_invalidate_translation_cache(as, 0, (size_t) -1); |
/* |
* Get the system rid of the stolen ASID. |
/branches/tracing/kernel/genarch/src/mm/page_ht.c |
---|
51,8 → 51,8 |
#include <adt/hash_table.h> |
#include <align.h> |
static index_t hash(unative_t key[]); |
static bool compare(unative_t key[], count_t keys, link_t *item); |
static size_t hash(unative_t key[]); |
static bool compare(unative_t key[], size_t keys, link_t *item); |
static void remove_callback(link_t *item); |
static void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, |
93,11 → 93,11 |
* |
* @return Index into page hash table. |
*/ |
index_t hash(unative_t key[]) |
size_t hash(unative_t key[]) |
{ |
as_t *as = (as_t *) key[KEY_AS]; |
uintptr_t page = (uintptr_t) key[KEY_PAGE]; |
index_t index; |
size_t index; |
/* |
* Virtual page addresses have roughly the same probability |
124,7 → 124,7 |
* |
* @return true on match, false otherwise. |
*/ |
bool compare(unative_t key[], count_t keys, link_t *item) |
bool compare(unative_t key[], size_t keys, link_t *item) |
{ |
pte_t *t; |
192,6 → 192,8 |
t->k = !(flags & PAGE_USER); |
t->c = (flags & PAGE_CACHEABLE) != 0; |
t->p = !(flags & PAGE_NOT_PRESENT); |
t->a = false; |
t->d = false; |
t->as = as; |
t->page = ALIGN_DOWN(page, PAGE_SIZE); |
/branches/tracing/kernel/genarch/src/ofw/ebus.c |
---|
49,7 → 49,7 |
{ |
ofw_tree_property_t *prop; |
ofw_ebus_range_t *range; |
count_t ranges; |
size_t ranges; |
prop = ofw_tree_getprop(node, "ranges"); |
if (!prop) |
91,7 → 91,7 |
return false; |
ofw_ebus_intr_map_t *intr_map = prop->value; |
count_t count = prop->size / sizeof(ofw_ebus_intr_map_t); |
size_t count = prop->size / sizeof(ofw_ebus_intr_map_t); |
ASSERT(count); |
/branches/tracing/kernel/genarch/src/ofw/fhc.c |
---|
46,7 → 46,7 |
{ |
ofw_tree_property_t *prop; |
ofw_fhc_range_t *range; |
count_t ranges; |
size_t ranges; |
prop = ofw_tree_getprop(node, "ranges"); |
if (!prop) |
88,7 → 88,7 |
ofw_tree_property_t *prop; |
ofw_central_range_t *range; |
count_t ranges; |
size_t ranges; |
prop = ofw_tree_getprop(node, "ranges"); |
if (!prop) |
/branches/tracing/kernel/genarch/src/ofw/ofw_tree.c |
---|
247,7 → 247,8 |
{ |
char buf[NAME_BUF_LEN + 1]; |
ofw_tree_node_t *node = ofw_root; |
index_t i, j; |
size_t i; |
size_t j; |
if (path[0] != '/') |
return NULL; |
/branches/tracing/kernel/genarch/src/ofw/pci.c |
---|
54,7 → 54,7 |
{ |
ofw_tree_property_t *prop; |
ofw_pci_range_t *range; |
count_t ranges; |
size_t ranges; |
prop = ofw_tree_getprop(node, "ranges"); |
if (!prop) { |
97,7 → 97,7 |
ofw_tree_property_t *prop; |
ofw_pci_reg_t *assigned_address; |
count_t assigned_addresses; |
size_t assigned_addresses; |
prop = ofw_tree_getprop(node, "assigned-addresses"); |
if (!prop) |
/branches/tracing/kernel/genarch/src/ofw/sbus.c |
---|
43,7 → 43,7 |
{ |
ofw_tree_property_t *prop; |
ofw_sbus_range_t *range; |
count_t ranges; |
size_t ranges; |
/* |
* The SBUS support is very rudimentary in that we simply assume |
/branches/tracing/kernel/genarch/src/acpi/madt.c |
---|
62,11 → 62,11 |
struct madt_l_apic *madt_l_apic_entries = NULL; |
struct madt_io_apic *madt_io_apic_entries = NULL; |
index_t madt_l_apic_entry_index = 0; |
index_t madt_io_apic_entry_index = 0; |
count_t madt_l_apic_entry_cnt = 0; |
count_t madt_io_apic_entry_cnt = 0; |
count_t cpu_count = 0; |
size_t madt_l_apic_entry_index = 0; |
size_t madt_io_apic_entry_index = 0; |
size_t madt_l_apic_entry_cnt = 0; |
size_t madt_io_apic_entry_cnt = 0; |
size_t cpu_count = 0; |
struct madt_apic_header * * madt_entries_index = NULL; |
unsigned int madt_entries_index_cnt = 0; |
86,10 → 86,10 |
/* |
* ACPI MADT Implementation of SMP configuration interface. |
*/ |
static count_t madt_cpu_count(void); |
static bool madt_cpu_enabled(index_t i); |
static bool madt_cpu_bootstrap(index_t i); |
static uint8_t madt_cpu_apic_id(index_t i); |
static size_t madt_cpu_count(void); |
static bool madt_cpu_enabled(size_t i); |
static bool madt_cpu_bootstrap(size_t i); |
static uint8_t madt_cpu_apic_id(size_t i); |
static int madt_irq_to_pin(unsigned int irq); |
struct smp_config_operations madt_config_operations = { |
100,12 → 100,12 |
.irq_to_pin = madt_irq_to_pin |
}; |
count_t madt_cpu_count(void) |
size_t madt_cpu_count(void) |
{ |
return madt_l_apic_entry_cnt; |
} |
bool madt_cpu_enabled(index_t i) |
bool madt_cpu_enabled(size_t i) |
{ |
ASSERT(i < madt_l_apic_entry_cnt); |
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1; |
112,13 → 112,13 |
} |
bool madt_cpu_bootstrap(index_t i) |
bool madt_cpu_bootstrap(size_t i) |
{ |
ASSERT(i < madt_l_apic_entry_cnt); |
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id(); |
} |
uint8_t madt_cpu_apic_id(index_t i) |
uint8_t madt_cpu_apic_id(size_t i) |
{ |
ASSERT(i < madt_l_apic_entry_cnt); |
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id; |
/branches/tracing/kernel/genarch/src/acpi/acpi.c |
---|
167,10 → 167,13 |
LOG("%p: ACPI Root System Description Pointer\n", acpi_rsdp); |
acpi_rsdt = (struct acpi_rsdt *) (unative_t) acpi_rsdp->rsdt_address; |
if (acpi_rsdp->revision) acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address); |
if (acpi_rsdp->revision) |
acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address); |
if (acpi_rsdt) map_sdt((struct acpi_sdt_header *) acpi_rsdt); |
if (acpi_xsdt) map_sdt((struct acpi_sdt_header *) acpi_xsdt); |
if (acpi_rsdt) |
map_sdt((struct acpi_sdt_header *) acpi_rsdt); |
if (acpi_xsdt) |
map_sdt((struct acpi_sdt_header *) acpi_xsdt); |
if (acpi_rsdt && !acpi_sdt_check((uint8_t *) acpi_rsdt)) { |
printf("RSDT: bad checksum\n"); |
181,8 → 184,10 |
return; |
} |
if (acpi_xsdt) configure_via_xsdt(); |
else if (acpi_rsdt) configure_via_rsdt(); |
if (acpi_xsdt) |
configure_via_xsdt(); |
else if (acpi_rsdt) |
configure_via_rsdt(); |
} |
/branches/tracing/kernel/genarch/src/drivers/pl050/pl050.c |
---|
0,0 → 1,117 |
/* |
* Copyright (c) 2009 Vineeth Pillai |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief pl050 keyboard/mouse driver. |
* |
* It takes care of low-level keyboard functions. |
*/ |
#include <genarch/drivers/pl050/pl050.h> |
#include <arch/asm.h> |
#include <console/chardev.h> |
#include <mm/slab.h> |
#include <ddi/device.h> |
#define PL050_KEY_RELEASE 0xF0 |
#define PL050_ESC_KEY 0xE0 |
#define PL050_CAPS_SCAN_CODE 0x58 |
/** Structure for pl050's IRQ. */ |
static pl050_t *pl050; |
static irq_ownership_t pl050_claim(irq_t *irq) |
{ |
uint8_t status; |
if ((status = pio_read_8(pl050->status)) & PL050_STAT_RXFULL) |
return IRQ_ACCEPT; |
else { |
return IRQ_DECLINE; |
} |
} |
static void pl050_irq_handler(irq_t *irq) |
{ |
uint8_t data; |
uint8_t status; |
pl050_instance_t *instance = irq->instance; |
while ((status = pio_read_8(pl050->status)) & PL050_STAT_RXFULL) { |
data = pio_read_8(pl050->data); |
indev_push_character(instance->kbrdin, data); |
} |
} |
/** Initialize pl050. */ |
pl050_instance_t *pl050_init(pl050_t *dev, inr_t inr) |
{ |
pl050_instance_t *instance = |
malloc(sizeof(pl050_instance_t), FRAME_ATOMIC); |
pl050 = dev; |
if (instance) { |
instance->pl050 = dev; |
instance->kbrdin = NULL; |
irq_initialize(&instance->irq); |
instance->irq.devno = device_assign_devno(); |
instance->irq.inr = inr; |
instance->irq.claim = pl050_claim; |
instance->irq.handler = pl050_irq_handler; |
instance->irq.instance = instance; |
} |
return instance; |
} |
void pl050_wire(pl050_instance_t *instance, indev_t *kbrdin) |
{ |
uint8_t val; |
instance->kbrdin = kbrdin; |
irq_register(&instance->irq); |
val = PL050_CR_RXINTR | PL050_CR_INTR; |
pio_write_8(pl050->ctrl, val); |
/* reset the data buffer */ |
pio_read_8(pl050->data); |
} |
/** @} |
*/ |
/branches/tracing/kernel/genarch/src/drivers/via-cuda/cuda.c |
---|
1,5 → 1,6 |
/* |
* Copyright (c) 2006 Martin Decky |
* Copyright (c) 2009 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
38,16 → 39,53 |
#include <arch/asm.h> |
#include <mm/slab.h> |
#include <ddi/device.h> |
#include <synch/spinlock.h> |
static irq_ownership_t cuda_claim(irq_t *irq) |
{ |
return IRQ_DECLINE; |
} |
static irq_ownership_t cuda_claim(irq_t *irq); |
static void cuda_irq_handler(irq_t *irq); |
static void cuda_irq_handler(irq_t *irq) |
{ |
} |
static void cuda_irq_listen(irq_t *irq); |
static void cuda_irq_receive(irq_t *irq); |
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len); |
static void cuda_irq_send_start(irq_t *irq); |
static void cuda_irq_send(irq_t *irq); |
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *buf, size_t len); |
static void cuda_send_start(cuda_instance_t *instance); |
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable); |
/** B register fields */ |
enum { |
TREQ = 0x08, |
TACK = 0x10, |
TIP = 0x20 |
}; |
/** IER register fields */ |
enum { |
IER_CLR = 0x00, |
IER_SET = 0x80, |
SR_INT = 0x04, |
ALL_INT = 0x7f |
}; |
/** ACR register fields */ |
enum { |
SR_OUT = 0x10 |
}; |
/** Packet types */ |
enum { |
PT_ADB = 0x00, |
PT_CUDA = 0x01 |
}; |
/** CUDA packet types */ |
enum { |
CPT_AUTOPOLL = 0x01 |
}; |
cuda_instance_t *cuda_init(cuda_t *dev, inr_t inr, cir_t cir, void *cir_arg) |
{ |
cuda_instance_t *instance |
55,7 → 93,15 |
if (instance) { |
instance->cuda = dev; |
instance->kbrdin = NULL; |
instance->xstate = cx_listen; |
instance->bidx = 0; |
instance->snd_bytes = 0; |
spinlock_initialize(&instance->dev_lock, "cuda_dev"); |
/* Disable all interrupts from CUDA. */ |
pio_write_8(&dev->ier, IER_CLR | ALL_INT); |
irq_initialize(&instance->irq); |
instance->irq.devno = device_assign_devno(); |
instance->irq.inr = inr; |
64,15 → 110,251 |
instance->irq.instance = instance; |
instance->irq.cir = cir; |
instance->irq.cir_arg = cir_arg; |
instance->irq.preack = true; |
} |
return instance; |
} |
#include <print.h> |
void cuda_wire(cuda_instance_t *instance, indev_t *kbrdin) |
{ |
cuda_t *dev = instance->cuda; |
ASSERT(instance); |
ASSERT(kbrdin); |
instance->kbrdin = kbrdin; |
irq_register(&instance->irq); |
/* Enable SR interrupt. */ |
pio_write_8(&dev->ier, TIP | TREQ); |
pio_write_8(&dev->ier, IER_SET | SR_INT); |
/* Enable ADB autopolling. */ |
cuda_autopoll_set(instance, true); |
} |
static irq_ownership_t cuda_claim(irq_t *irq) |
{ |
cuda_instance_t *instance = irq->instance; |
cuda_t *dev = instance->cuda; |
uint8_t ifr; |
spinlock_lock(&instance->dev_lock); |
ifr = pio_read_8(&dev->ifr); |
spinlock_unlock(&instance->dev_lock); |
if ((ifr & SR_INT) == 0) |
return IRQ_DECLINE; |
return IRQ_ACCEPT; |
} |
static void cuda_irq_handler(irq_t *irq) |
{ |
cuda_instance_t *instance = irq->instance; |
uint8_t rbuf[CUDA_RCV_BUF_SIZE]; |
size_t len; |
bool handle; |
handle = false; |
len = 0; |
spinlock_lock(&instance->dev_lock); |
/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */ |
pio_write_8(&instance->cuda->ifr, SR_INT); |
switch (instance->xstate) { |
case cx_listen: cuda_irq_listen(irq); break; |
case cx_receive: cuda_irq_receive(irq); break; |
case cx_rcv_end: cuda_irq_rcv_end(irq, rbuf, &len); |
handle = true; break; |
case cx_send_start: cuda_irq_send_start(irq); break; |
case cx_send: cuda_irq_send(irq); break; |
} |
spinlock_unlock(&instance->dev_lock); |
/* Handle an incoming packet. */ |
if (handle) |
cuda_packet_handle(instance, rbuf, len); |
} |
/** Interrupt in listen state. |
* |
* Start packet reception. |
*/ |
static void cuda_irq_listen(irq_t *irq) |
{ |
cuda_instance_t *instance = irq->instance; |
cuda_t *dev = instance->cuda; |
uint8_t b; |
b = pio_read_8(&dev->b); |
if ((b & TREQ) != 0) { |
printf("cuda_irq_listen: no TREQ?!\n"); |
return; |
} |
pio_read_8(&dev->sr); |
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP); |
instance->xstate = cx_receive; |
} |
/** Interrupt in receive state. |
* |
* Receive next byte of packet. |
*/ |
static void cuda_irq_receive(irq_t *irq) |
{ |
cuda_instance_t *instance = irq->instance; |
cuda_t *dev = instance->cuda; |
uint8_t b, data; |
data = pio_read_8(&dev->sr); |
if (instance->bidx < CUDA_RCV_BUF_SIZE) |
instance->rcv_buf[instance->bidx++] = data; |
b = pio_read_8(&dev->b); |
if ((b & TREQ) == 0) { |
pio_write_8(&dev->b, b ^ TACK); |
} else { |
pio_write_8(&dev->b, b | TACK | TIP); |
instance->xstate = cx_rcv_end; |
} |
} |
/** Interrupt in rcv_end state. |
* |
* Terminate packet reception. Either go back to listen state or start |
* receiving another packet if CUDA has one for us. |
*/ |
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len) |
{ |
cuda_instance_t *instance = irq->instance; |
cuda_t *dev = instance->cuda; |
uint8_t data, b; |
b = pio_read_8(&dev->b); |
data = pio_read_8(&dev->sr); |
if ((b & TREQ) == 0) { |
instance->xstate = cx_receive; |
pio_write_8(&dev->b, b & ~TIP); |
} else { |
instance->xstate = cx_listen; |
cuda_send_start(instance); |
} |
memcpy(buf, instance->rcv_buf, instance->bidx); |
*len = instance->bidx; |
instance->bidx = 0; |
} |
/** Interrupt in send_start state. |
* |
* Process result of sending first byte (and send second on success). |
*/ |
static void cuda_irq_send_start(irq_t *irq) |
{ |
cuda_instance_t *instance = irq->instance; |
cuda_t *dev = instance->cuda; |
uint8_t b; |
b = pio_read_8(&dev->b); |
if ((b & TREQ) == 0) { |
/* Collision */ |
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT); |
pio_read_8(&dev->sr); |
pio_write_8(&dev->b, pio_read_8(&dev->b) | TIP | TACK); |
instance->xstate = cx_listen; |
return; |
} |
pio_write_8(&dev->sr, instance->snd_buf[1]); |
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK); |
instance->bidx = 2; |
instance->xstate = cx_send; |
} |
/** Interrupt in send state. |
* |
* Send next byte or terminate transmission. |
*/ |
static void cuda_irq_send(irq_t *irq) |
{ |
cuda_instance_t *instance = irq->instance; |
cuda_t *dev = instance->cuda; |
if (instance->bidx < instance->snd_bytes) { |
/* Send next byte. */ |
pio_write_8(&dev->sr, instance->snd_buf[instance->bidx++]); |
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK); |
return; |
} |
/* End transfer. */ |
instance->snd_bytes = 0; |
instance->bidx = 0; |
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT); |
pio_read_8(&dev->sr); |
pio_write_8(&dev->b, pio_read_8(&dev->b) | TACK | TIP); |
instance->xstate = cx_listen; |
/* TODO: Match reply with request. */ |
} |
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *data, size_t len) |
{ |
if (data[0] != 0x00 || data[1] != 0x40 || (data[2] != 0x2c |
&& data[2] != 0x8c)) |
return; |
/* The packet contains one or two scancodes. */ |
if (data[3] != 0xff) |
indev_push_character(instance->kbrdin, data[3]); |
if (data[4] != 0xff) |
indev_push_character(instance->kbrdin, data[4]); |
} |
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable) |
{ |
instance->snd_buf[0] = PT_CUDA; |
instance->snd_buf[1] = CPT_AUTOPOLL; |
instance->snd_buf[2] = enable ? 0x01 : 0x00; |
instance->snd_bytes = 3; |
instance->bidx = 0; |
cuda_send_start(instance); |
} |
static void cuda_send_start(cuda_instance_t *instance) |
{ |
cuda_t *dev = instance->cuda; |
ASSERT(instance->xstate == cx_listen); |
if (instance->snd_bytes == 0) |
return; |
/* Check for incoming data. */ |
if ((pio_read_8(&dev->b) & TREQ) == 0) |
return; |
pio_write_8(&dev->acr, pio_read_8(&dev->acr) | SR_OUT); |
pio_write_8(&dev->sr, instance->snd_buf[0]); |
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP); |
instance->xstate = cx_send_start; |
} |
/** @} |
*/ |