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 + -
显示快捷键?