hal_aux.c

来自「eCos操作系统源码」· C语言 代码 · 共 720 行 · 第 1/2 页

C
720
字号
//=============================================================================////      hal_aux.c////      HAL auxiliary objects and code; per platform////=============================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2002, 2003 Gary Thomas//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s):   hmt// Contributors:hmt, gthomas// Date:        1999-06-08// Purpose:     HAL aux objects: startup tables.// Description: Tables for per-platform initialization////####DESCRIPTIONEND####////=============================================================================#include <pkgconf/hal.h>#include <pkgconf/io_pci.h>#include <cyg/infra/cyg_type.h>#include <cyg/infra/diag.h>#include <cyg/hal/hal_mem.h>            // HAL memory definitions#include <cyg/hal/ppc_regs.h>           // Platform registers#include <cyg/hal/hal_if.h>             // hal_if_init#include <cyg/hal/hal_intr.h>           // interrupt definitions#include <cyg/hal/hal_cache.h>#include <cyg/infra/cyg_ass.h>          // assertion macros#include <cyg/io/pci.h>#include <cyg/hal/hal_io.h>             // I/O macros#include CYGHWR_MEMORY_LAYOUT_H// Functions defined in this modulevoid _csb281_fs6377_init(int mode);static void _csb281_i2c_init(void);// The memory map is weakly defined, allowing the application to redefine// it if necessary. The regions defined below are the minimum requirements.CYGARC_MEMDESC_TABLE CYGBLD_ATTRIB_WEAK = {    // Mapping for the Cogent CSB281 development boards    CYGARC_MEMDESC_NOCACHE( 0x70000000, 0x10000000 ), // FLASH region, LCD, PS/2    CYGARC_MEMDESC_NOCACHE( 0xf0000000, 0x10000000 ), // PCI space, LEDS, control    CYGARC_MEMDESC_CACHE(   CYGMEM_REGION_ram, CYGMEM_REGION_ram_SIZE ), // Main memory// Main memory, mapped non-cacheable for PCI use    CYGARC_MEMDESC_NOCACHE_PA(CYGMEM_SECTION_pci_window,                               CYGARC_PHYSICAL_ADDRESS(CYGMEM_SECTION_pci_window),                               CYGMEM_SECTION_pci_window_SIZE),    CYGARC_MEMDESC_TABLE_END};//--------------------------------------------------------------------------// Platform init code.voidhal_platform_init(void){    cyg_uint32 bcsr, gcr, frr, eicr, iack;    int vec;    // Initialize I/O interfaces    hal_if_init();    // Reset interrupt controller/state    HAL_READ_UINT32LE(_CSB281_EPIC_GCR, gcr);    HAL_READ_UINT32LE(_CSB281_EPIC_FRR, frr);    HAL_WRITE_UINT32LE(_CSB281_EPIC_GCR, gcr | _CSB281_EPIC_GCR_R);    do {        HAL_READ_UINT32LE(_CSB281_EPIC_GCR, gcr);    } while ((gcr & _CSB281_EPIC_GCR_R) != 0);    HAL_WRITE_UINT32LE(_CSB281_EPIC_GCR, gcr | _CSB281_EPIC_GCR_M);    HAL_READ_UINT32LE(_CSB281_EPIC_EICR, eicr);  // Force direct interrupts    eicr &= ~_CSB281_EPIC_EICR_SIE;    HAL_WRITE_UINT32LE(_CSB281_EPIC_EICR, eicr);    for (vec = CYGNUM_HAL_INTERRUPT_IRQ0; vec <= CYGNUM_HAL_ISR_MAX; vec++) {        HAL_INTERRUPT_CONFIGURE(vec, 0, 0);  // Default to low-edge        HAL_INTERRUPT_SET_LEVEL(vec, 0x0F);  // Priority    }    vec = (frr & 0x0FFF0000) >> 16;  // Number of interrupt sources    while (vec-- > 0) {        HAL_READ_UINT32LE(_CSB281_EPIC_IACK, iack);          HAL_WRITE_UINT32LE(_CSB281_EPIC_EOI, 0);    }    HAL_WRITE_UINT32LE(_CSB281_EPIC_PCTPR, 1); // Enables interrupts#ifndef CYGSEM_HAL_USE_ROM_MONITOR    // Reset peripherals    HAL_READ_UINT32(_CSB281_BCSR, bcsr);    HAL_WRITE_UINT32(_CSB281_BCSR, _zero_bit(bcsr, _CSB281_BCSR_PRESET));    HAL_WRITE_UINT32(_CSB281_BCSR, _one_bit(bcsr, _CSB281_BCSR_PRESET));    _csb281_i2c_init();    _csb281_fs6377_init(0);#endif#ifdef CYGSEM_CSB281_LCD_COMM    lcd_comm_init();#endif    _csb281_pci_init();}//--------------------------------------------------------------------------// Interrupt supportCYG_ADDRWORD _pvrs[] = {    _CSB281_EPIC_IVPR0,     // CYGNUM_HAL_INTERRUPT_IRQ0   0x02    _CSB281_EPIC_IVPR1,     // CYGNUM_HAL_INTERRUPT_IRQ1   0x03    _CSB281_EPIC_IVPR2,     // CYGNUM_HAL_INTERRUPT_IRQ2   0x04    _CSB281_EPIC_IVPR3,     // CYGNUM_HAL_INTERRUPT_IRQ3   0x05    _CSB281_EPIC_IVPR4,     // CYGNUM_HAL_INTERRUPT_IRQ4   0x06    _CSB281_EPIC_UART0VPR,  // CYGNUM_HAL_INTERRUPT_UART0  0x07    _CSB281_EPIC_UART1VPR,  // CYGNUM_HAL_INTERRUPT_UART1  0x08    _CSB281_EPIC_GTVPR0,    // CYGNUM_HAL_INTERRUPT_TIMER0 0x09    _CSB281_EPIC_GTVPR1,    // CYGNUM_HAL_INTERRUPT_TIMER1 0x0A    _CSB281_EPIC_GTVPR2,    // CYGNUM_HAL_INTERRUPT_TIMER2 0x0B    _CSB281_EPIC_GTVPR3,    // CYGNUM_HAL_INTERRUPT_TIMER3 0x0C    _CSB281_EPIC_I2CVPR,    // CYGNUM_HAL_INTERRUPT_I2C    0x0D    _CSB281_EPIC_DMA0VPR,   // CYGNUM_HAL_INTERRUPT_DMA0   0x0E    _CSB281_EPIC_DMA1VPR,   // CYGNUM_HAL_INTERRUPT_DMA1   0x0F    _CSB281_EPIC_MSGVPR,    // CYGNUM_HAL_INTERRUPT_MSG    0x10};void hal_interrupt_mask(int vector){    cyg_uint32 pvr;    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");    if (vector < CYGNUM_HAL_INTERRUPT_IRQ0) {        // Can't do much with non-external interrupts        return;    }    HAL_READ_UINT32LE(_pvrs[vector-CYGNUM_HAL_INTERRUPT_IRQ0], pvr);    pvr |= _CSB281_EPIC_PVR_M;    HAL_WRITE_UINT32LE(_pvrs[vector-CYGNUM_HAL_INTERRUPT_IRQ0], pvr);//    diag_printf("%s(%d)\n", __FUNCTION__, vector);}void hal_interrupt_unmask(int vector){    cyg_uint32 pvr;    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");    if (vector < CYGNUM_HAL_INTERRUPT_IRQ0) {        // Can't do much with non-external interrupts        return;    }    HAL_READ_UINT32LE(_pvrs[vector-CYGNUM_HAL_INTERRUPT_IRQ0], pvr);    pvr &= ~_CSB281_EPIC_PVR_M;    HAL_WRITE_UINT32LE(_pvrs[vector-CYGNUM_HAL_INTERRUPT_IRQ0], pvr);//    diag_printf("%s(%d)\n", __FUNCTION__, vector);}void hal_interrupt_acknowledge(int vector){}void hal_interrupt_configure(int vector, int level, int up){    cyg_uint32 pvr;    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");    if (vector < CYGNUM_HAL_INTERRUPT_IRQ0) {        // Can't do much with non-external interrupts        return;    }//    diag_printf("%s(%d, %d, %d)\n", __FUNCTION__, vector, level, up);    HAL_READ_UINT32LE(_pvrs[vector-CYGNUM_HAL_INTERRUPT_IRQ0], pvr);    pvr &= _CSB281_EPIC_PVR_M;  // Preserve mask    pvr |= vector;    if (level) {        pvr |= _CSB281_EPIC_PVR_S;    } else {        pvr &= ~_CSB281_EPIC_PVR_S;    }    if (up) {        pvr |= _CSB281_EPIC_PVR_P;    } else {        pvr &= ~_CSB281_EPIC_PVR_P;    }    HAL_WRITE_UINT32LE(_pvrs[vector-CYGNUM_HAL_INTERRUPT_IRQ0], pvr);}void hal_interrupt_set_level(int vector, int level){    cyg_uint32 pvr;    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");    if (vector < CYGNUM_HAL_INTERRUPT_IRQ0) {        // Can't do much with non-external interrupts        return;    }    HAL_READ_UINT32LE(_pvrs[vector-CYGNUM_HAL_INTERRUPT_IRQ0], pvr);    pvr &= ~(_CSB281_EPIC_PVR_PRIO_MASK<<_CSB281_EPIC_PVR_PRIO_SHIFT);    pvr |= (level<<_CSB281_EPIC_PVR_PRIO_SHIFT);    HAL_WRITE_UINT32LE(_pvrs[vector-CYGNUM_HAL_INTERRUPT_IRQ0], pvr);}//--------------------------------------------------------------------------// PCI supportexternC void_csb281_pci_init(void){    static int _init = 0;    cyg_uint8 next_bus;    cyg_uint32 cmd_state;    if (_init) return;    _init = 1;    // Initialize PCI support    cyg_pci_init();    // Setup for bus mastering    HAL_PCI_CFG_READ_UINT32(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),                            CYG_PCI_CFG_COMMAND, cmd_state);    if ((cmd_state & CYG_PCI_CFG_COMMAND_MEMORY) == 0) {        // Force PCI-side window to 0        HAL_PCI_CFG_WRITE_UINT32(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),                                 CYG_PCI_CFG_BAR_0, 0x01);        // Enable bus mastering from host        HAL_PCI_CFG_WRITE_UINT32(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),                                 CYG_PCI_CFG_COMMAND,                                 CYG_PCI_CFG_COMMAND_MEMORY |                                 CYG_PCI_CFG_COMMAND_MASTER |                                 CYG_PCI_CFG_COMMAND_PARITY |                                 CYG_PCI_CFG_COMMAND_SERR);        // Setup latency timer field        HAL_PCI_CFG_WRITE_UINT8(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),                                CYG_PCI_CFG_LATENCY_TIMER, 32);        // Configure PCI bus.        next_bus = 1;        cyg_pci_configure_bus(0, &next_bus);    }    if (0){        cyg_uint8 devfn;        cyg_pci_device_id devid;        cyg_pci_device dev_info;        int i;        devid = CYG_PCI_DEV_MAKE_ID(next_bus-1, 0) | CYG_PCI_NULL_DEVFN;        while (cyg_pci_find_next(devid, &devid)) {            devfn = CYG_PCI_DEV_GET_DEVFN(devid);            cyg_pci_get_device_info(devid, &dev_info);            diag_printf("\n");            diag_printf("Bus:        %d\n", CYG_PCI_DEV_GET_BUS(devid));            diag_printf("PCI Device: %d\n", CYG_PCI_DEV_GET_DEV(devfn));            diag_printf("PCI Func  : %d\n", CYG_PCI_DEV_GET_FN(devfn));            diag_printf("Vendor Id : 0x%08X\n", dev_info.vendor);            diag_printf("Device Id : 0x%08X\n", dev_info.device);            for (i = 0; i < dev_info.num_bars; i++) {                diag_printf("  BAR[%d]    0x%08x /", i, dev_info.base_address[i]);                diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",                            dev_info.base_size[i], dev_info.base_map[i]);            }        }    }    // Configure interrupts (high level)?    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_PCI0, 1, 1);    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_PCI1, 1, 1);    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_LAN, 1, 1);}externC void _csb281_pci_translate_interrupt(int bus, int devfn, int *vec, int *valid){    cyg_uint8 dev = CYG_PCI_DEV_GET_DEV(devfn);    // Purely slot based    if (dev >= CYG_PCI_MIN_DEV) {        CYG_ADDRWORD __translation[] = {                                                   CYGNUM_HAL_INTERRUPT_PCI0,            CYGNUM_HAL_INTERRUPT_PCI1,            CYGNUM_HAL_INTERRUPT_LAN        };        *vec = __translation[dev-CYG_PCI_MIN_DEV];        *valid = true;    } else {        *valid = false;    }#if 0    diag_printf("Int - dev: %d, vector: %d [%s]\n",                 dev, *vec, *valid ? "OK" : "BAD");#endif}// PCI configuration space access#define _EXT_ENABLE                     0x80000000//// Prepare for a config cycle on the PCI bus//static __inline__ cyg_uint32_cfg_sel(int bus, int devfn, int offset){    cyg_uint32 cfg_addr, addr;    cyg_uint32 bcsr;    HAL_READ_UINT32(_CSB281_BCSR, bcsr);    bcsr = (bcsr & ~0x07) | (1<<(CYG_PCI_DEV_GET_DEV(devfn)-CYG_PCI_MIN_DEV));    HAL_WRITE_UINT32(_CSB281_BCSR, bcsr);    cfg_addr = _EXT_ENABLE |         (bus << 16) |         (CYG_PCI_DEV_GET_DEV(devfn) << 11) |         (CYG_PCI_DEV_GET_FN(devfn) << 8) |         ((offset & 0xFF) << 0);    HAL_WRITE_UINT32LE(_CSB281_PCI_CONFIG_ADDR, cfg_addr);    addr = _CSB281_PCI_CONFIG_DATA + (offset & 0x03);    return addr;}externC cyg_uint8 _csb281_pci_cfg_read_uint8(int bus, int devfn, int offset){

⌨️ 快捷键说明

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