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

📄 ixdp2400_misc.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================
//
//      ixdp2400_misc.c
//
//      HAL misc board support code for XScale IXDP2400
//
//==========================================================================
//####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):    lagarwal
// Contributors:
// Date:         2002-02-25
// 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_intr.h>           // Interrupt names
#include <cyg/hal/hal_cache.h>
#include <cyg/hal/hal_ixdp2400.h>       // Hardware definitions
#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
#include <cyg/hal/cfg_utility.h>
#include <cyg/io/i2c.h>
#include <cyg/io/pci.h>

#ifdef ENABLE_INT
CYG_ADDRESS	 pciIntList[PCI_ISR_COUNT];		/* list of int handlers */
CYG_ADDRWORD pciIntDataList[PCI_ISR_COUNT];	/* list of data objects */
#endif

externC cyg_pci_device slave_dev_info;

cyg_uint32 cpld_rev, board_rev, ext_osc_freq, silicon_rev;
struct board_config *board_config_data = (struct board_config *)SCRATCHPAD_BASE;
int qdr_ch_sz_array[MAX_QDR_CHANNEL];

extern void printf(char *fmt, ...);

int strap_options_val(void)
{
	return *(STRAP_OPTIONS_REG);
}

unsigned long swap32(unsigned long x)
{
#ifdef __ARMEB__
     return ((( x & 0x000000FF)<<24) |
             (( x & 0x0000FF00)<<8) |
             (( x & 0x00FF0000)>>8) |
             (( x & 0xFF000000)>>24));
#else
	 return x;
#endif
}

unsigned short swap16(unsigned short x)
{
#ifdef __ARMEB__
    return((( x & 0x00FF) <<8) |
           (( x & 0xFF00)>>8));
#else
	return x;
#endif
}

void display_led(char firstchar, char secondchar, char thirdchar, char fourthchar)
{
#ifdef __ARMEB__
	if(((silicon_rev & 0xF0) >> 4))
	{
		*((volatile cyg_uint8 *)ALPHANUM_DIS_DATA) = fourthchar;
		*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 1)) = thirdchar;
		*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 2)) = secondchar;
		*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 3)) = firstchar;
	}
	else
	{
		*((volatile cyg_uint8 *)ALPHANUM_DIS_DATA) = firstchar;
		*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 1)) = secondchar;
		*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 2)) = thirdchar;
		*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 3)) = fourthchar;
	}
#else
	*((volatile cyg_uint8 *)ALPHANUM_DIS_DATA) = fourthchar;
	*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 1)) = thirdchar;
	*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 2)) = secondchar;
	*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 3)) = firstchar;
#endif
}

#ifdef ENABLE_INT
void pciInt(void)
{
	int i;
	pci_ISR *isr;
	char cpld_int_val = *(CPLD_INT_REG);

	for(i = 0; i < PCI_ISR_COUNT; i++)
	{
		if((pciIntList[i] != (CYG_ADDRESS)hal_default_isr) && (cpld_int_val & (1 << i)))
		{
			isr = (pci_ISR *)pciIntList[i];
			(*isr)(i, pciIntDataList[i]);
		}
	}
}

void pciIntConnect(int vector, CYG_ADDRESS routine, CYG_ADDRWORD data)
{
	if(pciIntList[vector] == (CYG_ADDRESS)hal_default_isr)
	{
		pciIntList[vector]     = routine;
		pciIntDataList[vector] = data;
	}
}

void pciIntDisconnect(int vector)
{
	pciIntList[vector]     = (CYG_ADDRESS)hal_default_isr;
	pciIntDataList[vector] = (CYG_ADDRWORD)NULL;
}
#endif

void hal_sram_init(int channel, int skip_csr, int frm_pci, int offset)
{
	int i, j, qdr_ch_csr_base, qdr_base, sram_csr_val, temp, cache_on;
	int qdr_ch_size = MIN_SRAM_SIZE;
	int sram_detected = 0;

	// calculate the csr base and qdr base
	if(frm_pci)
	{
		qdr_ch_csr_base = slave_dev_info.base_map[CSR_BAR] + QDR_CH_BASE_FRM_PCI + (channel * 0x400);
		qdr_base = slave_dev_info.base_map[SRAM_BAR] + (channel * 0x10000000);
	}
	else
	{
		qdr_ch_csr_base = QDR_CH_CSR_BASE + (channel * 0x400000);
		qdr_base = SRAM_BASE + (channel * 0x10000000);
	}

	// init csrs
	if(!skip_csr)
	{
		int addr;

		// rcomp registers are only 4 bytes distant. So, when this function will be called by pci init it won't
		// work properly due to pci bug. Insert a dummy read cycle in between write operations.
		for(addr = 0x340; addr <= 0x3BC; addr += 4)
		{
			*((volatile cyg_uint32 *)(qdr_ch_csr_base + addr)) = 0xCCCC;
#ifdef A0_REV
			temp = *((volatile cyg_uint32 *)(qdr_ch_csr_base + addr));
#endif
		}
		
		// Invert rcomp polarity
		*((volatile cyg_uint32 *)(qdr_ch_csr_base + 0x300)) = 0x10060;

#ifdef QDR1
		// for 50 ohm ref resistor in real board/ tester
		*((volatile cyg_uint32 *)(qdr_ch_csr_base + 0x318)) = 0xFFFF3;
		// wait for 1ms
		hal_delay_us(1000);

		*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RX_DLL_OFF)) = 0x48;
#else
		// for 50 ohm ref resistor in real board/ tester
		*((volatile cyg_uint32 *)(qdr_ch_csr_base + 0x318)) = 0x518C3;
		// wait for 1ms
		hal_delay_us(1000);

		*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RX_DLL_OFF)) = 0x52;
#endif
		*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RX_DESKEW_OFF)) = 0x12;
		
		// set sram csr to use max sram size
		*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_CH_CONTROL_OFF)) = MAX_SRAM_SIZE_CSR_VAL;
		// wait for 3ms
		hal_delay_us(3000);
		*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RD_PTR_OFF)) = 0x4;		
		// read rd_ptr_off back to ensure that write is completed
		temp = *((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RD_PTR_OFF));
	}

	if(!frm_pci)
	{
		HAL_DCACHE_IS_ENABLED(cache_on);
		if (cache_on) {
			HAL_DCACHE_SYNC();
			HAL_DCACHE_DISABLE();
		}

		for(j = 1; j <= 5; j++)
		{
			volatile cyg_uint32 *temp1, *temp2;

			*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_CH_CONTROL_OFF)) = PIPELINE | (j << 7);
			hal_delay_us(3000);
			// now probe for the right size
			for(i = 0; i < SRAM_SIZE_LOOPS; i++)
			{
				temp1 = (volatile cyg_uint32 *)(qdr_base + qdr_ch_size);
				*temp1 = 0xAA55AA55;
				if(*temp1 != 0xAA55AA55)
				{
					break;
				}

				temp1 = (volatile cyg_uint32 *)(qdr_base + offset);
				temp2 = (volatile cyg_uint32 *)(qdr_base + (qdr_ch_size / 2) + offset);
				*temp1 = 0xA5A5A5A5;
				*temp2 = 0x55AAAA55;
				if(*temp1 == *temp2)
				{
					break;
				}
				sram_detected = 1;
				qdr_ch_size *= 2;
			}
		}
		if (cache_on) {
			HAL_DCACHE_ENABLE();
		}

		if(!sram_detected)
		{
			qdr_ch_size = 0;
		}
		qdr_ch_sz_array[channel] = qdr_ch_size;
		
		temp = 1024 * 1024;
		for(i = 0; i < 6; i++)
		{
			temp = temp * 2;
			if(temp == qdr_ch_size)
				break;
		}
		sram_csr_val = i << 7;
		sram_csr_val |= PIPELINE;
		
		*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_CH_CONTROL_OFF)) = sram_csr_val;
	}

	if(!frm_pci && qdr_ch_size)
	{
		// initialize whole SRAM with 0 so that it doesn't generate parity errors
		memset((char *)(qdr_base + offset), 0, (qdr_ch_size - offset));
		if(board_rev >= 3)
		{
			// parity is working only on 3rd board rev. and above
			*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_CH_CONTROL_OFF)) |= PARITY_ENABLE;
		}
	}
}

void hal_hardware_init(void)
{
	int i;

	silicon_rev = *(PRODUCT_ID_REG);
	display_led(DISPLAY_NULL, 'O', 'S', 'C');

	cpld_rev = *(CPLD_REV_REG);
	board_rev = (cpld_rev & 0xF0) >> 4;
	if(board_rev < 4)
	{
		ext_osc_freq = 600000000 / 6;
	}
	else
	{
		int numerator, denominator;
		int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8};

		numerator = (*(SYS_CLK_M_REG) & 0xFF) * 2;

		denominator = denom_array[(*(SYS_CLK_N_REG) & 0x7)];

		ext_osc_freq = (3125000 * numerator) / denominator;
	}

	// Let the timer run at a default rate (for delays)
    hal_clock_initialize((ext_osc_freq / 2));

    // Set up eCos/ROM interfaces
    hal_if_init();

	display_led('C', 'F', 'G', 'D');

	// if this is master npu then read config data
	if(strap_options_val() & CFG_PCI_BOOT_HOST)
	{
		struct KI_EEPROM_CONTENT temp;

		// read config data
		if(i2c_seq_read(SLAVE_ADDR_1, 0, (unsigned char *)&temp, sizeof(struct KI_EEPROM_CONTENT)))
        {
            printf("Encountered problem in reading config EPROM\n");
        }
        else
        {
            if(temp.comm_cfg.prom_fmt == '0')
            {
                // save in scratch for later reference
                // remember scratch is not byte writable
                for(i = 0; i < sizeof(struct KI_EEPROM_CONTENT); i += 4)
                {
                    *((cyg_uint32 *)((cyg_uint32)&(board_config_data->config_data) + i)) = *((cyg_uint32 *)((cyg_uint32)&temp + i));
                }
                // set the valid flag
                board_config_data->config_valid = CONFIG_DATA_VALID;
            }
            else
            {
                printf("Config EPROM is either not programmed or corrupted\n");
            }
        }
        board_config_data->sdram_size = hal_dram_size;
	}
	else
	{
		// if slave has flash then init valid flag with 0 so that we will know later
		// whether master has copied config data or not
		if(strap_options_val() & CFG_PROM_BOOT)
		{
			board_config_data->config_valid = 0;
		}
	}

    {
        char *min_product_type[] = {"IXP2800", "IXP2800 with Crypto", "IXP2400"};
        char *maj_rev[] = {"A1", "B0"};

        printf("Found %s Rev. %s\n", min_product_type[((silicon_rev & 0xFF00) >> 8)], maj_rev[((silicon_rev & 0xF0) >> 4)]);
	    printf("Core clock frequency is %d MHZ\n", ((ext_osc_freq * 6) / 1000000));
		printf("DDR channel operating freq. is %d MHZ\n", (((ext_osc_freq * 6) / 1000000) / ((*(CCR_REG) >> 16) & 0xF)));
        if(!(strap_options_val() & CFG_PCI_BOOT_HOST))
        {
            printf("QDR channel 0 operating freq. is %d MHZ\n", (((ext_osc_freq * 6) / 1000000) / (*(CCR_REG) & 0xF)));
        }
    }

	display_led('S', 'R', 'A', 'M');

	// init qdr channels
	for(i = 0; i < MAX_QDR_CHANNEL; i++)
	{
        if(!(strap_options_val() & CFG_PCI_BOOT_HOST) && (i == 0))
        {
            char dev_id;

            // on slave QDR channel 0 may have a TCAM card
            if(!i2c_read(SLAVE_ADDR_4, DEV_ID_ADDR, &dev_id))
            {
                if(dev_id == TC_DEV_ID)
                {
                    board_config_data->qdr_channel_size[i] = qdr_ch_sz_array[i] = 0;
                    printf("Found TCAM card on QDR channel 0. Skipping QDR channel 0 init.......\n");
                    continue;
                }
            }
        }
        hal_sram_init(i, 0, 0, 0);
		board_config_data->qdr_channel_size[i] = qdr_ch_sz_array[i];
	}
	
#ifdef ENABLE_INT
    {
        // init pci int and data list
        for (i = 0; i < PCI_ISR_COUNT; i++)
        {
            pciIntList[i]     = (CYG_ADDRESS)hal_default_isr;
            pciIntDataList[i] = (CYG_ADDRWORD)NULL;
        }
        
        // enable IRQ
        hal_unmask_all_int();

        // attach and enable pci intb
        HAL_INTERRUPT_ATTACH(CYGNUM_HAL_INTERRUPT_PCI_INTB, pciInt, 0, 0);
        HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_PCI_INTB);
    }
#endif
}

#include CYGHWR_MEMORY_LAYOUT_H

⌨️ 快捷键说明

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