mirror of
https://github.com/drasko/codezero.git
synced 2026-01-11 18:33:16 +01:00
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:
@@ -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
|
||||
|
||||
316
config/cml/examples/kmi/kmi-pb926.cml
Normal file
316
config/cml/examples/kmi/kmi-pb926.cml
Normal 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!
|
||||
70
conts/baremetal/kmi_service/SConstruct
Executable file
70
conts/baremetal/kmi_service/SConstruct
Executable 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')
|
||||
21
conts/baremetal/kmi_service/container.c
Executable file
21
conts/baremetal/kmi_service/container.c
Executable 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();
|
||||
}
|
||||
|
||||
13
conts/baremetal/kmi_service/include/container.h
Executable file
13
conts/baremetal/kmi_service/include/container.h
Executable 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__ */
|
||||
18
conts/baremetal/kmi_service/include/keyboard.h
Executable file
18
conts/baremetal/kmi_service/include/keyboard.h
Executable 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__ */
|
||||
7
conts/baremetal/kmi_service/include/linker.h
Executable file
7
conts/baremetal/kmi_service/include/linker.h
Executable file
@@ -0,0 +1,7 @@
|
||||
#ifndef __LINKER_H__
|
||||
#define __LINKER_H__
|
||||
|
||||
extern char vma_start[];
|
||||
extern char __end[];
|
||||
|
||||
#endif /* __LINKER_H__ */
|
||||
19
conts/baremetal/kmi_service/include/mouse.h
Executable file
19
conts/baremetal/kmi_service/include/mouse.h
Executable 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__ */
|
||||
19
conts/baremetal/kmi_service/include/thread.h
Executable file
19
conts/baremetal/kmi_service/include/thread.h
Executable 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__ */
|
||||
424
conts/baremetal/kmi_service/main.c
Executable file
424
conts/baremetal/kmi_service/main.c
Executable 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();
|
||||
}
|
||||
|
||||
|
||||
11
conts/baremetal/kmi_service/src/new_thread.S
Executable file
11
conts/baremetal/kmi_service/src/new_thread.S
Executable 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)
|
||||
|
||||
73
conts/baremetal/kmi_service/src/thread.c
Executable file
73
conts/baremetal/kmi_service/src/thread.c
Executable 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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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})
|
||||
|
||||
26
conts/libdev/include/libdev/kmi.h
Executable file
26
conts/libdev/include/libdev/kmi.h
Executable 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__ */
|
||||
14
conts/libdev/kmi/pl050/SConscript
Normal file
14
conts/libdev/kmi/pl050/SConscript
Normal 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
280
conts/libdev/kmi/pl050/keymap.h
Executable 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
387
conts/libdev/kmi/pl050/kmi.c
Executable 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
59
conts/libdev/kmi/pl050/kmi.h
Executable 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__ */
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user