diff -ruN porting03/ppc-stub.c porting05/ppc-stub.c --- porting03/ppc-stub.c Tue Apr 7 23:21:40 2009 +++ porting05/ppc-stub.c Sun Apr 12 12:09:59 2009 @@ -119,7 +119,7 @@ static const char hexchars[]="0123456789abcdef"; /* Number of registers. */ -#define NUMREGS (32+2*32+6) /* GPR(32), FPR(32), SRR0/1, CR, CTR, LR, XER */ +#define NUMREGS (32+2*32+7) /* GPR(32), FPR(32), SRR0/1, CR, CTR, LR, XER, FPSCR */ /* Number of bytes of registers. */ #define NUMREGBYTES (NUMREGS * 4) @@ -132,9 +132,9 @@ GPR16, GPR17, GPR18, GPR19, GPR20, GPR21, GPR22, GPR23, GPR24, GPR25, GPR26, GPR27, GPR28, GPR29, GPR30, GPR31, - /* FPR * 32 */ + FPRS, /* FPR * 32 */ - SRR0 = (32+2*32), SRR1, CR, LR, CTR, XER + SRR0 = (32+2*32), SRR1, CR, LR, CTR, XER, FPSCR }; #define SP GPR1 @@ -190,7 +190,12 @@ that trace flag works right. */ asm(" iret"); -#define BREAKPOINT() asm(" trap"); +static int breaking = 0; +#define BREAKPOINT() { \ + breaking++; \ + asm(" trap"); \ + asm(" nop"); \ + } /* Put the error code here just in case the user cares. */ int gdb_i386errcode; @@ -780,12 +785,18 @@ /* reply to host that an exception has occurred */ sigval = computeSignal (exceptionVector); + if (breaking && (sigval == 5) && (registers[MSR] & (1<<17))) { + breaking--; + registers[PC] += 4; + } + ptr = remcomOutBuffer; *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ *ptr++ = hexchars[sigval >> 4]; *ptr++ = hexchars[sigval & 0xf]; +#if 0 /* See gdb/regformats/reg-ppc.dat */ *ptr++ = hexchars[SP]; *ptr++ = ':'; @@ -796,6 +807,7 @@ *ptr++ = ':'; ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); /* PC */ *ptr++ = ';'; +#endif strcpy(ptr, "thread:"); ptr += 7; @@ -911,11 +923,11 @@ newPC = registers[PC]; /* clear the trace bit */ - registers[MSR] &= MSR_SE; + registers[MSR] &= ~(MSR_SE /* | MSR_BE */); /* set the trace bit if we're stepping */ if (stepping) - registers[MSR] |= MSR_SE; + registers[MSR] |= (MSR_SE /* | MSR_BE */); #if 0 _returnFromException (); /* this is a jump */ diff -ruN porting03/serial.c porting05/serial.c --- porting03/serial.c Tue Apr 7 23:21:40 2009 +++ porting05/serial.c Sun Apr 12 13:17:41 2009 @@ -78,6 +78,14 @@ return psc->psc_status & PSC_SR_RXRDY; } +static void udelay(int usec) +{ + volatile int i; + /* とりあえずてきとうな回数でのダミーループでウエイトを置く */ + for (i = 0; i < (save_clk / 1000000) * usec; i++) + ; +} + void serial_putc(int index, char c) { volatile struct mpc5xxx_psc *psc = regs[index].psc; @@ -88,6 +96,12 @@ while (!(psc->psc_status & PSC_SR_TXEMP)) { /* waiting */ } + + /* + * フロー制御が無い場合のバッファ溢れ防止として,ウエイトを置く. + * データの取りこぼしが発生しているようなら,ウエイトを増やすこと. + */ + udelay(20); psc->psc_buffer_8 = c; } diff -ruN porting03/startup.s porting05/startup.s --- porting03/startup.s Tue Apr 7 23:21:40 2009 +++ porting05/startup.s Sun Apr 12 12:09:59 2009 @@ -22,23 +22,22 @@ ori 1,1,0x200000@l stwu 1,-160(1) - stmw 2,8(1) - stw 0,4(1) + stmw 0,8(1) mfsprg2 2 - stw 2,0(1) + stw 2,12(1) mflr 2 - stw 2,128(1) + stw 2,136(1) mfcr 2 - stw 2,132(1) + stw 2,140(1) mfctr 2 - stw 2,136(1) + stw 2,144(1) mfxer 2 - stw 2,140(1) + stw 2,148(1) mfsrr0 4 - stw 4,144(1) + stw 4,152(1) mfsrr1 5 - stw 5,148(1) + stw 5,156(1) bl 1f 1: mflr 3 @@ -54,25 +53,26 @@ .type dispatch,@function dispatch: mr 1,3 + addi 1,1,-8 return_from_interrupt: - lwz 2,128(1) + lwz 2,136(1) mtlr 2 - lwz 2,132(1) + lwz 2,140(1) mtcr 2 - lwz 2,136(1) + lwz 2,144(1) mtctr 2 - lwz 2,140(1) + lwz 2,148(1) mtxer 2 - lwz 2,144(1) + lwz 2,152(1) mtsrr0 2 - lwz 2,148(1) + lwz 2,156(1) andi. 2,2,0xffff mtsrr1 2 - lmw 2,8(1) - lwz 0,4(1) - lwz 1,0(1) + lmw 2,16(1) + lwz 0,8(1) + lwz 1,12(1) sync isync diff -ruN porting03/stublib.c porting05/stublib.c --- porting03/stublib.c Tue Apr 7 23:21:40 2009 +++ porting05/stublib.c Sun Apr 12 12:09:59 2009 @@ -1,3 +1,5 @@ +#include + #include "kozos.h" #include "thread.h" #include "stublib.h" @@ -5,13 +7,10 @@ #include "lib.h" -#define SERIAL_NUMBER 0 +#define SERIAL_NUMBER 1 /* Number of registers. */ -#define NUMREGS (32+2*32+6) /* GPR(32), FPR(32), SRR0/1, CR, CTR, LR, XER */ - -/* Number of bytes of registers. */ -#define NUMREGBYTES (NUMREGS * 4) +#define NUMREGS (32+2*32+7) /* GPR(32), FPR(32), SRR0/1, CR, CTR, LR, XER, FPSCR */ enum regnames { GPR0, GPR1, GPR2, GPR3, GPR4, GPR5, GPR6, GPR7, @@ -19,10 +18,10 @@ GPR16, GPR17, GPR18, GPR19, GPR20, GPR21, GPR22, GPR23, GPR24, GPR25, GPR26, GPR27, GPR28, GPR29, GPR30, GPR31, - /* FPR * 32 */ + FPRS, /* FPR * 32 */ /* See gdb/ppc-linux-nat.c or gdb/regformats/reg-ppc.dat */ - SRR0 = (32+2*32), SRR1, CR, LR, CTR, XER + SRR0 = (32+2*32), SRR1, CR, LR, CTR, XER, FPSCR }; #define SP GPR1 @@ -65,12 +64,8 @@ void stub_store_regs(kz_thread *thp) { - memset(registers, 0, sizeof(registers)); - - /* 注意:grp0,gpr1は逆に格納されている */ - registers[GPR1] = thp->context.gpr[0]; - registers[GPR0] = thp->context.gpr[1]; - memcpy(®isters[GPR2], &thp->context.gpr[2], 4*30); + memcpy(®isters[GPR0], &thp->context.gpr[0], sizeof(registers[0]) * 32); + memset(®isters[FPRS], 0, sizeof(registers[0]) * 2 * 32); registers[PC] = thp->context.pc; registers[MSR] = thp->context.msr; @@ -82,9 +77,7 @@ void stub_restore_regs(kz_thread *thp) { - thp->context.gpr[0] = registers[GPR1]; - thp->context.gpr[1] = registers[GPR0]; - memcpy(&thp->context.gpr[2], ®isters[GPR2], 4*30); + memcpy(&thp->context.gpr[0], ®isters[GPR0], sizeof(registers[0]) * 32); thp->context.pc = registers[PC]; thp->context.msr = registers[MSR]; @@ -94,6 +87,22 @@ thp->context.xer = registers[XER]; } +static void clear_icache_all() +{ + extern unsigned long _etext; + int addr; + + asm volatile ("sync"); + asm volatile ("isync"); + + for (addr = 0x0; addr < (int)&_etext; addr += CFG_CACHELINE_SIZE) { + asm volatile ("icbi 0,%0" :: "r"(addr)); + } + + asm volatile ("sync"); + asm volatile ("isync"); +} + int stub_proc(kz_thread *thp, int signo) { gen_thread = thp; @@ -103,7 +112,12 @@ clearDebugChar(); handle_exception(signo); + registers[MSR] &= 0xffff; + stub_restore_regs(gen_thread); + + /* 命令書き換えが行われている場合があるので,命令キャッシュを全クリアする */ + clear_icache_all(); return 0; } diff -ruN porting03/thread.c porting05/thread.c --- porting03/thread.c Tue Apr 7 23:21:40 2009 +++ porting05/thread.c Sun Apr 12 12:09:59 2009 @@ -101,7 +101,7 @@ memset(thp->stack, 0, SIGSTKSZ); - thp->context.gpr[0] = (int)thp->stack; /* GPR0とGPR1は逆に設定 */ + thp->context.gpr[1] = (int)thp->stack; thp->context.gpr[3] = (int)thp; thp->context.gpr[4] = (int)argc; thp->context.gpr[5] = (int)argv; @@ -476,6 +476,7 @@ case 0x07: signo = SIGTRAP; break; case 0x09: signo = SIGALRM; break; case 0x0c: signo = SIGSYS; break; + case 0x0d: signo = SIGTRAP; break; default: signo = SIGBUS; break; @@ -483,8 +484,8 @@ /* _startup.s:_intr でGPR1を INTR_STACK_START - 160 に設定している */ p = (int *)(INTR_STACK_START - 160); + p += 2; for (i = 0; i < 32; i++) { - /* 注意:grp0,gpr1は逆に格納されている */ current->context.gpr[i] = *(p++); } current->context.lr = *(p++); @@ -534,6 +535,8 @@ ; } +void breakpoint(); + void kz_trap() { asm volatile ("trap"); @@ -541,7 +544,7 @@ void kz_break() { - asm volatile ("trap"); + breakpoint(); } void kz_srvcall(kz_syscall_type_t type, kz_syscall_param_t *param)