Beispiel #1
0
/*
 * Look for an Intel MP spec table, indicating SMP capable hardware.
 */
int
mpbios_probe(struct device *self)
{
	paddr_t  	ebda, memtop;

	paddr_t		cthpa;
	int		cthlen;
	const u_int8_t	*mpbios_page;
	int 		scan_loc;

	struct		mp_map t;

	/*
	 * Skip probe if someone else (e.g. acpi) already provided the
	 * necessary details.
	 */
	if (mp_busses)
		return (0);

	/* see if EBDA exists */

	mpbios_page = mpbios_map(0, PAGE_SIZE, &t);

	/* XXX Ugly magic constants below. */
	ebda = *(const u_int16_t *)(&mpbios_page[0x40e]);
	ebda <<= 4;

	memtop = *(const u_int16_t *)(&mpbios_page[0x413]);
	memtop <<= 10;

	mpbios_page = NULL;
	mpbios_unmap(&t);

	scan_loc = 0;

	if (ebda && ebda < IOM_BEGIN ) {
		mp_fps = mpbios_search(self, ebda, 1024, &mp_fp_map);
		if (mp_fps != NULL)
			goto found;
	}

	scan_loc = 1;

	if (memtop && memtop <= IOM_BEGIN ) {
		mp_fps = mpbios_search(self, memtop - 1024, 1024, &mp_fp_map);
		if (mp_fps != NULL)
			goto found;
	}

	scan_loc = 2;

	mp_fps = mpbios_search(self, BIOS_BASE, BIOS_COUNT, &mp_fp_map);
	if (mp_fps != NULL)
		goto found;

	/* nothing found */
	return (0);

 found:
	if (mp_verbose)
		printf("%s: MP floating pointer found in %s at 0x%lx\n",
		    self->dv_xname, loc_where[scan_loc], mp_fp_map.pa);

	if (mp_fps->pap == 0) {
		if (mp_fps->mpfb1 == 0) {
			printf("%s: MP fps invalid: "
			    "no default config and no configuration table\n",
			    self->dv_xname);

			goto err;
		}
		printf("%s: MP default configuration %d\n",
		    self->dv_xname, mp_fps->mpfb1);
		return (10);
	}

	cthpa = mp_fps->pap;

	mp_cth = mpbios_map(cthpa, sizeof (*mp_cth), &mp_cfg_table_map);
	cthlen = mp_cth->base_len;
	mpbios_unmap(&mp_cfg_table_map);

	mp_cth = mpbios_map(cthpa, cthlen, &mp_cfg_table_map);

	if (mp_verbose)
		printf("%s: MP config table at 0x%lx, %d bytes long\n",
		    self->dv_xname, cthpa, cthlen);

	if (mp_cth->signature != MP_CT_SIG) {
		printf("%s: MP signature mismatch (%x vs %x)\n",
		    self->dv_xname,
		    MP_CT_SIG, mp_cth->signature);
		goto err;
	}

	if (mpbios_cksum(mp_cth, cthlen)) {
		printf ("%s: MP Configuration Table checksum mismatch\n",
		    self->dv_xname);
		goto err;
	}
	return (10);

 err:
	if (mp_fps) {
		mp_fps = NULL;
		mpbios_unmap(&mp_fp_map);
	}
	if (mp_cth) {
		mp_cth = NULL;
		mpbios_unmap(&mp_cfg_table_map);
	}
	return (0);
}
/*
 * Look for an Intel MP spec table, indicating SMP capable hardware.
 */
int
mpbios_probe(device_t self)
{
	paddr_t  	ebda, memtop;

	paddr_t		cthpa;
	int		cthlen;
	const uint8_t	*mpbios_page;
	int 		scan_loc;

	struct		mp_map t;

	/* If MP is disabled, don't use MPBIOS or the ioapics. */
	if ((boothowto & RB_MD1) != 0)
		return 0;

	/* see if EBDA exists */

	mpbios_page = mpbios_map (0, PAGE_SIZE, &t);

	ebda =   *(const uint16_t *) (&mpbios_page[0x40e]);
	ebda <<= 4;

	memtop = *(const uint16_t *) (&mpbios_page[0x413]);
	memtop <<= 10;

	mpbios_page = NULL;
	mpbios_unmap(&t);

	scan_loc = 0;

	if (ebda && ebda < IOM_BEGIN ) {
		mp_fps = mpbios_search(self, ebda, 1024, &mp_fp_map);
		if (mp_fps != NULL)
			goto found;
	}

	scan_loc = 1;

	if (memtop && memtop <= IOM_BEGIN ) {
		mp_fps = mpbios_search(self, memtop - 1024, 1024, &mp_fp_map);
		if (mp_fps != NULL)
			goto found;
	}

	scan_loc = 2;

	mp_fps = mpbios_search(self, BIOS_BASE, BIOS_COUNT, &mp_fp_map);
	if (mp_fps != NULL)
		goto found;

	/* nothing found */
	return 0;

 found:
	if (mp_verbose)
		aprint_verbose_dev(self, "MP floating pointer found in %s at 0x%jx\n",
		    loc_where[scan_loc], (uintmax_t)mp_fp_map.pa);

	if (mp_fps->pap == 0) {
		if (mp_fps->mpfb1 == 0) {
			aprint_error_dev(self, "MP fps invalid: "
			    "no default config and no configuration table\n");

			goto err;
		}
		return 10;
	}

	cthpa = mp_fps->pap;

	mp_cth = mpbios_map (cthpa, sizeof (*mp_cth), &mp_cfg_table_map);
	cthlen = mp_cth->base_len;
	mpbios_unmap(&mp_cfg_table_map);

	mp_cth = mpbios_map (cthpa, cthlen, &mp_cfg_table_map);

	if (mp_verbose)
		aprint_verbose_dev(self, "MP config table at 0x%jx, %d bytes long\n",
		    (uintmax_t)cthpa, cthlen);

	if (mp_cth->signature != MP_CT_SIG) {
		aprint_error_dev(self, "MP signature mismatch (%x vs %x)\n",
		    MP_CT_SIG, mp_cth->signature);
		goto err;
	}

	if (mpbios_cksum(mp_cth, cthlen)) {
		aprint_error_dev(self, "MP Configuration Table checksum mismatch\n");
		goto err;
	}
	return 10;
 err:
	if (mp_fps) {
		mp_fps = NULL;
		mpbios_unmap(&mp_fp_map);
	}
	if (mp_cth) {
		mp_cth = NULL;
		mpbios_unmap(&mp_cfg_table_map);
	}
	return 0;
}