haeberlen@ira.uka.de
#include <idl4glue.h>
#include "console-server.h"
#include <config.h>
#include <l4/sigma0.h>
#include <stdio.h>
#include <sdi/ports.h>
#include <stdlib.h>
#include <new>
#include <assert.h>
#include <string.h>
#include <l4/thread.h>
#include <l4/ipc.h>
#include <l4/kip.h>
#include <l4/schedule.h>
#include <sdi/panic.h>
#include <sdi/log.h>
#include <sdi/locator.h>
#include <if/iflogging.h>
#include <if/ifsyscall.h>
#include "VirtualConsole.h"
L4_Bool_t ALTPressed = 0;
const int MAX_VIRT_CONSOLES = 12;
const uint16_t dataPort = 0x60u;
const uint16_t statusPort = 0x64u;
const L4_Word_t VIDEO_MEM = 0xb8000;
char* videoMemStart;
size_t videoMemSize = 4000;
int consoleWithFocus = 0;
VirtualConsole* consoles[MAX_VIRT_CONSOLES];
L4_ThreadId_t locatorid;
void setFocusToConsole(int console) {
consoles[consoleWithFocus]->setFocus(0);
consoles[console]->setFocus(1);
consoles[console]->update();
consoleWithFocus = console;
LogMessage("Switched to console%d", console);
}
void initConsoles() {
for(int i=0; i<MAX_VIRT_CONSOLES; i++) {
consoles[i] = new VirtualConsole(i, videoMemStart);
}
setFocusToConsole(0);
}
IDL4_INLINE void console_interrupt_implementation(CORBA_Object _caller, idl4_server_environment *_env)
{
uint8_t scanCode = inb(dataPort);
if(scanCode & 0x80) {
if(0xb8 == scanCode) {
ALTPressed = 0;
}
} else {
switch(scanCode) {
case 56:
ALTPressed = 1;
break;
case 87:
if(ALTPressed) setFocusToConsole(10);
break;
case 88:
if(ALTPressed) setFocusToConsole(11);
break;
case 73:
consoles[consoleWithFocus]->PageUp();
break;
case 81:
consoles[consoleWithFocus]->PageDown();
break;
}
if((0x3b <= scanCode) && (scanCode <= 0x44)) {
if(ALTPressed) {
setFocusToConsole(scanCode - 0x3b);
}
}
}
consoles[consoleWithFocus]->addInput(scanCode);
L4_Set_MsgTag(L4_Niltag);
L4_MsgTag_t tag = L4_Reply(_caller);
if(L4_IpcFailed(tag)) {
panic("Sending IPC to reenable interrupts failed");
}
return;
}
IDL4_PUBLISH_CONSOLE_INTERRUPT(console_interrupt_implementation);
IDL4_INLINE void console_Read_implementation(CORBA_Object _caller, const objectid_t consolehandle, const uint32_t pos, const idlsize_t readsize, buffer_t *buffer, idl4_server_environment *_env)
{
buffer->_length = consoles[consolehandle]->read(readsize, buffer->_buffer);
return;
}
IDL4_PUBLISH_CONSOLE_READ(console_Read_implementation);
IDL4_INLINE void console_Write_implementation(CORBA_Object _caller, const objectid_t consolehandle, const uint32_t pos, idlsize_t *byteswritten, const buffer_t *buffer, idl4_server_environment *_env)
{
*byteswritten = consoles[consolehandle]->write(buffer, pos);
return;
}
IDL4_PUBLISH_CONSOLE_WRITE(console_Write_implementation);
IDL4_INLINE void console_GetFileSize_implementation(CORBA_Object _caller, const objectid_t filehandle, idlsize_t *filesize, idl4_server_environment *_env)
{
*filesize = 0;
return;
}
IDL4_PUBLISH_CONSOLE_GETFILESIZE(console_GetFileSize_implementation);
void *console_vtable_4[CONSOLE_DEFAULT_VTABLE_SIZE] = CONSOLE_DEFAULT_VTABLE_4;
void *console_vtable_discard[CONSOLE_DEFAULT_VTABLE_SIZE] = CONSOLE_DEFAULT_VTABLE_DISCARD;
void **console_itable[8] = { console_vtable_discard, console_vtable_discard, console_vtable_discard, console_vtable_discard, console_vtable_4, console_vtable_discard, console_vtable_discard, console_vtable_discard };
void *console_ktable[CONSOLE_DEFAULT_KTABLE_SIZE] = CONSOLE_DEFAULT_KTABLE;
void console_server(void)
{
L4_ThreadId_t partner;
L4_MsgTag_t msgtag;
idl4_msgbuf_t msgbuf;
long cnt;
idl4_msgbuf_init(&msgbuf);
for (cnt = 0;cnt < CONSOLE_STRBUF_SIZE;cnt++)
idl4_msgbuf_add_buffer(&msgbuf, malloc(8000), 8000);
while (1)
{
partner = L4_nilthread;
msgtag.raw = 0;
cnt = 0;
while (1)
{
idl4_msgbuf_sync(&msgbuf);
idl4_reply_and_wait(&partner, &msgtag, &msgbuf, &cnt);
if (idl4_is_error(&msgtag))
break;
if (IDL4_EXPECT_FALSE(idl4_is_kernel_message(msgtag)))
idl4_process_request(&partner, &msgtag, &msgbuf, &cnt, console_ktable[idl4_get_kernel_message_id(msgtag) & CONSOLE_KID_MASK]);
else idl4_process_request(&partner, &msgtag, &msgbuf, &cnt, console_itable[idl4_get_interface_id(&msgtag) & CONSOLE_IID_MASK][idl4_get_function_id(&msgtag) & CONSOLE_FID_MASK]);
}
}
}
void console_discard(void) {
LogMessage("ERROR: IPC Msg to console server discarded!");
}
int main () {
LogMessage("ConsoleServer is alive");
TODO:
locatorid = L4_GlobalId (L4_ThreadIdUserBase (L4_KernelInterface ()) + 3, 1);
CORBA_Environment env (idl4_default_environment);
L4_ThreadId_t syscallServerId = L4_GlobalId(0x3ffff - 4, 1);
LogMessage("Synthesized PF");
videoMemStart = (char *) 0xb8000;
L4_Fpage_t page = L4_Sigma0_GetPage_RcvWindow(L4_nilthread,
L4_Fpage((L4_Word_t) videoMemStart, (L4_Word_t) videoMemSize),
L4_Fpage(0x90000000, (L4_Word_t) videoMemSize));
if(L4_IsNilFpage(page)) {
LogMessage("not ok");
} else {
LogMessage("ok (Addr: %lx Size: %lu)", L4_Address(page),
L4_Size(page));
}
videoMemStart = (char*) 0x90000000;
LogMessage("VideoMem at %p length %u", videoMemStart, videoMemSize);
memset(videoMemStart, 0, 4000);
initConsoles();
LogMessage("Register virtual consoles at the locator");
for(int i=0; i<MAX_VIRT_CONSOLES; i++) {
char name[128];
snprintf(name, sizeof(name), "console%d", i);
if(Register(GetLocator(), name, IF_FILE_ID, i) != OK)
panic("Couldn't register console");
}
L4_Word_t intNum = 1;
L4_ThreadId_t interruptThread = L4_GlobalId( intNum, 1 );
L4_ThreadId_t interruptHandler = L4_Myself();
LogMessage("Registering Console for interrupt...");
unsigned long one = 1;
L4_Word_t *word = &one;
IF_SYSCALL_AssociateInterrupt( (CORBA_Object)syscallServerId,
&interruptThread,
&interruptHandler,
word,
&env);
if(!*word) {
printf("%lx ", L4_ErrorCode());
panic("Registering the console-server for interrupt handling failed!");
}
LogMessage("Sarting console_server_loop");
console_server();
L4_Sleep(L4_Never);
panic("This should never be reached!");
return 0;
}