/branches/arm/kernel/genarch/include/kbd/pl050.h |
---|
0,0 → 1,94 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* 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 arm32 |
* @{ |
*/ |
/** @file |
*/ |
/** |
* This file implements pl050 specific functions for keyboard and mouse |
*/ |
#ifndef KERN_PL050_H |
#define KERN_PL050_H |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <console/chardev.h> |
/* |
* pl050 register offsets from the base address |
*/ |
#define PL050_CR 0x00 |
#define PL050_STAT 0x04 |
#define PL050_DATA 0x08 |
#define PL050_CLOCKDIV 0x0C |
#define PL050_INTRSTAT 0x10 |
/* |
* Control Register Bits |
*/ |
#define PL050_CR_TYPE (1 << 5) /* Type 0: PS2/AT mode, 1: No Line control bit mode */ |
#define PL050_CR_RXINTR (1 << 4) /* Recieve Interrupt Enable */ |
#define PL050_CR_TXINTR (1 << 3) /* Transmit Interrupt Enable */ |
#define PL050_CR_INTR (1 << 2) /* Interrupt Enable */ |
#define PL050_CR_FKMID (1 << 1) /* Force KMI Data Low */ |
#define PL050_CR_FKMIC 1 /* Force KMI Clock Low */ |
/* |
* Status register bits |
*/ |
#define PL050_STAT_TXEMPTY (1 << 6) /* 1: Transmit register empty */ |
#define PL050_STAT_TXBUSY (1 << 5) /* 1: Busy, sending data */ |
#define PL050_STAT_RXFULL (1 << 4) /* 1: register Full */ |
#define PL050_STAT_RXBUSY (1 << 3) /* 1: Busy, recieving Data */ |
#define PL050_STAT_RXPARITY (1 << 2) /* odd parity of the last bit recieved */ |
#define PL050_STAT_KMIC (1 << 1) /* status of KMICLKIN */ |
#define PL050_STAT_KMID 1 /* status of KMIDATAIN */ |
/* |
* Interrupt status register bits. |
*/ |
#define PL050_TX_INTRSTAT (1 << 1) /* Transmit intr asserted */ |
#define PL050_RX_INTRSTAT 1 /* Recieve intr asserted */ |
void pl050_grab(void); |
void pl050_release(void); |
char pl050_key_read(chardev_t *); |
uint8_t pl050_dataread(void); |
uint8_t pl050_statusread(void); |
void pl050_crwrite(uint8_t val); |
void pl050_poll(void); |
void pl050_init(devno_t, inr_t, uintptr_t, uintptr_t); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/genarch/Makefile.inc |
---|
72,6 → 72,13 |
genarch/src/kbd/scanc_pc.c |
endif |
## pl050 controller |
ifeq ($(CONFIG_PL050),y) |
GENARCH_SOURCES += \ |
genarch/src/kbd/key.c \ |
genarch/src/kbd/scanc_pl050.c |
DEFS += -DCONFIG_PL050 |
endif |
## Sun keyboard |
ifeq ($(CONFIG_SUN_KBD),y) |
GENARCH_SOURCES += \ |
/branches/arm/kernel/genarch/src/kbd/scanc_pl050.c |
---|
0,0 → 1,233 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* 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 Scan codes for pl050 keyboards. |
*/ |
#include <genarch/kbd/scanc.h> |
/** Primary meaning of scancodes. */ |
char sc_primary_map[] = { |
SPECIAL, /* 0x00 */ |
SPECIAL, /* 0x01 - F9 */ |
SPECIAL, /* 0x02 - F7 */ |
SPECIAL, /* 0x03 - F5 */ |
SPECIAL, /* 0x04 - F3 */ |
SPECIAL, /* 0x05 - F1 */ |
SPECIAL, /* 0x06 - F2 */ |
SPECIAL, /* 0x07 - F12 */ |
SPECIAL, /* 0x08 - */ |
SPECIAL, /* 0x09 - F10 */ |
SPECIAL, /* 0x0A - F8 */ |
SPECIAL, /* 0x0B - F10 */ |
SPECIAL, /* 0x0C - F4 */ |
'\t', /* 0x0D - Tab */ |
'~', |
SPECIAL, /* 0x0F */ |
SPECIAL, /* 0x10 */ |
SPECIAL, /* 0x11 - LAlt */ |
SPECIAL, /* 0x12 - LShift */ |
SPECIAL, /* ox13 */ |
SPECIAL, /* 0x14 Ctrl */ |
'q', '1', |
SPECIAL, /* 0x17 */ |
SPECIAL, /* 0x18 */ |
SPECIAL, /* 0x19 */ |
'z', 's', 'a', 'w', '2', |
SPECIAL, /* 0x1F */ |
SPECIAL, /* 0x20 */ |
'c', 'x', 'd', 'e', '4', '3', |
SPECIAL, /* 0x27 */ |
SPECIAL, /* 0x28 */ |
' ', 'v', 'f', 't', 'r', '5', |
SPECIAL, /* 0x2F */ |
SPECIAL, /* 0x30 */ |
'n', 'b', 'h', 'g', 'y', '6', |
SPECIAL, /* 0x37 */ |
SPECIAL, /* 0x38 */ |
SPECIAL, /* 0x39 */ |
'm', 'j', 'u', '7', '8', |
SPECIAL, /* 0x3F */ |
SPECIAL, /* 0x40 */ |
',', 'k', 'i', 'o', '0', '9', |
SPECIAL, /* 0x47 */ |
SPECIAL, /* 0x48 */ |
'.', '/', 'l', ';', 'p', '-', |
SPECIAL, /* 0x4F */ |
SPECIAL, /* 0x50 */ |
'\'', |
SPECIAL, /* 0x52 */ |
SPECIAL, /* 0x53 */ |
'{', '=', |
SPECIAL, /* 0x56 */ |
SPECIAL, /* 0x57 */ |
SPECIAL, /* 0x58 - Caps Lock */ |
SPECIAL, /* 0x59 - RShift */ |
'\n', '}', |
SPECIAL, /* 0x5C */ |
'\\', |
SPECIAL, /* 0x5E */ |
SPECIAL, /* 0x5F */ |
SPECIAL, /* 0x60 */ |
SPECIAL, /* 0x61 */ |
SPECIAL, /* 0x62 */ |
SPECIAL, /* 0x63 */ |
SPECIAL, /* 0x64 */ |
SPECIAL, /* 0x65 */ |
'\b', /* 0x66 - backspace*/ |
SPECIAL, /* 0x67 */ |
SPECIAL, /* 0x68 */ |
SPECIAL, /* 0x69 */ |
SPECIAL, /* 0x6a */ |
SPECIAL, /* 0x6b - Left Arrow */ |
SPECIAL, /* 0x6c */ |
SPECIAL, /* 0x6d */ |
SPECIAL, /* 0x6e */ |
SPECIAL, /* 0x6f */ |
SPECIAL, /* 0x70 - Del */ |
SPECIAL, /* 0x71 */ |
SPECIAL, /* 0x72 Down Arrow */ |
SPECIAL, /* 0x73 */ |
SPECIAL, /* 0x74 - Right Arrow */ |
SPECIAL, /* 0x75 Up Arrow */ |
SPECIAL, /* 0x76 Esc */ |
SPECIAL, /* 0x77 - NumLock*/ |
SPECIAL, /* 0x78 F11*/ |
SPECIAL, /* 0x79 */ |
SPECIAL, /* 0x7a */ |
SPECIAL, /* 0x7b */ |
SPECIAL, /* 0x7c */ |
SPECIAL, /* 0x7d */ |
SPECIAL, /* 0x7e */ |
SPECIAL /* 0x7f */ |
}; |
/** Secondary meaning of scancodes. */ |
char sc_secondary_map[] = { |
SPECIAL, /* 0x00 */ |
SPECIAL, /* 0x01 - F9 */ |
SPECIAL, /* 0x02 - F7 */ |
SPECIAL, /* 0x03 - F5 */ |
SPECIAL, /* 0x04 - F3 */ |
SPECIAL, /* 0x05 - F1 */ |
SPECIAL, /* 0x06 - F2 */ |
SPECIAL, /* 0x07 - F12 */ |
SPECIAL, /* 0x08 - */ |
SPECIAL, /* 0x09 - F10 */ |
SPECIAL, /* 0x0A - F8 */ |
SPECIAL, /* 0x0B - F10 */ |
SPECIAL, /* 0x0C - F4 */ |
'\t', /* 0x0D - Tab */ |
'~', |
SPECIAL, /* 0x0F */ |
SPECIAL, /* 0x10 */ |
SPECIAL, /* 0x11 - LAlt */ |
SPECIAL, /* 0x12 - LShift */ |
SPECIAL, /* ox13 */ |
SPECIAL, /* 0x14 Ctrl */ |
'Q', '!', |
SPECIAL, /* 0x17 */ |
SPECIAL, /* 0x18 */ |
SPECIAL, /* 0x19 */ |
'Z', 'S', 'A', 'W', '@', |
SPECIAL, /* 0x1F */ |
SPECIAL, /* 0x20 */ |
'C', 'X', 'D', 'E', '$', '#', |
SPECIAL, /* 0x27 */ |
SPECIAL, /* 0x28 */ |
' ', 'V', 'F', 'T', 'R', '%', |
SPECIAL, /* 0x2F */ |
SPECIAL, /* 0x30 */ |
'N', 'B', 'H', 'G', 'Y', '^', |
SPECIAL, /* 0x37 */ |
SPECIAL, /* 0x38 */ |
SPECIAL, /* 0x39 */ |
'M', 'J', 'U', '&', '*', |
SPECIAL, /* 0x3F */ |
SPECIAL, /* 0x40 */ |
'<', 'K', 'I', 'O', ')', '(', |
SPECIAL, /* 0x47 */ |
SPECIAL, /* 0x48 */ |
'>', '?', 'L', ':', 'P', '_', |
SPECIAL, /* 0x4F */ |
SPECIAL, /* 0x50 */ |
'"', |
SPECIAL, /* 0x52 */ |
SPECIAL, /* 0x53 */ |
'{', '+', |
SPECIAL, /* 0x56 */ |
SPECIAL, /* 0x57 */ |
SPECIAL, /* 0x58 - Caps Lock */ |
SPECIAL, /* 0x59 - RShift */ |
'\n', '}', |
SPECIAL, /* 0x5C */ |
'|', |
SPECIAL, /* 0x5E */ |
SPECIAL, /* 0x5F */ |
SPECIAL, /* 0x60 */ |
SPECIAL, /* 0x61 */ |
SPECIAL, /* 0x62 */ |
SPECIAL, /* 0x63 */ |
SPECIAL, /* 0x64 */ |
SPECIAL, /* 0x65 */ |
'\b', /* 0x66 - backspace*/ |
SPECIAL, /* 0x67 */ |
SPECIAL, /* 0x68 */ |
SPECIAL, /* 0x69 */ |
SPECIAL, /* 0x6a */ |
SPECIAL, /* 0x6b - Left Arrow */ |
SPECIAL, /* 0x6c */ |
SPECIAL, /* 0x6d */ |
SPECIAL, /* 0x6e */ |
SPECIAL, /* 0x6f */ |
SPECIAL, /* 0x70 - Del */ |
SPECIAL, /* 0x71 */ |
SPECIAL, /* 0x72 Down Arrow */ |
SPECIAL, /* 0x73 */ |
SPECIAL, /* 0x74 - Right Arrow */ |
SPECIAL, /* 0x75 Up Arrow */ |
SPECIAL, /* 0x76 Esc */ |
SPECIAL, /* 0x77 - NumLock*/ |
SPECIAL, /* 0x78 F11*/ |
SPECIAL, /* 0x79 */ |
SPECIAL, /* 0x7a */ |
SPECIAL, /* 0x7b */ |
SPECIAL, /* 0x7c */ |
SPECIAL, /* 0x7d */ |
SPECIAL, /* 0x7e */ |
SPECIAL /* 0x7f */ |
}; |
/** @} |
*/ |
/branches/arm/kernel/genarch/src/kbd/key.c |
---|
39,6 → 39,9 |
#ifdef CONFIG_I8042 |
#include <genarch/kbd/scanc_pc.h> |
#endif |
#ifdef CONFIG_PL050 |
#include <genarch/kbd/scanc_pl050.h> |
#endif |
#if (defined(CONFIG_Z8530) || defined(CONFIG_NS16550)) |
#include <genarch/kbd/scanc_sun.h> |
#endif |
/branches/arm/kernel/arch/arm32/include/drivers/pl050.h |
---|
0,0 → 1,93 |
/* |
* 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 arm32 |
* @{ |
*/ |
/** @file |
*/ |
/** |
* This file implements pl050 specific functions for keyboard and mouse |
*/ |
#ifndef KERN_arm32_PL050_H |
#define KERN_arm32_PL050_H |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <console/chardev.h> |
/* |
* pl050 register offsets from the base address |
*/ |
#define PL050_CR 0x00 |
#define PL050_STAT 0x04 |
#define PL050_DATA 0x08 |
#define PL050_CLOCKDIV 0x0C |
#define PL050_INTRSTAT 0x10 |
/* |
* Control Register Bits |
*/ |
#define PL050_CR_TYPE (1 << 5) /* Type 0: PS2/AT mode, 1: No Line control bit mode */ |
#define PL050_CR_RXINTR (1 << 4) /* Recieve Interrupt Enable */ |
#define PL050_CR_TXINTR (1 << 3) /* Transmit Interrupt Enable */ |
#define PL050_CR_INTR (1 << 2) /* Interrupt Enable */ |
#define PL050_CR_FKMID (1 << 1) /* Force KMI Data Low */ |
#define PL050_CR_FKMIC 1 /* Force KMI Clock Low */ |
/* |
* Status register bits |
*/ |
#define PL050_STAT_TXEMPTY (1 << 6) /* 1: Transmit register empty */ |
#define PL050_STAT_TXBUSY (1 << 5) /* 1: Busy, sending data */ |
#define PL050_STAT_RXFULL (1 << 4) /* 1: register Full */ |
#define PL050_STAT_RXBUSY (1 << 3) /* 1: Busy, recieving Data */ |
#define PL050_STAT_RXPARITY (1 << 2) /* odd parity of the last bit recieved */ |
#define PL050_STAT_KMIC (1 << 1) /* status of KMICLKIN */ |
#define PL050_STAT_KMID 1 /* status of KMIDATAIN */ |
/* |
* Interrupt status register bits. |
*/ |
#define PL050_TX_INTRSTAT (1 << 1) /* Transmit intr asserted */ |
#define PL050_RX_INTRSTAT 1 /* Recieve intr asserted */ |
void pl050_grab(void); |
void pl050_release(void); |
char pl050_key_read(chardev_t *); |
uint8_t pl050_dataread(void); |
uint8_t pl050_statusread(void); |
void pl050_crwrite(uint8_t val); |
void pl050_poll(void); |
void pl050_init(devno_t, inr_t, uintptr_t, uintptr_t); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/Makefile.inc |
---|
70,6 → 70,7 |
# no HW support for ASIDs |
#CONFIG_ASID = y |
#CONFIG_ASID_FIFO = y |
CONFIG_PL050 = y |
## Compile with support with software division and multiplication. |
# |
99,6 → 100,7 |
ifeq ($(MACHINE), gxemul_testarm) |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/gxemul.c |
else ifeq ($(MACHINE), qemu_icp) |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/qemu.c |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/qemu.c \ |
arch/$(ARCH)/src/drivers/pl050.c |
endif |
/branches/arm/kernel/arch/arm32/src/drivers/pl050.c |
---|
0,0 → 1,225 |
/* |
* 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 arm32 |
* @{ |
*/ |
/** |
* @file |
* @brief pl050 keyboard/mouse driver. |
* |
* It takes care of low-level keyboard functions. |
*/ |
#include <genarch/kbd/key.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <arch.h> |
#include <arch/drivers/pl050.h> |
#include <console/console.h> |
#include <interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <ipc/irq.h> |
#include <arch/debug/print.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <print.h> |
#define PL050_KEY_RELEASE 0xF0 |
#define PL050_ESC_KEY 0xE0 |
static void pl050_suspend(chardev_t *); |
static void pl050_resume(chardev_t *); |
static chardev_operations_t ops = { |
.suspend = pl050_suspend, |
.resume = pl050_resume, |
.read = pl050_key_read |
}; |
/** Structure for pl050's IRQ. */ |
static irq_t pl050_kbd_irq; |
/* static irq_t pl050_mouse_irq; */ |
static uintptr_t pl050_kbd_pbase; |
static uintptr_t pl050_kbd_vbase; |
uint8_t pl050_dataread(void) |
{ |
return *(uint8_t *)(pl050_kbd_vbase + PL050_DATA); |
} |
uint8_t pl050_statusread(void) |
{ |
return *(uint8_t *)(pl050_kbd_vbase + PL050_STAT); |
} |
void pl050_crwrite(uint8_t val) |
{ |
*(uint8_t *)pl050_kbd_vbase = val; |
} |
void pl050_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&pl050_kbd_irq.lock); |
pl050_kbd_irq.notif_cfg.notify = false; |
spinlock_unlock(&pl050_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
void pl050_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&pl050_kbd_irq.lock); |
if (pl050_kbd_irq.notif_cfg.answerbox) |
pl050_kbd_irq.notif_cfg.notify = true; |
spinlock_unlock(&pl050_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
static irq_ownership_t pl050_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static void pl050_irq_handler(irq_t *irq, void *arg, ...) |
{ |
static int key_released_flag = 0; |
static uint8_t prev_char = 0xFF; |
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) |
ipc_irq_send_notif(irq); |
else { |
uint8_t data; |
uint8_t status; |
if (((status = pl050_statusread()) & PL050_STAT_RXFULL)) { |
data = pl050_dataread(); |
if (data == PL050_ESC_KEY) |
return; |
if (data == PL050_KEY_RELEASE) { |
key_released_flag = 1; |
} else { |
if (key_released_flag && prev_char == data) { |
prev_char = 0xFF; |
key_released(data); |
} else { |
key_pressed(data); |
prev_char = data; |
} |
key_released_flag = 0; |
} |
} |
} |
} |
/** Initialize pl050. */ |
void pl050_init(devno_t kbd_devno, inr_t kbd_inr, uintptr_t pbase, uintptr_t vbase) |
{ |
uint8_t val = 0; |
chardev_initialize("pl050_kbd", &kbrd, &ops); |
stdin = &kbrd; |
irq_initialize(&pl050_kbd_irq); |
pl050_kbd_irq.devno = kbd_devno; |
pl050_kbd_irq.inr = kbd_inr; |
pl050_kbd_irq.claim = pl050_claim; |
pl050_kbd_irq.handler = pl050_irq_handler; |
pl050_kbd_pbase = pbase; |
pl050_kbd_vbase = vbase; |
irq_register(&pl050_kbd_irq); |
val = PL050_CR_RXINTR | PL050_CR_INTR | PL050_CR_FKMIC; |
pl050_crwrite(val); |
/* reset the data buffer */ |
pl050_dataread(); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, kbd_devno); |
sysinfo_set_item_val("kbd.inr", NULL, kbd_inr); |
sysinfo_set_item_val("kbd.pbase", NULL, pl050_kbd_pbase); |
sysinfo_set_item_val("kbd.vbase", NULL, vbase); |
pl050_grab(); |
} |
/* Called from getc(). */ |
void pl050_resume(chardev_t *d) |
{ |
} |
/* Called from getc(). */ |
void pl050_suspend(chardev_t *d) |
{ |
} |
char pl050_key_read(chardev_t *d) |
{ |
char ch; |
while(!(ch = active_read_buff_read())) { |
uint8_t x; |
while (!(pl050_statusread() & PL050_STAT_RXFULL)) |
; |
x = pl050_dataread(); |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
else |
active_read_key_pressed(x); |
} |
return ch; |
} |
/** Poll for key press and release events. |
* |
* This function can be used to implement keyboard polling. |
*/ |
void pl050_poll(void) |
{ |
uint8_t x; |
while (((x = pl050_statusread() & PL050_STAT_RXFULL))) { |
x = pl050_dataread(); |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
else |
key_pressed(x); |
} |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/drivers/qemu.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2007 Michal Kebrt, Petr Stepan |
* Copyright (c) 2009 Vineeth Pillai |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
37,6 → 37,7 |
#include <ipc/irq.h> |
#include <console/chardev.h> |
#include <arch/drivers/qemu.h> |
#include <arch/drivers/pl050.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <print.h> |
76,26 → 77,13 |
#define QEMU_ICP_TIMER_IRQ 6 |
static qemu_icp_hw_map_t qemu_icp_hw_map; |
static chardev_t console; |
static irq_t qemu_icp_console_irq; |
static irq_t qemu_icp_timer_irq; |
static bool hw_map_init_called = false; |
static bool vga_init = false; |
static void qemu_icp_kbd_enable(chardev_t *dev); |
static void qemu_icp_kbd_disable(chardev_t *dev); |
static void qemu_icp_write(chardev_t *dev, const char ch); |
static char qemu_icp_do_read(chardev_t *dev); |
void icp_vga_init(void); |
static chardev_operations_t qemu_icp_ops = { |
.resume = qemu_icp_kbd_enable, |
.suspend = qemu_icp_kbd_disable, |
.write = qemu_icp_write, |
.read = qemu_icp_do_read, |
}; |
/** Initializes the vga |
* |
*/ |
172,108 → 160,17 |
} |
/** Putchar that works with qemu_icp. |
* |
* @param dev Not used. |
* @param ch Characted to be printed. |
*/ |
static void qemu_icp_write(chardev_t *dev, const char ch) |
{ |
*((char *) qemu_icp_hw_map.videoram) = ch; |
} |
/** Enables qemu_icp keyboard (interrupt unmasked). |
* |
* @param dev Not used. |
* |
* Called from getc(). |
*/ |
static void qemu_icp_kbd_enable(chardev_t *dev) |
{ |
qemu_icp_irqc_unmask(QEMU_ICP_KBD_IRQ); |
} |
/** Disables qemu_icp keyboard (interrupt masked). |
* |
* @param dev not used |
* |
* Called from getc(). |
*/ |
static void qemu_icp_kbd_disable(chardev_t *dev) |
{ |
qemu_icp_irqc_mask(QEMU_ICP_KBD_IRQ); |
} |
/** Read character using polling, assume interrupts disabled. |
* |
* @param dev Not used. |
*/ |
static char qemu_icp_do_read(chardev_t *dev) |
{ |
char ch; |
while (1) { |
ch = *((volatile char *) qemu_icp_hw_map.kbd_data); |
if (ch) { |
if (ch == '\r') |
return '\n'; |
if (ch == 0x7f) |
return '\b'; |
return ch; |
} |
} |
} |
/** Process keyboard interrupt. |
* |
* @param irq IRQ information. |
* @param arg Not used. |
*/ |
static void qemu_icp_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) { |
ipc_irq_send_notif(irq); |
} else { |
char ch = 0; |
ch = *((char *) qemu_icp_hw_map.kbd_data); |
if (ch == '\r') { |
ch = '\n'; |
} |
if (ch == 0x7f) { |
ch = '\b'; |
} |
chardev_push_character(&console, ch); |
} |
} |
static irq_ownership_t qemu_icp_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Acquire console back for kernel. */ |
void qemu_icp_grab_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&qemu_icp_console_irq.lock); |
qemu_icp_console_irq.notif_cfg.notify = false; |
spinlock_unlock(&qemu_icp_console_irq.lock); |
interrupts_restore(ipl); |
pl050_grab(); |
} |
/** Return console to userspace. */ |
void qemu_icp_release_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&qemu_icp_console_irq.lock); |
if (qemu_icp_console_irq.notif_cfg.answerbox) { |
qemu_icp_console_irq.notif_cfg.notify = true; |
pl050_release(); |
} |
spinlock_unlock(&qemu_icp_console_irq.lock); |
interrupts_restore(ipl); |
} |
/** Initializes console object representing qemu_icp console. |
* |
281,26 → 178,10 |
*/ |
void qemu_icp_console_init(devno_t devno) |
{ |
chardev_initialize("qemu_icp_console", &console, &qemu_icp_ops); |
stdin = &console; |
stdout = &console; |
qemu_icp_irqc_mask(QEMU_ICP_KBD_IRQ); |
irq_initialize(&qemu_icp_console_irq); |
qemu_icp_console_irq.devno = devno; |
qemu_icp_console_irq.inr = QEMU_ICP_KBD_IRQ; |
qemu_icp_console_irq.claim = qemu_icp_claim; |
qemu_icp_console_irq.handler = qemu_icp_irq_handler; |
irq_register(&qemu_icp_console_irq); |
*(char *)qemu_icp_hw_map.kbd_ctrl = 0x17; |
pl050_init(devno, QEMU_ICP_KBD_IRQ, QEMU_ICP_KBD, qemu_icp_hw_map.kbd_ctrl); |
qemu_icp_irqc_unmask(QEMU_ICP_KBD_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, QEMU_ICP_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, qemu_icp_hw_map.kbd_data); |
} |
/** Starts qemu_icp Real Time Clock device, which asserts regular interrupts. |