📄 prism2dl.c
字号:
** Arguments:* fchunk Array of image chunks* nfchunks Number of image chunks* s3plug Array of plug records* ns3plug Number of plug records* pda Current pda data* fname File the image data was read from** Returns: * 0 success* ~0 failure----------------------------------------------------------------*/int plugimage( imgchunk_t *fchunk, UINT nfchunks, s3plugrec_t* s3plug, UINT ns3plug, pda_t *pda, char *fname){ int result = 0; int i; /* plug index */ int j; /* index of PDR or -1 if fname plug */ int c; /* chunk index */ UINT32 pstart; UINT32 pend; UINT32 cstart = 0; UINT32 cend; UINT32 chunkoff; UINT8 *src; UINT8 *dest; /* for each plug record */ for ( i = 0; i < ns3plug; i++) { pstart = s3plug[i].addr; pend = s3plug[i].addr + s3plug[i].len; /* find the matching PDR (or filename) */ if ( s3plug[i].itemcode != 0xffffffffUL ) { /* not filename */ for ( j = 0; j < pda->nrec; j++) { if ( s3plug[i].itemcode == hfa384x2host_16(pda->rec[j]->code) ) break; } } else { j = -1; } if ( j >= pda->nrec && j != -1 ) { /* if no matching PDR, fail */ fprintf(stderr, APPNAME ": warning: Failed to find PDR for " "plugrec 0x%04lx.\n", s3plug[i].itemcode); continue; /* and move on to the next PDR */#if 0 /* MSM: They swear that unless it's the MAC address, * the serial number, or the TX calibration records, * then there's reasonable defaults in the f/w * image. Therefore, missing PDRs in the card * should only be a warning, not fatal. * TODO: add fatals for the PDRs mentioned above. */ result = 1; continue; #endif } /* Validate plug len against PDR len */ if ( j != -1 && s3plug[i].len < hfa384x2host_16(pda->rec[j]->len) ) { fprintf(stderr, APPNAME ": error: Plug vs. PDR len mismatch for " "plugrec 0x%04lx, abort plugging.\n", s3plug[i].itemcode); result = 1; continue; } /* Validate plug address against chunk data and identify chunk */ for ( c = 0; c < nfchunks; c++) { cstart = fchunk[c].addr; cend = fchunk[c].addr + fchunk[c].len; if ( pstart >= cstart && pend <= cend ) break; } if ( c >= nfchunks ) { fprintf(stderr, APPNAME ": error: Failed to find image chunk for " "plugrec 0x%04lx.\n", s3plug[i].itemcode); result = 1; continue; } /* Plug data */ chunkoff = pstart - cstart; dest = fchunk[c].data + chunkoff; if (opt_verbose) { printf("Plugging item 0x%04lx @ 0x%06lx, len=%ld, " "cnum=%d coff=0x%06lx\n", s3plug[i].itemcode, pstart, s3plug[i].len, c, chunkoff); } if ( j == -1 ) { /* plug the filename */ src = strrchr(fname, '/'); src = (src == NULL) ? (UINT8*)fname : src + 1; memset(dest, 0, s3plug[i].len); strncpy(dest, src, s3plug[i].len - 1); } else { /* plug a PDR */ memcpy( dest, &(pda->rec[j]->data), s3plug[i].len); } } return result;}/*----------------------------------------------------------------* print_all_pdrs** Dumps the contents of all the pdr lists to stdout. Assumes that* the pdrlists have 'been made'. See mkpdrlist().** Arguments: none** Returns: * 0 - success * ~0 - failure (probably an errno)----------------------------------------------------------------*/void print_all_pdrs(pda_t *pda){ int i; int j; UINT16 *datap; UINT8 *offp; int end; int nwords; if ( opt_generate ) { for ( i = 0; i < pda->nrec; i++) { datap = (UINT16*)(pda->rec[i]); nwords = hfa384x2host_16(pda->rec[i]->len) +1; for ( j = 0; j < nwords; j++) { printf("0x%04x, ", hfa384x2host_16(datap[j])); } printf("\n"); } return; } printf("Current PDA:\n"); printf( " offset len code data\n" " ---------------------------------------------------\n"); /* 00000000 000 0x0000 0000 0000 0000 0000 0000.... */ /* 0000 0000 0000 0000 0000.... */ for ( i = 0; i < pda->nrec; i++) { offp = (UINT8*)(pda->rec[i]); printf(" %08d %03d 0x%04x ", offp - pda->buf, hfa384x2host_16(pda->rec[i]->len), hfa384x2host_16(pda->rec[i]->code)); datap = (UINT16*)&(pda->rec[i]->data.end_of_pda); nwords = hfa384x2host_16(pda->rec[i]->len) - 1; for ( j = 0; j < nwords; j++) { printf("%04x ", hfa384x2host_16(datap[j]) ); if ( (j % 8) == 7 && j < nwords - 1 ) { printf("\n "); } } printf("\n"); } if (opt_verbose) { printf("Raw PDA:\n"); datap = (UINT16*)pda->buf; end = (((UINT8*)pda->rec[pda->nrec - 1]) - pda->buf + 6) / 2; printf(" "); for ( i = 0; i < end; i++ ) { printf("%04x ", hfa384x2host_16(datap[i]) ); if ( (i % 16) == 15 ) { printf("\n "); } } printf("\n"); }}/*----------------------------------------------------------------* read_cardpda** Sends the command for the driver to read the pda from the card* named in the device variable. Upon success, the card pda is * stored in the "cardpda" variables. Note that the pda structure* is considered 'well formed' after this function. That means* that the nrecs is valid, the rec array has been set up, and there's* a valid PDAEND record in the raw PDA data.** Arguments: none** Returns: * 0 - success * ~0 - failure (probably an errno)----------------------------------------------------------------*/int read_cardpda(pda_t *pda, char *dev){ int result = 0; p80211msg_p2req_readpda_t msg; /* set up the msg */ msg.msgcode = DIDmsg_p2req_readpda; msg.msglen = sizeof(msg); strcpy(msg.devname, dev); msg.pda.did = DIDmsg_p2req_readpda_pda; msg.pda.len = HFA384x_PDA_LEN_MAX; msg.pda.status = P80211ENUM_msgitem_status_no_value; msg.resultcode.did = DIDmsg_p2req_readpda_resultcode; msg.resultcode.len = sizeof(UINT32); msg.resultcode.status = P80211ENUM_msgitem_status_no_value; if ( do_ioctl((p80211msg_t*)&msg) != 0 ) { /* do_ioctl prints an errno if appropriate */ result = -1; } else if ( msg.resultcode.data == P80211ENUM_resultcode_success ) { memcpy(pda->buf, msg.pda.data, HFA384x_PDA_LEN_MAX); result = mkpdrlist(pda); } else { /* resultcode must've been something other than success */ result = -1; } return result;}/*---------------------------------------------------------------* merge_pda* Merge the given pdr records into the given pda.* New PDR's are added.* If a PDR already exists then the current PDR overwrites the existing one.* If the PDR has a length of 1 then it is removed from the PDA.---------------------------------------------------------------*/voidmerge_pda(pda_t *pda, UINT16 *pdword, int nwords){ int i = 0; int j = 0; UINT8 *delpdastart; UINT8 *mvpdastart; UINT16 pdrlen; UINT16 pdrcode; UINT mvlen; /* Now, merge into the pda */ /* note that all the words are in hfa384x order */ i = 0; while ( i < nwords ) { /* For each PDR in the new list */ pdrlen = hfa384x2host_16(pdword[i]); /* in words */ pdrcode = hfa384x2host_16(pdword[i+1]); if ( pdrlen > (HFA384x_PDR_LEN_MAX / 2) ) { fprintf(stderr,APPNAME": invalid pdr length (0x%04x) encountered (pdrcode=0x%04x), exiting.\n", pdrlen, pdrcode); exit(1); } for ( j = 0; j < pda->nrec; j++) { /* Find matching code in PDA */ if ( pdrcode == hfa384x2host_16(pda->rec[j]->code) ) { break; } } if ( pdrlen == 1 && j < pda->nrec ) { /* Remove the pdr from the PDA */ if (opt_verbose) { printf(" Removing PDR: code=%04x, len=%d\n", pdrcode, pdrlen); } delpdastart = (UINT8*)(pda->rec[j]); mvpdastart = delpdastart + ((hfa384x2host_16(pda->rec[j]->len) + 1) * sizeof(UINT16)); mvlen = HFA384x_PDA_LEN_MAX - (mvpdastart - pda->buf); memmove( delpdastart, mvpdastart, mvlen); pda->nrec = 0; mkpdrlist(pda); } else if ( j < pda->nrec ) { /* Replace the pdr in the PDA */ if (opt_verbose) { printf(" Replacing PDR: code=%04x, len=%d\n", pdrcode, pdrlen); } if ( pdrlen == hfa384x2host_16(pda->rec[j]->len) ) { /* just overwrite */ memcpy( pda->rec[j], &(pdword[i]), (pdrlen + 1)*sizeof(UINT16)); } else { fprintf( stderr, APPNAME ": Replacing pdrs where (newlen!=oldlen) not " "supported.\n"); exit(1); } } else { /* Add the pdr to the PDA */ UINT8 *endp = (UINT8*)(pda->rec[pda->nrec - 1]); if (opt_verbose) { printf(" Adding PDR: code=%04x, len=%d\n", pdrcode, pdrlen); } /* overwrite the existing end record and add a new one */ memcpy( endp, &(pdword[i]), (pdrlen + 1)*sizeof(UINT16)); pda->rec[pda->nrec] = (hfa384x_pdrec_t*) (endp + ((pdrlen+1) * sizeof(UINT16))); pda->rec[pda->nrec]->len = host2hfa384x_16(2); pda->rec[pda->nrec]->code = host2hfa384x_16(HFA384x_PDR_END_OF_PDA); pda->rec[pda->nrec]->data.end_of_pda.crc = 0; pda->nrec++; } i += pdrlen + 1; }}/*----------------------------------------------------------------* read_filepda** Reads a collection of PDRs from a file and merges them into the* current PDA data set maintained within this program. The * PDA data set may be empty or not.** ASSUMED FILE FORMAT:* pdrline := <sep><hexnum><pdrline>[<sep>]* hexnum := [0x][[:hexdigit:]]{1-4}* sep := [,[:space:]][[:space:]]** COMMENTS:* ANY DETECTED CHARACTER that doesn't match * [[:space:][:hexdigit:],x] indicates the start of a comment* that extends to EOL. Note the 'x', it never starts an element* so we really don't have to worry about it.* REMOVE RECORDS:* PDR items in the file that have a length of 1 indicate that* the given PDR should be removed from the PDA. If that* same item appears later in the file (or in a subsequent* file) then it will be added again.** Arguments: none** Returns: * 0 - success * ~0 - failure (probably an errno)----------------------------------------------------------------*/int read_filepda(pda_t *pda, char *pdrfname){ int result = 0; FILE *pdrfile; UINT16 pdword[HFA384x_PDA_LEN_MAX / sizeof(UINT16)]; UINT nwords = 0; char linebuf[PDAFILE_LINE_MAX]; char *currp = NULL; char *nextp = NULL; regex_t regex; regmatch_t regmatch; char ebuf[100]; /* Open the file */ pdrfile = fopen(pdrfname, "r"); if ( pdrfile == NULL ) { result=errno; perror(APPNAME); return result; } printf("Processing PDR file: %s\n", pdrfname); /* Read all the words, skipping over the comments etc. */ memset(linebuf, 0, PDAFILE_LINE_MAX); result = regcomp( ®ex, "[,[:blank:]][[:blank:]]*", 0); if ( result != 0 ) { regerror( result, ®ex, ebuf, sizeof(ebuf)); fprintf(stderr, APPNAME": failed to compile pda regexp err=%s.\n", ebuf); exit(1); } while ( fgets(linebuf, PDAFILE_LINE_MAX, pdrfile) != NULL) { currp = linebuf; nextp = NULL; pdword[nwords] = strtoul( currp, &nextp, 16); if ( currp == nextp ) { /* is there noting valid? */ continue; } else { pdword[nwords] = host2hfa384x_16(pdword[nwords]); nwords++; currp = nextp; } while ( regexec(®ex, currp, 1, ®match, 0) == 0 ) { currp += regmatch.rm_eo; if ( !isxdigit(*currp) ) { /* Assume comment and move to next line */ memset(linebuf, 0, PDAFILE_LINE_MAX); break; } pdword[nwords] = strtoul( currp, &nextp, 16); pdword[nwords] = host2hfa384x_16(pdword[nwords]); /* printf("pdword=%04x currp=\"%s\"\n", pdword[nwords], currp); */ nwords++; currp = nextp; } memset(linebuf, 0, PDAFILE_LINE_MAX); } /* Merge the records into the pda */ merge_pda(pda, pdword, nwords); return result;}/*----------------------------------------------------------------* read_srecfile** Reads the given srecord file and loads the records into the * s3xxx arrays. This function can be called repeatedly (once for* each of a set of files), if necessary. This function performs* no validation of the data except for the grossest of S-record* line format checks. Don't forget that these will be DOS files...* CR/LF at the end of each line.** Here's the SREC format we're dealing with:* S[37]nnaaaaaaaaddd...dddcc** nn - number of bytes starting with the address field* aaaaaaaa - address in readable (or big endian) format* dd....dd - 0-245 data bytes (two chars per byte)* cc - checksum** The S7 record's (there should be only one) address value gets* saved in startaddr. It's the start execution address used* for RAM downloads. ** The S3 records have a collection of subformats indicated by the* value of aaaaaaaa:* 0xff000000 - Plug record, data field format:* xxxxxxxxaaaaaaaassssssss* x - PDR code number (little endian)* a - Address in load image to plug (little endian)* s - Length of plug data area (little endian)** 0xff100000 - CRC16 generation record, data field format:* aaaaaaaassssssssbbbbbbbb* a - Start address for CRC calculation (little endian)* s - Length of data to calculate over (little endian)* b - Boolean, true=write crc, false=don't write* * 0xff200000 - Info record, data field format:* ssssttttdd..dd
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -