090205

|



ちょっと気合い入れて全部刻みました。ベニヤ板の切断には下にスタイロフォー
ムを置いてその上から丸ノコで切るととても調子がいいです。今迄気付かなかっ
たのが悔やまれる。



今回、溝の正確さは今迄で一番なのだけど、そうなるとケガキの適当さが組み立ての時に問題に。ガタがないから歪んでしまって。なかなか難しい。

3664の続きです。サブルーチンコールからスレッドをスイッチするところは こう変更。__NORMAL_MODE__は-mnオプションで自動的にgccがデファインしてくれる。
rtsとrteのスタック状態を合わせるために2byteインクリメントしてます。ポイ ンタから値をとってくる部分も全部変更しないとだめ。mov.lのままだとお目当 ての部分は上位のe3に入ってしまう。リトルエンディアンだったらよかったの にね...。
	.globl _do_thread_switch
_do_thread_switch:
	; save context.
#ifdef __NORMAL_MODE__
	subs	#2,	er7
	mov.w	@_current_thread, r3
#else
	mov.l	@_current_thread, er3
#endif
	stc.b	ccr,	r0l
	mov.b	r0l,	@er7	; set CCR to MSB of return address.
	mov.l	er7, @(0x1c, er3) ; sp
	mov.l	er6, @(0x18, er3) ; callee saved
	mov.l	er5, @(0x14, er3) ; callee saved
	mov.l	er4, @(0x10, er3) ; callee saved
	; no need to store caller saved. (this is subroutine call.)

	jsr	@_thread_context_switch
#ifdef __NORMAL_MODE__
	mov.w	@_current_thread, r0
#else
	mov.l	@_current_thread, er0
#endif
	mov.l	@(0x1c, er0), er7  ; sp
	mov.l	@(0x18, er0), er6 ; callee saved
	mov.l	@(0x14, er0), er5 ; callee saved
	mov.l	@(0x10, er0), er4 ; callee saved
	mov.l	@(0x0c, er0), er3 ; caller saved
	mov.l	@(0x08, er0), er2 ; caller saved
	mov.l	@(0x04, er0), er1 ; caller saved
	mov.l	@(0x00, er0), er0 ; caller saved
	; resume interrupt. and return
	rte
スレッドの初期設定の部分も書き替えます。もうかなりイヤーなコードになっ てます。intを使ってもうちょっとすっきりさせることはできるけれど、逆に intもポインタもコロコロ変わる状況だと、できるだけ確定しておきたいという 気持ちもあって。あっと思ったらオーバーフローしてたというのがつらい。
thread_t
thread_create (uint8_t *thread_area, size_t stack_size, const char *name,
	       void (*start)(uint32_t), uint32_t arg)
{
  uint8_t s = intr_suspend ();
  struct thread_control *tc = (struct thread_control *)thread_area;

  __thread_setup (tc, stack_size, name);
  tc->regs.er0 = arg; // pass 1st arg.

#ifdef __NORMAL_MODE__
  tc->regs.sp = (uint32_t)(uint16_t)tc->stack_bottom;
  iprintf ("regs.sp = %x\n", tc->regs.sp);
#else
  tc->regs.sp = (uint32_t)tc->stack_bottom;
#endif
  // install return address for 'rts/rte'
#ifdef __NORMAL_MODE__
  *(uint32_t *)tc->stack_bottom = (uint16_t)start;
#else
  //  tc->regs.sp = (uint32_t)start;
  *(uint32_t *)tc->regs.sp = (uint32_t)start;
#endif
  intr_resume (s);
  LPRINTF ("[%d]:%s pc=%A sp=%x *sp=%x stack=%dbyte\n", tc->id, tc->name,
	   start, tc->regs.sp, *(uint32_t *)tc->stack_bottom, stack_size);

  return tc;
}
なんとかスレッドは動いたっぽい。まだタイマを実装してなく、遅延ディスパッ チが動かないので本当に動いているかまだ微妙。