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

📄 eagle35_hawk35.asm

📁 ADI BF DSP PCI接口代码
💻 ASM
字号:
/************************************	01/07/03	********************************************
 *	HOST (EAGLE-35) TO DEVICE (HAWK-35) TRANSFER EXAMPLE 
 *
 *	software rev. VisualDSP++ 3.1
 *
 *	The program first configures the PCI-TO-PCI bridge registers mainly to set the primary
 *	and secondary bus numbers (Please Refer to the Intel 21152 PCI-to-PCI Bridgh Configuration App note)
 *  Then it configures the Device: assign memory and I/O start addresses (BARs) and set the Command register
 *	with the appropriate value in order for the device to respond to Memory and I/O transactions. 
 * 
 *	This program sends a "blink program" from the EAGLE-35 (PCI HOST) to 
 *	a PCI DEVICE (HAWK-35 or 21535 PUB) using MemDMA. It then writes a word
 *  to PCI_CBAP register of the device (0xFEEDFACE) which the device can poll
 *  to know when to jump to the base of L2 and start executing the blink program
 *
 *	Note: this example program only configures one device so use the
 *  	#define PCI_SLOT		PCI_SLOT_Px, such that x is the slot where the card resides
 *		this #define is in My_Header.h
 * 	************************************************************************************************/
 
 

#include "defBF535.h"
#include "pci_ids.h"
#include "My_header.h"


.GLOBAL DEVICE_EXECUTE;
.EXTERN DMA_TO_DEVICE;
.EXTERN PCI_CFG_INIT;
.EXTERN PCI_CONFIG_TYPE0;

.section L2_data;
.var Config_Space[16];
.var Config_Space2[16];


.section program;
.align 4;


/************** install INTERRUPT HANDLER *************/
P0.H = HI(EVT7); P0.L = LO(EVT7);
P1.H = PCI_RST_ISR;  P1.L = PCI_RST_ISR;  // PCI ISR
[P0] = P1;	
ssync; 

P0.h = HI(EVT3); P0.l = LO(EVT3);
P1.H = expthand; P1.L = expthand;
[P0] = P1;	// software exception
ssync;

P0.h = HI(EVT5); P0.l = LO(EVT5);
P1.H = hwerrhand; P1.L = hwerrhand;
[P0] = P1;		// hardware exception
ssync;


//Check revision of silicon to set SIC_IMASK appropriately
P3.H = HI(SIC_IMASK);  P3.L = LO(SIC_IMASK);
P0.H = HI(CHIPID);     P0.L = LO(CHIPID);
R0 = [P0];
R1.H = 0XF000;
R1 = R1 & R0;
cc = bittst(R1, 28); // check if CHIP_ID is non zero
if cc jump rev_1_0; // if CHIP_ID is non-zero, a 1 in SIC_MASK enables interrupts

rev0_1_or_0_2:
//Unmask the Interrupt in System Interrupt Mask Register
R6 = [p3];
BITCLR(R6,3); // change bit to desired bit position to match your application
[ P3 ] = R6;
SSYNC;
jump continue;

rev_1_0:
R6 = [p3];
BITSET(R6,3); // change bit to desired bit position to match your application
[ P3 ] = R6;
SSYNC;



continue:
/*  unmask PCI interrupt at the core level. */
P2.H = HI(IMASK); P2.L = LO(IMASK); 
R0.l   = W[P2];
R1.L = LO(EVT_IVG7);
R0 = R0 | R1;
W[P2] = R0.l;  /* Set the IVG7 mask bit to unmask the interrupt*/
ssync;

	
  /* set PF15 to be output for LED  */
  P0.H = HI(FIO_DIR); P0.L = LO(FIO_DIR);
  R0.l = W[P0];
  BITSET(R0,15);
  W[P0] = R0.l; /* set PF 15 as an output */
  ssync;

  /* Initialize SDRAM */
  call sdram_init;
  
  
   /* toggle PCI reset */ 
  P4.H = HI(PCI_CTL); P4.L = LO(PCI_CTL);
  R0.l  = W[P4];
  bitset(R0,5);
//  bitset(R0,6);
  [P4] = R0;     // set PCI_RST 
  SSYNC;
  bitclr(R0,6);
  [P4] = R0;     // clear PCI_RST 
  SSYNC;
  
/*** Initialize the Host's PCI Configuration space registers ****/
  call PCI_CFG_INIT;
   
    // maximum allowed delay for the device to initialize itself
 	P4.H = 0x122f; P4.L = 0x74e0; // 2^25 PCI clocks
  	LSETUP(L_BEGIN, L_END) LC0 = P4;
	L_BEGIN: NOP;
	L_END: NOP; 

  /******************** HOST PCI Configurarion accesses ************************/
  

  P4.H = Config_Space; P4.L = Config_Space;
  
  P5.H = HI(PCI_CBAP); P5.L = LO(PCI_CBAP);

  // Device ID | Vendor ID
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x00;
  [P5] = R0;
  ssync;
  
  P3.H = HI(PCI_CONFIG_SPACE_PORT); P3.L = LO(PCI_CONFIG_SPACE_PORT);
  R0 = [P3]; 
  ssync;
  [P4++] = R0;
  
  // COMMAND
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x04;
  [P5] = R0;
  ssync;
  R0 = [P3];
  BITSET(R0,9);
  [P3] = R0; // enable fast back-to-back
  ssync;
  R0 = [P3];
  [P4++] = R0;
  
  // Class Code | Revision ID
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x08;
  [P5] = R0;
  ssync;
  R2 = [P3];  
  ssync;
  R3.L = 0x0;
  R3 = R2 | R3;
  R3.H = 0x0604;
  CC = R3 == R2; /* check Class Code register to see if this is a PCI bridge or device */
  if !CC jump PCI_CONFIG_TYPE0;  // jump to configure the device on bus 0
  [P4++] = R2;
 
  // BIST | Header Type | Latency Timer | Cache Line Size
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x0c; 
  [P5] = R0;
  ssync;
  R3 = [P3];  
  ssync;
  [P4++] = R3;

  // Secondary LT | Subordinate bus num |Secondary bus num |Primary bus num	 
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x18;
  [P5] = R0;
  ssync;
  r5.h = 0x40ff; r5.l = 0x0100;
  [P3] = R5;
  SSYNC;
    [P5] = R0;
  	R5 = [P3]; 
  	ssync;
  	[P4++] = R5;

 
  // Sec Status | IO Limit | IO base
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x1c;
  [P5] = R0;
  ssync;
  R5.H = 0xFFFF; R5.L = 0xe0e0; // IO base and limit see table 19 of the 21152 intel app note
  [P3] = R5;
  SSYNC;
    [P5] = R0;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
  
  // Memory Limit | Memory Base
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x20;
  [P5] = R0;
  ssync;
    R5.H = 0xe7D0; R5.L = 0xe7C0; // Define a 2MB region of non-prefetchable memory (System MMR Space)
    [P3] = R5;
  SSYNC;
    [P5] = R0;
  
  R3 = [P3];  
  ssync;
  [P4++] = R3;
  
  // Prefetchable Memory Limit | Prefetchable Memory Base
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x24;
  [P5] = R0;
  ssync;
    R5.H = 0xe7f0; R5.L = 0xe000; // prefetchable mem base and limit: 128 MB 
  [P3] = R5;
  SSYNC;
    [P5] = R0;
  
  R3 = [P3];  
  ssync;
  [P4++] = R3;
  
  // Prefetchable Base Upper 32 bits
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x28;
  [P5] = R0;
  ssync;
  R3 = [P3];  
  ssync;
  [P4++] = R3;
  
  // Prefetchable Limit Upper 32 bits
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x2c;
  [P5] = R0;
  ssync;
  R6 = [P3];  
  ssync;
  [P4++] = R6;
  
  // I0 LIMIT UPPER 16 BITS | IO BASE UPPER 16 BITS
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x30;
  [P5] = R0;
  ssync;
    r5.h = 0xFFFF; r5.l = 0x0000;
    [P3] = R5;
    SSYNC;
    [P5] = R0;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
  
  // Reserved
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x34;
  [P5] = R0;
  ssync;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
  
  // Expansion ROM Base Address
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x38;
  [P5] = R0;
  ssync;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
  
  
  // Bridge Control | Interrupt Pin | Interrupt Line
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x3c;
  [P5] = R0;
  ssync;
    R5.H = 0x0; R5.L = 0x0; // no ISA bus in system
  [P3] = R5;
  SSYNC;
    [P5] = R0;
  R7 = [P3]; 
  ssync;
  [P4++] = R7;
  ssync;
  
  
  // Status | Command -- THIS REGISTER SHOULD BE WRITTEN LAST PER 21152 PCI-to-PCI Intel app note page 15
  R0.H = BIT_31 | PCI_SLOT | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x04;
  [P5] = R0;
  ssync;
  R1.H = 0xFFFF; R1.L = 0x0007;  // clear status bits; turn on I/O & mem enables for downstream; turn on Master enable for upstream mem and I/O
  [P3] = R1;
  ssync;
  [P5] = R0;
  R1 = [P3];  
  ssync;
  [P4++] = R1;
  
  /************************ Configure Device behind a PCI-to-PCI bridge ****************************/

    
   /******************** Type1_Config ********************/
   /*	12/23/02 it appears that here IDSEL need not be generated.  
   		Probably, what's happening is that the PCI-PCI bridge having 
   		been configured, claims the transaction and forwards it to the device */
   	
   Type1_Config: nop;
   
  P4.H = Config_Space2; P4.L = Config_Space2;
  
  // Device ID | Vendor ID
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x01;
  [P5] = R0;
  ssync;
  
  P3.H = HI(PCI_CONFIG_SPACE_PORT); P3.L = LO(PCI_CONFIG_SPACE_PORT);
  R0 = [P3]; 
  ssync;
  [P4++] = R0;
 
  // Status | Command
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x05;
  [P5] = R0;
  ssync;
  R1 = 0x207;  /* enable device to respond to mem and IO transactions and to master the PCI BUS;
  				  fast back-to-back */
  [P3] = R1;
  ssync;
  [P5] = R0;
  R1 = [P3]; 
  ssync;
  [P4++] = R1;
  
  // Class Code | Revision ID
  R0.H = BIT_31 |BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x09; 
  [P5] = R0;
  ssync;
  R2 = [P3]; 
  ssync;
  [P4++] = R2;
 
  // BIST | Header Type | Latency Timer | Cache Line Size
  R0.H = BIT_31 |BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x0d; 
  [P5] = R0;
  ssync;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
  
  // BAR 0 -- Memory BAR
  R0.H = BIT_31 |BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x11;
  [P5] = R0;
  ssync;
  R5 = 0xFFFFFFFF;
  [P3] = R5;
  SSYNC;
  [P5] = R0;
  SSYNC;
  R4 = [P3]; 
  ssync;
  R5.L = 0xFFF0;
  R4 = R5 & R4;  // set lower 4 bits to zero
  R4 = ~R4;      // complement R4 
  R4 += 1;       // memory size requested by device [in bytes]
  
  	[P5] = R0;
    ssync;
    P0.H = HI(Memory_Window); P0.L = LO(Memory_Window);
    
    [P3] = P0;
    ssync;
    
    [P5] = R0;
    ssync;
    r4 = [p3]; 
    ssync;
  [P4++] = R4;
  ssync;
  
  // BAR 1 
  R0.H = BIT_31 |BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x15;
  [P5] = R0;
  ssync;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
   
  
  // BAR 2 -- I/O BAR for the ADSP-BF535	 
  R0.H = BIT_31 |BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x19;
  [P5] = R0;
  ssync;
  R5 = 0xFFFFFFFF; 
  [P3] = R5; // Write all 1's to the I/0 BAR
  SSYNC;
    [P5] = R0;
  	R4 = [P3];  // Read I/O BAR back 
  	ssync;
  	R5.L = 0xFFFC;
  	R4 = R5 & R4;  // set lower 2 bits to zero
  	R4 = ~R4;      // complement R4 
  	R4 += 1;       // I/O size requested by device [in bytes]
  
  	
  	  [P5] = R0;
  	  ssync;
  	  R1.H = 0xEEFE; R1.L = 0x0000; // map Device I/0 to the PCI IO space
  	  [P3] = R1;
  	  ssync;
  	  
  	  [P5] = R0;
  	  ssync;
  	  R5 = [p3];
  	  ssync;
  [P4++] = R5;
  
  // BAR 3
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x1d;
  [P5] = R0;
  ssync;
  R3 = [P3];  
  ssync;
  [P4++] = R3;
  
  // BAR 4
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x21;
  [P5] = R0;
  ssync;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
  
  // BAR 5
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x25;
  [P5] = R0;
  ssync;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
  
  // Cardbus CIS Pointer - not implemented on 21535
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x29;
  [P5] = R0;
  ssync;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
  
  // Subsystem ID | Subsystem Vendor ID
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x2d;
  [P5] = R0;
  ssync;
  R6 = [P3];  
  ssync;
  [P4++] = R6;
  
  // Expansion ROM
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x31;
  [P5] = R0;
  ssync;
  R3 = [P3];  
  ssync;
  [P4++] = R3;
  
   // Reserved: should return zeros
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x35;
  [P5] = R0;
  ssync;
  R3 = [P3];  
  ssync;
  [P4++] = R3;
  
  // Reserved: should return zeros
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x39;
  [P5] = R0;
  ssync;
  R3 = [P3]; 
  ssync;
  [P4++] = R3;
  
  
  // Max_Latency | Min_Gnt | Interrupt pin | Interrupt Line
  R0.H = BIT_31 | BUS_NUMBER; 
  R0.L = DEVICE_NUMBER | FUNCTION_NUMBER| 0x3d;
  [P5] = R0;
  ssync;
  R7 = [P3]; 
  ssync;
  [P4++] = R7;
  
  /****************************************************/
 
 CALL DMA_TO_DEVICE;
  
  nop;
  nop;
  /*************** write CBAP of device to direct it to go L2 and execute DMAed code ************/
  
DEVICE_EXECUTE:
  
   P4.H = HI(PCI_IBAP); P4.L = LO(PCI_IBAP);
   R0.h = HI(IO_Window); R0.L = LO(IO_Window); 
   [P4] = R0;
   ssync;
   R1 = 0x14; 
   r2 = R0 | R1;
   P2 = R2; // address of PCI CBAP register
   R3.H = 0xFEED; R3.L = 0xFACE; // device polls on CBAP PCI reg for this token to start execution at L2 base addr
   csync;
   [P2] = R3;
   ssync;

DEVICE_EXECUTE.END:   
   IDLE;
   SSYNC;
   /************************** End of program  ****************************/
				
/*
 * Software Exception Handler: lights up LEDs 1-5 and loops forever.
 */
expthand:
  P0.h = 0xffc0; P0.l = 0x2406;     
  R0.h = 0; R0.l = 0xf800;
  R1 = ~R0;
  R1 = R1 & R0;
  W[P0]=R1;
  csync;
  jump expthand;

/*
 * Hardware Exception Handler:	lights up LEDs 1, 3, and 5 and loops forever.
 */
hwerrhand:
  P0.h = 0xffc0; P0.l = 0x2406;     
  R0.h = 0; R0.l = 0xa800;
  R1.H = 0; R1.L = 0xf800;
  R0 = ~R0;
  R1 = R1 & R0;
  W[P0]=R1;
  csync;
  jump hwerrhand;

/* Initialize Micron 64MB MT48LC4M16A2-7E - copied from sdram_init.asm */
sdram_init:
  P0.h = HI(EBIU_SDRRC); P0.l = LO(EBIU_SDRRC);
  R0 = 0x0817 (z);
  W[P0] = R0;
  ssync;

  P0.h = HI(EBIU_SDBCTL); P0.l = LO(EBIU_SDBCTL);
  R0.h = 0x0;  R0.l = 0x0015;
  // R0.l = 0x0001;  // for BUB
  [P0] = R0;
  ssync;

  P0.h = HI(EBIU_SDGCTL); P0.l = LO(EBIU_SDGCTL);
  R0.h = 0x0091; R0.l = 0x99fb;
  [P0] = R0;
  ssync;

  rts;	




.align 4;
PCI_RST_ISR:
  P4.H = HI(PCI_CTL); P4.L = LO(PCI_CTL);		// disable PCI before writing config space
  R0.h = 0x0; R0.l = 0x0;
  [P4] = R0;     // disable PCI
  SSYNC;

  P4.H = HI(PCI_STAT); P4.L = LO(PCI_STAT);		// clear PCI status before writing config space
  R0 = [P4];
  bitset(R0,6);  /*  Write a 1 to clear PCI RESET status bit */
  [P4] = R0; 
  SSYNC;

  P0.h = HI(FIO_FLAG_C); P0.l = LO(FIO_FLAG_C);
  R0.l = W[P0];
  BITSET(R0,15);
  W[P0] = R0.l; /* clear PF 15 */
  ssync;

  call PCI_CFG_INIT;

  P0.h = HI(FIO_FLAG_S); P0.l = LO(FIO_FLAG_S);
  R0.l = W[P0];
  BITSET(R0,15);
  W[P0] = R0.l; /* set PF 15 */
  ssync;

RTI; /* return from PCI Reset interrupt */




  

⌨️ 快捷键说明

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