amdfwtool: Fix some PSP2 issues
1. Change the function which integrated one firmware, to the function which pushes the whole group. Use fw_table as a parameter instead of using the global table name. 2. Let PSP2 and PSP1 not dependent on the other. It turns out PSP2 can exist without PSP1. For some APU, the PSP directory has to be put in PSP2 field (ROMSIG 0x14). 3. Reserve 32 more bytes in PSP2 header. It is defined by spec. It is tested, and it is true. These above changes are overlapping, hard to split them. Sorry. Change-Id: I834630d9596d7fb941e2cad5d00ac3af04a537b5 Signed-off-by: Zheng Bao <fishbaozi@gmail.com> Reviewed-on: https://review.coreboot.org/13808 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
parent
ebf732b4a5
commit
c3a08a9d5e
|
@ -46,6 +46,8 @@
|
||||||
* +------------+---------------+----------------+------------+
|
* +------------+---------------+----------------+------------+
|
||||||
* | 'PSP2' | Fletcher | Count |Look up mode|
|
* | '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 | | 2nd PSP directory
|
||||||
* +------------+---------------+----------------+------------+
|
* +------------+---------------+----------------+------------+
|
||||||
* | ID-Sel | PSP ID | PSPDIR ADDR | | 3rd 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_IMC,
|
||||||
AMD_FW_GEC,
|
AMD_FW_GEC,
|
||||||
AMD_FW_XHCI,
|
AMD_FW_XHCI,
|
||||||
|
AMD_FW_INVALID,
|
||||||
} amd_fw_type;
|
} amd_fw_type;
|
||||||
|
|
||||||
typedef struct _amd_fw_entry {
|
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_SMU_FIRMWARE2 },
|
||||||
{ .type = AMD_FW_PSP_SMUSCS },
|
{ .type = AMD_FW_PSP_SMUSCS },
|
||||||
{ .type = AMD_PSP_FUSE_CHAIN },
|
{ .type = AMD_PSP_FUSE_CHAIN },
|
||||||
|
{ .type = AMD_FW_INVALID },
|
||||||
};
|
};
|
||||||
|
|
||||||
#if PSP2
|
#if PSP2
|
||||||
|
@ -204,6 +208,7 @@ amd_fw_entry amd_psp2_fw_table[] = {
|
||||||
{ .type = AMD_FW_PSP_SMU_FIRMWARE2 },
|
{ .type = AMD_FW_PSP_SMU_FIRMWARE2 },
|
||||||
{ .type = AMD_FW_PSP_SMUSCS },
|
{ .type = AMD_FW_PSP_SMUSCS },
|
||||||
{ .type = AMD_PSP_FUSE_CHAIN },
|
{ .type = AMD_PSP_FUSE_CHAIN },
|
||||||
|
{ .type = AMD_FW_INVALID },
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -211,6 +216,7 @@ amd_fw_entry amd_fw_table[] = {
|
||||||
{ .type = AMD_FW_XHCI },
|
{ .type = AMD_FW_XHCI },
|
||||||
{ .type = AMD_FW_IMC },
|
{ .type = AMD_FW_IMC },
|
||||||
{ .type = AMD_FW_GEC },
|
{ .type = AMD_FW_GEC },
|
||||||
|
{ .type = AMD_FW_INVALID },
|
||||||
};
|
};
|
||||||
|
|
||||||
void fill_psp_head(uint32_t *pspdir, int count)
|
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);
|
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;
|
int fd;
|
||||||
struct stat fd_stat;
|
struct stat fd_stat;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (amd_fw_table[i].filename != NULL) {
|
for (i = 0; fw_table[i].type != AMD_FW_INVALID; i ++) {
|
||||||
fd = open (amd_fw_table[i].filename, O_RDONLY);
|
if (fw_table[i].filename != NULL) {
|
||||||
fstat(fd, &fd_stat);
|
fd = open (fw_table[i].filename, O_RDONLY);
|
||||||
|
fstat(fd, &fd_stat);
|
||||||
|
|
||||||
switch (amd_fw_table[i].type) {
|
switch (fw_table[i].type) {
|
||||||
case AMD_FW_IMC:
|
case AMD_FW_IMC:
|
||||||
pos = ALIGN(pos, 0x10000);
|
pos = ALIGN(pos, 0x10000);
|
||||||
romsig[1] = pos + ROM_BASE_ADDRESS;
|
romsig[1] = pos + ROM_BASE_ADDRESS;
|
||||||
break;
|
break;
|
||||||
case AMD_FW_GEC:
|
case AMD_FW_GEC:
|
||||||
romsig[2] = pos + ROM_BASE_ADDRESS;
|
romsig[2] = pos + ROM_BASE_ADDRESS;
|
||||||
break;
|
break;
|
||||||
case AMD_FW_XHCI:
|
case AMD_FW_XHCI:
|
||||||
romsig[3] = pos + ROM_BASE_ADDRESS;
|
romsig[3] = pos + ROM_BASE_ADDRESS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Error */
|
/* Error */
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
read (fd, base+pos, fd_stat.st_size);
|
||||||
|
|
||||||
|
pos += fd_stat.st_size;
|
||||||
|
pos = ALIGN(pos, 0x100);
|
||||||
|
close (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
read (fd, base+pos, fd_stat.st_size);
|
|
||||||
|
|
||||||
pos += fd_stat.st_size;
|
|
||||||
pos = ALIGN(pos, 0x100);
|
|
||||||
close (fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pos;
|
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;
|
int fd;
|
||||||
struct stat fd_stat;
|
struct stat fd_stat;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (amd_psp_fw_table[i].type == AMD_PSP_FUSE_CHAIN) {
|
for (i = 0; fw_table[i].type != AMD_FW_INVALID; i ++) {
|
||||||
pspdir[4+4*i+0] = amd_psp_fw_table[i].type;
|
if (fw_table[i].type == AMD_PSP_FUSE_CHAIN) {
|
||||||
pspdir[4+4*i+1] = 0xFFFFFFFF;
|
pspdir[4+4*i+0] = fw_table[i].type;
|
||||||
pspdir[4+4*i+2] = 1;
|
pspdir[4+4*i+1] = 0xFFFFFFFF;
|
||||||
pspdir[4+4*i+3] = 0;
|
pspdir[4+4*i+2] = 1;
|
||||||
} else if (amd_psp_fw_table[i].filename != NULL) {
|
pspdir[4+4*i+3] = 0;
|
||||||
pspdir[4+4*i+0] = amd_psp_fw_table[i].type;
|
} else if (fw_table[i].filename != NULL) {
|
||||||
|
pspdir[4+4*i+0] = fw_table[i].type;
|
||||||
|
|
||||||
fd = open (amd_psp_fw_table[i].filename, O_RDONLY);
|
fd = open (fw_table[i].filename, O_RDONLY);
|
||||||
fstat(fd, &fd_stat);
|
fstat(fd, &fd_stat);
|
||||||
pspdir[4+4*i+1] = fd_stat.st_size;
|
pspdir[4+4*i+1] = fd_stat.st_size;
|
||||||
|
|
||||||
pspdir[4+4*i+2] = pos + ROM_BASE_ADDRESS;
|
pspdir[4+4*i+2] = pos + ROM_BASE_ADDRESS;
|
||||||
pspdir[4+4*i+3] = 0;
|
pspdir[4+4*i+3] = 0;
|
||||||
|
|
||||||
read (fd, base+pos, fd_stat.st_size);
|
read (fd, base+pos, fd_stat.st_size);
|
||||||
|
|
||||||
pos += fd_stat.st_size;
|
pos += fd_stat.st_size;
|
||||||
pos = ALIGN(pos, 0x100);
|
pos = ALIGN(pos, 0x100);
|
||||||
close (fd);
|
close (fd);
|
||||||
} else {
|
} else {
|
||||||
/* This APU doesn't have this firmware. */
|
/* This APU doesn't have this firmware. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
fill_psp_head(pspdir, i);
|
||||||
return pos;
|
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 main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c, count, pspflag = 0;
|
int c, pspflag = 0;
|
||||||
#if PSP2
|
#if PSP2
|
||||||
int psp2flag = 0;
|
int psp2flag = 0;
|
||||||
int psp2count;
|
|
||||||
uint32_t *psp2dir;
|
uint32_t *psp2dir;
|
||||||
#endif
|
#endif
|
||||||
|
#if PSP_COMBO
|
||||||
|
int psp2count;
|
||||||
|
#endif
|
||||||
|
|
||||||
void *rom = NULL;
|
void *rom = NULL;
|
||||||
uint32_t current;
|
uint32_t current;
|
||||||
uint32_t *amd_romsig, *pspdir;
|
uint32_t *amd_romsig, *pspdir;
|
||||||
|
@ -519,9 +534,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
current = ALIGN(current, 0x100);
|
current = ALIGN(current, 0x100);
|
||||||
for (count = 0; count < sizeof(amd_fw_table) / sizeof(amd_fw_entry); count ++) {
|
current = integrate_firmwares(rom, current, amd_romsig, amd_fw_table);
|
||||||
current = integerate_one_fw(rom, current, amd_romsig, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pspflag == 1) {
|
if (pspflag == 1) {
|
||||||
current = ALIGN(current, 0x10000);
|
current = ALIGN(current, 0x10000);
|
||||||
|
@ -529,51 +542,45 @@ int main(int argc, char **argv)
|
||||||
amd_romsig[4] = current + ROM_BASE_ADDRESS;
|
amd_romsig[4] = current + ROM_BASE_ADDRESS;
|
||||||
|
|
||||||
current += 0x200; /* Conservative size of pspdir */
|
current += 0x200; /* Conservative size of pspdir */
|
||||||
for (count = 0; count < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); count ++) {
|
current = integrate_psp_firmwares(rom, current, pspdir, amd_psp_fw_table);
|
||||||
current = integerate_one_psp(rom, current, pspdir, count);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fill_psp_head(pspdir, count);
|
|
||||||
|
|
||||||
#if PSP2
|
#if PSP2
|
||||||
if (psp2flag == 1) {
|
if (psp2flag == 1) {
|
||||||
current = ALIGN(current, 0x10000); /* PSP2 dir */
|
current = ALIGN(current, 0x10000); /* PSP2 dir */
|
||||||
psp2dir = rom + current;
|
psp2dir = rom + current;
|
||||||
amd_romsig[5] = current + ROM_BASE_ADDRESS;
|
amd_romsig[5] = current + ROM_BASE_ADDRESS;
|
||||||
current += 0x100; /* Add conservative size of psp2dir. */
|
current += 0x100; /* Add conservative size of psp2dir. */
|
||||||
|
|
||||||
#if PSP_COMBO
|
#if PSP_COMBO
|
||||||
/* TODO: remove the hardcode. */
|
/* TODO: remove the hardcode. */
|
||||||
psp2count = 1; /* Start from 1. */
|
psp2count = 1; /* Start from 1. */
|
||||||
/* for (; psp2count <= PSP2COUNT; psp2count++, current=ALIGN(current, 0x100)) { */
|
/* for (; psp2count <= PSP2COUNT; psp2count++, current=ALIGN(current, 0x100)) { */
|
||||||
/* Now the psp2dir is psp combo dir. */
|
/* Now the psp2dir is psp combo dir. */
|
||||||
psp2dir[psp2count*4 + 0] = 0; /* 0 -Compare PSP ID, 1 -Compare chip family ID */
|
psp2dir[psp2count*4 + 0 + 4] = 0; /* 0 -Compare PSP ID, 1 -Compare chip family ID */
|
||||||
psp2dir[psp2count*4 + 1] = 0x10220B00; /* TODO: PSP ID. Documentation is needed. */
|
psp2dir[psp2count*4 + 1 + 4] = 0x10220B00; /* TODO: PSP ID. Documentation is needed. */
|
||||||
psp2dir[psp2count*4 + 2] = current + ROM_BASE_ADDRESS;
|
psp2dir[psp2count*4 + 2 + 4] = current + ROM_BASE_ADDRESS;
|
||||||
pspdir = rom + current;
|
pspdir = rom + current;
|
||||||
psp2dir[psp2count*4 + 3] = 0;
|
psp2dir[psp2count*4 + 3 + 4] = 0;
|
||||||
|
|
||||||
current += 0x200; /* Add conservative size of pspdir. Start of PSP entries. */
|
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 = integrate_psp_firmwares(rom, current, pspdir, amd_psp2_fw_table);
|
||||||
current = integerate_one_psp(rom, current, pspdir, count);
|
/* } */ /* End of loop */
|
||||||
}
|
|
||||||
fill_psp_head(pspdir, count);
|
|
||||||
/* } */ /* End of loop */
|
|
||||||
|
|
||||||
/* fill the PSP combo head */
|
/* fill the PSP combo head */
|
||||||
psp2dir[0] = 0x50535032; /* 'PSP2' */
|
psp2dir[0] = 0x50535032; /* 'PSP2' */
|
||||||
psp2dir[2] = psp2count; /* Count */
|
psp2dir[2] = psp2count; /* Count */
|
||||||
psp2dir[3] = 0; /* 0-Dynamic look up through all entries, 1-PSP/chip ID match */
|
psp2dir[3] = 1; /* 0-Dynamic look up through all entries, 1-PSP/chip ID match */
|
||||||
psp2dir[1] = fletcher32((uint16_t *)&psp2dir[1], (psp2count*16 + 16)/2 - 2);
|
psp2dir[4] = 0; /* reserved 4 dwords. */
|
||||||
#else
|
psp2dir[5] = 0;
|
||||||
for (count = 0; count < sizeof(amd_psp2_fw_table) / sizeof(amd_fw_entry); count ++) {
|
psp2dir[6] = 0;
|
||||||
current = integerate_one_psp(rom, current, psp2dir, count);
|
psp2dir[7] = 0;
|
||||||
}
|
psp2dir[1] = fletcher32((uint16_t *)&psp2dir[1], (psp2count*16 + 32)/2 - 2);
|
||||||
fill_psp_head(psp2dir, count);
|
#else
|
||||||
#endif
|
current = integrate_psp_firmwares(rom, current, psp2dir, amd_psp2_fw_table);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);
|
targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);
|
||||||
write(targetfd, amd_romsig, current - AMD_ROMSIG_OFFSET);
|
write(targetfd, amd_romsig, current - AMD_ROMSIG_OFFSET);
|
||||||
|
|
Loading…
Reference in New Issue