FreeCalypso > hg > freecalypso-sw
view loadtools/flutil.c @ 270:d1388095ab27
doc/RVTMUX write-up
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Thu, 06 Feb 2014 09:54:02 +0000 |
parents | cd12d1049f91 |
children | f027c6fbe37e |
line wrap: on
line source
/* * Miscellaneous utility functions for flash support */ #include <sys/types.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include "flash.h" extern struct flash_bank_info flash_bank_info[2]; compute_flash_totsize_nsecs(bank) { struct flash_bank_info *bi; struct flash_region_desc *reg; bi = flash_bank_info + bank; for (reg = bi->bank_desc->regions; reg->nsectors; reg++) { bi->nsectors += reg->nsectors; bi->total_size += reg->sector_size * reg->nsectors; } } /* the following function is used to verify that total_size is a power of 2 */ count_ones(word) uint32_t word; { int count; for (count = 0; word; word >>= 1) count += word & 1; return count; } get_flash_sector_table(bank) { struct flash_bank_info *bi; struct flash_region_desc *reg; struct sector_info *sp; uint32_t offset; int i; bi = flash_bank_info + bank; if (bi->sectors) return(0); sp = (struct sector_info *) malloc(sizeof(struct sector_info) * (bi->nsectors + 1)); if (!sp) { fprintf(stderr, "unable to malloc buffer for flash bank %d sector table\n", bank); return(-1); } bi->sectors = sp; /* now fill it */ offset = 0; for (reg = bi->bank_desc->regions; reg->nsectors; reg++) { for (i = 0; i < reg->nsectors; i++) { sp->start = offset; sp->size = reg->sector_size; sp++; offset += reg->sector_size; } } /* sanity checks */ if (sp - bi->sectors != bi->nsectors) { fprintf(stderr, "BUG in get_flash_sector_table(): wrong # of sectors at the end\n"); abort(); } if (offset != bi->total_size) { fprintf(stderr, "BUG in get_flash_sector_table(): wrong offset at the end\n"); abort(); } /* finish */ sp->start = 0; sp->size = 0; return(0); } flashcmd_sectors(argc, argv, bank) char **argv; { struct flash_bank_info *bi; struct sector_info *sp; if (argc > 2) { fprintf(stderr, "error: too many arguments\n"); return(-1); } if (get_flash_sector_table(bank) < 0) return(-1); bi = flash_bank_info + bank; printf("%u sectors in flash bank %d:\n", bi->nsectors, bank); printf("Offset Size\n"); for (sp = bi->sectors; sp->size; sp++) printf("%08lX %lx\n", (u_long) sp->start, (u_long) sp->size); return(0); } get_flash_sector_range(bi, useroff, userlen, startp, endp) struct flash_bank_info *bi; u_long useroff, userlen; struct sector_info **startp, **endp; { struct sector_info *sp; uint32_t remlen; for (sp = bi->sectors; sp->size; sp++) if (sp->start == useroff) break; if (!sp->size) { fprintf(stderr, "error: specified offset not aligned to a flash sector boundary\n"); return(-1); } *startp = sp; for (remlen = userlen; remlen; ) { if (remlen < sp->size) { fprintf(stderr, "error: specified length not aligned to a flash sector boundary\n"); return(-1); } remlen -= sp->size; sp++; } *endp = sp; return(0); } build_flashw_hex_string(bin, strbuf, nwords, m0src) u_char *bin; char *strbuf; int nwords, m0src; { int i; u_char *dp; char *s; for (dp = bin, s = strbuf, i = 0; i < nwords; dp += 2, s += 4, i++) { if (m0src) sprintf(s, "%02X%02X", dp[0], dp[1]); else sprintf(s, "%02X%02X", dp[1], dp[0]); } *s = '\0'; } flash_id_check(bank, repeat) { struct flash_bank_info *bi; struct flash_bank_desc *bd; struct flash_idcheck *id; int stat, fail; uint16_t rdval; unsigned cnt; bi = flash_bank_info + bank; if (bi->idcheck_done && !repeat) return(0); printf("Performing flash ID check\n"); stat = do_w16(bi->base_addr + 0xAAA, 0xAA); if (stat) { bad_w16: fprintf(stderr, "unexpected response to w16 in read ID cmd sequence - aborting\n"); return(-1); } stat = do_w16(bi->base_addr + 0x554, 0x55); if (stat) goto bad_w16; stat = do_w16(bi->base_addr + 0xAAA, 0x90); if (stat) goto bad_w16; bd = bi->bank_desc; id = bd->idcheck_table; fail = 0; for (cnt = 0; cnt < bd->idcheck_num; cnt++) { stat = do_r16(bi->base_addr + id->offset, &rdval); if (stat) return(stat); /* error msg already printed */ printf("offset %02X: %04X -- ", (int)id->offset, (int)rdval); if (rdval == id->expect_val) printf("PASS\n"); else { printf("FAIL: expected %04X\n", (int)id->expect_val); fail = 1; break; } id++; } /* reset flash to read mode */ stat = do_w16(bi->base_addr + 0xAAA, 0xF0); if (stat) { fprintf(stderr, "unexpected response to w16 when resetting flash to read mode!\n"); return(-1); } if (fail) return(-1); bi->idcheck_done = 1; return(0); }