090919

|


RS125のE/G積んで(結局RS125にした)、CR85の整備。プラグキャップの摩耗の原
因を探るべく、E/G降ろしました。リアマウントが痩せてしまっている。とはい
え、ここが痩せていても左右から押さえてるし、そう問題はないんじゃないか
とも思うのだけど。左右の押さえは力がE/Gにかかるようになっている。以前、
カラーが長すぎてカラーの上でE/Gが踊ってしまうという失敗もあった。今は
十分に押さえ代がある。



とりあえずカラー作成。YH75(A7075相当品)の丸棒から。これは80mm以上の穴開 けになるのでなかなか手間がかかる。どうがんばってもちょっと偏心してしま う。手頃なガンドリルでも探すかな。切子の排出が大変。

半日かかって完成。プラハンで叩いてちょうどくらいのいいところにできた。

これまたヤフオクで落とした90フレームが到着。これはステアリングレースは 使える。マウントブッシュは、ちょっとくたびれか。フレームごと落として部 品とり戦略です。

岡山からメールが来ていた。携帯を見たら昨日から電話が来ていた。携帯は使っ てないのよ。折り返し電話してみると、エントリー締切過ぎてのエントリーな ので5000円と嘆願書の提出が必要とのこと。わざわざすいません。エントリー をお願いしました。
さんざ迷ってて遅れてしまったのだ。体力的に不安だけど、やっぱり年に一度は 岡山走りたいだろー。ということで。行きますよ! 久々にドライで走りたいところ。
SH4A続き。例外をハンドリングします。例外ハンドラはリセットベクタを除き、
VBRの設定でどこにでも設定できる。いろいろ方法はあるけれど、これはすべて
リンカにまかせて

OUTPUT_FORMAT("elf32-shl")
OUTPUT_ARCH(sh)

MEMORY
{
	ram : o = 0xa9000000, l = 0x10000
	vector_generic	: o = 0xa9010100, l = 0x300
	vector_tlbmiss	: o = 0xa9010400, l = 0x200
	vector_interrupt : o = 0xa9010600, l = 0x1000
}

SECTIONS
{
	 _stack_start = 0xa9010000;
	 _VBR = 0xa9010000;

	 .vector_generic :
	 {
	 	 *(.vector_generic)
	 } > vector_generic
	 .vector_tlbmiss :
	 {
	 	 *(.vector_tlbmiss)
	 } > vector_tlbmiss
	 .vector_interrupt :
	 {
	 	 *(.vector_interrupt)
	 } > vector_interrupt

	.text :
	{
		*(.text)
		 *(.rodata*)
		 . = ALIGN (4);
	} > ram

	.data :
	{
		*(.data)
		 . = ALIGN (4);
	} > ram

	.bss :
	{
		 _bss_start = . ;
		*(.bss)
	} > ram
	_bss_end = .;
}

とした。対応するソースは、

#include <asm/asm.h>
	.section	.vector_generic, "ax"	// "A"llocate. e"X"ecute.
	// Use interrupted bank stack pointer.
	stc	spc,	r4	// Bank1
	stc	ssr,	r5	// Bank1
	stc	sgr,	r6	// Bank1
	mov.l	r8,	@-r15
	mov.l	r9,	@-r15
	mov.l	r10,	@-r15
	mov.l	r11,	@-r15
	mov.l	r12,	@-r15
	mov.l	r13,	@-r15
	mov.l	.L_exception_generic	r2
	jsr	@r2
	 mov.l	r14,	@-r15

	mov.l	@r15+,	r14
	mov.l	@r15+,	r13
	mov.l	@r15+,	r12
	mov.l	@r15+,	r11
	mov.l	@r15+,	r10
	mov.l	@r15+,	r9
	rte
	 mov.l	@r15+,	r8
	.align	2
.L_exception_generic:
	.long	_exception_generic

.sectionで、"a"を指定することが重要。勝手に定義したセクション名はこれが
ないとロードされない。このルーチンはバンク0から入ることを想定して、
caller-savedは退避していない。スタックの退避、復帰用のためにプレデクリ
メントストア、ポストインクリメントロードを用意してあるのがいい。ARM
だと、さらに
	stmia	r0!,	{r0-r15}
	ldmia	r0,	{r0-r15}
のように一命令にできてしまうけれど、個人的にはSHくらいがいい落し所だと
思う。MIPSは投げやり過ぎ。

void
exception_generic (uint32_t spc, uint32_t ssr, uint32_t sgr)
{
  uint32_t r;

  CPU_GET_SR (r);
  cpu_dump_sr (r);
  iprintf ("EXTEVT=%x, SPC=%x SSR=%x SGR=%x\n", *EXPEVT, spc, ssr, sgr);

ここで例外の起きた命令を飛ばして次にリターンするように設定。これはテス
トだから。

  // Skip this instruction.
  __asm volatile ("ldc %0, spc" :: "r"(spc + 2));
}


エントリーのルーチンも変更、VBRをldscpritで設定されたところに設定します。
ついでにレジスタバンクも0からスタート。

	.align	2
	.section .text
	.globl	start
start:
1:	mov.l	.L_led, r0
	mov	#0x4,	r1
	mov.l	r1,	@r0
// Set VBR
	mov.l	.L_VBR, r0
	ldc	r0,	vbr
// Change BANK0
	stc	sr,	r1
	mov.l	.L_SR_RB0, r0
	and	r0,	r1
	ldc	r1,	sr
// Jump to C routine.
	mov.l	.L_startup, r0
// Set stack
	mov.l	.L_stack_start, r15
	jmp	@r0
	 nop
	/* NOTREACHED */
	.align	2
.L_led:
	.long	0xa4000008
.L_startup:
	.long	_startup
.L_stack_start:
	.long	_stack_start
.L_VBR:
	.long	_VBR
.L_SR_RB0:
	.long	0xdfffffff


いろいろ例外を意図的に発生させてテスト。


uint32_t
exception (int32_t argc __attribute__((unused)),
     const char *argv[] __attribute__((unused)))
{
一般不当命令例外
  //  __asm volatile (".short 0xfffd");	// 0x180
無条件トラップ
  // __asm volatile ("trapa #33");	// 0x160
スロット不当命令例外
  //  __asm volatile ("1: nop; bra 1b; mov.l 2f, r0;.align 2;2: .long 0xaa");//0x1a0
データアドレスエラー(読み出し)
  //  __asm volatile ("mov r15, r0;add #1, r0;mov.l @r0, r1");// 0xe0
データアドレスエラー(書き込み)
  __asm volatile ("mov r15, r0;add #1, r0;mov.l r1, @r0"); //0x100

  printf ("skip instruction\n");

  return 0;
}

uint32_t
test (int32_t argc __attribute__((unused)),
     const char *argv[] __attribute__((unused)))
{
  uint32_t r;

  CPU_GET_SR (r);
  cpu_dump_sr (r);

  return 0;
}

U-Boot 2008.10-rc2-00002-g87b4ef5-dirty (Sep 18 2008 - 15:01:39)

CPU: SH4
BOARD: Renesas Technology Corp. R0P7785LC0011RL
DRAM:  128MB
FLASH: 64MB
*** Warning - bad CRC, using default environment

PCI: SH7780 PCI host bridge found.
PCI:   Bus Dev VenId DevId Class Int
        00  00  10ec  8169  0200  00
        00  01  1095  3512  0180  00
In:    serial
Out:   serial
Err:   serial
Net:   RTL8169#0
=> bootp
BOOTP broadcast 1
Using RTL8169#0 device
TFTP from server 192.168.33.2; our IP address is 192.168.33.12
Filename 'sh7785.img'.
Load address: 0x9000000
Loading: #####
done
Bytes transferred = 65836 (1012c hex)
=> go 0xa9000000
## Starting application at 0xA9000000 ...
ohayo
Privilege-mode, bank 0, Exception disabled, FPU enabled, IMASK=0xf
mon> test
Privilege-mode, bank 0, Exception enabled, FPU enabled, IMASK=0xf
mon> exception
Privilege-mode, bank 1, Exception disabled, FPU enabled, IMASK=0xf
EXTEVT=100, SPC=a900009c SSR=400000f1 SGR=a900ffb4
skip instruction
mon> test
Privilege-mode, bank 0, Exception enabled, FPU enabled, IMASK=0xf
mon> exception
Privilege-mode, bank 1, Exception disabled, FPU enabled, IMASK=0xf
EXTEVT=100, SPC=a900009c SSR=400000f1 SGR=a900ffb4
skip instruction
mon> test
Privilege-mode, bank 0, Exception enabled, FPU enabled, IMASK=0xf
mon> 

FPU disabledは試せなかった。というのもprintfで割り算を使う。通常divsi3
あたりがあればいいのだけれど、SHではudivsi3_i4iという今迄会ったことのな
いものが呼ばれる。ここでFPUのレジスタを使っているのでFPU disabledでは
printfが動かなかった。

SH2モードにすればいいだろうと、libgcc,newlib共にm2を指定すると今度
は___udivsi3_i4iがundefined reference。うーん...。SH4AであえてFPUを無効
にして動すことはないだろうし、まぁいいか。