トップ «前の日記(2005年03月14日) 最新 次の日記(2005年03月20日)» 編集
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|10|12|
2009|02|03|06|07|10|11|12|
2010|01|02|03|04|07|09|10|11|12|
2011|01|03|04|05|06|07|08|10|
2012|01|06|08|09|10|12|
2013|01|02|03|04|07|09|11|12|
2014|01|03|04|05|06|09|
2015|04|
2016|01|08|
ここは旧えびめもです。えびめも2に移行します(2016/12/1)

2005年03月19日

SH-Linux Hack

超スーパー専門的な話だけど、sh-linuxのページテーブル管理でアドレス識別子(TC,SA2,SA1,SA0)の付け方のビットフィールドのメモ。
arch/sh/mm/tlb-sh4.c より
 
void update_mmu_cache(struct vm_area_struct * vma,
                      unsigned long address, pte_t pte)
{
  中略
        local_irq_save(flags);
 
        /* Set PTEH register */
        vpn = (address & MMU_VPN_MASK) | get_asid();
        ctrl_outl(vpn, MMU_PTEH);
 
        pteval = pte_val(pte);
        /* Set PTEA register */
        /* TODO: make this look less hacky */
        ptea = ((pteval >> 28) & 0xe) | (pteval & 0x1);
        ctrl_outl(ptea, MMU_PTEA);
 
        /* Set PTEL register */
        pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
#ifdef CONFIG_SH_WRITETHROUGH
        pteval |= _PAGE_WT;
#endif
        /* conveniently, we want all the software flags to be 0 anyway */
        ctrl_outl(pteval, MMU_PTEL);
 
        /* Load the TLB */
        asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
        local_irq_restore(flags);
ということで、肝心なのは
 
        ptea = ((pteval >> 28) & 0xe) | (pteval & 0x1);
        ctrl_outl(ptea, MMU_PTEA);
の部分。ptevalの bit0とbit28,29,30 を使用してPTEAを作っているらしい。きっとbitの空きがなかったので苦労したところなんだろう。これでようやく
/* software: moves to PTEA.TC (Timing Control) */
#define _PAGE_PCC_AREA5 0x00000000      /* use BSC registers for area5 */
#define _PAGE_PCC_AREA6 0x80000000      /* use BSC registers for area6 */
/* software: moves to PTEA.SA[2:0] (Space Attributes) */
#define _PAGE_PCC_IODYN 0x00000001      /* IO space, dynamically sized bus */
#define _PAGE_PCC_IO8   0x20000000      /* IO space, 8 bit bus */
#define _PAGE_PCC_IO16  0x20000001      /* IO space, 16 bit bus */
#define _PAGE_PCC_COM8  0x40000000      /* Common Memory space, 8 bit bus */
#define _PAGE_PCC_COM16 0x40000001      /* Common Memory space, 16 bit bus */
#define _PAGE_PCC_ATR8  0x60000000      /* Attribute Memory space, 8 bit bus */
#define _PAGE_PCC_ATR16 0x60000001      /* Attribute Memory space, 6 bit bus */
とdefineされている理由が納得できた。(なんで上位ビットを使ってるのかなーという話ね)