~ubuntu-branches/debian/stretch/uswsusp/stretch

« back to all changes in this revision

Viewing changes to dmidecode.c

  • Committer: Bazaar Package Importer
  • Author(s): Christian Perrier
  • Date: 2008-08-20 09:09:13 UTC
  • mfrom: (0.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080820090913-0eahue1zo8egcxls
Tags: 0.8-1.1
* Non-maintainer upload to fix pending l10n issues.
* Remove extra and useless debian/po/ff/ directory
* Debconf translation updates:
  - Japanese. Closes: #489939
  - German. Closes: #493747
  - French. Closes: #493771
  - Romanian. Closes: #493772
  - Galician. Closes: #494050
  - Finnish. Closes: #494087
  - Italian. Closes: #494096
  - Basque. Closes: #494277
  - Basque. Closes: #494277
  - Czech. Closes: #494410
  - Swedish. Closes: #494412
  - Russian. Closes: #495412
  - Portuguese. Closes: #495451
  - Spanish. Closes: #495499
  - Slovak. Closes: #495516

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      DMI decoder for s2ram
 
3
 *
 
4
 *      (C) 2000,2001 Alan Cox <alan@redhat.com>
 
5
 *      
 
6
 *      2-July-2001 Matt Domsch <Matt_Domsch@dell.com>
 
7
 *      Additional structures displayed per SMBIOS 2.3.1 spec
 
8
 *
 
9
 *      (C) 2006 Pavel Machek <pavel@suse.cz>
 
10
 *
 
11
 *      Licensed under the GNU General Public license v2.
 
12
 */
 
13
 
 
14
#include "config.h"
 
15
#include <stdio.h>
 
16
#include <unistd.h>
 
17
#include <fcntl.h>
 
18
#include <string.h>
 
19
#include <stdlib.h>
 
20
#include <sys/mman.h>
 
21
 
 
22
typedef unsigned char u8;
 
23
typedef unsigned short u16;
 
24
typedef unsigned int u32;
 
25
 
 
26
struct dmi_header
 
27
{
 
28
        u8      type;
 
29
        u8      length;
 
30
        u16     handle;
 
31
};
 
32
 
 
33
#ifdef S2RAM
 
34
extern char bios_version[1024], sys_vendor[1024], sys_product[1024], sys_version[1024];
 
35
#define PRINTF(a...)
 
36
#else
 
37
char bios_version[1024], sys_vendor[1024], sys_product[1024], sys_version[1024];
 
38
#define PRINTF printf
 
39
#endif
 
40
 
 
41
static char *dmi_string(struct dmi_header *dm, u8 s)
 
42
{
 
43
        char *bp=(char *)dm;
 
44
        if (!s) return "";
 
45
        
 
46
        bp+=dm->length;
 
47
        while (s>1) {
 
48
                bp+=strlen(bp);
 
49
                bp++;
 
50
                s--;
 
51
        }
 
52
        return bp;
 
53
}
 
54
 
 
55
/*
 
56
 * Copy a physical memory chunk into a memory buffer.
 
57
 * This function allocates memory.
 
58
 */
 
59
void *mem_chunk(size_t base, size_t len)
 
60
{
 
61
        void *p;
 
62
        int fd;
 
63
        size_t mmoffset;
 
64
        void *mmp;
 
65
 
 
66
        if((fd=open("/dev/mem", O_RDONLY))==-1){
 
67
                perror("/dev/mem");
 
68
                return NULL;
 
69
        }
 
70
 
 
71
        if((p=malloc(len))==NULL) {
 
72
                perror("/dev/mem malloc");
 
73
                return NULL;
 
74
        }
 
75
 
 
76
        mmoffset=base%getpagesize();
 
77
        /*
 
78
         * Please note that we don't use mmap() for performance reasons here,
 
79
         * but to workaround problems many people encountered when trying
 
80
         * to read from /dev/mem using regular read() calls.
 
81
         */
 
82
        mmp=mmap(0, mmoffset+len, PROT_READ, MAP_SHARED, fd, base-mmoffset);
 
83
        if(mmp==MAP_FAILED) {
 
84
                perror("mmap");
 
85
                free(p);
 
86
                return NULL;
 
87
        }
 
88
 
 
89
        memcpy(p, (u8 *)mmp+mmoffset, len);
 
90
 
 
91
        if(munmap(mmp, mmoffset+len)==-1)
 
92
                perror("/dev/mem munmap");
 
93
 
 
94
        if(close(fd)==-1)
 
95
                perror("/dev/mem");
 
96
 
 
97
        return p;
 
98
}
 
99
 
 
100
static void dmi_table(u32 base, int len, int num)
 
101
{
 
102
        char *buf;
 
103
        struct dmi_header *dm;
 
104
        char *data;
 
105
        int i=0;
 
106
        
 
107
        if ((buf=mem_chunk(base, len))==0) {
 
108
                printf("DMI Table is unreachable\n");
 
109
                return;
 
110
        }
 
111
        
 
112
        data = buf;
 
113
        while (i<num) {
 
114
                u32 u;
 
115
                u32 u2;
 
116
                dm=(struct dmi_header *)data;
 
117
                switch(dm->type)
 
118
                {
 
119
                case  0:
 
120
                        PRINTF("\tBIOS Information Block\n");
 
121
                        PRINTF("\t\tVendor: %s\n", 
 
122
                               dmi_string(dm, data[4]));
 
123
                        strcpy(bios_version, dmi_string(dm, data[5]));
 
124
                        PRINTF("\t\tVersion: %s\n", bios_version);
 
125
                        PRINTF("\t\tRelease: %s\n",
 
126
                               dmi_string(dm, data[8]));
 
127
                        PRINTF("\t\tBIOS base: 0x%04X0\n",
 
128
                               data[7]<<8|data[6]);
 
129
                        PRINTF("\t\tROM size: %dK\n",
 
130
                               64*data[9]);
 
131
                        PRINTF("\t\tCapabilities:\n");
 
132
                        u=data[13]<<24|data[12]<<16|data[11]<<8|data[10];               
 
133
                        u2=data[17]<<24|data[16]<<16|data[15]<<8|data[14];
 
134
                        PRINTF("\t\t\tFlags: 0x%08X%08X\n",
 
135
                               u2,u);
 
136
                        break;
 
137
                        
 
138
                case 1:
 
139
                        PRINTF("\tSystem Information Block\n");
 
140
                        strcpy(sys_vendor, dmi_string(dm, data[4]));
 
141
                        strcpy(sys_product, dmi_string(dm, data[5]));
 
142
                        strcpy(sys_version, dmi_string(dm, data[6]));
 
143
                        PRINTF("\t\tVendor: %s\n", sys_vendor);
 
144
                        PRINTF("\t\tProduct: %s\n", sys_product);
 
145
                        PRINTF("\t\tVersion: %s\n", sys_version);
 
146
                        PRINTF("\t\tSerial Number: %s\n",
 
147
                               dmi_string(dm, data[7]));
 
148
                        break;
 
149
                        
 
150
                case 2:
 
151
                        PRINTF("\tBoard Information Block\n");
 
152
                        PRINTF("\t\tVendor: %s\n",
 
153
                               dmi_string(dm, data[4]));
 
154
                        PRINTF("\t\tProduct: %s\n",
 
155
                               dmi_string(dm, data[5]));
 
156
                        PRINTF("\t\tVersion: %s\n",
 
157
                               dmi_string(dm, data[6]));
 
158
                        PRINTF("\t\tSerial Number: %s\n",
 
159
                               dmi_string(dm, data[7]));
 
160
                        break;
 
161
                        
 
162
                default:
 
163
                        break;
 
164
                }
 
165
                data+=dm->length;
 
166
                while(*data || data[1])
 
167
                        data++;
 
168
                data+=2;
 
169
                i++;
 
170
        }
 
171
        free(buf);
 
172
}
 
173
 
 
174
void dmi_scan(void)
 
175
{
 
176
        size_t fp;
 
177
        u8 *buf;
 
178
 
 
179
        if((buf=mem_chunk(0xF0000, 0x10000))==NULL)
 
180
                return;
 
181
 
 
182
        for(fp=0; fp<=0xFFF0; fp+=16) {
 
183
                if(memcmp(buf+fp, "_DMI_", 5)==0) {
 
184
                        u8 *cur = buf+fp;
 
185
                        u16 num=cur[13]<<8|cur[12];
 
186
                        u16 len=cur[7]<<8|cur[6];
 
187
                        u32 base=cur[11]<<24|cur[10]<<16|cur[9]<<8|cur[8];
 
188
 
 
189
                        PRINTF("DMI %d.%d present.\n",
 
190
                               cur[14]>>4, cur[14]&0x0F);
 
191
                        PRINTF("%d structures occupying %d bytes.\n",
 
192
                               cur[13]<<8|cur[12],
 
193
                               cur[7]<<8|cur[6]);
 
194
                        PRINTF("DMI table at 0x%08X.\n",
 
195
                               cur[11]<<24|cur[10]<<16|cur[9]<<8|cur[8]);
 
196
                        dmi_table(base,len,num);
 
197
                }
 
198
        }
 
199
        free(buf);
 
200
        return;
 
201
}
 
202
 
 
203
#ifndef S2RAM
 
204
int main(int argc, char *argv[])
 
205
{
 
206
        dmi_scan();
 
207
}
 
208
#endif