]> git.pld-linux.org Git - packages/microcode-data-intel.git/blob - intel-microcode2ucode-single.c
up to 20180108
[packages/microcode-data-intel.git] / intel-microcode2ucode-single.c
1 /*
2  * Convert Intel microcode.dat into a single binary microcode.bin file
3  *
4  * Based on code by Kay Sievers <kay.sievers@vrfy.org>
5  * Changed to create a single file by Thomas Bächler <thomas@archlinux.org>
6  */
7
8
9 #ifndef _GNU_SOURCE
10 # define _GNU_SOURCE 1
11 #endif
12
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <time.h>
18 #include <limits.h>
19 #include <stdbool.h>
20 #include <inttypes.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <sys/stat.h>
24
25 struct microcode_header_intel {
26         unsigned int hdrver;
27         unsigned int rev;
28         unsigned int date;
29         unsigned int sig;
30         unsigned int cksum;
31         unsigned int ldrver;
32         unsigned int pf;
33         unsigned int datasize;
34         unsigned int totalsize;
35         unsigned int reserved[3];
36 };
37
38 union mcbuf {
39         struct microcode_header_intel hdr;
40         unsigned int i[0];
41         char c[0];
42 };
43
44 int main(int argc, char *argv[])
45 {
46         const char *filename = "/lib/firmware/microcode.dat";
47         FILE *f;
48         char line[LINE_MAX];
49         char buf[4000000];
50         union mcbuf *mc;
51         size_t bufsize, count, start;
52         int rc = EXIT_SUCCESS;
53
54         if (argv[1] != NULL)
55                 filename = argv[1];
56
57         count = 0;
58         mc = (union mcbuf *) buf;
59         f = fopen(filename, "re");
60         if (f == NULL) {
61                 printf("open %s: %m\n", filename);
62                 rc = EXIT_FAILURE;
63                 goto out;
64         }
65
66         while (fgets(line, sizeof(line), f) != NULL) {
67                 if (sscanf(line, "%x, %x, %x, %x",
68                     &mc->i[count],
69                     &mc->i[count + 1],
70                     &mc->i[count + 2],
71                     &mc->i[count + 3]) != 4)
72                         continue;
73                 count += 4;
74         }
75         fclose(f);
76
77         bufsize = count * sizeof(int);
78         printf("%s: %lu(%luk) bytes, %zu integers\n",
79                filename,
80                bufsize,
81                bufsize / 1024,
82                count);
83
84         if (bufsize < sizeof(struct microcode_header_intel))
85                 goto out;
86
87         f = fopen("microcode.bin", "we");
88         if (f == NULL) {
89                 printf("open microcode.bin: %m\n");
90                 rc = EXIT_FAILURE;
91                 goto out;
92         }
93
94         start = 0;
95         for (;;) {
96                 size_t size;
97                 unsigned int family, model, stepping, type;
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                 stepping = mc->hdr.sig & 0x0f;
122                 model = (mc->hdr.sig >> 4) & 0x0f;
123                 family = (mc->hdr.sig >> 8) & 0x0f;
124                 type = (mc->hdr.sig >> 12) & 0x0f;
125                 if (family == 0x06)
126                         model += ((mc->hdr.sig >> 16) & 0x0f) << 4;
127                 if (family == 0x0f)
128                         family += (mc->hdr.sig >> 20) & 0xff;
129
130                 year = mc->hdr.date & 0xffff;
131                 month = mc->hdr.date >> 24;
132                 day = (mc->hdr.date >> 16) & 0xff;
133
134                 printf("\n");
135                 printf("signature: 0x%02x (stepping %d, model %d, family %d, type %d)\n",
136                         mc->hdr.sig, stepping, model, family, type);
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                 if (fwrite(mc, size, 1, f) != 1) {
143                         printf("write microcode.bin: %m\n");
144                         rc = EXIT_FAILURE;
145                         goto out;
146                 }
147
148                 start += size;
149                 if (start >= bufsize)
150                         break;
151         }
152         fclose(f);
153         printf("\n");
154 out:
155         return rc;
156 }
This page took 0.031921 seconds and 3 git commands to generate.