Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: [mpc8xx, ecos] Падение при включении кэша данных
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы
Андрей Бабошин
Добрый день

Пытаюсь включить поддержку mmu & cache в eCos'е для процессора f852t.
ММУ инициализируется, кэш инструкций тоже, а вот с кэшем данных — проблема.
Падает — вернее улетает по неизвестным адресам.

Вот код инициализации

Код
#ifdef CYGHWR_HAL_POWERPC_ENABLE_MMU
    bl mmu_init
#endif // CYGHWR_HAL_POWERPC_ENABLE_MMU

#define M8xx_MI_CTR_ITLB_INDX(x) ((x)<<8)   /* ITLB index */
#define M8xx_MD_CTR_DTLB_INDX(x) ((x)<<8)   /* DTLB index */
#define M8xx_MD_CTR_TWAM (1<<26)
#define M8xx_MI_AP      786     /* IMMU Access Protection Register */
#define M8xx_MD_AP      794     /* DMMU Access Protection Register */
#define _CPU_MSR_SET( _msr_value ) { asm volatile ("mtmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); }
#define _CPU_MSR_GET( _msr_value ) \
  do { \
    _msr_value = 0; \
    asm volatile ("mfmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); \
  } while (0)

void hal_MMU_init (void);
void hal_enable_caches(void);


/*
* The MMU_TLB_table is used to statically initialize the Table Lookaside
* Buffers in the MMU of an MPC8260.
*/
typedef struct {
    unsigned int      mmu_epn;    /* Effective Page Number */
    unsigned int      mmu_twc;    /* Tablewalk Control Register */
    unsigned int      mmu_rpn;    /* Real Page Number */
} MMU_TLB_table_t;

MMU_TLB_table_t MMU_TLB_table[] = {
  /*
     * DRAM: CS1, Start address 0x00000000, 4M,
     *    ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
     *    R/W,X for all, no ASID comparison, not cache-inhibited.
     *    Last 512K block is cache-inhibited, but not guarded for use by EPPCBug.
     * EPN        TWC    RPN
     */
  { 0x00000200,    0x05,    0x000009FD },    /* DRAM - PS=512K */
    { 0x00080200,    0x05,    0x000809FD },    /* DRAM - PS=512K */
    { 0x00100200,    0x05,    0x001009FD },    /* DRAM - PS=512K */
    { 0x00180200,    0x05,    0x001809FD },    /* DRAM - PS=512K */
    { 0x00200200,    0x05,    0x002009FD },    /* DRAM - PS=512K */
    { 0x00280200,    0x05,    0x002809FD },    /* DRAM - PS=512K */
    { 0x00300200,    0x05,    0x003009FD },    /* DRAM - PS=512K */
    { 0x00380200,    0x05,    0x003809FF },    /* DRAM - PS=512K, cache-inhibited */
    /*
     *
     * NVRAM: CS4, Start address 0xFA000000, 32K,
     *    ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
     *    R/W,X for all, no ASID comparison, cache-inhibited.
     *
     * EPN        TWC    RPN
     */
      { 0xFA000200,    0x01,    0xFA0009FF },    /* NVRAM - PS=16K */
      { 0xFA004200,    0x01,    0xFA0049FF },    /* NVRAM - PS=16K */
    /*
     *
     * Board Control/Status Register #1/#2: CS4, Start address 0xFA100000, (4 x 8 bits?)
     *    ASID=0x0, APG=0x0, guarded memory, write-through data cache policy,
     *    R/W,X for all, no ASID comparison, cache-inhibited.
     * EPN        TWC    RPN
     */
      { 0xFA100200,    0x13,    0xFA1009F7 },    /* BCSR - PS=4K */
    /*
     *
     * (IMMR-SPRs) Dual Port RAM: Start address 0xFA200000, 16K,
     *    ASID=0x0, APG=0x0, guarded memory, write-through data cache policy,
     *    R/W,X for all, no ASID comparison, cache-inhibited.
     *
     *    Note: We use the value in MBXA/PG2, which is also the value that
     *    EPPC-Bug programmed into our boards. The alternative is the value
     *     in MBXA/PG1: 0xFFA00000. This value might well depend on the revision
     *    of the firmware.
     * EPN        TWC    RPN
     */
      { 0xFA200200,    0x13,    0xFA2009FF },    /* IMMR - PS=16K */
    /*
     *
     * Flash: CS0, Start address 0xFE000000, 4M, (BootROM-EPPCBug)
     *    ASID=0x0, APG=0x0, not guarded memory,
     *    R/O,X for all, no ASID comparison, not cache-inhibited.
     * EPN        TWC    RPN
     */
      { 0xFE000200,    0x05,    0xFE000CFD },    /* Flash - PS=512K */
      { 0xFE080200,    0x05,    0xFE080CFD },    /* Flash - PS=512K */
      { 0xFE100200,    0x05,    0xFE100CFD },    /* Flash - PS=512K */
      { 0xFE180200,    0x05,    0xFE180CFD },    /* Flash - PS=512K */
      { 0xFE200200,    0x05,    0xFE200CFD },    /* Flash - PS=512K */
      { 0xFE280200,    0x05,    0xFE280CFD },    /* Flash - PS=512K */
      { 0xFE300200,    0x05,    0xFE300CFD },    /* Flash - PS=512K */
      { 0xFE380200,    0x05,    0xFE380CFD },    /* Flash - PS=512K */
    /*
     * BootROM: CS7, Start address 0xFC000000, 4M?, (socketed FLASH)
     *    ASID=0x0, APG=0x0, not guarded memory,
     *    R/O,X for all, no ASID comparison, not cache-inhibited.
     * EPN        TWC    RPN
     */
      { 0xFC000200,    0x05,    0xFC000CFD },    /* BootROM - PS=512K */
    /*
     *
     * PCI/ISA I/O Space: CS5, Start address 0x80000000, 512M?
     *    ASID=0x0, APG=0x0, guarded memory,
     *    R/W,X for all, no ASID comparison, cache-inhibited.
     * EPN        TWC    RPN
     */
      { 0x80000200,    0x1D,    0x800009FF },    /* PCI I/O - PS=8M */
    /*
     *
     * PCI/ISA Memory Space: CS5, Start address 0xC0000000, 512M?
     *    ASID=0x0, APG=0x0, guarded memory,
     *    R/W,X for all, no ASID comparison, cache-inhibited.
     * EPN        TWC    RPN
     */
      { 0xC0000200,    0x1D,    0xC00009FF },    /* PCI Memory - PS=8M */
    /*
     *
     * PCI Bridge/QSPAN Registers: CS6, Start address 0xFA210000, 4K
     *    ASID=0x0, APG=0x0, guarded memory,
     *    R/W,X for all, no ASID comparison, cache-inhibited.
     * EPN        TWC    RPN
     */
      { 0xFA210200,    0x11,    0xFA2109F7 },    /* QSPAN - PS=4K */
};

/*
* MMU_N_TLB_Table_Entries is defined here because the size of the
* MMU_TLB_table is only known in this file.
*/
int MMU_N_TLB_Table_Entries = ( sizeof(MMU_TLB_table) / sizeof(MMU_TLB_table[0]) );

externC void mmu_init (void) {


    CYG_INTERRUPT_STATE oldints;
    HAL_DISABLE_INTERRUPTS(oldints);

    register unsigned int reg1, i;
    
/*
* Initialize the TLBs
*
* Instruction address translation and data address translation
* must be disabled during initialization (IR=0, DR=0 in MSR).
* We can assume the MSR has already been set this way.
*/

/*    
* Initialize IMMU & DMMU Control Registers (MI_CTR & MD_CTR)
*     GPM [0]            0b0 = PowerPC mode
*    PPM [1]            0b0 = Page resolution of protection
*    CIDEF [2]        0b0/0b1 = Default cache-inhibit attribute =
*                            NO for IMMU, YES for DMMU!
*    reserved/WTDEF [3]    0b0 = Default write-through attribute = not
*    RSV4x [4]        0b0 = 4 entries not reserved
*    reserved/TWAM [5]    0b0/0b1 = 4-Kbyte page hardware assist
*    PPCS [6]        0b0 = Ignore user/supervisor state
*    reserved [7-18]        0x00
*    xTLB_INDX [19-23]    31 = 0x1F
*    reserved [24-31]    0x00
*    
* Note: It is important that cache-inhibit be set as the default for the
* data cache when the DMMU is disabled in order to prevent internal memory
* mapped registers from being cached accidentally when address translation
* is turned off at the start of exception processing.
*/

    diag_printf ("mmu_init\n");
    
    reg1 = M8xx_MI_CTR_ITLB_INDX(31);
//    _mtspr(MI_CTR, reg1 );
    CYGARC_MTSPR(MI_CTR, reg1);
    reg1 = CYGARC_REG_MD_CTR_CIDEF | M8xx_MD_CTR_TWAM | M8xx_MD_CTR_DTLB_INDX(31);
//    _mtspr( CYGARC_REG_MD_CTR, reg1 );
    CYGARC_MTSPR(CYGARC_REG_MD_CTR, reg1);
//    _isync;
    asm volatile ("isync\n"::);

    diag_printf ("mmu_init (1)\n");


/*
* Invalidate all TLB entries in both TLBs.
* Note: We rely on the RSV4 bit in MI_CTR and MD_CTR being 0b0, so
*       all 32 entries are invalidated.
*/
    __asm__ volatile ("tlbia\n"::);
//    _isync;
    asm volatile ("isync\n"::);
    diag_printf ("mmu_init (2)\n");
/*
* Set Current Address Space ID Register (M_CASID).
* Supervisor: CASID = 0
*/
    reg1 = 0;
//    _mtspr( M_CASID, reg1 );
    CYGARC_MTSPR(M_CASID, reg1);
    diag_printf ("mmu_init (3)\n");
/*
* Initialize the MMU Access Protection Registers (MI_AP, MD_AP)
* We ignore the Access Protection Group (APG) mechanism globally
* by setting all of the Mx_AP fields to 0b01 : client access
* permission is defined by page protection bits.
*/
    reg1 = 0x55555555;
//    _mtspr( M8xx_MI_AP, reg1 );
    CYGARC_MTSPR(M8xx_MI_AP, reg1);
//    _mtspr( M8xx_MD_AP, reg1 );
    CYGARC_MTSPR(M8xx_MD_AP, reg1);

    diag_printf ("mmu_init (4)\n");
/*  
* Load both 32-entry TLBs with values from the MMU_TLB_table
* which is defined in the BSP.
* Note the _TLB_Table must have at most 32 entries. This code
* makes no effort to enforce this restriction.
*/
    for( i = 0; i < MMU_N_TLB_Table_Entries; ++i ) {
    reg1 = MMU_TLB_table[i].mmu_epn;
    CYGARC_MTSPR( MI_EPN, reg1 );
    CYGARC_MTSPR( MD_EPN, reg1 );
    reg1 = MMU_TLB_table[i].mmu_twc;
    CYGARC_MTSPR( MI_TWC, reg1 );
    CYGARC_MTSPR( MD_TWC, reg1 );
    reg1 = MMU_TLB_table[i].mmu_rpn;    // RPN must be written last!
    CYGARC_MTSPR( MI_RPN, reg1 );
    CYGARC_MTSPR( MD_RPN, reg1 );
    }
    diag_printf ("mmu_init (5)\n");
    hal_MMU_init ();

/*
* Turn on address translation by setting MSR[IR] and MSR[DR].
*/
    diag_printf ("mmu_init (6)\n");
    _CPU_MSR_GET( reg1 );
    diag_printf ("read = %d\n", reg1);
    diag_printf ("mmu_init (7)\n");
[b]//    reg1 |= MSR_IR | MSR_DR; (*)[/b]
    reg1 |= MSR_IR;
    _CPU_MSR_SET( reg1 );
    
    diag_printf ("mmu_init (8)\n");
    
    hal_enable_caches ();
    
    HAL_RESTORE_INTERRUPTS(oldints);

    diag_printf ("mmu_init ok\n");
}

//---------------------------------------------------------------------------
// Use MMU resources to map memory regions.  
// This relies that the platform HAL providing an
//          externC cyg_memdesc_t cyg_hal_mem_map[];
// as detailed in hal_cache.h, and the variant HAL providing the
// MMU mapping/clear functions.
externC void
hal_MMU_init (void)
{
    int id = 0;
    int i  = 0;
    
    diag_printf ("hal_MMU_init\n");
    diag_printf ("cyg_hal_clear_MMU->\n");
    cyg_hal_clear_MMU ();
    diag_printf ("<-cyg_hal_clear_MMU\n");

    while (cyg_hal_mem_map[i].size) {
    //diag_printf ("cyg_hal_mem_map[i].size\n");
    diag_printf ("exec mmap:\n");
    diag_printf ("\tvirtual_addr: %p\n", cyg_hal_mem_map[i].virtual_addr);
    diag_printf ("\tphysical_addr: %p\n", cyg_hal_mem_map[i].physical_addr);
    diag_printf ("\tsize: %d\n", cyg_hal_mem_map[i].size);
    diag_printf ("\tflags: %d\n", cyg_hal_mem_map[i].flags);
        id = cyg_hal_map_memory (id,
                                 cyg_hal_mem_map[i].virtual_addr,
                                 cyg_hal_mem_map[i].physical_addr,
                                 cyg_hal_mem_map[i].size,
                                 cyg_hal_mem_map[i].flags);
        i++;
    }
    diag_printf ("hal_MMU_init ok\n");
}

//---------------------------------------------------------------------------
// Initial cache enabling
// Specific behavior for each platform configured via plf_cache.h

externC void
hal_enable_caches(void)
{
    
    diag_printf ("hal_enable_caches");
#ifndef CYG_HAL_STARTUP_RAM
    // Invalidate caches
    HAL_DCACHE_INVALIDATE_ALL();
    HAL_ICACHE_INVALIDATE_ALL();
#else
    diag_printf ("CYG_HAL_STARTUP_RAM\n");
#endif

#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
    diag_printf ("CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP\n");
#ifdef HAL_ICACHE_UNLOCK_ALL
    HAL_ICACHE_UNLOCK_ALL();
#endif
    HAL_ICACHE_ENABLE();
#endif

#ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
    diag_printf ("CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP\n");
#ifdef HAL_DCACHE_UNLOCK_ALL
    HAL_DCACHE_UNLOCK_ALL();
#endif
    HAL_DCACHE_ENABLE();
#ifdef HAL_DCACHE_WRITE_MODE
#ifdef CYGSEM_HAL_DCACHE_STARTUP_MODE_COPYBACK
    HAL_DCACHE_WRITE_MODE(HAL_DCACHE_WRITEBACK_MODE);
#else
    HAL_DCACHE_WRITE_MODE(HAL_DCACHE_WRITETHRU_MODE);
#endif
#endif
#endif
}


проблема возникает в строчке // reg1 |= MSR_IR | MSR_DR; (*)
Если убрать MSR_DR — все работает.
Может, она для инициализации и не нужна?
AndrewN
Цитата(Андрей Бабошин @ Jul 29 2008, 17:05) *
Пытаюсь включить поддержку mmu & cache в eCos'е для процессора f852t.
ММУ инициализируется, кэш инструкций тоже, а вот с кэшем данных — проблема.
Падает — вернее улетает по неизвестным адресам.
[code snipped]
проблема возникает в строчке // reg1 |= MSR_IR | MSR_DR; (*)
Если убрать MSR_DR — все работает.
Может, она для инициализации и не нужна?

MSR[DR] Data Relocate бит 27 контролирует трансляцию вирт. адресов данных,
это не кэш, этот бит как раз относится к MMU. Может быть data TLB не настроен?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.