Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4668 → Rev 4669

/trunk/kernel/genarch/include/kbrd/scanc_pl050.h
0,0 → 1,58
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Scan codes for pl050 keyboards.
*/
 
#ifndef KERN_SCANC_PL050_H_
#define KERN_SCANC_PL050_H_
 
#define SC_SCAN_ESCAPE 0xE0
#define SC_ESC 0x76
#define SC_BACKSPACE 0x66
#define SC_LSHIFT 0x12
#define SC_RSHIFT 0x59
#define SC_CAPSLOCK 0x58
#define SC_SPEC_ESCAPE 0xe0
#define SC_LEFTARR 0x6b
#define SC_RIGHTARR 0x74
#define SC_UPARR 0x75
#define SC_DOWNARR 0x72
#define SC_DELETE 0x70
#define SC_HOME 0x6C
#define SC_END 0x69
 
#endif
 
/** @}
*/
/trunk/kernel/genarch/include/drivers/pl050/pl050.h
0,0 → 1,105
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
* @{
*/
/** @file
* @brief Describes the pl050 keyboard/mouse controller
*/
 
/**
* This file implements pl050 specific functions for keyboard and mouse
*/
 
#ifndef KERN_genarch_PL050_H
#define KERN_genarch_PL050_H
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <typedefs.h>
 
 
/*
* pl050 register offsets from the base address
*/
#define PL050_CR 0x00
#define PL050_STAT 0x04
#define PL050_DATA 0x08
#define PL050_CLOCKDIV 0x0C
#define PL050_INTRSTAT 0x10
 
/*
* Control Register Bits
*/
#define PL050_CR_TYPE (1 << 5) /* Type 0: PS2/AT mode, 1: No Line control bit mode */
#define PL050_CR_RXINTR (1 << 4) /* Recieve Interrupt Enable */
#define PL050_CR_TXINTR (1 << 3) /* Transmit Interrupt Enable */
#define PL050_CR_INTR (1 << 2) /* Interrupt Enable */
#define PL050_CR_FKMID (1 << 1) /* Force KMI Data Low */
#define PL050_CR_FKMIC 1 /* Force KMI Clock Low */
 
/*
* Status register bits
*/
#define PL050_STAT_TXEMPTY (1 << 6) /* 1: Transmit register empty */
#define PL050_STAT_TXBUSY (1 << 5) /* 1: Busy, sending data */
#define PL050_STAT_RXFULL (1 << 4) /* 1: register Full */
#define PL050_STAT_RXBUSY (1 << 3) /* 1: Busy, recieving Data */
#define PL050_STAT_RXPARITY (1 << 2) /* odd parity of the last bit recieved */
#define PL050_STAT_KMIC (1 << 1) /* status of KMICLKIN */
#define PL050_STAT_KMID 1 /* status of KMIDATAIN */
 
/*
* Interrupt status register bits.
*/
#define PL050_TX_INTRSTAT (1 << 1) /* Transmit intr asserted */
#define PL050_RX_INTRSTAT 1 /* Recieve intr asserted */
 
typedef struct {
ioport8_t *base;
ioport8_t *data;
ioport8_t *status;
ioport8_t *ctrl;
} pl050_t;
 
typedef struct {
irq_t irq;
pl050_t *pl050;
indev_t *kbrdin;
} pl050_instance_t;
 
extern pl050_instance_t *pl050_init(pl050_t *, inr_t);
extern void pl050_wire(pl050_instance_t *, indev_t *);
 
 
#endif
 
/** @}
*/
/trunk/kernel/genarch/Makefile.inc
110,6 → 110,12
genarch/src/kbrd/scanc_sun.c
endif
 
ifeq ($(CONFIG_PL050),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd_pl050.c \
genarch/src/kbrd/scanc_pl050.c
endif
 
ifeq ($(CONFIG_MAC_KBD),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd.c \
/trunk/kernel/genarch/src/kbrd/kbrd_pl050.c
0,0 → 1,209
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief pl050 Keyboard processing.
*/
 
#include <genarch/kbrd/kbrd.h>
#include <genarch/kbrd/scanc.h>
 
#include <genarch/kbrd/scanc_pl050.h>
 
#include <synch/spinlock.h>
#include <console/chardev.h>
#include <console/console.h>
#include <proc/thread.h>
#include <arch.h>
#include <macros.h>
 
#define PRESSED_SHIFT (1 << 0)
#define PRESSED_CAPSLOCK (1 << 1)
#define LOCKED_CAPSLOCK (1 << 0)
 
#define PL050_KEY_RELEASE 0xF0
#define PL050_ESC_KEY 0xE0
#define PL050_CAPS_SCAN_CODE 0x58
#define PL050_NUM_SCAN_CODE 0x77
#define PL050_SCROLL_SCAN_CODE 0x7E
 
static bool is_lock_key(wchar_t);
 
static indev_operations_t kbrd_raw_ops = {
.poll = NULL
};
 
/** Process release of key.
*
* @param sc Scancode of the key being released.
*/
static void key_released(kbrd_instance_t *instance, wchar_t sc)
{
spinlock_lock(&instance->keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
instance->keyflags &= ~PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
instance->keyflags &= ~PRESSED_CAPSLOCK;
if (instance->lockflags & LOCKED_CAPSLOCK)
instance->lockflags &= ~LOCKED_CAPSLOCK;
else
instance->lockflags |= LOCKED_CAPSLOCK;
break;
default:
break;
}
spinlock_unlock(&instance->keylock);
}
 
/** Process keypress.
*
* @param sc Scancode of the key being pressed.
*/
static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
{
bool letter;
bool shift;
bool capslock;
spinlock_lock(&instance->keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
instance->keyflags |= PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
instance->keyflags |= PRESSED_CAPSLOCK;
break;
case SC_SCAN_ESCAPE:
break;
default:
letter = islower(sc_primary_map[sc]);
shift = instance->keyflags & PRESSED_SHIFT;
capslock = (instance->keyflags & PRESSED_CAPSLOCK) ||
(instance->lockflags & LOCKED_CAPSLOCK);
if ((letter) && (capslock))
shift = !shift;
if (shift)
indev_push_character(instance->sink, sc_secondary_map[sc]);
else
indev_push_character(instance->sink, sc_primary_map[sc]);
break;
}
spinlock_unlock(&instance->keylock);
}
 
static void kkbrd(void *arg)
{
static int key_released_flag = 0;
static int is_locked = 0;
kbrd_instance_t *instance = (kbrd_instance_t *) arg;
while (true) {
wchar_t sc = indev_pop_character(&instance->raw);
 
if (sc == PL050_KEY_RELEASE) {
key_released_flag = 1;
} else {
if (key_released_flag) {
key_released_flag = 0;
if (is_lock_key(sc)) {
if (!is_locked) {
is_locked = 1;
} else {
is_locked = 0;
continue;
}
}
key_released(instance, sc);
 
} else {
if (is_lock_key(sc) && is_locked)
continue;
key_pressed(instance, sc);
}
}
}
}
 
kbrd_instance_t *kbrd_init(void)
{
kbrd_instance_t *instance
= malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC);
if (instance) {
instance->thread
= thread_create(kkbrd, (void *) instance, TASK, 0, "kkbrd", false);
if (!instance->thread) {
free(instance);
return NULL;
}
instance->sink = NULL;
indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
spinlock_initialize(&instance->keylock, "instance_keylock");
instance->keyflags = 0;
instance->lockflags = 0;
}
return instance;
}
 
indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
{
ASSERT(instance);
ASSERT(sink);
instance->sink = sink;
thread_ready(instance->thread);
return &instance->raw;
}
 
static bool is_lock_key(wchar_t sc)
{
return ((sc == PL050_CAPS_SCAN_CODE) || (sc == PL050_NUM_SCAN_CODE) ||
(sc == PL050_SCROLL_SCAN_CODE));
}
 
/** @}
*/
/trunk/kernel/genarch/src/kbrd/scanc_pl050.c
0,0 → 1,234
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, U_SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Scan codes for pl050 keyboards.
*/
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[] = {
U_NULL, /* 0x00 */
U_SPECIAL, /* 0x01 - F9 */
U_SPECIAL, /* 0x02 - F7 */
U_SPECIAL, /* 0x03 - F5 */
U_SPECIAL, /* 0x04 - F3 */
U_SPECIAL, /* 0x05 - F1 */
U_SPECIAL, /* 0x06 - F2 */
U_SPECIAL, /* 0x07 - F12 */
U_SPECIAL, /* 0x08 - */
U_SPECIAL, /* 0x09 - F10 */
U_SPECIAL, /* 0x0A - F8 */
U_SPECIAL, /* 0x0B - F10 */
U_SPECIAL, /* 0x0C - F4 */
'\t', /* 0x0D - Tab */
'`',
U_SPECIAL, /* 0x0F */
U_SPECIAL, /* 0x10 */
U_SPECIAL, /* 0x11 - LAlt */
U_SPECIAL, /* 0x12 - LShift */
U_SPECIAL, /* ox13 */
U_SPECIAL, /* 0x14 Ctrl */
'q', '1',
U_SPECIAL, /* 0x17 */
U_SPECIAL, /* 0x18 */
U_SPECIAL, /* 0x19 */
'z', 's', 'a', 'w', '2',
U_SPECIAL, /* 0x1F */
U_SPECIAL, /* 0x20 */
'c', 'x', 'd', 'e', '4', '3',
U_SPECIAL, /* 0x27 */
U_SPECIAL, /* 0x28 */
' ', 'v', 'f', 't', 'r', '5',
U_SPECIAL, /* 0x2F */
U_SPECIAL, /* 0x30 */
'n', 'b', 'h', 'g', 'y', '6',
U_SPECIAL, /* 0x37 */
U_SPECIAL, /* 0x38 */
U_SPECIAL, /* 0x39 */
'm', 'j', 'u', '7', '8',
U_SPECIAL, /* 0x3F */
U_SPECIAL, /* 0x40 */
',', 'k', 'i', 'o', '0', '9',
U_SPECIAL, /* 0x47 */
U_SPECIAL, /* 0x48 */
'.', '/', 'l', ';', 'p', '-',
U_SPECIAL, /* 0x4F */
U_SPECIAL, /* 0x50 */
U_SPECIAL, /* 0x51 */
'\'',
U_SPECIAL, /* 0x53 */
'[', '=',
U_SPECIAL, /* 0x56 */
U_SPECIAL, /* 0x57 */
U_SPECIAL, /* 0x58 - Caps Lock */
U_SPECIAL, /* 0x59 - RShift */
'\n', ']',
U_SPECIAL, /* 0x5C */
'\\',
U_SPECIAL, /* 0x5E */
U_SPECIAL, /* 0x5F */
U_SPECIAL, /* 0x60 */
U_SPECIAL, /* 0x61 */
U_SPECIAL, /* 0x62 */
U_SPECIAL, /* 0x63 */
U_SPECIAL, /* 0x64 */
U_SPECIAL, /* 0x65 */
'\b', /* 0x66 - backspace*/
U_SPECIAL, /* 0x67 */
U_SPECIAL, /* 0x68 */
U_END_ARROW, /* 0x69 */
U_SPECIAL, /* 0x6a */
U_LEFT_ARROW, /* 0x6b - Left Arrow */
U_SPECIAL, /* 0x6c */
U_SPECIAL, /* 0x6d */
U_SPECIAL, /* 0x6e */
U_SPECIAL, /* 0x6f */
U_SPECIAL, /* 0x70 */
U_DELETE, /* 0x71 - Del*/
U_DOWN_ARROW, /* 0x72 Down Arrow */
U_SPECIAL, /* 0x73 */
U_RIGHT_ARROW, /* 0x74 - Right Arrow */
U_UP_ARROW, /* 0x75 Up Arrow */
U_ESCAPE, /* 0x76 Esc */
U_SPECIAL, /* 0x77 - NumLock*/
U_SPECIAL, /* 0x78 F11*/
U_SPECIAL, /* 0x79 */
U_PAGE_DOWN, /* 0x7a */
U_SPECIAL, /* 0x7b */
U_SPECIAL, /* 0x7c */
U_PAGE_UP, /* 0x7d */
U_SPECIAL, /* 0x7e */
U_SPECIAL /* 0x7f */
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[] = {
U_NULL, /* 0x00 */
U_SPECIAL, /* 0x01 - F9 */
U_SPECIAL, /* 0x02 - F7 */
U_SPECIAL, /* 0x03 - F5 */
U_SPECIAL, /* 0x04 - F3 */
U_SPECIAL, /* 0x05 - F1 */
U_SPECIAL, /* 0x06 - F2 */
U_SPECIAL, /* 0x07 - F12 */
U_SPECIAL, /* 0x08 - */
U_SPECIAL, /* 0x09 - F10 */
U_SPECIAL, /* 0x0A - F8 */
U_SPECIAL, /* 0x0B - F10 */
U_SPECIAL, /* 0x0C - F4 */
'\t', /* 0x0D - Tab */
'~',
U_SPECIAL, /* 0x0F */
U_SPECIAL, /* 0x10 */
U_SPECIAL, /* 0x11 - LAlt */
U_SPECIAL, /* 0x12 - LShift */
U_SPECIAL, /* ox13 */
U_SPECIAL, /* 0x14 Ctrl */
'Q', '!',
U_SPECIAL, /* 0x17 */
U_SPECIAL, /* 0x18 */
U_SPECIAL, /* 0x19 */
'Z', 'S', 'A', 'W', '@',
U_SPECIAL, /* 0x1F */
U_SPECIAL, /* 0x20 */
'C', 'X', 'D', 'E', '$', '#',
U_SPECIAL, /* 0x27 */
U_SPECIAL, /* 0x28 */
' ', 'V', 'F', 'T', 'R', '%',
U_SPECIAL, /* 0x2F */
U_SPECIAL, /* 0x30 */
'N', 'B', 'H', 'G', 'Y', '^',
U_SPECIAL, /* 0x37 */
U_SPECIAL, /* 0x38 */
U_SPECIAL, /* 0x39 */
'M', 'J', 'U', '&', '*',
U_SPECIAL, /* 0x3F */
U_SPECIAL, /* 0x40 */
'<', 'K', 'I', 'O', ')', '(',
U_SPECIAL, /* 0x47 */
U_SPECIAL, /* 0x48 */
'>', '?', 'L', ':', 'P', '_',
U_SPECIAL, /* 0x4F */
U_SPECIAL, /* 0x50 */
U_SPECIAL, /* 0x51 */
'"',
U_SPECIAL, /* 0x53 */
'{', '+',
U_SPECIAL, /* 0x56 */
U_SPECIAL, /* 0x57 */
U_SPECIAL, /* 0x58 - Caps Lock */
U_SPECIAL, /* 0x59 - RShift */
'\n', '}',
U_SPECIAL, /* 0x5C */
'|',
U_SPECIAL, /* 0x5E */
U_SPECIAL, /* 0x5F */
U_SPECIAL, /* 0x60 */
U_SPECIAL, /* 0x61 */
U_SPECIAL, /* 0x62 */
U_SPECIAL, /* 0x63 */
U_SPECIAL, /* 0x64 */
U_SPECIAL, /* 0x65 */
'\b', /* 0x66 - backspace*/
U_SPECIAL, /* 0x67 */
U_SPECIAL, /* 0x68 */
U_END_ARROW, /* 0x69 */
U_SPECIAL, /* 0x6a */
U_LEFT_ARROW, /* 0x6b - Left Arrow */
U_SPECIAL, /* 0x6c */
U_SPECIAL, /* 0x6d */
U_SPECIAL, /* 0x6e */
U_SPECIAL, /* 0x6f */
U_SPECIAL, /* 0x70 */
U_DELETE, /* 0x71 - Del*/
U_DOWN_ARROW, /* 0x72 Down Arrow */
U_SPECIAL, /* 0x73 */
U_RIGHT_ARROW, /* 0x74 - Right Arrow */
U_UP_ARROW, /* 0x75 Up Arrow */
U_ESCAPE, /* 0x76 Esc */
U_SPECIAL, /* 0x77 - NumLock*/
U_SPECIAL, /* 0x78 F11*/
U_SPECIAL, /* 0x79 */
U_PAGE_DOWN, /* 0x7a */
U_SPECIAL, /* 0x7b */
U_SPECIAL, /* 0x7c */
U_PAGE_UP, /* 0x7d */
U_SPECIAL, /* 0x7e */
U_SPECIAL /* 0x7f */
};
 
/** @}
*/
/trunk/kernel/genarch/src/fb/fb.c
116,7 → 116,14
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
}
 
static void rgb_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst)
= (RED(rgb, 8) << 24) | (GREEN(rgb, 8) << 16) | (BLUE(rgb, 8) << 8);
 
}
 
 
/** RGB 8:8:8 conversion
*
*/
470,7 → 477,7
pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
rgb_conv = rgb_888;
rgb_conv = rgb_8880;
pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
/trunk/kernel/genarch/src/drivers/pl050/pl050.c
0,0 → 1,117
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief pl050 keyboard/mouse driver.
*
* It takes care of low-level keyboard functions.
*/
 
#include <genarch/drivers/pl050/pl050.h>
#include <arch/asm.h>
#include <console/chardev.h>
#include <mm/slab.h>
#include <ddi/device.h>
 
#define PL050_KEY_RELEASE 0xF0
#define PL050_ESC_KEY 0xE0
#define PL050_CAPS_SCAN_CODE 0x58
 
/** Structure for pl050's IRQ. */
static pl050_t *pl050;
 
static irq_ownership_t pl050_claim(irq_t *irq)
{
uint8_t status;
if ((status = pio_read_8(pl050->status)) & PL050_STAT_RXFULL)
return IRQ_ACCEPT;
else {
return IRQ_DECLINE;
}
}
 
static void pl050_irq_handler(irq_t *irq)
{
uint8_t data;
uint8_t status;
pl050_instance_t *instance = irq->instance;
while ((status = pio_read_8(pl050->status)) & PL050_STAT_RXFULL) {
data = pio_read_8(pl050->data);
indev_push_character(instance->kbrdin, data);
 
}
}
 
/** Initialize pl050. */
pl050_instance_t *pl050_init(pl050_t *dev, inr_t inr)
{
 
pl050_instance_t *instance =
malloc(sizeof(pl050_instance_t), FRAME_ATOMIC);
 
pl050 = dev;
 
if (instance) {
instance->pl050 = dev;
instance->kbrdin = NULL;
 
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = pl050_claim;
instance->irq.handler = pl050_irq_handler;
instance->irq.instance = instance;
}
 
return instance;
}
 
void pl050_wire(pl050_instance_t *instance, indev_t *kbrdin)
{
uint8_t val;
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
 
val = PL050_CR_RXINTR | PL050_CR_INTR;
 
pio_write_8(pl050->ctrl, val);
 
/* reset the data buffer */
pio_read_8(pl050->data);
}
 
 
/** @}
*/
/trunk/kernel/Makefile
343,6 → 343,9
clean:
-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(KARCH)/_link.ld
find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \;
ifeq ($(PLATFORM),arm32)
rm -f arch/$(KARCH)/include/machine.h
endif
for arch in arch/* ; do \
[ -e $$arch/_link.ld ] && rm $$arch/_link.ld 2>/dev/null ; \
done ; exit 0
350,6 → 353,9
archlinks:
ln -sfn ../../arch/$(KARCH)/include/ generic/include/arch
ln -sfn ../../genarch/include/ generic/include/genarch
ifeq ($(PLATFORM),arm32)
ln -sfn mach/$(MACHINE)/$(MACHINE).h arch/$(KARCH)/include/machine.h
endif
 
depend: archlinks
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
/trunk/kernel/arch/arm32/include/exception.h
136,6 → 136,13
extern void install_exception_handlers(void);
extern void exception_init(void);
extern void print_istate(istate_t *istate);
extern void reset_exception_entry(void);
extern void irq_exception_entry(void);
extern void fiq_exception_entry(void);
extern void undef_instr_exception_entry(void);
extern void prefetch_abort_exception_entry(void);
extern void data_abort_exception_entry(void);
extern void swi_exception_entry(void);
 
 
#endif
/trunk/kernel/arch/arm32/include/machine_func.h
0,0 → 1,132
/*
* Copyright (c) 2007 Michal Kebrt
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
* @{
*/
/** @file
* @brief Declarations of machine specific functions.
*
* These functions enable to differentiate more kinds of ARM emulators
* or CPUs. It's the same concept as "arch" functions on the architecture
* level.
*/
 
#ifndef KERN_arm32_MACHINE_FUNC_H_
#define KERN_arm32_MACHINE_FUNC_H_
 
#include <console/console.h>
#include <arch/types.h>
#include <arch/exception.h>
 
#define MACHINE_GENFUNC machine_genfunc
 
struct arm_machine_ops {
void (*machine_grab_console)(void);
void (*machine_release_console)(void);
void (*machine_init)(void);
void (*machine_timer_irq_start)(void);
void (*machine_cpu_halt)(void);
uintptr_t (*machine_get_memory_size)(void);
void (*machine_fb_init)(void);
void (*machine_irq_exception)(int, istate_t*);
uintptr_t (*machine_get_fb_address)(void);
void (*machine_frame_init)(void);
void (*machine_output_init)(void);
void (*machine_input_init)(void);
};
 
extern struct arm_machine_ops machine_ops;
 
 
/** Acquire console back for kernel. */
extern void machine_grab_console(void);
 
/** Return console to userspace. */
extern void machine_release_console(void);
 
 
/** Maps HW devices to the kernel address space using #hw_map. */
extern void machine_init(void);
 
 
/** Starts timer. */
extern void machine_timer_irq_start(void);
 
 
/** Halts CPU. */
extern void machine_cpu_halt(void);
 
 
/** Returns size of available memory.
*
* @return Size of available memory.
*/
extern uintptr_t machine_get_memory_size(void);
 
/** Initializes the Frame Buffer
*
*/
extern void machine_fb_init(void);
 
 
/** Interrupt exception handler.
*
* @param exc_no Interrupt exception number.
* @param istate Saved processor state.
*/
extern void machine_irq_exception(int exc_no, istate_t *istate);
 
 
/** Returns address of framebuffer device.
*
* @return Address of framebuffer device.
*/
extern uintptr_t machine_get_fb_address(void);
 
/*
* Machine specific frame initialization
*/
extern void machine_frame_init(void);
 
/*
* configure the serial line output device.
*/
extern void machine_output_init(void);
 
/*
* configure the serial line input device.
*/
extern void machine_input_init(void);
 
extern void machine_genfunc(void);
#endif
 
/** @}
*/
/trunk/kernel/arch/arm32/include/mach/testarm/testarm.h
0,0 → 1,87
/*
* Copyright (c) 2007 Michal Kebrt
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32gxemul GXemul
* @brief GXemul machine specific parts.
* @ingroup arm32
* @{
*/
/** @file
* @brief GXemul peripheries drivers declarations.
*/
 
#ifndef KERN_arm32_GXEMUL_H_
#define KERN_arm32_GXEMUL_H_
 
#include <arch/machine_func.h>
 
/** Last interrupt number (beginning from 0) whose status is probed
* from interrupt controller
*/
#define GXEMUL_IRQC_MAX_IRQ 8
#define GXEMUL_KBD_IRQ 2
#define GXEMUL_TIMER_IRQ 4
 
/** Timer frequency */
#define GXEMUL_TIMER_FREQ 100
 
#define GXEMUL_KBD_ADDRESS 0x10000000
#define GXEMUL_MP_ADDRESS 0x11000000
#define GXEMUL_FB_ADDRESS 0x12000000
#define GXEMUL_RTC_ADDRESS 0x15000000
#define GXEMUL_IRQC_ADDRESS 0x16000000
 
extern void *gxemul_kbd;
extern void *gxemul_rtc;
extern void *gxemul_irqc;
 
#define GXEMUL_HALT_OFFSET 0x010
#define GXEMUL_RTC_FREQ_OFFSET 0x100
#define GXEMUL_MP_MEMSIZE_OFFSET 0x090
#define GXEMUL_RTC_ACK_OFFSET 0x110
 
extern void gxemul_init(void);
extern void gxemul_fb_init(void);
extern void gxemul_output_init(void);
extern void gxemul_input_init(void);
extern void gxemul_release_console(void);
extern void gxemul_grab_console(void);
extern void gxemul_timer_irq_start(void);
extern void gxemul_cpu_halt(void);
extern void gxemul_irq_exception(int exc_no, istate_t *istate);
extern uintptr_t gxemul_get_memory_size(void);
extern uintptr_t gxemul_get_fb_address(void);
extern void gxemul_fb_init(void);
extern void gxemul_frame_init(void);
 
 
#endif
 
/** @}
*/
/trunk/kernel/arch/arm32/include/mach/integratorcp/integratorcp.h
0,0 → 1,116
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32integratorcp
* @brief Integratorcp machine specific parts.
* @ingroup arm32
* @{
*/
/** @file
* @brief Integratorcp peripheries drivers declarations.
*/
 
#ifndef KERN_arm32_ICP_H_
#define KERN_arm32_ICP_H_
 
#include <arch/machine_func.h>
 
/** Last interrupt number (beginning from 0) whose status is probed
* from interrupt controller
*/
#define ICP_IRQC_MAX_IRQ 8
#define ICP_KBD_IRQ 3
#define ICP_TIMER_IRQ 6
 
/** Timer frequency */
#define ICP_TIMER_FREQ 10000
 
#define ICP_UART 0x16000000
#define ICP_KBD 0x18000000
#define ICP_KBD_STAT 0x04
#define ICP_KBD_DATA 0x08
#define ICP_KBD_INTR_STAT 0x10
#define ICP_RTC 0x13000000
#define ICP_RTC1_LOAD_OFFSET 0x100
#define ICP_RTC1_READ_OFFSET 0x104
#define ICP_RTC1_CTL_OFFSET 0x108
#define ICP_RTC1_INTRCLR_OFFSET 0x10C
#define ICP_RTC1_INTRSTAT_OFFSET 0x114
#define ICP_RTC1_BGLOAD_OFFSET 0x118
#define ICP_RTC_CTL_VALUE 0x00E2
#define ICP_IRQC 0x14000000
#define ICP_IRQC_MASK_OFFSET 0xC
#define ICP_IRQC_UNMASK_OFFSET 0x8
#define ICP_FB 0x00800000
#define ICP_FB_FRAME (ICP_FB >> 12)
#define ICP_FB_NUM_FRAME 512
#define ICP_VGA 0xC0000000
#define ICP_CMCR 0x10000000
#define ICP_SDRAM_MASK 0x1C
#define ICP_SDRAMCR_OFFSET 0x20
 
typedef struct {
uintptr_t uart;
uintptr_t kbd_ctrl;
uintptr_t kbd_stat;
uintptr_t kbd_data;
uintptr_t kbd_intstat;
uintptr_t rtc;
uintptr_t rtc1_load;
uintptr_t rtc1_read;
uintptr_t rtc1_ctl;
uintptr_t rtc1_intrclr;
uintptr_t rtc1_intrstat;
uintptr_t rtc1_bgload;
uintptr_t irqc;
uintptr_t irqc_mask;
uintptr_t irqc_unmask;
uintptr_t vga;
uintptr_t cmcr;
uintptr_t sdramcr;
} icp_hw_map_t;
 
 
extern void icp_init(void);
extern void icp_fb_init(void);
extern void icp_output_init(void);
extern void icp_input_init(void);
extern void icp_release_console(void);
extern void icp_grab_console(void);
extern void icp_timer_irq_start(void);
extern void icp_cpu_halt(void);
extern void icp_irq_exception(int exc_no, istate_t *istate);
extern uintptr_t icp_get_memory_size(void);
extern uintptr_t icp_get_fb_address(void);
extern void icp_fb_init(void);
extern void icp_frame_init(void);
 
#endif
 
/** @}
*/
/trunk/kernel/arch/arm32/include/drivers/gxemul.h
File deleted
/trunk/kernel/arch/arm32/Makefile.inc
45,7 → 45,9
ARCH_SOURCES = \
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/exc_handler.S \
arch/$(KARCH)/src/arm32.c \
arch/$(KARCH)/src/machine_func.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/dummy.S \
arch/$(KARCH)/src/panic.S \
58,5 → 60,12
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/mm/page_fault.c \
arch/$(KARCH)/src/drivers/gxemul.c
arch/$(KARCH)/src/mm/page_fault.c
ifeq ($(MACHINE), testarm)
ARCH_SOURCES += arch/$(KARCH)/src/mach/testarm/testarm.c
else ifeq ($(MACHINE), integratorcp)
ARCH_SOURCES += arch/$(KARCH)/src/mach/integratorcp/integratorcp.c
endif
ifeq ($(CONFIG_PL050), y)
ARCH_SOURCES += genarch/src/drivers/pl050/pl050.c
endif
/trunk/kernel/arch/arm32/src/exception.c
39,7 → 39,7
#include <interrupt.h>
#include <arch/mm/page_fault.h>
#include <arch/barrier.h>
#include <arch/drivers/gxemul.h>
#include <arch/machine.h>
#include <print.h>
#include <syscall/syscall.h>
 
58,159 → 58,6
/** Size of memory block occupied by exception vectors. */
#define EXC_VECTORS_SIZE (EXC_VECTORS * 4)
 
/** Switches to kernel stack and saves all registers there.
*
* Temporary exception stack is used to save a few registers
* before stack switch takes place.
*
*/
inline static void setup_stack_and_save_regs()
{
asm volatile (
"ldr r13, =exc_stack\n"
"stmfd r13!, {r0}\n"
"mrs r0, spsr\n"
"and r0, r0, #0x1f\n"
"cmp r0, #0x10\n"
"bne 1f\n"
/* prev mode was usermode */
"ldmfd r13!, {r0}\n"
"ldr r13, =supervisor_sp\n"
"ldr r13, [r13]\n"
"stmfd r13!, {lr}\n"
"stmfd r13!, {r0-r12}\n"
"stmfd r13!, {r13, lr}^\n"
"mrs r0, spsr\n"
"stmfd r13!, {r0}\n"
"b 2f\n"
/* mode was not usermode */
"1:\n"
"stmfd r13!, {r1, r2, r3}\n"
"mrs r1, cpsr\n"
"mov r2, lr\n"
"bic r1, r1, #0x1f\n"
"orr r1, r1, r0\n"
"mrs r0, cpsr\n"
"msr cpsr_c, r1\n"
"mov r3, r13\n"
"stmfd r13!, {r2}\n"
"mov r2, lr\n"
"stmfd r13!, {r4-r12}\n"
"mov r1, r13\n"
/* the following two lines are for debugging */
"mov sp, #0\n"
"mov lr, #0\n"
"msr cpsr_c, r0\n"
"ldmfd r13!, {r4, r5, r6, r7}\n"
"stmfd r1!, {r4, r5, r6}\n"
"stmfd r1!, {r7}\n"
"stmfd r1!, {r2}\n"
"stmfd r1!, {r3}\n"
"mrs r0, spsr\n"
"stmfd r1!, {r0}\n"
"mov r13, r1\n"
"2:\n"
);
}
 
/** Returns from exception mode.
*
* Previously saved state of registers (including control register)
* is restored from the stack.
*/
inline static void load_regs()
{
asm volatile(
"ldmfd r13!, {r0} \n"
"msr spsr, r0 \n"
"and r0, r0, #0x1f \n"
"cmp r0, #0x10 \n"
"bne 1f \n"
 
/* return to user mode */
"ldmfd r13!, {r13, lr}^ \n"
"b 2f \n"
 
/* return to non-user mode */
"1:\n"
"ldmfd r13!, {r1, r2} \n"
"mrs r3, cpsr \n"
"bic r3, r3, #0x1f \n"
"orr r3, r3, r0 \n"
"mrs r0, cpsr \n"
"msr cpsr_c, r3 \n"
 
"mov r13, r1 \n"
"mov lr, r2 \n"
"msr cpsr_c, r0 \n"
 
/* actual return */
"2:\n"
"ldmfd r13, {r0-r12, pc}^\n"
);
}
 
 
/** Switch CPU to mode in which interrupts are serviced (currently it
* is Undefined mode).
*
* The default mode for interrupt servicing (Interrupt Mode)
* can not be used because of nested interrupts (which can occur
* because interrupts are enabled in higher levels of interrupt handler).
*/
inline static void switch_to_irq_servicing_mode()
{
/* switch to Undefined mode */
asm volatile(
/* save regs used during switching */
"stmfd sp!, {r0-r3} \n"
 
/* save stack pointer and link register to r1, r2 */
"mov r1, sp \n"
"mov r2, lr \n"
 
/* mode switch */
"mrs r0, cpsr \n"
"bic r0, r0, #0x1f \n"
"orr r0, r0, #0x1b \n"
"msr cpsr_c, r0 \n"
 
/* restore saved sp and lr */
"mov sp, r1 \n"
"mov lr, r2 \n"
 
/* restore original regs */
"ldmfd sp!, {r0-r3} \n"
);
}
 
/** Calls exception dispatch routine. */
#define CALL_EXC_DISPATCH(exception) \
asm volatile ( \
"mov r0, %[exc]\n" \
"mov r1, r13\n" \
"bl exc_dispatch\n" \
:: [exc] "i" (exception) \
);\
 
/** General exception handler.
*
* Stores registers, dispatches the exception,
* and finally restores registers and returns from exception processing.
*
* @param exception Exception number.
*/
#define PROCESS_EXCEPTION(exception) \
setup_stack_and_save_regs(); \
CALL_EXC_DISPATCH(exception) \
load_regs();
 
/** Updates specified exception vector to jump to given handler.
*
* Addresses of handlers are stored in memory following exception vectors.
232,71 → 79,6
 
}
 
/** Low-level Reset Exception handler. */
static void reset_exception_entry(void)
{
PROCESS_EXCEPTION(EXC_RESET);
}
 
/** Low-level Software Interrupt Exception handler. */
static void swi_exception_entry(void)
{
PROCESS_EXCEPTION(EXC_SWI);
}
 
/** Low-level Undefined Instruction Exception handler. */
static void undef_instr_exception_entry(void)
{
PROCESS_EXCEPTION(EXC_UNDEF_INSTR);
}
 
/** Low-level Fast Interrupt Exception handler. */
static void fiq_exception_entry(void)
{
PROCESS_EXCEPTION(EXC_FIQ);
}
 
/** Low-level Prefetch Abort Exception handler. */
static void prefetch_abort_exception_entry(void)
{
asm volatile (
"sub lr, lr, #4"
);
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
}
 
/** Low-level Data Abort Exception handler. */
static void data_abort_exception_entry(void)
{
asm volatile (
"sub lr, lr, #8"
);
PROCESS_EXCEPTION(EXC_DATA_ABORT);
}
 
/** Low-level Interrupt Exception handler.
*
* CPU is switched to Undefined mode before further interrupt processing
* because of possible occurence of nested interrupt exception, which
* would overwrite (and thus spoil) stack pointer.
*/
static void irq_exception_entry(void)
{
asm volatile (
"sub lr, lr, #4"
);
setup_stack_and_save_regs();
switch_to_irq_servicing_mode();
CALL_EXC_DISPATCH(EXC_IRQ)
 
load_regs();
}
 
/** Software Interrupt handler.
*
* Dispatches the syscall.
307,37 → 89,6
istate->r3, istate->r4, istate->r5, istate->r6);
}
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
{
return *((uint32_t *) gxemul_irqc);
}
 
/** Interrupt Exception handler.
*
* Determines the sources of interrupt and calls their handlers.
*/
static void irq_exception(int exc_no, istate_t *istate)
{
uint32_t sources = gxemul_irqc_get_sources();
unsigned int i;
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
printf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Fills exception vectors with appropriate exception handlers. */
void install_exception_handlers(void)
{
384,6 → 135,15
}
#endif
 
/** Interrupt Exception handler.
*
* Determines the sources of interrupt and calls their handlers.
*/
static void irq_exception(int exc_no, istate_t *istate)
{
machine_irq_exception(exc_no, istate);
}
 
/** Initializes exception handling.
*
* Installs low-level exception handlers and then registers
/trunk/kernel/arch/arm32/src/start.S
35,11 → 35,33
.global supervisor_sp
 
kernel_image_start:
 
# initialize Stack pointer for exception modes
mrs r4, cpsr
bic r4, r4, #0x1f
 
#FIQ Mode
orr r3, r4, #0x11
msr cpsr_c, r3
ldr sp, =exc_stack
 
#IRQ Mode
orr r3, r4, #0x12
msr cpsr_c, r3
ldr sp, =exc_stack
 
#ABORT Mode
orr r3, r4, #0x17
msr cpsr_c, r3
ldr sp, =exc_stack
 
#UNDEFINED Mode
orr r3, r4, #0x1b
msr cpsr_c, r3
ldr sp, =exc_stack
 
# switch to supervisor mode
mrs r3, cpsr
bic r3, r3, #0x1f
orr r3, r3, #0x13
orr r3, r4, #0x13
msr cpsr_c, r3
ldr sp, =temp_stack
/trunk/kernel/arch/arm32/src/machine_func.c
0,0 → 1,147
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
* @{
*/
/** @file
* @brief Definitions of machine specific functions.
*
* These functions enable to differentiate more kinds of ARM emulators
* or CPUs. It's the same concept as "arch" functions on the architecture
* level.
*/
 
#include <arch/machine_func.h>
 
 
/** Acquire console back for kernel. */
void machine_grab_console(void)
{
(machine_ops.machine_grab_console)();
}
 
/** Return console to userspace. */
void machine_release_console(void)
{
(machine_ops.machine_release_console)();
}
 
 
/** Maps HW devices to the kernel address space using #hw_map. */
void machine_init(void)
{
(machine_ops.machine_init)();
}
 
 
/** Starts timer. */
void machine_timer_irq_start(void)
{
(machine_ops.machine_timer_irq_start)();
}
 
 
/** Halts CPU. */
void machine_cpu_halt(void)
{
(machine_ops.machine_cpu_halt)();
}
 
 
/** Returns size of available memory.
*
* @return Size of available memory.
*/
uintptr_t machine_get_memory_size(void)
{
return (machine_ops.machine_get_memory_size)();
}
 
/** Initializes the Frame Buffer
*
*/
void machine_fb_init(void)
{
(machine_ops.machine_fb_init)();
}
 
 
/** Interrupt exception handler.
*
* @param exc_no Interrupt exception number.
* @param istate Saved processor state.
*/
void machine_irq_exception(int exc_no, istate_t *istate)
{
(machine_ops.machine_irq_exception)(exc_no, istate);
}
 
 
/** Returns address of framebuffer device.
*
* @return Address of framebuffer device.
*/
uintptr_t machine_get_fb_address(void)
{
return (machine_ops.machine_get_fb_address)();
}
 
/*
* Machine specific frame initialization
*/
void machine_frame_init(void)
{
(machine_ops.machine_frame_init)();
}
 
/*
* configure the output device.
*/
void machine_output_init(void)
{
(machine_ops.machine_output_init)();
}
 
/*
* configure the input device.
*/
void machine_input_init(void)
{
(machine_ops.machine_input_init)();
}
 
/*
* Generic function to use, if sepcific function doesn't define any of the above functions.
*/
void machine_genfunc()
{
}
 
/** @}
*/
/trunk/kernel/arch/arm32/src/arm32.c
37,13 → 37,10
#include <config.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <genarch/srln/srln.h>
#include <sysinfo/sysinfo.h>
#include <console/console.h>
#include <ddi/irq.h>
#include <arch/drivers/gxemul.h>
#include <arch/machine.h>
#include <print.h>
#include <config.h>
#include <interrupt.h>
77,7 → 74,7
/** Performs arm32 specific initialization afterr mm is initialized. */
void arch_post_mm_init(void)
{
gxemul_init();
machine_init();
/* Initialize exception dispatch table */
exception_init();
84,18 → 81,10
interrupt_init();
#ifdef CONFIG_FB
fb_properties_t prop = {
.addr = GXEMUL_FB_ADDRESS,
.offset = 0,
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_BGR_8_8_8,
};
fb_init(&prop);
machine_fb_init();
#else
#ifdef CONFIG_ARM_PRN
dsrlnout_init((ioport8_t *) gxemul_kbd);
machine_output_init();
#endif /* CONFIG_ARM_PRN */
#endif /* CONFIG_FB */
}
126,30 → 115,7
*/
void arch_post_smp_init(void)
{
#ifdef CONFIG_ARM_KBD
/*
* Initialize the GXemul keyboard port. Then initialize the serial line
* module and connect it to the GXemul keyboard.
*/
dsrlnin_instance_t *dsrlnin_instance
= dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ);
if (dsrlnin_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
dsrlnin_wire(dsrlnin_instance, srln);
}
}
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
#endif
machine_input_init();
}
 
 
156,7 → 122,6
/** Performs arm32 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
tlb_invalidate_all();
}
 
 
168,6 → 133,7
{
uint8_t *stck;
tlb_invalidate_all();
stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
supervisor_sp = (uintptr_t) stck;
}
183,8 → 149,7
/** Halts CPU. */
void cpu_halt(void)
{
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET))
= 0;
machine_cpu_halt();
}
 
/** Reboot. */
211,6 → 176,7
/** Acquire console back for kernel. */
void arch_grab_console(void)
{
machine_grab_console();
#ifdef CONFIG_FB
fb_redraw();
#endif
219,6 → 185,7
/** Return console to userspace. */
void arch_release_console(void)
{
machine_release_console();
}
 
/** @}
/trunk/kernel/arch/arm32/src/mach/testarm/testarm.c
0,0 → 1,242
/*
* Copyright (c) 2007 Michal Kebrt, Petr Stepan
* 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 arm32gxemul
* @{
*/
/** @file
* @brief GXemul drivers.
*/
 
#include <arch/exception.h>
#include <arch/mach/testarm/testarm.h>
#include <mm/page.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <genarch/srln/srln.h>
#include <console/console.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <config.h>
#include <sysinfo/sysinfo.h>
#include <interrupt.h>
#include <print.h>
 
 
void *gxemul_kbd;
void *gxemul_rtc;
void *gxemul_irqc;
static irq_t gxemul_timer_irq;
 
struct arm_machine_ops machine_ops = {
MACHINE_GENFUNC,
MACHINE_GENFUNC,
gxemul_init,
gxemul_timer_irq_start,
gxemul_cpu_halt,
gxemul_get_memory_size,
gxemul_fb_init,
gxemul_irq_exception,
gxemul_get_fb_address,
gxemul_frame_init,
gxemul_output_init,
gxemul_input_init
};
 
void gxemul_init(void)
{
gxemul_kbd = (void *) hw_map(GXEMUL_KBD_ADDRESS, PAGE_SIZE);
gxemul_rtc = (void *) hw_map(GXEMUL_RTC_ADDRESS, PAGE_SIZE);
gxemul_irqc = (void *) hw_map(GXEMUL_IRQC_ADDRESS, PAGE_SIZE);
}
 
void gxemul_fb_init(void)
{
fb_properties_t prop = {
.addr = GXEMUL_FB_ADDRESS,
.offset = 0,
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_BGR_8_8_8,
};
fb_init(&prop);
}
 
void gxemul_output_init(void)
{
dsrlnout_init((ioport8_t *) gxemul_kbd);
}
 
void gxemul_input_init(void)
{
#ifdef CONFIG_ARM_KBD
/*
* Initialize the GXemul keyboard port. Then initialize the serial line
* module and connect it to the GXemul keyboard.
*/
dsrlnin_instance_t *dsrlnin_instance
= dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ);
if (dsrlnin_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
dsrlnin_wire(dsrlnin_instance, srln);
}
}
 
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
#endif
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
= frequency;
}
 
static irq_ownership_t gxemul_timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
 
/* acknowledge tick */
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
= 0;
}
 
/** Initializes and registers timer interrupt handler. */
static void gxemul_timer_irq_init(void)
{
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
 
irq_register(&gxemul_timer_irq);
}
 
 
/** Starts timer.
*
* Initiates regular timer interrupts after initializing
* corresponding interrupt handler.
*/
void gxemul_timer_irq_start(void)
{
gxemul_timer_irq_init();
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** Returns the size of emulated memory.
*
* @return Size in bytes.
*/
uintptr_t gxemul_get_memory_size(void)
{
return *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
}
 
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
{
return *((uint32_t *) gxemul_irqc);
}
 
/** Interrupt Exception handler.
*
* Determines the sources of interrupt and calls their handlers.
*/
void gxemul_irq_exception(int exc_no, istate_t *istate)
{
uint32_t sources = gxemul_irqc_get_sources();
unsigned int i;
 
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
printf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
void gxemul_cpu_halt(void)
{
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET)) = 0;
}
 
void gxemul_frame_init(void)
{
}
 
uintptr_t gxemul_get_fb_address()
{
return ((uintptr_t)GXEMUL_FB_ADDRESS);
}
 
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/trunk/kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
0,0 → 1,360
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32integratorcp
* @{
*/
/** @file
* @brief ICP drivers.
*/
 
#include <interrupt.h>
#include <ipc/irq.h>
#include <console/chardev.h>
#include <genarch/drivers/pl050/pl050.h>
#include <genarch/kbrd/kbrd.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <print.h>
#include <ddi/device.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <arch/mach/integratorcp/integratorcp.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <ddi/ddi.h>
#include <print.h>
 
#define SDRAM_SIZE (sdram[((*(uint32_t *)(ICP_CMCR+ICP_SDRAMCR_OFFSET) & ICP_SDRAM_MASK) >> 2)])
static parea_t fb_parea;
static icp_hw_map_t icp_hw_map;
static irq_t icp_timer_irq;
struct arm_machine_ops machine_ops = {
MACHINE_GENFUNC,
MACHINE_GENFUNC,
icp_init,
icp_timer_irq_start,
icp_cpu_halt,
icp_get_memory_size,
icp_fb_init,
icp_irq_exception,
icp_get_fb_address,
icp_frame_init,
icp_output_init,
icp_input_init
};
 
static bool hw_map_init_called = false;
static bool vga_init = false;
uint32_t sdram[8] = {
16777216, /* 16mb */
33554432, /* 32mb */
67108864, /* 64mb */
134217728, /* 128mb */
268435456, /* 256mb */
0, /* Reserverd */
0, /* Reserverd */
0 /* Reserverd */
};
 
void icp_vga_init(void);
 
/** Initializes the vga
*
*/
void icp_vga_init(void)
{
*(uint32_t*)((char *)(icp_hw_map.cmcr)+0x14) = 0xA05F0000;
*(uint32_t*)((char *)(icp_hw_map.cmcr)+0x1C) = 0x12C11000;
*(uint32_t*)icp_hw_map.vga = 0x3F1F3F9C;
*(uint32_t*)((char *)(icp_hw_map.vga) + 0x4) = 0x080B61DF;
*(uint32_t*)((char *)(icp_hw_map.vga) + 0x8) = 0x067F3800;
*(uint32_t*)((char *)(icp_hw_map.vga) + 0x10) = ICP_FB;
*(uint32_t *)((char *)(icp_hw_map.vga) + 0x1C) = 0x182B;
*(uint32_t*)((char *)(icp_hw_map.cmcr)+0xC) = 0x33805000;
}
 
/** Returns the mask of active interrupts. */
static inline uint32_t icp_irqc_get_sources(void)
{
return *((uint32_t *) icp_hw_map.irqc);
}
 
 
/** Masks interrupt.
*
* @param irq interrupt number
*/
static inline void icp_irqc_mask(uint32_t irq)
{
*((uint32_t *) icp_hw_map.irqc_mask) = (1 << irq);
}
 
 
/** Unmasks interrupt.
*
* @param irq interrupt number
*/
static inline void icp_irqc_unmask(uint32_t irq)
{
*((uint32_t *) icp_hw_map.irqc_unmask) |= (1 << irq);
}
 
/** Initializes the icp frame buffer */
void icp_fb_init(void)
{
fb_properties_t prop = {
.addr = 0,
.offset = 0,
.x = 640,
.y = 480,
.scan = 2560,
.visual = VISUAL_RGB_8_8_8_0,
};
prop.addr = icp_get_fb_address();
fb_init(&prop);
fb_parea.pbase = ICP_FB;
fb_parea.frames = 300;
ddi_parea_register(&fb_parea);
}
 
/** Initializes icp_hw_map. */
void icp_init(void)
{
icp_hw_map.uart = hw_map(ICP_UART, PAGE_SIZE);
icp_hw_map.kbd_ctrl = hw_map(ICP_KBD, PAGE_SIZE);
icp_hw_map.kbd_stat = icp_hw_map.kbd_ctrl + ICP_KBD_STAT;
icp_hw_map.kbd_data = icp_hw_map.kbd_ctrl + ICP_KBD_DATA;
icp_hw_map.kbd_intstat = icp_hw_map.kbd_ctrl + ICP_KBD_INTR_STAT;
icp_hw_map.rtc = hw_map(ICP_RTC, PAGE_SIZE);
icp_hw_map.rtc1_load = icp_hw_map.rtc + ICP_RTC1_LOAD_OFFSET;
icp_hw_map.rtc1_read = icp_hw_map.rtc + ICP_RTC1_READ_OFFSET;
icp_hw_map.rtc1_ctl = icp_hw_map.rtc + ICP_RTC1_CTL_OFFSET;
icp_hw_map.rtc1_intrclr = icp_hw_map.rtc + ICP_RTC1_INTRCLR_OFFSET;
icp_hw_map.rtc1_bgload = icp_hw_map.rtc + ICP_RTC1_BGLOAD_OFFSET;
icp_hw_map.rtc1_intrstat = icp_hw_map.rtc + ICP_RTC1_INTRSTAT_OFFSET;
 
icp_hw_map.irqc = hw_map(ICP_IRQC, PAGE_SIZE);
icp_hw_map.irqc_mask = icp_hw_map.irqc + ICP_IRQC_MASK_OFFSET;
icp_hw_map.irqc_unmask = icp_hw_map.irqc + ICP_IRQC_UNMASK_OFFSET;
icp_hw_map.cmcr = hw_map(ICP_CMCR, PAGE_SIZE);
icp_hw_map.sdramcr = icp_hw_map.cmcr + ICP_SDRAMCR_OFFSET;
icp_hw_map.vga = hw_map(ICP_VGA, PAGE_SIZE);
 
hw_map_init_called = true;
}
 
 
/** Acquire console back for kernel. */
void icp_grab_console(void)
{
}
 
/** Return console to userspace. */
void icp_release_console(void)
{
}
 
/** Starts icp Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void icp_timer_start(uint32_t frequency)
{
icp_irqc_mask(ICP_TIMER_IRQ);
*((uint32_t*) icp_hw_map.rtc1_load) = frequency;
*((uint32_t*) icp_hw_map.rtc1_bgload) = frequency;
*((uint32_t*) icp_hw_map.rtc1_ctl) = ICP_RTC_CTL_VALUE;
icp_irqc_unmask(ICP_TIMER_IRQ);
}
 
static irq_ownership_t icp_timer_claim(irq_t *irq)
{
if (icp_hw_map.rtc1_intrstat) {
*((uint32_t*) icp_hw_map.rtc1_intrclr) = 1;
return IRQ_ACCEPT;
} else
return IRQ_DECLINE;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void icp_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
 
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
 
}
 
/** Initializes and registers timer interrupt handler. */
static void icp_timer_irq_init(void)
{
irq_initialize(&icp_timer_irq);
icp_timer_irq.devno = device_assign_devno();
icp_timer_irq.inr = ICP_TIMER_IRQ;
icp_timer_irq.claim = icp_timer_claim;
icp_timer_irq.handler = icp_timer_irq_handler;
 
irq_register(&icp_timer_irq);
}
 
 
/** Starts timer.
*
* Initiates regular timer interrupts after initializing
* corresponding interrupt handler.
*/
void icp_timer_irq_start(void)
{
icp_timer_irq_init();
icp_timer_start(ICP_TIMER_FREQ);
}
 
/** Returns the size of emulated memory.
*
* @return Size in bytes.
*/
size_t icp_get_memory_size(void)
{
if (hw_map_init_called) {
return (sdram[((*(uint32_t *)icp_hw_map.sdramcr & ICP_SDRAM_MASK) >> 2)]);
} else {
return SDRAM_SIZE;
}
}
 
/** Stops icp. */
void icp_cpu_halt(void)
{
while (1);
}
 
/** interrupt exception handler.
*
* Determines sources of the interrupt from interrupt controller and
* calls high-level handlers for them.
*
* @param exc_no Interrupt exception number.
* @param istate Saved processor state.
*/
void icp_irq_exception(int exc_no, istate_t *istate)
{
uint32_t sources = icp_irqc_get_sources();
int i;
for (i = 0; i < ICP_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
printf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Returns address of framebuffer device.
*
* @return Address of framebuffer device.
*/
uintptr_t icp_get_fb_address(void)
{
if (!vga_init) {
icp_vga_init();
vga_init = true;
}
return (uintptr_t) ICP_FB;
}
 
/*
* Integrator specific frame initialization
*/
void
icp_frame_init(void)
{
frame_mark_unavailable(ICP_FB_FRAME, ICP_FB_NUM_FRAME);
frame_mark_unavailable(0, 256);
}
 
void icp_output_init(void)
{
}
 
void icp_input_init(void)
{
 
pl050_t *pl050 = malloc(sizeof(pl050_t), FRAME_ATOMIC);
pl050->status = (ioport8_t *)icp_hw_map.kbd_stat;
pl050->data = (ioport8_t *)icp_hw_map.kbd_data;
pl050->ctrl = (ioport8_t *)icp_hw_map.kbd_ctrl;
pl050_instance_t *pl050_instance = pl050_init(pl050, ICP_KBD_IRQ);
if (pl050_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
icp_irqc_mask(ICP_KBD_IRQ);
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
pl050_wire(pl050_instance, kbrd);
icp_irqc_unmask(ICP_KBD_IRQ);
}
}
 
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, ICP_KBD_IRQ);
sysinfo_set_item_val("kbd.address.status", NULL,
(uintptr_t) icp_hw_map.kbd_stat);
sysinfo_set_item_val("kbd.address.data", NULL,
(uintptr_t) icp_hw_map.kbd_data);
 
}
 
 
/** @}
*/
/trunk/kernel/arch/arm32/src/mm/frame.c
35,7 → 35,7
 
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <arch/drivers/gxemul.h>
#include <arch/machine.h>
#include <config.h>
 
/** Address of the last frame in the memory. */
44,7 → 44,7
/** Creates memory zones. */
void frame_arch_init(void)
{
last_frame = *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
last_frame = machine_get_memory_size();
/* All memory as one zone */
zone_create(0, ADDR2PFN(last_frame),
53,6 → 53,8
/* blacklist boot page table */
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME,
BOOT_PAGE_TABLE_SIZE_IN_FRAMES);
 
machine_frame_init();
}
 
/** Frees the boot page table. */
/trunk/kernel/arch/arm32/src/interrupt.c
35,7 → 35,7
 
#include <arch/asm.h>
#include <arch/regutils.h>
#include <arch/drivers/gxemul.h>
#include <arch/machine.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <interrupt.h>
43,8 → 43,6
/** Initial size of a table holding interrupt handlers. */
#define IRQ_COUNT 8
 
static irq_t gxemul_timer_irq;
 
/** Disable interrupts.
*
* @return Old interrupt priority level.
52,7 → 50,7
ipl_t interrupts_disable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl);
return ipl;
65,7 → 63,7
ipl_t interrupts_enable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT);
return ipl;
91,41 → 89,6
return current_status_reg_read();
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
= frequency;
}
 
static irq_ownership_t gxemul_timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
/* acknowledge tick */
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
= 0;
}
 
/** Initialize basic tables for exception dispatching
* and starts the timer.
*/
132,16 → 95,8
void interrupt_init(void)
{
irq_init(IRQ_COUNT, IRQ_COUNT);
machine_timer_irq_start();
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
irq_register(&gxemul_timer_irq);
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** @}
/trunk/kernel/arch/arm32/src/exc_handler.S
0,0 → 1,199
#
# Copyright (c) 2009 Vineeth Pillai
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
.text
 
.global irq_exception_entry
.global fiq_exception_entry
.global data_abort_exception_entry
.global prefetch_abort_exception_entry
.global undef_instr_exception_entry
.global swi_exception_entry
.global reset_exception_entry
 
 
# Switches to kernel stack and saves all registers there.
#
# The stack frame created by the function looks like:
#
# |_________________|
# | |
# | SPSR |
# | |
# |_________________|
# | Stack Pointer |
# | of |
# | Previous Mode |
# |_________________|
# | Return address |
# | of |
# | Previous Mode |
# |_________________|
# | R0 - R12 |
# | of |
# | Previous Mode |
# |_________________|
# | Return address |
# | from |
# |Exception Handler|
# |_________________|
# | |
#
#
 
.macro SAVE_REGS_TO_STACK
stmfd r13!, {r0-r3}
mov r3, sp
add sp, sp, #16
mrs r1, cpsr
bic r1, r1, #0x1f
mrs r2, spsr
and r0, r2, #0x1f
cmp r0, #0x10
bne 1f
 
# prev mode was usermode
mov r0, lr
 
# Switch to supervisor mode
orr r1, r1, #0x13
msr cpsr_c, r1
 
# Load sp with [supervisor_sp]
ldr r13, =supervisor_sp
ldr r13, [r13]
 
# Populate the stack frame
msr spsr, r2
mov lr, r0
stmfd r13!, {lr}
stmfd r13!, {r4-r12}
ldmfd r3!, {r4-r7}
stmfd r13!, {r4-r7}
stmfd r13!, {r13, lr}^
stmfd r13!, {r2}
b 2f
 
# mode was not usermode
1:
# Switch to previous mode which is undoubtedly the supervisor mode
orr r1, r1, r0
mov r0, lr
msr cpsr_c, r1
 
# Populate the stack frame
mov r1, sp
stmfd r13!, {r0}
stmfd r13!, {r4-r12}
 
# Store r0-r3 in r4-r7 and then push it on to stack
ldmfd r3!, {r4-r7}
stmfd r13!, {r4-r7}
 
# Push return address and stack pointer on to stack
stmfd r13!, {lr}
stmfd r13!, {r1}
mov lr, r0
msr spsr, r2
stmfd r13!, {r2}
2:
.endm
 
.macro LOAD_REGS_FROM_STACK
ldmfd r13!, {r0}
msr spsr, r0
and r0, r0, #0x1f
cmp r0, #0x10
bne 1f
 
# return to user mode
ldmfd r13!, {r13, lr}^
b 2f
 
# return to non-user mode
1:
ldmfd r13!, {r1, lr}
 
2:
ldmfd r13!, {r0-r12, pc}^
.endm
 
reset_exception_entry:
SAVE_REGS_TO_STACK
mov r0, #0
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
irq_exception_entry:
sub lr, lr, #4
SAVE_REGS_TO_STACK
mov r0, #5
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
fiq_exception_entry:
sub lr, lr, #4
SAVE_REGS_TO_STACK
mov r0, #6
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
undef_instr_exception_entry:
SAVE_REGS_TO_STACK
mov r0, #1
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
prefetch_abort_exception_entry:
sub lr, lr, #4
SAVE_REGS_TO_STACK
mov r0, #3
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
data_abort_exception_entry:
sub lr, lr, #8
SAVE_REGS_TO_STACK
mov r0, #4
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
swi_exception_entry:
ldr r13, =exc_stack
SAVE_REGS_TO_STACK
mov r0, #2
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
/trunk/kernel/arch/arm32/src/drivers/gxemul.c
File deleted
/trunk/uspace/srv/kbd/ctl/pl050.c
0,0 → 1,262
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief PL050 keyboard controller driver.
*/
 
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
#include <kbd_ctl.h>
#include <gsp.h>
#include <stdio.h>
 
#define PL050_CAPS_SCAN_CODE 0x58
#define PL050_NUM_SCAN_CODE 0x77
#define PL050_SCROLL_SCAN_CODE 0x7E
 
static bool is_lock_key(int);
enum dec_state {
ds_s,
ds_e
};
 
static enum dec_state ds;
 
static int scanmap_simple[] = {
 
[0x0e] = KC_BACKTICK,
 
[0x16] = KC_1,
[0x1e] = KC_2,
[0x26] = KC_3,
[0x25] = KC_4,
[0x2e] = KC_5,
[0x36] = KC_6,
[0x3d] = KC_7,
[0x3e] = KC_8,
[0x46] = KC_9,
[0x45] = KC_0,
 
[0x4e] = KC_MINUS,
[0x55] = KC_EQUALS,
[0x66] = KC_BACKSPACE,
 
[0x0d] = KC_TAB,
 
[0x15] = KC_Q,
[0x1d] = KC_W,
[0x24] = KC_E,
[0x2d] = KC_R,
[0x2c] = KC_T,
[0x35] = KC_Y,
[0x3c] = KC_U,
[0x43] = KC_I,
[0x44] = KC_O,
[0x4d] = KC_P,
 
[0x54] = KC_LBRACKET,
[0x5b] = KC_RBRACKET,
 
[0x58] = KC_CAPS_LOCK,
 
[0x1c] = KC_A,
[0x1b] = KC_S,
[0x23] = KC_D,
[0x2b] = KC_F,
[0x34] = KC_G,
[0x33] = KC_H,
[0x3b] = KC_J,
[0x42] = KC_K,
[0x4b] = KC_L,
 
[0x4c] = KC_SEMICOLON,
[0x52] = KC_QUOTE,
[0x5d] = KC_BACKSLASH,
 
[0x12] = KC_LSHIFT,
 
[0x1a] = KC_Z,
[0x22] = KC_X,
[0x21] = KC_C,
[0x2a] = KC_V,
[0x32] = KC_B,
[0x31] = KC_N,
[0x3a] = KC_M,
 
[0x41] = KC_COMMA,
[0x49] = KC_PERIOD,
[0x4a] = KC_SLASH,
 
[0x59] = KC_RSHIFT,
 
[0x14] = KC_LCTRL,
[0x11] = KC_LALT,
[0x29] = KC_SPACE,
 
[0x76] = KC_ESCAPE,
 
[0x05] = KC_F1,
[0x06] = KC_F2,
[0x04] = KC_F3,
[0x0c] = KC_F4,
[0x03] = KC_F5,
[0x0b] = KC_F6,
[0x02] = KC_F7,
 
[0x0a] = KC_F8,
[0x01] = KC_F9,
[0x09] = KC_F10,
 
[0x78] = KC_F11,
[0x07] = KC_F12,
 
[0x60] = KC_SCROLL_LOCK,
 
[0x5a] = KC_ENTER,
 
[0x77] = KC_NUM_LOCK,
[0x7c] = KC_NTIMES,
[0x7b] = KC_NMINUS,
[0x79] = KC_NPLUS,
[0x6c] = KC_N7,
[0x75] = KC_N8,
[0x7d] = KC_N9,
[0x6b] = KC_N4,
[0x73] = KC_N5,
[0x74] = KC_N6,
[0x69] = KC_N1,
[0x72] = KC_N2,
[0x7a] = KC_N3,
[0x70] = KC_N0,
[0x71] = KC_NPERIOD
};
 
static int scanmap_e0[] = {
[0x65] = KC_RALT,
[0x59] = KC_RSHIFT,
 
[0x64] = KC_PRTSCR,
 
[0x70] = KC_INSERT,
[0x6c] = KC_HOME,
[0x7d] = KC_PAGE_UP,
 
[0x71] = KC_DELETE,
[0x69] = KC_END,
[0x7a] = KC_PAGE_DOWN,
 
[0x75] = KC_UP,
[0x6b] = KC_LEFT,
[0x72] = KC_DOWN,
[0x74] = KC_RIGHT,
 
[0x4a] = KC_NSLASH,
[0x5a] = KC_NENTER
};
 
int kbd_ctl_init(void)
{
ds = ds_s;
return 0;
}
 
void kbd_ctl_parse_scancode(int scancode)
{
static int key_release_flag = 0;
static int is_locked = 0;
console_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;
default:
map = NULL;
map_length = 0;
}
 
ds = ds_s;
if (scancode == 0xf0) {
key_release_flag = 1;
return;
} else {
if (key_release_flag) {
type = KEY_RELEASE;
key_release_flag = 0;
if (is_lock_key(scancode)) {
if (!is_locked) {
is_locked = 1;
} else {
is_locked = 0;
return;
}
}
} else {
if (is_lock_key(scancode) && is_locked)
return;
type = KEY_PRESS;
}
}
 
if (scancode < 0)
return;
 
key = map[scancode];
if (key != 0)
kbd_push_ev(type, key);
}
 
static bool is_lock_key(int sc)
{
return ((sc == PL050_CAPS_SCAN_CODE) || (sc == PL050_NUM_SCAN_CODE) ||
(sc == PL050_SCROLL_SCAN_CODE));
}
 
/**
* @}
*/
/trunk/uspace/srv/kbd/port/pl050.c
0,0 → 1,114
/*
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief pl050 port driver.
*/
 
#include <ddi.h>
#include <libarch/ddi.h>
#include <ipc/ipc.h>
#include <async.h>
#include <unistd.h>
#include <sysinfo.h>
#include <kbd_port.h>
#include <kbd.h>
#include <ddi.h>
#include <stdio.h>
 
#define PL050_STAT_RXFULL (1 << 4)
static irq_cmd_t pl050_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = NULL,
.dstarg = 1
},
{
.cmd = CMD_BTEST,
.value = PL050_STAT_RXFULL,
.srcarg = 1,
.dstarg = 3
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.srcarg = 3
},
{
.cmd = CMD_PIO_READ_8,
.addr = NULL, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
 
static irq_code_t pl050_kbd = {
sizeof(pl050_cmds) / sizeof(irq_cmd_t),
pl050_cmds
};
 
static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
{
 
pl050_kbd.cmds[0].addr = (void *) sysinfo_value("kbd.address.status");
pl050_kbd.cmds[3].addr = (void *) sysinfo_value("kbd.address.data");
 
async_set_interrupt_received(pl050_irq_handler);
 
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(), 0, &pl050_kbd);
 
return 0;
}
 
void kbd_port_yield(void)
{
}
 
void kbd_port_reclaim(void)
{
}
 
static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
 
kbd_push_scancode(scan_code);
return;
}
 
/**
* @}
*/
/trunk/uspace/srv/kbd/Makefile
61,6 → 61,7
endif
 
ifeq ($(UARCH), arm32)
ifeq ($(MACHINE), testarm)
GENARCH_SOURCES += \
port/gxemul.c
72,6 → 73,12
ctl/stty.c
endif
endif
ifeq ($(MACHINE), integratorcp)
GENARCH_SOURCES += \
port/pl050.c \
ctl/pl050.c
endif
endif
 
ifeq ($(UARCH), ia32)
GENARCH_SOURCES += \
/trunk/uspace/srv/fb/fb.c
250,7 → 250,17
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
}
 
static void rgb_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst)
= (RED(rgb, 8) << 24) | (GREEN(rgb, 8) << 16) | BLUE(rgb, 8) << 8;
}
 
static void mask_8880(void *dst, bool mask)
{
*((uint32_t *) dst) = (mask ? 0xffffff00 : 0);
}
 
/** RGB 8:8:8 conversion
*
*/
650,8 → 660,8
screen.pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
screen.rgb_conv = rgb_888;
screen.mask_conv = mask_888;
screen.rgb_conv = rgb_8880;
screen.mask_conv = mask_8880;
screen.pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
1744,17 → 1754,17
unsigned int fb_height = sysinfo_value("fb.height");
unsigned int fb_scanline = sysinfo_value("fb.scanline");
unsigned int fb_visual = sysinfo_value("fb.visual");
 
unsigned int fbsize = fb_scanline * fb_height;
void *fb_addr = as_get_mappable_page(fbsize);
 
if (physmem_map(fb_ph_addr + fb_offset, fb_addr,
ALIGN_UP(fbsize, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0)
return -1;
 
if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual))
return 0;
 
return -1;
}
 
/trunk/HelenOS.config
55,6 → 55,11
@ "serengeti" Serengeti system
! [PLATFORM=sparc64] MACHINE (choice)
 
% Machine type
@ "testarm" Gxemul Testarm
@ "integratorcp" Integratorcp
! [PLATFORM=arm32] MACHINE (choice)
 
% CPU type
@ "pentium4" Pentium 4
@ "pentium3" Pentium 3
325,8 → 330,12
 
% Input device class
@ "generic" Keyboard or serial line
! [PLATFORM=arm32&MACHINE=integratorcp] CONFIG_HID_IN (choice)
 
% Input device class
@ "generic" Keyboard or serial line
@ "none" No input device
! [PLATFORM=ia32|PLATFORM=arm32|PLATFORM=amd64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_HID_IN (choice)
! [PLATFORM=ia32|(PLATFORM=arm32&MACHINE=testarm)|PLATFORM=amd64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_HID_IN (choice)
 
% Input device class
@ "generic" Keyboard or serial line
337,6 → 346,10
 
% Output device class
@ "generic" Monitor or serial line
! [PLATFORM=arm32&MACHINE=integratorcp] CONFIG_HID_OUT (choice)
 
% Output device class
@ "generic" Monitor or serial line
@ "none" No output device
! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ppc32|(PLATFORM=ia64&MACHINE=i460GX)|(PLATFORM=mips32&MACHINE=msim)] CONFIG_HID_OUT (choice)
 
352,7 → 365,7
@ "monitor" Monitor
@ "serial" Serial line
@ "none" No output device
! [PLATFORM=arm32] CONFIG_HID_OUT (choice)
! [PLATFORM=arm32&MACHINE=testarm] CONFIG_HID_OUT (choice)
 
% PC keyboard support
! [CONFIG_HID_IN=generic&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_PC_KBD (y/n)
367,10 → 380,10
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=mips32] CONFIG_MIPS_PRN (y/n)
 
% Support for GXemul keyboard
! [CONFIG_HID_IN=generic&PLATFORM=arm32] CONFIG_ARM_KBD (y/n)
! [CONFIG_HID_IN=generic&PLATFORM=arm32&MACHINE=testarm] CONFIG_ARM_KBD (y/n)
 
% Support for GXemul printer
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32] CONFIG_ARM_PRN (y/n)
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&MACHINE=testarm] CONFIG_ARM_PRN (y/n)
 
% Support for VIA CUDA controller
! [CONFIG_HID_IN=generic&PLATFORM=ppc32] CONFIG_VIA_CUDA (y/n)
393,6 → 406,9
% i8042 controller support
! [CONFIG_PC_KBD=y] CONFIG_I8042 (y)
 
% pl050 controller support
! [CONFIG_HID_IN=generic&PLATFORM=arm32&MACHINE=integratorcp] CONFIG_PL050 (y)
 
% Sun keyboard support
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic&(CONFIG_NS16550=y|CONFIG_Z8530=y)] CONFIG_SUN_KBD (y)
 
/trunk/boot/arch/arm32/Makefile.inc
35,7 → 35,7
-rm arch/$(BARCH)/loader/image.boot
 
arch/$(BARCH)/loader/image.boot:
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) MACHINE=$(MACHINE)
 
clean:
make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
/trunk/boot/arch/arm32/loader/_link.ld.in
17,6 → 17,9
*(COMMON); /* global variables */
*(.reginfo);
 
. = 0x2000;
*(ST); /* bootloader stack section */
 
. = 0x4000;
*(PT); /* page table placed at 0x4000 */
[[COMPONENTS]]
/trunk/boot/arch/arm32/loader/boot.S
34,8 → 34,10
.global start
.global jump_to_kernel
.global page_table
.global boot_stack
 
start:
ldr sp, =boot_stack
b bootstrap
 
jump_to_kernel:
46,6 → 48,10
#
bx r0
 
#bootloader stack
.section ST
.space 4096
boot_stack:
 
# place page_table to PT section
.section PT
/trunk/boot/arch/arm32/loader/main.c
67,7 → 67,7
/** Prints bootloader version information. */
static void version_print(void)
{
printf("HelenOS ARM32 Bootloader\nRelease %s%s%s\nCopyright (c) 2007 HelenOS project\n",
printf("HelenOS ARM32 Bootloader\nRelease %s%s%s\nCopyright (c) 2009 HelenOS project\n",
release, revision, timestamp);
}
 
91,8 → 91,6
bootinfo.cnt = 0;
unsigned int i, j;
for (i = 0; i < COMPONENTS; i++) {
printf(" %L: %s image (size %d bytes)\n",
components[i].start, components[i].name, components[i].size);
top = ALIGN_UP(top, KERNEL_PAGE_SIZE);
if (i > 0) {
bootinfo.tasks[bootinfo.cnt].addr = ((void *) KERNEL_VIRTUAL_ADDRESS) + top;
106,18 → 104,17
j = bootinfo.cnt - 1;
 
printf("\nCopying components\n");
 
printf("Component\tAddress\t\tSize (Bytes)\n");
printf("============================================\n");
for (i = COMPONENTS - 1; i > 0; i--, j--) {
printf(" %s...", components[i].name);
printf("%s\t\t0x%x\t%d\n", components[i].name, bootinfo.tasks[j].addr, components[i].size);
memcpy((void *)bootinfo.tasks[j].addr, components[i].start,
components[i].size);
printf("done.\n");
}
printf("\nCopying kernel...");
printf("KERNEL\t\t0x%x\t%d\n", KERNEL_VIRTUAL_ADDRESS, components[0].size);
 
memcpy((void *)KERNEL_VIRTUAL_ADDRESS, components[0].start,
components[0].size);
printf("done.\n");
 
printf("\nBooting the kernel...\n");
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo);
/trunk/boot/arch/arm32/loader/print/gxemul.c
File deleted
/trunk/boot/arch/arm32/loader/print/print.c
0,0 → 1,79
/*
* Copyright (c) 2007 Michal Kebrt
* Copyright (c) 2009 Vineeth Pillai
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
 
/** @addtogroup arm32boot
* @{
*/
/** @file
* @brief bootloader output logic
*/
 
 
#include <printf.h>
 
 
/** Address where characters to be printed are expected. */
#ifdef MACHINE_GXEMUL_TESTARM
#define PUTC_ADDRESS 0x10000000
#endif
#ifdef MACHINE_ICP
#define PUTC_ADDRESS 0x16000000
#endif
 
 
 
/** Prints a character to the console.
*
* @param ch Character to be printed.
*/
static void putc(char ch)
{
if (ch == '\n')
*((volatile char *) PUTC_ADDRESS) = '\r';
*((volatile char *) PUTC_ADDRESS) = ch;
}
 
 
/** Prints a string to the console.
*
* @param str String to be printed.
* @param len Number of characters to be printed.
*/
void write(const char *str, const int len)
{
int i;
for (i = 0; i < len; ++i) {
putc(str[i]);
}
}
 
/** @}
*/
 
Property changes:
Added: svn:mergeinfo
/trunk/boot/arch/arm32/loader/Makefile
41,6 → 41,15
TARGET = arm-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin
 
ifeq ($(MACHINE), testarm)
DMACHINE = MACHINE_GXEMUL_TESTARM
endif
 
ifeq ($(MACHINE), integratorcp)
DMACHINE = MACHINE_ICP
endif
 
 
ifeq ($(COMPILER),gcc_native)
CC = gcc
AS = as
64,7 → 73,7
boot.S \
asm.S \
mm.c \
print/gxemul.c \
print/print.c \
_components.c \
../../../generic/printf.c \
../../../generic/string.c \
92,8 → 101,11
$(USPACEDIR)/srv/fs/devfs/devfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/bd/file_bd/file_bd \
$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
$(USPACEDIR)/srv/bd/file_bd/file_bd
ifeq ($(MACHINE), testarm)
RD_SRVS += \
$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
endif
 
RD_APPS = \
$(USPACEDIR)/app/getvc/getvc \
148,4 → 160,4
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
$(CC) -D$(DMACHINE) $(DEFS) $(CFLAGS) -c $< -o $@