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

📄 ntb_srom_util.c

📁 基于ecos的redboot
💻 C
字号:
/*
---------------------------------------------------------------------------
                 Copyright (c) 2002, 2003 Intel Corporation
						 All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. 
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. 
* Neither the name of Intel Corporation nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission. 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      
---------------------------------------------------------------------------
system: IXDP2400
subsystem: BootMonitor
author: lagarwal
revisions:
--------------------------------------------------------------------------
*/

#include <cyg/infra/cyg_type.h>
#include <redboot.h>
#include <cyg/hal/hal_ixdp2400.h>
#include <cyg/hal/ntb_srom_util.h>
#include <cyg/io/pci.h>

//#define USE_MEM_ADRS

static cmd_fun do_ntb_srom;

RedBoot_cmd("ntb_srom", 
            "Manage 21555 SROM", 
            "{cmds}",
            do_ntb_srom
    );

local_cmd_entry("read",
                "Read 21555 SROM",
                "-b <offset>",
                cmd_ntb_srom_rd,
                NTB_SROM_cmds
    );

local_cmd_entry("write",
                "Write 21555 SROM",
                "-b <mem_base> -l <image_length>",
                cmd_ntb_srom_wr,
                NTB_SROM_cmds
    );

local_cmd_entry("erase",
                "Erase 21555 SROM",
                "",
                cmd_ntb_srom_erase,
                NTB_SROM_cmds
    );

// Define table boundaries
CYG_HAL_TABLE_BEGIN( __NTB_SROM_cmds_TAB__, NTB_SROM_cmds);
CYG_HAL_TABLE_END( __NTB_SROM_cmds_TAB_END__, NTB_SROM_cmds);

extern struct cmd __NTB_SROM_cmds_TAB__[], __NTB_SROM_cmds_TAB_END__;

cyg_uint32 ntb_iobase = 0;

static void ntb_srom_usage(char *why)
{
    printf("*** invalid command: %s\n", why);
    cmd_usage(__NTB_SROM_cmds_TAB__, &__NTB_SROM_cmds_TAB_END__, "ntb_srom ");
}

static void do_ntb_srom(int argc, char *argv[])
{
    struct cmd *cmd;

    if (argc < 2) {
        ntb_srom_usage("Too few arguments");
        return;
    }
    if ((cmd = cmd_search(__NTB_SROM_cmds_TAB__, &__NTB_SROM_cmds_TAB_END__, 
                          argv[1])) != (struct cmd *)0) {
        (cmd->fun)(argc, argv);
        return;
    }
    ntb_srom_usage("Unrecognized command");
}

static cyg_uint8 read_uint8(cyg_uint32 addr)
{
	cyg_uint8 val;

#ifdef USE_MEM_ADRS
	return *((volatile cyg_uint8 *)addr);
#else
	HAL_READ_UINT8(addr, val);
	return val;
#endif
}

static void write_uint32(cyg_uint32 addr, cyg_uint32 val)
{
#ifdef USE_MEM_ADRS
	*((volatile cyg_uint32 *)addr) = swap32(val);
#else
	*((volatile cyg_uint32 *)addr) = val;
#endif
}

static void write_uint8(cyg_uint32 addr, cyg_uint32 val)
{
#ifdef USE_MEM_ADRS
	*((volatile cyg_uint8 *)addr) = val;
#else
	HAL_WRITE_UINT8(addr, val);
#endif
}

static int check_idle(void)
{
	cyg_uint8 rom_ctl;
	int ctr = 0;

	rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
    /* Check that the previous operation completed */
    while(rom_ctl & (I21555_ROM_CTRL_PromStartBusy | I21555_ROM_CTRL_SromStartBusy))
    {
        hal_delay_us(SROM_WAIT_USEC);
        rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
		ctr++;
		if(ctr > 10)
		{
			printf("idle check timed out\n");
			return 1;
		}
    }
	return 0;
}

static int start_and_wait(void)
{
	cyg_uint8 rom_ctl;
	int ctr = 0;

	write_uint8((ntb_iobase + I21555_ROM_CTRL), I21555_ROM_CTRL_SromStartBusy);

	rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
    while(rom_ctl & I21555_ROM_CTRL_SromStartBusy)
    {
        hal_delay_us(SROM_WAIT_USEC);
		rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
		ctr++;
		if(ctr > 10)
		{
			printf("operation timed out\n");
			return 1;
		}
    }
	return 0;
}

static void start_and_wait_poll(void)
{
	cyg_uint8 rom_ctl;

	write_uint8((ntb_iobase + I21555_ROM_CTRL), I21555_ROM_CTRL_SromStartBusy);

	rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
	while(rom_ctl & I21555_ROM_CTRL_SromStartBusy)
	{
		hal_delay_us(SROM_WAIT_USEC);
		rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
	}
	
	rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
	while (rom_ctl & I21555_ROM_CTRL_SromPoll)
	{
		write_uint8((ntb_iobase + I21555_ROM_CTRL), I21555_ROM_CTRL_SromStartBusy);

		rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
		while(rom_ctl & I21555_ROM_CTRL_SromStartBusy)
		{
			hal_delay_us(SROM_WAIT_USEC);
			rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
		}
		rom_ctl = read_uint8(ntb_iobase + I21555_ROM_CTRL);
	}
}

static int i21555SromWriteEnable(void)
{
	if(check_idle())
		return 1;

	write_uint32((ntb_iobase + I21555_ROM_ADDR), I21555_ROM_ADDR_WriteEnable);

    if(start_and_wait())
	{
		printf("write enable operation failed\n");
		return 1;
	}

	return 0;
}

static void i21555SromWriteDisable(void)
{
	if(check_idle())
		return;

	write_uint32((ntb_iobase + I21555_ROM_ADDR), I21555_ROM_ADDR_WriteDisable);
    
    if(start_and_wait())
		printf("write disable operation failed\n");
}

void get_21555_iobase(void)
{
    cyg_pci_device_id dev_id = CYG_PCI_NULL_DEVID;
    cyg_pci_device dev_info;

	if(!ntb_iobase)
	{
		if(!cyg_pci_find_device(NTB_VENDOR_ID, NTB_DEVICE_ID, &dev_id))
		{
			printf("Couldn't find 21555\n");
			return;
		}

		cyg_pci_get_device_info(dev_id, &dev_info);

#ifdef USE_MEM_ADRS
		ntb_iobase = dev_info.base_map[0];
		//printf("ntb_iobase = 0x%08x\n", ntb_iobase);
		//printf("dev_info.base_address[0] = 0x%08x\n", dev_info.base_address[0]);
#else
		ntb_iobase = dev_info.base_map[1];
		//printf("ntb_iobase = 0x%08x\n", ntb_iobase);
		//printf("dev_info.base_address[1] = 0x%08x\n", dev_info.base_address[1]);
#endif
	}
}

void dump_srom(void *_p, CYG_ADDRWORD s)
{
    int i, c;
    cyg_uint8 *p = (cyg_uint8 *)_p;
    int srom_off = 0;

    while ((int)s > 0) {
        printf("0x%02X: ", srom_off);
        for (i = 0;  i < 16;  i++) {
            if (i < (int)s) {
                printf("%02X", p[i] & 0xFF);
            } else {
                printf("  ");
            }
            if ((i % 2) == 1) printf(" ");
            if ((i % 8) == 7) printf(" ");
        }
        printf(" |");
        for (i = 0;  i < 16;  i++) {
            if (i < (int)s) {
                c = p[i] & 0xFF;
                if ((c < 0x20) || (c >= 0x7F)) c = '.';
            } else {
                c = ' ';
            }
            printf("%c", c);
        }
        printf("|\n");
        s -= 16;
        p += 16;
        srom_off += 16;
    }
}

int read_srom_byte(char off, char *val)
{
    cyg_uint8 ret_val;

    get_21555_iobase();

    if(!ntb_iobase)
    {
        printf("Can't access 21555 CSR\n");
        return 1;
    }

	if(check_idle())
		return 1;

    /* Initiate the read operation */
	write_uint32((ntb_iobase + I21555_ROM_ADDR), (off | I21555_ROM_ADDR_Read));
    
    if(start_and_wait())
	{
		printf("read operation failed\n");
		return 1;
	}
    
	ret_val = read_uint8(ntb_iobase + I21555_ROM_DATA);
    *val = ret_val;

    return 0;
}

void cmd_ntb_srom_rd(int argc, char * argv[])
{
    char i;
    char srom_data[SROM_NUM_BYTES];
	bool rd_addr_set = false;
    struct option_info opts[1];
	int rd_addr;

    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
              (void **)&rd_addr, (bool *)&rd_addr_set, "SROM offset");
    if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, 0))
    {
        ntb_srom_usage("invalid arguments");
        return;
    }

	if(rd_addr_set)
	{
		if(rd_addr > SROM_NUM_BYTES)
		{
			printf("Offset can't be more then %d. Using %d as offset\n", (SROM_NUM_BYTES - 1), (SROM_NUM_BYTES - 1));
			rd_addr = SROM_NUM_BYTES - 1;
		}
		if(read_srom_byte((char)rd_addr, srom_data))
			return;
		printf("value of offset 0x%02X is = 0x%02X\n", rd_addr, srom_data[0]);
		return;
	}

    for(i = 0; i < SROM_NUM_BYTES; i++)
    {
        if(read_srom_byte(i, (srom_data + i)))
			return;
    }
    dump_srom((void *)srom_data, SROM_NUM_BYTES);
}

void write_srom(char *buf, unsigned long len)
{
    char i;

    get_21555_iobase();
    if(!ntb_iobase)
    {
        printf("Can't access 21555 CSR\n");
        return;
    }

	if(i21555SromWriteEnable())
		return;

	if(check_idle())
		return;

    for (i = 0; i < len; i++)
    {
		write_uint32((ntb_iobase + I21555_ROM_ADDR), (i | I21555_ROM_ADDR_Write));

		write_uint8((ntb_iobase + I21555_ROM_DATA), *((volatile cyg_uint8 *)((int)buf + i)));

        if(start_and_wait())
		{
			printf("write operation failed\n");
			return;
		}

        start_and_wait_poll();
    }

	i21555SromWriteDisable();
}

void cmd_ntb_srom_wr(int argc, char * argv[])
{
    unsigned long mem_addr, length;
    bool mem_addr_set = false;
    bool length_set = false;
    struct option_info opts[2];

    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
              (void **)&mem_addr, (bool *)&mem_addr_set, "memory base address");
    init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
              (void **)&length, (bool *)&length_set, "binary length");
    if (!scan_opts(argc, argv, 2, opts, 2, 0, 0, 0))
    {
        ntb_srom_usage("invalid arguments");
        return;
    }

    if (!mem_addr_set || !length_set) {
        ntb_srom_usage("required parameter missing");
        return;
    }

    if(!verify_action("\tOverwrite 21555 SROM"))
        return;

    if(length > SROM_NUM_BYTES)
    {
        printf("Binary Length can't be more then %d. Using %d as binary length\n", SROM_NUM_BYTES, SROM_NUM_BYTES);
        length = SROM_NUM_BYTES;
    }

    write_srom((char *)mem_addr, length);
}

void cmd_ntb_srom_erase(int argc, char * argv[])
{
    get_21555_iobase();
    if(!ntb_iobase)
    {
        printf("Can't access 21555 CSR\n");
        return;
    }

    if(!verify_action("\tErase 21555 SROM"))
        return;

	if(i21555SromWriteEnable())
		return;

	if(check_idle())
		return;

	write_uint32((ntb_iobase + I21555_ROM_ADDR), I21555_ROM_ADDR_EraseAll);

    if(start_and_wait())
	{
		printf("erase all operation failed\n");
		return;
	}

    start_and_wait_poll();

	i21555SromWriteDisable();
}

⌨️ 快捷键说明

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