From 58115dc00010269322dc8c62ca7172fa06280e2c Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Mon, 16 May 2011 13:26:49 +0200 Subject: [PATCH 1/6] New Makefile target: qemudbg This target starts qemu in Debug-Mode and GDB. There is a GDB-Script file script.gdb which is extensible to match your debugging needs. --- Makefile.example | 9 +++++++++ script.gdb | 7 +++++++ 2 files changed, 16 insertions(+) create mode 100644 script.gdb diff --git a/Makefile.example b/Makefile.example index 1614b2ff..554c241d 100644 --- a/Makefile.example +++ b/Makefile.example @@ -19,6 +19,8 @@ RANLIB_FOR_TARGET=ranlib STRIP_FOR_TARGET=strip READELF_FOR_TARGET=readelf NASM = nasm +EMU=qemu +GDB=gdb MAKE = make NASMFLAGS = -felf32 -g @@ -71,6 +73,13 @@ $(NAME).elf: qemu: newlib tools $(NAME).elf qemu -smp 2 -net nic,model=rtl8139 -net user,hostfwd=tcp::12345-:7 -net dump -kernel metalsvm.elf -initrd tools/initrd.img +qemudbg: newlib tools $(NAME).elf + qemu -S -s -smp 2 -net nic,model=rtl8139 -net user,hostfwd=tcp::12345-:7 -net dump -kernel metalsvm.elf -initrd tools/initrd.img + +gdb: $(NAME).elf + make qemudbg > /dev/null & + $(GDB) -x script.gdb + clean: $Q$(RM) $(NAME).elf $(NAME).sym *~ $Q$(MAKE) -C tools clean diff --git a/script.gdb b/script.gdb new file mode 100644 index 00000000..644bde95 --- /dev/null +++ b/script.gdb @@ -0,0 +1,7 @@ +# Constant part of the script +symbol-file metalsvm.sym +target remote localhost:1234 + +# Configure breakpoints and everything as you wish here. +break main +continue From 098546fe2597f34f89a3c6bd22f49641fdf339f1 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 17 May 2011 08:09:40 -0700 Subject: [PATCH 2/6] fix typo in the declaration of icc_ping --- arch/x86/include/asm/icc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/icc.h b/arch/x86/include/asm/icc.h index 31fdb2ef..dfc69302 100644 --- a/arch/x86/include/asm/icc.h +++ b/arch/x86/include/asm/icc.h @@ -51,9 +51,9 @@ typedef struct { #define ICC_TYPE_PINGRESPONSE (1 << 3) int icc_init(void); -int icc_ping(); +int icc_ping(int ue); void icc_check(void); - +int icc_halt(void); #endif #ifdef __cplusplus From 7970899fd1dc96f921f9702b03fd07e3024a640d Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 17 May 2011 08:12:56 -0700 Subject: [PATCH 3/6] use HALT instead of NOP8 --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index f70a84ee..c6241d52 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -118,7 +118,7 @@ int mmu_init(void) } else { kputs("Unable to initialize the memory management subsystem\n"); while(1) { - NOP8; + HALT; } } From 08f51532578871c4615ef66c870294dd4308dc6d Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 17 May 2011 08:13:20 -0700 Subject: [PATCH 4/6] add the support of inter core interrupts --- arch/x86/kernel/irq.c | 3 ++ arch/x86/kernel/timer.c | 9 +++- arch/x86/scc/icc.c | 106 +++++++++++++++++++++++++++++++++------- kernel/main.c | 4 ++ kernel/tasks.c | 2 - kernel/tests.c | 2 +- 6 files changed, 103 insertions(+), 23 deletions(-) diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 247a55ea..3c4b621f 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -234,6 +234,9 @@ void irq_handler(struct state *s) /* This is a blank function pointer */ void (*handler) (struct state * s); + // at first, we check our work queues + check_workqueues(); + /* * Find out if we have a custom handler to run for this * IRQ and then finally, run it diff --git a/arch/x86/kernel/timer.c b/arch/x86/kernel/timer.c index 617d47d9..73c83a51 100644 --- a/arch/x86/kernel/timer.c +++ b/arch/x86/kernel/timer.c @@ -80,8 +80,15 @@ void timer_wait(unsigned int ticks) { uint64_t eticks = timer_ticks + ticks; - while (timer_ticks < eticks) + while (timer_ticks < eticks) { + check_workqueues(); + + // recheck break condition + if (timer_ticks >= eticks) + break; + reschedule(); + } } #define LATCH(f) ((CLOCK_TICK_RATE + f/2) / f) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 58a89be5..734898cc 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -18,8 +18,10 @@ #include #include #include +#include #ifdef CONFIG_ROCKCREEK #include +#include #include #include #include @@ -72,9 +74,20 @@ static int scc_clear(void) return 0; } +static void intr_handler(struct state *s) +{ + // reset appropriate bit in the core configuration register + int tmp, z; + + z = Z_PID(RC_COREID[my_ue]); + tmp=ReadConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1)); + tmp &= ~2; + SetConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1), tmp); +} + int icc_init(void) { - int i; + int i, z, tmp; uint64_t start, end, ticks, freq = 533; uint32_t cr4, msg = 0; @@ -117,9 +130,6 @@ int icc_init(void) num_ues = RCCE_num_ues(); kprintf("Got rank %d of %d ranks\n", my_ue, num_ues); - i = ReadConfigReg(CRB_OWN+GLCFG0); - kprintf("glcfg0 0x%x\n", i); - RCCE_barrier(&RCCE_COMM_WORLD); kputs("RCCE test...\t"); @@ -130,11 +140,60 @@ int icc_init(void) else kprintf("failed! (0x%x)\n", msg); + // reset INTR/LINT0 flag + z = Z_PID(RC_COREID[my_ue]); + tmp=ReadConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1)); + tmp &= ~2; + SetConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1), tmp); + + // set interrupt handler (INTR/LINT0) + irq_install_handler(124, intr_handler); + kputs("Now, the SCC is initialized!\n"); return 0; } +static inline int icc_send_irq(int ue) +{ + int tmp, x, y, z, addr; + + z = Z_PID(RC_COREID[ue]); + x = X_PID(RC_COREID[ue]); + y = Y_PID(RC_COREID[ue]); + addr = CRB_ADDR(x,y) + (z==0 ? GLCFG0 : GLCFG1); + + // send interrupt to ue + do { + tmp=ReadConfigReg(addr); + } while(tmp & 2); + tmp |= 2; + SetConfigReg(addr, tmp); + + return 0; +} + +int icc_halt(void) +{ + uint32_t flags; + uint32_t do_send = 1; + + do { + // iRCCE is not thread save => disable interrupts + flags = irq_nested_disable(); + + if (do_send) + do_send = (iRCCE_isend_push() == iRCCE_PENDING); + icc_check(); + + irq_nested_enable(flags); + } while(do_send); + + HALT; + + return 0; +} + int icc_ping(int ue) { icc_header_t ping_header = {ICC_TYPE_PINGREQUEST, 0, sizeof(uint64_t)}; @@ -159,6 +218,9 @@ int icc_ping(int ue) while(iRCCE_isend_test(&send_request, NULL) != iRCCE_SUCCESS) icc_check(); // oh, we have time to check incoming requests + // wake up receiver + icc_send_irq(ue); + irq_nested_enable(flags); return 0; @@ -180,7 +242,10 @@ static void interpret_header(icc_header_t* header, int recv_ue) iRCCE_irecv_wait(&recv_req); iRCCE_isend((char*) &tsc, sizeof(uint64_t), recv_ue, NULL); - iRCCE_isend_push(); + if (iRCCE_isend_push() == iRCCE_PENDING) + iRCCE_isend_push(); + + icc_send_irq(recv_ue); } break; case ICC_TYPE_PINGRESPONSE: { @@ -206,9 +271,20 @@ void icc_check(void) { static icc_header_t header[MAX_SCC_CORES]; static iRCCE_RECV_REQUEST request[MAX_SCC_CORES]; - static int8_t pending[MAX_SCC_CORES] = {[0 ... MAX_SCC_CORES-1] = 0}; + static int8_t first_call = 1; int i, ret; + if (first_call) { + first_call = 0; + + for(i=0; i 1 spinlock_irqsave_lock(&table_lock); #endif diff --git a/kernel/tests.c b/kernel/tests.c index 72869600..5c26d41d 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -93,7 +93,7 @@ static int STDCALL ping(void* arg) for(i=0; i<20; i++) { icc_ping(1); - sleep(1); + HALT; } return 0; From fc17e7710de8ea49cc030806c143b7064f8a3d2e Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 18 May 2011 00:37:25 -0700 Subject: [PATCH 5/6] simplify pingpong benchmark --- arch/x86/scc/icc.c | 53 +++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 734898cc..05292396 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -165,6 +165,7 @@ static inline int icc_send_irq(int ue) // send interrupt to ue do { + NOP1; tmp=ReadConfigReg(addr); } while(tmp & 2); tmp |= 2; @@ -194,29 +195,32 @@ int icc_halt(void) return 0; } +static volatile uint64_t ping_start = 0; +static icc_header_t ping_request = {ICC_TYPE_PINGREQUEST, 0, 0}; +static icc_header_t ping_response = {ICC_TYPE_PINGRESPONSE, 0, 0}; + int icc_ping(int ue) { - icc_header_t ping_header = {ICC_TYPE_PINGREQUEST, 0, sizeof(uint64_t)}; - uint64_t tsc; uint32_t flags; - iRCCE_SEND_REQUEST send_request; if (BUILTIN_EXPECT(ue == my_ue, 0)) return -EINVAL; if (BUILTIN_EXPECT((ue < 0) || (ue >= num_ues), 0)) return -EINVAL; - tsc = rdtsc(); + while(ping_start) { + NOP8; + } + + ping_start = rdtsc(); // iRCCE is not thread save => disable interrupts flags = irq_nested_disable(); - iRCCE_isend((char*) &ping_header, sizeof(icc_header_t), ue, NULL); - iRCCE_isend((char*) &tsc, sizeof(uint64_t), ue, &send_request); + iRCCE_isend((char*) &ping_request, sizeof(icc_header_t), ue, NULL); - // waiting for the completion - while(iRCCE_isend_test(&send_request, NULL) != iRCCE_SUCCESS) - icc_check(); // oh, we have time to check incoming requests + // wait some time + NOP8; // wake up receiver icc_send_irq(ue); @@ -233,30 +237,19 @@ static void interpret_header(icc_header_t* header, int recv_ue) switch(header->type) { case ICC_TYPE_PINGREQUEST: { - icc_header_t response = {ICC_TYPE_PINGRESPONSE, 0, sizeof(uint64_t)}; - iRCCE_RECV_REQUEST recv_req; - uint64_t tsc; - iRCCE_isend((char*) &response, sizeof(icc_header_t), recv_ue, NULL); - if (iRCCE_irecv((char*) &tsc, sizeof(uint64_t), recv_ue, &recv_req) != iRCCE_SUCCESS) - iRCCE_irecv_wait(&recv_req); + iRCCE_isend((char*) &ping_response, sizeof(icc_header_t), recv_ue, NULL); - iRCCE_isend((char*) &tsc, sizeof(uint64_t), recv_ue, NULL); - if (iRCCE_isend_push() == iRCCE_PENDING) - iRCCE_isend_push(); + // wait some time + NOP8; + // wake up remote core icc_send_irq(recv_ue); } break; - case ICC_TYPE_PINGRESPONSE: { - uint64_t start, end; - iRCCE_RECV_REQUEST recv_req; - - if (iRCCE_irecv((char*) &start, sizeof(uint64_t), recv_ue, &recv_req) != iRCCE_SUCCESS) - iRCCE_irecv_wait(&recv_req); - end = rdtsc(); - kprintf("Receive ping response. Ticks: %d\n", end-start); - } + case ICC_TYPE_PINGRESPONSE: + kprintf("Receive ping response. Ticks: %d\n", rdtsc()-ping_start); + ping_start = 0; break; default: kprintf("Receive unknown ICC message (%d)\n", header->type); @@ -286,7 +279,6 @@ void icc_check(void) } // pushes the progress of non-blocking communication requests - iRCCE_isend_push(); iRCCE_irecv_push(); for(i=0; i Date: Wed, 18 May 2011 18:14:23 +0200 Subject: [PATCH 6/6] add lseek (SEEK_SET, SEEK_CUR, SEEK_END) - still missing some filetype checking --- include/metalsvm/stdio.h | 10 ++++++++++ kernel/syscall.c | 30 ++++++++++++++++++++++++++---- newlib/examples/hello.c | 1 + newlib/examples/test | 2 +- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/include/metalsvm/stdio.h b/include/metalsvm/stdio.h index 6f9fc20e..527fd2b4 100644 --- a/include/metalsvm/stdio.h +++ b/include/metalsvm/stdio.h @@ -23,6 +23,16 @@ * @brief Stringstream related functions. Mainly printf-stuff. */ +#ifndef SEEK_SET +#define SEEK_SET 0 /* set file offset to offset */ +#endif +#ifndef SEEK_CUR +#define SEEK_CUR 1 /* set file offset to current plus offset */ +#endif +#ifndef SEEK_END +#define SEEK_END 2 /* set file offset to EOF plus offset */ +#endif + #ifndef __STDIO_H__ #define __STDIO_H__ diff --git a/kernel/syscall.c b/kernel/syscall.c index 46471282..bff2f279 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -29,7 +29,7 @@ static int sys_write(int fd, const char *buf, size_t len) { unsigned int wrotebytes; wrotebytes = write_fs(per_core(current_task)->fildes_table[fd].node, (uint8_t*)buf, len, per_core(current_task)->fildes_table[fd].offset); - kprintf("writing into filesystem -- fd:%i, Filelength:%i, Writtenbytes: %i, Bufferlength: %s \n", fd, len, wrotebytes, buf); + //kprintf("writing into filesystem -- fd:%i, Filelength:%i, Writtenbytes: %i, Bufferlength: %s \n", fd, len, wrotebytes, buf); per_core(current_task)->fildes_table[fd].offset += wrotebytes; return wrotebytes; @@ -74,8 +74,31 @@ static int sys_read(int fd, const char *buf, size_t len) static int sys_lseek(int fd, off_t pos, int origin) { - kprintf("lseek used, but not ready yet"); - return 0; + int ret = -EINVAL; + + /* Beware: still not checking the filetype & size*/ + + switch(origin) + { + case SEEK_SET: { /* set file offset to offset */ + per_core(current_task)->fildes_table[fd].offset = pos; + ret = 0; + break; + } + case SEEK_CUR: { /* set file offset to current plus offset */ + ret = pos + per_core(current_task)->fildes_table[fd].offset; + break; + } + case SEEK_END: { /* set file offset to EOF plus offset */ + per_core(current_task)->fildes_table[fd].offset = pos + per_core(current_task)->fildes_table[fd].node->block_size; + ret = 0; + break; + } + default: + ret = -EINVAL; + break; + } + return ret; } static int sys_sbrk(int incr) @@ -150,7 +173,6 @@ int syscall_handler(uint32_t sys_nr, ...) off_t pos = va_arg(vl, off_t); int origin = va_arg(vl, int); ret = sys_lseek(fd, pos, origin); - kprintf("hallo!!! %i", ret); break; } case __NR_sbrk: { diff --git a/newlib/examples/hello.c b/newlib/examples/hello.c index 6ec4d968..c0336af9 100644 --- a/newlib/examples/hello.c +++ b/newlib/examples/hello.c @@ -35,6 +35,7 @@ int main(int argc, char** argv) setbuf(testfile, NULL); fflush(NULL); fwrite("wsx", 3, 1, testfile); + fseek(testfile, 2, SEEK_CUR); fwrite("nextnextnext", 1, 10, testfile); fclose(testfile); diff --git a/newlib/examples/test b/newlib/examples/test index 4bcfe98e..28d14454 100644 --- a/newlib/examples/test +++ b/newlib/examples/test @@ -1 +1 @@ -d +123456789