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

📄 u-boot代码记录.c

📁 本人移植 uboot后代码注释 注释很详细的
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Modify memory.
 *
 * Syntax:
 *	mm{.b, .w, .l} {addr}
 *	nm{.b, .w, .l} {addr}
 */
static int
mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
{
	ulong	addr, i;
	int	nbytes, size;
	extern char console_buffer[];

	if (argc != 2) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}


	/* We use the last specified parameters, unless new ones are
	 * entered.
	 */
	addr = mm_last_addr;
	size = mm_last_size;

	if ((flag & CMD_FLAG_REPEAT) == 0) {
		/* New command specified.  Check for a size specification.
		 * Defaults to long if no or incorrect specification.
		 */
		if ((size = cmd_get_data_size(argv[0], 4)) < 0)
			return 1;

		/* Address is specified since argc > 1
		*/
		addr = simple_strtoul(argv[1], NULL, 16);
		addr += base_address;
	}



	/* Print the address, followed by value.  Then accept input for
	 * the next value.  A non-converted value exits.
	 */
	do 
	 {
		printf("%08lx:", addr);
		if (size == 4)
			printf(" %08x", *((uint   *)addr));
		else if (size == 2)
			printf(" %04x", *((ushort *)addr));
		else
			printf(" %02x", *((u_char *)addr));

		nbytes = readline (" ? ");
		if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
			/* <CR> pressed as only input, don't modify current
			 * location and move to next. "-" pressed will go back.
			 */
			if (incrflag)
				addr += nbytes ? -size : size;
			nbytes = 1;

		else {
			char *endp;
			i = simple_strtoul(console_buffer, &endp, 16);
			nbytes = endp - console_buffer;
			if (nbytes) {

				if (size == 4)
					*((uint   *)addr) = i;
				else if (size == 2)
					*((ushort *)addr) = i;
				else
					*((u_char *)addr) = i;
				if (incrflag)
					addr += size;
			}
		}
	} while (nbytes);

	mm_last_addr = addr;
	mm_last_size = size;
	return 0;
}








void start_armboot (void)
{
	init_fnc_t **init_fnc_ptr;
	char *s;

	ulong size;



	/* Pointer is writable since we allocated a register for it */
	gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
	/* compiler optimization barrier needed for GCC >= 3.4 */
	__asm__ __volatile__("": : :"memory");

	memset ((void*)gd, 0, sizeof (gd_t));
	gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
	memset (gd->bd, 0, sizeof (bd_t));

	monitor_flash_len = _bss_start - _armboot_start;

	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
		if ((*init_fnc_ptr)() != 0) {
			hang ();
		}
	}


	/* configure available FLASH banks */
	size = flash_init ();
	display_flash_config (size);



	/*
	 * reserve memory for VFD display (always full pages)
	 */
	/* bss_end is defined in the board-specific linker script */
	addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
	size = vfd_setmem (addr);
	gd->fb_base = addr;



	/*
	 * reserve memory for LCD display (always full pages)
	 */
	/* bss_end is defined in the board-specific linker script */
	addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
	size = lcd_setmem (addr);
	gd->fb_base = addr;


	/* armboot_start is defined in the board-specific linker script */
	mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);

#if (CONFIG_COMMANDS & CFG_CMD_NAND)
	puts ("NAND:  ");
	nand_init();		/* go init the NAND */
#endif



	/* initialize environment */
	env_relocate ();



	/* IP Address */
	gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

	/* MAC Address */
	{
		int i;
		ulong reg;
		char *s, *e;
		char tmp[64];

		i = getenv_r ("ethaddr", tmp, sizeof (tmp));
		s = (i > 0) ? tmp : NULL;

		for (reg = 0; reg < 6; ++reg)
		{
			gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
			if (s)
				s = (*e) ? e + 1 : e;
		}

	}

	devices_init ();	/* get the devices list going. */



	jumptable_init ();

	console_init_r ();	/* fully init console as a device */



	/* enable exceptions */
	enable_interrupts ();

	/* Perform network card initialisation if necessary */




	/* Initialize from environment */
	if ((s = getenv ("loadaddr")) != NULL) {
		load_addr = simple_strtoul (s, NULL, 16);
	}

	if ((s = getenv ("bootfile")) != NULL) {
		copy_filename (BootFile, s, sizeof (BootFile));
	}


#if (CONFIG_COMMANDS & CFG_CMD_NET)
	eth_initialize(gd->bd);
#endif
	/* main_loop() can return to retry autoboot, if so just run it again. */
	for (;;) {
		main_loop ();
	}

	/* NOTREACHED - no way out of command loop except booting */
}









dm9000_reset(void)
{
	DM9000_DBG("resetting\n");
	DM9000_iow(DM9000_NCR, NCR_RST);
	udelay(1000);		/* delay 1ms */
}

dm9000_probe(void)
{
	u32 id_val;
	id_val = DM9000_ior(DM9000_VIDL);
	id_val |= DM9000_ior(DM9000_VIDH) << 8;
	id_val |= DM9000_ior(DM9000_PIDL) << 16;
	id_val |= DM9000_ior(DM9000_PIDH) << 24;
	if (id_val == DM9000_ID) 
		{
		printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE,
		       id_val);
		return 0;
	}
	else 
	{
		printf("dm9000 not found at 0x%08x id: 0x%08x\n",
		       CONFIG_DM9000_BASE, id_val);
		return -1;
	}



/* Initilize dm9000 board
*/
int
eth_init(bd_t * bd)
{
	int i, oft, lnk;
	DM9000_DBG("eth_init()\n");

	/* RESET device */
	dm9000_reset();
	dm9000_probe();

	/* NIC Type: FASTETHER, HOMERUN, LONGRUN */
	identify_nic();

	/* GPIO0 on pre-activate PHY */
	DM9000_iow(DM9000_GPR, 0x00);	/*REG_1F bit0 activate phyxcer */

	/* Set PHY */
	set_PHY_mode();

	/* Program operating register */
	DM9000_iow(DM9000_NCR, 0x0);	/* only intern phy supported by now */
	DM9000_iow(DM9000_TCR, 0);	/* TX Polling clear */
	DM9000_iow(DM9000_BPTR, 0x3f);	/* Less 3Kb, 200us */
	DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));	/* Flow Control : High/Low Water */
	DM9000_iow(DM9000_FCR, 0x0);	/* SH FIXME: This looks strange! Flow Control */
	DM9000_iow(DM9000_SMCR, 0);	/* Special Mode */
	DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);	/* clear TX status */
	DM9000_iow(DM9000_ISR, 0x0f);	/* Clear interrupt status */

	/* Set Node address */
	for (i = 0; i < 6; i++)
		((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);
	printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", bd->bi_enetaddr[0],
	       bd->bi_enetaddr[1], bd->bi_enetaddr[2], bd->bi_enetaddr[3],
	       bd->bi_enetaddr[4], bd->bi_enetaddr[5]);
	for (i = 0, oft = 0x10; i < 6; i++, oft++)
		DM9000_iow(oft, bd->bi_enetaddr[i]);
	for (i = 0, oft = 0x16; i < 8; i++, oft++)
		DM9000_iow(oft, 0xff);

	/* read back mac, just to be sure */
	for (i = 0, oft = 0x10; i < 6; i++, oft++)
		DM9000_DBG("%02x:", DM9000_ior(oft));
	DM9000_DBG("\n");

	/* Activate DM9000 */
	DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);	/* RX enable */
	DM9000_iow(DM9000_IMR, IMR_PAR);	/* Enable TX/RX interrupt mask */
	i = 0;
	while (!(phy_read(1) & 0x20)) {	/* autonegation complete bit */
		udelay(1000);
		i++;
		if (i == 10000) {
			printf("could not establish link\n");
			return 0;
		}
	}

	/* see what we've got */
	lnk = phy_read(17) >> 12;
	printf("operating at ");
	switch (lnk) {
	case 1:
		printf("10M half duplex ");
		break;
	case 2:
		printf("10M full duplex ");
		break;
	case 4:
		printf("100M half duplex ");
		break;
	case 8:
		printf("100M full duplex ");
		break;
	default:
		printf("unknown: %d ", lnk);
		break;
	}
	printf("mode\n");
	return 0;
}




///////////////////////////////////////////////////nandflash部分/////////////////////////////////////////////////////////////


#if (CONFIG_COMMANDS & CFG_CMD_NAND)
extern ulong nand_probe(ulong physadr);

static inline void NF_Reset(void)
{
	int i;

	NF_SetCE(NFCE_LOW);
	NF_Cmd(0xFF);		/* reset command */
	for(i = 0; i < 10; i++);	/* tWB = 100ns. */
	NF_WaitRB();		/* wait 200~500us; */
	NF_SetCE(NFCE_HIGH);
}

static inline void NF_Init(void)
{
#if 1
#define TACLS   0
#define TWRPH0  3
#define TWRPH1  0
#else
#define TACLS   0
#define TWRPH0  4
#define TWRPH1  2
#endif

	NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
	/*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
	/* 1  1    1     1,   1      xxx,  r xxx,   r xxx */
	/* En 512B 4step ECCR nFCE=H tACLS   tWRPH0   tWRPH1 */

	NF_Reset();
}

void nand_init(void)
{
	S3C2410_NAND * const nand = S3C2410_GetBase_NAND();                //获取nandflash寄存器基地址

	NF_Init();
#ifdef DEBUG
	printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
	printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */


struct nand_oob_config {
	/* position of ECC bytes inside oob */
	int ecc_pos[6];
	/* position of  bad blk flag inside oob -1 = inactive */
	int badblock_pos;
	/* position of ECC valid flag inside oob -1 = inactive */
	int eccvalid_pos;
} oob_config = { {0}, 0, 0};
struct nand_chip {
	int 		page_shift;
	u_char 		*data_buf;
	u_char 		*data_cache;
	int		cache_page;
	u_char 		ecc_code_buf[6];
	u_char 		reserved[2];
	char ChipID; /* Type of DiskOnChip */
	struct Nand *chips;
	int chipshift;
	char* chips_name;
	unsigned long erasesize;
	unsigned long mfr; /* Flash IDs - only one type of flash per device */
	unsigned long id;
	char* name;
	int numchips;
	char page256;
	char pageadrlen;
	unsigned long IO_ADDR;  /* address to access the 8 I/O lines to the flash device */
	unsigned long totlen;
	uint oobblock;  /* Size of OOB blocks (e.g. 512) */
	uint oobsize;   /* Amount of OOB data per block (e.g. 16) */
	uint eccsize;
	int bus16;
};

#define NAND_NOOB_ECCPOS0		0
#define NAND_NOOB_ECCPOS1		1
#define NAND_NOOB_ECCPOS2		2
#define NAND_NOOB_ECCPOS3		3
#define NAND_NOOB_ECCPOS4		6
#define NAND_NOOB_ECCPOS5		7
#define NAND_NOOB_BADBPOS		-1
#define NAND_NOOB_ECCVPOS		-1


/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */

static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
{
	int mfr, id, i;

	NAND_ENABLE_CE(nand);  /* set pin low */
	/* Reset the chip */
	if (NanD_Command(nand, NAND_CMD_RESET)) 
	{
#ifdef NAND_DEBUG
		printf("NanD_Command (reset) for %d,%d returned true\n",
		       floor, chip);
#endif
		NAND_DISABLE_CE(nand);  /* set pin high */
		return 0;
	}

	/* Read the NAND chip ID: 1. Send ReadID command */
	if (NanD_Command(nand, NAND_CMD_READID))   //发送读命令
	{
#ifdef NAND_DEBUG
		printf("NanD_Command (ReadID) for %d,%d returned true\n",
		       floor, chip);
#endif
		NAND_DISABLE_CE(nand);  /* set pin high */
		return 0;
	}

	/* Read the NAND chip ID: 2. Send address byte zero */
	NanD_Address(nand, ADDR_COLUMN, 0);         //发送地址   

	/* Read the manufacturer and device id codes from the device */

	mfr = READ_NAND(nand->IO_ADDR);             //读出数据1
	id = READ_NAND(nand->IO_ADDR);              //读出数据2

	NAND_DISABLE_CE(nand);  /* set pin high */

#ifdef NAND_DEBUG
	printf("NanD_Command (ReadID) got %x %x\n", mfr, id);
#endif
	if (mfr == 0xff || mfr == 0)    // 不执行
	{
		/* No response - return failure */
		return 0;
	}

	/* Check it's the same as the first chip we identified.
	 * M-Systems say that any given nand_chip device should only
	 * contain _one_ type of flash part, although that's not a
	 * hardware restriction. */
	if (nand->mfr)              //不执行,因为它的值开始的时候是NULL
	{
		if (nand->mfr == mfr && nand->id == id) 
		{
			return 1;	/* This is another the same the first */
		} 
		else 
		{
			printf("Flash chip at floor %d, chip %d is different:\n",floor, chip);
		}
	}

	/* Print and store the manufacturer and ID codes. */
	for (i = 0; nand_flash_ids[i].name != NULL; i++)   /*查找表,在linux/mtd下*/
		{
		if (mfr == nand_flash_ids[i].manufacture_id &&d == nand_flash_ids[i].model_id)  //当找到mfr和id都一样即查找成功 
			{
#ifdef NAND_DEBUG
			printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
			       "Chip ID: 0x%2.2X (%s)\n", mfr, id,
			       nand_flash_ids[i].name);
#endif
			if (!nand->mfr)    //要执行
				{
				nand->mfr = mfr;
				nand->id = id;
				nand->chipshift =
				    nand_flash_ids[i].chipshift;
				nand->page256 = nand_flash_ids[i].page256;
				nand->eccsize = 256;
				if (nand->page256) {
					nand->oobblock = 256;
					nand->oobsize = 8;
					nand->page_shift = 8;
				} 
				else 
				{
					nand->oobblock = 512;
					nand->oobsize = 16;
					nand->page_shift = 9;
				}
				nand->pageadrlen = nand_flash_ids[i].pageadrlen;
				nand->erasesize  = nand_flash_ids[i].erasesize;
				nand->chips_name = nand_flash_ids[i].name;
				nand->bus16	 = nand_flash_ids[i].bus16;
 				return 1;
			}
			return 0;
		}
	}


#ifdef NAND_DEBUG
	/* We haven't fully identified the chip. Print as much as we know. */
	printf("Unknown flash chip found: %2.2X %2.2X\n",
	       id, mfr);
#endif

	return 0;
}





tatic void NanD_ScanChips(struct nand_chip *nand)
{

⌨️ 快捷键说明

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