091007

|


ロガー計画続き。スピードセンサもコンパレータ経由にしてみました。3.3Vから
10kΩでプルアップして、それをLM339に。P-LAPと同じくアクティブロー。
LM339の出力はオープンドレインなので、ここはLPC2388の内部でプルアップ。
LM339は5Vで駆動。これはP-LAPが5Vのため。

VccをA/Dコンバータでとろうかとか思っていたけれど、よくよく考えてみたら Vccが落ちてきたらVrefも落ちるのでだめだ。
そしてテスタをあてていてとんでもないことが発覚。なんと今迄、本来3.3V駆 動のLPC2388を5Vで駆動していた。SDカードも5Vで動かしていた。
というのも、Interface 2009/05号 p41のピン配置表が間違っていて、CN2の3.3Vと 5Vが反対なんだ。本当はCN2.38が5V、CN2.39が3.3V。あとCN3も間違えていて、 CN3.A19がP0_21でCN3.B19がP0_18。
この右側のロガー試作テスト機は、これに気付いていて、正しい結線にしてい たのだけど、ロガー本体は気付く前に電源廻りを組んでいて、そのままだっ た...。
今迄動いてたのが凄い。LPC2388もSDカードも屈強だ。
そうそう、P-LAP3も1点計測に。いちいちこれ変更するの面倒だ。もうちょっと 安定すればP-LAP本体は外してロガーから全て駆動できるのだけど...。

SH4A続き。PMBのエントリはITLBだけに登録される。UTLBには乗らない。ITLBに
登録されるのは最大2つまで。これはマニュアルにはなく、観測結果。

まずは512MBをMMUにP0にマップします。SH7785のTLB拡張モードを使って64Mペー
ジで8枚マップしてみます。

uint32_t
mmu (int32_t argc __attribute__((unused)),
     const char *argv[] __attribute__((unused)))
{
  struct tlb_entry tlb_entry =
    { 0x00000000, 0x40000000, 0, WRITEBACK, PG_64M, P_RW, FALSE };

全部のTLBエントリをゼロクリアします。明示的にしない限り、有効でないなん
らかの値が入っています。

  sh4a_tlb_clear_all ();

SH4A TLB拡張モードでアドレス変換スタート。
  sh4a_mmu_start ();

512MBのメモリを全てP0にマップします。64MBページなので8ページだけ。
  int i;
  for (i = 0; i < 8; i++)
    {
      sh4a_tlb_entry_generate (&tlb_entry);
      tlb_entry.vpn += 0x4000000;
      tlb_entry.ppn += 0x4000000;
    }

  return 0;
}


void
sh4a_mmu_start ()
{
ASIDを設定します。これはTLBエントリのマッチに使われます。
  // Set ASID
  *SH4A_PTEH = 0;
エントリ全部無効化して、アドレス変換を開始します。
  // Invalidate all entries. and start Address translation.
  *SH4A_MMUCR = MMUCR_TI | MMUCR_AT;
#ifdef SH4A_EXT_MMU
  *SH4A_MMUCR |= MMUCR_ME; ここでTLB拡張モードに設定します。
#endif

  CPU_SYNC_RESOURCE ();
}

void
sh4a_tlb_entry_generate (struct tlb_entry *e)
{
  uint32_t pteh, ptel, ptea;
  uint32_t pgsz_table[] = { 0x400, 0x1000, 0x1000, 0x100000, 0x2000, 0x40000,
			    0x400000, 0x4000000 };
  uint32_t pgsz = pgsz_table[e->size];
  uint32_t pgsz_mask = pgsz - 1;

  if ((e->vpn & pgsz_mask) || (e->ppn & pgsz_mask))
    {
      iprintf ("*** miss aligned address *** %x %x %x\n", e->vpn, e->ppn,
	       pgsz_mask);
      return;
    }
  if (e->asid & ~PTEH_ASID)
    {
      iprintf ("*** invalid ASID %x\n", e->asid);
      return;
    }

  pteh = e->vpn | e->asid;
  ptel = e->ppn;
  if (e->shared)
    ptel |= PTEL_SH;
  switch (e->cache)
    {
    case UNCACHED:
      break;
    case WRITEBACK:
      ptel |= PTEL_C;
      break;
    case WRITETHRU:
      ptel |= (PTEL_C | PTEL_WT);
      break;
    }
#ifdef SH4A_EXT_MMU
  uint32_t extmmu_pgsz_bits[] = { PTEA_ESZ_1K, PTEA_ESZ_4K, PTEA_ESZ_64K,
				  PTEA_ESZ_1M, PTEA_ESZ_8K, PTEA_ESZ_256K,
				  PTEA_ESZ_4M, PTEA_ESZ_64M };
  ptea = extmmu_pgsz_bits[e->size];
  switch (e->protect)
    {
    case P_RDONLY:
      ptea |= PTEA_EPR_P_R | PTEA_EPR_P_X;
      break;
    case P_RW:
      ptea |= PTEA_EPR_P_R | PTEA_EPR_P_W | PTEA_EPR_P_X;
      break;
    case U_RDONLY:
      ptea |= PTEA_EPR_P_R | PTEA_EPR_P_W | PTEA_EPR_P_X |
	PTEA_EPR_U_R | PTEA_EPR_U_X;
      break;
    case U_RW:
      ptea |= PTEA_EPR_P_R | PTEA_EPR_P_W | PTEA_EPR_P_X |
	PTEA_EPR_U_R | PTEA_EPR_U_W | PTEA_EPR_U_X;
      break;
    }
  *SH4A_PTEA = ptea;
#else
#error "notyet"
#endif
  *SH4A_PTEH = pteh;

 ここでPTEL_Vを設定しなければTLBミス例外が、PTEL_Vを設定してPTEL_Dを設
定しなければTLB初期ページ例外が発生します。

  *SH4A_PTEL = ptel | PTEL_V | PTEL_D;

登録するエントリを一つづつずらします。
  uint32_t r = *SH4A_MMUCR;
  uint32_t urc = (r >> MMUCR_URC_SHIFT) & MMUCR_URC_MASK;
  urc++;
  urc &= MMUCR_URC_MASK;
  *SH4A_MMUCR &= ~(MMUCR_URC_MASK << MMUCR_URC_SHIFT);
  *SH4A_MMUCR |= urc << MMUCR_URC_SHIFT;
ここで登録。
  __asm volatile ("ldtlb");
  CPU_SYNC_RESOURCE ();
}



=> go 0x89000000
## Starting application at 0x89000000 ...
stack_start: 0x89100000
RAM data: 0x890078a4-0x89007df4 1360byte
bss: 0x89007e00-0x8900bb8c 15756byte
Privilege-mode, bank 1, Exception disabled, FPU enabled, IMASK=0xf
bss memory check passed.
PMB page size 16MB mask=ffffff VPN:a4000000 PPN:4000000
PMB page size 128MB mask=7ffffff VPN:90000000 PPN:58000000
md_thread_create: [2]:uart recv pc=890048c0 sp=8900b658 stack=1024byte
thread_start: [2]
md_thread_create: [3]:uart send pc=89004850 sp=8900bb30 stack=1024byte
thread_start: [3]
md_thread_create: [4]:test pc=8900194c sp=8900a95c stack=1024byte
thread_start: [4]
test_thread:1234abcd
INTC: fffffff6 1f000000
hello 0
test4> mmu
test4> tlbdump
MMUCR: 2c002081
PTEH: 1c000000
PTEL: 5c00010c
TTB: 0
TEA: 0
PTEA: 0
--------------------ITLB--------------------
(-|V)  16M -- WT VPN:89000000 PPN:9000000 PMB 
--------------------UTLB--------------------
(D|V) [rwx][---]  64M -- WB -- VPN:0 PPN:40000000 ASID:0 
(D|V) [rwx][---]  64M -- WB -- VPN:4000000 PPN:44000000 ASID:0 
(D|V) [rwx][---]  64M -- WB -- VPN:8000000 PPN:48000000 ASID:0 
(D|V) [rwx][---]  64M -- WB -- VPN:c000000 PPN:4c000000 ASID:0 
(D|V) [rwx][---]  64M -- WB -- VPN:10000000 PPN:50000000 ASID:0 
(D|V) [rwx][---]  64M -- WB -- VPN:14000000 PPN:54000000 ASID:0 
(D|V) [rwx][---]  64M -- WB -- VPN:18000000 PPN:58000000 ASID:0 
(D|V) [rwx][---]  64M -- WB -- VPN:1c000000 PPN:5c000000 ASID:0 

TLB拡張モードでは、DA2をゼロクリアしてもプロテクションモードの特権の
r-xは消えません。特権モードでも読めない、フェッチできないエントリがあっ
ても意味がない。

このプログラムが動いている0x8000000-0xc000000以外をゼロクリアします。
test4> mem c 14000000 4000000
clear 14000000-18000000
test4> mem c 18000000 4000000
clear 18000000-1c000000
test4> mem c 1c000000 4000000
clear 1c000000-20000000
test4> mem c 10000000 4000000
clear 10000000-14000000
test4> mem c c000000 4000000
clear c000000-10000000
test4> mem c 4000000 4000000
clear 4000000-8000000
test4> mem c 0 4000000
clear 0-4000000
ここでまたパターン探しします。
test4> mem r 89000000
(r)89000000: 402bd001
test4> mem f 402bd001
Find pattern 402bd001... (0-20000000)
402bd001 found at 9000000
402bd001 found at 90083a8
402bd001 found at 90083dc

0x8000000-0xc000000以外の領域からは見つからなかったことからシャドウはない。

test4> mem r 89000004
(r)89000004: 90009