summaryrefslogtreecommitdiff
path: root/util/amdfwtool/amdfwtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/amdfwtool/amdfwtool.c')
-rw-r--r--util/amdfwtool/amdfwtool.c195
1 files changed, 101 insertions, 94 deletions
diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c
index 073c138907..3dff2acb02 100644
--- a/util/amdfwtool/amdfwtool.c
+++ b/util/amdfwtool/amdfwtool.c
@@ -46,6 +46,8 @@
* +------------+---------------+----------------+------------+
* | 'PSP2' | Fletcher | Count |Look up mode|
* +------------+---------------+----------------+------------+
+ * | R e s e r v e d |
+ * +------------+---------------+----------------+------------+
* | ID-Sel | PSP ID | PSPDIR ADDR | | 2nd PSP directory
* +------------+---------------+----------------+------------+
* | ID-Sel | PSP ID | PSPDIR ADDR | | 3rd PSP directory
@@ -166,6 +168,7 @@ typedef enum _amd_fw_type {
AMD_FW_IMC,
AMD_FW_GEC,
AMD_FW_XHCI,
+ AMD_FW_INVALID,
} amd_fw_type;
typedef struct _amd_fw_entry {
@@ -187,6 +190,7 @@ amd_fw_entry amd_psp_fw_table[] = {
{ .type = AMD_FW_PSP_SMU_FIRMWARE2 },
{ .type = AMD_FW_PSP_SMUSCS },
{ .type = AMD_PSP_FUSE_CHAIN },
+ { .type = AMD_FW_INVALID },
};
#if PSP2
@@ -204,6 +208,7 @@ amd_fw_entry amd_psp2_fw_table[] = {
{ .type = AMD_FW_PSP_SMU_FIRMWARE2 },
{ .type = AMD_FW_PSP_SMUSCS },
{ .type = AMD_PSP_FUSE_CHAIN },
+ { .type = AMD_FW_INVALID },
};
#endif
@@ -211,6 +216,7 @@ amd_fw_entry amd_fw_table[] = {
{ .type = AMD_FW_XHCI },
{ .type = AMD_FW_IMC },
{ .type = AMD_FW_GEC },
+ { .type = AMD_FW_INVALID },
};
void fill_psp_head(uint32_t *pspdir, int count)
@@ -221,70 +227,76 @@ void fill_psp_head(uint32_t *pspdir, int count)
pspdir[1] = fletcher32((uint16_t *)&pspdir[1], (count *16 + 16)/2 - 2);
}
-uint32_t integerate_one_fw(void *base, uint32_t pos, uint32_t *romsig, int i)
+uint32_t integrate_firmwares(void *base, uint32_t pos, uint32_t *romsig, amd_fw_entry *fw_table)
{
int fd;
struct stat fd_stat;
+ int i;
- if (amd_fw_table[i].filename != NULL) {
- fd = open (amd_fw_table[i].filename, O_RDONLY);
- fstat(fd, &fd_stat);
-
- switch (amd_fw_table[i].type) {
- case AMD_FW_IMC:
- pos = ALIGN(pos, 0x10000);
- romsig[1] = pos + ROM_BASE_ADDRESS;
- break;
- case AMD_FW_GEC:
- romsig[2] = pos + ROM_BASE_ADDRESS;
- break;
- case AMD_FW_XHCI:
- romsig[3] = pos + ROM_BASE_ADDRESS;
- break;
- default:
- /* Error */
- break;
- }
+ for (i = 0; fw_table[i].type != AMD_FW_INVALID; i ++) {
+ if (fw_table[i].filename != NULL) {
+ fd = open (fw_table[i].filename, O_RDONLY);
+ fstat(fd, &fd_stat);
+
+ switch (fw_table[i].type) {
+ case AMD_FW_IMC:
+ pos = ALIGN(pos, 0x10000);
+ romsig[1] = pos + ROM_BASE_ADDRESS;
+ break;
+ case AMD_FW_GEC:
+ romsig[2] = pos + ROM_BASE_ADDRESS;
+ break;
+ case AMD_FW_XHCI:
+ romsig[3] = pos + ROM_BASE_ADDRESS;
+ break;
+ default:
+ /* Error */
+ break;
+ }
- read (fd, base+pos, fd_stat.st_size);
+ read (fd, base+pos, fd_stat.st_size);
- pos += fd_stat.st_size;
- pos = ALIGN(pos, 0x100);
- close (fd);
+ pos += fd_stat.st_size;
+ pos = ALIGN(pos, 0x100);
+ close (fd);
+ }
}
return pos;
}
-uint32_t integerate_one_psp(void *base, uint32_t pos, uint32_t *pspdir, int i)
+uint32_t integrate_psp_firmwares(void *base, uint32_t pos, uint32_t *pspdir, amd_fw_entry *fw_table)
{
int fd;
struct stat fd_stat;
+ int i;
- if (amd_psp_fw_table[i].type == AMD_PSP_FUSE_CHAIN) {
- pspdir[4+4*i+0] = amd_psp_fw_table[i].type;
- pspdir[4+4*i+1] = 0xFFFFFFFF;
- pspdir[4+4*i+2] = 1;
- pspdir[4+4*i+3] = 0;
- } else if (amd_psp_fw_table[i].filename != NULL) {
- pspdir[4+4*i+0] = amd_psp_fw_table[i].type;
-
- fd = open (amd_psp_fw_table[i].filename, O_RDONLY);
- fstat(fd, &fd_stat);
- pspdir[4+4*i+1] = fd_stat.st_size;
-
- pspdir[4+4*i+2] = pos + ROM_BASE_ADDRESS;
- pspdir[4+4*i+3] = 0;
-
- read (fd, base+pos, fd_stat.st_size);
-
- pos += fd_stat.st_size;
- pos = ALIGN(pos, 0x100);
- close (fd);
- } else {
- /* This APU doesn't have this firmware. */
+ for (i = 0; fw_table[i].type != AMD_FW_INVALID; i ++) {
+ if (fw_table[i].type == AMD_PSP_FUSE_CHAIN) {
+ pspdir[4+4*i+0] = fw_table[i].type;
+ pspdir[4+4*i+1] = 0xFFFFFFFF;
+ pspdir[4+4*i+2] = 1;
+ pspdir[4+4*i+3] = 0;
+ } else if (fw_table[i].filename != NULL) {
+ pspdir[4+4*i+0] = fw_table[i].type;
+
+ fd = open (fw_table[i].filename, O_RDONLY);
+ fstat(fd, &fd_stat);
+ pspdir[4+4*i+1] = fd_stat.st_size;
+
+ pspdir[4+4*i+2] = pos + ROM_BASE_ADDRESS;
+ pspdir[4+4*i+3] = 0;
+
+ read (fd, base+pos, fd_stat.st_size);
+
+ pos += fd_stat.st_size;
+ pos = ALIGN(pos, 0x100);
+ close (fd);
+ } else {
+ /* This APU doesn't have this firmware. */
+ }
}
-
+ fill_psp_head(pspdir, i);
return pos;
}
@@ -363,12 +375,15 @@ void register_fw_filename(amd_fw_type type, char filename[], int pspflag)
int main(int argc, char **argv)
{
- int c, count, pspflag = 0;
+ int c, pspflag = 0;
#if PSP2
int psp2flag = 0;
- int psp2count;
uint32_t *psp2dir;
#endif
+#if PSP_COMBO
+ int psp2count;
+#endif
+
void *rom = NULL;
uint32_t current;
uint32_t *amd_romsig, *pspdir;
@@ -519,9 +534,7 @@ int main(int argc, char **argv)
}
current = ALIGN(current, 0x100);
- for (count = 0; count < sizeof(amd_fw_table) / sizeof(amd_fw_entry); count ++) {
- current = integerate_one_fw(rom, current, amd_romsig, count);
- }
+ current = integrate_firmwares(rom, current, amd_romsig, amd_fw_table);
if (pspflag == 1) {
current = ALIGN(current, 0x10000);
@@ -529,51 +542,45 @@ int main(int argc, char **argv)
amd_romsig[4] = current + ROM_BASE_ADDRESS;
current += 0x200; /* Conservative size of pspdir */
- for (count = 0; count < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); count ++) {
- current = integerate_one_psp(rom, current, pspdir, count);
- }
-
- fill_psp_head(pspdir, count);
+ current = integrate_psp_firmwares(rom, current, pspdir, amd_psp_fw_table);
+ }
#if PSP2
- if (psp2flag == 1) {
- current = ALIGN(current, 0x10000); /* PSP2 dir */
- psp2dir = rom + current;
- amd_romsig[5] = current + ROM_BASE_ADDRESS;
- current += 0x100; /* Add conservative size of psp2dir. */
-
- #if PSP_COMBO
- /* TODO: remove the hardcode. */
- psp2count = 1; /* Start from 1. */
- /* for (; psp2count <= PSP2COUNT; psp2count++, current=ALIGN(current, 0x100)) { */
- /* Now the psp2dir is psp combo dir. */
- psp2dir[psp2count*4 + 0] = 0; /* 0 -Compare PSP ID, 1 -Compare chip family ID */
- psp2dir[psp2count*4 + 1] = 0x10220B00; /* TODO: PSP ID. Documentation is needed. */
- psp2dir[psp2count*4 + 2] = current + ROM_BASE_ADDRESS;
- pspdir = rom + current;
- psp2dir[psp2count*4 + 3] = 0;
-
- current += 0x200; /* Add conservative size of pspdir. Start of PSP entries. */
- for (count = 0; count < sizeof(amd_psp2_fw_table) / sizeof(amd_fw_entry); count ++) {
- current = integerate_one_psp(rom, current, pspdir, count);
- }
- fill_psp_head(pspdir, count);
- /* } */ /* End of loop */
-
- /* fill the PSP combo head */
- psp2dir[0] = 0x50535032; /* 'PSP2' */
- psp2dir[2] = psp2count; /* Count */
- psp2dir[3] = 0; /* 0-Dynamic look up through all entries, 1-PSP/chip ID match */
- psp2dir[1] = fletcher32((uint16_t *)&psp2dir[1], (psp2count*16 + 16)/2 - 2);
- #else
- for (count = 0; count < sizeof(amd_psp2_fw_table) / sizeof(amd_fw_entry); count ++) {
- current = integerate_one_psp(rom, current, psp2dir, count);
- }
- fill_psp_head(psp2dir, count);
- #endif
- }
+ if (psp2flag == 1) {
+ current = ALIGN(current, 0x10000); /* PSP2 dir */
+ psp2dir = rom + current;
+ amd_romsig[5] = current + ROM_BASE_ADDRESS;
+ current += 0x100; /* Add conservative size of psp2dir. */
+
+#if PSP_COMBO
+ /* TODO: remove the hardcode. */
+ psp2count = 1; /* Start from 1. */
+ /* for (; psp2count <= PSP2COUNT; psp2count++, current=ALIGN(current, 0x100)) { */
+ /* Now the psp2dir is psp combo dir. */
+ psp2dir[psp2count*4 + 0 + 4] = 0; /* 0 -Compare PSP ID, 1 -Compare chip family ID */
+ psp2dir[psp2count*4 + 1 + 4] = 0x10220B00; /* TODO: PSP ID. Documentation is needed. */
+ psp2dir[psp2count*4 + 2 + 4] = current + ROM_BASE_ADDRESS;
+ pspdir = rom + current;
+ psp2dir[psp2count*4 + 3 + 4] = 0;
+
+ current += 0x200; /* Add conservative size of pspdir. Start of PSP entries. */
+ current = integrate_psp_firmwares(rom, current, pspdir, amd_psp2_fw_table);
+ /* } */ /* End of loop */
+
+ /* fill the PSP combo head */
+ psp2dir[0] = 0x50535032; /* 'PSP2' */
+ psp2dir[2] = psp2count; /* Count */
+ psp2dir[3] = 1; /* 0-Dynamic look up through all entries, 1-PSP/chip ID match */
+ psp2dir[4] = 0; /* reserved 4 dwords. */
+ psp2dir[5] = 0;
+ psp2dir[6] = 0;
+ psp2dir[7] = 0;
+ psp2dir[1] = fletcher32((uint16_t *)&psp2dir[1], (psp2count*16 + 32)/2 - 2);
+#else
+ current = integrate_psp_firmwares(rom, current, psp2dir, amd_psp2_fw_table);
#endif
}
+#endif
targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);
write(targetfd, amd_romsig, current - AMD_ROMSIG_OFFSET);