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

📄 basiccrt.s

📁 在blankfin中 实现src 的程序
💻 S
字号:
/* Copyright (C) 2000 Analog Devices Inc., All Rights Reserved.
** This contains Analog Devices Background IP and Development IP as
** defined in the ADI/Intel Collaboration Agreement.
** ADI/Intel Confidential.
*/
// basic startup code which
// - installs default event handlers (!SMALL)
// - turns the cycle counter on
// - loads up FP & SP (both supervisor and user)
// - initialises the device drivers (FIOCRT)
// - gets out of supervisor mode and into user mode (!SMALL)
// - loads other registers with unassigned pattern 0x81818181 (!SMALL)
// - calls monstartup to set up the profiling routines (PROFCRT)
// - calls the C++ startup (CPLUSCRT)
// - initialises argc/argv (FIOCRT/normal)
// - calls _main
// - calls _exit (which calls monexit to dump accumulated prof data (PROFCRT))
// - defines dummy IO routines (!FIOCRT)

#include <DefBlackfin.h>
#define IVBh (EVT0 >> 16)
#define IVBl (EVT0 & 0xFFFF)
#ifdef SMALL
#define UNASSIGNED_FILL 0
// just IVG15
#define INTERRUPT_BITS 0x400
#else
#define UNASSIGNED_FILL 1
// all interrupts
#define INTERRUPT_BITS 0x7FF
#endif

	.section program;
	.align 4;
start:
	// Zap loop counters to zero, to make sure that
	// hw loops are disabled - it could be really baffling
	// if the counters and bottom regs are set, and we happen
	// to run into them.
	P0.H = 0xFFC0;
	P0.L = 0x4C0A;
	r1.h = 0x0000;
	r1.l = 0x0817;	//Micron 64MB MT48LC4M16A2-7E
	w[p0] = r1;
	p0 += -6;
	r1.h = 0x0404;	//Micron 64MB MT48LC4M16A2-7E
	r1.l = 0x0015;	//Micron 64MB MT48LC4M16A2-7E
	[p0] = r1;
	p0 += -4;
	r1.h = 0x0091;	//Micron 64MB MT48LC4M16A2-7E
	r1.l = 0x99fb;	//Micron 64MB MT48LC4M16A2-7E
	[p0] = r1;
	
	R7 = 0;
	LC0 = R7;
	LC1 = R7;

	// Clear the DAG Length regs too, so that it's safe to
	// use I-regs without them wrapping around.
	L0 = R7;
	L1 = R7;
	L2 = R7;
	L3 = R7;

	// Initialise the Event Vector table.
	P0.H = IVBh;
	P0.L = IVBl;

#ifdef SMALL

	// For the small environment, zero the EVT, so that
	// there is defined behaviour.
	P0 += 2*4;		// Skip Emulation and Reset
	P1 = 13;
	//R1 = 0;
	R1.H = usermode;
	R1.L = usermode;
	LSETUP (.ivt,.ivt) LC0 = P1;
.ivt:	[P0++] = R1;
	// Set IVG15's handler to be the start of the mode-change
	// code. Then, before we return from the Reset back to user
	// mode, we'll raise IVG15. This will mean we stay in supervisor
	// mode, and continue from the mode-change point., but at a
	// much lower priority.
	P1.H = supervisor_mode;
	P1.L = supervisor_mode;
	[P0] = P1;
#else
	
	// Clear out the IVT. Install exception handler
	// to deal with ISR-registering, exit/abort, and
	// file I/O.

	R1 = 0;
	P1 = 12;
	LSETUP(.ivt, .ivt) LC0 = P1;
	P1.L=_ex_def_exception;
	P1.H=_ex_def_exception;
	[P0++]=R1;		// emu
	[P0++]=R1;		// reset
	[P0++]=R1;		// nmi
	[P0++]=P1;		// exceptions
.ivt:	[P0++]=R1;		// remaining entries
#endif	/* SMALL */

	R0 = SYSCFG;		// Enable the Cycle counter
	BITSET(R0,1);
	SYSCFG = R0;

	// Initialise the stacks. First the user-mode stack:
	FP.L=ldf_stack_end;
	FP.H=ldf_stack_end;
	SP.L=ldf_stack_end;
	SP.H=ldf_stack_end;
	usp = sp;

	// Now the supervisor stack.
	SP.L=ldf_sysstack_end - 16;
	SP.H=ldf_sysstack_end - 16;

#ifdef L1CACHE

#define NUM_ICPLBS 16
#define NUM_DCPLBS 16    	

#ifdef ICACHE
// Enable Code L1 memory as Cache

	P0.L = (IMEM_CONTROL & 0xFFFF);
	P0.H = (IMEM_CONTROL >> 16);
	R0 = [P0];
	R1 = ENIM|IMC;
	R0 = R0 | R1;			
	[P0] = R0;

//Invalidate the cache for Code L1

	P3.L = (ITEST_DATA0 & 0xFFFF);
	P3.H = (ITEST_DATA0 >> 16);
	R0=0;[P3]=R0; // Cache Line Invalid Command

	P3.L = (ITEST_COMMAND & 0xFFFF);
	P3.H = (ITEST_COMMAND >> 16);
		
	p2=0x4;   //  Four Mini Banks
	lsetup(iflushs0,iflushe0) lc1=p2;
iflushs0:
		p2=0x40;	//128 cache lines 32 bytes per line one mini-bank	
		lsetup(iflushs1,iflushe1) lc0=p2;
	iflushs1:
		r0=lc1;
		r0+=-1;
		r0<<=16;		// place mini banks at 16:17
		r1=lc0;
		r1+=-1;
		r1<<=5;
		r2=r0 | r1;
		bitset(r2,1);	// Write access
		[p3]=r2;		// Way 0
		bitset(r2,26);	// Set to Way 1
		[p3]=r2;		// Way 1
		bitset(r2,27);	// Set to Way 3
		[p3]=r2;		// Way 3
		bitclr(r2,26);	// Set to Way 2
		[p3]=r2;		// Way 2
	iflushe1:nop;

iflushe0:nop;
#endif	



#ifdef DCACHE

// Enable Data Bank A and Bank B for Cache

	P0.L = (DMEM_CONTROL & 0xFFFF);
	P0.H = (DMEM_CONTROL >> 16);
	R0 = [P0];
	R1 = ENDM|ACACHE_BCACHE  ;
	R0 = R0 | R1;			
	[P0] = R0;


//Invalidate the cache for Bank A

	P3.L = (DTEST_DATA0 & 0xFFFF);
	P3.H = (DTEST_DATA0 >> 16);
	R0=0;[P3]=R0; // Cache Line Invalid Command

	P3.L = (DTEST_COMMAND & 0xFFFF);
	P3.H = (DTEST_COMMAND >> 16);
		
	p2=0x4;   //  Four Mini Banks
	lsetup(dbankaflushs0,dbankaflushe0) lc1=p2;
dbankaflushs0:
		p2=0x40;	//128 cache lines 32 bytes per line one mini-bank	
		lsetup(dbankaflushs1,dbankaflushe1) lc0=p2;
	dbankaflushs1:
		r0=lc1;
		r0+=-1;
		r0<<=16;		// place mini banks at 16:17
		r1=lc0;
		r1+=-1;
		r1<<=5;			// place Index at 5:10
		r2=r0 | r1;
		bitset(r2,1);	// Write access
		[p3]=r2;		// Way 0
		bitset(r2,26);	// Set to Way 1
		[p3]=r2;		// Way 1

	dbankaflushe1:nop;

dbankaflushe0:nop;



//Invalidate the cache for Bank B

	P3.L = (DTEST_DATA0 & 0xFFFF);
	P3.H = (DTEST_DATA0 >> 16);
	R0=0;[P3]=R0; // Cache Line Invalid Command

	P3.L = (DTEST_COMMAND & 0xFFFF);
	P3.H = (DTEST_COMMAND >> 16);
		
	p2=0x4;   //  Four Mini Banks
	lsetup(dbankbflushs0,dbankbflushe0) lc1=p2;
dbankbflushs0:
		p2=0x40;	//128 cache lines 32 bytes per line one mini-bank	
		lsetup(dbankbflushs1,dbankbflushe1) lc0=p2;
	dbankbflushs1:
		r0=lc1;
		r0+=-1;
		r0<<=16;		// place mini banks at 16:17
		r1=lc0;
		r1+=-1;
		r1<<=5;
		r2=r0 | r1;
		bitset(r2,1);	// Write access
		bitset(r2,23);	// Data Bank B

		[p3]=r2;		// Way 0
		bitset(r2,26);	// Set to Way 1
		[p3]=r2;		// Way 1

	dbankbflushe1:nop;

dbankbflushe0:nop;

// set ITestCmd back to 0 so the write bit is not set

// set DTestCmd back to 0 so the write bit is not set

	P3.L = (DTEST_COMMAND & 0xFFFF);
	P3.H = (DTEST_COMMAND >> 16);
	r0 = 0;
	[p3] = r0;
#endif	

#ifdef ICACHE
	P3.L = (ITEST_COMMAND & 0xFFFF);
	P3.H = (ITEST_COMMAND >> 16);
	r0 = 0;
	[p3] = r0;
#endif	

#ifdef DCACHE
	P0.L = (DMEM_CONTROL & 0xFFFF);
	P0.H = (DMEM_CONTROL >> 16);
	R0 = [P0];
	R1 = ~ENDM;
	R0 = R0 & R1;			
	[P0] = R0;
#endif	

#ifdef ICACHE
	P0.L = (IMEM_CONTROL & 0xFFFF);
	P0.H = (IMEM_CONTROL >> 16);
	R0 = [P0];
	R1 = ~ENIM;
	R0 = R0 & R1;			
	[P0] = R0;

	// Set up ICPLBs
	i0.l = ICPLB_ADDR0 & 0xFFFF;
	i0.h = ICPLB_ADDR0 >> 16;
	i1.l = ICPLB_DATA0 & 0xFFFF;
	i1.h = ICPLB_DATA0 >> 16;
	i2.l = icplbs_table;
	i2.h = icplbs_table;

	p4 = NUM_ICPLBS;
    	lsetup(start_icplb, end_icplb) lc0=p4;
    	start_icplb:	r2 = [i2++];   // address
    			[i0++] = r2;
    			r2 = [i2++];   // data
	end_icplb:	[i1++] = r2;

#endif	

#ifdef DCACHE
	// Set up DCPLBs
	i0.l = DCPLB_ADDR0 & 0xFFFF;
	i0.h = DCPLB_ADDR0 >> 16;
	i1.l = DCPLB_DATA0 & 0xFFFF;
	i1.h = DCPLB_DATA0 >> 16;
	i2.l = dcplbs_table;
	i2.h = dcplbs_table;

	/* read entries from table */
	p4 = NUM_DCPLBS;
    	lsetup(start_dcplb, end_dcplb) lc0=p4;
    	start_dcplb:	r2 = [i2++];   // address
    			[i0++] = r2;
    			r2 = [i2++];   // data
	end_dcplb:	[i1++] = r2;
#endif	


#ifdef ICACHE
	// Enable Cache with CPLBs enabled
	p0.l = IMEM_CONTROL & 0xFFFF;
	p0.h = IMEM_CONTROL >> 16;
	r0 = (IMC | ENICPLB | ENIM);
        [p0] = r0;
#endif	
       
#ifdef DCACHE
	p0.l = DMEM_CONTROL & 0xFFFF;
	p0.h = DMEM_CONTROL >> 16;
	r0 = (ACACHE_BCACHE | ENDCPLB | ENDM);
	[p0] = r0;
#endif	



#endif /* L1CACHE */

#ifdef FIOCRT
	// initialise the devices known about for stdio.
	call _init_devtab;
#endif /* FIOCRT */

	//  Enable interrupts
	R0 = INTERRUPT_BITS;
	R0 <<= 5;	// enable interrupts; 4-0 not settable
	STI R0;
#ifdef SMALL
	RAISE 15;
#endif

	// Move the processor into user mode.
	P0.L=usermode;
	P0.H=usermode;
	RETI=P0;
	rti;		// should take us to following instruction in user mode
usermode:
#ifdef SMALL
	// In the small configuration, we don't want to be in user mode,
	// because of the bloat required to service requests to supervisor
	// resources. So we've arranged for IVG15 to be raised earlier,
	// and it should take effect here...
	JUMP usermode;

	// ...and bring us to here.
supervisor_mode:
	[--SP] = RETI;	// re-enables the interrupt system
#endif	/* SMALL */


#ifdef UNASSIGNED_FILL
	P0.L=unass;
	P0.H=unass;
	R0=[P0];
	R2=R0;
	R3=R0;
	R4=R0;
	R5=R0;
	R6=R0;
	R7=R0;
	P0=R0;
	P1=R0;
	P2=R0;
	P3=R0;
	P4=R0;
	P5=R0;
	[SP]=R0;
	[SP+4]=R0;
	[FP]=R0;
	[FP+4]=R0;
#endif

#ifdef PROFCRT
        call monstartup; // initialise profiling routines
#endif  /* PROFCRT */
#ifdef PROFGUIDE
        call ___start_prof; // initialise profile guided routine
#endif  /* PROFGUIDE */
#ifdef CPLUSCRT
	R0=0;		// load up R0 and R1 and call _main()
	R1=R0;
	call ___ctorloop;
#endif  /* CPLUSCRT */
#ifdef FIOCRT
	// FILE IO provides access to real command-line arguments.
//	call __getargv;
	r1.l=__Argv; 
	r1.h=__Argv;
#else
	// Default to having no arguments and a null list.
	R0=0;
	R1.L=argv;
	R1.H=argv;
#endif /* FIOCRT */

	// At long last, call the application program.
	call _main;

	call _exit;	// passing in main's return value

	nop;
	nop;
	HLT;		// In case we're still here.


	.global start;
	.type start,STT_FUNC;
	.global _main;
	.type _main,STT_FUNC;
	.global _exit;
	.type _exit,STT_FUNC;
#ifdef FIOCRT
	.global __getargv;
	.type __getargv,STT_FUNC;
	.global _init_devtab;
	.type _init_devtab,STT_FUNC;
#else
	// If File IO support isn't provided, then
	// we provide dummy versions of the device-handling
	// functions, so that the exception handlers don't rely
	// on the file IO library
	.align 2;
_dev_open:
_dev_close:
_dev_write:
_dev_read:
_dev_seek:
_dev_dup:
	R0 = -1;
	RTS;

	.global _dev_open;
	.type _dev_open,STT_FUNC;
	.global _dev_close;
	.type _dev_close,STT_FUNC;
	.global _dev_write;
	.type _dev_write,STT_FUNC;
	.global _dev_read;
	.type _dev_read,STT_FUNC;
	.global _dev_seek;
	.type _dev_seek,STT_FUNC;
	.global _dev_dup;
	.type _dev_dup,STT_FUNC;
#endif /* FIOCRT */


	.section data1;
#ifndef FIOCRT
	// With no FILE IO support, we cannot fetch arguments
	// from the command line, so we provide a null list.
	.align 4;
argv:
	.byte4=0;				// argv[0]==0
#endif /* !FIOCRT */
	.align 4;
unass:
	.byte4=0x81818181;

	.align 4;
nullp:
	.byte4=0;				// no environment pointers
	.align 4;
__Environ:
	.byte4=nullp;
	.global __Environ;
	.type __Environ,STT_OBJECT;
#ifdef L1CACHE

	// Data for use when initialising the CPLBs when setting up
	// the cache. 
icplbs_table:
	.byte4=
		0xEF000000, (PAGE_SIZE_4MB | CPLB_LOCK 			 | CPLB_VALID), // Needed for 21535 chip anomaly
		0xF0000000, (PAGE_SIZE_1MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// L2 SRAM 
		0x03400000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x03000000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x02C00000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x02800000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x02400000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x02000000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 			
		0x01C00000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x01800000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x01400000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x01000000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 	
		0x00C00000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x00800000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x00400000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID),	// SDRAM 
		0x00000000, (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID);	// SDRAM 	

dcplbs_table:
	#define SGENERIC (CPLB_L1_CHBL | CPLB_WT | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID)
	#define AGENERIC                (CPLB_WT | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID)
	.byte4=
		0xFFC00000, (PAGE_SIZE_4MB | CPLB_WT | CPLB_SUPV_WR | CPLB_LOCK | CPLB_VALID), // MMRs 
		0xFFB00000, (PAGE_SIZE_1MB | CPLB_WT | CPLB_SUPV_WR | CPLB_LOCK | CPLB_VALID), // Scratchpad 
		0xF0000000, (PAGE_SIZE_1MB | SGENERIC), // L2 SRAM 
		0xEEF00000, (PAGE_SIZE_1MB | CPLB_WT | CPLB_SUPV_WR | CPLB_LOCK | CPLB_VALID),	// PCI
		0x02C00000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x02800000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x02400000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x02000000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x01C00000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x01800000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x01400000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x01000000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 	
		0x00C00000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x00800000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x00400000, (PAGE_SIZE_4MB | SGENERIC),	// SDRAM 
		0x00000000, (PAGE_SIZE_4MB | SGENERIC);	// SDRAM 	

#endif /* L1CACHE */

#ifdef CPLUSCRT
.section ctor;
	.align 4;
___ctor_table:
	.byte4=0;				
.global ___ctor_table;
.type ___ctor_table,STT_OBJECT;
#endif  /* CPLUSCRT */

⌨️ 快捷键说明

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