📄 u-boot代码记录.c
字号:
/* 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 + -