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

📄 400x.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************* * File: bsps/400x.c * Purpose: provide 400x-specific routines for SerialICE drivers * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	970218	Created using code from d4003.c *	970218	Moved do_icache/dcache here from iceif.c *	970224	Disabled dcache dataram printing. *	970225	Fixed the dcache dataram printing. *	970226	Removed lockbit check. *	970226	Various changes to optimize flushes. *	970226	Fixed soft iflush. Set 1 is lockable not set0. *	970226	Added stuff to i/dcache_opts[]. *	970226	Removed set selection from dcache cmd. *	970227	Added code to force alignment in cache display funcs. *	970305	Switched i/dcache to use get_rsa(). *	970310	moved brkInstall and brkRemove here from iceif.c and *		rewrote them. *	970310	Created ilockReq, hwibReq, and hwdbReq. *	970311	Removed write_target from method_ram *	970312	Added -l and -v to icache/dcache *	970312	Merged icache and dcache cmds *	970402	Changed the "don't flush locked entries" to iset0 *		I don't understand how it worked before! *	980312	Switched to unified scheme for dll and imon. *	980319	Removed code from ilockReq_400x. *	980323	Ignore flush_cache requests if target is running. *	980421	Added cache_size to cache_cmd *	980720	Added nobrkRemove. Needed for force_getsap. *	980803	Added isset=0 to brkRemove. *	980812	Added return if cache_size == 0. Also setFlushneeded(). *	980823	Removed t0 to hold const. No need for value of zero. *	981026	Added lnsize to flush_cache printDiag. *	981215	Added flush_target_400x_ejtag in an attempt to speed up *		the time taken to perform a flush. *	981216	400x ejtag needs dflush after dma downloads. */#ifndef LR4001#define LR4001#endif#include <imon.h>#include <mips.h>#include "iceif.h"#include "defs.h"#ifndef PMCC#include <stdlib.h>#endif#define ONLY_FLUSH_WHEN_NEEDED	/* optimize the cache flushes */#define LCK_BIT 	(1<<4)#define USE_SINGLE_LINE_FLUSH	/* use single-line flushes when possible */#define k12k0(a)	(((Ulong)(a))&~(1<<29))char *dirty_icache_line;char *dirty_dcache_line;void setupcacheline_400x(Ulong addr);void markIcacheDirty(Ulong addr,int size);void markDcacheDirty(Ulong addr,int size);/**************************************************************  void flush_target_400x(mode)*	Flush the designated cache in the target.*/void flush_target_400x(int mode){Ulong cfg,tmpcfg;/* flush_target_400x: The gpr[10]s in this func were 26 (k0) *//* flush_target_400x: The gpr[11]s in this func were 26 (k1) *//* emit code to flush the caches *//* we are already in an isr with ints disabled *//* the instr buffer is in kseg1 */if (!target_stopped) return; /* 980323 */if (need_initial_flush) {	printDiag(1,"performing initial flush 400x\n");        need_initial_flush = 0;        flush_target_400x(DCACHEI);        flush_target_400x(ICACHEI);        }switch (mode) {    case ICACHEI :	printDiag(1,"\niflush 400x size=%d lnsize=%d\n",		icache_size,cache_line_size);	if (icache_size == 0) {		iflush_needed = 0;		return;		}	send_buffer();	cfg = read_target(XT_MEM,M_CFG4001,4);	tmpcfg = cfg;	tmpcfg &= ~(CFG_CMODEMASK|CFG_IS1EN|CFG_DSIZEMASK|CFG_ISIZEMASK);	tmpcfg |= (CFG_ICEN|CFG_DCEN|CFG_CMODE_ITEST);	/* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */	writeGpr(8,tmpcfg);	writeGpr(9,M_CFG4001);	send_instr(SW(8,0,9));	send_instr(0);	send_instr(0);	send_instr(0);	/* actual cache code */	writeGpr(9,K0BASE);	writeGpr(8,K0BASE+icache_size);	/* flush loop */	send_instr(SW(0,0,9));	send_instr(ADDIU(9,9,cache_line_size));	send_instr(BNE(8,9,-3));	readA0();	/* flush Icache set1 */	tmpcfg = cfg;	tmpcfg &= ~(CFG_CMODEMASK|CFG_DSIZEMASK|CFG_ISIZEMASK);	tmpcfg |= (CFG_ICEN|CFG_IS1EN|CFG_DCEN|CFG_CMODE_ITEST);	/* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */	writeGpr(8,tmpcfg);	writeGpr(9,M_CFG4001);	send_instr(SW(8,0,9));	send_instr(0);	send_instr(0);	send_instr(0);	/* actual cache code */	writeGpr(9,K0BASE);	writeGpr(8,K0BASE+icache_size);	/* flush loop */	send_instr(SW(0,0,9));	send_instr(ADDIU(9,9,cache_line_size));	send_instr(BNE(8,9,-3));	readA0();	iflush_needed = 0;	break;    case ICACHE :#ifdef ONLY_FLUSH_WHEN_NEEDED	if (!iflush_needed) return;#endif	printDiag(1,"\nsoft iflush 400x size=%d lnsize=%d\n",		icache_size,cache_line_size);	if (icache_size == 0) {		iflush_needed = 0;		return;		}	send_buffer();	cfg = read_target(XT_MEM,M_CFG4001,4);	tmpcfg = cfg;	tmpcfg &= ~(CFG_CMODEMASK|CFG_IS1EN|CFG_DSIZEMASK|CFG_ISIZEMASK);	tmpcfg |= (CFG_ICEN|CFG_DCEN|CFG_CMODE_ITEST);	/* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */	writeGpr(8,tmpcfg);	writeGpr(9,M_CFG4001);	send_instr(SW(8,0,9));	send_instr(0);	send_instr(0);	send_instr(0);	/* actual cache code */	writeGpr(9,K0BASE);	writeGpr(8,K0BASE+icache_size);	/* flush loop */#if 1   /* only flush non-locked entries */	/* 970226 only set 1 is lockable */	/* 970402 Wrong! only set0 is lockable */	send_instr(LW(10,0,9));	send_instr(0); /* nop */	send_instr(SLLV(10,27));	send_instr(BLTZ(10,2));	send_instr(0); /* nop */	send_instr(SW(0,0,9));	send_instr(ADDIU(9,9,cache_line_size));	send_instr(BNE(8,9,-8));#else	send_instr(SW(0,0,9));	send_instr(ADDIU(9,9,cache_line_size));	send_instr(BNE(8,9,-3));#endif	readA0();	/* flush Icache set1 */	tmpcfg = cfg;	tmpcfg &= ~(CFG_CMODEMASK|CFG_DSIZEMASK|CFG_ISIZEMASK);	tmpcfg |= (CFG_ICEN|CFG_IS1EN|CFG_DCEN|CFG_CMODE_ITEST);	/* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */	writeGpr(8,tmpcfg);	writeGpr(9,M_CFG4001);	send_instr(SW(8,0,9));	send_instr(0);	send_instr(0);	send_instr(0);	/* actual cache code */	writeGpr(9,K0BASE);	writeGpr(8,K0BASE+icache_size);	/* flush loop */#if 0   /* only flush non-locked entries */	/* 970226 only set 1 is lockable. */	/* 970402 Wrong! only set0 is lockable */	send_instr(LW(10,0,9));	send_instr(0); /* nop */	send_instr(SLLV(10,27));	send_instr(BLTZ(10,2));	send_instr(0); /* nop */	send_instr(SW(0,0,9));	send_instr(ADDIU(9,9,cache_line_size));	send_instr(BNE(8,9,-8));#else	send_instr(SW(0,0,9));	send_instr(ADDIU(9,9,cache_line_size));	send_instr(BNE(8,9,-3));#endif	readA0();	iflush_needed = 0;	break;    case DCACHE :#ifdef ONLY_FLUSH_WHEN_NEEDED	if (!dflush_needed) return;#endif    case DCACHEI :	printDiag(1,"\ndflush 400x size=%d lnsize=%d\n",		dcache_size,cache_line_size);	if (dcache_size == 0) {		dflush_needed = 0;		return;		}	send_buffer();	/* flush Dcache set0 */	cfg = read_target(XT_MEM,M_CFG4001,4);	tmpcfg = cfg;	tmpcfg &= ~(CFG_CMODEMASK|CFG_ICEN|CFG_IS1EN|CFG_DSIZEMASK|CFG_ISIZEMASK);	tmpcfg |= (CFG_DCEN|CFG_CMODE_DTEST);	/* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */	writeGpr(8,tmpcfg);	writeGpr(9,M_CFG4001);	send_instr(SW(8,0,9));	send_instr(0);	send_instr(0);	send_instr(0);	/* actual cache code */	writeGpr(9,K0BASE);	writeGpr(8,K0BASE+dcache_size);	/* flush loop */	send_instr(SW(0,0,9));	send_instr(ADDIU(9,9,cache_line_size));	send_instr(BNE(8,9,-3));	readA0();	dflush_needed = 0;	break;	}/* restore cfg reg *//* write_target(XT_MEM,M_CFG4001,cfg,4); */writeGpr(8,cfg);writeGpr(9,M_CFG4001);send_instr(SW(8,0,9));send_instr(0);readA0();}/**************************************************************/Ulong readCache_400x(set,what,addr)int set,what;Ulong addr;{Ulong cfg,tmpcfg,val;/* we are already in an isr with ints disabled *//* the instr buffer is in kseg1 */tmpcfg = cfg = read_target(XT_MEM,M_CFG4001,4);tmpcfg &= ~(CFG_CMODEMASK|CFG_IS1EN|CFG_ICEN|CFG_DSIZEMASK|CFG_ISIZEMASK);tmpcfg |= CFG_DCEN;tmpcfg &= ~(CFG_WBEN|CFG_PGSZMASK);if (what == ICACHETAG) tmpcfg |= (CFG_ICEN|CFG_CMODE_ITEST);else if (what == ICACHERAM) tmpcfg |= (CFG_ICEN|CFG_CMODE_IDATA);else if (what == DCACHETAG) tmpcfg |= CFG_CMODE_DTEST;else if (what == DCACHERAM) return(0); /* there is no way to read this */if ((what == ICACHERAM || what == ICACHETAG) && set) tmpcfg |= CFG_IS1EN;else if (what == DCACHERAM || what == DCACHETAG) /* only one set */ ;send_buffer();/* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */writeGpr(8,tmpcfg);writeGpr(9,M_CFG4001);send_instr(SW(8,0,9));send_instr(0);send_instr(0);send_instr(0);/* val = read_target(XT_MEM,addr,4); */writeGpr(9,addr);send_instr(LW(4,0,9));send_instr(0);send_instr(0);send_instr(0);/* restore cfg reg write_target(XT_MEM,M_CFG4001,cfg,4); */writeGpr(8,cfg);writeGpr(9,M_CFG4001);send_instr(SW(8,0,9));send_instr(0);send_instr(0);send_instr(0);val = readA0();return(val);}/**************************************************************/static void writeCache(int set,int what,Ulong addr,Ulong val,int sz){Ulong cfg,tmpcfg;/* The target is already in an isr with ints disabled *//* the instr buffer is in kseg1 */tmpcfg = cfg = read_target(XT_MEM,M_CFG4001,4);tmpcfg &= ~(CFG_CMODEMASK|CFG_IS1EN|CFG_ICEN|CFG_DSIZEMASK|CFG_ISIZEMASK);tmpcfg |= CFG_DCEN;if (what == ICACHETAG) tmpcfg |= (CFG_ICEN|CFG_CMODE_ITEST);else if (what == ICACHERAM) tmpcfg |= (CFG_ICEN|CFG_CMODE_IDATA);else if (what == DCACHETAG) tmpcfg |= CFG_CMODE_DTEST;else if (what == DCACHERAM) ;if ((what == ICACHERAM || what == ICACHETAG) && set) tmpcfg |= CFG_IS1EN;else if (what == DCACHERAM || what == DCACHETAG) /* only one set */ ;send_buffer();/* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */writeGpr(8,tmpcfg);writeGpr(9,M_CFG4001);send_instr(SW(8,0,9));send_instr(0);send_instr(0);send_instr(0);/* write value to cache */writeGpr(8,val);writeGpr(9,addr);if (sz == 4) send_instr(SW(8,0,9));else if (sz == 2) send_instr(SH(8,0,9));else send_instr(SB(8,0,9));send_instr(0);send_instr(0);send_instr(0);/* write_target(XT_MEM,M_CFG4001,cfg,4); */writeGpr(8,cfg);writeGpr(9,M_CFG4001);send_instr(SW(8,0,9));send_instr(0);send_instr(0);send_instr(0);readA0();}#ifdef PMCC/**************************************************************/Optdesc cache_opts_400x[] = {	{"[-vidl][set [addr [value]]]","display cache"},	{"set","select set (default 0)"},	{"addr","specify address"},	{"-i","display icache"},	{"-d","display dcache (default)"},	{"-v","display only valid entries"},	{"-l","display only locked entries"},	{"-w","write entry"},	{"-t","write tag entry"},	{0}};void cache_cmd_400x(ac,av)int ac;char *av[];{int n,i,j,set,vflag,lflag,iflag,wflag,tflag,cachetag;static Ulong next_adr;Ulong adr,tag,msk,dadr,val;int cache_size;vflag = lflag = iflag = wflag = tflag = 0;for (n=0,i=1;i<ac;i++) {	if (av[i][0] == '-') {		for (j=1;av[i][j];j++) {			if (av[i][j] == 'v') vflag = 1;			else if (av[i][j] == 'l') lflag = 1;			else if (av[i][j] == 'i') iflag = 1;			else if (av[i][j] == 'd') iflag = 0;			else if (av[i][j] == 'w') wflag = 1;			else if (av[i][j] == 't') tflag = 1;			else {				printf("%s: unknown option\n",av[i][j]);				return;

⌨️ 快捷键说明

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