Subversion Repositories Kolibri OS

Rev

Rev 5270 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5270 Rev 6934
Line 1... Line -...
1
#include 
-
 
2
#include 
1
#include 
3
#include 
2
#include 
4
#include 
3
#include 
5
#include 
4
#include 
6
#include 
5
#include 
7
#include 
6
#include 
-
 
7
#include 
8
 
8
#include 
-
 
9
struct kobject *dmi_kobj;
Line 9... Line 10...
9
static void *dmi_alloc(unsigned len)
10
 
10
{
11
static void *dmi_alloc(unsigned len)
11
    return __builtin_malloc(len);
12
{
12
};
13
    return __builtin_malloc(len);
Line 17... Line 18...
17
 * Management BIOS.  See further: http://www.dmtf.org/standards
18
 * of and an antecedent to, SMBIOS, which stands for System
18
 */
19
 * Management BIOS.  See further: http://www.dmtf.org/standards
19
static const char dmi_empty_string[] = "        ";
20
 */
20
 
21
static const char dmi_empty_string[] = "        ";
Line -... Line 22...
-
 
22
 
-
 
23
static u32 dmi_ver __initdata;
21
static u16 dmi_ver;
24
static u32 dmi_len;
-
 
25
static u16 dmi_num;
-
 
26
static u8 smbios_entry_point[32];
-
 
27
static int smbios_entry_point_size;
22
/*
28
 
23
 * Catch too early calls to dmi_check_system():
29
/*
24
 */
30
 * Catch too early calls to dmi_check_system():
25
static int dmi_initialized;
31
 */
Line 26... Line 32...
26
 
32
static int dmi_initialized;
27
/* DMI system identification string used during boot */
33
 
Line 28... Line 34...
28
static char dmi_ids_string[128];
34
/* DMI system identification string used during boot */
29
 
35
static char dmi_ids_string[128] __initdata;
30
static struct dmi_memdev_info {
36
 
31
	const char *device;
37
static struct dmi_memdev_info {
Line 78... Line 84...
78
/*
84
 
79
 *	We have to be cautious here. We have seen BIOSes with DMI pointers
85
/*
80
 *	pointing to completely the wrong place for example
86
 *	We have to be cautious here. We have seen BIOSes with DMI pointers
81
 */
87
 *	pointing to completely the wrong place for example
82
static void dmi_table(u8 *buf, int len, int num,
88
 */
83
		      void (*decode)(const struct dmi_header *, void *),
89
static void dmi_decode_table(u8 *buf,
84
		      void *private_data)
90
		      void (*decode)(const struct dmi_header *, void *),
85
{
91
		      void *private_data)
86
	u8 *data = buf;
92
{
87
	int i = 0;
93
	u8 *data = buf;
Line 88... Line 94...
88
 
94
	int i = 0;
89
	/*
95
 
-
 
96
	/*
90
	 *	Stop when we see all the items the table claimed to have
97
	 * Stop when we have seen all the items the table claimed to have
-
 
98
	 * (SMBIOS < 3.0 only) OR we reach an end-of-table marker (SMBIOS
91
	 *	OR we run off the end of the table (also happens)
99
	 * >= 3.0 only) OR we run off the end of the table (should never
-
 
100
	 * happen but sometimes does on bogus implementations.)
92
	 */
101
	 */
93
	while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
102
	while ((!dmi_num || i < dmi_num) &&
Line 94... Line 103...
94
		const struct dmi_header *dm = (const struct dmi_header *)data;
103
	       (data - buf + sizeof(struct dmi_header)) <= dmi_len) {
95
 
104
		const struct dmi_header *dm = (const struct dmi_header *)data;
96
		/*
105
 
97
		 *  We want to know the total length (formatted area and
106
		/*
98
		 *  strings) before decoding to make sure we won't run off the
107
		 *  We want to know the total length (formatted area and
99
		 *  table in dmi_decode or dmi_string
108
		 *  strings) before decoding to make sure we won't run off the
100
		 */
109
		 *  table in dmi_decode or dmi_string
101
		data += dm->length;
110
		 */
102
		while ((data - buf < len - 1) && (data[0] || data[1]))
111
		data += dm->length;
103
			data++;
112
		while ((data - buf < dmi_len - 1) && (data[0] || data[1]))
-
 
113
			data++;
104
		if (data - buf < len - 1)
114
		if (data - buf < dmi_len - 1)
105
			decode(dm, private_data);
115
			decode(dm, private_data);
-
 
116
 
-
 
117
		data += 2;
-
 
118
		i++;
-
 
119
 
-
 
120
		/*
-
 
121
		 * 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0]
-
 
122
		 * For tables behind a 64-bit entry point, we have no item
-
 
123
		 * count and no exact table length, so stop on end-of-table
-
 
124
		 * marker. For tables behind a 32-bit entry point, we have
-
 
125
		 * seen OEM structures behind the end-of-table marker on
-
 
126
		 * some systems, so don't trust it.
106
		data += 2;
127
		 */
-
 
128
		if (!dmi_num && dm->type == DMI_ENTRY_END_OF_TABLE)
-
 
129
			break;
-
 
130
	}
-
 
131
 
107
		i++;
132
	/* Trim DMI table length if needed */
Line 108... Line 133...
108
	}
133
	if (dmi_len > data - buf)
109
}
-
 
110
 
-
 
Line 111... Line 134...
111
static u32 dmi_base;
134
		dmi_len = data - buf;
112
static u16 dmi_len;
135
}
113
static u16 dmi_num;
136
 
114
 
137
static phys_addr_t dmi_base;
-
 
138
 
Line 115... Line 139...
115
static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
139
static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
116
        void *))
140
        void *))
117
{
141
{
Line 118... Line 142...
118
	u8 *buf;
142
	u8 *buf;
Line 119... Line 143...
119
 
143
	u32 orig_dmi_len = dmi_len;
Line 120... Line 144...
120
	buf = (u8*)MapIoMem(dmi_base, dmi_len, PG_SW);
144
 
121
	if (buf == NULL)
145
	buf = (u8*)MapIoMem(dmi_base, dmi_len, PG_SW);
Line 190... Line 214...
190
     * As of version 2.6 of the SMBIOS specification, the first 3 fields of
214
    /*
191
     * the UUID are supposed to be little-endian encoded.  The specification
215
     * As of version 2.6 of the SMBIOS specification, the first 3 fields of
192
     * says that this is the defacto standard.
216
     * the UUID are supposed to be little-endian encoded.  The specification
193
     */
217
     * says that this is the defacto standard.
194
    if (dmi_ver >= 0x0206)
218
     */
195
        sprintf(s, "%pUL", d);
219
	if (dmi_ver >= 0x020600)
196
    else
220
        sprintf(s, "%pUL", d);
197
        sprintf(s, "%pUB", d);
221
    else
198
 
222
        sprintf(s, "%pUB", d);
Line 199... Line 223...
199
    dmi_ident[slot] = s;
223
 
Line 327... Line 351...
327
 
351
		return;
Line 328... Line 352...
328
	dmi_save_dev_onboard(*(d+1), *(u16 *)(d+2), *(d+4), *(d+5),
352
 
329
			     dmi_string_nosave(dm, *(d-1)));
353
	dmi_save_dev_onboard(*(d+1), *(u16 *)(d+2), *(d+4), *(d+5),
330
	dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
354
			     dmi_string_nosave(dm, *(d-1)));
-
 
355
	dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
Line -... Line 356...
-
 
356
}
-
 
357
 
-
 
358
static void __init count_mem_devices(const struct dmi_header *dm, void *v)
-
 
359
{
-
 
360
	if (dm->type != DMI_ENTRY_MEM_DEVICE)
331
 
361
		return;
Line 332... Line 362...
332
}
362
	dmi_memdev_nr++;
333
 
363
}
334
/*
364
 
Line 427... Line 457...
427
 * takes precedence) and return 0.  Otherwise return 1.
457
 * 0.  If the DMI header is present, set dmi_ver accordingly (SMBIOS
428
 */
458
 * takes precedence) and return 0.  Otherwise return 1.
429
static int __init dmi_present(const u8 *buf)
459
 */
430
{
460
static int __init dmi_present(const u8 *buf)
431
    int smbios_ver;
461
{
432
 
462
	u32 smbios_ver;
Line 433... Line 463...
433
    if (memcmp(buf, "_SM_", 4) == 0 &&
463
 
434
        buf[5] < 32 && dmi_checksum(buf, buf[5])) {
464
    if (memcmp(buf, "_SM_", 4) == 0 &&
-
 
465
        buf[5] < 32 && dmi_checksum(buf, buf[5])) {
435
        smbios_ver = (buf[6] << 8) + buf[7];
466
		smbios_ver = get_unaligned_be16(buf + 6);
-
 
467
		smbios_entry_point_size = buf[5];
Line 436... Line 468...
436
 
468
		memcpy(smbios_entry_point, buf, smbios_entry_point_size);
437
        /* Some BIOS report weird SMBIOS version, fix that up */
469
 
438
        switch (smbios_ver) {
470
        /* Some BIOS report weird SMBIOS version, fix that up */
439
        case 0x021F:
471
        switch (smbios_ver) {
Line 453... Line 485...
453
 
485
    }
Line 454... Line 486...
454
    buf += 16;
486
 
Line 455... Line 487...
455
 
487
    buf += 16;
-
 
488
 
-
 
489
    if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
-
 
490
		if (smbios_ver)
456
    if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
491
			dmi_ver = smbios_ver;
-
 
492
		else
457
        dmi_num = (buf[13] << 8) | buf[12];
493
			dmi_ver = (buf[14] & 0xF0) << 4 | (buf[14] & 0x0F);
458
        dmi_len = (buf[7] << 8) | buf[6];
494
		dmi_ver <<= 8;
459
        dmi_base = (buf[11] << 24) | (buf[10] << 16) |
495
		dmi_num = get_unaligned_le16(buf + 12);
Line 460... Line 496...
460
            (buf[9] << 8) | buf[8];
496
		dmi_len = get_unaligned_le16(buf + 6);
461
 
497
		dmi_base = get_unaligned_le32(buf + 8);
462
        if (dmi_walk_early(dmi_decode) == 0) {
-
 
463
            if (smbios_ver) {
498
 
464
                dmi_ver = smbios_ver;
499
        if (dmi_walk_early(dmi_decode) == 0) {
465
                pr_info("SMBIOS %d.%d present.\n",
500
            if (smbios_ver) {
-
 
501
                pr_info("SMBIOS %d.%d present.\n",
466
                       dmi_ver >> 8, dmi_ver & 0xFF);
502
					dmi_ver >> 16, (dmi_ver >> 8) & 0xFF);
467
            } else {
503
            } else {
468
                dmi_ver = (buf[14] & 0xF0) << 4 |
504
				smbios_entry_point_size = 15;
469
                       (buf[14] & 0x0F);
505
				memcpy(smbios_entry_point, buf,
470
                pr_info("Legacy DMI %d.%d present.\n",
506
				       smbios_entry_point_size);
471
                       dmi_ver >> 8, dmi_ver & 0xFF);
507
                pr_info("Legacy DMI %d.%d present.\n",
472
            }
508
					dmi_ver >> 16, (dmi_ver >> 8) & 0xFF);
473
			dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
509
            }
474
			printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string);
510
			dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
475
            return 0;
511
			printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string);
Line 476... Line 512...
476
        }
512
            return 0;
477
    }
513
        }
Line -... Line 514...
-
 
514
    }
-
 
515
 
-
 
516
    return 1;
-
 
517
}
-
 
518
 
-
 
519
/*
-
 
520
 * Check for the SMBIOS 3.0 64-bit entry point signature. Unlike the legacy
-
 
521
 * 32-bit entry point, there is no embedded DMI header (_DMI_) in here.
-
 
522
 */
-
 
523
static int __init dmi_smbios3_present(const u8 *buf)
-
 
524
{
-
 
525
	if (memcmp(buf, "_SM3_", 5) == 0 &&
-
 
526
	    buf[6] < 32 && dmi_checksum(buf, buf[6])) {
-
 
527
		dmi_ver = get_unaligned_be32(buf + 6) & 0xFFFFFF;
-
 
528
		dmi_num = 0;			/* No longer specified */
-
 
529
		dmi_len = get_unaligned_le32(buf + 12);
-
 
530
		dmi_base = get_unaligned_le64(buf + 16);
-
 
531
		smbios_entry_point_size = buf[6];
-
 
532
		memcpy(smbios_entry_point, buf, smbios_entry_point_size);
-
 
533
 
-
 
534
		if (dmi_walk_early(dmi_decode) == 0) {
-
 
535
			pr_info("SMBIOS %d.%d.%d present.\n",
-
 
536
				dmi_ver >> 16, (dmi_ver >> 8) & 0xFF,
-
 
537
				dmi_ver & 0xFF);
-
 
538
			dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
-
 
539
			pr_debug("DMI: %s\n", dmi_ids_string);
-
 
540
			return 0;
478
 
541
		}
479
    return 1;
542
	}
480
}
543
	return 1;
481
 
544
}
Line 497... Line 560...
497
     */
560
     * detecting an SMBIOS header.
498
    memset(buf, 0, 16);
561
     */
499
    for (q = p; q < p + 0x10000; q += 16) {
562
    memset(buf, 0, 16);
500
        memcpy(buf + 16, q, 16);
563
    for (q = p; q < p + 0x10000; q += 16) {
501
        if (!dmi_present(buf)) {
564
        memcpy(buf + 16, q, 16);
502
            dmi_available = 1;
565
        if (!dmi_smbios3_present(buf) || !dmi_present(buf)) {
503
            goto out;
566
            dmi_available = 1;
504
        }
567
            goto out;
505
        memcpy(buf, buf + 16, 16);
568
        }
506
    }
569
        memcpy(buf, buf + 16, 16);
507
 error:
570
    }