1 /* 2 * Copyright(c) 2015, 2016 Intel Corporation. 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of version 2 of the GNU General Public License as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * BSD LICENSE 19 * 20 * Redistribution and use in source and binary forms, with or without 21 * modification, are permitted provided that the following conditions 22 * are met: 23 * 24 * - Redistributions of source code must retain the above copyright 25 * notice, this list of conditions and the following disclaimer. 26 * - Redistributions in binary form must reproduce the above copyright 27 * notice, this list of conditions and the following disclaimer in 28 * the documentation and/or other materials provided with the 29 * distribution. 30 * - Neither the name of Intel Corporation nor the names of its 31 * contributors may be used to endorse or promote products derived 32 * from this software without specific prior written permission. 33 * 34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45 * 46 */ 47 #include <linux/delay.h> 48 #include "hfi.h" 49 #include "common.h" 50 #include "eprom.h" 51 52 /* 53 * The EPROM is logically divided into three partitions: 54 * partition 0: the first 128K, visible from PCI ROM BAR 55 * partition 1: 4K config file (sector size) 56 * partition 2: the rest 57 */ 58 #define P0_SIZE (128 * 1024) 59 #define P1_SIZE (4 * 1024) 60 #define P1_START P0_SIZE 61 #define P2_START (P0_SIZE + P1_SIZE) 62 63 /* controller page size, in bytes */ 64 #define EP_PAGE_SIZE 256 65 #define EP_PAGE_MASK (EP_PAGE_SIZE - 1) 66 #define EP_PAGE_DWORDS (EP_PAGE_SIZE / sizeof(u32)) 67 68 /* controller commands */ 69 #define CMD_SHIFT 24 70 #define CMD_NOP (0) 71 #define CMD_READ_DATA(addr) ((0x03 << CMD_SHIFT) | addr) 72 #define CMD_RELEASE_POWERDOWN_NOID ((0xab << CMD_SHIFT)) 73 74 /* controller interface speeds */ 75 #define EP_SPEED_FULL 0x2 /* full speed */ 76 77 /* 78 * How long to wait for the EPROM to become available, in ms. 79 * The spec 32 Mb EPROM takes around 40s to erase then write. 80 * Double it for safety. 81 */ 82 #define EPROM_TIMEOUT 80000 /* ms */ 83 84 /* 85 * Read a 256 byte (64 dword) EPROM page. 86 * All callers have verified the offset is at a page boundary. 87 */ 88 static void read_page(struct hfi1_devdata *dd, u32 offset, u32 *result) 89 { 90 int i; 91 92 write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_READ_DATA(offset)); 93 for (i = 0; i < EP_PAGE_DWORDS; i++) 94 result[i] = (u32)read_csr(dd, ASIC_EEP_DATA); 95 write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_NOP); /* close open page */ 96 } 97 98 /* 99 * Read length bytes starting at offset from the start of the EPROM. 100 */ 101 static int read_length(struct hfi1_devdata *dd, u32 start, u32 len, void *dest) 102 { 103 u32 buffer[EP_PAGE_DWORDS]; 104 u32 end; 105 u32 start_offset; 106 u32 read_start; 107 u32 bytes; 108 109 if (len == 0) 110 return 0; 111 112 end = start + len; 113 114 /* 115 * Make sure the read range is not outside of the controller read 116 * command address range. Note that '>' is correct below - the end 117 * of the range is OK if it stops at the limit, but no higher. 118 */ 119 if (end > (1 << CMD_SHIFT)) 120 return -EINVAL; 121 122 /* read the first partial page */ 123 start_offset = start & EP_PAGE_MASK; 124 if (start_offset) { 125 /* partial starting page */ 126 127 /* align and read the page that contains the start */ 128 read_start = start & ~EP_PAGE_MASK; 129 read_page(dd, read_start, buffer); 130 131 /* the rest of the page is available data */ 132 bytes = EP_PAGE_SIZE - start_offset; 133 134 if (len <= bytes) { 135 /* end is within this page */ 136 memcpy(dest, (u8 *)buffer + start_offset, len); 137 return 0; 138 } 139 140 memcpy(dest, (u8 *)buffer + start_offset, bytes); 141 142 start += bytes; 143 len -= bytes; 144 dest += bytes; 145 } 146 /* start is now page aligned */ 147 148 /* read whole pages */ 149 while (len >= EP_PAGE_SIZE) { 150 read_page(dd, start, buffer); 151 memcpy(dest, buffer, EP_PAGE_SIZE); 152 153 start += EP_PAGE_SIZE; 154 len -= EP_PAGE_SIZE; 155 dest += EP_PAGE_SIZE; 156 } 157 158 /* read the last partial page */ 159 if (len) { 160 read_page(dd, start, buffer); 161 memcpy(dest, buffer, len); 162 } 163 164 return 0; 165 } 166 167 /* 168 * Initialize the EPROM handler. 169 */ 170 int eprom_init(struct hfi1_devdata *dd) 171 { 172 int ret = 0; 173 174 /* only the discrete chip has an EPROM */ 175 if (dd->pcidev->device != PCI_DEVICE_ID_INTEL0) 176 return 0; 177 178 /* 179 * It is OK if both HFIs reset the EPROM as long as they don't 180 * do it at the same time. 181 */ 182 ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT); 183 if (ret) { 184 dd_dev_err(dd, 185 "%s: unable to acquire EPROM resource, no EPROM support\n", 186 __func__); 187 goto done_asic; 188 } 189 190 /* reset EPROM to be sure it is in a good state */ 191 192 /* set reset */ 193 write_csr(dd, ASIC_EEP_CTL_STAT, ASIC_EEP_CTL_STAT_EP_RESET_SMASK); 194 /* clear reset, set speed */ 195 write_csr(dd, ASIC_EEP_CTL_STAT, 196 EP_SPEED_FULL << ASIC_EEP_CTL_STAT_RATE_SPI_SHIFT); 197 198 /* wake the device with command "release powerdown NoID" */ 199 write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_RELEASE_POWERDOWN_NOID); 200 201 dd->eprom_available = true; 202 release_chip_resource(dd, CR_EPROM); 203 done_asic: 204 return ret; 205 } 206 207 /* magic character sequence that trails an image */ 208 #define IMAGE_TRAIL_MAGIC "egamiAPO" 209 210 /* EPROM file types */ 211 #define HFI1_EFT_PLATFORM_CONFIG 2 212 213 /* segment size - 128 KiB */ 214 #define SEG_SIZE (128 * 1024) 215 216 struct hfi1_eprom_footer { 217 u32 oprom_size; /* size of the oprom, in bytes */ 218 u16 num_table_entries; 219 u16 version; /* version of this footer */ 220 u32 magic; /* must be last */ 221 }; 222 223 struct hfi1_eprom_table_entry { 224 u32 type; /* file type */ 225 u32 offset; /* file offset from start of EPROM */ 226 u32 size; /* file size, in bytes */ 227 }; 228 229 /* 230 * Calculate the max number of table entries that will fit within a directory 231 * buffer of size 'dir_size'. 232 */ 233 #define MAX_TABLE_ENTRIES(dir_size) \ 234 (((dir_size) - sizeof(struct hfi1_eprom_footer)) / \ 235 sizeof(struct hfi1_eprom_table_entry)) 236 237 #define DIRECTORY_SIZE(n) (sizeof(struct hfi1_eprom_footer) + \ 238 (sizeof(struct hfi1_eprom_table_entry) * (n))) 239 240 #define MAGIC4(a, b, c, d) ((d) << 24 | (c) << 16 | (b) << 8 | (a)) 241 #define FOOTER_MAGIC MAGIC4('e', 'p', 'r', 'm') 242 #define FOOTER_VERSION 1 243 244 /* 245 * Read all of partition 1. The actual file is at the front. Adjust 246 * the returned size if a trailing image magic is found. 247 */ 248 static int read_partition_platform_config(struct hfi1_devdata *dd, void **data, 249 u32 *size) 250 { 251 void *buffer; 252 void *p; 253 u32 length; 254 int ret; 255 256 buffer = kmalloc(P1_SIZE, GFP_KERNEL); 257 if (!buffer) 258 return -ENOMEM; 259 260 ret = read_length(dd, P1_START, P1_SIZE, buffer); 261 if (ret) { 262 kfree(buffer); 263 return ret; 264 } 265 266 /* scan for image magic that may trail the actual data */ 267 p = strnstr(buffer, IMAGE_TRAIL_MAGIC, P1_SIZE); 268 if (p) 269 length = p - buffer; 270 else 271 length = P1_SIZE; 272 273 *data = buffer; 274 *size = length; 275 return 0; 276 } 277 278 /* 279 * The segment magic has been checked. There is a footer and table of 280 * contents present. 281 * 282 * directory is a u32 aligned buffer of size EP_PAGE_SIZE. 283 */ 284 static int read_segment_platform_config(struct hfi1_devdata *dd, 285 void *directory, void **data, u32 *size) 286 { 287 struct hfi1_eprom_footer *footer; 288 struct hfi1_eprom_table_entry *table; 289 struct hfi1_eprom_table_entry *entry; 290 void *buffer = NULL; 291 void *table_buffer = NULL; 292 int ret, i; 293 u32 directory_size; 294 u32 seg_base, seg_offset; 295 u32 bytes_available, ncopied, to_copy; 296 297 /* the footer is at the end of the directory */ 298 footer = (struct hfi1_eprom_footer *) 299 (directory + EP_PAGE_SIZE - sizeof(*footer)); 300 301 /* make sure the structure version is supported */ 302 if (footer->version != FOOTER_VERSION) 303 return -EINVAL; 304 305 /* oprom size cannot be larger than a segment */ 306 if (footer->oprom_size >= SEG_SIZE) 307 return -EINVAL; 308 309 /* the file table must fit in a segment with the oprom */ 310 if (footer->num_table_entries > 311 MAX_TABLE_ENTRIES(SEG_SIZE - footer->oprom_size)) 312 return -EINVAL; 313 314 /* find the file table start, which precedes the footer */ 315 directory_size = DIRECTORY_SIZE(footer->num_table_entries); 316 if (directory_size <= EP_PAGE_SIZE) { 317 /* the file table fits into the directory buffer handed in */ 318 table = (struct hfi1_eprom_table_entry *) 319 (directory + EP_PAGE_SIZE - directory_size); 320 } else { 321 /* need to allocate and read more */ 322 table_buffer = kmalloc(directory_size, GFP_KERNEL); 323 if (!table_buffer) 324 return -ENOMEM; 325 ret = read_length(dd, SEG_SIZE - directory_size, 326 directory_size, table_buffer); 327 if (ret) 328 goto done; 329 table = table_buffer; 330 } 331 332 /* look for the platform configuration file in the table */ 333 for (entry = NULL, i = 0; i < footer->num_table_entries; i++) { 334 if (table[i].type == HFI1_EFT_PLATFORM_CONFIG) { 335 entry = &table[i]; 336 break; 337 } 338 } 339 if (!entry) { 340 ret = -ENOENT; 341 goto done; 342 } 343 344 /* 345 * Sanity check on the configuration file size - it should never 346 * be larger than 4 KiB. 347 */ 348 if (entry->size > (4 * 1024)) { 349 dd_dev_err(dd, "Bad configuration file size 0x%x\n", 350 entry->size); 351 ret = -EINVAL; 352 goto done; 353 } 354 355 /* check for bogus offset and size that wrap when added together */ 356 if (entry->offset + entry->size < entry->offset) { 357 dd_dev_err(dd, 358 "Bad configuration file start + size 0x%x+0x%x\n", 359 entry->offset, entry->size); 360 ret = -EINVAL; 361 goto done; 362 } 363 364 /* allocate the buffer to return */ 365 buffer = kmalloc(entry->size, GFP_KERNEL); 366 if (!buffer) { 367 ret = -ENOMEM; 368 goto done; 369 } 370 371 /* 372 * Extract the file by looping over segments until it is fully read. 373 */ 374 seg_offset = entry->offset % SEG_SIZE; 375 seg_base = entry->offset - seg_offset; 376 ncopied = 0; 377 while (ncopied < entry->size) { 378 /* calculate data bytes available in this segment */ 379 380 /* start with the bytes from the current offset to the end */ 381 bytes_available = SEG_SIZE - seg_offset; 382 /* subtract off footer and table from segment 0 */ 383 if (seg_base == 0) { 384 /* 385 * Sanity check: should not have a starting point 386 * at or within the directory. 387 */ 388 if (bytes_available <= directory_size) { 389 dd_dev_err(dd, 390 "Bad configuration file - offset 0x%x within footer+table\n", 391 entry->offset); 392 ret = -EINVAL; 393 goto done; 394 } 395 bytes_available -= directory_size; 396 } 397 398 /* calculate bytes wanted */ 399 to_copy = entry->size - ncopied; 400 401 /* max out at the available bytes in this segment */ 402 if (to_copy > bytes_available) 403 to_copy = bytes_available; 404 405 /* 406 * Read from the EPROM. 407 * 408 * The sanity check for entry->offset is done in read_length(). 409 * The EPROM offset is validated against what the hardware 410 * addressing supports. In addition, if the offset is larger 411 * than the actual EPROM, it silently wraps. It will work 412 * fine, though the reader may not get what they expected 413 * from the EPROM. 414 */ 415 ret = read_length(dd, seg_base + seg_offset, to_copy, 416 buffer + ncopied); 417 if (ret) 418 goto done; 419 420 ncopied += to_copy; 421 422 /* set up for next segment */ 423 seg_offset = footer->oprom_size; 424 seg_base += SEG_SIZE; 425 } 426 427 /* success */ 428 ret = 0; 429 *data = buffer; 430 *size = entry->size; 431 432 done: 433 kfree(table_buffer); 434 if (ret) 435 kfree(buffer); 436 return ret; 437 } 438 439 /* 440 * Read the platform configuration file from the EPROM. 441 * 442 * On success, an allocated buffer containing the data and its size are 443 * returned. It is up to the caller to free this buffer. 444 * 445 * Return value: 446 * 0 - success 447 * -ENXIO - no EPROM is available 448 * -EBUSY - not able to acquire access to the EPROM 449 * -ENOENT - no recognizable file written 450 * -ENOMEM - buffer could not be allocated 451 * -EINVAL - invalid EPROM contentents found 452 */ 453 int eprom_read_platform_config(struct hfi1_devdata *dd, void **data, u32 *size) 454 { 455 u32 directory[EP_PAGE_DWORDS]; /* aligned buffer */ 456 int ret; 457 458 if (!dd->eprom_available) 459 return -ENXIO; 460 461 ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT); 462 if (ret) 463 return -EBUSY; 464 465 /* read the last page of the segment for the EPROM format magic */ 466 ret = read_length(dd, SEG_SIZE - EP_PAGE_SIZE, EP_PAGE_SIZE, directory); 467 if (ret) 468 goto done; 469 470 /* last dword of the segment contains a magic value */ 471 if (directory[EP_PAGE_DWORDS - 1] == FOOTER_MAGIC) { 472 /* segment format */ 473 ret = read_segment_platform_config(dd, directory, data, size); 474 } else { 475 /* partition format */ 476 ret = read_partition_platform_config(dd, data, size); 477 } 478 479 done: 480 release_chip_resource(dd, CR_EPROM); 481 return ret; 482 } 483