]> git.pld-linux.org Git - packages/microcode-data-intel.git/blob - intel-microcode2ucode.c
caad0323e80503bbe1dd98802f7dcc8e427b39fc
[packages/microcode-data-intel.git] / intel-microcode2ucode.c
1 /*
2  * Convert Intel microcode.dat into individual ucode files
3  * named: intel-ucode/$family-$model-$stepping
4  *
5  * The subdir intel-ucode/ is created in the current working
6  * directory. We get multiple ucodes in the same file, so they
7  * are appended to an existing file. Make sure the directory
8  * is empty before every run of the converter.
9  *
10  * Kay Sievers <kay.sievers@vrfy.org>
11  */
12
13
14 #ifndef _GNU_SOURCE
15 # define _GNU_SOURCE 1
16 #endif
17
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <time.h>
23 #include <limits.h>
24 #include <stdbool.h>
25 #include <inttypes.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <sys/stat.h>
29
30 struct microcode_header_intel {
31         unsigned int hdrver;
32         unsigned int rev;
33         unsigned int date;
34         unsigned int sig;
35         unsigned int cksum;
36         unsigned int ldrver;
37         unsigned int pf;
38         unsigned int datasize;
39         unsigned int totalsize;
40         unsigned int reserved[3];
41 };
42
43 union mcbuf {
44         struct microcode_header_intel hdr;
45         unsigned int i[0];
46         char c[0];
47 };
48
49 int main(int argc, char *argv[])
50 {
51         char *filename = "/lib/firmware/microcode.dat";
52         FILE *f;
53         char line[LINE_MAX];
54         char buf[4000000];
55         union mcbuf *mc;
56         size_t bufsize, count, start;
57         int rc = EXIT_SUCCESS;
58
59         if (argv[1] != NULL)
60                 filename = argv[1];
61
62         count = 0;
63         mc = (union mcbuf *) buf;
64         f = fopen(filename, "re");
65         if (f == NULL) {
66                 printf("open %s: %m\n", filename);
67                 rc = EXIT_FAILURE;
68                 goto out;
69         }
70
71         while (fgets(line, sizeof(line), f) != NULL) {
72                 if (sscanf(line, "%x, %x, %x, %x",
73                     &mc->i[count],
74                     &mc->i[count + 1],
75                     &mc->i[count + 2],
76                     &mc->i[count + 3]) != 4)
77                         continue;
78                 count += 4;
79         }
80         fclose(f);
81
82         bufsize = count * sizeof(int);
83         printf("%s: %lu(%luk) bytes, %zu integers\n",
84                filename,
85                bufsize,
86                bufsize / 1024,
87                count);
88
89         if (bufsize < sizeof(struct microcode_header_intel))
90                 goto out;
91
92         mkdir("intel-ucode", 0750);
93
94         start = 0;
95         for (;;) {
96                 size_t size;
97                 unsigned int family, model, stepping;
98                 unsigned int year, month, day;
99
100                 mc = (union mcbuf *) &buf[start];
101
102                 if (mc->hdr.totalsize)
103                         size = mc->hdr.totalsize;
104                 else
105                         size = 2000 + sizeof(struct microcode_header_intel);
106
107                 if (mc->hdr.ldrver != 1 || mc->hdr.hdrver != 1) {
108                         printf("unknown version/format:\n");
109                         rc = EXIT_FAILURE;
110                         break;
111                 }
112
113                 /*
114                  *  0- 3 stepping
115                  *  4- 7 model
116                  *  8-11 family
117                  * 12-13 type
118                  * 16-19 extended model
119                  * 20-27 extended family
120                  */
121                 family = (mc->hdr.sig >> 8) & 0xf;
122                 if (family == 0xf)
123                         family += (mc->hdr.sig >> 20) & 0xff;
124                 model = (mc->hdr.sig >> 4) & 0x0f;
125                 if (family == 0x06)
126                         model += ((mc->hdr.sig >> 16) & 0x0f) << 4;
127                 stepping = mc->hdr.sig & 0x0f;
128
129                 year = mc->hdr.date & 0xffff;
130                 month = mc->hdr.date >> 24;
131                 day = (mc->hdr.date >> 16) & 0xff;
132
133                 asprintf(&filename, "intel-ucode/%02x-%02x-%02x", family, model, stepping);
134                 printf("\n");
135                 printf("%s\n", filename);
136                 printf("signature: 0x%02x\n", mc->hdr.sig);
137                 printf("flags:     0x%02x\n", mc->hdr.pf);
138                 printf("revision:  0x%02x\n", mc->hdr.rev);
139                 printf("date:      %04x-%02x-%02x\n", year, month, day);
140                 printf("size:      %zu\n", size);
141
142                 f = fopen(filename, "ae");
143                 if (f == NULL) {
144                         printf("open %s: %m\n", filename);
145                         rc = EXIT_FAILURE;
146                         goto out;
147                 }
148                 if (fwrite(mc, size, 1, f) != 1) {
149                         printf("write %s: %m\n", filename);
150                         rc = EXIT_FAILURE;
151                         goto out;
152                 }
153                 fclose(f);
154                 free(filename);
155
156                 start += size;
157                 if (start >= bufsize)
158                         break;
159         }
160         printf("\n");
161 out:
162         return rc;
163 }
This page took 0.045981 seconds and 2 git commands to generate.