Ejemplo n.º 1
0
/****************************************************************************
 * get_cmos_checksum_info
 *
 * Get layout information for CMOS checksum.
 ****************************************************************************/
static void get_cmos_checksum_info(void)
{
	const cmos_entry_t *e;
	struct cmos_checksum *checksum;
	cmos_checksum_layout_t layout;
	unsigned index, index2;

	checksum = (struct cmos_checksum *)next_cmos_rec((const struct lb_record *)first_cmos_table_enum(), LB_TAG_OPTION_CHECKSUM);

	if (checksum != NULL) {	/* We are lucky.  The coreboot table hints us to the checksum.
				 * We might have to check the type field here though.
				 */
		layout.summed_area_start = checksum->range_start;
		layout.summed_area_end = checksum->range_end;
		layout.checksum_at = checksum->location;
		try_convert_checksum_layout(&layout);
		cmos_checksum_start = layout.summed_area_start;
		cmos_checksum_end = layout.summed_area_end;
		cmos_checksum_index = layout.checksum_at;
		return;
	}

	if ((e = find_cmos_entry(checksum_param_name)) == NULL)
		return;

	/* If we get here, we are unlucky.  The CMOS option table contains the
	 * location of the CMOS checksum.  However, there is no information
	 * regarding which bytes of the CMOS area the checksum is computed over.
	 * Thus we have to hope our presets will be fine.
	 */

	if (e->bit % 8) {
		fprintf(stderr,
			"%s: Error: CMOS checksum is not byte-aligned.\n",
			prog_name);
		exit(1);
	}

	index = e->bit / 8;
	index2 = index + 1;	/* The CMOS checksum occupies 16 bits. */

	if (verify_cmos_byte_index(index) || verify_cmos_byte_index(index2)) {
		fprintf(stderr,
			"%s: Error: CMOS checksum location out of range.\n",
			prog_name);
		exit(1);
	}

	if (((index >= cmos_checksum_start) && (index <= cmos_checksum_end)) ||
	    (((index2) >= cmos_checksum_start)
	     && ((index2) <= cmos_checksum_end))) {
		fprintf(stderr,
			"%s: Error: CMOS checksum overlaps checksummed area.\n",
			prog_name);
		exit(1);
	}

	cmos_checksum_index = index;
}
Ejemplo n.º 2
0
/****************************************************************************
 * checksum_layout_to_bytes
 *
 * On entry, '*layout' contains checksum-related layout information expressed
 * in bits.  Perform sanity checking on the information and convert it from
 * bit positions to byte positions.  Return OK on success or an error code if
 * a sanity check fails.
 ****************************************************************************/
int checksum_layout_to_bytes(cmos_checksum_layout_t * layout)
{
	unsigned start, end, index;

	start = layout->summed_area_start;
	end = layout->summed_area_end;
	index = layout->checksum_at;

	if (start % 8)
		return LAYOUT_SUMMED_AREA_START_NOT_ALIGNED;

	if ((end % 8) != 7)
		return LAYOUT_SUMMED_AREA_END_NOT_ALIGNED;

	if (index % 8)
		return LAYOUT_CHECKSUM_LOCATION_NOT_ALIGNED;

	if (end <= start)
		return LAYOUT_INVALID_SUMMED_AREA;

	/* Convert bit positions to byte positions. */
	start /= 8;
	end /= 8;		/* equivalent to "end = ((end - 7) / 8)" */
	index /= 8;

	if (verify_cmos_byte_index(start) || verify_cmos_byte_index(end))
		return LAYOUT_SUMMED_AREA_OUT_OF_RANGE;

	if (verify_cmos_byte_index(index))
		return LAYOUT_CHECKSUM_LOCATION_OUT_OF_RANGE;

	/* checksum occupies 16 bits */
	if (areas_overlap(start, end - start + 1, index, index + 1))
		return LAYOUT_CHECKSUM_OVERLAPS_SUMMED_AREA;

	layout->summed_area_start = start;
	layout->summed_area_end = end;
	layout->checksum_at = index;
	return OK;
}
Ejemplo n.º 3
0
static unsigned char cmos_hal_read(unsigned index)
{
	unsigned short port_0, port_1;

	assert(!verify_cmos_byte_index(index));

	if (index < 128) {
		port_0 = 0x70;
		port_1 = 0x71;
	} else {
		port_0 = 0x72;
		port_1 = 0x73;
	}

	OUTB(index, port_0);
	return INB(port_1);
}
Ejemplo n.º 4
0
static void cmos_hal_write(unsigned index, unsigned char value)
{
	unsigned short port_0, port_1;

	assert(!verify_cmos_byte_index(index));

	if (index < 128) {
		port_0 = 0x70;
		port_1 = 0x71;
	} else {
		port_0 = 0x72;
		port_1 = 0x73;
	}

	OUTB(index, port_0);
	OUTB(value, port_1);
}