/uspace/trunk/ns/ns.c |
---|
33,6 → 33,7 |
#include <ipc/ipc.h> |
#include <ipc/ns.h> |
#include <ipc/services.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <stdlib.h> |
76,21 → 77,23 |
int static ping_phone; |
static void get_realtime_as(ipc_callid_t callid, ipc_call_t *call) |
static void *clockaddr = NULL; |
static void *klogaddr = NULL; |
static void get_as(ipc_callid_t callid, ipc_call_t *call, char *name, void **addr) |
{ |
static void *addr = NULL; |
void *ph_addr; |
if (!addr) { |
ph_addr = (void *)sysinfo_value("clock.faddr"); |
if (!*addr) { |
ph_addr = (void *)sysinfo_value(name); |
if (!ph_addr) { |
ipc_answer_fast(callid, ENOENT, 0, 0); |
return; |
} |
addr = as_get_mappable_page(PAGE_SIZE); |
map_physmem(ph_addr, addr, 1, AS_AREA_READ | AS_AREA_CACHEABLE); |
*addr = as_get_mappable_page(PAGE_SIZE); |
map_physmem(ph_addr, *addr, 1, AS_AREA_READ | AS_AREA_CACHEABLE); |
} |
ipc_answer_fast(callid, 0, (ipcarg_t)addr, AS_AREA_READ); |
ipc_answer_fast(callid, 0, (ipcarg_t)*addr, AS_AREA_READ); |
} |
int main(int argc, char **argv) |
109,7 → 112,16 |
callid = ipc_wait_for_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_AS_AREA_RECV: |
get_realtime_as(callid, &call); |
switch (IPC_GET_ARG3(call)) { |
case SERVICE_MEM_REALTIME: |
get_as(callid, &call, "clock.faddr", &clockaddr); |
break; |
case SERVICE_MEM_KLOG: |
get_as(callid, &call, "klog.faddr", &klogaddr); |
break; |
default: |
ipc_answer_fast(callid, ENOENT, 0, 0); |
} |
continue; |
case IPC_M_PHONE_HUNGUP: |
retval = 0; |
/uspace/trunk/klog/Makefile |
---|
0,0 → 1,73 |
# |
# Copyright (C) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Setup toolchain |
# |
LIBC_PREFIX = ../libc |
SOFTINT_PREFIX = ../softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
## Sources |
# |
OUTPUT = klog |
SOURCES = \ |
klog.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/uspace/trunk/klog/klog.c |
---|
0,0 → 1,78 |
/* |
* Copyright (C) 2006 Ondrej Palkovsky |
* 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. |
*/ |
#include <stdio.h> |
#include <ipc/ipc.h> |
#include <async.h> |
#include <ipc/services.h> |
#include <as.h> |
#include <kernel/ipc/irq.h> |
/* Pointer to klog area */ |
static char *klog; |
void interrupt_received(ipc_callid_t callid, ipc_call_t *call) |
{ |
int i; |
// psthread_serialize_start(); |
/* TODO: remove workaround around non-functional vsnprintf */ |
for (i=0; klog[i + IPC_GET_ARG2(*call)] && i < IPC_GET_ARG3(*call); i++) |
putchar(klog[i + IPC_GET_ARG2(*call)]); |
putchar('\n'); |
// psthread_serialize_done(); |
} |
int main(int argc, char *argv[]) |
{ |
int res; |
void *mapping; |
printf("Kernel console output.\n"); |
mapping = as_get_mappable_page(PAGE_SIZE); |
res = ipc_call_sync_3(PHONE_NS, IPC_M_AS_AREA_RECV, |
(sysarg_t)mapping, PAGE_SIZE, SERVICE_MEM_KLOG, |
NULL,NULL,NULL); |
if (res) { |
printf("Failed to initialize klog memarea\n"); |
_exit(1); |
} |
klog = mapping; |
if (ipc_register_irq(IPC_IRQ_KLOG, NULL)) { |
printf("Error registering for klog service.\n"); |
return 0; |
} |
async_set_interrupt_received(interrupt_received); |
async_manager(); |
return 0; |
} |
/uspace/trunk/libc/include/async.h |
---|
98,12 → 98,10 |
void async_create_manager(void); |
void async_destroy_manager(void); |
void async_set_client_connection(async_client_conn_t conn); |
void async_set_interrupt_received(async_client_conn_t conn); |
int _async_init(void); |
/* Should be defined by application */ |
void interrupt_received(ipc_call_t *call) __attribute__((weak)); |
extern atomic_t async_futex; |
#endif |
/uspace/trunk/libc/include/ipc/services.h |
---|
41,5 → 41,6 |
/* Memory area to be received from NS */ |
#define SERVICE_MEM_REALTIME 1 |
#define SERVICE_MEM_KLOG 2 |
#endif |
/uspace/trunk/libc/generic/time.c |
---|
34,6 → 34,7 |
#include <unistd.h> |
#include <atomic.h> |
#include <futex.h> |
#include <ipc/services.h> |
#include <sysinfo.h> |
#include <as.h> |
67,7 → 68,7 |
mapping = as_get_mappable_page(PAGE_SIZE); |
/* Get the mapping of kernel clock */ |
res = ipc_call_sync_3(PHONE_NS, IPC_M_AS_AREA_RECV, |
mapping, PAGE_SIZE, 0, |
mapping, PAGE_SIZE, SERVICE_MEM_REALTIME, |
NULL,&rights,NULL); |
if (res) { |
printf("Failed to initialize timeofday memarea\n"); |
/uspace/trunk/libc/generic/async.c |
---|
138,7 → 138,9 |
__thread connection_t *PS_connection; |
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call); |
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call); |
static async_client_conn_t client_connection = default_client_connection; |
static async_client_conn_t interrupt_received = default_interrupt_received; |
/** Add microseconds to give timeval */ |
static void tv_add(struct timeval *tv, suseconds_t usecs) |
341,17 → 343,10 |
{ |
ipc_answer_fast(callid, ENOENT, 0, 0); |
} |
/** Function that gets called on interrupt receival |
* |
* This function is defined as a weak symbol - to be redefined in |
* user code. |
*/ |
void interrupt_received(ipc_call_t *call) |
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call) |
{ |
} |
/** Wrapper for client connection thread |
* |
* When new connection arrives, thread with this function is created. |
440,7 → 435,7 |
/* Unrouted call - do some default behaviour */ |
switch (IPC_GET_METHOD(*call)) { |
case IPC_M_INTERRUPT: |
interrupt_received(call); |
(*interrupt_received)(callid,call); |
return; |
case IPC_M_CONNECT_ME_TO: |
/* Open new connection with thread etc. */ |
757,3 → 752,7 |
{ |
client_connection = conn; |
} |
void async_set_interrupt_received(async_client_conn_t conn) |
{ |
interrupt_received = conn; |
} |
/uspace/trunk/Makefile |
---|
39,7 → 39,9 |
ns \ |
fb \ |
console \ |
tetris |
tetris \ |
ipcc \ |
klog |
ifeq ($(ARCH), amd64) |
DIRS += pci \ |
/uspace/trunk/ipcc/ipcc.c |
---|
0,0 → 1,233 |
#include <stdio.h> |
#include <async.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <errno.h> |
#define TEST_START 10000 |
#define MAXLIST 4 |
#define MSG_HANG_ME_UP 2000 |
static int connections[50]; |
static ipc_callid_t callids[50]; |
static int phones[20]; |
static int myservice = 0; |
static void client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
ipcarg_t phonehash = icall->in_phone_hash; |
int retval; |
int i; |
printf("Connected phone: %P, accepting\n", icall->in_phone_hash); |
ipc_answer_fast(iid, 0, 0, 0); |
for (i=0;i < 1024;i++) |
if (!connections[i]) { |
connections[i] = phonehash; |
break; |
} |
while (1) { |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
printf("Phone (%P) hung up.\n", phonehash); |
retval = 0; |
break; |
default: |
printf("Received message from %P: %X\n", phonehash,callid); |
for (i=0; i < 1024; i++) |
if (!callids[i]) { |
callids[i] = callid; |
break; |
} |
continue; |
} |
ipc_answer_fast(callid, retval, 0, 0); |
} |
} |
static void printhelp(void) |
{ |
printf("? - help\n"); |
printf("c - connect to other service\n"); |
printf("h - hangup connection\n"); |
printf("a - send async message to other service\n"); |
printf("s - send sync message to other service\n"); |
printf("d - answer message that we have received\n"); |
printf("j - jump to endless loop\n"); |
printf("p - page fault\n"); |
} |
static void callback(void *private, int retval, ipc_call_t *data) |
{ |
printf("Received response to msg %d - retval: %d.\n", private, |
retval); |
} |
static void do_answer_msg(void) |
{ |
int i,cnt, errn; |
char c; |
ipc_callid_t callid; |
cnt = 0; |
for (i=0;i < 50;i++) { |
if (callids[i]) { |
printf("%d: %P\n", cnt, callids[i]); |
cnt++; |
} |
if (cnt >= 10) |
break; |
} |
if (!cnt) |
return; |
printf("Choose message:\n"); |
do { |
c = getchar(); |
} while (c < '0' || (c-'0') >= cnt); |
cnt = c - '0' + 1; |
for (i=0;cnt;i++) |
if (callids[i]) |
cnt--; |
i -= 1; |
printf("Normal (n) or hangup (h) or error(e) message?\n"); |
do { |
c = getchar(); |
} while (c != 'n' && c != 'h' && c != 'e'); |
if (c == 'n') |
errn = 0; |
else if (c == 'h') |
errn = EHANGUP; |
else if (c == 'e') |
errn = ENOENT; |
printf("Answering %P\n", callids[i]); |
ipc_answer_fast(callids[i], errn, 0, 0); |
callids[i] = 0; |
} |
static void do_send_msg(int async) |
{ |
int phoneid; |
int res; |
static int msgid = 1; |
char c; |
printf("Select phoneid to send msg: 2-9\n"); |
do { |
c = getchar(); |
} while (c < '2' || c > '9'); |
phoneid = c - '0'; |
if (async) { |
ipc_call_async(phoneid, 2000, 0, (void *)msgid, callback, 1); |
printf("Async sent - msg %d\n", msgid); |
msgid++; |
} else { |
printf("Sending msg..."); |
res = ipc_call_sync_2(phoneid, 2000, 0, 0, NULL, NULL); |
printf("done: %d\n", res); |
} |
} |
static void do_hangup(void) |
{ |
char c; |
int res; |
int phoneid; |
printf("Select phoneid to hangup: 2-9\n"); |
do { |
c = getchar(); |
} while (c < '2' || c > '9'); |
phoneid = c - '0'; |
printf("Hanging up..."); |
res = ipc_hangup(phoneid); |
printf("done: %d\n", phoneid); |
} |
static void do_connect(void) |
{ |
char c; |
int svc; |
int phid; |
printf("Choose one service: 0:10000....9:10009\n"); |
do { |
c = getchar(); |
} while (c < '0' || c > '9'); |
svc = TEST_START + c - '0'; |
if (svc == myservice) { |
printf("Currently cannot connect to myself, update test\n"); |
return; |
} |
printf("Connecting to %d..", svc); |
phid = ipc_connect_me_to(PHONE_NS, svc, 0); |
if (phid > 0) { |
printf("phoneid: %d\n", phid); |
phones[phid] = 1; |
} else |
printf("error: %d\n", phid); |
} |
int main(void) |
{ |
ipcarg_t phonead; |
int i; |
char c; |
int res; |
printf("********************************\n"); |
printf("***********IPC Tester***********\n"); |
printf("********************************\n"); |
async_set_client_connection(client_connection); |
for (i=TEST_START;i < TEST_START+10;i++) { |
res = ipc_connect_to_me(PHONE_NS, i, 0, &phonead); |
if (!res) |
break; |
printf("Failed registering as %d..:%d\n", i, res); |
} |
printf("Registered as service: %d\n", i); |
myservice = i; |
printhelp(); |
while (1) { |
c = getchar(); |
switch (c) { |
case '?': |
printhelp(); |
break; |
case 'h': |
do_hangup(); |
break; |
case 'c': |
do_connect(); |
break; |
case 'a': |
do_send_msg(1); |
break; |
case 's': |
do_send_msg(0); |
break; |
case 'd': |
do_answer_msg(); |
break; |
case 'j': |
while (1) |
; |
case 'p': |
printf("Doing page fault\n"); |
*((char *)0) = 1; |
printf("done\n"); |
} |
} |
} |
/uspace/trunk/ipcc/Makefile |
---|
0,0 → 1,73 |
# |
# Copyright (C) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Setup toolchain |
# |
LIBC_PREFIX = ../libc |
SOFTINT_PREFIX = ../softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../kbd/include |
LIBS = $(LIBC_PREFIX)/libc.a |
## Sources |
# |
OUTPUT = ipcc |
SOURCES = ipcc.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |