Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3548 → Rev 3549

/branches/sparc/uspace/srv/kbd/genarch/include/nofb.h
0,0 → 1,48
/*
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_genarch_NOFB_H_
#define KBD_genarch_NOFB_H_
 
 
#include <key_buffer.h>
#include <genarch/scanc.h>
 
extern int kbd_process_no_fb(keybuffer_t *keybuffer, int scan_code);
 
#endif
 
/**
* @}
*/
/branches/sparc/uspace/srv/kbd/genarch/src/nofb.c
0,0 → 1,185
/*
* Copyright (c) 2006 Josef Cejka
* 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 kbdmips32 mips32
* @brief HelenOS mips32 arch dependent parts of uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#include <genarch/nofb.h>
 
#define KEY_F1 0x504f1bL
#define KEY_F2 0x514f1bL
#define KEY_F3 0x524f1bL
#define KEY_F4 0x534f1bL
#define KEY_F5 0x35315b1bL
#define KEY_F6 0x37315b1bL
#define KEY_F7 0x38315b1bL
#define KEY_F8 0x39315b1bL
#define KEY_F9 0x30325b1bL
#define KEY_F10 0x31325b1bL
#define KEY_F11 0x33325b1bL
#define KEY_F12 0x34325b1bL
 
/**
* Processes the key pressed - pushes the key code into the key buffer.
* Used in MSIM and Serengeti, i.e. non-framebuffer consoles.
*/
int kbd_process_no_fb(keybuffer_t *keybuffer, int scan_code)
{
static unsigned long buf = 0;
static int count = 0;
if(scan_code == 0x7e) {
switch (buf) {
case KEY_F5:
keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
buf = count = 0;
return 1;
case KEY_F6:
keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
buf = count = 0;
return 1;
case KEY_F7:
keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
buf = count = 0;
return 1;
case KEY_F8:
keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
buf = count = 0;
return 1;
case KEY_F9:
keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
buf = count = 0;
return 1;
case KEY_F10:
keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
buf = count = 0;
return 1;
case KEY_F11:
keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
buf = count = 0;
return 1;
case KEY_F12:
keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
buf = count = 0;
return 1;
default:
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) &0xff);
keybuffer_push(keybuffer, (buf >> 16) &0xff);
keybuffer_push(keybuffer, (buf >> 24) &0xff);
keybuffer_push(keybuffer, scan_code);
buf = count = 0;
return 1;
}
}
 
buf |= ((unsigned long) scan_code)<<(8*(count++));
if((buf & 0xff) != (KEY_F1 & 0xff)) {
keybuffer_push(keybuffer, buf);
buf = count = 0;
return 1;
}
 
if (count <= 1)
return 1;
 
if ((buf & 0xffff) != (KEY_F1 & 0xffff)
&& (buf & 0xffff) != (KEY_F5 & 0xffff) ) {
 
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) &0xff);
buf = count = 0;
return 1;
}
 
if (count <= 2)
return 1;
 
switch (buf) {
case KEY_F1:
keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
buf = count = 0;
return 1;
case KEY_F2:
keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
buf = count = 0;
return 1;
case KEY_F3:
keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
buf = count = 0;
return 1;
case KEY_F4:
keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
buf = count = 0;
return 1;
}
 
 
if((buf & 0xffffff) != (KEY_F5 & 0xffffff)
&& (buf & 0xffffff) != (KEY_F9 & 0xffffff)) {
 
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) & 0xff);
keybuffer_push(keybuffer, (buf >> 16) & 0xff);
buf=count=0;
return 1;
}
 
if (count <= 3)
return 1;
switch (buf) {
case KEY_F5:
case KEY_F6:
case KEY_F7:
case KEY_F8:
case KEY_F9:
case KEY_F10:
case KEY_F11:
case KEY_F12:
return 1;
default:
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) &0xff);
keybuffer_push(keybuffer, (buf >> 16) &0xff);
keybuffer_push(keybuffer, (buf >> 24) &0xff);
buf = count = 0;
return 1;
}
return 1;
}
 
/** @}
*/
/branches/sparc/uspace/srv/kbd/Makefile
67,16 → 67,21
endif
ifeq ($(ARCH), sparc64)
ARCH_SOURCES += \
arch/$(ARCH)/src/scanc.c
arch/$(ARCH)/src/scanc.c \
arch/$(ARCH)/src/sgcn.c
GENARCH_SOURCES = \
genarch/src/kbd.c
genarch/src/kbd.c \
genarch/src/nofb.c
endif
ifeq ($(ARCH), arm32)
ARCH_SOURCES += \
arch/$(ARCH)/src/kbd_gxemul.c
endif
ifeq ($(ARCH), mips32)
GENARCH_SOURCES += \
genarch/src/nofb.c
endif
 
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
/branches/sparc/uspace/srv/kbd/arch/sparc64/include/sgcn.h
0,0 → 1,46
/*
* Copyright (c) 2008 Pavel Rimsky
* 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 kbdsparc64 sparc64
* @brief Serengeti-specific parts of uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_sparc64_SGCN_H_
#define KBD_sparc64_SGCN_H_
 
void sgcn_init(void);
void sgcn_key_pressed(void);
 
#endif
 
/** @}
*/
/branches/sparc/uspace/srv/kbd/arch/sparc64/src/kbd.c
35,6 → 35,7
*/
 
#include <arch/kbd.h>
#include <arch/sgcn.h>
#include <ipc/ipc.h>
#include <sysinfo.h>
#include <kbd.h>
78,6 → 79,7
 
#define KBD_Z8530 1
#define KBD_NS16550 2
#define KBD_SGCN 3
 
int kbd_arch_init(void)
{
91,6 → 93,9
ns16550_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ns16550_kbd);
break;
case KBD_SGCN:
sgcn_init();
break;
default:
break;
}
100,6 → 105,11
/** Process keyboard events */
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
{
if (sysinfo_value("kbd.type") == KBD_SGCN) {
sgcn_key_pressed();
return 1;
}
int scan_code = IPC_GET_ARG1(*call);
 
if (scan_code == KBD_ALL_KEYS_UP)
/branches/sparc/uspace/srv/kbd/arch/sparc64/src/sgcn.c
0,0 → 1,162
/*
* Copyright (c) 2008 Pavel Rimsky
* 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 kbdsparc64 sparc64
* @brief Serengeti-specific parts of uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#include <arch/sgcn.h>
#include <as.h>
#include <ddi.h>
#include <ipc/ipc.h>
#include <kbd.h>
#include <genarch/nofb.h>
#include <genarch/kbd.h>
#include <sysinfo.h>
#include <stdio.h>
#include <futex.h>
 
/**
* SGCN buffer header. It is placed at the very beginning of the SGCN
* buffer.
*/
typedef struct {
/** hard-wired to "CON" */
char magic[4];
/** we don't need this */
char unused[8];
/** offset within the SGCN buffer of the input buffer start */
uint32_t in_begin;
/** offset within the SGCN buffer of the input buffer end */
uint32_t in_end;
/** offset within the SGCN buffer of the input buffer read pointer */
uint32_t in_rdptr;
/** offset within the SGCN buffer of the input buffer write pointer */
uint32_t in_wrptr;
 
/** offset within the SGCN buffer of the output buffer start */
uint32_t out_begin;
/** offset within the SGCN buffer of the output buffer end */
uint32_t out_end;
/** offset within the SGCN buffer of the output buffer read pointer */
uint32_t out_rdptr;
/** offset within the SGCN buffer of the output buffer write pointer */
uint32_t out_wrptr;
} __attribute__ ((packed)) sgcn_buffer_header_t;
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the console buffer beginning.
*/
#define SGCN_BUFFER(type, offset) \
((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
 
/** Returns a pointer to the console buffer header. */
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
 
extern keybuffer_t keybuffer;
 
/**
* Virtual address mapped to SRAM.
*/
static uintptr_t sram_virt_addr;
 
/**
* SGCN buffer offset within SGCN.
*/
static uintptr_t sram_buffer_offset;
 
/**
* Initializes the SGCN driver.
* Maps the physical memory (SRAM) and registers the interrupt.
*/
void sgcn_init(void)
{
sram_virt_addr = (uintptr_t) as_get_mappable_page(sysinfo_value("sram.area.size"));
int result = physmem_map(
(void *) sysinfo_value("sram.address.physical"),
(void *) sram_virt_addr,
sysinfo_value("sram.area.size") / PAGE_SIZE,
AS_AREA_READ | AS_AREA_WRITE
);
if (result != 0) {
printf("SGCN: uspace driver could not map physical memory.");
}
sram_buffer_offset = sysinfo_value("sram.buffer.offset");
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"),
0, (void *) 0);
}
 
 
 
/**
* Handler of the "key pressed" event. Reads codes of all the pressed keys from
* the buffer.
*/
void sgcn_key_pressed(void)
{
char c;
uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
uint32_t end = SGCN_BUFFER_HEADER->in_end;
uint32_t size = end - begin;
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
while (*in_rdptr_ptr != *in_wrptr_ptr) {
c = *buf_ptr;
*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
printf("Pressed character %c.\n", c);
if (c == '\r') {
c = '\n';
}
//keybuffer_push(&keybuffer, c);
kbd_process_no_fb(&keybuffer, c);
}
}
 
/** @}
*/
/branches/sparc/uspace/srv/kbd/arch/mips32/src/kbd.c
34,6 → 34,7
/** @file
*/
#include <arch/kbd.h>
#include <genarch/nofb.h>
#include <ipc/ipc.h>
#include <sysinfo.h>
#include <kbd.h>
99,146 → 100,6
}
*/
 
static int kbd_arch_process_no_fb(keybuffer_t *keybuffer, int scan_code)
{
 
static unsigned long buf = 0;
static int count = 0;
 
/* Please preserve this code (it can be used to determine scancodes)
keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
keybuffer_push(keybuffer, to_hex(scan_code&0xf));
keybuffer_push(keybuffer, ' ');
keybuffer_push(keybuffer, ' ');
return 1;
*/
if(scan_code == 0x7e) {
switch (buf) {
case MSIM_KEY_F5:
keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
buf = count = 0;
return 1;
case MSIM_KEY_F6:
keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
buf = count = 0;
return 1;
case MSIM_KEY_F7:
keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
buf = count = 0;
return 1;
case MSIM_KEY_F8:
keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
buf = count = 0;
return 1;
case MSIM_KEY_F9:
keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
buf = count = 0;
return 1;
case MSIM_KEY_F10:
keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
buf = count = 0;
return 1;
case MSIM_KEY_F11:
keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
buf = count = 0;
return 1;
case MSIM_KEY_F12:
keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
buf = count = 0;
return 1;
default:
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) &0xff);
keybuffer_push(keybuffer, (buf >> 16) &0xff);
keybuffer_push(keybuffer, (buf >> 24) &0xff);
keybuffer_push(keybuffer, scan_code);
buf = count = 0;
return 1;
}
}
 
buf |= ((unsigned long) scan_code)<<(8*(count++));
if((buf & 0xff) != (MSIM_KEY_F1 & 0xff)) {
keybuffer_push(keybuffer, buf);
buf = count = 0;
return 1;
}
 
if (count <= 1)
return 1;
 
if ((buf & 0xffff) != (MSIM_KEY_F1 & 0xffff)
&& (buf & 0xffff) != (MSIM_KEY_F5 & 0xffff) ) {
 
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) &0xff);
buf = count = 0;
return 1;
}
 
if (count <= 2)
return 1;
 
switch (buf) {
case MSIM_KEY_F1:
keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
buf = count = 0;
return 1;
case MSIM_KEY_F2:
keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
buf = count = 0;
return 1;
case MSIM_KEY_F3:
keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
buf = count = 0;
return 1;
case MSIM_KEY_F4:
keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
buf = count = 0;
return 1;
}
 
 
if((buf & 0xffffff) != (MSIM_KEY_F5 & 0xffffff)
&& (buf & 0xffffff) != (MSIM_KEY_F9 & 0xffffff)) {
 
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) & 0xff);
keybuffer_push(keybuffer, (buf >> 16) & 0xff);
buf=count=0;
return 1;
}
 
if (count <= 3)
return 1;
switch (buf) {
case MSIM_KEY_F5:
case MSIM_KEY_F6:
case MSIM_KEY_F7:
case MSIM_KEY_F8:
case MSIM_KEY_F9:
case MSIM_KEY_F10:
case MSIM_KEY_F11:
case MSIM_KEY_F12:
return 1;
default:
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) &0xff);
keybuffer_push(keybuffer, (buf >> 16) &0xff);
keybuffer_push(keybuffer, (buf >> 24) &0xff);
buf = count = 0;
return 1;
}
return 1;
}
 
 
 
static int kbd_arch_process_fb(keybuffer_t *keybuffer, int scan_code)
{
static unsigned long buf = 0;
371,7 → 232,7
if (fb_fb)
return kbd_arch_process_fb(keybuffer, scan_code);
 
return kbd_arch_process_no_fb(keybuffer, scan_code);
return kbd_process_no_fb(keybuffer, scan_code);
}
/** @}
*/
/branches/sparc/uspace/srv/console/console.c
327,7 → 327,6
break;
case KBD_PUSHCHAR:
/* got key from keyboard driver */
retval = 0;
c = IPC_GET_ARG1(call);
/* switch to another virtual console */
/branches/sparc/uspace/srv/fb/sgcn.h
0,0 → 1,46
/*
* Copyright (c) 2008 Pavel Rimsky
* 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.
*/
 
/** @defgroup sgcnfb SGCN
* @brief userland driver of the Serengeti console output
* @{
*/
/** @file
*/
 
#ifndef FB_SGCN_H_
#define FB_SGCN_H_
 
int sgcn_init(void);
 
#endif
 
/**
* @}
*/
/branches/sparc/uspace/srv/fb/main.c
38,6 → 38,7
#include "fb.h"
#include "ega.h"
#include "msim.h"
#include "sgcn.h"
#include "main.h"
 
#define NAME "fb"
79,6 → 80,12
initialized = true;
}
#endif
#ifdef SGCN_ENABLED
if ((!initialized) && (sysinfo_value("fb.kind") == 4)) {
if (sgcn_init() == 0)
initialized = true;
}
#endif
 
if (!initialized)
return -1;
/branches/sparc/uspace/srv/fb/sgcn.c
0,0 → 1,303
/*
* Copyright (c) 2006 Ondrej Palkovsky
* Copyright (c) 2008 Martin Decky
* Copyright (c) 2008 Pavel Rimsky
* 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.
*/
 
/** @defgroup sgcnfb SGCN
* @brief userland driver of the Serengeti console output
* @{
*/
/** @file
*/
 
#include <async.h>
#include <ipc/ipc.h>
#include <ipc/fb.h>
#include <sysinfo.h>
#include <as.h>
#include <errno.h>
#include <stdio.h>
#include <ddi.h>
 
#include "sgcn.h"
 
#define WIDTH 80
#define HEIGHT 24
 
#define MAX_CONTROL 20
 
/**
* Virtual address mapped to SRAM.
*/
static uintptr_t sram_virt_addr;
 
/**
* SGCN buffer offset within SGCN.
*/
static uintptr_t sram_buffer_offset;
 
/* Allow only 1 connection */
static int client_connected = 0;
 
/**
* SGCN buffer header. It is placed at the very beginning of the SGCN
* buffer.
*/
typedef struct {
/** hard-wired to "CON" */
char magic[4];
/** we don't need this */
char unused[8];
/** offset within the SGCN buffer of the input buffer start */
uint32_t in_begin;
/** offset within the SGCN buffer of the input buffer end */
uint32_t in_end;
/** offset within the SGCN buffer of the input buffer read pointer */
uint32_t in_rdptr;
/** offset within the SGCN buffer of the input buffer write pointer */
uint32_t in_wrptr;
 
/** offset within the SGCN buffer of the output buffer start */
uint32_t out_begin;
/** offset within the SGCN buffer of the output buffer end */
uint32_t out_end;
/** offset within the SGCN buffer of the output buffer read pointer */
uint32_t out_rdptr;
/** offset within the SGCN buffer of the output buffer write pointer */
uint32_t out_wrptr;
} __attribute__ ((packed)) sgcn_buffer_header_t;
 
// TODO it is suggested to extract the common parts of this file and the msim.c file
// into a separate file and place that file to the genarch directory
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the console buffer beginning.
*/
#define SGCN_BUFFER(type, offset) \
((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
 
/** Returns a pointer to the console buffer header. */
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
 
static void sgcn_putc(char c)
{
uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
uint32_t end = SGCN_BUFFER_HEADER->out_end;
uint32_t size = end - begin;
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
 
uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
while (*out_rdptr_ptr == new_wrptr)
;
*buf_ptr = c;
*out_wrptr_ptr = new_wrptr;
}
 
static void sgcn_puts(char *str)
{
while (*str)
sgcn_putc(*(str++));
}
 
static void sgcn_goto(const unsigned int row, const unsigned int col)
{
if ((row > HEIGHT) || (col > WIDTH))
return;
char control[20];
snprintf(control, 20, "\033[%u;%uf", row + 1, col + 1);
sgcn_puts(control);
}
 
static void sgcn_clrscr(void)
{
sgcn_puts("\033[2J");
}
 
static void sgcn_scroll(int i)
{
if (i > 0) {
sgcn_goto(HEIGHT - 1, 0);
while (i--)
sgcn_puts("\033D");
} else if (i < 0) {
sgcn_goto(0, 0);
while (i++)
sgcn_puts("\033M");
}
}
 
static void sgcn_set_style(const unsigned int mode)
{
char control[MAX_CONTROL];
snprintf(control, MAX_CONTROL, "\033[%um", mode);
sgcn_puts(control);
}
 
static void sgcn_cursor_disable(void)
{
sgcn_puts("\033[?25l");
}
 
static void sgcn_cursor_enable(void)
{
sgcn_puts("\033[?25h");
}
 
static void sgcn_client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
int retval;
ipc_callid_t callid;
ipc_call_t call;
char c;
int lastcol = 0;
int lastrow = 0;
int newcol;
int newrow;
int fgcolor;
int bgcolor;
int i;
if (client_connected) {
ipc_answer_0(iid, ELIMIT);
return;
}
client_connected = 1;
ipc_answer_0(iid, EOK);
/* Clear the terminal, set scrolling region
to 0 - 24 lines */
sgcn_clrscr();
sgcn_goto(0, 0);
sgcn_puts("\033[0;24r");
while (true) {
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
client_connected = 0;
ipc_answer_0(callid, EOK);
return;
case FB_PUTCHAR:
c = IPC_GET_ARG1(call);
newrow = IPC_GET_ARG2(call);
newcol = IPC_GET_ARG3(call);
if ((lastcol != newcol) || (lastrow != newrow))
sgcn_goto(newrow, newcol);
lastcol = newcol + 1;
lastrow = newrow;
sgcn_putc(c);
retval = 0;
break;
case FB_CURSOR_GOTO:
newrow = IPC_GET_ARG1(call);
newcol = IPC_GET_ARG2(call);
sgcn_goto(newrow, newcol);
lastrow = newrow;
lastcol = newcol;
retval = 0;
break;
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, HEIGHT, WIDTH);
continue;
case FB_CLEAR:
sgcn_clrscr();
retval = 0;
break;
case FB_SET_STYLE:
fgcolor = IPC_GET_ARG1(call);
bgcolor = IPC_GET_ARG2(call);
if (fgcolor < bgcolor)
sgcn_set_style(0);
else
sgcn_set_style(7);
retval = 0;
break;
case FB_SCROLL:
i = IPC_GET_ARG1(call);
if ((i > HEIGHT) || (i < -HEIGHT)) {
retval = EINVAL;
break;
}
sgcn_scroll(i);
sgcn_goto(lastrow, lastcol);
retval = 0;
break;
case FB_CURSOR_VISIBILITY:
if(IPC_GET_ARG1(call))
sgcn_cursor_enable();
else
sgcn_cursor_disable();
retval = 0;
break;
default:
retval = ENOENT;
}
ipc_answer_0(callid, retval);
}
}
 
int sgcn_init(void)
{
sram_virt_addr = (uintptr_t) as_get_mappable_page(sysinfo_value("sram.area.size"));
int result = physmem_map(
(void *) sysinfo_value("sram.address.physical"),
(void *) sram_virt_addr,
sysinfo_value("sram.area.size") / PAGE_SIZE,
AS_AREA_READ | AS_AREA_WRITE
);
if (result != 0) {
printf("SGCN: uspace driver couldn't map physical memory: %d\n",
result);
}
sram_buffer_offset = sysinfo_value("sram.buffer.offset");
async_set_client_connection(sgcn_client_connection);
return 0;
}
 
/**
* @}
*/
/branches/sparc/uspace/srv/fb/Makefile
62,6 → 62,10
SOURCES += msim.c
CFLAGS += -DMSIM_ENABLED -DFB_INVERT_ENDIAN
endif
ifeq ($(ARCH), sparc64)
SOURCES += sgcn.c
CFLAGS += -DSGCN_ENABLED
endif
 
CFLAGS += -D$(ARCH)