Пример #1
0
/* Helper to load a VPD LID. Pass a ptr to the corresponding LX keyword */
static void *vpd_lid_preload(const uint8_t *lx)
{
	int rc;

	/* Now this is a guess game as we don't have the info from the
	 * pHyp folks. But basically, it seems to boil down to loading
	 * a LID whose name is 0x80e000yy where yy is the last 2 digits
	 * of the LX record in hex.
	 *
	 * [ Correction: After a chat with some folks, it looks like it's
	 * actually 4 digits, though the lid number is limited to fff
	 * so we weren't far off. ]
	 *
	 * For safety, we look for a matching LX record in an LXRn
	 * (n = lxrn argument) or in VINI if lxrn=0xff
	 */
	vpd_lid_no = 0x80e00000 | ((lx[6] & 0xf) << 8) | lx[7];

	/* We don't quite know how to get to the LID directory so
	 * we don't know the size. Let's allocate 16K. All the VPD LIDs
	 * I've seen so far are much smaller.
	 */
#define VPD_LID_MAX_SIZE	0x4000
	vpd_lid = malloc(VPD_LID_MAX_SIZE);

	if (!vpd_lid) {
		prerror("VPD: Failed to allocate memory for LID\n");
		return NULL;
	}

	/* Adjust LID number for flash side */
	vpd_lid_no = fsp_adjust_lid_side(vpd_lid_no);
	printf("VPD: Trying to load VPD LID 0x%08x...\n", vpd_lid_no);

	vpd_lid_size = VPD_LID_MAX_SIZE;

	/* Load it from the FSP */
	rc = fsp_preload_lid(vpd_lid_no, vpd_lid, &vpd_lid_size);
	if (rc) {
		prerror("VPD: Error %d loading VPD LID\n", rc);
		goto fail;
	}

	return vpd_lid;
 fail:
	free(vpd_lid);
	return NULL;
}
Пример #2
0
/* Helper to load a VPD LID. Pass a ptr to the corresponding LX keyword */
static void *vpd_lid_load(const uint8_t *lx, uint8_t lxrn, size_t *size)
{
    /* Now this is a guess game as we don't have the info from the
     * pHyp folks. But basically, it seems to boil down to loading
     * a LID whose name is 0x80e000yy where yy is the last 2 digits
     * of the LX record in hex.
     *
     * [ Correction: After a chat with some folks, it looks like it's
     * actually 4 digits, though the lid number is limited to fff
     * so we weren't far off. ]
     *
     * For safety, we look for a matching LX record in an LXRn
     * (n = lxrn argument) or in VINI if lxrn=0xff
     */
    uint32_t lid_no = 0x80e00000 | ((lx[6] & 0xf) << 8) | lx[7];

    /* We don't quite know how to get to the LID directory so
     * we don't know the size. Let's allocate 16K. All the VPD LIDs
     * I've seen so far are much smaller.
     */
#define VPD_LID_MAX_SIZE	0x4000
    void *data = malloc(VPD_LID_MAX_SIZE);
    char record[4] = "LXR0";
    const void *valid_lx;
    uint8_t lx_size;
    int rc;

    if (!data) {
        prerror("VPD: Failed to allocate memory for LID\n");
        return NULL;
    }

    /* Adjust LID number for flash side */
    lid_no = fsp_adjust_lid_side(lid_no);
    printf("VPD: Trying to load VPD LID 0x%08x...\n", lid_no);

    *size = VPD_LID_MAX_SIZE;

    /* Load it from the FSP */
    rc = fsp_fetch_data(0, FSP_DATASET_NONSP_LID, lid_no, 0, data, size);
    if (rc) {
        prerror("VPD: Error %d loading VPD LID\n", rc);
        goto fail;
    }

    /* Validate it */
    if (lxrn < 9)
        record[3] = '0' + lxrn;
    else
        memcpy(record, "VINI", 4);

    valid_lx = vpd_find(data, *size, record, "LX", &lx_size);
    if (!valid_lx || lx_size != 8) {
        prerror("VPD: Cannot find validation LX record\n");
        goto fail;
    }
    if (memcmp(valid_lx, lx, 8) != 0) {
        prerror("VPD: LX record mismatch !\n");
        goto fail;
    }

    printf("VPD: Loaded %zu bytes\n", *size);

    /* Got it ! */
    return realloc(data, *size);
fail:
    free(data);
    return NULL;
}