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

📄 hal_if.c

📁 Intel XScale PXA255 引导Linux的Redboot 版bootloader源代码!
💻 C
📖 第 1 页 / 共 2 页
字号:
//=============================================================================////      hal_if.c////      ROM/RAM interfacing functions////=============================================================================//####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 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          //####COPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s):   jskov// Contributors:jskov// Date:        2000-06-07////####DESCRIPTIONEND####////=============================================================================#include <pkgconf/hal.h>#ifdef CYGPKG_KERNEL# include <pkgconf/kernel.h>#endif#include <cyg/infra/cyg_ass.h>          // assertions#include <cyg/hal/hal_arch.h>           // set/restore GP#include <cyg/hal/hal_io.h>             // IO macros#include <cyg/hal/hal_if.h>             // our interface#include <cyg/hal/hal_diag.h>           // Diag IO#include <cyg/hal/hal_misc.h>           // User break#include <cyg/hal/hal_stub.h>           // stub functionality#include <cyg/hal/plf_stub.h>           // reset entry - FIXME, should be moved#include <cyg/hal/hal_intr.h>           // hal_vsr_table and others//--------------------------------------------------------------------------externC void patch_dbg_syscalls(void * vector);externC void init_thread_syscall(void * vector);//--------------------------------------------------------------------------// Implementations and function wrappers for monitor services#ifdef CYGPRI_HAL_IMPLEMENTS_IF_SERVICESstatic voiddelay_us(cyg_int32 usecs){#ifdef CYGPKG_KERNEL    cyg_int32 start, elapsed;    cyg_int32 usec_ticks, slice;    CYGARC_HAL_SAVE_GP();    // How many ticks total we should wait for.    usec_ticks = usecs*CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;    usec_ticks /= CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR/1000;    do {        // Spin in slices of 1/2 the RTC period. Allows interrupts        // time to run without messing up the algorithm. If we spun        // for 1 period (or more) of the RTC, there'd be also problems        // figuring out when the timer wrapped.  We may lose a tick or        // two for each cycle but it shouldn't matter much.        slice = usec_ticks % (CYGNUM_KERNEL_COUNTERS_RTC_PERIOD / 2);            HAL_CLOCK_READ(&start);        do {            HAL_CLOCK_READ(&elapsed);            elapsed = (elapsed - start); // counts up!            if (elapsed < 0)                elapsed += CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;        } while (elapsed < slice);        // Adjust by elapsed, not slice, since an interrupt may have        // been stalling us for some time.        usec_ticks -= elapsed;    } while (usec_ticks > 0);    CYGARC_HAL_RESTORE_GP();#else#ifdef HAL_DELAY_US    // Use a HAL feature if defined    HAL_DELAY_US(usecs);#else    // If no accurate delay mechanism, just spin for a while. Having    // an inaccurate delay is much better than no delay at all. The    // count of 100 should mean the loop takes something resembling    // 1us on most CPUs running between 30-100MHz [depends on how many    // instructions this compiles to, how many dispatch units can be    // used for the simple loop, actual CPU frequency, etc]    while (usecs-- > 0) {        int i;        for (i = 0; i < 100; i++);    }#endif#endif}static voidreset(void){    CYGARC_HAL_SAVE_GP();    // With luck, the platform defines some magic that will cause a hardware    // reset.    HAL_STUB_PLATFORM_RESET();#ifdef HAL_STUB_PLATFORM_RESET_ENTRY    // If that's not the case (above is an empty statement) there may    // be defined an address we can jump to - and effectively    // reinitialize the system. Not quite as good as a reset, but it    // is often enough.    goto *HAL_STUB_PLATFORM_RESET_ENTRY;#else#error " no RESET_ENTRY"#endif    CYGARC_HAL_RESTORE_GP();}// This is the system's default kill signal routine. Unless overridden// by the application, it will cause a board reset when GDB quits the// connection. (The user can avoid the reset by using the GDB 'detach'// command instead of 'kill' or 'quit').static intkill_by_reset(int __irq_nr, void* __regs){    CYGARC_HAL_SAVE_GP();    reset();    CYGARC_HAL_RESTORE_GP();    return 0;}static intnop_service(void){    // This is the default service. It always returns false (0), and    // _does_ not trigger any assertions. Clients must either cope    // with the service failure or assert.    return 0;}//----------------------------------// Comm controls#ifdef CYGNUM_HAL_VIRTUAL_VECTOR_AUX_CHANNELS#define CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS \  (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS+CYGNUM_HAL_VIRTUAL_VECTOR_AUX_CHANNELS)#else#define CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS \  CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS#endifstatic hal_virtual_comm_table_t comm_channels[CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS+1];static intset_debug_comm(int __comm_id){    static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY;    hal_virtual_comm_table_t* __chan;    int interrupt_state = 0;    int res = 1, update = 0;    CYGARC_HAL_SAVE_GP();    CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER               && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS,               "Invalid channel");    switch (__comm_id) {    case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT:        if (__selected_id > 0)            res = __selected_id-1;        else if (__selected_id == 0)            res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;        else             res = __selected_id;        break;    case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY:        CYGACC_CALL_IF_DEBUG_PROCS_SET(0);        __selected_id = __comm_id;        break;    case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER:        __comm_id = 0;        update = 1;        break;    default:        __comm_id++;                    // skip mangler entry        update = 1;        break;    }    if (update) {        // Find the interrupt state of the channel.        __chan = CYGACC_CALL_IF_DEBUG_PROCS();        if (__chan)            interrupt_state = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_DISABLE);        __selected_id = __comm_id;        CYGACC_CALL_IF_DEBUG_PROCS_SET(comm_channels[__comm_id]);        // Set interrupt state on the new channel.        __chan = CYGACC_CALL_IF_DEBUG_PROCS();        if (interrupt_state)            CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_ENABLE);        else            CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_DISABLE);    }    CYGARC_HAL_RESTORE_GP();    return res;}static intset_console_comm(int __comm_id){    static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY;    int res = 1, update = 0;    CYGARC_HAL_SAVE_GP();    CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER               && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS,               "Invalid channel");    switch (__comm_id) {    case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT:        if (__selected_id > 0)            res = __selected_id-1;        else if (__selected_id == 0)            res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;        else            res = __selected_id;        break;    case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY:        CYGACC_CALL_IF_CONSOLE_PROCS_SET(0);        __selected_id = __comm_id;        break;    case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER:        __comm_id = 0;        update = 1;        break;

⌨️ 快捷键说明

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