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/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 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..05292396 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,34 +140,90 @@ 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 { + NOP1; + 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; +} + +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); irq_nested_enable(flags); @@ -171,27 +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); - 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); @@ -206,31 +264,36 @@ 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; ifildes_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; @@ -75,8 +75,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) @@ -151,7 +174,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/kernel/tasks.c b/kernel/tasks.c index 88a9bfba..d7e4d4a0 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -714,8 +714,6 @@ void scheduler(void) unsigned int i; unsigned int new_id; - check_workqueues(); - #if MAX_CORES > 1 spinlock_irqsave_lock(&table_lock); #endif diff --git a/kernel/tests.c b/kernel/tests.c index eae9d856..3b8eb57b 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; 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; } } diff --git a/newlib/examples/hello.c b/newlib/examples/hello.c index 4bc7817c..134f2522 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 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