1 /* 2 * PowerNV OPAL Firmware Update Interface 3 * 4 * Copyright 2013 IBM Corp. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #define DEBUG 13 14 #include <linux/kernel.h> 15 #include <linux/reboot.h> 16 #include <linux/init.h> 17 #include <linux/kobject.h> 18 #include <linux/sysfs.h> 19 #include <linux/slab.h> 20 #include <linux/mm.h> 21 #include <linux/vmalloc.h> 22 #include <linux/pagemap.h> 23 24 #include <asm/opal.h> 25 26 /* FLASH status codes */ 27 #define FLASH_NO_OP -1099 /* No operation initiated by user */ 28 #define FLASH_NO_AUTH -9002 /* Not a service authority partition */ 29 30 /* Validate image status values */ 31 #define VALIDATE_IMG_READY -1001 /* Image ready for validation */ 32 #define VALIDATE_IMG_INCOMPLETE -1002 /* User copied < VALIDATE_BUF_SIZE */ 33 34 /* Manage image status values */ 35 #define MANAGE_ACTIVE_ERR -9001 /* Cannot overwrite active img */ 36 37 /* Flash image status values */ 38 #define FLASH_IMG_READY 0 /* Img ready for flash on reboot */ 39 #define FLASH_INVALID_IMG -1003 /* Flash image shorter than expected */ 40 #define FLASH_IMG_NULL_DATA -1004 /* Bad data in sg list entry */ 41 #define FLASH_IMG_BAD_LEN -1005 /* Bad length in sg list entry */ 42 43 /* Manage operation tokens */ 44 #define FLASH_REJECT_TMP_SIDE 0 /* Reject temporary fw image */ 45 #define FLASH_COMMIT_TMP_SIDE 1 /* Commit temporary fw image */ 46 47 /* Update tokens */ 48 #define FLASH_UPDATE_CANCEL 0 /* Cancel update request */ 49 #define FLASH_UPDATE_INIT 1 /* Initiate update */ 50 51 /* Validate image update result tokens */ 52 #define VALIDATE_TMP_UPDATE 0 /* T side will be updated */ 53 #define VALIDATE_FLASH_AUTH 1 /* Partition does not have authority */ 54 #define VALIDATE_INVALID_IMG 2 /* Candidate image is not valid */ 55 #define VALIDATE_CUR_UNKNOWN 3 /* Current fixpack level is unknown */ 56 /* 57 * Current T side will be committed to P side before being replace with new 58 * image, and the new image is downlevel from current image 59 */ 60 #define VALIDATE_TMP_COMMIT_DL 4 61 /* 62 * Current T side will be committed to P side before being replaced with new 63 * image 64 */ 65 #define VALIDATE_TMP_COMMIT 5 66 /* 67 * T side will be updated with a downlevel image 68 */ 69 #define VALIDATE_TMP_UPDATE_DL 6 70 /* 71 * The candidate image's release date is later than the system's firmware 72 * service entitlement date - service warranty period has expired 73 */ 74 #define VALIDATE_OUT_OF_WRNTY 7 75 76 /* Validate buffer size */ 77 #define VALIDATE_BUF_SIZE 4096 78 79 /* XXX: Assume candidate image size is <= 1GB */ 80 #define MAX_IMAGE_SIZE 0x40000000 81 82 /* Image status */ 83 enum { 84 IMAGE_INVALID, 85 IMAGE_LOADING, 86 IMAGE_READY, 87 }; 88 89 /* Candidate image data */ 90 struct image_data_t { 91 int status; 92 void *data; 93 uint32_t size; 94 }; 95 96 /* Candidate image header */ 97 struct image_header_t { 98 uint16_t magic; 99 uint16_t version; 100 uint32_t size; 101 }; 102 103 struct validate_flash_t { 104 int status; /* Return status */ 105 void *buf; /* Candidate image buffer */ 106 uint32_t buf_size; /* Image size */ 107 uint32_t result; /* Update results token */ 108 }; 109 110 struct manage_flash_t { 111 int status; /* Return status */ 112 }; 113 114 struct update_flash_t { 115 int status; /* Return status */ 116 }; 117 118 static struct image_header_t image_header; 119 static struct image_data_t image_data; 120 static struct validate_flash_t validate_flash_data; 121 static struct manage_flash_t manage_flash_data; 122 static struct update_flash_t update_flash_data; 123 124 static DEFINE_MUTEX(image_data_mutex); 125 126 /* 127 * Validate candidate image 128 */ 129 static inline void opal_flash_validate(void) 130 { 131 long ret; 132 void *buf = validate_flash_data.buf; 133 __be32 size, result; 134 135 ret = opal_validate_flash(__pa(buf), &size, &result); 136 137 validate_flash_data.status = ret; 138 validate_flash_data.buf_size = be32_to_cpu(size); 139 validate_flash_data.result = be32_to_cpu(result); 140 } 141 142 /* 143 * Validate output format: 144 * validate result token 145 * current image version details 146 * new image version details 147 */ 148 static ssize_t validate_show(struct kobject *kobj, 149 struct kobj_attribute *attr, char *buf) 150 { 151 struct validate_flash_t *args_buf = &validate_flash_data; 152 int len; 153 154 /* Candidate image is not validated */ 155 if (args_buf->status < VALIDATE_TMP_UPDATE) { 156 len = sprintf(buf, "%d\n", args_buf->status); 157 goto out; 158 } 159 160 /* Result token */ 161 len = sprintf(buf, "%d\n", args_buf->result); 162 163 /* Current and candidate image version details */ 164 if ((args_buf->result != VALIDATE_TMP_UPDATE) && 165 (args_buf->result < VALIDATE_CUR_UNKNOWN)) 166 goto out; 167 168 if (args_buf->buf_size > (VALIDATE_BUF_SIZE - len)) { 169 memcpy(buf + len, args_buf->buf, VALIDATE_BUF_SIZE - len); 170 len = VALIDATE_BUF_SIZE; 171 } else { 172 memcpy(buf + len, args_buf->buf, args_buf->buf_size); 173 len += args_buf->buf_size; 174 } 175 out: 176 /* Set status to default */ 177 args_buf->status = FLASH_NO_OP; 178 return len; 179 } 180 181 /* 182 * Validate candidate firmware image 183 * 184 * Note: 185 * We are only interested in first 4K bytes of the 186 * candidate image. 187 */ 188 static ssize_t validate_store(struct kobject *kobj, 189 struct kobj_attribute *attr, 190 const char *buf, size_t count) 191 { 192 struct validate_flash_t *args_buf = &validate_flash_data; 193 194 if (buf[0] != '1') 195 return -EINVAL; 196 197 mutex_lock(&image_data_mutex); 198 199 if (image_data.status != IMAGE_READY || 200 image_data.size < VALIDATE_BUF_SIZE) { 201 args_buf->result = VALIDATE_INVALID_IMG; 202 args_buf->status = VALIDATE_IMG_INCOMPLETE; 203 goto out; 204 } 205 206 /* Copy first 4k bytes of candidate image */ 207 memcpy(args_buf->buf, image_data.data, VALIDATE_BUF_SIZE); 208 209 args_buf->status = VALIDATE_IMG_READY; 210 args_buf->buf_size = VALIDATE_BUF_SIZE; 211 212 /* Validate candidate image */ 213 opal_flash_validate(); 214 215 out: 216 mutex_unlock(&image_data_mutex); 217 return count; 218 } 219 220 /* 221 * Manage flash routine 222 */ 223 static inline void opal_flash_manage(uint8_t op) 224 { 225 struct manage_flash_t *const args_buf = &manage_flash_data; 226 227 args_buf->status = opal_manage_flash(op); 228 } 229 230 /* 231 * Show manage flash status 232 */ 233 static ssize_t manage_show(struct kobject *kobj, 234 struct kobj_attribute *attr, char *buf) 235 { 236 struct manage_flash_t *const args_buf = &manage_flash_data; 237 int rc; 238 239 rc = sprintf(buf, "%d\n", args_buf->status); 240 /* Set status to default*/ 241 args_buf->status = FLASH_NO_OP; 242 return rc; 243 } 244 245 /* 246 * Manage operations: 247 * 0 - Reject 248 * 1 - Commit 249 */ 250 static ssize_t manage_store(struct kobject *kobj, 251 struct kobj_attribute *attr, 252 const char *buf, size_t count) 253 { 254 uint8_t op; 255 switch (buf[0]) { 256 case '0': 257 op = FLASH_REJECT_TMP_SIDE; 258 break; 259 case '1': 260 op = FLASH_COMMIT_TMP_SIDE; 261 break; 262 default: 263 return -EINVAL; 264 } 265 266 /* commit/reject temporary image */ 267 opal_flash_manage(op); 268 return count; 269 } 270 271 /* 272 * OPAL update flash 273 */ 274 static int opal_flash_update(int op) 275 { 276 struct opal_sg_list *list; 277 unsigned long addr; 278 int64_t rc = OPAL_PARAMETER; 279 280 if (op == FLASH_UPDATE_CANCEL) { 281 pr_alert("FLASH: Image update cancelled\n"); 282 addr = '\0'; 283 goto flash; 284 } 285 286 list = opal_vmalloc_to_sg_list(image_data.data, image_data.size); 287 if (!list) 288 goto invalid_img; 289 290 /* First entry address */ 291 addr = __pa(list); 292 293 pr_alert("FLASH: Image is %u bytes\n", image_data.size); 294 pr_alert("FLASH: Image update requested\n"); 295 pr_alert("FLASH: Image will be updated during system reboot\n"); 296 pr_alert("FLASH: This will take several minutes. Do not power off!\n"); 297 298 flash: 299 rc = opal_update_flash(addr); 300 301 invalid_img: 302 return rc; 303 } 304 305 /* 306 * Show candidate image status 307 */ 308 static ssize_t update_show(struct kobject *kobj, 309 struct kobj_attribute *attr, char *buf) 310 { 311 struct update_flash_t *const args_buf = &update_flash_data; 312 return sprintf(buf, "%d\n", args_buf->status); 313 } 314 315 /* 316 * Set update image flag 317 * 1 - Flash new image 318 * 0 - Cancel flash request 319 */ 320 static ssize_t update_store(struct kobject *kobj, 321 struct kobj_attribute *attr, 322 const char *buf, size_t count) 323 { 324 struct update_flash_t *const args_buf = &update_flash_data; 325 int rc = count; 326 327 mutex_lock(&image_data_mutex); 328 329 switch (buf[0]) { 330 case '0': 331 if (args_buf->status == FLASH_IMG_READY) 332 opal_flash_update(FLASH_UPDATE_CANCEL); 333 args_buf->status = FLASH_NO_OP; 334 break; 335 case '1': 336 /* Image is loaded? */ 337 if (image_data.status == IMAGE_READY) 338 args_buf->status = 339 opal_flash_update(FLASH_UPDATE_INIT); 340 else 341 args_buf->status = FLASH_INVALID_IMG; 342 break; 343 default: 344 rc = -EINVAL; 345 } 346 347 mutex_unlock(&image_data_mutex); 348 return rc; 349 } 350 351 /* 352 * Free image buffer 353 */ 354 static void free_image_buf(void) 355 { 356 void *addr; 357 int size; 358 359 addr = image_data.data; 360 size = PAGE_ALIGN(image_data.size); 361 while (size > 0) { 362 ClearPageReserved(vmalloc_to_page(addr)); 363 addr += PAGE_SIZE; 364 size -= PAGE_SIZE; 365 } 366 vfree(image_data.data); 367 image_data.data = NULL; 368 image_data.status = IMAGE_INVALID; 369 } 370 371 /* 372 * Allocate image buffer. 373 */ 374 static int alloc_image_buf(char *buffer, size_t count) 375 { 376 void *addr; 377 int size; 378 379 if (count < sizeof(struct image_header_t)) { 380 pr_warn("FLASH: Invalid candidate image\n"); 381 return -EINVAL; 382 } 383 384 memcpy(&image_header, (void *)buffer, sizeof(struct image_header_t)); 385 image_data.size = be32_to_cpu(image_header.size); 386 pr_debug("FLASH: Candidate image size = %u\n", image_data.size); 387 388 if (image_data.size > MAX_IMAGE_SIZE) { 389 pr_warn("FLASH: Too large image\n"); 390 return -EINVAL; 391 } 392 if (image_data.size < VALIDATE_BUF_SIZE) { 393 pr_warn("FLASH: Image is shorter than expected\n"); 394 return -EINVAL; 395 } 396 397 image_data.data = vzalloc(PAGE_ALIGN(image_data.size)); 398 if (!image_data.data) { 399 pr_err("%s : Failed to allocate memory\n", __func__); 400 return -ENOMEM; 401 } 402 403 /* Pin memory */ 404 addr = image_data.data; 405 size = PAGE_ALIGN(image_data.size); 406 while (size > 0) { 407 SetPageReserved(vmalloc_to_page(addr)); 408 addr += PAGE_SIZE; 409 size -= PAGE_SIZE; 410 } 411 412 image_data.status = IMAGE_LOADING; 413 return 0; 414 } 415 416 /* 417 * Copy candidate image 418 * 419 * Parse candidate image header to get total image size 420 * and pre-allocate required memory. 421 */ 422 static ssize_t image_data_write(struct file *filp, struct kobject *kobj, 423 struct bin_attribute *bin_attr, 424 char *buffer, loff_t pos, size_t count) 425 { 426 int rc; 427 428 mutex_lock(&image_data_mutex); 429 430 /* New image ? */ 431 if (pos == 0) { 432 /* Free memory, if already allocated */ 433 if (image_data.data) 434 free_image_buf(); 435 436 /* Cancel outstanding image update request */ 437 if (update_flash_data.status == FLASH_IMG_READY) 438 opal_flash_update(FLASH_UPDATE_CANCEL); 439 440 /* Allocate memory */ 441 rc = alloc_image_buf(buffer, count); 442 if (rc) 443 goto out; 444 } 445 446 if (image_data.status != IMAGE_LOADING) { 447 rc = -ENOMEM; 448 goto out; 449 } 450 451 if ((pos + count) > image_data.size) { 452 rc = -EINVAL; 453 goto out; 454 } 455 456 memcpy(image_data.data + pos, (void *)buffer, count); 457 rc = count; 458 459 /* Set image status */ 460 if ((pos + count) == image_data.size) { 461 pr_debug("FLASH: Candidate image loaded....\n"); 462 image_data.status = IMAGE_READY; 463 } 464 465 out: 466 mutex_unlock(&image_data_mutex); 467 return rc; 468 } 469 470 /* 471 * sysfs interface : 472 * OPAL uses below sysfs files for code update. 473 * We create these files under /sys/firmware/opal. 474 * 475 * image : Interface to load candidate firmware image 476 * validate_flash : Validate firmware image 477 * manage_flash : Commit/Reject firmware image 478 * update_flash : Flash new firmware image 479 * 480 */ 481 static struct bin_attribute image_data_attr = { 482 .attr = {.name = "image", .mode = 0200}, 483 .size = MAX_IMAGE_SIZE, /* Limit image size */ 484 .write = image_data_write, 485 }; 486 487 static struct kobj_attribute validate_attribute = 488 __ATTR(validate_flash, 0600, validate_show, validate_store); 489 490 static struct kobj_attribute manage_attribute = 491 __ATTR(manage_flash, 0600, manage_show, manage_store); 492 493 static struct kobj_attribute update_attribute = 494 __ATTR(update_flash, 0600, update_show, update_store); 495 496 static struct attribute *image_op_attrs[] = { 497 &validate_attribute.attr, 498 &manage_attribute.attr, 499 &update_attribute.attr, 500 NULL /* need to NULL terminate the list of attributes */ 501 }; 502 503 static struct attribute_group image_op_attr_group = { 504 .attrs = image_op_attrs, 505 }; 506 507 void __init opal_flash_init(void) 508 { 509 int ret; 510 511 /* Allocate validate image buffer */ 512 validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL); 513 if (!validate_flash_data.buf) { 514 pr_err("%s : Failed to allocate memory\n", __func__); 515 return; 516 } 517 518 /* Make sure /sys/firmware/opal directory is created */ 519 if (!opal_kobj) { 520 pr_warn("FLASH: opal kobject is not available\n"); 521 goto nokobj; 522 } 523 524 /* Create the sysfs files */ 525 ret = sysfs_create_group(opal_kobj, &image_op_attr_group); 526 if (ret) { 527 pr_warn("FLASH: Failed to create sysfs files\n"); 528 goto nokobj; 529 } 530 531 ret = sysfs_create_bin_file(opal_kobj, &image_data_attr); 532 if (ret) { 533 pr_warn("FLASH: Failed to create sysfs files\n"); 534 goto nosysfs_file; 535 } 536 537 /* Set default status */ 538 validate_flash_data.status = FLASH_NO_OP; 539 manage_flash_data.status = FLASH_NO_OP; 540 update_flash_data.status = FLASH_NO_OP; 541 image_data.status = IMAGE_INVALID; 542 return; 543 544 nosysfs_file: 545 sysfs_remove_group(opal_kobj, &image_op_attr_group); 546 547 nokobj: 548 kfree(validate_flash_data.buf); 549 return; 550 } 551