📄 eagle35_hawk35.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 + -