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