Exemplo n.º 1
0
int
hal_flash_program(void *addr, void *data, int len, void **err)
{
    int swabbed = 0;
    cyg_uint32 *p;
    int i, retval;

    if (is_swabbed_redboot(addr, data)
#if (CYG_BYTEORDER == CYG_LSBFIRST) && defined(CYGOPT_REDBOOT_FLASH_BYTEORDER_MSBFIRST)
#ifdef CYGOPT_REDBOOT_FIS
	|| addr == fis_addr
#endif
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
	|| addr == cfg_base
#endif
#endif
	) {
	swabbed = 1;
	for (i = 0, p = data; i < len; i += 4, ++p)
	    *p = CYG_SWAP32(*p);
    }

    retval = flash_program(addr, data, len, err);

    if (swabbed) {
	for (i = 0, p = data; i < len; i += 4, ++p)
	    *p = CYG_SWAP32(*p);
    }

    return retval;
}
Exemplo n.º 2
0
// Try to figure out if RedBoot is re-flashing a RedBoot with
// a different endianess. This is obviously not foolproof, but
// should be good enough.
static inline int
is_swabbed_redboot(void *faddr, cyg_uint32 *p)
{
    if (faddr == (void *)0x50000000
	    && (CYG_SWAP32(p[1]) == 0xe59ff018)
	    && (CYG_SWAP32(p[2]) == 0xe59ff018)
	    && (CYG_SWAP32(p[3]) == 0xe59ff018)
	    && (CYG_SWAP32(p[4]) == 0xe59ff018)
	    && (p[5] == 0))
	return 1;
    return 0;
}
Exemplo n.º 3
0
//
// Little endian mode requires some trickery due to the way the IXP4xx
// AHB and expansion busses work.
//
int
hal_flash_read(void *addr, void *data, int len, void **err)
{
    int retval;

    retval = flash_read(addr, data, len, err);

    if (0
#if (CYG_BYTEORDER == CYG_LSBFIRST) && defined(CYGOPT_REDBOOT_FLASH_BYTEORDER_MSBFIRST)
#ifdef CYGOPT_REDBOOT_FIS
	|| addr == fis_addr
#endif
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
	|| addr == cfg_base
#endif
#endif
	) {
	cyg_uint32 *p;
	int i;

	for (i = 0, p = data; i < len; i += 4, ++p)
	    *p = CYG_SWAP32(*p);
    }
    return retval;
}
Exemplo n.º 4
0
// Change endianness of config data
void
conf_endian_fixup(void *ptr)
{
#ifdef REDBOOT_FLASH_REVERSE_BYTEORDER
    struct _config *p = (struct _config *)ptr;
    unsigned char *dp = p->config_data;
    void *val_ptr;
    int len;
    cyg_uint16 u16;
    cyg_uint32 u32;

    p->len = CYG_SWAP32(p->len);
    p->key1 = CYG_SWAP32(p->key1);
    p->key2 = CYG_SWAP32(p->key2);
    p->cksum = CYG_SWAP32(p->cksum);

    while (dp < &p->config_data[sizeof(config->config_data)]) {
        len = 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) +
            config_length(CONFIG_OBJECT_TYPE(dp));
        val_ptr = (void *)CONFIG_OBJECT_VALUE(dp);

        switch (CONFIG_OBJECT_TYPE(dp)) {
            // Note: the data may be unaligned in the configuration data
        case CONFIG_BOOL:
            if (sizeof(bool) == 2) {
                memcpy(&u16, val_ptr, 2);
                u16 = CYG_SWAP16(u16);
                memcpy(val_ptr, &u16, 2);
            } else if (sizeof(bool) == 4) {
                memcpy(&u32, val_ptr, 4);
                u32 = CYG_SWAP32(u32);
                memcpy(val_ptr, &u32, 4);
            }
            break;
        case CONFIG_INT:
            if (sizeof(unsigned long) == 2) {
                memcpy(&u16, val_ptr, 2);
                u16 = CYG_SWAP16(u16);
                memcpy(val_ptr, &u16, 2);
            } else if (sizeof(unsigned long) == 4) {
                memcpy(&u32, val_ptr, 4);
                u32 = CYG_SWAP32(u32);
                memcpy(val_ptr, &u32, 4);
            }
            break;
        }

        dp += len;
    }
#endif
}
Exemplo n.º 5
0
// fis_endian_fixup() is used to swap endianess if required.
//
static inline void fis_endian_fixup(void *addr)
{
#ifdef REDBOOT_FLASH_REVERSE_BYTEORDER
    struct fis_image_desc *p = addr;
    int cnt = fisdir_size / sizeof(struct fis_image_desc);

    while (cnt-- > 0) {
        p->flash_base = CYG_SWAP32(p->flash_base);
        p->mem_base = CYG_SWAP32(p->mem_base);
        p->size = CYG_SWAP32(p->size);
        p->entry_point = CYG_SWAP32(p->entry_point);
        p->data_length = CYG_SWAP32(p->data_length);
        p->desc_cksum = CYG_SWAP32(p->desc_cksum);
        p->file_cksum = CYG_SWAP32(p->file_cksum);
        p++;
    }
#endif
}
Exemplo n.º 6
0
Arquivo: swab.c Projeto: cilynx/dd-wrt
static void
do_swab(int argc, char *argv[])
{
    // Fill a region of memory with a pattern
    struct option_info opts[4];
    unsigned long base;
    long len;
    bool base_set, len_set;
    bool set_32bit, set_16bit;

    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
              (void *)&base, (bool *)&base_set, "base address");
    init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
              (void *)&len, (bool *)&len_set, "length");
    init_opts(&opts[2], '4', false, OPTION_ARG_TYPE_FLG,
              (void *)&set_32bit, (bool *)0, "fill 32 bit units");
    init_opts(&opts[3], '2', false, OPTION_ARG_TYPE_FLG,
              (void *)&set_16bit, (bool *)0, "fill 16 bit units");
    if (!scan_opts(argc, argv, 1, opts, 4, 0, 0, "")) {
        return;
    }
    if (!base_set || !len_set) {
        diag_printf("usage: swab -b <addr> -l <length> [-2|-4]\n");
        return;
    }
    if (set_16bit) {
        // 16 bits at a time
        while ((len -= sizeof(cyg_uint16)) >= 0) {
	    *(cyg_uint16 *)base = CYG_SWAP16(*(cyg_uint16 *)base);
	    base += sizeof(cyg_uint16);
	}
    } else {
        // Default - 32 bits
        while ((len -= sizeof(cyg_uint32)) >= 0) {
	    *(cyg_uint32 *)base = CYG_SWAP32(*(cyg_uint32 *)base);
	    base += sizeof(cyg_uint32);
	}
    }
}