KMI patch for devel branch on bahadir's repo.

Important points:
----------------
1. Works fine for pb926 + qemu.

2. Scan code logic for kryboard is not complete.
We just have generic keys and shift working.

3. Mouse scancodes are collected but not decoded.

4. Right now we are doing enable_irq(), just before we go for waiting
again for new irqs. This is not correct but we had latency issues.
This needs to be fixed immediately.

5. Also it seems like the notify_clot count should be an atomic
variable. Needs to be discussed.
This commit is contained in:
Amit Mahajan
2010-03-30 10:54:04 +05:30
parent 17c2336613
commit 92645be6ff
28 changed files with 1898 additions and 32 deletions

View File

@@ -137,7 +137,8 @@ default CONT%(cn)d_OPT_NAME from
((CONT%(cn)d_BAREMETAL_PROJ_THREADS_DEMO==y) ? "thread_demo%(cn)d" :
((CONT%(cn)d_BAREMETAL_PROJ_TEST_SUITE==y) ? "test_suite%(cn)d" :
((CONT%(cn)d_BAREMETAL_PROJ_UART_SERVICE==y) ? "uart_service%(cn)d" :
((CONT%(cn)d_BAREMETAL_PROJ_TIMER_SERVICE==y) ? "timer_service%(cn)d" : "empty%(cn)d"))))))
((CONT%(cn)d_BAREMETAL_PROJ_KMI_SERVICE==y) ? "kmi_service%(cn)d" :
((CONT%(cn)d_BAREMETAL_PROJ_TIMER_SERVICE==y) ? "timer_service%(cn)d" : "empty%(cn)d")))))))
when CONT%(cn)d_TYPE_LINUX==y suppress cont%(cn)d_default_pager_params
unless CONT%(cn)d_TYPE_POSIX==y suppress cont%(cn)d_posix_pager_params
@@ -168,6 +169,7 @@ CONT%(cn)d_BAREMETAL_PROJ_THREADS_DEMO 'Thread Library Demo'
CONT%(cn)d_BAREMETAL_PROJ_TEST_SUITE 'Microkernel Tests'
CONT%(cn)d_BAREMETAL_PROJ_UART_SERVICE 'UART Service'
CONT%(cn)d_BAREMETAL_PROJ_TIMER_SERVICE 'Timer Service'
CONT%(cn)d_BAREMETAL_PROJ_KMI_SERVICE 'Keyboard Mouse Service'
choices cont%(cn)d_baremetal_params
CONT%(cn)d_BAREMETAL_PROJ_EMPTY
@@ -176,6 +178,7 @@ choices cont%(cn)d_baremetal_params
CONT%(cn)d_BAREMETAL_PROJ_TEST_SUITE
CONT%(cn)d_BAREMETAL_PROJ_UART_SERVICE
CONT%(cn)d_BAREMETAL_PROJ_TIMER_SERVICE
CONT%(cn)d_BAREMETAL_PROJ_KMI_SERVICE
default CONT%(cn)d_BAREMETAL_PROJ_EMPTY
menu cont%(cn)d_default_pager_params
@@ -232,16 +235,22 @@ cont%(cn)d_cap_device_uart1 'Container %(cn)d UART1 Menu'
cont%(cn)d_cap_device_uart2 'Container %(cn)d UART2 Menu'
cont%(cn)d_cap_device_uart3 'Container %(cn)d UART3 Menu'
cont%(cn)d_cap_device_timer1 'Container %(cn)d TIMER23 Menu'
cont%(cn)d_cap_device_keyboard0 'Container %(cn)d KEYBOARD0 Menu'
cont%(cn)d_cap_device_mouse0 'Container %(cn)d MOUSE0 Menu'
CONT%(cn)d_CAP_DEVICE_UART1_USE 'Container %(cn)d UART1 Enable'
CONT%(cn)d_CAP_DEVICE_UART2_USE 'Container %(cn)d UART2 Enable'
CONT%(cn)d_CAP_DEVICE_UART3_USE 'Container %(cn)d UART3 Enable'
CONT%(cn)d_CAP_DEVICE_TIMER1_USE 'Container %(cn)d TIMER23 Enable'
CONT%(cn)d_CAP_DEVICE_KEYBOARD0_USE 'Container %(cn)d KEYBOARD0 Enable'
CONT%(cn)d_CAP_DEVICE_MOUSE0_USE 'Container %(cn)d MOUSE0 Enable'
default CONT%(cn)d_CAP_DEVICE_UART1_USE from n
default CONT%(cn)d_CAP_DEVICE_UART2_USE from n
default CONT%(cn)d_CAP_DEVICE_UART3_USE from n
default CONT%(cn)d_CAP_DEVICE_TIMER1_USE from n
default CONT%(cn)d_CAP_DEVICE_KEYBOARD0_USE from n
default CONT%(cn)d_CAP_DEVICE_MOUSE0_USE from n
menu cont%(cn)d_cap_device_uart1
CONT%(cn)d_CAP_DEVICE_UART1_USE
@@ -255,11 +264,19 @@ menu cont%(cn)d_cap_device_uart3
menu cont%(cn)d_cap_device_timer1
CONT%(cn)d_CAP_DEVICE_TIMER1_USE
menu cont%(cn)d_cap_device_keyboard0
CONT%(cn)d_CAP_DEVICE_KEYBOARD0_USE
menu cont%(cn)d_cap_device_mouse0
CONT%(cn)d_CAP_DEVICE_MOUSE0_USE
menu cont%(cn)d_device_list
cont%(cn)d_cap_device_uart1
cont%(cn)d_cap_device_uart2
cont%(cn)d_cap_device_uart3
cont%(cn)d_cap_device_timer1
cont%(cn)d_cap_device_keyboard0
cont%(cn)d_cap_device_mouse0
#
# Settings for Custom Capabilities

View File

@@ -0,0 +1,316 @@
#
# Automatically generated, don't edit
#
# Generated on: amit-laptop-ubuntu
# At: Mon, 29 Mar 2010 17:55:04 +0000
# Linux version 2.6.28-11-generic (buildd@palmer) (gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4) ) #42-Ubuntu SMP Fri Apr 17 01:57:59 UTC 2009
#
# Codezero Microkernel Configurator
#
#
# Main architecture
#
CONFIG_ARCH_ARM=y
#
# ARM Architecture Configuration
#
#
# ARM Platform Type
#
#
# ARM Platform Type
#
CONFIG_PLATFORM_EB=n
CONFIG_PLATFORM_PBA8=n
CONFIG_PLATFORM_PB926=y
CONFIG_PLATFORM_PB11MPCORE=n
CONFIG_PLATFORM_BEAGLE=n
CONFIG_PLATFORM_PBA9=n
#
# ARM CPU type
#
#
# ARM Processor Type
#
CONFIG_CPU_ARM926=y
#
# Generic Processor Properties
#
CONFIG_ICACHE_DISABLE=n
CONFIG_DCACHE_DISABLE=n
#
# Generic Kernel Properties
#
CONFIG_PREEMPT_DISABLE=n
CONFIG_DEBUG_ACCOUNTING=n
CONFIG_DEBUG_SPINLOCKS=n
CONFIG_SCHED_TICKS=1000
#
# Toolchain Prefix
#
CONFIG_TOOLCHAIN="arm-none-eabi-"
#
# Container Setup
#
CONFIG_CAPABILITIES=y
CONFIG_CONTAINERS=1
#
# Container 0 Parameters
#
#
# Container 0 Type
#
CONFIG_CONT0_TYPE_BAREMETAL=y
CONFIG_CONT0_TYPE_POSIX=n
CONFIG_CONT0_TYPE_LINUX=n
#
# Container 0 Options
#
CONFIG_CONT0_OPT_NAME="kmi_service0"
#
# Baremetal Project
#
CONFIG_CONT0_BAREMETAL_PROJ_EMPTY=n
CONFIG_CONT0_BAREMETAL_PROJ_HELLO_WORLD=n
CONFIG_CONT0_BAREMETAL_PROJ_THREADS_DEMO=n
CONFIG_CONT0_BAREMETAL_PROJ_TEST_SUITE=n
CONFIG_CONT0_BAREMETAL_PROJ_UART_SERVICE=n
CONFIG_CONT0_BAREMETAL_PROJ_TIMER_SERVICE=n
CONFIG_CONT0_BAREMETAL_PROJ_KMI_SERVICE=y
#
# Container 0 Default Pager Parameters
#
CONFIG_CONT0_PAGER_LMA=0x100000
CONFIG_CONT0_PAGER_VMA=0xa0000000
#
# Container 0 Physical Memory Regions (Capabilities)
#
CONFIG_CONT0_PHYSMEM_REGIONS=1
CONFIG_CONT0_PHYS0_START=0x100000
CONFIG_CONT0_PHYS0_END=0xe00000
#
# Container 0 Virtual Memory Regions (Capabilities)
#
CONFIG_CONT0_VIRTMEM_REGIONS=1
CONFIG_CONT0_VIRT0_START=0xa0000000
CONFIG_CONT0_VIRT0_END=0xb0000000
#
# Container 0 Capability List
#
#
# Container 0 Thread Pool Capability
#
CONFIG_CONT0_CAP_THREADPOOL_USE=y
CONFIG_CONT0_CAP_THREADPOOL_SIZE=64
#
# Container 0 Space Pool Capability
#
CONFIG_CONT0_CAP_SPACEPOOL_USE=y
CONFIG_CONT0_CAP_SPACEPOOL_SIZE=64
#
# Container 0 Mutex Pool Capability
#
CONFIG_CONT0_CAP_MUTEXPOOL_USE=y
CONFIG_CONT0_CAP_MUTEXPOOL_SIZE=100
#
# Container 0 Map Pool Capability
#
CONFIG_CONT0_CAP_MAPPOOL_USE=y
CONFIG_CONT0_CAP_MAPPOOL_SIZE=800
#
# Container 0 Capability Pool Capability
#
CONFIG_CONT0_CAP_CAPPOOL_USE=y
CONFIG_CONT0_CAP_CAPPOOL_SIZE=32
#
# Container 0 Thread Control Capability
#
CONFIG_CONT0_CAP_TCTRL_USE=y
CONFIG_CONT0_CAP_TCTRL_TARGET_CURRENT_CONTAINER=y
CONFIG_CONT0_CAP_TCTRL_TARGET_CURRENT_PAGER_SPACE=n
#
# Container 0 Exchange Registers Capability
#
CONFIG_CONT0_CAP_EXREGS_USE=y
CONFIG_CONT0_CAP_EXREGS_TARGET_CURRENT_CONTAINER=y
CONFIG_CONT0_CAP_EXREGS_TARGET_CURRENT_PAGER_SPACE=n
#
# Container 0 IPC Capability
#
CONFIG_CONT0_CAP_IPC_USE=y
CONFIG_CONT0_CAP_IPC_TARGET_CURRENT_CONTAINER=y
CONFIG_CONT0_CAP_IPC_TARGET_CURRENT_PAGER_SPACE=n
CONFIG_CONT0_CAP_IPC_TARGET_ANOTHER_CONTAINER=n
CONFIG_CONT0_CAP_IPC_TARGET_ANOTHER_PAGER=n
#
# Container 0 Capability Control Capability
#
CONFIG_CONT0_CAP_CAPCTRL_USE=y
CONFIG_CONT0_CAP_CAPCTRL_TARGET_CURRENT_CONTAINER=y
CONFIG_CONT0_CAP_CAPCTRL_TARGET_CURRENT_PAGER_SPACE=n
#
# Container 0 Userspace Mutex Control Capability
#
CONFIG_CONT0_CAP_UMUTEX_USE=y
CONFIG_CONT0_CAP_UMUTEX_TARGET_CURRENT_CONTAINER=y
CONFIG_CONT0_CAP_UMUTEX_TARGET_CURRENT_PAGER_SPACE=n
#
# Container 0 IRQ Control Capability
#
CONFIG_CONT0_CAP_IRQCTRL_USE=y
CONFIG_CONT0_CAP_IRQCTRL_TARGET_CURRENT_CONTAINER=y
CONFIG_CONT0_CAP_IRQCTRL_TARGET_CURRENT_PAGER_SPACE=n
#
# Container 0 Custom Capability 0 Parameters
#
CONFIG_CONT0_CAP_CUSTOM0_USE=n
#
# Container 0 Custom Capability 1 Parameters
#
CONFIG_CONT0_CAP_CUSTOM1_USE=n
#
# Container 0 Custom Capability 2 Parameters
#
CONFIG_CONT0_CAP_CUSTOM2_USE=n
#
# Container 0 Custom Capability 3 Parameters
#
CONFIG_CONT0_CAP_CUSTOM3_USE=n
#
# Container 0 Devices (Capabilities)
#
#
# Container 0 UART1 Menu
#
CONFIG_CONT0_CAP_DEVICE_UART1_USE=n
#
# Container 0 UART2 Menu
#
CONFIG_CONT0_CAP_DEVICE_UART2_USE=n
#
# Container 0 UART3 Menu
#
CONFIG_CONT0_CAP_DEVICE_UART3_USE=n
#
# Container 0 TIMER23 Menu
#
CONFIG_CONT0_CAP_DEVICE_TIMER1_USE=n
#
# Container 0 KEYBOARD0 Menu
#
CONFIG_CONT0_CAP_DEVICE_KEYBOARD0_USE=y
#
# Container 0 MOUSE0 Menu
#
CONFIG_CONT0_CAP_DEVICE_MOUSE0_USE=y
#
# Derived symbols
#
CONFIG_CONT3_START_PC_ADDR=0xd0000000
CONFIG_DEBUG_PERFMON_KERNEL=n
CONFIG_SUBARCH_V5=y
CONFIG_CONT1_PAGER_LOAD_ADDR=0x1100000
CONFIG_DRIVER_IRQ_PL190=y
CONFIG_DRIVER_TIMER_SP804=y
CONFIG_CONT2_START_PC_ADDR=0xc0000000
CONFIG_DRIVER_IRQ_GIC=n
CONFIG_CONT2_PAGER_VIRT_ADDR=0xc0000000
CONFIG_RAM_BASE_PLAT=0
CONFIG_DRIVER_INTC_OMAP=n
CONFIG_CONT2_PAGER_LOAD_ADDR=0x2100000
CONFIG_CONT1_PAGER_VIRT_ADDR=0xb0000000
CONFIG_CONT3_PAGER_LOAD_ADDR=0x3100000
CONFIG_SUBARCH_V7=n
CONFIG_SUBARCH_V6=n
CONFIG_DRIVER_TIMER_OMAP=n
CONFIG_CONT0_PAGER_LOAD_ADDR=0x100000
CONFIG_CONT0_PAGER_VIRT_ADDR=0xa0000000
CONFIG_DRIVER_UART_OMAP=n
CONFIG_DRIVER_UART_PL011=y
CONFIG_CONT3_PAGER_VIRT_ADDR=0xd0000000
CONFIG_CONT0_START_PC_ADDR=0xa0000000
CONFIG_CONT1_START_PC_ADDR=0xb0000000
#
# That's all, folks!

View File

@@ -0,0 +1,70 @@
# -*- mode: python; coding: utf-8; -*-
#
# Codezero -- Virtualization microkernel for embedded systems.
#
# Copyright © 2009 B Labs Ltd
#
import os, shelve, sys
from os.path import *
PROJRELROOT = '../..'
sys.path.append(PROJRELROOT)
from config.projpaths import *
from config.configuration import *
from configure import *
config = configuration_retrieve()
arch = config.arch
platform = config.platform
gcc_arch_flag = config.gcc_arch_flag
# Wrapper library for system calls
LIBL4_RELDIR = 'conts/libl4'
KERNEL_INCLUDE = join(PROJROOT, 'include')
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
# Some user-space libraries
LIBC_RELDIR = 'conts/libc'
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
join(LIBC_DIR, 'include/arch' + '/' + arch)]
LIBDEV_RELDIR = 'conts/libdev'
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
LIBDEV_INCLUDE = join(LIBDEV_DIR, 'include')
LIBMEM_RELDIR = 'conts/libmem'
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
LIBMEM_INCLUDE = LIBMEM_DIR
env = Environment(CC = config.toolchain + 'gcc',
# We don't use -nostdinc because sometimes we need standard headers,
# such as stdarg.h e.g. for variable args, as in printk().
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
'-Werror', '-march=' + gcc_arch_flag], \
LINKFLAGS = ['-nostdlib', '-T' + "include/linker.lds", "-u_start"],\
ASFLAGS = ['-D__ASSEMBLY__'], \
PROGSUFFIX = '.elf', # The suffix to use for final executable
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace', \
'libmm', 'libmc', 'libmalloc', 'gcc', 'c-userspace'],
# libgcc.a - This is required for division routines.
CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBDEV_INCLUDE, \
LIBC_INCLUDE, LIBMEM_INCLUDE],
LIBPATH = [LIBL4_LIBPATH, LIBDEV_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
src = Glob('*.[cS]')
src += Glob('src/*.[cS]')
src += Glob('src/arch/*.[cS]')
objs = env.Object(src)
prog = env.Program('main.elf', objs)
Depends(prog, 'include/linker.lds')

View File

@@ -0,0 +1,21 @@
/*
* Container entry point for pager
*
* Copyright (C) 2007-2009 B Labs Ltd.
*/
#include <l4lib/init.h>
#include <l4lib/utcb.h>
void main(void);
void __container_init(void)
{
/* Generic L4 initialisation */
__l4_init();
/* Entry to main */
main();
}

View File

@@ -0,0 +1,13 @@
/*
* Autogenerated definitions for this container.
*/
#ifndef __CONTAINER_H__
#define __CONTAINER_H__
#define __CONTAINER_NAME__ "kmi_service"
#define __CONTAINER_ID__ 0
#define __CONTAINER__ "cont0"
#endif /* __CONTAINER_H__ */

View File

@@ -0,0 +1,18 @@
/*
* Keyboard details.
*/
#ifndef __KEYBOARD_H__
#define __KEYBOARD_H__
#include <libdev/kmi.h>
/*
* Keyboard structure
*/
struct keyboard {
unsigned long base; /* Virtual base address */
struct capability cap; /* Capability describing keyboard */
struct keyboard_state state;
};
#endif /* __KEYBOARD_H__ */

View File

@@ -0,0 +1,7 @@
#ifndef __LINKER_H__
#define __LINKER_H__
extern char vma_start[];
extern char __end[];
#endif /* __LINKER_H__ */

View File

@@ -0,0 +1,19 @@
/*
* Mouse details.
*/
#ifndef __MOUSE_H__
#define __MOUSE_H__
#include <l4lib/mutex.h>
#include <l4/lib/list.h>
#include <l4lib/types.h>
/*
* Keyboard structure
*/
struct mouse {
unsigned long base; /* Virtual base address */
struct capability cap; /* Capability describing keyboard */
};
#endif /* __MOUSE_H__ */

View File

@@ -0,0 +1,19 @@
#ifndef __THREAD_H__
#define __THREAD_H__
#include <l4lib/macros.h>
#include L4LIB_INC_ARCH(syslib.h)
#include L4LIB_INC_ARCH(syscalls.h)
#include <l4lib/exregs.h>
#include <l4/api/thread.h>
int thread_create(int (*func)(void *), void *args, unsigned int flags,
struct task_ids *new_ids);
/* For same space */
#define STACK_SIZE 0x1000
#define THREADS_TOTAL 10
#endif /* __THREAD_H__ */

View File

@@ -0,0 +1,424 @@
/*
* Keyboard and Mouse service for userspace
*/
#include <l4lib/lib/addr.h>
#include <l4lib/irq.h>
#include <l4lib/ipcdefs.h>
#include <l4/api/errno.h>
#include <l4/api/irq.h>
#include <l4/api/capability.h>
#include <l4/generic/cap-types.h>
#include <l4/api/space.h>
#include <malloc/malloc.h>
#include <container.h>
#include <linker.h>
#include <keyboard.h>
#include <mouse.h>
#include <thread.h>
#define KEYBOARDS_TOTAL 1
#define MOUSE_TOTAL 1
static struct capability caparray[32];
static int total_caps = 0;
struct keyboard kbd[KEYBOARDS_TOTAL];
struct mouse mouse[MOUSE_TOTAL];
int cap_read_all()
{
int ncaps;
int err;
/* Read number of capabilities */
if ((err = l4_capability_control(CAP_CONTROL_NCAPS,
0, &ncaps)) < 0) {
printf("l4_capability_control() reading # of"
" capabilities failed.\n Could not "
"complete CAP_CONTROL_NCAPS request.\n");
BUG();
}
total_caps = ncaps;
/* Read all capabilities */
if ((err = l4_capability_control(CAP_CONTROL_READ,
0, caparray)) < 0) {
printf("l4_capability_control() reading of "
"capabilities failed.\n Could not "
"complete CAP_CONTROL_READ_CAPS request.\n");
BUG();
}
return 0;
}
int cap_share_all_with_space()
{
int err;
/* Share all capabilities */
if ((err = l4_capability_control(CAP_CONTROL_SHARE,
CAP_SHARE_ALL_SPACE, 0)) < 0) {
printf("l4_capability_control() sharing of "
"capabilities failed.\n Could not "
"complete CAP_CONTROL_SHARE request. err=%d\n",
err);
BUG();
}
return 0;
}
/*
* Scans for up to KEYBOARDS_TOTAL
* keyboard devices and MOUSE_TOTAL mouse
* in capabilities.
*/
int kmi_probe_devices(void)
{
int keyboards = 0, nmouse = 0;
/* Scan for timer devices */
for (int i = 0; i < total_caps; i++) {
/* Match device type */
if (cap_devtype(&caparray[i]) == CAP_DEVTYPE_KEYBOARD) {
/* Copy to correct device index */
memcpy(&kbd[cap_devnum(&caparray[i])].cap,
&caparray[i], sizeof(kbd[0].cap));
keyboards++;
}
if (cap_devtype(&caparray[i]) == CAP_DEVTYPE_MOUSE) {
/* Copy to correct device index */
memcpy(&mouse[cap_devnum(&caparray[i])].cap,
&caparray[i], sizeof(mouse[0].cap));
nmouse++;
}
}
if (keyboards != KEYBOARDS_TOTAL) {
printf("%s: Error, not all keyboards could be found. "
"keyboards=%d\n", __CONTAINER_NAME__, keyboards);
return -ENODEV;
}
if (nmouse != MOUSE_TOTAL) {
printf("%s: Error, not all mouse could be found. "
"mouse=%d\n", __CONTAINER_NAME__, nmouse);
return -ENODEV;
}
return 0;
}
int keyboard_irq_handler(void *arg)
{
int err;
struct keyboard *keyboard = (struct keyboard *)arg;
const int slot = 0;
/*
* For versatile, KMI refernce clock = 24MHz
* KMI manual says we need 8MHz clock,
* so divide by 3
*/
kmi_keyboard_init(keyboard->base, 3);
printf("%s: Keyboard initialization done..\n", __CONTAINER_NAME__);
/* Register self for timer irq, using notify slot 0 */
if ((err = l4_irq_control(IRQ_CONTROL_REGISTER, slot,
keyboard->cap.irq)) < 0) {
printf("%s: FATAL: Keyboard irq could not be registered. "
"err=%d\n", __FUNCTION__, err);
BUG();
}
/* Handle irqs forever */
while (1) {
char c;
/* Block on irq */
int data = l4_irq_wait(slot, keyboard->cap.irq);
while (data--)
if ((c = kmi_keyboard_read(keyboard->base, &keyboard->state)))
printf("%c", c);
}
}
int mouse_irq_handler(void *arg)
{
int err;
struct mouse *mouse = (struct mouse *)arg;
const int slot = 0;
/*
* For versatile, KMI refernce clock = 24MHz
* KMI manual says we need 8MHz clock,
* so divide by 3
*/
kmi_mouse_init(mouse->base, 3);
printf("%s: Mouse initialization done..\n", __CONTAINER_NAME__);
/* Register self for timer irq, using notify slot 0 */
if ((err = l4_irq_control(IRQ_CONTROL_REGISTER, slot,
mouse->cap.irq)) < 0) {
printf("%s: FATAL: Mouse irq could not be registered. "
"err=%d\n", __FUNCTION__, err);
BUG();
}
/* Handle irqs forever */
while (1) {
int c;
/* Block on irq */
int data = l4_irq_wait(slot, mouse->cap.irq);
while (data--)
if ((c = kmi_data_read(mouse->base)))
printf("mouse data: %d\n", c);
}
}
int kmi_setup_devices(void)
{
struct task_ids irq_tids;
int err;
for (int i = 0; i < KEYBOARDS_TOTAL; i++) {
/* Get one page from address pool */
kbd[i].base = (unsigned long)l4_new_virtual(1);
kbd[i].state.shift = 0;
kbd[i].state.caps_lock = 0;
kbd[i].state.keyup = 0;
/* Map timer to a virtual address region */
if (IS_ERR(l4_map((void *)__pfn_to_addr(kbd[i].cap.start),
(void *)kbd[i].base, kbd[i].cap.size,
MAP_USR_IO, self_tid()))) {
printf("%s: FATAL: Failed to map Keyboard device "
"%d to a virtual address\n",
__CONTAINER_NAME__,
cap_devnum(&kbd[i].cap));
BUG();
}
/*
* Create new keyboard irq handler thread.
*
* This will initialize its keyboard argument, register
* itself as its irq handler, initiate keyboard and
* wait on irqs.
*/
if ((err = thread_create(keyboard_irq_handler, &kbd[i],
TC_SHARE_SPACE,
&irq_tids)) < 0) {
printf("FATAL: Creation of irq handler "
"thread failed.\n");
BUG();
}
}
for (int i = 0; i < MOUSE_TOTAL; i++) {
/* Get one page from address pool */
mouse[i].base = (unsigned long)l4_new_virtual(1);
/* Map timer to a virtual address region */
if (IS_ERR(l4_map((void *)__pfn_to_addr(mouse[i].cap.start),
(void *)mouse[i].base, mouse[i].cap.size,
MAP_USR_IO, self_tid()))) {
printf("%s: FATAL: Failed to map Mouse device "
"%d to a virtual address\n",
__CONTAINER_NAME__, cap_devnum(&mouse[i].cap));
BUG();
}
/*
* Create new mouse irq handler thread.
*
* This will initialize its mouse argument, register
* itself as its irq handler, initiate mouse and
* wait on irqs.
*/
if ((err = thread_create(mouse_irq_handler, &mouse[i],
TC_SHARE_SPACE, &irq_tids)) < 0) {
printf("FATAL: Creation of irq handler "
"thread failed.\n");
BUG();
}
}
return 0;
}
/*
* Declare a statically allocated char buffer
* with enough bitmap size to cover given size
*/
#define DECLARE_IDPOOL(name, size) \
char name[(sizeof(struct id_pool) + ((size >> 12) >> 3))]
#define PAGE_POOL_SIZE SZ_1MB
static struct address_pool device_vaddr_pool;
DECLARE_IDPOOL(device_id_pool, PAGE_POOL_SIZE);
/*
* Initialize a virtual address pool
* for mapping physical devices.
*/
void init_vaddr_pool(void)
{
for (int i = 0; i < total_caps; i++) {
/* Find the virtual memory region for this process */
if (cap_type(&caparray[i]) == CAP_TYPE_MAP_VIRTMEM
&& __pfn_to_addr(caparray[i].start) ==
(unsigned long)vma_start) {
/*
* Do we have any unused virtual space
* where we run, and do we have enough
* pages of it to map all timers?
*/
if (__pfn(page_align_up(__end)) + KEYBOARDS_TOTAL +
MOUSE_TOTAL <= caparray[i].end) {
/*
* Yes. We initialize the device
* virtual memory pool here.
*
* We may allocate virtual memory
* addresses from this pool.
*/
address_pool_init(&device_vaddr_pool,
(struct id_pool *)&device_id_pool,
page_align_up(__end),
__pfn_to_addr(caparray[i].end));
return;
} else
goto out_err;
}
}
out_err:
printf("%s: FATAL: No virtual memory "
"region available to map "
"devices.\n", __CONTAINER_NAME__);
BUG();
}
void *l4_new_virtual(int npages)
{
return address_new(&device_vaddr_pool, npages, PAGE_SIZE);
}
void handle_requests(void)
{
u32 mr[MR_UNUSED_TOTAL];
l4id_t senderid;
u32 tag;
int ret;
printf("%s: Initiating ipc.\n", __CONTAINER__);
if ((ret = l4_receive(L4_ANYTHREAD)) < 0) {
printf("%s: %s: IPC Error: %d. Quitting...\n", __CONTAINER__,
__FUNCTION__, ret);
BUG();
}
/* Syslib conventional ipc data which uses first few mrs. */
tag = l4_get_tag();
senderid = l4_get_sender();
/* Read mrs not used by syslib */
for (int i = 0; i < MR_UNUSED_TOTAL; i++)
mr[i] = read_mr(MR_UNUSED_START + i);
/*
* TODO:
*
* Maybe add tags here that handle requests for sharing
* of the requested timer device with the client?
*
* In order to be able to do that, we should have a
* shareable/grantable capability to the device. Also
* the request should (currently) come from a task
* inside the current container
*/
switch (tag) {
default:
printf("%s: Error received ipc from 0x%x residing "
"in container %x with an unrecognized tag: "
"0x%x\n", __CONTAINER__, senderid,
__cid(senderid), tag);
}
/* Reply */
if ((ret = l4_ipc_return(ret)) < 0) {
printf("%s: IPC return error: %d.\n", __FUNCTION__, ret);
BUG();
}
}
/*
* UTCB-size aligned utcb.
*
* BIG WARNING NOTE: This declaration is legal if we are
* running in a disjoint virtual address space, where the
* utcb declaration lies in a unique virtual address in
* the system.
*/
#define DECLARE_UTCB(name) \
struct utcb name ALIGN(sizeof(struct utcb))
DECLARE_UTCB(utcb);
/* Set up own utcb for ipc */
int l4_utcb_setup(void *utcb_address)
{
struct task_ids ids;
struct exregs_data exregs;
int err;
l4_getid(&ids);
/* Clear utcb */
memset(utcb_address, 0, sizeof(struct utcb));
/* Setup exregs for utcb request */
memset(&exregs, 0, sizeof(exregs));
exregs_set_utcb(&exregs, (unsigned long)utcb_address);
if ((err = l4_exchange_registers(&exregs, ids.tid)) < 0)
return err;
return 0;
}
void main(void)
{
int err;
/* Read all capabilities */
cap_read_all();
/* Share all with space */
cap_share_all_with_space();
/* Scan for keyboard devices in capabilities */
kmi_probe_devices();
/* Initialize virtual address pool for timers */
init_vaddr_pool();
/* Setup own static utcb */
if ((err = l4_utcb_setup(&utcb)) < 0) {
printf("FATAL: Could not set up own utcb. "
"err=%d\n", err);
BUG();
}
/* Map and initialize keyboard devices */
kmi_setup_devices();
/* Listen for timer requests */
while (1)
handle_requests();
}

View File

@@ -0,0 +1,11 @@
#include <l4lib/macros.h>
#include L4LIB_INC_ARCH(asm.h)
BEGIN_PROC(local_setup_new_thread)
ldr r0, [sp, #-4]! @ Load first argument.
mov lr, pc @ Save return address
ldr pc, [sp, #-4]! @ Load function pointer from stack
new_thread_exit:
b new_thread_exit @ We infinitely loop for now.
END_PROC(local_setup_new_thread)

View File

@@ -0,0 +1,73 @@
/*
* Thread creation userspace helpers
*
* Copyright (C) 2009 B Labs Ltd.
*/
#include <thread.h>
#include <l4/api/errno.h>
char stack[THREADS_TOTAL][STACK_SIZE] ALIGN(8);
char *__stack_ptr = &stack[1][0];
char utcb[THREADS_TOTAL][UTCB_SIZE] ALIGN(8);
char *__utcb_ptr = &utcb[1][0];
extern void local_setup_new_thread(void);
int thread_create(int (*func)(void *), void *args, unsigned int flags,
struct task_ids *new_ids)
{
struct task_ids ids;
struct exregs_data exregs;
int err;
l4_getid(&ids);
/* Shared space only */
if (!(TC_SHARE_SPACE & flags)) {
printf("%s: This function allows only "
"shared space thread creation.\n",
__FUNCTION__);
return -EINVAL;
}
/* Create thread */
if ((err = l4_thread_control(THREAD_CREATE | flags, &ids)) < 0)
return err;
/* Check if more stack/utcb available */
if ((unsigned long)__utcb_ptr ==
(unsigned long)&utcb[THREADS_TOTAL][0])
return -ENOMEM;
if ((unsigned long)__stack_ptr ==
(unsigned long)&stack[THREADS_TOTAL][0])
return -ENOMEM;
/* First word of new stack is arg */
((unsigned long *)__stack_ptr)[-1] = (unsigned long)args;
/* Second word of new stack is function address */
((unsigned long *)__stack_ptr)[-2] = (unsigned long)func;
/* Setup new thread pc, sp, utcb */
memset(&exregs, 0, sizeof(exregs));
exregs_set_stack(&exregs, (unsigned long)__stack_ptr);
exregs_set_utcb(&exregs, (unsigned long)__utcb_ptr);
exregs_set_pc(&exregs, (unsigned long)local_setup_new_thread);
if ((err = l4_exchange_registers(&exregs, ids.tid)) < 0)
return err;
/* Update utcb, stack pointers */
__stack_ptr += STACK_SIZE;
__utcb_ptr += UTCB_SIZE;
/* Start the new thread */
if ((err = l4_thread_control(THREAD_RUN, &ids)) < 0)
return err;
memcpy(new_ids, &ids, sizeof(ids));
return 0;
}

View File

@@ -372,9 +372,9 @@ void init_vaddr_pool(void)
* addresses from this pool.
*/
address_pool_init(&device_vaddr_pool,
(struct id_pool *)&device_id_pool,
page_align_up(__end),
__pfn_to_addr(caparray[i].end));
(struct id_pool *)&device_id_pool,
page_align_up(__end),
__pfn_to_addr(caparray[i].end));
return;
} else
goto out_err;

View File

@@ -36,6 +36,8 @@ objects += SConscript('uart/pl011/SConscript', duplicate=0, \
exports = {'platform' : platform, 'env' : e})
objects += SConscript('timer/sp804/SConscript', duplicate=0, \
exports = {'platform' : platform, 'env' : e})
objects += SConscript('kmi/pl050/SConscript', duplicate=0, \
exports = {'platform' : platform, 'env' : e})
objects += SConscript('uart/omap/SConscript', duplicate=0, \
exports = {'platform' : platform, 'env' : e})

View File

@@ -0,0 +1,26 @@
#ifndef __KMI_H__
#define __KMI_H__
/*
* Current keyboard state
*/
struct keyboard_state{
int keyup;
int shift;
int caps_lock;
};
/* Common functions */
void kmi_irq_handler(unsigned long base);
int kmi_data_read(unsigned long base);
/* Keyboard specific calls */
char kmi_keyboard_read(unsigned long base, struct keyboard_state *state);
void kmi_keyboard_init(unsigned long base, unsigned int div);
/* Mouse specific calls */
void kmi_mouse_enable(unsigned long base);
void kmi_mouse_init(unsigned long base, unsigned int div);
#endif /* __KMI_H__ */

View File

@@ -0,0 +1,14 @@
Import('env', 'platform')
#Platforms using pl050
plat_list = ('eb', 'pba8', 'pba9', 'pb11mpcore', 'pb926')
# The set of source files associated with this SConscript file.
src_local = []
for plat_supported in plat_list:
if plat_supported == platform:
src_local += Glob('*.c')
obj = env.StaticObject(src_local)
Return('obj')

280
conts/libdev/kmi/pl050/keymap.h Executable file
View File

@@ -0,0 +1,280 @@
#ifndef __KEYMAP_H__
#define __KEYMAP_H__
/* Special meaning keys */
#define KEYCODE_LSHIFT 0x101
#define KEYCODE_RSHIFT 0x102
#define KEYCODE_LCTRL 0x103
#define KEYCODE_RCTRL 0x104
#define KEYCODE_ALT 0x105
#define KEYCODE_ALTGR 0x106
#define KEYCODE_CAPSLK 0x201
#define KEYCODE_SCRLK 0x202
#define KEYCODE_NUMLK 0x203
#define KEYCODE_TAB 0x301
#define KEYCODE_BACKSP 0x302
#define KEYCODE_RETURN 0x303
#define KEYCODE_ESCAPE 0x304
#define KEYCODE_ENTER 0x305
#define KEYCODE_PRTSCR 0x401
#define KEYCODE_BREAK 0x402
#define KEYCODE_INSERT 0x403
#define KEYCODE_HOME 0x404
#define KEYCODE_PAGEUP 0x405
#define KEYCODE_DELETE 0x406
#define KEYCODE_END 0x407
#define KEYCODE_PAGEDN 0x408
#define KEYCODE_UP 0x501
#define KEYCODE_DOWN 0x502
#define KEYCODE_LEFT 0x503
#define KEYCODE_RIGHT 0x504
#define KEYCODE_CENTER 0x505
#define KEYCODE_F1 0x601
#define KEYCODE_F2 0x602
#define KEYCODE_F3 0x603
#define KEYCODE_F4 0x604
#define KEYCODE_F5 0x605
#define KEYCODE_F6 0x606
#define KEYCODE_F7 0x607
#define KEYCODE_F8 0x608
#define KEYCODE_F9 0x609
#define KEYCODE_F10 0x60A
#define KEYCODE_F11 0x60B
#define KEYCODE_F12 0x60C
#define KEYCODE_WINL 0x701
#define KEYCODE_WINR 0x702
#define KEYCODE_MENU 0x703
#define MODIFIER_EXTENDED 0x00100000
#define MODIFIER_EXTENDED2 0x00200000
#define MODIFIER_RCTRL 0x00400000
#define MODIFIER_RSHIFT 0x00800000
#define MODIFIER_LSHIFT 0x01000000
#define MODIFIER_LCTRL 0x02000000
#define MODIFIER_ALT 0x04000000
#define MODIFIER_ALTGR 0x08000000
#define MODIFIER_SCRLK 0x10000000
#define MODIFIER_NUMLK 0x20000000
#define MODIFIER_CAPSLK 0x40000000
#define MODIFIER_RELEASE 0x80000000
#define MODIFIER_SHIFT (MODIFIER_LSHIFT | MODIFIER_RSHIFT)
#define MODIFIER_CTRL (MODIFIER_LCTRL | MODIFIER_RCTRL)
struct keyboard_key {
int nomods;
int shift;
int ext_nomods;
int ext_shift;
};
/*
* Keymap for a UK keyboard
* maps key numbers->key codes
*
* We will use scan code index to get the key
*
* FIXME: element 1 and 4 gives, muticharacter
* character constant error, fix this.
*/
struct keyboard_key keymap_uk2[256] = {
/* 0 */ {0,0,0,0},
#if 0
/* 1 */ {'`','¬',0,0},
#else
/* 1 */ {'`',0,0,0},
#endif
/* 2 */ {'1','!',0,0},
/* 3 */ {'2','"',0,0},
#if 0
/* 4 */ {'3','£',0,0},
#else
/* 4 */ {'3',0,0,0},
#endif
/* 5 */ {'4','$',0,0},
/* 6 */ {'5','%',0,0},
/* 7 */ {'6','^',0,0},
/* 8 */ {'7','&',0,0},
/* 9 */ {'8','*',0,0},
/* 10 */ {'9','(',0,0},
/* 11 */ {'0',')',0,0},
/* 12 */ {'-','_',0,0},
/* 13 */ {'=','+',0,0},
/* 14 */ {0,0,0,0},
/* 15 */ {KEYCODE_BACKSP,0,0,0},
/* 16 */ {KEYCODE_TAB,0,0,0},
/* 17 */ {'q','Q',0,0},
/* 18 */ {'w','W',0,0},
/* 19 */ {'e','E',0,0},
/* 20 */ {'r','R',0,0},
/* 21 */ {'t','T',0,0},
/* 22 */ {'y','Y',0,0},
/* 23 */ {'u','U',0,0},
/* 24 */ {'i','I',0,0},
/* 25 */ {'o','O',0,0},
/* 26 */ {'p','P',0,0},
/* 27 */ {'[','{',0,0},
/* 28 */ {']','}',0,0},
/* 29 */ {'#','~',0,0},
/* 30 */ {KEYCODE_CAPSLK,0,0,0},
/* 31 */ {'a','A',0,0},
/* 32 */ {'s','S',0,0},
/* 33 */ {'d','D',0,0},
/* 34 */ {'f','F',0,0},
/* 35 */ {'g','G',0,0},
/* 36 */ {'h','H',0,0},
/* 37 */ {'j','J',0,0},
/* 38 */ {'k','K',0,0},
/* 39 */ {'l','L',0,0},
/* 40 */ {';',':',0,0},
/* 41 */ {'\'','@',0,0},
/* 42 */ {0,0,0,0},
/* 43 */ {KEYCODE_RETURN,0,KEYCODE_ENTER,0},
/* 44 */ {KEYCODE_LSHIFT,0,0,0},
/* 45 */ {'\\','|',0,0},
/* 46 */ {'z','Z',0,0},
/* 47 */ {'x','X',0,0},
/* 48 */ {'c','C',0,0},
/* 49 */ {'v','V',0,0},
/* 50 */ {'b','B',0,0},
/* 51 */ {'n','N',0,0},
/* 52 */ {'m','M',0,0},
/* 53 */ {',','<',0,0},
/* 54 */ {'.','>',0,0},
/* 55 */ {'/','?','/' | MODIFIER_NUMLK,0},
/* 56 */ {0,0,0,0},
/* 57 */ {KEYCODE_RSHIFT,0,0,0},
/* 58 */ {KEYCODE_LCTRL,0,KEYCODE_RCTRL,0},
/* 59 */ {0,0,0,0},
/* 60 */ {KEYCODE_ALT,0,KEYCODE_ALTGR,0},
/* 61 */ {' ',0,0,0},
/* 62 */ {KEYCODE_ALTGR,0,0,0},
/* 63 */ {0,0,0,0},
/* 64 */ {KEYCODE_RCTRL,0,0,0},
/* 65 */ {0,0,0,0},
/* 66 */ {0,0,0,0},
/* 67 */ {0,0,0,0},
/* 68 */ {0,0,0,0},
/* 69 */ {0,0,0,0},
/* 70 */ {0,0,0,0},
/* 71 */ {0,0,0,0},
/* 72 */ {0,0,0,0},
/* 73 */ {0,0,0,0},
/* 74 */ {0,0,0,0},
/* 75 */ {KEYCODE_INSERT,0,0,0},
/* 76 */ {KEYCODE_DELETE,0,0,0},
/* 77 */ {0,0,0,0},
/* 78 */ {0,0,0,0},
/* 79 */ {KEYCODE_LEFT,0,0,0},
/* 80 */ {KEYCODE_HOME,0,0,0},
/* 81 */ {KEYCODE_END,0,0,0},
/* 82 */ {0,0,0,0},
/* 83 */ {KEYCODE_UP,0,0,0},
/* 84 */ {KEYCODE_DOWN,0,0,0},
/* 85 */ {KEYCODE_PAGEUP,0,0,0},
/* 86 */ {KEYCODE_PAGEDN,0,0,0},
/* 87 */ {0,0,0,0},
/* 88 */ {0,0,0,0},
/* 89 */ {KEYCODE_RIGHT,0,0,0},
/* 90 */ {KEYCODE_NUMLK,0,KEYCODE_BREAK,0},
/* 91 */ {KEYCODE_HOME | MODIFIER_NUMLK,0,KEYCODE_HOME,0},
/* 92 */ {KEYCODE_LEFT | MODIFIER_NUMLK,0,KEYCODE_LEFT,0},
/* 93 */ {KEYCODE_END | MODIFIER_NUMLK,0,KEYCODE_END,0},
/* 94 */ {0,0,0,0},
/* 95 */ {'/' | MODIFIER_NUMLK,0,0},
/* 96 */ {KEYCODE_UP | MODIFIER_NUMLK,0,KEYCODE_UP,0},
/* 97 */ {KEYCODE_CENTER | MODIFIER_NUMLK,0,KEYCODE_CENTER,0},
/* 98 */ {KEYCODE_DOWN | MODIFIER_NUMLK,0,KEYCODE_DOWN,0},
/* 99 */ {KEYCODE_INSERT | MODIFIER_NUMLK,0,KEYCODE_INSERT,0},
/* 100 */ {'*' | MODIFIER_NUMLK,0,KEYCODE_PRTSCR,0},
/* 101 */ {KEYCODE_PAGEUP | MODIFIER_NUMLK,0,KEYCODE_PAGEUP,0},
/* 102 */ {KEYCODE_RIGHT | MODIFIER_NUMLK,0,KEYCODE_RIGHT,0},
/* 103 */ {KEYCODE_PAGEDN | MODIFIER_NUMLK,0,KEYCODE_PAGEDN,0},
/* 104 */ {KEYCODE_DELETE | MODIFIER_NUMLK,0,KEYCODE_DELETE,0},
/* 105 */ {'-' | MODIFIER_NUMLK,0,0,0},
/* 106 */ {'+' | MODIFIER_NUMLK,0,0,0},
/* 107 */ {KEYCODE_ENTER,0,0,0},
/* 108 */ {0,0,0,0},
/* 109 */ {0,0,0,0},
/* 110 */ {KEYCODE_ESCAPE,0,0,0},
/* 111 */ {0,0,0,0},
/* 112 */ {KEYCODE_F1,0,0,7},
/* 113 */ {KEYCODE_F2,0,0,0},
/* 114 */ {KEYCODE_F3,0,0,0},
/* 115 */ {KEYCODE_F4,0,0,0},
/* 116 */ {KEYCODE_F5,0,0,0},
/* 117 */ {KEYCODE_F6,0,0,0},
/* 118 */ {KEYCODE_F7,0,0,0},
/* 119 */ {KEYCODE_F8,0,0,0},
/* 120 */ {KEYCODE_F9,0,0,0},
/* 121 */ {KEYCODE_F10,0,0,0},
/* 122 */ {KEYCODE_F11,0,0,0},
/* 123 */ {KEYCODE_F12,0,0,0},
/* 124 */ {KEYCODE_PRTSCR,0,0,0},
/* 125 */ {KEYCODE_SCRLK,0,KEYCODE_BREAK,0},
/* 126 */ {KEYCODE_BREAK,0,0,0},
/* 127 */ {0,0,0,0},
/* 128 */ {KEYCODE_WINL,0,KEYCODE_WINL,0},
/* 129 */ {KEYCODE_WINR,0,KEYCODE_WINR,0},
/* 130 */ {KEYCODE_MENU,0,KEYCODE_MENU,0},
/* currently no keys with numbers > 130 */
/* 131 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 140 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 150 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 160 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 170 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 180 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 190 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 200 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 210 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 220 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 230 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 240 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
/* 250 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}
};
/*
* Scan code to key number conversion table for
* an extended AT keyboard in mode 2
*
* This will give us the key index for keyboard
*/
int scancode_mode2_extended[256] = {
0, 120, 0, 116, 114, 112, 113,
123, 0, 121, 119, 117, 115, 16,
1, 0, 0, 60, 44, 0, 58,
17, 2, 0, 0, 0, 46, 32,
31, 18, 3, 128, 0, 48, 47,
33, 19, 5, 4, 129, 0, 61,
49, 34, 21, 20, 6, 130, 0,
51, 50, 36, 35, 22, 7, 0,
0, 0, 52, 37, 23, 8, 9,
0, 0, 53, 38, 24, 25, 11,
10, 0, 0, 54, 55, 39, 40,
26, 12, 0, 0, 0, 41, 0,
27, 13, 0, 0, 30, 57, 43,
28, 0, 29, 0, 0, 0, 45,
0, 0, 0, 0, 15, 0, 0,
93, 0, 92, 91, 0, 0, 0,
99, 104, 98, 97, 102, 96, 110,
90, 122, 106, 103, 105, 100, 101,
125, 0, 0, 0, 0, 118, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
/* no keys with codes > 0x8F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#endif /* __KEYMAP_H__ */

387
conts/libdev/kmi/pl050/kmi.c Executable file
View File

@@ -0,0 +1,387 @@
/*
* PL050 Primecell Keyboard, Mouse driver
*
* Copyright (C) 2010 Amit Mahajan
*/
#include <libdev/kmi.h>
#include "kmi.h"
#include "keymap.h"
/*
* Reading Rx data automatically clears the RXITR
*/
void kmi_irq_handler(unsigned long base)
{
}
int kmi_data_read(unsigned long base)
{
/* Check and return if data present */
if (*(volatile unsigned long *)(base + PL050_KMISTAT) & KMI_RXFULL)
return *(volatile unsigned long *)(base + PL050_KMIDATA);
else
return 0;
}
#if 0
char kmi_keyboard_read(int c, struct keyboard_state *state)
{
int keycode, shkeycode;
int keynum;
int extflag;
int modmask;
/* Special codes */
switch (c) {
case 0xF0:
/* release */
state->modifiers |= MODIFIER_RELEASE;
return 0;
case 0xE0:
/* extended */
state->modifiers |= MODIFIER_EXTENDED;
return 0;
case 0xE1:
/* extended for 2 characters - only used for Break in mode 2 */
state->modifiers |= MODIFIER_EXTENDED;
state->modifiers |= MODIFIER_EXTENDED2;
return 0;
}
extflag = 1;
modmask = 0xFFFFFFFF;
/* Is this a scan code? */
if (c > 0 && c <= 0x9F)
{
keynum = scancode_mode2_extended[c];
/* ignore unrecognised codes */
if (!keynum)
{
state->modifiers &= ~MODIFIER_RELEASE;
return 0;
}
/* is this an extended code? */
if (state->modifiers & MODIFIER_EXTENDED)
{
keycode = keymap_uk2[keynum].ext_nomods;
extflag = 0;
state->modifiers &= ~MODIFIER_EXTENDED;
if (!keycode)
{
state->modifiers &= ~MODIFIER_RELEASE;
return 0;
}
}
else if (state->modifiers & MODIFIER_EXTENDED2)
{
keycode = keymap_uk2[keynum].ext_nomods;
extflag = 0;
state->modifiers &= ~MODIFIER_EXTENDED2;
if (!keycode)
{
state->modifiers &= ~MODIFIER_RELEASE;
return 0;
}
}
else
{
keycode = keymap_uk2[keynum].nomods;
if (!keycode)
{
state->modifiers &= ~MODIFIER_RELEASE;
return 0;
}
}
/* handle shift */
if (state->modifiers & MODIFIER_CAPSLK)
{
if (keycode >= 'a' && keycode <= 'z')
{
if (!(state->modifiers & MODIFIER_SHIFT))
{
shkeycode = !extflag ? keymap_uk2[keynum].ext_shift : keymap_uk2[keynum].shift;
if (shkeycode)
keycode = shkeycode;
}
}
else
{
if (state->modifiers & MODIFIER_SHIFT)
{
shkeycode = !extflag ? keymap_uk2[keynum].ext_shift : keymap_uk2[keynum].shift;
if (shkeycode)
keycode = shkeycode;
}
}
}
else
{
if (state->modifiers & MODIFIER_SHIFT)
{
shkeycode = extflag ? keymap_uk2[keynum].ext_shift : keymap_uk2[keynum].shift;
if (shkeycode)
keycode = shkeycode;
}
}
/* handle the numeric keypad */
if (keycode & MODIFIER_NUMLK)
{
keycode &= ~MODIFIER_NUMLK;
if (state->modifiers & MODIFIER_NUMLK)
{
if (!(state->modifiers & MODIFIER_SHIFT))
{
switch (keycode)
{
case KEYCODE_HOME:
keycode = '7';
break;
case KEYCODE_UP:
keycode = '8';
break;
case KEYCODE_PAGEUP:
keycode = '9';
break;
case KEYCODE_LEFT:
keycode = '4';
break;
case KEYCODE_CENTER:
keycode = '5';
break;
case KEYCODE_RIGHT:
keycode = '6';
break;
case KEYCODE_END:
keycode = '1';
break;
case KEYCODE_DOWN:
keycode = '2';
break;
case KEYCODE_PAGEDN:
keycode = '3';
break;
case KEYCODE_INSERT:
keycode = '0';
break;
case KEYCODE_DELETE:
keycode = '.';
break;
}
}
else
modmask = ~MODIFIER_SHIFT;
}
}
/* modifier keys */
switch (keycode)
{
case KEYCODE_LSHIFT:
if (state->modifiers & MODIFIER_RELEASE)
state->modifiers &= ~(MODIFIER_LSHIFT | MODIFIER_RELEASE);
else
state->modifiers |= MODIFIER_LSHIFT;
return 0;
case KEYCODE_RSHIFT:
if (state->modifiers & MODIFIER_RELEASE)
state->modifiers &= ~(MODIFIER_RSHIFT | MODIFIER_RELEASE);
else
state->modifiers |= MODIFIER_RSHIFT;
return 0;
case KEYCODE_LCTRL:
if (state->modifiers & MODIFIER_RELEASE)
state->modifiers &= ~(MODIFIER_LCTRL | MODIFIER_RELEASE);
else
state->modifiers |= MODIFIER_LCTRL;
return 0;
case KEYCODE_RCTRL:
if (state->modifiers & MODIFIER_RELEASE)
state->modifiers &= ~(MODIFIER_RCTRL | MODIFIER_RELEASE);
else
state->modifiers |= MODIFIER_RCTRL;
return 0;
case KEYCODE_ALT:
if (state->modifiers & MODIFIER_RELEASE)
state->modifiers &= ~(MODIFIER_ALT | MODIFIER_RELEASE);
else
state->modifiers |= MODIFIER_ALT;
return 0;
case KEYCODE_ALTGR:
if (state->modifiers & MODIFIER_RELEASE)
state->modifiers &= ~(MODIFIER_ALTGR | MODIFIER_RELEASE);
else
state->modifiers |= MODIFIER_ALTGR;
return 0;
case KEYCODE_CAPSLK:
if (state->modifiers & MODIFIER_RELEASE)
state->modifiers &= ~MODIFIER_RELEASE;
else
{
state->modifiers ^= MODIFIER_CAPSLK;
//__keyb_update_locks (state);
}
return 0;
case KEYCODE_SCRLK:
if (state->modifiers & MODIFIER_RELEASE)
state->modifiers &= ~MODIFIER_RELEASE;
else
{
state->modifiers ^= MODIFIER_SCRLK;
//__keyb_update_locks (state);
}
return 0;
case KEYCODE_NUMLK:
if (state->modifiers & MODIFIER_RELEASE)
state->modifiers &= ~MODIFIER_RELEASE;
else
{
state->modifiers ^= MODIFIER_NUMLK;
//__keyb_update_locks (state);
}
return 0;
}
if (state->modifiers & MODIFIER_RELEASE)
{
/* clear release condition */
state->modifiers &= ~MODIFIER_RELEASE;
}
else
{
/* write code into the buffer */
return keycode;
}
return 0;
}
return 0;
}
#endif
/*
* Simple logic to interpret keyboard keys and shift keys
* TODO: Add support for all the modifier keys
*
* Keyevents work in 3 phase manner, if you press 'A':
* 1. scan code for 'A' is generated
* 2. Key release event i.e KYBD_DATA_KEYUP
* 3. scan code for 'A' again is generated
*/
char kmi_keyboard_read(unsigned long base, struct keyboard_state *state)
{
int keynum, keycode = 0;
/* Read Keyboard RX buffer */
unsigned char data = kmi_data_read(base);
/* if a key up occurred (key released) occured */
if (data == KYBD_DATA_KEYUP) {
state->keyup = 1;
return 0;
}
else if (state->keyup){
state->keyup = 0;
/* Check if shift was lifted */
if ((data == KYBD_DATA_SHIFTL) || (data == KYBD_DATA_SHIFTR)) {
state->shift = 0;
}
else {
/* Find key number */
keynum = scancode_mode2_extended[data];
if(state->shift)
keycode = keymap_uk2[keynum].shift;
else
keycode = keymap_uk2[keynum].nomods;
}
}
else if ((data == KYBD_DATA_SHIFTL) || (data == KYBD_DATA_SHIFTR)) {
state->shift = 1;
}
return (unsigned char)keycode;
}
void kmi_keyboard_init(unsigned long base, unsigned int div)
{
/* STOP KMI */
*(volatile unsigned long *)(base + PL050_KMICR) = 0x0;
/*
* For versatile, KMI refernce clock = 24MHz
* KMI manual says we need 8MHz clock,
* so divide by 3
*/
*(volatile unsigned long *)(base + PL050_KMICLKDIV) = div;
/* Enable KMI and TX/RX interrupts */
*(volatile unsigned long *)(base + PL050_KMICR) =
KMI_RXINTR | KMI_EN;
/* Reset and wait for reset to complete */
*(volatile unsigned long *)(base + PL050_KMIDATA) =
KYBD_DATA_RESET;
while(kmi_data_read(base) != KYBD_DATA_RTR);
}
void kmi_mouse_enable(unsigned long base)
{
unsigned long *datareg = (unsigned long *)(base + PL050_KMIDATA);
*datareg = MOUSE_DATA_ENABLE;
/*sleep for sometime here */
while (*datareg != MOUSE_DATA_ACK);
}
void kmi_mouse_init(unsigned long base, unsigned int div)
{
int data[2];
/* STOP KMI */
*(volatile unsigned long *)(base + PL050_KMICR) = 0x0;
/*
* For versatile, KMI refernce clock = 24MHz
* KMI manual says we need 8MHz clock,
* so divide by 3
*/
*(volatile unsigned long *)(base + PL050_KMICLKDIV) = div;
/* Enable KMI and TX/RX interrupts */
*(volatile unsigned long *)(base + PL050_KMICR) =
KMI_RXINTR | KMI_EN;
/* Reset and wait for reset to complete */
*(volatile unsigned long *)(base + PL050_KMIDATA) =
MOUSE_DATA_RESET;
do {
data[0] = kmi_data_read(base);
/* Some sleep here */
data[1] = kmi_data_read(base);
}while((data[0] != MOUSE_DATA_ACK) && (data[1] != MOUSE_DATA_RTR));
/* Set enable data code to mouse */
kmi_mouse_enable(base);
}

59
conts/libdev/kmi/pl050/kmi.h Executable file
View File

@@ -0,0 +1,59 @@
#ifndef __PL050_KMI_H__
#define __PL050_KMI_H__
/* Register offsets */
#define PL050_KMICR 0x00
#define PL050_KMISTAT 0x04
#define PL050_KMIDATA 0x08
#define PL050_KMICLKDIV 0x0C
#define PL050_KMIIR 0x10
/* Bit definitions for KMI control register */
#define KMI_TYPE (1 << 0x5)
#define KMI_RXINTR (1 << 0x4)
#define KMI_TXINTR (1 << 0x3)
#define KMI_EN (1 << 0x2)
#define KMI_FD (1 << 0x1)
#define KMI_FC (1 << 0x0)
/* KMI generic defines */
#define KMI_DATA_RESET 0xFF
#define KMI_DATA_RTR 0xAA
/* Keyboard special defines */
#define KYBD_DATA_RESET KMI_DATA_RESET // Keyboard reset
#define KYBD_DATA_RTR KMI_DATA_RTR // Keyboard response to reset
#define KYBD_DATA_KEYUP 0xF0 // Key up control code
#define KYBD_DATA_SHIFTL 18 // Shift key left
#define KYBD_DATA_SHIFTR 89 // Shift key right
/* Bit definitions for KMI STAT register */
#define KMI_TXEMPTY (1 << 0x6)
#define KMI_TXBUSY (1 << 0x5)
#define KMI_RXFULL (1 << 0x4)
#define KMI_RXBUSY (1 << 0x3)
#define KMI_RXPARITY (1 << 0x2)
#define KMI_CLKIN (1 << 0x1)
#define KMI_DATAIN (1 << 0x0)
/* Mouse special defines */
#define MOUSE_DATA_RESET KMI_DATA_RESET // Mouse reset
#define MOUSE_DATA_RTR KMI_DATA_RTR // Mouse response to reset
#define MOUSE_DATA_ACK 0xFA
#define MOUSE_DATA_ENABLE 0xF4 // Mouse enable
/* Common functions */
void kmi_irq_handler(unsigned long base);
int kmi_data_read(unsigned long base);
/* Keyboard specific calls */
char kmi_keyboard_read(unsigned long base, struct keyboard_state *state);
void kmi_keyboard_init(unsigned long base, unsigned int div);
/* Mouse specific calls */
void kmi_mouse_enable(unsigned long base);
void kmi_mouse_init(unsigned long base, unsigned int div);
#endif /* __PL050_KMI_H__ */

View File

@@ -46,6 +46,8 @@
*/
#define CAP_DEVTYPE_TIMER 1
#define CAP_DEVTYPE_UART 2
#define CAP_DEVTYPE_KEYBOARD 3
#define CAP_DEVTYPE_MOUSE 4
#define CAP_DEVTYPE_OTHER 0xF
#define CAP_DEVTYPE_MASK 0xFFFF
#define CAP_DEVNUM_MASK 0xFFFF0000

View File

@@ -47,6 +47,9 @@ struct irq_desc {
/* Notification slot for this irq */
int task_notify_slot;
/* If user will ack this irq */
int user_ack;
/* Waitqueue head for this irq */
struct waitqueue_head wqh_irq;

View File

@@ -13,7 +13,7 @@
* an irq on any irq chip.
*/
#define VIC_CHIP_OFFSET 0
#define SIC_CHIP_OFFSET 32
#define SIC_CHIP_OFFSET 31
/* Maximum irqs on VIC and SIC */
#define VIC_IRQS_MAX 32
@@ -33,6 +33,8 @@
/* Secondary Interrupt controller local IRQ numbers */
#define SIC_IRQ_SWI 0
#define SIC_IRQ_KEYBOARD 3
#define SIC_IRQ_MOUSE 4
#define SIC_IRQ_UART3 6
/* Global irq numbers, note these should reflect global device names */
@@ -47,6 +49,7 @@
#define IRQ_SICSWI (SIC_IRQ_SWI + SIC_CHIP_OFFSET)
#define IRQ_UART3 (SIC_IRQ_UART3 + SIC_CHIP_OFFSET)
#define IRQ_KEYBOARD0 (SIC_IRQ_KEYBOARD + SIC_CHIP_OFFSET)
#define IRQ_MOUSE0 (SIC_IRQ_MOUSE + SIC_CHIP_OFFSET)
#endif /* __PLATFORM_IRQ_H__ */

View File

@@ -17,6 +17,8 @@
* as we use these names for device capability
*/
#define PLATFORM_SYSTEM_REGISTERS 0x10000000 /* System registers */
#define PLATFORM_KEYBOARD0_BASE 0x10006000 /* Keyboard */
#define PLATFORM_MOUSE0_BASE 0x10007000 /* Mouse */
#define PLATFORM_SYSCTRL_BASE 0x101E0000 /* System controller */
#define PLATFORM_WATCHDOG_BASE 0x101E1000 /* Watchdog */
#define PLATFORM_TIMER0_BASE 0x101E2000 /* Timers 0 and 1 */
@@ -44,7 +46,9 @@
#define PLATFORM_SYSCTRL_VBASE (IO_AREA0_VADDR + (4 * DEVICE_PAGE))
/* Add userspace devices here as they become necessary for irqs */
#define PLATFORM_TIMER1_VBASE (IO_AREA0_VADDR + (6 * DEVICE_PAGE))
#define PLATFORM_TIMER1_VBASE (IO_AREA0_VADDR + (6 * DEVICE_PAGE))
#define PLATFORM_KEYBOARD0_VBASE (IO_AREA0_VADDR + (7 * DEVICE_PAGE))
#define PLATFORM_MOUSE0_VBASE (IO_AREA0_VADDR + (8 * DEVICE_PAGE))
/* The SP810 system controller offsets */
#define SP810_BASE PLATFORM_SYSCTRL_VBASE
@@ -55,6 +59,8 @@
#define PLATFORM_UART2_SIZE 0x1000
#define PLATFORM_UART3_SIZE 0x1000
#define PLATFORM_TIMER1_SIZE 0x1000
#define PLATFORM_KEYBOARD0_SIZE 0x1000
#define PLATFORM_MOUSE0_SIZE 0x1000
#endif /* __PLATFORM_PB926_OFFSETS_H__ */

View File

@@ -50,7 +50,7 @@ device_suppress_sym = \
'''\tcont${CONTID}_cap_device_${DEVNAME_LOWER}
'''
devices = ['UART1', 'UART2', 'UART3', 'TIMER1']
devices = ['UART1', 'UART2', 'UART3', 'TIMER1', 'KEYBOARD0', 'MOUSE0']
#
# When a symbol is used by a single container, sometimes it is

View File

@@ -111,6 +111,16 @@ int irq_wait(l4id_t irq_index)
if ((ret = tcb_check_and_lazy_map_utcb(current, 1)) < 0)
return ret;
/*
* In case user has asked for unmasking the irq only after
* user hanlder is done, unmask the irq
*
* FIXME: This is not the correct place for this call,
* fix this.
*/
if (desc->user_ack)
irq_enable(irq_index);
/* Wait until the irq changes slot value */
WAIT_EVENT(&desc->wqh_irq,
utcb->notify[desc->task_notify_slot] != 0,

View File

@@ -152,7 +152,11 @@ void do_irq(void)
BUG();
}
irq_enable(irq_index);
/*
* Do not enable irq if user wants to do it explicitely
*/
if (!this_irq->user_ack)
irq_enable(irq_index);
}

View File

@@ -65,6 +65,23 @@ static int platform_timer_user_handler(struct irq_desc *desc)
return 0;
}
/*
* Keyboard handler for userspace
*/
static int platform_keyboard_user_handler(struct irq_desc *desc)
{
irq_thread_notify(desc);
return 0;
}
/*
* Mouse handler for userspace
*/
static int platform_mouse_user_handler(struct irq_desc *desc)
{
irq_thread_notify(desc);
return 0;
}
/*
* Built-in irq handlers initialised at compile time.
@@ -75,11 +92,25 @@ struct irq_desc irq_desc_array[IRQS_MAX] = {
.name = "Timer0",
.chip = &irq_chip_array[0],
.handler = platform_timer_handler,
.user_ack = 0,
},
[IRQ_TIMER1] = {
.name = "Timer1",
.chip = &irq_chip_array[0],
.handler = platform_timer_user_handler,
.user_ack = 0,
},
[IRQ_KEYBOARD0] = {
.name = "Keyboard",
.chip = &irq_chip_array[1],
.handler = platform_keyboard_user_handler,
.user_ack = 1,
},
[IRQ_MOUSE0] = {
.name = "Mouse",
.chip = &irq_chip_array[1],
.handler = platform_mouse_user_handler,
.user_ack = 1,
},
};

View File

@@ -30,45 +30,66 @@
*/
int platform_setup_device_caps(struct kernel_resources *kres)
{
struct capability *uart[4], *timer[2];
struct capability *uart[3], *timer[1],
*keyboard[1], *mouse[1];
/* Setup capabilities for userspace uarts and timers */
uart[0] = alloc_bootmem(sizeof(*uart[0]), 0);
uart[0]->start = __pfn(PLATFORM_UART1_BASE);
uart[0]->end = uart[0]->start + 1;
uart[0]->size = uart[0]->end - uart[1]->start;
cap_set_devtype(uart[0], CAP_DEVTYPE_UART);
cap_set_devnum(uart[0], 1);
link_init(&uart[0]->list);
cap_list_insert(uart[0], &kres->devmem_free);
uart[1] = alloc_bootmem(sizeof(*uart[1]), 0);
uart[1]->start = __pfn(PLATFORM_UART1_BASE);
uart[1]->start = __pfn(PLATFORM_UART2_BASE);
uart[1]->end = uart[1]->start + 1;
uart[1]->size = uart[1]->end - uart[1]->start;
cap_set_devtype(uart[1], CAP_DEVTYPE_UART);
cap_set_devnum(uart[1], 1);
cap_set_devnum(uart[1], 2);
link_init(&uart[1]->list);
cap_list_insert(uart[1], &kres->devmem_free);
uart[2] = alloc_bootmem(sizeof(*uart[2]), 0);
uart[2]->start = __pfn(PLATFORM_UART2_BASE);
uart[2]->start = __pfn(PLATFORM_UART3_BASE);
uart[2]->end = uart[2]->start + 1;
uart[2]->size = uart[2]->end - uart[2]->start;
cap_set_devtype(uart[2], CAP_DEVTYPE_UART);
cap_set_devnum(uart[2], 2);
cap_set_devnum(uart[2], 3);
link_init(&uart[2]->list);
cap_list_insert(uart[2], &kres->devmem_free);
uart[3] = alloc_bootmem(sizeof(*uart[3]), 0);
uart[3]->start = __pfn(PLATFORM_UART3_BASE);
uart[3]->end = uart[3]->start + 1;
uart[3]->size = uart[3]->end - uart[3]->start;
cap_set_devtype(uart[3], CAP_DEVTYPE_UART);
cap_set_devnum(uart[3], 3);
link_init(&uart[3]->list);
cap_list_insert(uart[3], &kres->devmem_free);
/* Setup timer1 capability as free */
timer[1] = alloc_bootmem(sizeof(*timer[1]), 0);
timer[1]->start = __pfn(PLATFORM_TIMER1_BASE);
timer[1]->end = timer[1]->start + 1;
timer[1]->size = timer[1]->end - timer[1]->start;
cap_set_devtype(timer[1], CAP_DEVTYPE_TIMER);
cap_set_devnum(timer[1], 1);
link_init(&timer[1]->list);
cap_list_insert(timer[1], &kres->devmem_free);
timer[0] = alloc_bootmem(sizeof(*timer[0]), 0);
timer[0]->start = __pfn(PLATFORM_TIMER1_BASE);
timer[0]->end = timer[0]->start + 1;
timer[0]->size = timer[0]->end - timer[0]->start;
cap_set_devtype(timer[0], CAP_DEVTYPE_TIMER);
cap_set_devnum(timer[0], 1);
link_init(&timer[0]->list);
cap_list_insert(timer[0], &kres->devmem_free);
/* Setup keyboard capability as free */
keyboard[0] = alloc_bootmem(sizeof(*keyboard[0]), 0);
keyboard[0]->start = __pfn(PLATFORM_KEYBOARD0_BASE);
keyboard[0]->end = keyboard[0]->start + 1;
keyboard[0]->size = keyboard[0]->end - keyboard[0]->start;
cap_set_devtype(keyboard[0], CAP_DEVTYPE_KEYBOARD);
cap_set_devnum(keyboard[0], 0);
link_init(&keyboard[0]->list);
cap_list_insert(keyboard[0], &kres->devmem_free);
/* Setup mouse capability as free */
mouse[0] = alloc_bootmem(sizeof(*mouse[0]), 0);
mouse[0]->start = __pfn(PLATFORM_MOUSE0_BASE);
mouse[0]->end = mouse[0]->start + 1;
mouse[0]->size = mouse[0]->end - mouse[0]->start;
cap_set_devtype(mouse[0], CAP_DEVTYPE_MOUSE);
cap_set_devnum(mouse[0], 0);
link_init(&mouse[0]->list);
cap_list_insert(mouse[0], &kres->devmem_free);
return 0;
}
@@ -116,11 +137,21 @@ void init_platform_irq_controller()
irq_controllers_init();
}
/* Add userspace devices here as you develop their irq handlers */
void init_platform_devices()
{
/* Add userspace devices here as you develop their irq handlers */
/* TIMER23 */
add_boot_mapping(PLATFORM_TIMER1_BASE, PLATFORM_TIMER1_VBASE,
PAGE_SIZE, MAP_IO_DEFAULT);
/* KEYBOARD - KMI0 */
add_boot_mapping(PLATFORM_KEYBOARD0_BASE, PLATFORM_KEYBOARD0_VBASE,
PAGE_SIZE, MAP_IO_DEFAULT);
/* MOUSE - KMI1 */
add_boot_mapping(PLATFORM_MOUSE0_BASE, PLATFORM_MOUSE0_VBASE,
PAGE_SIZE, MAP_IO_DEFAULT);
}
/* If these bits are off, 32Khz OSC source is used */