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

📄 excep_platform.c

📁 一个专门针对mips的bootloader程序源代码
💻 C
字号:

/************************************************************************
 *
 *  excep_platform.c
 *
 *  Platform specific exception functions
 *
 *  TBD : This file calls pci functions. Since the EXCEP module is 
 *  installed before the PCI module, this is not very nice (but it
 *  works with the present implementation of the PCI module).
 *
 *  due to the fact
 *
 *
 * ######################################################################
 *
 * Copyright (c) 1999-2000 MIPS Technologies, Inc. All rights reserved. 
 * 
 * Unpublished rights reserved under the Copyright Laws of the United States of 
 * America. 
 * 
 * This document contains information that is proprietary to MIPS Technologies, 
 * Inc. ("MIPS Technologies"). Any copying, modifying or use of this information 
 * (in whole or in part) which is not expressly permitted in writing by MIPS 
 * Technologies or a contractually-authorized third party is strictly 
 * prohibited. At a minimum, this information is protected under unfair 
 * competition laws and the expression of the information contained herein is 
 * protected under federal copyright laws. Violations thereof may result in 
 * criminal penalties and fines. 
 * MIPS Technologies or any contractually-authorized third party reserves the 
 * right to change the information contained in this document to improve 
 * function, design or otherwise. MIPS Technologies does not assume any 
 * liability arising out of the application or use of this information. Any 
 * license under patent rights or any other intellectual property rights owned 
 * by MIPS Technologies or third parties shall be conveyed by MIPS Technologies 
 * or any contractually-authorized third party in a separate license agreement 
 * between the parties. 
 * The information contained in this document constitutes one or more of the 
 * following: commercial computer software, commercial computer software 
 * documentation or other commercial items. If the user of this information, or 
 * any related documentation of any kind, including related technical data or 
 * manuals, is an agency, department, or other entity of the United States 
 * government ("Government"), the use, duplication, reproduction, release, 
 * modification, disclosure, or transfer of this information, or any related 
 * documentation of any kind, is restricted in accordance with Federal 
 * Acquisition Regulation 12.212 for civilian agencies and Defense Federal 
 * Acquisition Regulation Supplement 227.7202 for military agencies. The use of 
 * this information by the Government is further restricted in accordance with 
 * the terms of the license agreement(s) and/or applicable contract terms and 
 * conditions covering this information from MIPS Technologies or any 
 * contractually-authorized third party. 
 *
 ************************************************************************/


/************************************************************************
 *  Include files
 ************************************************************************/

#include <sysdefs.h>

#include <excep.h>
#include <excep_api.h>

#include <sys_api.h>
#include <pci_api.h>

#include <product.h>

/* Atlas */
#include <atlas.h>
#include <icta.h>

/* Malta */
#include <malta.h>
#include <piix4.h>

#include <pb1000.h>

/************************************************************************
 *  Definitions
 ************************************************************************/

/************************************************************************
 *  Public variables
 ************************************************************************/

/************************************************************************
 *  Static variables
 ************************************************************************/

/************************************************************************
 *  Static function prototypes
 ************************************************************************/


/************************************************************************
 *  Implementation : Static functions
 ************************************************************************/


/************************************************************************
 *  Implementation : Public functions
 ************************************************************************/


/************************************************************************
 *
 *                          arch_excep_init_intctrl
 *  Description :
 *  -------------
 *
 *  Initialise interrupt controller.
 *
 *  Parameters :
 *  ------------
 *
 *  Function will fill out the ic_count and ic_int parameters.
 *
 *  Return values :
 *  ---------------
 *
 *  None
 *
 ************************************************************************/
void
arch_excep_init_intctrl(
    UINT32 *ic_count,   /* Number of interrupts handled by interrupt 
			   controller (0 if no controller is available) */
    UINT32 *ic_int )    /* HW interrupt used by interrupt controller	*/
{
    UINT32 data;
#if 0
    switch( sys_platform )
    {
		
		
				
	case PRODUCT_PB1000_ID:

		*ic_count = 32;  /* There are 32 interrupts for the AU1000 on controller 0 */
		
		 /* The Interrupt controller will use HW0 - C0_STATUS_IM_HW0 
		 This value evaluates to 2.  
		 In the Au1000 data book this is Interrupt COntroller 0, Request 0 which is
		 mapped to CPO Cause bit 10
		 Note that the the definitions below indicate 
		 the interrupt number rather than the mask.
		(0..1 for SW interrupts and 2...7 for HW interrupts) */
		
		*ic_int =  C0_STATUS_IM_HW0;    
		
		break;
		
      case PRODUCT_ATLASA_ID :

        /* Atlas interrupt controller (icta) needs no initialisation */

        *ic_count = ICTA_IC_COUNT;
		*ic_int   = ATLAS_CPUINT_ICTA;

        break;

      case PRODUCT_MALTA_ID :

	/**** Setup PCI A..D sterring ****/

        /*  PCI A..B are routed to IRQ10.
	 *  PCI C..D are routed to IRQ11.
	 */

	pci_config_write32( 
	    PCI_BUS_LOCAL,
	    MALTA_DEVNUM_PIIX4,
	    PIIX4_PCI_FUNCTION_BRIDGE,
	    PIIX4_PCI_PIRQRC,
	    ( PIIX4_PIRQRC_PCIA_IR_IRQ10 << PIIX4_PIRQRC_PCIA_IR_SHF ) |
	    ( PIIX4_PIRQRC_PCIB_IR_IRQ10 << PIIX4_PIRQRC_PCIB_IR_SHF ) |
	    ( PIIX4_PIRQRC_PCIC_IR_IRQ11 << PIIX4_PIRQRC_PCIC_IR_SHF ) |
	    ( PIIX4_PIRQRC_PCID_IR_IRQ11 << PIIX4_PIRQRC_PCID_IR_SHF )
	);

	/**** Setup for level trigger on IRQ10 and IRQ11 ****/

	MALTA_PIIX4_IO8( PIIX4_ELCR2_OFS ) |= (PIIX4_ELCR2_IRQ10LEVEL_BIT |
					       PIIX4_ELCR2_IRQ11LEVEL_BIT );

	/**** Enable Serial IRQ ****/

	/* GENCFG */

	pci_config_read32(
	    PCI_BUS_LOCAL,
	    MALTA_DEVNUM_PIIX4,
	    PIIX4_PCI_FUNCTION_BRIDGE,
	    PIIX4_PCI_GENCFG,
	    &data );

	pci_config_write32(
	    PCI_BUS_LOCAL,
	    MALTA_DEVNUM_PIIX4,
	    PIIX4_PCI_FUNCTION_BRIDGE,
	    PIIX4_PCI_GENCFG,
	    data | PIIX4_GENCFG_SERIRQ_BIT );

	/* SERIRQ */

	pci_config_read8(
	    PCI_BUS_LOCAL,
	    MALTA_DEVNUM_PIIX4,
	    PIIX4_PCI_FUNCTION_BRIDGE,
	    PIIX4_PCI_SERIRQC,
	    (UINT8 *)&data );

	pci_config_write8(
	    PCI_BUS_LOCAL,
	    MALTA_DEVNUM_PIIX4,
	    PIIX4_PCI_FUNCTION_BRIDGE,
	    PIIX4_PCI_SERIRQC,
	    *(UINT8 *)(&data) | PIIX4_SERIRQC_ENABLE_BIT | PIIX4_SERIRQC_CONT_BIT );

        /**** Initialise PIIX4 master interrupt controller ****/

	/* ICW1 */
	MALTA_PIIX4_IO8( PIIX4_ICW1M_OFS ) = PIIX4_ICW1_ICWSEL_BIT |
					     PIIX4_ICW1_ICW4WR_BIT;

        /* ICW2 */
	MALTA_PIIX4_IO8( PIIX4_ICW2M_OFS ) = 0 << PIIX4_ICW2_BASE_SHF;

	/* ICW3 */
	MALTA_PIIX4_IO8( PIIX4_ICW3M_OFS ) = PIIX4_ICW3M_CAS_BIT;

	/* ICW4 */
	MALTA_PIIX4_IO8( PIIX4_ICW4M_OFS ) = PIIX4_ICW4_UPMODE_BIT;

	/* OCW3 (select ISR when later reading OCW3) */
	MALTA_PIIX4_IO8( PIIX4_OCW3M_OFS ) = 
			       (PIIX4_OCW3_OCWSEL_3 << PIIX4_OCW3_OCWSEL_SHF) |
			       (PIIX4_OCW3_RRC_ISR  << PIIX4_OCW3_RRC_SHF)    |
			        PIIX4_OCW3_ESMM_BIT;


        /**** Initialise PIIX4 slave interrupt controller ****/

	/* ICW1 */
	MALTA_PIIX4_IO8( PIIX4_ICW1S_OFS ) = PIIX4_ICW1_ICWSEL_BIT |
					     PIIX4_ICW1_ICW4WR_BIT;

        /* ICW2 */
	MALTA_PIIX4_IO8( PIIX4_ICW2S_OFS ) = 1 << PIIX4_ICW2_BASE_SHF;

	/* ICW3 */
	MALTA_PIIX4_IO8( PIIX4_ICW3S_OFS ) = PIIX4_ICW3S_SID_DEF << 
					     PIIX4_ICW3S_SID_SHF;

	/* ICW4 */
	MALTA_PIIX4_IO8( PIIX4_ICW4S_OFS ) = PIIX4_ICW4_UPMODE_BIT;


	/**** Mask all interrupts ****/

	MALTA_PIIX4_IO8( PIIX4_OCW1M_OFS ) = 0xFF;
	MALTA_PIIX4_IO8( PIIX4_OCW1S_OFS ) = 0xFF;

        /* The slave controller is attached to master IRQ2 */

        MALTA_PIIX4_IO8( PIIX4_OCW1M_OFS ) &= ~(1 << 2 );


	/**** Fill out parameters ****/
		
	*ic_count = PIIX4_IRQ_COUNT;
	*ic_int   = MALTA_CPUINT_PIIX4;

	break;

      default :

        /* No interrupt controller */
	*ic_count = 0;

        break;
    }
#else
	*ic_count = 0;
#endif
}


/************************************************************************
 *
 *                          arch_excep_enable_int
 *  Description :
 *  -------------
 *
 *  Enable specific source in interrupt controller
 *
 *  Return values :
 *  ---------------
 *
 *  None
 *
 ************************************************************************/
void
arch_excep_enable_int(
    UINT32 ic_line )    /* Interrupt source                             */
{
    switch( sys_platform )
    {
      case PRODUCT_ATLASA_ID :

        REG32(KSEG1( ATLAS_ICTA_BASE + ICTA_INTSETEN_OFS )) =
            1 << ic_line;
        break;

      case PRODUCT_MALTA_ID :

        if( ic_line < 8 )
        {
            MALTA_PIIX4_IO8( PIIX4_OCW1M_OFS ) &= ~(1 << ic_line);
        }
        else
        {
            MALTA_PIIX4_IO8( PIIX4_OCW1S_OFS ) &= ~(1 << (ic_line - 8));

            /* remember the slave is attached to master IRQ2 */
            MALTA_PIIX4_IO8( PIIX4_OCW1M_OFS ) &= ~(1 << 2 );
        }

        break;

	case PRODUCT_PB1000_ID:

		/* FIX!!! */

		break;

      default :

        /* No interrupt controller */
        break;
    }
}


/************************************************************************
 *
 *                          arch_excep_disable_int
 *  Description :
 *  -------------
 *
 *  Disable specific source in interrupt controller
 *
 *  Return values :
 *  ---------------
 *
 *  None
 *
 ************************************************************************/
void
arch_excep_disable_int(
    UINT32 ic_line )    /* Interrupt source                             */
{
    switch( sys_platform )
    {
      case PRODUCT_ATLASA_ID :

        REG32(KSEG1( ATLAS_ICTA_BASE + ICTA_INTRSTEN_OFS )) =
            1 << ic_line;
        break;

      case PRODUCT_MALTA_ID :

        if( ic_line < 8 )
        {
            MALTA_PIIX4_IO8( PIIX4_OCW1M_OFS ) |= (1 << ic_line);
        }
        else
        {
            MALTA_PIIX4_IO8( PIIX4_OCW1S_OFS ) |= (1 << (ic_line - 8));
        }

        break;

	case PRODUCT_PB1000_ID:
		
		/* FIX!!! */

		break;
		
      default :

        /* No interrupt controller */
        break;
    }
}


/************************************************************************
 *
 *                          arch_excep_pending
 *  Description :
 *  -------------
 *
 *  Return pending interrupt(s) in interrupt controller.
 *  On some platforms, all pending interrupts are returned, on other
 *  platforms only the hightest priority interrupt is returned.
 *
 *  Return values :
 *  ---------------
 *
 *  Pending interrupt(s)
 *
 ************************************************************************/
UINT32
arch_excep_pending( void )
{
    UINT32 index;
#if 0
    switch( sys_platform )
    {
		
		
	case PRODUCT_PB1000_ID:
		
		/* Return all pending interrupts */
		return REG32(KSEG1( PB1000_ICTRL_BASE + ICTRL_REQ0INT_OFS ));
		
		
      case PRODUCT_ATLASA_ID :

	/* Return all pending interrupts */
        return REG32(KSEG1( ATLAS_ICTA_BASE + ICTA_INTSTATUS_OFS ));

      case PRODUCT_MALTA_ID :

        /*  Determine highest priority pending interrupt by performing
         *  a PCI Interrupt Acknowledge cycle.
	 */
        index = pci_iack();

	/*  Determine the IRQ number based on the vector returned.
	 *  arch_excep_init_intctrl configured PIIX4 to return IRQ number
	 *  as the vector. PIIX4 has an 8 bit vector.
	 */
	index &= 0xFF;

	/*  IRQ7 is used to detect spurious interrupts.
	 *  The interrupt acknowledge cycle returns IRQ7 index
	 *  if no interrupts is requested.
	 *  We can differentiate between this situation and a
	 *  "Normal" IRQ7 by reading the ISR.
	 */

	return 	    
	    ( (index != 7) || (MALTA_PIIX4_IO8( PIIX4_OCW3M_OFS ) & (1 << 7)) ) ?
	        (1 << index) : 0;

      default :

        /* No interrupt controller */
	return 0;
    }
#else
	return 0;
#endif
}


/************************************************************************
 *
 *                          arch_excep_eoi
 *  Description :
 *  -------------
 *
 *  Perform EOI cycle for indicated interrupt
 *
 *  Return values :
 *  ---------------
 *
 *  None
 *
 ************************************************************************/
void
arch_excep_eoi(
    UINT32 index )
{
    switch( sys_platform )
    {
      case PRODUCT_MALTA_ID :

#define NSEOI    ( (PIIX4_OCW2_CODE_NSEOI << PIIX4_OCW2_CODE_SHF) | \
		   (PIIX4_OCW2_OCWSEL_2   << PIIX4_OCW2_OCWSEL_SHF) )

	/* Perform Non-specific EOI for master (ignore index) */
	MALTA_PIIX4_IO8( PIIX4_OCW2M_OFS ) = NSEOI;

	/* Perform Non-specific EOI for slave (ignore index) */
	MALTA_PIIX4_IO8( PIIX4_OCW2S_OFS ) = NSEOI;

	break;

      default :

        /* No EOI needed */
	break;
    }
}

⌨️ 快捷键说明

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