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 begins an image */ 208 #define IMAGE_START_MAGIC "APO=" 209 210 /* magic character sequence that might trail an image */ 211 #define IMAGE_TRAIL_MAGIC "egamiAPO" 212 213 /* EPROM file types */ 214 #define HFI1_EFT_PLATFORM_CONFIG 2 215 216 /* segment size - 128 KiB */ 217 #define SEG_SIZE (128 * 1024) 218 219 struct hfi1_eprom_footer { 220 u32 oprom_size; /* size of the oprom, in bytes */ 221 u16 num_table_entries; 222 u16 version; /* version of this footer */ 223 u32 magic; /* must be last */ 224 }; 225 226 struct hfi1_eprom_table_entry { 227 u32 type; /* file type */ 228 u32 offset; /* file offset from start of EPROM */ 229 u32 size; /* file size, in bytes */ 230 }; 231 232 /* 233 * Calculate the max number of table entries that will fit within a directory 234 * buffer of size 'dir_size'. 235 */ 236 #define MAX_TABLE_ENTRIES(dir_size) \ 237 (((dir_size) - sizeof(struct hfi1_eprom_footer)) / \ 238 sizeof(struct hfi1_eprom_table_entry)) 239 240 #define DIRECTORY_SIZE(n) (sizeof(struct hfi1_eprom_footer) + \ 241 (sizeof(struct hfi1_eprom_table_entry) * (n))) 242 243 #define MAGIC4(a, b, c, d) ((d) << 24 | (c) << 16 | (b) << 8 | (a)) 244 #define FOOTER_MAGIC MAGIC4('e', 'p', 'r', 'm') 245 #define FOOTER_VERSION 1 246 247 /* 248 * Read all of partition 1. The actual file is at the front. Adjust 249 * the returned size if a trailing image magic is found. 250 */ 251 static int read_partition_platform_config(struct hfi1_devdata *dd, void **data, 252 u32 *size) 253 { 254 void *buffer; 255 void *p; 256 u32 length; 257 int ret; 258 259 buffer = kmalloc(P1_SIZE, GFP_KERNEL); 260 if (!buffer) 261 return -ENOMEM; 262 263 ret = read_length(dd, P1_START, P1_SIZE, buffer); 264 if (ret) { 265 kfree(buffer); 266 return ret; 267 } 268 269 /* config partition is valid only if it starts with IMAGE_START_MAGIC */ 270 if (memcmp(buffer, IMAGE_START_MAGIC, strlen(IMAGE_START_MAGIC))) { 271 kfree(buffer); 272 return -ENOENT; 273 } 274 275 /* scan for image magic that may trail the actual data */ 276 p = strnstr(buffer, IMAGE_TRAIL_MAGIC, P1_SIZE); 277 if (p) 278 length = p - buffer; 279 else 280 length = P1_SIZE; 281 282 *data = buffer; 283 *size = length; 284 return 0; 285 } 286 287 /* 288 * The segment magic has been checked. There is a footer and table of 289 * contents present. 290 * 291 * directory is a u32 aligned buffer of size EP_PAGE_SIZE. 292 */ 293 static int read_segment_platform_config(struct hfi1_devdata *dd, 294 void *directory, void **data, u32 *size) 295 { 296 struct hfi1_eprom_footer *footer; 297 struct hfi1_eprom_table_entry *table; 298 struct hfi1_eprom_table_entry *entry; 299 void *buffer = NULL; 300 void *table_buffer = NULL; 301 int ret, i; 302 u32 directory_size; 303 u32 seg_base, seg_offset; 304 u32 bytes_available, ncopied, to_copy; 305 306 /* the footer is at the end of the directory */ 307 footer = (struct hfi1_eprom_footer *) 308 (directory + EP_PAGE_SIZE - sizeof(*footer)); 309 310 /* make sure the structure version is supported */ 311 if (footer->version != FOOTER_VERSION) 312 return -EINVAL; 313 314 /* oprom size cannot be larger than a segment */ 315 if (footer->oprom_size >= SEG_SIZE) 316 return -EINVAL; 317 318 /* the file table must fit in a segment with the oprom */ 319 if (footer->num_table_entries > 320 MAX_TABLE_ENTRIES(SEG_SIZE - footer->oprom_size)) 321 return -EINVAL; 322 323 /* find the file table start, which precedes the footer */ 324 directory_size = DIRECTORY_SIZE(footer->num_table_entries); 325 if (directory_size <= EP_PAGE_SIZE) { 326 /* the file table fits into the directory buffer handed in */ 327 table = (struct hfi1_eprom_table_entry *) 328 (directory + EP_PAGE_SIZE - directory_size); 329 } else { 330 /* need to allocate and read more */ 331 table_buffer = kmalloc(directory_size, GFP_KERNEL); 332 if (!table_buffer) 333 return -ENOMEM; 334 ret = read_length(dd, SEG_SIZE - directory_size, 335 directory_size, table_buffer); 336 if (ret) 337 goto done; 338 table = table_buffer; 339 } 340 341 /* look for the platform configuration file in the table */ 342 for (entry = NULL, i = 0; i < footer->num_table_entries; i++) { 343 if (table[i].type == HFI1_EFT_PLATFORM_CONFIG) { 344 entry = &table[i]; 345 break; 346 } 347 } 348 if (!entry) { 349 ret = -ENOENT; 350 goto done; 351 } 352 353 /* 354 * Sanity check on the configuration file size - it should never 355 * be larger than 4 KiB. 356 */ 357 if (entry->size > (4 * 1024)) { 358 dd_dev_err(dd, "Bad configuration file size 0x%x\n", 359 entry->size); 360 ret = -EINVAL; 361 goto done; 362 } 363 364 /* check for bogus offset and size that wrap when added together */ 365 if (entry->offset + entry->size < entry->offset) { 366 dd_dev_err(dd, 367 "Bad configuration file start + size 0x%x+0x%x\n", 368 entry->offset, entry->size); 369 ret = -EINVAL; 370 goto done; 371 } 372 373 /* allocate the buffer to return */ 374 buffer = kmalloc(entry->size, GFP_KERNEL); 375 if (!buffer) { 376 ret = -ENOMEM; 377 goto done; 378 } 379 380 /* 381 * Extract the file by looping over segments until it is fully read. 382 */ 383 seg_offset = entry->offset % SEG_SIZE; 384 seg_base = entry->offset - seg_offset; 385 ncopied = 0; 386 while (ncopied < entry->size) { 387 /* calculate data bytes available in this segment */ 388 389 /* start with the bytes from the current offset to the end */ 390 bytes_available = SEG_SIZE - seg_offset; 391 /* subtract off footer and table from segment 0 */ 392 if (seg_base == 0) { 393 /* 394 * Sanity check: should not have a starting point 395 * at or within the directory. 396 */ 397 if (bytes_available <= directory_size) { 398 dd_dev_err(dd, 399 "Bad configuration file - offset 0x%x within footer+table\n", 400 entry->offset); 401 ret = -EINVAL; 402 goto done; 403 } 404 bytes_available -= directory_size; 405 } 406 407 /* calculate bytes wanted */ 408 to_copy = entry->size - ncopied; 409 410 /* max out at the available bytes in this segment */ 411 if (to_copy > bytes_available) 412 to_copy = bytes_available; 413 414 /* 415 * Read from the EPROM. 416 * 417 * The sanity check for entry->offset is done in read_length(). 418 * The EPROM offset is validated against what the hardware 419 * addressing supports. In addition, if the offset is larger 420 * than the actual EPROM, it silently wraps. It will work 421 * fine, though the reader may not get what they expected 422 * from the EPROM. 423 */ 424 ret = read_length(dd, seg_base + seg_offset, to_copy, 425 buffer + ncopied); 426 if (ret) 427 goto done; 428 429 ncopied += to_copy; 430 431 /* set up for next segment */ 432 seg_offset = footer->oprom_size; 433 seg_base += SEG_SIZE; 434 } 435 436 /* success */ 437 ret = 0; 438 *data = buffer; 439 *size = entry->size; 440 441 done: 442 kfree(table_buffer); 443 if (ret) 444 kfree(buffer); 445 return ret; 446 } 447 448 /* 449 * Read the platform configuration file from the EPROM. 450 * 451 * On success, an allocated buffer containing the data and its size are 452 * returned. It is up to the caller to free this buffer. 453 * 454 * Return value: 455 * 0 - success 456 * -ENXIO - no EPROM is available 457 * -EBUSY - not able to acquire access to the EPROM 458 * -ENOENT - no recognizable file written 459 * -ENOMEM - buffer could not be allocated 460 * -EINVAL - invalid EPROM contentents found 461 */ 462 int eprom_read_platform_config(struct hfi1_devdata *dd, void **data, u32 *size) 463 { 464 u32 directory[EP_PAGE_DWORDS]; /* aligned buffer */ 465 int ret; 466 467 if (!dd->eprom_available) 468 return -ENXIO; 469 470 ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT); 471 if (ret) 472 return -EBUSY; 473 474 /* read the last page of the segment for the EPROM format magic */ 475 ret = read_length(dd, SEG_SIZE - EP_PAGE_SIZE, EP_PAGE_SIZE, directory); 476 if (ret) 477 goto done; 478 479 /* last dword of the segment contains a magic value */ 480 if (directory[EP_PAGE_DWORDS - 1] == FOOTER_MAGIC) { 481 /* segment format */ 482 ret = read_segment_platform_config(dd, directory, data, size); 483 } else { 484 /* partition format */ 485 ret = read_partition_platform_config(dd, data, size); 486 } 487 488 done: 489 release_chip_resource(dd, CR_EPROM); 490 return ret; 491 } 492