⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iq80310_misc.c

📁 移植到WLIT项目的redboot源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//==========================================================================////      iq80310_misc.c////      HAL misc board support code for XScale IQ80310////==========================================================================//####COPYRIGHTBEGIN####//                                                                          // -------------------------------------------                              // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in         // compliance with the License.  You may obtain a copy of the License at    // http://www.redhat.com/                                                   //                                                                          // Software distributed under the License is distributed on an "AS IS"      // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the // License for the specific language governing rights and limitations under // the License.                                                             //                                                                          // The Original Code is eCos - Embedded Configurable Operating System,      // released September 30, 1998.                                             //                                                                          // The Initial Developer of the Original Code is Red Hat.                   // Portions created by Red Hat are                                          // Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          //####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    msalter// Contributors: msalter// Date:         2000-10-10// Purpose:      HAL board support// Description:  Implementations of HAL board interfaces////####DESCRIPTIONEND####////========================================================================*/#include <pkgconf/hal.h>#include <pkgconf/system.h>#include CYGBLD_HAL_PLATFORM_H#include CYGHWR_MEMORY_LAYOUT_H#include <cyg/infra/cyg_type.h>         // base types#include <cyg/infra/cyg_trac.h>         // tracing macros#include <cyg/infra/cyg_ass.h>          // assertion macros#include <cyg/hal/hal_io.h>             // IO macros#include <cyg/hal/hal_stub.h>           // Stub macros#include <cyg/hal/hal_if.h>             // calling interface API#include <cyg/hal/hal_arch.h>           // Register state info#include <cyg/hal/hal_diag.h>#include <cyg/hal/hal_intr.h>           // Interrupt names#include <cyg/hal/hal_cache.h>#include <cyg/hal/hal_iq80310.h>        // Hardware definitions#include <cyg/infra/diag.h>             // diag_printf#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLEDstatic cyg_uint32 nfiq_ISR(cyg_vector_t vector, cyg_addrword_t data);static cyg_uint32 nirq_ISR(cyg_vector_t vector, cyg_addrword_t data);static cyg_uint32 nmi_mcu_ISR(cyg_vector_t vector, cyg_addrword_t data);static cyg_uint32 nmi_patu_ISR(cyg_vector_t vector, cyg_addrword_t data);static cyg_uint32 nmi_satu_ISR(cyg_vector_t vector, cyg_addrword_t data);static cyg_uint32 nmi_pb_ISR(cyg_vector_t vector, cyg_addrword_t data);static cyg_uint32 nmi_sb_ISR(cyg_vector_t vector, cyg_addrword_t data);// Some initialization has already been done before we get here.//// Set up the interrupt environment.// Set up the MMU so that we can use caches.// Enable caches.// - All done!void hal_hardware_init(void){    unsigned rtmp = 0;    // Route INTA-INTD to IRQ pin    //   The Yavapai manual is incorrect in that a '1' value    //   routes to the IRQ line, not a '0' value.    *PIRSR_REG = 0x0f;    // Disable all interrupt sources:    *IIMR_REG = 0x7f;    *OIMR_REG = 0x7f; // don't mask INTD which is really xint3    *X3MASK_REG = XINT3_TIMER | XINT3_ETHERNET | XINT3_UART_1 | \	          XINT3_UART_2 | XINT3_PCI_INTD;    // Let the timer run at a default rate (for delays)    hal_clock_initialize(CYGNUM_HAL_RTC_PERIOD);    // Set up eCos/ROM interfaces    hal_if_init();    // attach some builtin interrupt handlers    HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_NIRQ, &nirq_ISR, CYGNUM_HAL_INTERRUPT_NIRQ, 0);    HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_NIRQ);    HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_NFIQ, &nfiq_ISR, CYGNUM_HAL_INTERRUPT_NFIQ, 0);    HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_NFIQ);    HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_MCU_ERR, &nmi_mcu_ISR, CYGNUM_HAL_INTERRUPT_MCU_ERR, 0);    HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_MCU_ERR);    HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_PATU_ERR, &nmi_patu_ISR, CYGNUM_HAL_INTERRUPT_PATU_ERR, 0);    HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_PATU_ERR);    HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_SATU_ERR, &nmi_satu_ISR, CYGNUM_HAL_INTERRUPT_SATU_ERR, 0);    HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_SATU_ERR);    HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_PBDG_ERR, &nmi_pb_ISR, CYGNUM_HAL_INTERRUPT_PBDG_ERR, 0);    HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_PBDG_ERR);    HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_SBDG_ERR, &nmi_sb_ISR, CYGNUM_HAL_INTERRUPT_SBDG_ERR, 0);    HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_SBDG_ERR);    // Enable FIQ#if 0    asm volatile ("mrs %0,cpsr\n"		  "bic %0,%0,#0x40\n"		  "msr cpsr,%0\n"		  : "=r"(rtmp) : );#endif}#include CYGHWR_MEMORY_LAYOUT_Htypedef void code_fun(void);void __attribute__ ((naked)) iq80310_program_new_stack(void *func){    asm volatile ("mov    r12,sp\n"		  "stmdb  sp!, {r4, r12, lr, pc}\n"		  "sub    r4,r12, #4\n"		  "mov    r12,#0xa0000000\n"		  "add    sp,r12,#0x1000000\n"		  "mov    lr,pc\n"		  "mov    pc,r0\n"		  "ldmdb  r4, {r4, sp, pc}\n");    return;}// -------------------------------------------------------------------------// Clock can come from the PMU or from an external timer.// The external timer is the preferred choice.#if CYGNUM_HAL_INTERRUPT_RTC == CYGNUM_HAL_INTERRUPT_PMU_CCNT_OVFL// Proper version that uses the clock counter in the PMU to do proper// interrupts that require acknowledgement and all that good stuff.static cyg_uint32 hal_clock_init_period; // The START value, it counts upvoid hal_clock_initialize(cyg_uint32 period){    // event types both zero; clear all 3 interrupts;    // disable all 3 counter interrupts;    // CCNT counts every processor cycle; reset all counters;    // enable PMU.    register cyg_uint32 init = 0x00000707;    asm volatile (        "mcr      p14,0,%0,c0,c0,0;" // write into PMNC        :        : "r"(init)        /*:*/        );    // the CCNT in the PMU counts *up* then interrupts at overflow    // ie. at 0x1_0000_0000 as it were.    // So init to 0xffffffff - period + 1 to get the right answer.    period = (~period) + 1;    hal_clock_init_period = period;    hal_clock_reset( 0, 0 );}// This routine is called during a clock interrupt.// (before acknowledging the interrupt)void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period){    asm volatile (        "mrc      p14,0,r0,c1,c0,0;" // read from CCNT - how long since OVFL        "add      %0, %0, r0;"       // synchronize with previous overflow        "mcr      p14,0,%0,c1,c0,0;" // write into CCNT        :        : "r"(hal_clock_init_period)        : "r0"        );}// Read the current value of the clock, returning the number of hardware// "ticks" that have occurred (i.e. how far away the current value is from// the start)void hal_clock_read(cyg_uint32 *pvalue){    register cyg_uint32 now;    asm volatile (        "mrc      p14,0,%0,c1,c0,0;" // read from CCNT        : "=r"(now)        :        /*:*/        );    *pvalue = now - hal_clock_init_period;}// Delay for some usecs.void hal_delay_us(cyg_uint32 delay){  int i;  // the loop is going to take 3 ticks.  At 600 MHz, to give uS, multiply  // by 600/3 = 200. No volatile is needed on i; gcc recognizes delay  // loops and does NOT elide them.  for ( i = 200 * delay; i ; i--)    ;}#else // external timerstatic cyg_uint32 _period;void hal_clock_initialize(cyg_uint32 period){    _period = period;    // disable timer    EXT_TIMER_INT_DISAB();    EXT_TIMER_CNT_DISAB();    *TIMER_LA0_REG_ADDR = period;    *TIMER_LA1_REG_ADDR = period >> 8;    *TIMER_LA2_REG_ADDR = period >> 16;    EXT_TIMER_INT_ENAB();    EXT_TIMER_CNT_ENAB();}// This routine is called during a clock interrupt.void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period){    // to clear the timer interrupt, clear the timer interrupt    // enable, then re-set the int. enable bit    EXT_TIMER_INT_DISAB();    EXT_TIMER_INT_ENAB();}// Read the current value of the clock, returning the number of hardware// "ticks" that have occurred (i.e. how far away the current value is from// the start)void hal_clock_read(cyg_uint32 *pvalue){    cyg_uint8  cnt0, cnt1, cnt2, cnt3;    cyg_uint32 timer_val;;    // first read latches the count    // Actually, it looks like there is a hardware problem where    // invalid counts get latched. This do while loop appears    // to get around the problem.    do {	cnt0 = *TIMER_LA0_REG_ADDR & TIMER_COUNT_MASK;    } while (cnt0 == 0);    cnt1 = *TIMER_LA1_REG_ADDR & TIMER_COUNT_MASK;    cnt2 = *TIMER_LA2_REG_ADDR & TIMER_COUNT_MASK;    cnt3 = *TIMER_LA3_REG_ADDR & 0xf;	/* only 4 bits in most sig. */    /* now build up the count value */    timer_val  =  ((cnt0 & 0x40) >> 1) | (cnt0 & 0x1f);    timer_val |= (((cnt1 & 0x40) >> 1) | (cnt1 & 0x1f)) << 6;    timer_val |= (((cnt2 & 0x40) >> 1) | (cnt2 & 0x1f)) << 12;    timer_val |= cnt3 << 18;    *pvalue = timer_val;}// Delay for some usecs.void hal_delay_us(cyg_uint32 delay){#define _CNT_MASK 0x3fffff#define _TICKS_PER_USEC (EXT_TIMER_CLK_FREQ / 1000000)    cyg_uint32 now, last, diff, ticks;    hal_clock_read(&last);    diff = ticks = 0;    while (delay > ticks) {	hal_clock_read(&now);	if (now < last)	    diff += ((_period - last) + now);	else	    diff += (now - last);	last = now;	if (diff >= _TICKS_PER_USEC) {	    ticks += (diff / _TICKS_PER_USEC);	    diff %= _TICKS_PER_USEC;	}    }}#endif// -------------------------------------------------------------------------typedef cyg_uint32 cyg_ISR(cyg_uint32 vector, CYG_ADDRWORD data);extern void cyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj );static inline cyg_uint32hal_call_isr (cyg_uint32 vector){    cyg_ISR *isr;    CYG_ADDRWORD data;    cyg_uint32 isr_ret;    isr = (cyg_ISR*) hal_interrupt_handlers[vector];    data = hal_interrupt_data[vector];    isr_ret = (*isr) (vector, data);#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT    if (isr_ret & CYG_ISR_CALL_DSR) {        cyg_interrupt_post_dsr (hal_interrupt_objects[vector]);    }#endif    return isr_ret & ~CYG_ISR_CALL_DSR;}void _scrub_ecc(unsigned p){    asm volatile ("ldrb r4, [%0]\n"		  "strb r4, [%0]\n" : : "r"(p) );}static cyg_uint32 nmi_mcu_ISR(cyg_vector_t vector, cyg_addrword_t data){    cyg_uint32 eccr_reg;    // Read current state of ECC register    eccr_reg = *ECCR_REG;    // Turn off all ecc error reporting    *ECCR_REG = 0x4;    // Check for ECC Error 0    if(*MCISR_REG & 0x1) {	#ifdef DEBUG_NMI	diag_printf("ELOG0 = 0x%X\n", *ELOG0_REG);	diag_printf("ECC Error Detected at Address 0x%X\n",*ECAR0_REG);		#endif	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -