BTX problems
Jung-uk Kim
jkim at FreeBSD.org
Mon Aug 22 17:19:52 GMT 2005
On Monday 22 August 2005 12:33 pm, Kenneth D. Merry wrote:
> On Mon, Aug 22, 2005 at 12:16:51 -0400, Jung-uk Kim wrote:
> > On Monday 22 August 2005 11:57 am, Kenneth D. Merry wrote:
> > > On Mon, Aug 22, 2005 at 11:37:25 -0400, Jung-uk Kim wrote:
> > > > On Saturday 20 August 2005 01:02 am, Kenneth D. Merry wrote:
> > > > > On Tue, Aug 16, 2005 at 13:39:48 -0400, John Baldwin wrote:
> > > > > > There haven't been a whole lot of changes. My guess
> > > > > > would be the recently added smbios support. You can
> > > > > > probably just comment out the call to smbios_detect() in
> > > > > > sys/boot/i386/loader/main.c as a simple test for that.
> > > > > > It could also possibly be the multiple console support in
> > > > > > which case it would be easiest to just step your sys/boot
> > > > > > tree back using CVS. The good news is that sys/boot is
> > > > > > largely self-contained so you can step it back while
> > > > > > keeping the rest of the tree up to date for testing
> > > > > > purposes at least.
> > > > >
> > > > > Thanks for the tips!
> > > > >
> > > > > Commenting out smbios_detect() did the trick. The loader
> > > > > works fine after that.
> > > > >
> > > > > So now what? Is there a way to fix it so it won't crash on
> > > > > my system?
> > > >
> > > > So, I guess I broke it, then. Can you install
> > > > ports/sysutils/dmidecode and send me dmidecode output?
> > >
> > > Sure, here it is.
> >
> > Okay, it looks good so far. Can you do:
> >
> > dd if=/dev/mem of=dmi.dat bs=1 count=1534 skip=984640
> > dd if=/dev/mem of=smbios.dat bs=1 count=65536 skip=983040
> >
> > and send me dmi.dat and smbios.dat, please?
>
> Here they are.
It's very strange. It seems SM entry and DMI structures are all sane.
I don't understand why it happens. :-( I just wrote a qucik-and-dirty
userland wrapper for smbios.c, which is attached.
SMBIOS entry: 0x000f00a0
DMI structures: length = 1534, paddr = 0x000f0640, count = 49
smbios.bios.vendor="American Megatrends Inc."
smbios.bios.version="0700xx "
smbios.bios.reldate="11/14/2001"
smbios.system.maker="Supermicro"
smbios.system.product="P3TDE6"
smbios.system.version="1234567890"
smbios.planar.maker="Supermicro"
smbios.planar.product="P3TDE6"
smbios.planar.version="1234567890"
smbios.chassis.maker="Supermicro"
smbios.chassis.version="P3TDE6"
Is it possible that PTOV() is not working somehow??? I need help
here.
Thanks,
Jung-uk Kim
-------------- next part --------------
/*-
* Copyright (c) 2005 Jung-uk Kim <jkim at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/boot/i386/libi386/smbios.c,v 1.2 2005/07/27 19:11:10 jkim Exp $");
#include <stand.h>
#include <bootstrap.h>
#include "btxv86.h"
#else
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#endif
/*
* Detect SMBIOS and export information about the SMBIOS into the
* environment.
*
* System Management BIOS Reference Specification, v2.4 Final
* http://www.dmtf.org/standards/published_documents/DSP0134.pdf
*/
/*
* Spec. 2.1.1 SMBIOS Structure Table Entry Point
*
* 'The SMBIOS Entry Point structure, described below, can be located by
* application software by searching for the anchor-string on paragraph
* (16-byte) boundaries within the physical memory address range
* 000F0000h to 000FFFFFh.'
*/
#define SMBIOS_START 0xf0000
#define SMBIOS_LENGTH 0x10000
#define SMBIOS_STEP 0x10
#define SMBIOS_SIG "_SM_"
#define SMBIOS_DMI_SIG "_DMI_"
static u_int8_t *smbios_parse_table(const u_int8_t *dmi);
static void smbios_setenv(const char *env, const u_int8_t *dmi,
const int offset);
static u_int8_t smbios_checksum(const u_int8_t *addr, const u_int8_t len);
static u_int8_t *smbios_sigsearch(const caddr_t addr, const u_int32_t len);
#if 0
void
smbios_detect(void)
{
u_int8_t *smbios, *dmi, *addr;
u_int16_t i, length, count;
u_int32_t paddr;
/* locate and validate the SMBIOS */
smbios = smbios_sigsearch(PTOV(SMBIOS_START), SMBIOS_LENGTH);
if (smbios == NULL)
return;
length = *(u_int16_t *)(smbios + 0x16); /* Structure Table Length */
paddr = *(u_int32_t *)(smbios + 0x18); /* Structure Table Address */
count = *(u_int16_t *)(smbios + 0x1c); /* No of SMBIOS Structures */
for (dmi = addr = PTOV(paddr), i = 0;
dmi - addr < length && i < count; i++)
dmi = smbios_parse_table(dmi);
}
#else
int main(void)
{
int smfd = -1, dmifd = -1, err = 0;
u_int8_t *smbios = NULL, *dmi = NULL, *addr = NULL;
u_int8_t *smp = NULL, *dmip = NULL;
u_int16_t i, length, count;
u_int32_t paddr;
smfd = open("smbios.dat", O_RDONLY);
if (smfd < 0) {
printf("cannot open smbios.dat\n");
err = -1;
goto done;
}
smbios = calloc(1, SMBIOS_LENGTH);
if (!smbios) {
printf("cannot allocate smbios buffer\n");
err = -2;
goto done;
}
if (read(smfd, smbios, SMBIOS_LENGTH) < SMBIOS_LENGTH) {
printf("cannot read smbios.dat\n");
err = -3;
goto done;
}
close(smfd);
/* locate and validate the SMBIOS */
smp = smbios_sigsearch(smbios, SMBIOS_LENGTH);
if (smp == NULL) {
printf("SMBIOS not found\n");
err = -4;
goto done;
} else {
printf("SMBIOS entry: 0x%08x\n", (u_int32_t)(smp - smbios) +
SMBIOS_START);
length = *(u_int16_t *)(smp + 0x16); /* Structure Table Length */
paddr = *(u_int32_t *)(smp + 0x18); /* Structure Table Address */
count = *(u_int16_t *)(smp + 0x1c); /* No of SMBIOS Structures */
printf("DMI structures: length = %u, paddr = 0x%08x, count = %u\n",
length, paddr, count);
}
dmifd = open("dmi.dat", O_RDONLY);
if (dmifd < 0) {
printf("cannot open dmi.dat\n");
err = -5;
goto done;
}
dmi = calloc(1, length);
if (!dmi) {
printf("cannot allocate dmi buffer\n");
err = -6;
goto done;
}
if (read(dmifd, dmi, length) < length) {
printf("cannot read dmi.dat\n");
err = -7;
goto done;
}
close(dmifd);
for (dmip = addr = dmi, i = 0; dmip - addr < length && i < count; i++)
dmip = smbios_parse_table(dmip);
done:
if (smfd >= 0)
close(smfd);
if (smbios)
free(smbios);
if (dmifd >= 0)
close(dmifd);
if (dmi)
free(dmi);
return (err);
}
#endif
static u_int8_t *
smbios_parse_table(const u_int8_t *dmi)
{
u_int8_t *dp;
switch(dmi[0]) {
case 0: /* Type 0: BIOS */
smbios_setenv("smbios.bios.vendor", dmi, 0x04);
smbios_setenv("smbios.bios.version", dmi, 0x05);
smbios_setenv("smbios.bios.reldate", dmi, 0x08);
break;
case 1: /* Type 1: System */
smbios_setenv("smbios.system.maker", dmi, 0x04);
smbios_setenv("smbios.system.product", dmi, 0x05);
smbios_setenv("smbios.system.version", dmi, 0x06);
break;
case 2: /* Type 2: Base Board (or Module) */
smbios_setenv("smbios.planar.maker", dmi, 0x04);
smbios_setenv("smbios.planar.product", dmi, 0x05);
smbios_setenv("smbios.planar.version", dmi, 0x06);
break;
case 3: /* Type 3: System Enclosure or Chassis */
smbios_setenv("smbios.chassis.maker", dmi, 0x04);
smbios_setenv("smbios.chassis.version", dmi, 0x06);
break;
default: /* skip other types */
break;
}
/* find structure terminator */
dp = (u_int8_t *)(dmi + dmi[1]);
while (dp[0] != 0 || dp[1] != 0)
dp++;
return(dp + 2);
}
static void
smbios_setenv(const char *str, const u_int8_t *dmi, const int offset)
{
char *cp;
int i;
/* skip undefined string */
if (dmi[offset] == 0)
return;
for (cp = (char *)(dmi + dmi[1]), i = 0; i < dmi[offset] - 1; i++)
cp += strlen(cp) + 1;
#if 0
setenv(str, cp, 1);
#else
printf("%s=\"%s\"\n", str, cp);
#endif
}
static u_int8_t
smbios_checksum(const u_int8_t *addr, const u_int8_t len)
{
u_int8_t sum;
int i;
for (sum = 0, i = 0; i < len; i++)
sum += addr[i];
return(sum);
}
static u_int8_t *
smbios_sigsearch(const caddr_t addr, const u_int32_t len)
{
caddr_t cp;
/* search on 16-byte boundaries */
for (cp = addr; cp - addr < len; cp += SMBIOS_STEP) {
/* compare signature, validate checksum */
if (!strncmp(cp, SMBIOS_SIG, 4)) {
if (smbios_checksum(cp, *(cp + 0x05)))
continue;
if (strncmp(cp + 0x10, SMBIOS_DMI_SIG, 5))
continue;
if (smbios_checksum(cp + 0x10, 0x0f))
continue;
return(cp);
}
}
return(NULL);
}
More information about the freebsd-current
mailing list