Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4717 → Rev 4718

/branches/network/kernel/genarch/include/kbrd/scanc_mac.h
0,0 → 1,48
/*
* Copyright (c) 2009 Jiri Svoboda
* 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 Macintosh ADB keyboards.
*/
 
#ifndef KERN_SCANC_MAC_H_
#define KERN_SCANC_MAC_H_
 
#define SC_LSHIFT 0x38
#define SC_RSHIFT 0xfd /* Not used */
#define SC_CAPSLOCK 0xfe /* Not used */
#define SC_SCAN_ESCAPE 0xff /* Not used */
 
#endif
 
/** @}
*/
/branches/network/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
 
/** @}
*/
/branches/network/kernel/genarch/include/fb/visuals.h
35,17 → 35,20
#ifndef KERN_VISUALS_H_
#define KERN_VISUALS_H_
 
#define VISUAL_INDIRECT_8 0
typedef enum {
VISUAL_INDIRECT_8,
VISUAL_RGB_5_5_5_LE,
VISUAL_RGB_5_5_5_BE,
VISUAL_RGB_5_6_5_LE,
VISUAL_RGB_5_6_5_BE,
VISUAL_BGR_8_8_8,
VISUAL_BGR_0_8_8_8,
VISUAL_BGR_8_8_8_0,
VISUAL_RGB_8_8_8,
VISUAL_RGB_0_8_8_8,
VISUAL_RGB_8_8_8_0
} visual_t;
 
#define VISUAL_RGB_5_5_5 1
#define VISUAL_RGB_5_6_5 2
#define VISUAL_RGB_8_8_8 3
#define VISUAL_RGB_8_8_8_0 4
#define VISUAL_RGB_0_8_8_8 5
 
#define VISUAL_BGR_0_8_8_8 6
#define VISUAL_BGR_8_8_8 7
 
#endif
 
/** @}
/branches/network/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
 
/** @}
*/
/branches/network/kernel/genarch/include/drivers/via-cuda/cuda.h
38,14 → 38,80
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <synch/spinlock.h>
 
typedef struct {
uint8_t b;
uint8_t pad0[0x1ff];
 
uint8_t a;
uint8_t pad1[0x1ff];
 
uint8_t dirb;
uint8_t pad2[0x1ff];
 
uint8_t dira;
uint8_t pad3[0x1ff];
 
uint8_t t1cl;
uint8_t pad4[0x1ff];
 
uint8_t t1ch;
uint8_t pad5[0x1ff];
 
uint8_t t1ll;
uint8_t pad6[0x1ff];
 
uint8_t t1lh;
uint8_t pad7[0x1ff];
 
uint8_t t2cl;
uint8_t pad8[0x1ff];
 
uint8_t t2ch;
uint8_t pad9[0x1ff];
 
uint8_t sr;
uint8_t pad10[0x1ff];
 
uint8_t acr;
uint8_t pad11[0x1ff];
 
uint8_t pcr;
uint8_t pad12[0x1ff];
 
uint8_t ifr;
uint8_t pad13[0x1ff];
 
uint8_t ier;
uint8_t pad14[0x1ff];
 
uint8_t anh;
uint8_t pad15[0x1ff];
} cuda_t;
 
enum {
CUDA_RCV_BUF_SIZE = 5
};
 
enum cuda_xfer_state {
cx_listen,
cx_receive,
cx_rcv_end,
cx_send_start,
cx_send
};
 
typedef struct {
irq_t irq;
cuda_t *cuda;
indev_t *kbrdin;
uint8_t rcv_buf[CUDA_RCV_BUF_SIZE];
uint8_t snd_buf[CUDA_RCV_BUF_SIZE];
size_t bidx;
size_t snd_bytes;
enum cuda_xfer_state xstate;
SPINLOCK_DECLARE(dev_lock);
} cuda_instance_t;
 
extern cuda_instance_t *cuda_init(cuda_t *, inr_t, cir_t, void *);
/branches/network/kernel/genarch/Makefile.inc
110,6 → 110,18
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 \
genarch/src/kbrd/scanc_mac.c
endif
 
ifeq ($(CONFIG_SRLN),y)
GENARCH_SOURCES += \
genarch/src/srln/srln.c
/branches/network/kernel/genarch/src/kbrd/kbrd.c
45,6 → 45,10
#include <genarch/kbrd/scanc_sun.h>
#endif
 
#ifdef CONFIG_MAC_KBD
#include <genarch/kbrd/scanc_mac.h>
#endif
 
#include <synch/spinlock.h>
#include <console/chardev.h>
#include <console/console.h>
/branches/network/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));
}
 
/** @}
*/
/branches/network/kernel/genarch/src/kbrd/scanc_mac.c
0,0 → 1,306
/*
* Copyright (c) 2009 Jiri Svoboda
* 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 Macintosh ADB keyboards.
*/
 
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[SCANCODES] = {
[0x00] = 'a',
[0x01] = 's',
[0x02] = 'd',
[0x03] = 'f',
[0x04] = 'h',
[0x05] = 'g',
[0x06] = 'z',
[0x07] = 'x',
[0x08] = 'c',
[0x09] = 'v',
[0x0a] = U_SPECIAL,
[0x0b] = 'b',
[0x0c] = 'q',
[0x0d] = 'w',
[0x0e] = 'e',
[0x0f] = 'r',
[0x10] = 'y',
[0x11] = 't',
[0x12] = '1',
[0x13] = '2',
[0x14] = '3',
[0x15] = '4',
[0x16] = '6',
[0x17] = '5',
[0x18] = '=',
[0x19] = '9',
[0x1a] = '7',
[0x1b] = '-',
[0x1c] = '8',
[0x1d] = '0',
[0x1e] = ']',
[0x1f] = 'o',
[0x20] = 'u',
[0x21] = '[',
[0x22] = 'i',
[0x23] = 'p',
[0x24] = '\n', /* Enter */
[0x25] = 'l',
[0x26] = 'j',
[0x27] = '\'',
[0x28] = 'k',
[0x29] = ';',
[0x2a] = '\\',
[0x2b] = ',',
[0x2c] = '/',
[0x2d] = 'n',
[0x2e] = 'm',
[0x2f] = '.',
[0x30] = '\t', /* Tab */
[0x31] = ' ', /* Space */
[0x32] = '`',
[0x33] = '\b', /* Backspace */
[0x34] = U_SPECIAL,
[0x35] = U_ESCAPE,
[0x36] = U_SPECIAL,
[0x37] = U_SPECIAL,
[0x38] = U_SPECIAL,
[0x39] = U_SPECIAL,
[0x3a] = U_SPECIAL,
[0x3b] = U_LEFT_ARROW,
[0x3c] = U_RIGHT_ARROW,
[0x3d] = U_DOWN_ARROW,
[0x3e] = U_UP_ARROW,
[0x3f] = U_SPECIAL,
[0x40] = U_SPECIAL,
[0x41] = '.', /* Num Separator */
[0x42] = U_SPECIAL,
[0x43] = '*', /* Num Times */
[0x44] = U_SPECIAL,
[0x45] = '+', /* Num Plus */
[0x46] = U_SPECIAL,
[0x47] = U_SPECIAL,
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_SPECIAL,
[0x4b] = '/', /* Num Divide */
[0x4c] = U_SPECIAL,
[0x4d] = U_SPECIAL,
[0x4e] = '-', /* Num Minus */
[0x4f] = U_SPECIAL,
[0x50] = U_SPECIAL,
[0x51] = U_SPECIAL,
[0x52] = '0', /* Num Zero */
[0x53] = '1', /* Num One */
[0x54] = '2', /* Num Two */
[0x55] = '3', /* Num Three */
[0x56] = '4', /* Num Four */
[0x57] = '5', /* Num Five */
[0x58] = '6', /* Num Six */
[0x59] = '7', /* Num Seven */
[0x5a] = U_SPECIAL,
[0x5b] = '8', /* Num Eight */
[0x5c] = '9', /* Num Nine */
[0x5d] = U_SPECIAL,
[0x5e] = U_SPECIAL,
[0x5f] = U_SPECIAL,
[0x60] = U_SPECIAL,
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL,
[0x63] = U_SPECIAL,
[0x64] = U_SPECIAL,
[0x65] = U_SPECIAL,
[0x66] = U_SPECIAL,
[0x67] = U_SPECIAL,
[0x68] = U_SPECIAL,
[0x69] = U_SPECIAL,
[0x6a] = U_SPECIAL,
[0x6b] = U_SPECIAL,
[0x6c] = U_SPECIAL,
[0x6d] = U_SPECIAL,
[0x6e] = U_SPECIAL,
[0x6f] = U_SPECIAL,
[0x70] = U_SPECIAL,
[0x71] = U_SPECIAL,
[0x72] = U_SPECIAL,
[0x73] = U_HOME_ARROW,
[0x74] = U_PAGE_UP,
[0x75] = U_DELETE,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL,
[0x78] = U_SPECIAL,
[0x79] = U_PAGE_DOWN,
[0x7a] = U_SPECIAL,
[0x7b] = U_SPECIAL,
[0x7c] = U_SPECIAL,
[0x7d] = U_SPECIAL,
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[SCANCODES] = {
[0x00] = 'A',
[0x01] = 'S',
[0x02] = 'D',
[0x03] = 'F',
[0x04] = 'H',
[0x05] = 'G',
[0x06] = 'Z',
[0x07] = 'X',
[0x08] = 'C',
[0x09] = 'V',
[0x0a] = U_SPECIAL,
[0x0b] = 'B',
[0x0c] = 'Q',
[0x0d] = 'W',
[0x0e] = 'E',
[0x0f] = 'R',
[0x10] = 'Y',
[0x11] = 'T',
[0x12] = '!',
[0x13] = '@',
[0x14] = '#',
[0x15] = '$',
[0x16] = '^',
[0x17] = '%',
[0x18] = '+',
[0x19] = '(',
[0x1a] = '&',
[0x1b] = '_',
[0x1c] = '*',
[0x1d] = ')',
[0x1e] = '}',
[0x1f] = 'O',
[0x20] = 'U',
[0x21] = '{',
[0x22] = 'I',
[0x23] = 'P',
[0x24] = '\n', /* Enter */
[0x25] = 'L',
[0x26] = 'J',
[0x27] = '"',
[0x28] = 'K',
[0x29] = ':',
[0x2a] = '|',
[0x2b] = '<',
[0x2c] = '?',
[0x2d] = 'N',
[0x2e] = 'M',
[0x2f] = '>',
[0x30] = '\t', /* Tab */
[0x31] = ' ', /* Space */
[0x32] = '~',
[0x33] = '\b', /* Backspace */
[0x34] = U_SPECIAL,
[0x35] = U_SPECIAL,
[0x36] = U_SPECIAL,
[0x37] = U_SPECIAL,
[0x38] = U_SPECIAL,
[0x39] = U_SPECIAL,
[0x3a] = U_SPECIAL,
[0x3b] = U_SPECIAL,
[0x3c] = U_SPECIAL,
[0x3d] = U_SPECIAL,
[0x3e] = U_SPECIAL,
[0x3f] = U_SPECIAL,
[0x40] = U_SPECIAL,
[0x41] = '.', /* Num Separator */
[0x42] = U_SPECIAL,
[0x43] = '*', /* Num Times */
[0x44] = U_SPECIAL,
[0x45] = '+', /* Num Plus */
[0x46] = U_SPECIAL,
[0x47] = U_SPECIAL,
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_SPECIAL,
[0x4b] = '/', /* Num Divide */
[0x4c] = U_SPECIAL,
[0x4d] = U_SPECIAL,
[0x4e] = '-', /* Num Minus */
[0x4f] = U_SPECIAL,
[0x50] = U_SPECIAL,
[0x51] = U_SPECIAL,
[0x52] = '0', /* Num Zero */
[0x53] = '1', /* Num One */
[0x54] = '2', /* Num Two */
[0x55] = '3', /* Num Three */
[0x56] = '4', /* Num Four */
[0x57] = '5', /* Num Five */
[0x58] = '6', /* Num Six */
[0x59] = '7', /* Num Seven */
[0x5a] = U_SPECIAL,
[0x5b] = '8', /* Num Eight */
[0x5c] = '9', /* Num Nine */
[0x5d] = U_SPECIAL,
[0x5e] = U_SPECIAL,
[0x5f] = U_SPECIAL,
[0x60] = U_SPECIAL,
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL,
[0x63] = U_SPECIAL,
[0x64] = U_SPECIAL,
[0x65] = U_SPECIAL,
[0x66] = U_SPECIAL,
[0x67] = U_SPECIAL,
[0x68] = U_SPECIAL,
[0x69] = U_SPECIAL,
[0x6a] = U_SPECIAL,
[0x6b] = U_SPECIAL,
[0x6c] = U_SPECIAL,
[0x6d] = U_SPECIAL,
[0x6e] = U_SPECIAL,
[0x6f] = U_SPECIAL,
[0x70] = U_SPECIAL,
[0x71] = U_SPECIAL,
[0x72] = U_SPECIAL,
[0x73] = U_SPECIAL,
[0x74] = U_SPECIAL,
[0x75] = U_SPECIAL,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL,
[0x78] = U_SPECIAL,
[0x79] = U_SPECIAL,
[0x7a] = U_SPECIAL,
[0x7b] = U_SPECIAL,
[0x7c] = U_SPECIAL,
[0x7d] = U_SPECIAL,
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** @}
*/
/branches/network/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 */
};
 
/** @}
*/
/branches/network/kernel/genarch/src/fb/fb.c
50,6 → 50,7
#include <string.h>
#include <ddi/ddi.h>
#include <arch/types.h>
#include <byteorder.h>
 
SPINLOCK_INITIALIZE(fb_lock);
 
80,9 → 81,9
#define FG_COLOR 0xffff00
#define INV_COLOR 0xaaaaaa
 
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
#define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
#define GREEN(x, bits) (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
#define BLUE(x, bits) (((x) >> (8 - (bits))) & ((1 << (bits)) - 1))
 
#define COL2X(col) ((col) * FONT_WIDTH)
#define ROW2Y(row) ((row) * FONT_SCANLINES)
97,69 → 98,79
 
static void (*rgb_conv)(void *, uint32_t);
 
 
/** ARGB 8:8:8:8 conversion
/*
* RGB conversion functions.
*
* These functions write an RGB value to some memory in some predefined format.
* The naming convention corresponds to the format created by these functions.
* The functions use the so called network order (i.e. big endian) with respect
* to their names.
*/
 
static void rgb_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = rgb & 0xffffff;
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) |
(RED(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (BLUE(rgb, 8)));
}
 
 
/** ABGR 8:8:8:8 conversion
*
*/
static void bgr_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst)
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) |
(BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (RED(rgb, 8)));
}
 
static void rgb_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = host2uint32_t_be((RED(rgb, 8) << 24) |
(GREEN(rgb, 8) << 16) | (BLUE(rgb, 8) << 8) | 0);
}
 
/** RGB 8:8:8 conversion
*
*/
static void bgr_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = host2uint32_t_be((BLUE(rgb, 8) << 24) |
(GREEN(rgb, 8) << 16) | (RED(rgb, 8) << 8) | 0);
}
 
static void rgb_888(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = BLUE(rgb, 8);
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = RED(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
}
 
 
/** BGR 8:8:8 conversion
*
*/
static void bgr_888(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[0] = BLUE(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
((uint8_t *) dst)[2] = RED(rgb, 8);
}
 
static void rgb_555_be(void *dst, uint32_t rgb)
{
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 10 |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5));
}
 
/** RGB 5:5:5 conversion
*
*/
static void rgb_555(void *dst, uint32_t rgb)
static void rgb_555_le(void *dst, uint32_t rgb)
{
*((uint16_t *) dst)
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 10 |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5));
}
 
static void rgb_565_be(void *dst, uint32_t rgb)
{
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 11 |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
}
 
/** RGB 5:6:5 conversion
*
*/
static void rgb_565(void *dst, uint32_t rgb)
static void rgb_565_le(void *dst, uint32_t rgb)
{
*((uint16_t *) dst)
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 11 |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
}
 
 
/** RGB 3:2:3
/** BGR 3:2:3
*
* Even though we try 3:2:3 color scheme here, an 8-bit framebuffer
* will most likely use a color palette. The color appearance
176,7 → 187,7
* 0 and 255 to other colors.
*
*/
static void rgb_323(void *dst, uint32_t rgb)
static void bgr_323(void *dst, uint32_t rgb)
{
*((uint8_t *) dst)
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
450,17 → 461,25
{
switch (props->visual) {
case VISUAL_INDIRECT_8:
rgb_conv = rgb_323;
rgb_conv = bgr_323;
pixelbytes = 1;
break;
case VISUAL_RGB_5_5_5:
rgb_conv = rgb_555;
case VISUAL_RGB_5_5_5_LE:
rgb_conv = rgb_555_le;
pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5:
rgb_conv = rgb_565;
case VISUAL_RGB_5_5_5_BE:
rgb_conv = rgb_555_be;
pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5_LE:
rgb_conv = rgb_565_le;
pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5_BE:
rgb_conv = rgb_565_be;
pixelbytes = 2;
break;
case VISUAL_RGB_8_8_8:
rgb_conv = rgb_888;
pixelbytes = 3;
470,7 → 489,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:
481,6 → 500,10
rgb_conv = bgr_0888;
pixelbytes = 4;
break;
case VISUAL_BGR_8_8_8_0:
rgb_conv = bgr_8880;
pixelbytes = 4;
break;
default:
panic("Unsupported visual.");
}
/branches/network/kernel/genarch/src/mm/page_ht.c
192,6 → 192,8
t->k = !(flags & PAGE_USER);
t->c = (flags & PAGE_CACHEABLE) != 0;
t->p = !(flags & PAGE_NOT_PRESENT);
t->a = false;
t->d = false;
 
t->as = as;
t->page = ALIGN_DOWN(page, PAGE_SIZE);
/branches/network/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);
}
 
 
/** @}
*/
/branches/network/kernel/genarch/src/drivers/via-cuda/cuda.c
1,5 → 1,6
/*
* Copyright (c) 2006 Martin Decky
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
38,16 → 39,53
#include <arch/asm.h>
#include <mm/slab.h>
#include <ddi/device.h>
#include <synch/spinlock.h>
 
static irq_ownership_t cuda_claim(irq_t *irq)
{
return IRQ_DECLINE;
}
static irq_ownership_t cuda_claim(irq_t *irq);
static void cuda_irq_handler(irq_t *irq);
 
static void cuda_irq_handler(irq_t *irq)
{
}
static void cuda_irq_listen(irq_t *irq);
static void cuda_irq_receive(irq_t *irq);
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len);
static void cuda_irq_send_start(irq_t *irq);
static void cuda_irq_send(irq_t *irq);
 
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *buf, size_t len);
static void cuda_send_start(cuda_instance_t *instance);
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable);
 
/** B register fields */
enum {
TREQ = 0x08,
TACK = 0x10,
TIP = 0x20
};
 
/** IER register fields */
enum {
IER_CLR = 0x00,
IER_SET = 0x80,
 
SR_INT = 0x04,
ALL_INT = 0x7f
};
 
/** ACR register fields */
enum {
SR_OUT = 0x10
};
 
/** Packet types */
enum {
PT_ADB = 0x00,
PT_CUDA = 0x01
};
 
/** CUDA packet types */
enum {
CPT_AUTOPOLL = 0x01
};
 
cuda_instance_t *cuda_init(cuda_t *dev, inr_t inr, cir_t cir, void *cir_arg)
{
cuda_instance_t *instance
55,7 → 93,15
if (instance) {
instance->cuda = dev;
instance->kbrdin = NULL;
instance->xstate = cx_listen;
instance->bidx = 0;
instance->snd_bytes = 0;
 
spinlock_initialize(&instance->dev_lock, "cuda_dev");
 
/* Disable all interrupts from CUDA. */
pio_write_8(&dev->ier, IER_CLR | ALL_INT);
 
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
64,15 → 110,251
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
instance->irq.preack = true;
}
return instance;
}
 
#include <print.h>
void cuda_wire(cuda_instance_t *instance, indev_t *kbrdin)
{
cuda_t *dev = instance->cuda;
 
ASSERT(instance);
ASSERT(kbrdin);
 
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
 
/* Enable SR interrupt. */
pio_write_8(&dev->ier, TIP | TREQ);
pio_write_8(&dev->ier, IER_SET | SR_INT);
 
/* Enable ADB autopolling. */
cuda_autopoll_set(instance, true);
}
 
static irq_ownership_t cuda_claim(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t ifr;
 
spinlock_lock(&instance->dev_lock);
ifr = pio_read_8(&dev->ifr);
spinlock_unlock(&instance->dev_lock);
 
if ((ifr & SR_INT) == 0)
return IRQ_DECLINE;
 
return IRQ_ACCEPT;
}
 
static void cuda_irq_handler(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
uint8_t rbuf[CUDA_RCV_BUF_SIZE];
size_t len;
bool handle;
 
handle = false;
len = 0;
 
spinlock_lock(&instance->dev_lock);
 
/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
pio_write_8(&instance->cuda->ifr, SR_INT);
 
switch (instance->xstate) {
case cx_listen: cuda_irq_listen(irq); break;
case cx_receive: cuda_irq_receive(irq); break;
case cx_rcv_end: cuda_irq_rcv_end(irq, rbuf, &len);
handle = true; break;
case cx_send_start: cuda_irq_send_start(irq); break;
case cx_send: cuda_irq_send(irq); break;
}
 
spinlock_unlock(&instance->dev_lock);
 
/* Handle an incoming packet. */
if (handle)
cuda_packet_handle(instance, rbuf, len);
}
 
/** Interrupt in listen state.
*
* Start packet reception.
*/
static void cuda_irq_listen(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) != 0) {
printf("cuda_irq_listen: no TREQ?!\n");
return;
}
 
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
instance->xstate = cx_receive;
}
 
/** Interrupt in receive state.
*
* Receive next byte of packet.
*/
static void cuda_irq_receive(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b, data;
 
data = pio_read_8(&dev->sr);
if (instance->bidx < CUDA_RCV_BUF_SIZE)
instance->rcv_buf[instance->bidx++] = data;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) == 0) {
pio_write_8(&dev->b, b ^ TACK);
} else {
pio_write_8(&dev->b, b | TACK | TIP);
instance->xstate = cx_rcv_end;
}
}
 
/** Interrupt in rcv_end state.
*
* Terminate packet reception. Either go back to listen state or start
* receiving another packet if CUDA has one for us.
*/
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t data, b;
 
b = pio_read_8(&dev->b);
data = pio_read_8(&dev->sr);
 
if ((b & TREQ) == 0) {
instance->xstate = cx_receive;
pio_write_8(&dev->b, b & ~TIP);
} else {
instance->xstate = cx_listen;
cuda_send_start(instance);
}
 
memcpy(buf, instance->rcv_buf, instance->bidx);
*len = instance->bidx;
instance->bidx = 0;
}
 
/** Interrupt in send_start state.
*
* Process result of sending first byte (and send second on success).
*/
static void cuda_irq_send_start(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) == 0) {
/* Collision */
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) | TIP | TACK);
instance->xstate = cx_listen;
return;
}
 
pio_write_8(&dev->sr, instance->snd_buf[1]);
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
instance->bidx = 2;
 
instance->xstate = cx_send;
}
 
/** Interrupt in send state.
*
* Send next byte or terminate transmission.
*/
static void cuda_irq_send(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
 
if (instance->bidx < instance->snd_bytes) {
/* Send next byte. */
pio_write_8(&dev->sr, instance->snd_buf[instance->bidx++]);
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
return;
}
 
/* End transfer. */
instance->snd_bytes = 0;
instance->bidx = 0;
 
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) | TACK | TIP);
 
instance->xstate = cx_listen;
/* TODO: Match reply with request. */
}
 
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *data, size_t len)
{
if (data[0] != 0x00 || data[1] != 0x40 || (data[2] != 0x2c
&& data[2] != 0x8c))
return;
 
/* The packet contains one or two scancodes. */
if (data[3] != 0xff)
indev_push_character(instance->kbrdin, data[3]);
if (data[4] != 0xff)
indev_push_character(instance->kbrdin, data[4]);
}
 
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable)
{
instance->snd_buf[0] = PT_CUDA;
instance->snd_buf[1] = CPT_AUTOPOLL;
instance->snd_buf[2] = enable ? 0x01 : 0x00;
instance->snd_bytes = 3;
instance->bidx = 0;
 
cuda_send_start(instance);
}
 
static void cuda_send_start(cuda_instance_t *instance)
{
cuda_t *dev = instance->cuda;
 
ASSERT(instance->xstate == cx_listen);
 
if (instance->snd_bytes == 0)
return;
 
/* Check for incoming data. */
if ((pio_read_8(&dev->b) & TREQ) == 0)
return;
 
pio_write_8(&dev->acr, pio_read_8(&dev->acr) | SR_OUT);
pio_write_8(&dev->sr, instance->snd_buf[0]);
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
 
instance->xstate = cx_send_start;
}
 
 
/** @}
*/
/branches/network/kernel/generic/include/string.h
88,7 → 88,7
extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
 
extern const char *str_chr(const char *str, wchar_t ch);
extern char *str_chr(const char *str, wchar_t ch);
 
extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
extern bool wstr_remove(wchar_t *str, size_t pos);
/branches/network/kernel/generic/include/context.h
45,7 → 45,7
(c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
#endif /* context_set */
 
extern int context_save_arch(context_t *c);
extern int context_save_arch(context_t *c) __attribute__ ((returns_twice));
extern void context_restore_arch(context_t *c) __attribute__ ((noreturn));
 
/** Save register context.
76,10 → 76,6
* corresponding call to context_save(), the only
* difference being return value.
*
* Note that content of any local variable defined by
* the caller of context_save() is undefined after
* context_restore().
*
* @param c Context structure.
*/
static inline void context_restore(context_t *c)
/branches/network/kernel/generic/src/main/uinit.c
79,6 → 79,14
uarg.uspace_thread_arg = NULL;
 
free((uspace_arg_t *) arg);
/*
* Disable interrupts so that the execution of userspace() is not
* disturbed by any interrupts as some of the userspace()
* implementations will switch to the userspace stack before switching
* the mode.
*/
(void) interrupts_disable();
userspace(&uarg);
}
 
/branches/network/kernel/generic/src/lib/string.c
637,7 → 637,7
* @return Pointer to character in @a str or NULL if not found.
*
*/
const char *str_chr(const char *str, wchar_t ch)
char *str_chr(const char *str, wchar_t ch)
{
wchar_t acc;
size_t off = 0;
645,7 → 645,7
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
return (str + last);
return (char *) (str + last);
last = off;
}
/branches/network/kernel/generic/src/ipc/event.c
140,9 → 140,11
IPC_SET_ARG4(call->data, a4);
IPC_SET_ARG5(call->data, a5);
ipl_t ipl = interrupts_disable();
spinlock_lock(&events[evno].answerbox->irq_lock);
list_append(&call->link, &events[evno].answerbox->irq_notifs);
spinlock_unlock(&events[evno].answerbox->irq_lock);
interrupts_restore(ipl);
waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST);
}
/branches/network/kernel/arch/sparc64/include/atomic.h
123,7 → 123,7
"ldx %0, %2\n"
"brz %2, 0b\n"
"nop\n"
"ba %xcc, 1b\n"
"ba %%xcc, 1b\n"
"nop\n"
"2:\n"
: "+m" (*((uint64_t *) x)), "+r" (tmp1), "+r" (tmp2) : "r" (0)
/branches/network/kernel/arch/sparc64/include/context.h
39,7 → 39,7
#include <arch/types.h>
#include <align.h>
 
#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE
#define SP_DELTA (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
#ifdef context_set
#undef context_set
/branches/network/kernel/arch/sparc64/src/asm.S
277,7 → 277,7
*/
.global switch_to_userspace
switch_to_userspace:
save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
flushw
wrpr %g0, 0, %cleanwin ! avoid information leak
 
/branches/network/kernel/arch/sparc64/src/drivers/scr.c
133,11 → 133,11
break;
case 16:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_5_6_5;
visual = VISUAL_RGB_5_6_5_BE;
break;
case 24:
fb_scanline = fb_linebytes * 4;
visual = VISUAL_RGB_8_8_8_0;
visual = VISUAL_BGR_8_8_8_0;
break;
case 32:
fb_scanline = fb_linebytes * (fb_depth >> 3);
177,11 → 177,11
break;
case 16:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_5_6_5;
visual = VISUAL_RGB_5_6_5_BE;
break;
case 24:
fb_scanline = fb_linebytes * 4;
visual = VISUAL_RGB_8_8_8_0;
visual = VISUAL_BGR_8_8_8_0;
break;
case 32:
fb_scanline = fb_linebytes * (fb_depth >> 3);
/branches/network/kernel/arch/ia64/include/atomic.h
52,12 → 52,12
return v;
}
 
 
static inline uint64_t test_and_set(atomic_t *val) {
static inline uint64_t test_and_set(atomic_t *val)
{
uint64_t v;
asm volatile (
"movl %0 = 0x01;;\n"
"movl %0 = 0x1;;\n"
"xchg8 %0 = %1, %0;;\n"
: "=r" (v), "+m" (val->count)
);
65,6 → 65,13
return v;
}
 
static inline void atomic_lock_arch(atomic_t *val)
{
do {
while (val->count)
;
} while (test_and_set(val));
}
 
static inline void atomic_inc(atomic_t *val)
{
/branches/network/kernel/arch/ia64/include/mm/tlb.h
92,6 → 92,7
extern void data_dirty_bit_fault(uint64_t vector, istate_t *istate);
extern void instruction_access_bit_fault(uint64_t vector, istate_t *istate);
extern void data_access_bit_fault(uint64_t vector, istate_t *istate);
extern void data_access_rights_fault(uint64_t vector, istate_t *istate);
extern void page_not_present(uint64_t vector, istate_t *istate);
 
#endif
/branches/network/kernel/arch/ia64/src/ivt.S
536,7 → 536,7
HEAVYWEIGHT_HANDLER 0x5000 page_not_present
HEAVYWEIGHT_HANDLER 0x5100
HEAVYWEIGHT_HANDLER 0x5200
HEAVYWEIGHT_HANDLER 0x5300
HEAVYWEIGHT_HANDLER 0x5300 data_access_rights_fault
HEAVYWEIGHT_HANDLER 0x5400 general_exception
HEAVYWEIGHT_HANDLER 0x5500 disabled_fp_register
HEAVYWEIGHT_HANDLER 0x5600
/branches/network/kernel/arch/ia64/src/mm/tlb.c
710,6 → 710,37
page_table_unlock(AS, true);
}
 
/** Data access rights fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_access_rights_fault(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
 
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
 
/*
* Assume a write to a read-only page.
*/
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
ASSERT(t && t->p);
ASSERT(!t->w);
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
page_table_unlock(AS, true);
}
 
/** Page not present fault handler.
*
* @param vector Interruption vector.
/branches/network/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
/branches/network/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
 
/** @}
*/
/branches/network/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_MACHINE_H_
#define KERN_arm32_MACHINE_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
 
/** @}
*/
/branches/network/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_MACHINE_H_
#define KERN_arm32_MACHINE_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
 
/** @}
*/
/branches/network/kernel/arch/arm32/include/drivers/gxemul.h
File deleted
/branches/network/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,16
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
endif
 
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
/branches/network/kernel/arch/arm32/src/exception.c
39,10 → 39,17
#include <interrupt.h>
#include <arch/mm/page_fault.h>
#include <arch/barrier.h>
#include <arch/drivers/gxemul.h>
#include <print.h>
#include <syscall/syscall.h>
 
#ifdef MACHINE_testarm
#include <arch/mach/testarm/testarm.h>
#endif
 
#ifdef MACHINE_integratorcp
#include <arch/mach/integratorcp/integratorcp.h>
#endif
 
/** Offset used in calculation of exception handler's relative address.
*
* @see install_handler()
58,159 → 65,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 → 86,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 → 96,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 → 142,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
/branches/network/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
/branches/network/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()
{
}
 
/** @}
*/
/branches/network/kernel/arch/arm32/src/arm32.c
37,13 → 37,9
#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 <print.h>
#include <config.h>
#include <interrupt.h>
52,6 → 48,15
#include <macros.h>
#include <string.h>
 
#ifdef MACHINE_testarm
#include <arch/mach/testarm/testarm.h>
#endif
 
#ifdef MACHINE_integratorcp
#include <arch/mach/integratorcp/integratorcp.h>
#endif
 
 
/** Performs arm32-specific initialization before main_bsp() is called. */
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
{
77,7 → 82,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 → 89,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 → 123,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 → 130,6
/** Performs arm32 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
tlb_invalidate_all();
}
 
 
168,6 → 141,7
{
uint8_t *stck;
tlb_invalidate_all();
stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
supervisor_sp = (uintptr_t) stck;
}
183,8 → 157,7
/** Halts CPU. */
void cpu_halt(void)
{
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET))
= 0;
machine_cpu_halt();
}
 
/** Reboot. */
211,6 → 184,7
/** Acquire console back for kernel. */
void arch_grab_console(void)
{
machine_grab_console();
#ifdef CONFIG_FB
fb_redraw();
#endif
219,6 → 193,7
/** Return console to userspace. */
void arch_release_console(void)
{
machine_release_console();
}
 
/** @}
/branches/network/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_RGB_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
/branches/network/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_BGR_0_8_8_8,
};
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);
 
}
 
 
/** @}
*/
/branches/network/kernel/arch/arm32/src/mm/frame.c
35,9 → 35,16
 
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <arch/drivers/gxemul.h>
#include <config.h>
 
#ifdef MACHINE_testarm
#include <arch/mach/testarm/testarm.h>
#endif
 
#ifdef MACHINE_integratorcp
#include <arch/mach/integratorcp/integratorcp.h>
#endif
 
/** Address of the last frame in the memory. */
uintptr_t last_frame = 0;
 
44,7 → 51,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 → 60,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. */
/branches/network/kernel/arch/arm32/src/interrupt.c
35,16 → 35,21
 
#include <arch/asm.h>
#include <arch/regutils.h>
#include <arch/drivers/gxemul.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <interrupt.h>
 
#ifdef MACHINE_testarm
#include <arch/mach/testarm/testarm.h>
#endif
 
#ifdef MACHINE_integratorcp
#include <arch/mach/integratorcp/integratorcp.h>
#endif
 
/** 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 → 57,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 → 70,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 → 96,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 → 102,7
void interrupt_init(void)
{
irq_init(IRQ_COUNT, IRQ_COUNT);
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);
machine_timer_irq_start();
}
 
/** @}
/branches/network/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
 
/branches/network/kernel/arch/arm32/src/drivers/gxemul.c
File deleted
/branches/network/kernel/arch/ppc32/src/ppc32.c
36,6 → 36,7
#include <arch.h>
#include <arch/boot/boot.h>
#include <genarch/drivers/via-cuda/cuda.h>
#include <genarch/kbrd/kbrd.h>
#include <arch/interrupt.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
91,10 → 92,10
visual = VISUAL_INDIRECT_8;
break;
case 16:
visual = VISUAL_RGB_5_5_5;
visual = VISUAL_RGB_5_5_5_BE;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
visual = VISUAL_BGR_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
117,31 → 118,6
/* Initialize IRQ routing */
irq_init(IRQ_COUNT, IRQ_COUNT);
if (bootinfo.macio.addr) {
/* Initialize PIC */
cir_t cir;
void *cir_arg;
pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg);
#ifdef CONFIG_VIA_CUDA
uintptr_t pa = bootinfo.macio.addr + 0x16000;
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
size_t offset = pa - aligned_addr;
size_t size = 2 * PAGE_SIZE;
cuda_t *cuda = (cuda_t *)
(hw_map(aligned_addr, offset + size) + offset);
/* Initialize I/O controller */
cuda_instance_t *cuda_instance =
cuda_init(cuda, IRQ_CUDA, cir, cir_arg);
if (cuda_instance) {
indev_t *sink = stdin_wire();
cuda_wire(cuda_instance, sink);
}
#endif
}
/* Merge all zones to 1 big zone */
zone_merge_all();
}
157,6 → 133,35
 
void arch_post_smp_init(void)
{
if (bootinfo.macio.addr) {
/* Initialize PIC */
cir_t cir;
void *cir_arg;
pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg);
 
#ifdef CONFIG_MAC_KBD
uintptr_t pa = bootinfo.macio.addr + 0x16000;
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
size_t offset = pa - aligned_addr;
size_t size = 2 * PAGE_SIZE;
cuda_t *cuda = (cuda_t *)
(hw_map(aligned_addr, offset + size) + offset);
/* Initialize I/O controller */
cuda_instance_t *cuda_instance =
cuda_init(cuda, IRQ_CUDA, cir, cir_arg);
if (cuda_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
cuda_wire(cuda_instance, kbrd);
pic_enable_interrupt(IRQ_CUDA);
}
}
#endif
}
}
 
void calibrate_delay_loop(void)
/branches/network/kernel/arch/mips32/include/context_offset.h
86,7 → 86,7
#define EOFFSET_STATUS 0x58
#define EOFFSET_EPC 0x5c
#define EOFFSET_K1 0x60
#define REGISTER_SPACE 100
#define REGISTER_SPACE 104 /* respect stack alignment */
 
#ifdef __ASM__
 
/branches/network/kernel/arch/mips32/include/atomic.h
88,6 → 88,13
return v;
}
 
static inline void atomic_lock_arch(atomic_t *val) {
do {
while (val->count)
;
} while (test_and_set(val));
}
 
#endif
 
/** @}
/branches/network/kernel/arch/mips32/src/mips32.c
141,7 → 141,7
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_BGR_8_8_8,
.visual = VISUAL_RGB_8_8_8,
};
fb_init(&gxemul_prop);
#else
/branches/network/kernel/arch/ia32/src/drivers/vesa.c
85,15 → 85,15
if ((vesa_red_mask == 5) && (vesa_red_pos == 10)
&& (vesa_green_mask == 5) && (vesa_green_pos == 5)
&& (vesa_blue_mask == 5) && (vesa_blue_pos == 0))
visual = VISUAL_RGB_5_5_5;
visual = VISUAL_RGB_5_5_5_LE;
else
visual = VISUAL_RGB_5_6_5;
visual = VISUAL_RGB_5_6_5_LE;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
visual = VISUAL_BGR_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
visual = VISUAL_BGR_8_8_8_0;
break;
default:
panic("Unsupported bits per pixel.");