/branches/arm/kernel/generic/src/main/version.c |
---|
36,7 → 36,7 |
#include <print.h> |
char *project = "SPARTAN kernel"; |
char *copyright = "Copyright (c) 2001-2008 HelenOS project"; |
char *copyright = "Copyright (c) 2001-2009 HelenOS project"; |
char *release = RELEASE; |
char *name = NAME; |
char *arch = ARCH; |
/branches/arm/kernel/arch/arm32/include/machine.h |
---|
111,6 → 111,10 |
*/ |
extern uintptr_t machine_get_fb_address(void); |
/* |
* Machine specific frame initialization |
*/ |
extern void machine_frame_init(void); |
#ifdef MACHINE_GXEMUL_TESTARM |
#define machine_console_init(devno) gxemul_console_init(devno) |
125,6 → 129,7 |
gxemul_irq_exception(exc_no, istate) |
#define machine_get_fb_address gxemul_get_fb_address |
#define machine_fb_init gxemul_fb_init |
#define machine_frame_init gxemul_frame_init |
#endif |
#ifdef MACHINE_QEMU_ICP |
140,6 → 145,7 |
qemu_icp_irq_exception(exc_no, istate) |
#define machine_get_fb_address qemu_icp_get_fb_address |
#define machine_fb_init qemu_icp_fb_init |
#define machine_frame_init qemu_icp_frame_init |
#endif |
#endif |
/branches/arm/kernel/arch/arm32/include/drivers/gxemul.h |
---|
73,6 → 73,7 |
extern size_t gxemul_get_memory_size(void); |
extern uintptr_t gxemul_get_fb_address(void); |
extern void gxemul_fb_init(void); |
extern void gxemul_frame_init(void); |
#endif |
/branches/arm/kernel/arch/arm32/include/drivers/qemu.h |
---|
46,14 → 46,17 |
#define QEMU_ICP_IRQC_MAX_IRQ 8 |
/** Timer frequency */ |
#define QEMU_ICP_TIMER_FREQ 1000 |
#define QEMU_ICP_TIMER_FREQ 10000 |
/** Struct containing mappings of qemu_icp HW devices into kernel part |
* of virtual address space. |
*/ |
typedef struct { |
uintptr_t videoram; |
uintptr_t kbd; |
uintptr_t uart; |
uintptr_t kbd_ctrl; |
uintptr_t kbd_stat; |
uintptr_t kbd_data; |
uintptr_t kbd_intstat; |
uintptr_t rtc; |
uintptr_t rtc1_load; |
uintptr_t rtc1_read; |
65,6 → 68,7 |
uintptr_t irqc_unmask; |
uintptr_t vga; |
uintptr_t cmcr; |
uintptr_t sdramcr; |
} qemu_icp_hw_map_t; |
extern void qemu_icp_hw_map_init(void); |
78,6 → 82,7 |
extern size_t qemu_icp_get_memory_size(void); |
extern uintptr_t qemu_icp_get_fb_address(void); |
extern void qemu_icp_fb_init(void); |
extern void qemu_icp_frame_init(void); |
#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/src/mm/frame.c |
---|
53,6 → 53,9 |
/* blacklist boot page table */ |
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME, |
BOOT_PAGE_TABLE_SIZE_IN_FRAMES); |
/* Machine specific frame initialization */ |
machine_frame_init(); |
} |
/** Frees the boot page table. */ |
/branches/arm/kernel/arch/arm32/src/drivers/pl050.c |
---|
0,0 → 1,233 |
/* |
* 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 |
#define PL050_CAPS_SCAN_CODE 0x58 |
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 int caps_locked = 0; |
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) |
ipc_irq_send_notif(irq); |
else { |
uint8_t data; |
uint8_t status; |
while (((status = pl050_statusread()) & PL050_STAT_RXFULL)) { |
data = pl050_dataread(); |
if (data == PL050_KEY_RELEASE) { |
key_released_flag = 1; |
} else { |
if (key_released_flag) { |
key_released_flag = 0; |
if (data == PL050_CAPS_SCAN_CODE) { |
if (!caps_locked) { |
caps_locked = 1; |
} else { |
caps_locked = 0; |
return; |
} |
} |
key_released(data); |
} else { |
if (data == PL050_CAPS_SCAN_CODE && caps_locked) |
return; |
key_pressed(data); |
} |
} |
} |
} |
} |
/** 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_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; |
printf("entering key_read\n"); |
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; |
printf("entering poll\n"); |
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/gxemul.c |
---|
396,5 → 396,11 |
return (uintptr_t) GXEMUL_FB; |
} |
/* |
* GXEMUL specific frame initialization |
*/ |
void gxemul_frame_init(void) |
{ |
} |
/** @} |
*/ |
/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,11 → 37,14 |
#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> |
#include <ddi/device.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
#include <arch/mm/frame.h> |
#include <arch/machine.h> |
#include <arch/debug/print.h> |
#include <genarch/fb/fb.h> |
48,9 → 51,11 |
#include <genarch/fb/visuals.h> |
/* Addresses of devices. */ |
#define QEMU_ICP_VIDEORAM 0x16000000 |
#define QEMU_ICP_UART 0x16000000 |
#define QEMU_ICP_KBD 0x18000000 |
#define QEMU_ICP_HALT_OFFSET 0x10 |
#define ICP_KBD_STAT 0x04 |
#define ICP_KBD_DATA 0x08 |
#define ICP_KBD_INTR_STAT 0x10 |
#define QEMU_ICP_RTC 0x13000000 |
#define QEMU_ICP_RTC1_LOAD_OFFSET 0x100 |
#define QEMU_ICP_RTC1_READ_OFFSET 0x104 |
61,38 → 66,38 |
#define QEMU_ICP_IRQC 0x14000000 |
#define QEMU_ICP_IRQC_MASK_OFFSET 0xC |
#define QEMU_ICP_IRQC_UNMASK_OFFSET 0x8 |
#define QEMU_ICP_MP 0x11000000 |
#define QEMU_ICP_MP_MEMSIZE_OFFSET 0x0090 |
#define QEMU_ICP_FB 0x94000 |
#define QEMU_ICP_FB 0x00800000 |
#define QEMU_ICP_FB_FRAME (QEMU_ICP_FB >> 12) |
#define QEMU_ICP_FB_NUM_FRAME 300 |
#define ICP_VGA 0xC0000000 |
#define ICP_CMCR 0x10000000 |
#define QEMU_ICP_SDRAM_MASK 0x1C |
#define QEMU_ICP_SDRAMCR_OFFSET 0x20 |
/* IRQs */ |
#define QEMU_ICP_KBD_IRQ 3 |
#define QEMU_ICP_TIMER_IRQ 6 |
#define SDRAM_SIZE (sdram[((*(uint32_t *)(ICP_CMCR+QEMU_ICP_SDRAMCR_OFFSET) & QEMU_ICP_SDRAM_MASK) >> 2)]) |
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; |
uint32_t sdram[8] = { |
16777216, /* 16mb */ |
33554432, /* 32mb */ |
67108864, /* 64mb */ |
134217728, /* 128mb */ |
268435456, /* 256mb */ |
0, /* Reserverd */ |
0, /* Reserverd */ |
0 /* Reserverd */ |
}; |
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 |
* |
*/ |
144,8 → 149,11 |
/** Initializes #qemu_icp_hw_map. */ |
void qemu_icp_hw_map_init(void) |
{ |
qemu_icp_hw_map.videoram = hw_map(QEMU_ICP_VIDEORAM, PAGE_SIZE); |
qemu_icp_hw_map.kbd = hw_map(QEMU_ICP_KBD, PAGE_SIZE); |
qemu_icp_hw_map.uart = hw_map(QEMU_ICP_UART, PAGE_SIZE); |
qemu_icp_hw_map.kbd_ctrl = hw_map(QEMU_ICP_KBD, PAGE_SIZE); |
qemu_icp_hw_map.kbd_stat = qemu_icp_hw_map.kbd_ctrl + ICP_KBD_STAT; |
qemu_icp_hw_map.kbd_data = qemu_icp_hw_map.kbd_ctrl + ICP_KBD_DATA; |
qemu_icp_hw_map.kbd_intstat = qemu_icp_hw_map.kbd_ctrl + ICP_KBD_INTR_STAT; |
qemu_icp_hw_map.rtc = hw_map(QEMU_ICP_RTC, PAGE_SIZE); |
qemu_icp_hw_map.rtc1_load = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_LOAD_OFFSET; |
qemu_icp_hw_map.rtc1_read = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_READ_OFFSET; |
155,118 → 163,25 |
qemu_icp_hw_map.irqc = hw_map(QEMU_ICP_IRQC, PAGE_SIZE); |
qemu_icp_hw_map.irqc_mask = qemu_icp_hw_map.irqc + QEMU_ICP_IRQC_MASK_OFFSET; |
qemu_icp_hw_map.irqc_unmask = qemu_icp_hw_map.irqc + |
QEMU_ICP_IRQC_UNMASK_OFFSET; |
qemu_icp_hw_map.irqc_unmask = qemu_icp_hw_map.irqc + QEMU_ICP_IRQC_UNMASK_OFFSET; |
qemu_icp_hw_map.cmcr = hw_map(ICP_CMCR, PAGE_SIZE); |
qemu_icp_hw_map.sdramcr = qemu_icp_hw_map.cmcr + QEMU_ICP_SDRAMCR_OFFSET; |
qemu_icp_hw_map.vga = hw_map(ICP_VGA, PAGE_SIZE); |
//icp_vga_init(); |
hw_map_init_called = true; |
} |
/** 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); |
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); |
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; |
} |
spinlock_unlock(&qemu_icp_console_irq.lock); |
interrupts_restore(ipl); |
pl050_release(); |
} |
/** Initializes console object representing qemu_icp console. |
275,24 → 190,10 |
*/ |
void qemu_icp_console_init(devno_t devno) |
{ |
qemu_icp_irqc_mask(QEMU_ICP_KBD_IRQ); |
chardev_initialize("qemu_icp_console", &console, &qemu_icp_ops); |
stdin = &console; |
stdout = &console; |
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); |
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); |
} |
/** Starts qemu_icp Real Time Clock device, which asserts regular interrupts. |
310,7 → 211,6 |
static irq_ownership_t qemu_icp_timer_claim(void) |
{ |
*((uint32_t*) qemu_icp_hw_map.rtc1_intrclr) = 1; |
return IRQ_ACCEPT; |
} |
325,6 → 225,8 |
* We are holding a lock which prevents preemption. |
* Release the lock, call clock() and reacquire the lock again. |
*/ |
*((uint32_t*) qemu_icp_hw_map.rtc1_intrclr) = 1; |
spinlock_unlock(&irq->lock); |
clock(); |
spinlock_lock(&irq->lock); |
361,8 → 263,12 |
*/ |
size_t qemu_icp_get_memory_size(void) |
{ |
//return *((int *) (QEMU_ICP_MP + QEMU_ICP_MP_MEMSIZE_OFFSET)); |
return 0x2000000; |
if (hw_map_init_called) { |
return (sdram[((*(uint32_t *)qemu_icp_hw_map.sdramcr & QEMU_ICP_SDRAM_MASK) >> 2)]); |
} else { |
return SDRAM_SIZE; |
} |
} |
/** Prints a character. |
375,7 → 281,7 |
if (!hw_map_init_called) { |
addr = (char *) QEMU_ICP_KBD; |
} else { |
addr = (char *) qemu_icp_hw_map.videoram; |
addr = (char *) qemu_icp_hw_map.uart; |
} |
if (ch == '\n') |
386,17 → 292,10 |
/** Stops qemu_icp. */ |
void qemu_icp_cpu_halt(void) |
{ |
char * addr = 0; |
if (!hw_map_init_called) { |
addr = (char *) QEMU_ICP_KBD; |
} else { |
addr = (char *) qemu_icp_hw_map.videoram; |
} |
*(addr + QEMU_ICP_HALT_OFFSET) = '\0'; |
while (1); |
} |
/** Gxemul specific interrupt exception handler. |
/** interrupt exception handler. |
* |
* Determines sources of the interrupt from interrupt controller and |
* calls high-level handlers for them. |
438,6 → 337,15 |
return (uintptr_t) QEMU_ICP_FB; |
} |
/* |
* Integrator specific frame initialization |
*/ |
void |
qemu_icp_frame_init(void) |
{ |
frame_mark_unavailable(QEMU_ICP_FB_FRAME, QEMU_ICP_FB_NUM_FRAME); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/exception.c |
---|
100,9 → 100,9 |
"mov r2, lr \n" |
"stmfd r13!, {r4-r12} \n" |
"mov r1, r13 \n" |
/* the following two lines are for debugging */ |
/* the following two lines are for debugging */ |
"mov sp, #0 \n" |
"mov lr, #0 \n" |
"mov lr, #0 \n" |
"msr cpsr_c, r0 \n" |
"ldmfd r13!, {r4, r5, r6, r7} \n" |
/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/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, /* 0x51 */ |
'\'', |
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, /* 0x51 */ |
'"', |
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/genarch/include/kbd/scanc_pl050.h |
---|
0,0 → 1,58 |
/* |
* 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. |
*/ |
#ifndef KERN_SCANC_PL050_H_ |
#define KERN_SCANC_PL050_H_ |
#define SC_ESC 0x76 |
#define SC_BACKSPACE 0x66 |
#define SC_LSHIFT 0x12 |
#define SC_RSHIFT 0x59 |
#define SC_CAPSLOCK 0x58 |
#define SC_SPEC_ESCAPE 0xe0 |
#define SC_LEFTARR 0x6b |
#define SC_RIGHTARR 0x74 |
#define SC_UPARR 0x75 |
#define SC_DOWNARR 0x72 |
#define SC_DELETE 0x70 |
#define SC_HOME 0x6C |
#define SC_END 0x69 |
#endif |
/** @} |
*/ |
/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 += \ |