Mon May 7 04:27:43 2018 UTC ()
 If the microcode.dat file is not bundled in the archive file, extract from
binary files. I verified the output from both microcode-20180312.tgz's
microcode.dat and intel-ucode/??-??-?? are the same.

 This change is required for microcode-20180425.tgz.


(msaitoh)
diff -r1.3 -r1.4 pkgsrc/sysutils/intel-microcode-netbsd/files/extract.c

cvs diff -r1.3 -r1.4 pkgsrc/sysutils/intel-microcode-netbsd/files/extract.c (expand / switch to unified diff)

--- pkgsrc/sysutils/intel-microcode-netbsd/files/extract.c 2014/02/19 19:31:08 1.3
+++ pkgsrc/sysutils/intel-microcode-netbsd/files/extract.c 2018/05/07 04:27:43 1.4
@@ -1,15 +1,16 @@ @@ -1,15 +1,16 @@
1/* $NetBSD: extract.c,v 1.3 2014/02/19 19:31:08 drochner Exp $ */ 1/* $NetBSD: extract.c,v 1.4 2018/05/07 04:27:43 msaitoh Exp $ */
2 2
 3#include <sys/stat.h>
3#include <stdlib.h> 4#include <stdlib.h>
4#include <unistd.h> 5#include <unistd.h>
5#include <fcntl.h> 6#include <fcntl.h>
6#include <stdio.h> 7#include <stdio.h>
7#include <string.h> 8#include <string.h>
8#include <errno.h> 9#include <errno.h>
9#include <err.h> 10#include <err.h>
10 11
11#include <x86/cpu_ucode.h> 12#include <x86/cpu_ucode.h>
12 13
13FILE *in; 14FILE *in;
14int lc; 15int lc;
15 16
@@ -71,94 +72,207 @@ again: @@ -71,94 +72,207 @@ again:
71 printf("replacing %s\n", alias); 72 printf("replacing %s\n", alias);
72 if (unlink(alias)) 73 if (unlink(alias))
73 err(2, "unlink %s", alias); 74 err(2, "unlink %s", alias);
74 goto again; 75 goto again;
75} 76}
76 77
77static void 78static void
78writeout(struct intel1_ucode_header *uh, int len, 79writeout(struct intel1_ucode_header *uh, int len,
79 struct intel1_ucode_ext_table *eh) 80 struct intel1_ucode_ext_table *eh)
80{ 81{
81 char name[18], alias[11]; 82 char name[18], alias[11];
82 int fd, used, i, j; 83 int fd, used, i, j;
83 struct intel1_ucode_proc_signature *eps; 84 struct intel1_ucode_proc_signature *eps;
 85 int rv;
84 86
85 sprintf(name, "%08x.%08x", uh->uh_signature, uh->uh_rev); 87 sprintf(name, "%08x.%08x", uh->uh_signature, uh->uh_rev);
86 fd = open(name, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644); 88 fd = open(name, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644);
87 if (fd < 0) 89 if (fd < 0)
88 err(2, "open %s", name); 90 err(2, "open %s", name);
89 write(fd, uh, len); 91 rv = write(fd, uh, len);
 92 if (rv == -1)
 93 err(EXIT_FAILURE, "failed to write %s\n", name);
90 close(fd); 94 close(fd);
91 95
92 used = 0; 96 used = 0;
93 for (i = 0; i < 8; i++) { 97 for (i = 0; i < 8; i++) {
94 if (!(uh->uh_proc_flags & (1 << i))) 98 if (!(uh->uh_proc_flags & (1 << i)))
95 continue; 99 continue;
96 sprintf(alias, "%08x-%d", uh->uh_signature, i); 100 sprintf(alias, "%08x-%d", uh->uh_signature, i);
97 used += link_unless_newer_exists(name, alias, uh->uh_rev); 101 used += link_unless_newer_exists(name, alias, uh->uh_rev);
98 } 102 }
99 if (eh) { 103 if (eh) {
100 /* extension headers are unused in rev. 20140122 */ 104 printf("%s: Check the extended header.\n", __func__);
101 for (j = 0; j < eh->uet_count; j++) { 105 for (j = 0; j < eh->uet_count; j++) {
102 eps = &eh->uet_proc_sig[j]; 106 eps = &eh->uet_proc_sig[j];
103 for (i = 0; i < 8; i++) { 107 for (i = 0; i < 8; i++) {
104 if (!(eps->ups_proc_flags & (1 << i))) 108 if (!(eps->ups_proc_flags & (1 << i)))
105 continue; 109 continue;
106 sprintf(alias, "%08x-%d", 110 sprintf(alias, "%08x-%d",
107 eps->ups_signature, i); 111 eps->ups_signature, i);
108 used += link_unless_newer_exists(name, alias, 112 used += link_unless_newer_exists(name, alias,
109 uh->uh_rev); 113 uh->uh_rev);
110 } 114 }
111 } 115 }
112 } 116 }
113 117
114 unlink(name); 118 unlink(name);
115 printf("%s: %d links\n", name, used); 119 printf("%s: %d links\n", name, used);
116} 120}
117 121
 122void
 123update_size(struct intel1_ucode_header *uh,
 124 uint32_t *datasize, uint32_t *totalsize)
 125{
 126 if (uh->uh_data_size)
 127 *datasize = uh->uh_data_size;
 128 else
 129 *datasize = 2000;
 130 if (uh->uh_total_size)
 131 *totalsize = uh->uh_total_size;
 132 else
 133 *totalsize = *datasize + 48;
 134}
 135
 136/* Extract .dat (or .inc) file. Usually for microcode.dat. */
118int 137int
119main(int argc, char **argv) 138extract_dat(const char *fname)
120{ 139{
121 struct intel1_ucode_header uh; 140 struct intel1_ucode_header uh;
122 int datasize, totalsize; 141 uint32_t datasize, totalsize;
123 void *theupdate; 142 void *theupdate;
124 struct intel1_ucode_ext_table *eh; 143 struct intel1_ucode_ext_table *eh;
125 144
126 if (argc < 2) 145 in = fopen(fname, "r");
127 errx(1, "need filename"); 
128 
129 in = fopen(argv[1], "r"); 
130 if (!in) 146 if (!in)
131 err(2, "could not open \"%s\"", argv[1]); 147 err(2, "could not open \"%s\"", fname);
132 148
133 for (;;) { 149 for (;;) {
134 if (getbin(&uh, sizeof(uh)) < 0) 150 if (getbin(&uh, sizeof(uh)) < 0)
135 break; 151 break;
136 if (uh.uh_header_ver != 1) 152 if (uh.uh_header_ver != 1)
137 errx(3, "wrong file format, last line %d", lc); 153 errx(3, "wrong file format, last line %d", lc);
138 if (uh.uh_data_size) 154
139 datasize = uh.uh_data_size; 155 update_size(&uh, &datasize, &totalsize);
140 else 
141 datasize = 2000; 
142 if (uh.uh_total_size) 
143 totalsize = uh.uh_total_size; 
144 else 
145 totalsize = datasize + 48; 
146 156
147 theupdate = malloc(totalsize); 157 theupdate = malloc(totalsize);
148 memcpy(theupdate, &uh, 48); 158 memcpy(theupdate, &uh, 48);
149 if (getbin((char *)theupdate + 48, totalsize - 48) < 0) 159 if (getbin((char *)theupdate + 48, totalsize - 48) < 0)
150 errx(3, "data format"); 160 errx(3, "data format");
151 161
152 if (totalsize != datasize + 48) 162 if (totalsize != datasize + 48)
153 eh = (void *)((char *)theupdate + 48 + datasize); 163 eh = (void *)((char *)theupdate + 48 + datasize);
154 else 164 else
155 eh = NULL; 165 eh = NULL;
156 166
157 writeout(theupdate, totalsize, eh); 167 writeout(theupdate, totalsize, eh);
158 free(theupdate); 168 free(theupdate);
159 169
160 } 170 }
161 171
162 fclose(in); 172 fclose(in);
163 exit(0); 173
 174 return 0;
 175}
 176
 177/* Extract binary files (UV-WX-YZ style filename) */
 178int
 179extract_bin(int argc, char **argv)
 180{
 181 struct intel1_ucode_header *uh;
 182 uint32_t datasize, totalsize;
 183 void *theupdate, *buf;
 184 struct intel1_ucode_ext_table *eh;
 185 struct stat sb;
 186 size_t left;
 187 int i, rv;
 188
 189 argv++; /* Skip argc[0] (command name). */
 190
 191 for (i = 1; i < argc; i++, argv++) {
 192 rv = stat(*argv, &sb);
 193 if (rv != 0)
 194 err(EXIT_FAILURE, "failed to stat \"%s\"", *argv);
 195
 196 theupdate = buf = malloc(sb.st_size);
 197 if (theupdate == NULL)
 198 err(EXIT_FAILURE,
 199 "failed to alloc buf for \"%s\" (size = %zu)",
 200 *argv, sb.st_size);
 201
 202 in = fopen(*argv, "r");
 203 if (!in)
 204 err(EXIT_FAILURE, "could not open \"%s\"", *argv);
 205
 206 rv = fread(theupdate, sizeof(char), sb.st_size, in);
 207 if (rv != sb.st_size)
 208 err(EXIT_FAILURE,
 209 "failed to read \"%s\" (size = %zu)",
 210 *argv, sb.st_size);
 211 left = sb.st_size;
 212next:
 213 uh = (struct intel1_ucode_header *)theupdate;
 214
 215#if 0 /* Dump header */
 216 for (int j = 0; j < sizeof(struct intel1_ucode_header) / 4;
 217 j++) {
 218 uint32_t *q = (uint32_t *)uh;
 219
 220 if ((j % 4) == 0)
 221 printf("%08x:", j);
 222 printf(" %08x", q[j]);
 223 if ((j % 4) == 3)
 224 printf("\n");
 225 }
 226 printf("\n");
 227#endif
 228
 229 if (uh->uh_header_ver != 1)
 230 errx(EXIT_FAILURE,
 231 "wrong file format, last line %d", lc);
 232
 233 update_size(uh, &datasize, &totalsize);
 234
 235 if (totalsize != datasize + 48)
 236 eh = (void *)((char *)theupdate + 48 + datasize);
 237 else
 238 eh = NULL;
 239
 240 writeout(theupdate, totalsize, eh);
 241
 242 if ((eh == NULL) && (totalsize != left)) {
 243 printf("file = %s. size in headers (%u) != file size "
 244 "left (%zu). This file has multiple entries "
 245 "without the extended signature stucture.\n",
 246 *argv, totalsize, left);
 247 theupdate += totalsize;
 248 left -= totalsize;
 249 goto next;
 250 }
 251
 252 free(buf);
 253 fclose(in);
 254 }
 255
 256 return 0;
 257}
 258
 259int
 260main(int argc, char **argv)
 261{
 262 const char *p;
 263 int rv;
 264
 265 if (argc < 2)
 266 errx(1, "need filename");
 267
 268 p = strchr(argv[1], '.');
 269 if ((p != NULL) && (strcmp(p + 1, "dat") == 0)) {
 270 /* Extract microcode.dat file */
 271 rv = extract_dat(argv[1]);
 272 } else {
 273 /* Extract UV-WX-YZ files */
 274 rv = extract_bin(argc, argv);
 275 }
 276
 277 return rv;
164} 278}