/branches/dynload/uspace/app/bdsh/input.c |
---|
94,7 → 94,6 |
return rc; |
} |
/* Borrowed from Jiri Svoboda's 'cli' uspace app */ |
static void read_line(char *buffer, int n) |
{ |
char c; |
114,9 → 113,11 |
} |
continue; |
} |
if (c >= ' ') { |
putchar(c); |
buffer[chars++] = c; |
} |
} |
putchar('\n'); |
buffer[chars] = '\0'; |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/ls/ls.c |
---|
114,7 → 114,7 |
ls_print_dir(dp->d_name); |
break; |
case LS_FILE: |
ls_print_file(dp->d_name); |
ls_print_file(dp->d_name, buff); |
break; |
case LS_BOGUS: |
/* Odd chance it was deleted from the time readdir() found |
143,9 → 143,9 |
return; |
} |
static void ls_print_file(const char *f) |
static void ls_print_file(const char *name, const char *pathname) |
{ |
printf("%-40s\t%llu\n", f, (long long) flen(f)); |
printf("%-40s\t%llu\n", name, (long long) flen(pathname)); |
return; |
} |
192,7 → 192,7 |
free(buff); |
return CMD_FAILURE; |
case LS_FILE: |
ls_print_file(buff); |
ls_print_file(buff, buff); |
break; |
case LS_DIR: |
dirp = opendir(buff); |
/branches/dynload/uspace/app/bdsh/cmds/modules/ls/ls.h |
---|
10,7 → 10,7 |
static unsigned int ls_scope(const char *); |
static void ls_scan_dir(const char *, DIR *); |
static void ls_print_dir(const char *); |
static void ls_print_file(const char *); |
static void ls_print_file(const char *, const char *); |
#endif /* LS_H */ |
/branches/dynload/uspace/app/init/init.c |
---|
112,6 → 112,8 |
spawn("/srv/fb"); |
spawn("/srv/kbd"); |
spawn("/srv/console"); |
spawn("/srv/fhc"); |
spawn("/srv/obio"); |
console_wait(); |
version_print(); |
/branches/dynload/uspace/lib/libc/include/ddi.h |
---|
37,9 → 37,10 |
#include <task.h> |
extern int physmem_map(void *pf, void *vp, unsigned long pages, int flags); |
extern int iospace_enable(task_id_t id, void *ioaddr, unsigned long size); |
extern int preemption_control(int enable); |
extern int physmem_map(void *, void *, unsigned long, int); |
extern int iospace_enable(task_id_t, void *, unsigned long); |
extern int preemption_control(int); |
extern int pio_enable(void *, size_t, void **); |
#endif |
/branches/dynload/uspace/lib/libc/include/task.h |
---|
40,6 → 40,7 |
typedef uint64_t task_id_t; |
extern task_id_t task_get_id(void); |
extern int task_set_name(const char *name); |
extern task_id_t task_spawn(const char *path, char *const argv[]); |
#endif |
/branches/dynload/uspace/lib/libc/include/kbd/keycode.h |
---|
199,9 → 199,19 |
} keycode_t; |
enum keymod { |
KM_SHIFT = 0x01, |
KM_CTRL = 0x02, |
KM_ALT = 0x04 |
KM_LSHIFT = 0x001, |
KM_RSHIFT = 0x002, |
KM_LCTRL = 0x004, |
KM_RCTRL = 0x008, |
KM_LALT = 0x010, |
KM_RALT = 0x020, |
KM_CAPS_LOCK = 0x040, |
KM_NUM_LOCK = 0x080, |
KM_SCROLL_LOCK = 0x100, |
KM_SHIFT = KM_LSHIFT | KM_RSHIFT, |
KM_CTRL = KM_LCTRL | KM_RCTRL, |
KM_ALT = KM_LALT | KM_RALT |
} keymod_t; |
#endif |
/branches/dynload/uspace/lib/libc/include/ipc/bus.h |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcipc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_BUS_H_ |
#define LIBC_BUS_H_ |
#include <ipc/ipc.h> |
typedef enum { |
BUS_CLEAR_INTERRUPT = IPC_FIRST_USER_METHOD |
} bus_request_t; |
#endif |
/** @} |
*/ |
/branches/dynload/uspace/lib/libc/include/ipc/services.h |
---|
44,7 → 44,9 |
SERVICE_VIDEO, |
SERVICE_CONSOLE, |
SERVICE_VFS, |
SERVICE_DEVMAP |
SERVICE_DEVMAP, |
SERVICE_FHC, |
SERVICE_OBIO |
} services_t; |
/* Memory area to be received from NS */ |
/branches/dynload/uspace/lib/libc/generic/ddi.c |
---|
35,6 → 35,9 |
#include <ddi.h> |
#include <libc.h> |
#include <task.h> |
#include <as.h> |
#include <align.h> |
#include <libarch/config.h> |
#include <kernel/ddi/ddi_arg.h> |
/** Map piece of physical memory to task. |
42,17 → 45,19 |
* Caller of this function must have the CAP_MEM_MANAGER capability. |
* |
* @param pf Physical address of the starting frame. |
* @param vp Virtual address of the sterting page. |
* @param vp Virtual address of the starting page. |
* @param pages Number of pages to map. |
* @param flags Flags for the new address space area. |
* |
* @return 0 on success, EPERM if the caller lacks the CAP_MEM_MANAGER capability, |
* ENOENT if there is no task with specified ID and ENOMEM if there |
* was some problem in creating address space area. |
* @return 0 on success, EPERM if the caller lacks the |
* CAP_MEM_MANAGER capability, ENOENT if there is no task |
* with specified ID and ENOMEM if there was some problem |
* in creating address space area. |
*/ |
int physmem_map(void *pf, void *vp, unsigned long pages, int flags) |
{ |
return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) pf, (sysarg_t) vp, pages, flags); |
return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) pf, (sysarg_t) vp, pages, |
flags); |
} |
/** Enable I/O space range to task. |
63,9 → 68,10 |
* @param ioaddr Starting address of the I/O range. |
* @param size Size of the range. |
* |
* @return 0 on success, EPERM if the caller lacks the CAP_IO_MANAGER capability, |
* ENOENT if there is no task with specified ID and ENOMEM if there |
* was some problem in allocating memory. |
* @return 0 on success, EPERM if the caller lacks the |
* CAP_IO_MANAGER capability, ENOENT if there is no task |
* with specified ID and ENOMEM if there was some problem |
* in allocating memory. |
*/ |
int iospace_enable(task_id_t id, void *ioaddr, unsigned long size) |
{ |
87,5 → 93,36 |
return __SYSCALL1(SYS_PREEMPT_CONTROL, (sysarg_t) enable); |
} |
/** Enable PIO for specified I/O range. |
* |
* @param pio_addr I/O start address. |
* @param size Size of the I/O region. |
* @param use_addr Address where the final address for application's PIO |
* will be stored. |
* |
* @return Zero on success or negative error code. |
*/ |
int pio_enable(void *pio_addr, size_t size, void **use_addr) |
{ |
void *phys; |
void *virt; |
size_t offset; |
unsigned int pages; |
#ifdef IO_SPACE_BOUNDARY |
if (pio_addr < IO_SPACE_BOUNDARY) { |
*use_addr = pio_addr; |
return iospace_enable(task_get_id(), pio_addr, size); |
} |
#endif |
phys = ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE); |
offset = pio_addr - phys; |
pages = ALIGN_UP(offset + size, PAGE_SIZE) >> PAGE_WIDTH; |
virt = as_get_mappable_page(pages); |
*use_addr = virt + offset; |
return physmem_map(phys, virt, pages, AS_AREA_READ | AS_AREA_WRITE); |
} |
/** @} |
*/ |
/branches/dynload/uspace/lib/libc/generic/task.c |
---|
38,6 → 38,7 |
#include <stdlib.h> |
#include <errno.h> |
#include <loader/loader.h> |
#include <string.h> |
task_id_t task_get_id(void) |
{ |
48,6 → 49,17 |
return task_id; |
} |
/** Set the task name. |
* |
* @param name The new name, typically the command used to execute the |
* program. |
* @return Zero on success or negative error code. |
*/ |
int task_set_name(const char *name) |
{ |
return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, strlen(name)); |
} |
/** Create a new task by running an executable from the filesystem. |
* |
* This is really just a convenience wrapper over the more complicated |
/branches/dynload/uspace/lib/libc/arch/ia32/include/ddi.h |
---|
33,6 → 33,8 |
#ifndef LIBC_ia32_DDI_H_ |
#define LIBC_ia32_DDI_H_ |
#define IO_SPACE_BOUNDARY ((void *) (64 * 1024)) |
static inline void outb(int16_t port, uint8_t b) |
{ |
asm volatile ("outb %0, %1\n" :: "a" (b), "d" (port)); |
/branches/dynload/uspace/srv/kbd/ctl/pc.c |
---|
40,30 → 40,15 |
#include <kbd/keycode.h> |
#include <kbd_ctl.h> |
static int scanmap_simple[]; |
enum dec_state { |
ds_s, |
ds_e |
}; |
void kbd_ctl_parse_scancode(int scancode) |
{ |
kbd_ev_type_t type; |
unsigned int key; |
static enum dec_state ds = ds_s; |
if (scancode < 0 || scancode >= 0x100) |
return; |
static int scanmap_simple[] = { |
if (scancode & 0x80) { |
scancode &= ~0x80; |
type = KE_RELEASE; |
} else { |
type = KE_PRESS; |
} |
key = scanmap_simple[scancode]; |
if (key != 0) |
kbd_push_ev(type, key, 0); |
} |
static int scanmap_simple[128] = { |
[0x29] = KC_BACKTICK, |
[0x02] = KC_1, |
150,15 → 135,91 |
[0x57] = KC_F11, |
[0x58] = KC_F12, |
[0x1c] = KC_ENTER |
[0x46] = KC_SCROLL_LOCK, |
/* |
[0x1] = KC_PRNSCR, |
[0x1] = KC_SCROLL_LOCK, |
[0x1] = KC_PAUSE, |
*/ |
[0x1c] = KC_ENTER, |
[0x45] = KC_NUM_LOCK, |
[0x37] = KC_NTIMES, |
[0x4a] = KC_NMINUS, |
[0x4e] = KC_NPLUS, |
[0x47] = KC_N7, |
[0x48] = KC_N8, |
[0x49] = KC_N9, |
[0x4b] = KC_N4, |
[0x4c] = KC_N5, |
[0x4d] = KC_N6, |
[0x4f] = KC_N1, |
[0x50] = KC_N2, |
[0x51] = KC_N3, |
[0x52] = KC_N0, |
[0x53] = KC_NPERIOD |
}; |
static int scanmap_e0[] = { |
[0x38] = KC_RALT, |
[0x1d] = KC_RSHIFT, |
[0x37] = KC_PRTSCR, |
[0x52] = KC_INSERT, |
[0x47] = KC_HOME, |
[0x49] = KC_PAGE_UP, |
[0x53] = KC_DELETE, |
[0x4f] = KC_END, |
[0x51] = KC_PAGE_DOWN, |
[0x48] = KC_UP, |
[0x4b] = KC_LEFT, |
[0x50] = KC_DOWN, |
[0x4d] = KC_RIGHT, |
[0x35] = KC_NSLASH, |
[0x1c] = KC_NENTER |
}; |
void kbd_ctl_parse_scancode(int scancode) |
{ |
kbd_ev_type_t type; |
unsigned int key; |
int *map; |
size_t map_length; |
if (scancode == 0xe0) { |
ds = ds_e; |
return; |
} |
switch (ds) { |
case ds_s: |
map = scanmap_simple; |
map_length = sizeof(scanmap_simple) / sizeof(int); |
break; |
case ds_e: |
map = scanmap_e0; |
map_length = sizeof(scanmap_e0) / sizeof(int); |
break; |
} |
ds = ds_s; |
if (scancode & 0x80) { |
scancode &= ~0x80; |
type = KE_RELEASE; |
} else { |
type = KE_PRESS; |
} |
if (scancode < 0 || scancode >= map_length) |
return; |
key = map[scancode]; |
if (key != 0) |
kbd_push_ev(type, key); |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/kbd/ctl/stty.c |
---|
47,7 → 47,7 |
static void parse_ds_e2a(int scancode); |
static void parse_ds_e2b(int scancode); |
static void parse_leaf(int scancode, int *map, size_t map_length); |
static void parse_leaf(int scancode, int (*map)[2], size_t map_length); |
enum dec_state { |
ds_start, |
58,121 → 58,169 |
ds_e2b |
}; |
static int map_start[] = { |
static int map_start[][2] = { |
[0x60] = KC_BACKTICK, |
[0x60] = { 0, KC_BACKTICK }, |
[0x31] = KC_1, |
[0x32] = KC_2, |
[0x33] = KC_3, |
[0x34] = KC_4, |
[0x35] = KC_5, |
[0x36] = KC_6, |
[0x37] = KC_7, |
[0x38] = KC_8, |
[0x39] = KC_9, |
[0x30] = KC_0, |
[0x31] = { 0, KC_1 }, |
[0x32] = { 0, KC_2 }, |
[0x33] = { 0, KC_3 }, |
[0x34] = { 0, KC_4 }, |
[0x35] = { 0, KC_5 }, |
[0x36] = { 0, KC_6 }, |
[0x37] = { 0, KC_7 }, |
[0x38] = { 0, KC_8 }, |
[0x39] = { 0, KC_9 }, |
[0x30] = { 0, KC_0 }, |
[0x2d] = KC_MINUS, |
[0x3d] = KC_EQUALS, |
[0x08] = KC_BACKSPACE, |
[0x2d] = { 0, KC_MINUS }, |
[0x3d] = { 0, KC_EQUALS }, |
[0x08] = { 0, KC_BACKSPACE }, |
[0x0f] = KC_TAB, |
[0x0f] = { 0, KC_TAB }, |
[0x71] = KC_Q, |
[0x77] = KC_W, |
[0x65] = KC_E, |
[0x72] = KC_R, |
[0x74] = KC_T, |
[0x79] = KC_Y, |
[0x75] = KC_U, |
[0x69] = KC_I, |
[0x6f] = KC_O, |
[0x70] = KC_P, |
[0x71] = { 0, KC_Q }, |
[0x77] = { 0, KC_W }, |
[0x65] = { 0, KC_E }, |
[0x72] = { 0, KC_R }, |
[0x74] = { 0, KC_T }, |
[0x79] = { 0, KC_Y }, |
[0x75] = { 0, KC_U }, |
[0x69] = { 0, KC_I }, |
[0x6f] = { 0, KC_O }, |
[0x70] = { 0, KC_P }, |
[0x5b] = KC_LBRACKET, |
[0x5d] = KC_RBRACKET, |
[0x5b] = { 0, KC_LBRACKET }, |
[0x5d] = { 0, KC_RBRACKET }, |
// [0x3a] = KC_CAPS_LOCK, |
[0x61] = { 0, KC_A }, |
[0x73] = { 0, KC_S }, |
[0x64] = { 0, KC_D }, |
[0x66] = { 0, KC_F }, |
[0x67] = { 0, KC_G }, |
[0x68] = { 0, KC_H }, |
[0x6a] = { 0, KC_J }, |
[0x6b] = { 0, KC_K }, |
[0x6c] = { 0, KC_L }, |
[0x61] = KC_A, |
[0x73] = KC_S, |
[0x64] = KC_D, |
[0x66] = KC_F, |
[0x67] = KC_G, |
[0x68] = KC_H, |
[0x6a] = KC_J, |
[0x6b] = KC_K, |
[0x6c] = KC_L, |
[0x3b] = { 0, KC_SEMICOLON }, |
[0x27] = { 0, KC_QUOTE }, |
[0x5c] = { 0, KC_BACKSLASH }, |
[0x3b] = KC_SEMICOLON, |
[0x27] = KC_QUOTE, |
[0x5c] = KC_BACKSLASH, |
[0x7a] = { 0, KC_Z }, |
[0x78] = { 0, KC_X }, |
[0x63] = { 0, KC_C }, |
[0x76] = { 0, KC_V }, |
[0x62] = { 0, KC_B }, |
[0x6e] = { 0, KC_N }, |
[0x6d] = { 0, KC_M }, |
// [0x2a] = KC_LSHIFT, |
[0x2c] = { 0, KC_COMMA }, |
[0x2e] = { 0, KC_PERIOD }, |
[0x2f] = { 0, KC_SLASH }, |
[0x7a] = KC_Z, |
[0x78] = KC_X, |
[0x63] = KC_C, |
[0x76] = KC_V, |
[0x62] = KC_B, |
[0x6e] = KC_N, |
[0x6d] = KC_M, |
[0x20] = { 0, KC_SPACE }, |
[0x2c] = KC_COMMA, |
[0x2e] = KC_PERIOD, |
[0x2f] = KC_SLASH, |
[0x1b] = { 0, KC_ESCAPE }, |
// [0x36] = KC_RSHIFT, |
[0x0a] = { 0, KC_ENTER }, |
[0x0d] = { 0, KC_ENTER }, |
// [0x1d] = KC_LCTRL, |
// [0x38] = KC_LALT, |
[0x20] = KC_SPACE, |
/* with Shift pressed */ |
[0x1b] = KC_ESCAPE, |
[0x7e] = { KM_LSHIFT, KC_BACKTICK }, |
[0x0a] = KC_ENTER, |
[0x0d] = KC_ENTER |
[0x21] = { KM_LSHIFT, KC_1 }, |
[0x40] = { KM_LSHIFT, KC_2 }, |
[0x23] = { KM_LSHIFT, KC_3 }, |
[0x24] = { KM_LSHIFT, KC_4 }, |
[0x25] = { KM_LSHIFT, KC_5 }, |
[0x5e] = { KM_LSHIFT, KC_6 }, |
[0x26] = { KM_LSHIFT, KC_7 }, |
[0x2a] = { KM_LSHIFT, KC_8 }, |
[0x28] = { KM_LSHIFT, KC_9 }, |
[0x29] = { KM_LSHIFT, KC_0 }, |
/* |
[0x1] = KC_PRNSCR, |
[0x1] = KC_SCROLL_LOCK, |
[0x1] = KC_PAUSE, |
*/ |
[0x5f] = { KM_LSHIFT, KC_MINUS }, |
[0x2b] = { KM_LSHIFT, KC_EQUALS }, |
[0x51] = { KM_LSHIFT, KC_Q }, |
[0x57] = { KM_LSHIFT, KC_W }, |
[0x45] = { KM_LSHIFT, KC_E }, |
[0x52] = { KM_LSHIFT, KC_R }, |
[0x54] = { KM_LSHIFT, KC_T }, |
[0x59] = { KM_LSHIFT, KC_Y }, |
[0x55] = { KM_LSHIFT, KC_U }, |
[0x49] = { KM_LSHIFT, KC_I }, |
[0x4f] = { KM_LSHIFT, KC_O }, |
[0x50] = { KM_LSHIFT, KC_P }, |
[0x7b] = { KM_LSHIFT, KC_LBRACKET }, |
[0x7d] = { KM_LSHIFT, KC_RBRACKET }, |
[0x41] = { KM_LSHIFT, KC_A }, |
[0x53] = { KM_LSHIFT, KC_S }, |
[0x44] = { KM_LSHIFT, KC_D }, |
[0x46] = { KM_LSHIFT, KC_F }, |
[0x47] = { KM_LSHIFT, KC_G }, |
[0x48] = { KM_LSHIFT, KC_H }, |
[0x4a] = { KM_LSHIFT, KC_J }, |
[0x4b] = { KM_LSHIFT, KC_K }, |
[0x4c] = { KM_LSHIFT, KC_L }, |
[0x3a] = { KM_LSHIFT, KC_SEMICOLON }, |
[0x22] = { KM_LSHIFT, KC_QUOTE }, |
[0x7c] = { KM_LSHIFT, KC_BACKSLASH }, |
[0x5a] = { KM_LSHIFT, KC_Z }, |
[0x58] = { KM_LSHIFT, KC_X }, |
[0x43] = { KM_LSHIFT, KC_C }, |
[0x56] = { KM_LSHIFT, KC_V }, |
[0x42] = { KM_LSHIFT, KC_B }, |
[0x4e] = { KM_LSHIFT, KC_N }, |
[0x4d] = { KM_LSHIFT, KC_M }, |
[0x3c] = { KM_LSHIFT, KC_COMMA }, |
[0x3e] = { KM_LSHIFT, KC_PERIOD }, |
[0x3f] = { KM_LSHIFT, KC_SLASH } |
}; |
static int map_e1[] = |
static int map_e1[][2] = |
{ |
[0x50] = KC_F1, |
[0x51] = KC_F2, |
[0x52] = KC_F3, |
[0x53] = KC_F4, |
[0x50] = { 0, KC_F1 }, |
[0x51] = { 0, KC_F2 }, |
[0x52] = { 0, KC_F3 }, |
[0x53] = { 0, KC_F4 }, |
}; |
static int map_e2[] = |
static int map_e2[][2] = |
{ |
[0x41] = KC_UP, |
[0x42] = KC_DOWN, |
[0x44] = KC_LEFT, |
[0x43] = KC_RIGHT, |
[0x41] = { 0, KC_UP }, |
[0x42] = { 0, KC_DOWN }, |
[0x44] = { 0, KC_LEFT }, |
[0x43] = { 0, KC_RIGHT }, |
}; |
static int map_e2a[] = |
static int map_e2a[][2] = |
{ |
[0x35] = KC_F5, |
[0x37] = KC_F6, |
[0x38] = KC_F7, |
[0x39] = KC_F8, |
[0x35] = { 0, KC_F5 }, |
[0x37] = { 0, KC_F6 }, |
[0x38] = { 0, KC_F7 }, |
[0x39] = { 0, KC_F8 }, |
}; |
static int map_e2b[] = |
static int map_e2b[][2] = |
{ |
[0x30] = KC_F9, |
[0x31] = KC_F10, |
[0x32] = KC_F11, |
[0x33] = KC_F12, |
[0x30] = { 0, KC_F9 }, |
[0x31] = { 0, KC_F10 }, |
[0x32] = { 0, KC_F11 }, |
[0x33] = { 0, KC_F12 }, |
}; |
static unsigned int mods_keys[][2] = { |
{ KM_LSHIFT, KC_LSHIFT }, |
{ 0, 0 } |
}; |
static enum dec_state ds; |
190,15 → 238,12 |
static void parse_ds_start(int scancode) |
{ |
if (scancode < 0 || scancode >= sizeof(map_start) / sizeof(int)) |
return; |
if (scancode == 0x1b) { |
ds = ds_e; |
return; |
} |
parse_leaf(scancode, map_start, sizeof(map_start) / sizeof(int)); |
parse_leaf(scancode, map_start, sizeof(map_start) / (2 * sizeof(int))); |
} |
static void parse_ds_e(int scancode) |
212,12 → 257,12 |
default: ds = ds_start; return; |
} |
kbd_push_ev(KE_PRESS, KC_ESCAPE, 0); |
kbd_push_ev(KE_PRESS, KC_ESCAPE); |
} |
static void parse_ds_e1(int scancode) |
{ |
parse_leaf(scancode, map_e1, sizeof(map_e1) / sizeof(int)); |
parse_leaf(scancode, map_e1, sizeof(map_e1) / (2 * sizeof(int))); |
} |
static void parse_ds_e2(int scancode) |
228,22 → 273,23 |
default: ds = ds_start; break; |
} |
parse_leaf(scancode, map_e2, sizeof(map_e2) / sizeof(int)); |
parse_leaf(scancode, map_e2, sizeof(map_e2) / (2 * sizeof(int))); |
} |
static void parse_ds_e2a(int scancode) |
{ |
parse_leaf(scancode, map_e2a, sizeof(map_e2a) / sizeof(int)); |
parse_leaf(scancode, map_e2a, sizeof(map_e2a) / (2 * sizeof(int))); |
} |
static void parse_ds_e2b(int scancode) |
{ |
parse_leaf(scancode, map_e2b, sizeof(map_e2b) / sizeof(int)); |
parse_leaf(scancode, map_e2b, sizeof(map_e2b) / (2 * sizeof(int))); |
} |
static void parse_leaf(int scancode, int *map, size_t map_length) |
static void parse_leaf(int scancode, int (*map)[2], size_t map_length) |
{ |
unsigned int key; |
unsigned int key, mod; |
int i; |
ds = ds_start; |
250,12 → 296,34 |
if (scancode < 0 || scancode >= map_length) |
return; |
key = map[scancode]; |
if (key != 0) |
kbd_push_ev(KE_PRESS, key, 0); |
mod = map[scancode][0]; |
key = map[scancode][1]; |
/* Simulate modifier pressing. */ |
i = 0; |
while (mods_keys[i][0] != 0) { |
if (mod & mods_keys[i][0]) { |
kbd_push_ev(KE_PRESS, mods_keys[i][1]); |
} |
++i; |
} |
if (key != 0) { |
kbd_push_ev(KE_PRESS, key); |
kbd_push_ev(KE_RELEASE, key); |
} |
/* Simulate modifier releasing. */ |
i = 0; |
while (mods_keys[i][0] != 0) { |
if (mod & mods_keys[i][0]) { |
kbd_push_ev(KE_RELEASE, mods_keys[i][1]); |
} |
++i; |
} |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/kbd/ctl/sun.c |
---|
65,7 → 65,7 |
key = scanmap_simple[scancode]; |
if (key != 0) |
kbd_push_ev(type, key, 0); |
kbd_push_ev(type, key); |
} |
/** Primary meaning of scancodes. */ |
/branches/dynload/uspace/srv/kbd/ctl/gxe_fb.c |
---|
47,7 → 47,7 |
static void parse_ds_e1b(int scancode); |
static void parse_ds_e1c(int scancode); |
static void parse_leaf(int scancode, int *map, size_t map_length); |
static void parse_leaf(int scancode, int (*map)[2], size_t map_length); |
enum dec_state { |
ds_start, |
58,117 → 58,165 |
ds_e1c |
}; |
static int map_start[] = { |
static int map_start[][2] = { |
[0x60] = KC_BACKTICK, |
[0x60] = { 0, KC_BACKTICK }, |
[0x31] = KC_1, |
[0x32] = KC_2, |
[0x33] = KC_3, |
[0x34] = KC_4, |
[0x35] = KC_5, |
[0x36] = KC_6, |
[0x37] = KC_7, |
[0x38] = KC_8, |
[0x39] = KC_9, |
[0x30] = KC_0, |
[0x31] = { 0, KC_1 }, |
[0x32] = { 0, KC_2 }, |
[0x33] = { 0, KC_3 }, |
[0x34] = { 0, KC_4 }, |
[0x35] = { 0, KC_5 }, |
[0x36] = { 0, KC_6 }, |
[0x37] = { 0, KC_7 }, |
[0x38] = { 0, KC_8 }, |
[0x39] = { 0, KC_9 }, |
[0x30] = { 0, KC_0 }, |
[0x2d] = KC_MINUS, |
[0x3d] = KC_EQUALS, |
[0x08] = KC_BACKSPACE, |
[0x2d] = { 0, KC_MINUS }, |
[0x3d] = { 0, KC_EQUALS }, |
[0x08] = { 0, KC_BACKSPACE }, |
[0x0f] = KC_TAB, |
[0x0f] = { 0, KC_TAB }, |
[0x71] = KC_Q, |
[0x77] = KC_W, |
[0x65] = KC_E, |
[0x72] = KC_R, |
[0x74] = KC_T, |
[0x79] = KC_Y, |
[0x75] = KC_U, |
[0x69] = KC_I, |
[0x6f] = KC_O, |
[0x70] = KC_P, |
[0x71] = { 0, KC_Q }, |
[0x77] = { 0, KC_W }, |
[0x65] = { 0, KC_E }, |
[0x72] = { 0, KC_R }, |
[0x74] = { 0, KC_T }, |
[0x79] = { 0, KC_Y }, |
[0x75] = { 0, KC_U }, |
[0x69] = { 0, KC_I }, |
[0x6f] = { 0, KC_O }, |
[0x70] = { 0, KC_P }, |
[0x5b] = KC_LBRACKET, |
[0x5d] = KC_RBRACKET, |
[0x5b] = { 0, KC_LBRACKET }, |
[0x5d] = { 0, KC_RBRACKET }, |
// [0x3a] = KC_CAPS_LOCK, |
[0x61] = { 0, KC_A }, |
[0x73] = { 0, KC_S }, |
[0x64] = { 0, KC_D }, |
[0x66] = { 0, KC_F }, |
[0x67] = { 0, KC_G }, |
[0x68] = { 0, KC_H }, |
[0x6a] = { 0, KC_J }, |
[0x6b] = { 0, KC_K }, |
[0x6c] = { 0, KC_L }, |
[0x61] = KC_A, |
[0x73] = KC_S, |
[0x64] = KC_D, |
[0x66] = KC_F, |
[0x67] = KC_G, |
[0x68] = KC_H, |
[0x6a] = KC_J, |
[0x6b] = KC_K, |
[0x6c] = KC_L, |
[0x3b] = { 0, KC_SEMICOLON }, |
[0x27] = { 0, KC_QUOTE }, |
[0x5c] = { 0, KC_BACKSLASH }, |
[0x3b] = KC_SEMICOLON, |
[0x27] = KC_QUOTE, |
[0x5c] = KC_BACKSLASH, |
[0x7a] = { 0, KC_Z }, |
[0x78] = { 0, KC_X }, |
[0x63] = { 0, KC_C }, |
[0x76] = { 0, KC_V }, |
[0x62] = { 0, KC_B }, |
[0x6e] = { 0, KC_N }, |
[0x6d] = { 0, KC_M }, |
// [0x2a] = KC_LSHIFT, |
[0x2c] = { 0, KC_COMMA }, |
[0x2e] = { 0, KC_PERIOD }, |
[0x2f] = { 0, KC_SLASH }, |
[0x7a] = KC_Z, |
[0x78] = KC_X, |
[0x63] = KC_C, |
[0x76] = KC_V, |
[0x62] = KC_B, |
[0x6e] = KC_N, |
[0x6d] = KC_M, |
[0x20] = { 0, KC_SPACE }, |
[0x2c] = KC_COMMA, |
[0x2e] = KC_PERIOD, |
[0x2f] = KC_SLASH, |
[0x1b] = { 0, KC_ESCAPE }, |
// [0x36] = KC_RSHIFT, |
[0x0a] = { 0, KC_ENTER }, |
[0x0d] = { 0, KC_ENTER }, |
// [0x1d] = KC_LCTRL, |
// [0x38] = KC_LALT, |
[0x20] = KC_SPACE, |
/* with Shift pressed */ |
[0x1b] = KC_ESCAPE, |
[0x7e] = { KM_LSHIFT, KC_BACKTICK }, |
[0x0a] = KC_ENTER, |
[0x0d] = KC_ENTER |
[0x21] = { KM_LSHIFT, KC_1 }, |
[0x40] = { KM_LSHIFT, KC_2 }, |
[0x23] = { KM_LSHIFT, KC_3 }, |
[0x24] = { KM_LSHIFT, KC_4 }, |
[0x25] = { KM_LSHIFT, KC_5 }, |
[0x5e] = { KM_LSHIFT, KC_6 }, |
[0x26] = { KM_LSHIFT, KC_7 }, |
[0x2a] = { KM_LSHIFT, KC_8 }, |
[0x28] = { KM_LSHIFT, KC_9 }, |
[0x29] = { KM_LSHIFT, KC_0 }, |
/* |
[0x1] = KC_PRNSCR, |
[0x1] = KC_SCROLL_LOCK, |
[0x1] = KC_PAUSE, |
*/ |
[0x5f] = { KM_LSHIFT, KC_MINUS }, |
[0x2b] = { KM_LSHIFT, KC_EQUALS }, |
[0x51] = { KM_LSHIFT, KC_Q }, |
[0x57] = { KM_LSHIFT, KC_W }, |
[0x45] = { KM_LSHIFT, KC_E }, |
[0x52] = { KM_LSHIFT, KC_R }, |
[0x54] = { KM_LSHIFT, KC_T }, |
[0x59] = { KM_LSHIFT, KC_Y }, |
[0x55] = { KM_LSHIFT, KC_U }, |
[0x49] = { KM_LSHIFT, KC_I }, |
[0x4f] = { KM_LSHIFT, KC_O }, |
[0x50] = { KM_LSHIFT, KC_P }, |
[0x7b] = { KM_LSHIFT, KC_LBRACKET }, |
[0x7d] = { KM_LSHIFT, KC_RBRACKET }, |
[0x41] = { KM_LSHIFT, KC_A }, |
[0x53] = { KM_LSHIFT, KC_S }, |
[0x44] = { KM_LSHIFT, KC_D }, |
[0x46] = { KM_LSHIFT, KC_F }, |
[0x47] = { KM_LSHIFT, KC_G }, |
[0x48] = { KM_LSHIFT, KC_H }, |
[0x4a] = { KM_LSHIFT, KC_J }, |
[0x4b] = { KM_LSHIFT, KC_K }, |
[0x4c] = { KM_LSHIFT, KC_L }, |
[0x3a] = { KM_LSHIFT, KC_SEMICOLON }, |
[0x22] = { KM_LSHIFT, KC_QUOTE }, |
[0x7c] = { KM_LSHIFT, KC_BACKSLASH }, |
[0x5a] = { KM_LSHIFT, KC_Z }, |
[0x58] = { KM_LSHIFT, KC_X }, |
[0x43] = { KM_LSHIFT, KC_C }, |
[0x56] = { KM_LSHIFT, KC_V }, |
[0x42] = { KM_LSHIFT, KC_B }, |
[0x4e] = { KM_LSHIFT, KC_N }, |
[0x4d] = { KM_LSHIFT, KC_M }, |
[0x3c] = { KM_LSHIFT, KC_COMMA }, |
[0x3e] = { KM_LSHIFT, KC_PERIOD }, |
[0x3f] = { KM_LSHIFT, KC_SLASH } |
}; |
static int map_e1[] = |
static int map_e1[][2] = |
{ |
}; |
static int map_e1a[] = |
static int map_e1a[][2] = |
{ |
[0x50] = KC_F1, |
[0x51] = KC_F2, |
[0x52] = KC_F3, |
[0x53] = KC_F4, |
[0x50] = { 0, KC_F1 }, |
[0x51] = { 0, KC_F2 }, |
[0x52] = { 0, KC_F3 }, |
[0x53] = { 0, KC_F4 }, |
}; |
static int map_e1b[] = |
static int map_e1b[][2] = |
{ |
[0x33] = KC_F5, |
[0x37] = KC_F6, |
[0x38] = KC_F7, |
[0x39] = KC_F8, |
[0x33] = { 0, KC_F5 }, |
[0x37] = { 0, KC_F6 }, |
[0x38] = { 0, KC_F7 }, |
[0x39] = { 0, KC_F8 }, |
}; |
static int map_e1c[] = |
static int map_e1c[][2] = |
{ |
[0x38] = KC_F9, |
[0x39] = KC_F10, |
[0x33] = KC_F11, |
[0x34] = KC_F12, |
[0x38] = { 0, KC_F9 }, |
[0x39] = { 0, KC_F10 }, |
[0x33] = { 0, KC_F11 }, |
[0x34] = { 0, KC_F12 }, |
}; |
static unsigned int mods_keys[][2] = { |
{ KM_LSHIFT, KC_LSHIFT }, |
{ 0, 0 } |
}; |
static enum dec_state ds = ds_start; |
191,7 → 239,7 |
return; |
} |
parse_leaf(scancode, map_start, sizeof(map_start) / sizeof(int)); |
parse_leaf(scancode, map_start, sizeof(map_start) / (2 * sizeof(int))); |
} |
static void parse_ds_e(int scancode) |
202,7 → 250,7 |
default: ds = ds_start; return; |
} |
kbd_push_ev(KE_PRESS, KC_ESCAPE, 0); |
kbd_push_ev(KE_PRESS, KC_ESCAPE); |
} |
static void parse_ds_e1(int scancode) |
214,27 → 262,28 |
default: ds = ds_start; break; |
} |
parse_leaf(scancode, map_e1, sizeof(map_e1) / sizeof(int)); |
parse_leaf(scancode, map_e1, sizeof(map_e1) / (2 * sizeof(int))); |
} |
static void parse_ds_e1a(int scancode) |
{ |
parse_leaf(scancode, map_e1a, sizeof(map_e1a) / sizeof(int)); |
parse_leaf(scancode, map_e1a, sizeof(map_e1a) / (2 * sizeof(int))); |
} |
static void parse_ds_e1b(int scancode) |
{ |
parse_leaf(scancode, map_e1b, sizeof(map_e1b) / sizeof(int)); |
parse_leaf(scancode, map_e1b, sizeof(map_e1b) / (2 * sizeof(int))); |
} |
static void parse_ds_e1c(int scancode) |
{ |
parse_leaf(scancode, map_e1c, sizeof(map_e1c) / sizeof(int)); |
parse_leaf(scancode, map_e1c, sizeof(map_e1c) / (2 * sizeof(int))); |
} |
static void parse_leaf(int scancode, int *map, size_t map_length) |
static void parse_leaf(int scancode, int (*map)[2], size_t map_length) |
{ |
unsigned int key; |
unsigned int key, mod; |
int i; |
ds = ds_start; |
241,12 → 290,33 |
if (scancode < 0 || scancode >= map_length) |
return; |
key = map[scancode]; |
if (key != 0) |
kbd_push_ev(KE_PRESS, key, 0); |
mod = map[scancode][0]; |
key = map[scancode][1]; |
/* Simulate modifier pressing. */ |
i = 0; |
while (mods_keys[i][0] != 0) { |
if (mod & mods_keys[i][0]) { |
kbd_push_ev(KE_PRESS, mods_keys[i][1]); |
} |
++i; |
} |
if (key != 0) { |
kbd_push_ev(KE_PRESS, key); |
kbd_push_ev(KE_RELEASE, key); |
} |
/* Simulate modifier releasing. */ |
i = 0; |
while (mods_keys[i][0] != 0) { |
if (mod & mods_keys[i][0]) { |
kbd_push_ev(KE_RELEASE, mods_keys[i][1]); |
} |
++i; |
} |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/kbd/include/kbd.h |
---|
45,8 → 45,11 |
#define KBD_MS_MIDDLE 1027 |
#define KBD_MS_MOVE 1028 |
extern int cir_service; |
extern int cir_phone; |
extern void kbd_push_scancode(int); |
extern void kbd_push_ev(int, unsigned int, unsigned int); |
extern void kbd_push_ev(int, unsigned int); |
#endif |
/branches/dynload/uspace/srv/kbd/port/gxemul.c |
---|
42,15 → 42,17 |
static irq_cmd_t gxemul_cmds[] = { |
{ |
CMD_MEM_READ_1, |
(void *) 0, |
0, |
2 |
.cmd = CMD_PIO_READ_8, |
.addr = (void *) 0, /* will be patched in run-time */ |
.dstarg = 2, |
}, |
{ |
.cmd = CMD_ACCEPT |
} |
}; |
static irq_code_t gxemul_kbd = { |
1, |
sizeof(gxemul_cmds) / sizeof(irq_cmd_t), |
gxemul_cmds |
}; |
/branches/dynload/uspace/srv/kbd/port/ns16550.c |
---|
50,12 → 50,37 |
#define MCR_REG 4 /** Modem Control Register. */ |
#define LSR_REG 5 /** Line Status Register. */ |
irq_cmd_t ns16550_cmds[1] = { |
{ CMD_PORT_READ_1, 0, 0, 2 }, |
#define LSR_DATA_READY 0x01 |
static irq_cmd_t ns16550_cmds[] = { |
{ |
.cmd = CMD_PIO_READ_8, |
.addr = (void *) 0, /* will be patched in run-time */ |
.dstarg = 1 |
}, |
{ |
.cmd = CMD_BTEST, |
.value = LSR_DATA_READY, |
.srcarg = 1, |
.dstarg = 3 |
}, |
{ |
.cmd = CMD_PREDICATE, |
.value = 2, |
.srcarg = 3 |
}, |
{ |
.cmd = CMD_PIO_READ_8, |
.addr = (void *) 0, /* will be patched in run-time */ |
.dstarg = 2 |
}, |
{ |
.cmd = CMD_ACCEPT |
} |
}; |
irq_code_t ns16550_kbd = { |
1, |
sizeof(ns16550_cmds) / sizeof(irq_cmd_t), |
ns16550_cmds |
}; |
68,7 → 93,8 |
async_set_interrupt_received(ns16550_irq_handler); |
ns16550_port = sysinfo_value("kbd.port"); |
ns16550_kbd.cmds[0].addr = (void *) (ns16550_port + RBR_REG); |
ns16550_kbd.cmds[0].addr = (void *) (ns16550_port + LSR_REG); |
ns16550_kbd.cmds[3].addr = (void *) (ns16550_port + RBR_REG); |
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), |
0, &ns16550_kbd); |
iospace_enable(task_get_id(), ns16550_port, 8); |
76,8 → 102,6 |
return 0; |
} |
#define LSR_DATA_READY 0x01 |
static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call) |
{ |
int scan_code = IPC_GET_ARG2(*call); |
/branches/dynload/uspace/srv/kbd/port/msim.c |
---|
40,12 → 40,20 |
#include <kbd_port.h> |
#include <kbd.h> |
irq_cmd_t msim_cmds[1] = { |
{ CMD_MEM_READ_1, (void *) 0, 0, 2 } |
irq_cmd_t msim_cmds[] = { |
{ |
.cmd = CMD_PIO_READ_8, |
.addr = (void *) 0, /* will be patched in run-time */ |
.dstarg = 2 |
}, |
{ |
.cmd = CMD_ACCEPT |
} |
}; |
irq_code_t msim_kbd = { |
1, |
sizeof(msim_cmds) / sizeof(irq_cmd_t), |
msim_cmds |
}; |
/branches/dynload/uspace/srv/kbd/port/i8042.c |
---|
63,13 → 63,35 |
#define MOUSE_OUT_INIT 0xf4 |
#define MOUSE_ACK 0xfa |
static irq_cmd_t i8042_cmds[2] = { |
{ CMD_PORT_READ_1, (void *) 0x64, 0, 1 }, |
{ CMD_PORT_READ_1, (void *) 0x60, 0, 2 } |
static irq_cmd_t i8042_cmds[] = { |
{ |
.cmd = CMD_PIO_READ_8, |
.addr = (void *) 0x64, |
.dstarg = 1 |
}, |
{ |
.cmd = CMD_BTEST, |
.value = i8042_OUTPUT_FULL, |
.srcarg = 1, |
.dstarg = 3 |
}, |
{ |
.cmd = CMD_PREDICATE, |
.value = 2, |
.srcarg = 3 |
}, |
{ |
.cmd = CMD_PIO_READ_8, |
.addr = (void *) 0x60, |
.dstarg = 2 |
}, |
{ |
.cmd = CMD_ACCEPT |
} |
}; |
static irq_code_t i8042_kbd = { |
2, |
sizeof(i8042_cmds) / sizeof(irq_cmd_t), |
i8042_cmds |
}; |
/branches/dynload/uspace/srv/kbd/port/z8530.c |
---|
35,6 → 35,7 |
*/ |
#include <ipc/ipc.h> |
#include <ipc/bus.h> |
#include <async.h> |
#include <sysinfo.h> |
#include <kbd.h> |
41,19 → 42,40 |
#include <kbd_port.h> |
#include <sys/types.h> |
/** Top-half pseudocode for z8530. */ |
irq_cmd_t z8530_cmds[] = { |
#define CHAN_A_STATUS 4 |
#define CHAN_A_DATA 6 |
#define RR0_RCA 1 |
static irq_cmd_t z8530_cmds[] = { |
{ |
CMD_MEM_READ_1, |
0, /**< Address. Will be patched in run-time. */ |
0, /**< Value. Not used. */ |
1 /**< Arg 1 will contain the result. */ |
.cmd = CMD_PIO_READ_8, |
.addr = (void *) 0, /* will be patched in run-time */ |
.dstarg = 1 |
}, |
{ |
.cmd = CMD_BTEST, |
.value = RR0_RCA, |
.srcarg = 1, |
.dstarg = 3 |
}, |
{ |
.cmd = CMD_PREDICATE, |
.value = 2, |
.srcarg = 3 |
}, |
{ |
.cmd = CMD_PIO_READ_8, |
.addr = (void *) 0, /* will be patched in run-time */ |
.dstarg = 2 |
}, |
{ |
.cmd = CMD_ACCEPT |
} |
}; |
irq_code_t z8530_kbd = { |
1, |
sizeof(z8530_cmds) / sizeof(irq_cmd_t), |
z8530_cmds |
}; |
62,16 → 84,23 |
int kbd_port_init(void) |
{ |
async_set_interrupt_received(z8530_irq_handler); |
z8530_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual") + 6; |
z8530_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual") + |
CHAN_A_STATUS; |
z8530_cmds[3].addr = (void *) sysinfo_value("kbd.address.virtual") + |
CHAN_A_DATA; |
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), |
0, &z8530_kbd); |
sysinfo_value("kbd.inr"), &z8530_kbd); |
return 0; |
} |
static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call) |
{ |
int scan_code = IPC_GET_ARG1(*call); |
int scan_code = IPC_GET_ARG2(*call); |
kbd_push_scancode(scan_code); |
if (cir_service) |
async_msg_1(cir_phone, BUS_CLEAR_INTERRUPT, |
IPC_GET_METHOD(*call)); |
} |
/** @} |
/branches/dynload/uspace/srv/kbd/generic/kbd.c |
---|
37,6 → 37,7 |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <sysinfo.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <stdlib.h> |
46,6 → 47,7 |
#include <errno.h> |
#include <libadt/fifo.h> |
#include <kbd/kbd.h> |
#include <kbd/keycode.h> |
#include <kbd.h> |
#include <key_buffer.h> |
59,21 → 61,68 |
int phone2cons = -1; |
keybuffer_t keybuffer; |
/** Currently active modifiers. */ |
static unsigned mods = KM_NUM_LOCK; |
/** Currently pressed lock keys. We track these to tackle autorepeat. */ |
static unsigned lock_keys; |
int cir_service = 0; |
int cir_phone = -1; |
void kbd_push_scancode(int scancode) |
{ |
printf("scancode: 0x%x\n", scancode); |
/* printf("scancode: 0x%x\n", scancode);*/ |
kbd_ctl_parse_scancode(scancode); |
} |
#include <kbd/keycode.h> |
void kbd_push_ev(int type, unsigned int key, unsigned int mods) |
void kbd_push_ev(int type, unsigned int key) |
{ |
kbd_event_t ev; |
unsigned mod_mask; |
switch (key) { |
case KC_LCTRL: mod_mask = KM_LCTRL; break; |
case KC_RCTRL: mod_mask = KM_RCTRL; break; |
case KC_LSHIFT: mod_mask = KM_LSHIFT; break; |
case KC_RSHIFT: mod_mask = KM_RSHIFT; break; |
case KC_LALT: mod_mask = KM_LALT; break; |
case KC_RALT: mod_mask = KM_RALT; break; |
default: mod_mask = 0; break; |
} |
if (mod_mask != 0) { |
if (type == KE_PRESS) |
mods = mods | mod_mask; |
else |
mods = mods & ~mod_mask; |
} |
switch (key) { |
case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break; |
case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break; |
case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break; |
default: mod_mask = 0; break; |
} |
if (mod_mask != 0) { |
if (type == KE_PRESS) { |
/* |
* Only change lock state on transition from released |
* to pressed. This prevents autorepeat from messing |
* up the lock state. |
*/ |
mods = mods ^ (mod_mask & ~lock_keys); |
lock_keys = lock_keys | mod_mask; |
} else { |
lock_keys = lock_keys & ~mod_mask; |
} |
} |
/* |
printf("type: %d\n", type); |
printf("mods: 0x%x\n", mods); |
printf("keycode: %u\n", key); |
*/ |
ev.type = type; |
ev.key = key; |
ev.mods = mods; |
83,27 → 132,6 |
async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c); |
} |
//static void irq_handler(ipc_callid_t iid, ipc_call_t *call) |
//{ |
// kbd_event_t ev; |
// |
// kbd_arch_process(&keybuffer, call); |
// |
// if (cons_connected && phone2cons != -1) { |
// /* |
// * One interrupt can produce more than one event so the result |
// * is stored in a FIFO. |
// */ |
// while (!keybuffer_empty(&keybuffer)) { |
// if (!keybuffer_pop(&keybuffer, &ev)) |
// break; |
// |
// async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key, |
// ev.mods, ev.c); |
// } |
// } |
//} |
static void console_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
ipc_callid_t callid; |
142,7 → 170,6 |
} |
int main(int argc, char **argv) |
{ |
printf(NAME ": HelenOS Keyboard service\n"); |
149,6 → 176,18 |
ipcarg_t phonead; |
if (sysinfo_value("kbd.cir.fhc") == 1) |
cir_service = SERVICE_FHC; |
else if (sysinfo_value("kbd.cir.obio") == 1) |
cir_service = SERVICE_OBIO; |
if (cir_service) { |
while (cir_phone < 0) { |
cir_phone = ipc_connect_me_to(PHONE_NS, cir_service, |
0, 0); |
} |
} |
/* Initialize port driver. */ |
if (kbd_port_init()) |
return -1; |
/branches/dynload/uspace/srv/kbd/Makefile |
---|
79,8 → 79,8 |
endif |
ifeq ($(UARCH), ia64) |
GENARCH_SOURCES += \ |
port/dummy.c \ |
ctl/stty.c |
port/i8042.c \ |
ctl/pc.c |
endif |
ifeq ($(MACHINE), msim) |
GENARCH_SOURCES += \ |
/branches/dynload/uspace/srv/kbd/layout/us_qwerty.c |
---|
36,26 → 36,7 |
#include <kbd/keycode.h> |
#include <layout.h> |
static int map_normal[] = { |
[KC_BACKTICK] = '`', |
[KC_1] = '1', |
[KC_2] = '2', |
[KC_3] = '3', |
[KC_4] = '4', |
[KC_5] = '5', |
[KC_6] = '6', |
[KC_7] = '7', |
[KC_8] = '8', |
[KC_9] = '9', |
[KC_0] = '0', |
[KC_MINUS] = '-', |
[KC_EQUALS] = '=', |
[KC_BACKSPACE] = '\b', |
[KC_TAB] = '\t', |
static char map_lcase[] = { |
[KC_Q] = 'q', |
[KC_W] = 'w', |
[KC_E] = 'e', |
67,9 → 48,6 |
[KC_O] = 'o', |
[KC_P] = 'p', |
[KC_LBRACKET] = '[', |
[KC_RBRACKET] = ']', |
[KC_A] = 'a', |
[KC_S] = 's', |
[KC_D] = 'd', |
80,11 → 58,6 |
[KC_K] = 'k', |
[KC_L] = 'l', |
[KC_SEMICOLON] = ';', |
[KC_QUOTE] = '\'', |
[KC_BACKSLASH] = '\\', |
[KC_ENTER] = '\n', |
[KC_Z] = 'z', |
[KC_X] = 'x', |
[KC_C] = 'c', |
92,20 → 65,162 |
[KC_B] = 'b', |
[KC_N] = 'n', |
[KC_M] = 'm', |
}; |
static char map_ucase[] = { |
[KC_Q] = 'Q', |
[KC_W] = 'W', |
[KC_E] = 'E', |
[KC_R] = 'R', |
[KC_T] = 'T', |
[KC_Y] = 'Y', |
[KC_U] = 'U', |
[KC_I] = 'I', |
[KC_O] = 'O', |
[KC_P] = 'P', |
[KC_A] = 'A', |
[KC_S] = 'S', |
[KC_D] = 'D', |
[KC_F] = 'F', |
[KC_G] = 'G', |
[KC_H] = 'H', |
[KC_J] = 'J', |
[KC_K] = 'K', |
[KC_L] = 'L', |
[KC_Z] = 'Z', |
[KC_X] = 'X', |
[KC_C] = 'C', |
[KC_V] = 'V', |
[KC_B] = 'B', |
[KC_N] = 'N', |
[KC_M] = 'M', |
}; |
static char map_not_shifted[] = { |
[KC_BACKTICK] = '`', |
[KC_1] = '1', |
[KC_2] = '2', |
[KC_3] = '3', |
[KC_4] = '4', |
[KC_5] = '5', |
[KC_6] = '6', |
[KC_7] = '7', |
[KC_8] = '8', |
[KC_9] = '9', |
[KC_0] = '0', |
[KC_MINUS] = '-', |
[KC_EQUALS] = '=', |
[KC_LBRACKET] = '[', |
[KC_RBRACKET] = ']', |
[KC_SEMICOLON] = ';', |
[KC_QUOTE] = '\'', |
[KC_BACKSLASH] = '\\', |
[KC_COMMA] = ',', |
[KC_PERIOD] = '.', |
[KC_SLASH] = '/', |
}; |
[KC_SPACE] = ' ' |
static char map_shifted[] = { |
[KC_BACKTICK] = '~', |
[KC_1] = '!', |
[KC_2] = '@', |
[KC_3] = '#', |
[KC_4] = '$', |
[KC_5] = '%', |
[KC_6] = '^', |
[KC_7] = '&', |
[KC_8] = '*', |
[KC_9] = '(', |
[KC_0] = ')', |
[KC_MINUS] = '_', |
[KC_EQUALS] = '+', |
[KC_LBRACKET] = '{', |
[KC_RBRACKET] = '}', |
[KC_SEMICOLON] = ':', |
[KC_QUOTE] = '"', |
[KC_BACKSLASH] = '|', |
[KC_COMMA] = '<', |
[KC_PERIOD] = '>', |
[KC_SLASH] = '?', |
}; |
static char map_neutral[] = { |
[KC_BACKSPACE] = '\b', |
[KC_TAB] = '\t', |
[KC_ENTER] = '\n', |
[KC_SPACE] = ' ', |
[KC_NSLASH] = '/', |
[KC_NTIMES] = '*', |
[KC_NMINUS] = '-', |
[KC_NPLUS] = '+', |
[KC_NENTER] = '\n' |
}; |
static char map_numeric[] = { |
[KC_N7] = '7', |
[KC_N8] = '8', |
[KC_N9] = '9', |
[KC_N4] = '4', |
[KC_N5] = '5', |
[KC_N6] = '6', |
[KC_N1] = '1', |
[KC_N2] = '2', |
[KC_N3] = '3', |
[KC_N0] = '0', |
[KC_NPERIOD] = '.' |
}; |
static int translate(unsigned int key, char *map, size_t map_length) |
{ |
if (key >= map_length) return 0; |
return map[key]; |
} |
char layout_parse_ev(kbd_event_t *ev) |
{ |
if (ev->key >= sizeof(map_normal) / sizeof(int)) |
char c; |
/* Produce no characters when Ctrl or Alt is pressed. */ |
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0) |
return 0; |
return map_normal[ev->key]; |
c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char)); |
if (c != 0) return c; |
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0)) |
c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char)); |
else |
c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char)); |
if (c != 0) return c; |
if ((ev->mods & KM_SHIFT) != 0) |
c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char)); |
else |
c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char)); |
if (c != 0) return c; |
if ((ev->mods & KM_NUM_LOCK) != 0) |
c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char)); |
else |
c = 0; |
return c; |
} |
/** |
/branches/dynload/uspace/srv/kbd/layout/us_dvorak.c |
---|
36,29 → 36,7 |
#include <kbd/keycode.h> |
#include <layout.h> |
static int map_normal[] = { |
[KC_BACKTICK] = '`', |
[KC_1] = '1', |
[KC_2] = '2', |
[KC_3] = '3', |
[KC_4] = '4', |
[KC_5] = '5', |
[KC_6] = '6', |
[KC_7] = '7', |
[KC_8] = '8', |
[KC_9] = '9', |
[KC_0] = '0', |
[KC_MINUS] = '[', |
[KC_EQUALS] = ']', |
[KC_BACKSPACE] = '\b', |
[KC_TAB] = '\t', |
[KC_Q] = '\'', |
[KC_W] = ',', |
[KC_E] = '.', |
static char map_lcase[] = { |
[KC_R] = 'p', |
[KC_T] = 'y', |
[KC_Y] = 'f', |
67,9 → 45,6 |
[KC_O] = 'r', |
[KC_P] = 'l', |
[KC_LBRACKET] = '/', |
[KC_RBRACKET] = '=', |
[KC_A] = 'a', |
[KC_S] = 'o', |
[KC_D] = 'e', |
81,10 → 56,7 |
[KC_L] = 'n', |
[KC_SEMICOLON] = 's', |
[KC_QUOTE] = '-', |
[KC_BACKSLASH] = '\\', |
[KC_Z] = ';', |
[KC_X] = 'q', |
[KC_C] = 'j', |
[KC_V] = 'k', |
95,18 → 67,141 |
[KC_COMMA] = 'w', |
[KC_PERIOD] = 'v', |
[KC_SLASH] = 'z', |
}; |
static char map_ucase[] = { |
[KC_R] = 'P', |
[KC_T] = 'Y', |
[KC_Y] = 'F', |
[KC_U] = 'G', |
[KC_I] = 'C', |
[KC_O] = 'R', |
[KC_P] = 'L', |
[KC_A] = 'A', |
[KC_S] = 'O', |
[KC_D] = 'E', |
[KC_F] = 'U', |
[KC_G] = 'I', |
[KC_H] = 'D', |
[KC_J] = 'H', |
[KC_K] = 'T', |
[KC_L] = 'N', |
[KC_SEMICOLON] = 'S', |
[KC_X] = 'Q', |
[KC_C] = 'J', |
[KC_V] = 'K', |
[KC_B] = 'X', |
[KC_N] = 'B', |
[KC_M] = 'M', |
[KC_COMMA] = 'W', |
[KC_PERIOD] = 'V', |
[KC_SLASH] = 'Z', |
}; |
static char map_not_shifted[] = { |
[KC_BACKTICK] = '`', |
[KC_1] = '1', |
[KC_2] = '2', |
[KC_3] = '3', |
[KC_4] = '4', |
[KC_5] = '5', |
[KC_6] = '6', |
[KC_7] = '7', |
[KC_8] = '8', |
[KC_9] = '9', |
[KC_0] = '0', |
[KC_MINUS] = '[', |
[KC_EQUALS] = ']', |
[KC_Q] = '\'', |
[KC_W] = ',', |
[KC_E] = '.', |
[KC_LBRACKET] = '/', |
[KC_RBRACKET] = '=', |
[KC_QUOTE] = '-', |
[KC_BACKSLASH] = '\\', |
[KC_Z] = ';', |
}; |
static char map_shifted[] = { |
[KC_BACKTICK] = '~', |
[KC_1] = '!', |
[KC_2] = '@', |
[KC_3] = '#', |
[KC_4] = '$', |
[KC_5] = '%', |
[KC_6] = '^', |
[KC_7] = '&', |
[KC_8] = '*', |
[KC_9] = '(', |
[KC_0] = ')', |
[KC_MINUS] = '{', |
[KC_EQUALS] = '}', |
[KC_Q] = '"', |
[KC_W] = '<', |
[KC_E] = '>', |
[KC_LBRACKET] = '?', |
[KC_RBRACKET] = '+', |
[KC_QUOTE] = '_', |
[KC_BACKSLASH] = '|', |
[KC_Z] = ':', |
}; |
static char map_neutral[] = { |
[KC_BACKSPACE] = '\b', |
[KC_TAB] = '\t', |
[KC_ENTER] = '\n' |
}; |
static int translate(unsigned int key, char *map, size_t map_length) |
{ |
if (key >= map_length) return 0; |
return map[key]; |
} |
char layout_parse_ev(kbd_event_t *ev) |
{ |
if (ev->key >= sizeof(map_normal) / sizeof(int)) |
char c; |
/* Produce no characters when Ctrl or Alt is pressed. */ |
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0) |
return 0; |
return map_normal[ev->key]; |
c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char)); |
if (c != 0) return c; |
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0)) |
c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char)); |
else |
c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char)); |
if (c != 0) return c; |
if ((ev->mods & KM_SHIFT) != 0) |
c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char)); |
else |
c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char)); |
if (c != 0 ) return c; |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fhc/fhc.c |
---|
0,0 → 1,157 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup fhc |
* @{ |
*/ |
/** |
* @file fhc.c |
* @brief FHC bus controller driver. |
*/ |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <ipc/bus.h> |
#include <ipc/ns.h> |
#include <sysinfo.h> |
#include <as.h> |
#include <ddi.h> |
#include <align.h> |
#include <bool.h> |
#include <errno.h> |
#include <async.h> |
#include <align.h> |
#include <async.h> |
#include <stdio.h> |
#include <ipc/devmap.h> |
#define NAME "fhc" |
#define FHC_UART_INR 0x39 |
#define FHC_UART_IMAP 0x0 |
#define FHC_UART_ICLR 0x4 |
static void *fhc_uart_phys; |
static volatile uint32_t *fhc_uart_virt; |
static size_t fhc_uart_size; |
/** Handle one connection to fhc. |
* |
* @param iid Hash of the request that opened the connection. |
* @param icall Call data of the request that opened the connection. |
*/ |
static void fhc_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
/* |
* Answer the first IPC_M_CONNECT_ME_TO call. |
*/ |
ipc_answer_0(iid, EOK); |
while (1) { |
int inr; |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case BUS_CLEAR_INTERRUPT: |
inr = IPC_GET_ARG1(call); |
switch (inr) { |
case FHC_UART_INR: |
fhc_uart_virt[FHC_UART_ICLR] = 0; |
ipc_answer_0(callid, EOK); |
break; |
default: |
ipc_answer_0(callid, ENOTSUP); |
break; |
} |
break; |
default: |
ipc_answer_0(callid, EINVAL); |
break; |
} |
} |
} |
/** Initialize the FHC driver. |
* |
* So far, the driver heavily depends on information provided by the kernel via |
* sysinfo. In the future, there should be a standalone FHC driver. |
*/ |
static bool fhc_init(void) |
{ |
ipcarg_t phonead; |
fhc_uart_size = sysinfo_value("fhc.uart.size"); |
fhc_uart_phys = (void *) sysinfo_value("fhc.uart.physical"); |
if (!fhc_uart_size) { |
printf(NAME ": no FHC UART registers found\n"); |
return false; |
} |
fhc_uart_virt = as_get_mappable_page(fhc_uart_size); |
int flags = AS_AREA_READ | AS_AREA_WRITE; |
int retval = physmem_map(fhc_uart_phys, (void *) fhc_uart_virt, |
ALIGN_UP(fhc_uart_size, PAGE_SIZE) >> PAGE_WIDTH, flags); |
if (retval < 0) { |
printf(NAME ": Error mapping FHC UART registers\n"); |
return false; |
} |
printf(NAME ": FHC UART registers at %p, %d bytes\n", fhc_uart_phys, |
fhc_uart_size); |
async_set_client_connection(fhc_connection); |
ipc_connect_to_me(PHONE_NS, SERVICE_FHC, 0, 0, &phonead); |
return true; |
} |
int main(int argc, char **argv) |
{ |
printf(NAME ": HelenOS FHC bus controller driver\n"); |
if (!fhc_init()) |
return -1; |
printf(NAME ": Accepting connections\n"); |
async_manager(); |
/* Never reached */ |
return 0; |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fhc/Makefile |
---|
0,0 → 1,76 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Setup toolchain |
# |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
## Sources |
# |
OUTPUT = fhc |
SOURCES = \ |
fhc.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/branches/dynload/uspace/srv/loader/main.c |
---|
278,6 → 278,9 |
*/ |
static void loader_run(ipc_callid_t rid, ipc_call_t *request) |
{ |
/* Set the task name. */ |
task_set_name(pathname); |
if (is_dyn_linked == true) { |
/* Dynamically linked program */ |
DPRINTF("Run ELF interpreter.\n"); |
/branches/dynload/uspace/srv/obio/obio.c |
---|
0,0 → 1,158 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup obio |
* @{ |
*/ |
/** |
* @file obio.c |
* @brief OBIO driver. |
* |
* OBIO is a short for on-board I/O. On UltraSPARC IIi and systems with U2P, |
* there is a piece of the root PCI bus controller address space, which |
* contains interrupt mapping and clear registers for all on-board devices. |
* Although UltraSPARC IIi and U2P are different in general, these registers can |
* be found at the same addresses. |
*/ |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <ipc/bus.h> |
#include <ipc/ns.h> |
#include <sysinfo.h> |
#include <as.h> |
#include <ddi.h> |
#include <align.h> |
#include <bool.h> |
#include <errno.h> |
#include <async.h> |
#include <align.h> |
#include <async.h> |
#include <stdio.h> |
#include <ipc/devmap.h> |
#define NAME "obio" |
#define OBIO_SIZE 0x1898 |
#define OBIO_IMR_BASE 0x200 |
#define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK)) |
#define OBIO_CIR_BASE 0x300 |
#define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK)) |
#define INO_MASK 0x1f |
static void *base_phys; |
static volatile uint64_t *base_virt; |
/** Handle one connection to obio. |
* |
* @param iid Hash of the request that opened the connection. |
* @param icall Call data of the request that opened the connection. |
*/ |
static void obio_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
/* |
* Answer the first IPC_M_CONNECT_ME_TO call. |
*/ |
ipc_answer_0(iid, EOK); |
while (1) { |
int inr; |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case BUS_CLEAR_INTERRUPT: |
inr = IPC_GET_ARG1(call); |
base_virt[OBIO_CIR(inr) & INO_MASK] = 0; |
ipc_answer_0(callid, EOK); |
break; |
default: |
ipc_answer_0(callid, EINVAL); |
break; |
} |
} |
} |
/** Initialize the OBIO driver. |
* |
* So far, the driver heavily depends on information provided by the kernel via |
* sysinfo. In the future, there should be a standalone OBIO driver. |
*/ |
static bool obio_init(void) |
{ |
ipcarg_t phonead; |
base_phys = (void *) sysinfo_value("obio.base.physical"); |
if (!base_phys) { |
printf(NAME ": no OBIO registers found\n"); |
return false; |
} |
base_virt = as_get_mappable_page(OBIO_SIZE); |
int flags = AS_AREA_READ | AS_AREA_WRITE; |
int retval = physmem_map(base_phys, (void *) base_virt, |
ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags); |
if (retval < 0) { |
printf(NAME ": Error mapping OBIO registers\n"); |
return false; |
} |
printf(NAME ": OBIO registers with base at %p\n", base_phys); |
async_set_client_connection(obio_connection); |
ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, &phonead); |
return true; |
} |
int main(int argc, char **argv) |
{ |
printf(NAME ": HelenOS OBIO driver\n"); |
if (!obio_init()) |
return -1; |
printf(NAME ": Accepting connections\n"); |
async_manager(); |
/* Never reached */ |
return 0; |
} |
/** |
* @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/dynload/uspace/srv/obio/Makefile |
---|
0,0 → 1,76 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Setup toolchain |
# |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
## Sources |
# |
OUTPUT = obio |
SOURCES = \ |
obio.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/branches/dynload/uspace/srv/obio |
---|
Property changes: |
Added: svn:mergeinfo |
/branches/dynload/uspace/Makefile |
---|
68,6 → 68,12 |
DIRS += srv/pci |
endif |
ifeq ($(UARCH),sparc64) |
DIRS += \ |
srv/fhc \ |
srv/obio |
endif |
BUILDS := $(addsuffix .build,$(DIRS)) |
CLEANS := $(addsuffix .clean,$(DIRS)) |