0001
0002
0003
0004
0005
0006
0007
0008 #define DEBUG
0009
0010 #include <linux/kernel.h>
0011 #include <linux/reboot.h>
0012 #include <linux/init.h>
0013 #include <linux/kobject.h>
0014 #include <linux/sysfs.h>
0015 #include <linux/slab.h>
0016 #include <linux/mm.h>
0017 #include <linux/vmalloc.h>
0018 #include <linux/pagemap.h>
0019 #include <linux/delay.h>
0020
0021 #include <asm/opal.h>
0022
0023
0024 #define FLASH_NO_OP -1099
0025 #define FLASH_NO_AUTH -9002
0026
0027
0028 #define VALIDATE_IMG_READY -1001
0029 #define VALIDATE_IMG_INCOMPLETE -1002
0030
0031
0032 #define MANAGE_ACTIVE_ERR -9001
0033
0034
0035 #define FLASH_IMG_READY 0
0036 #define FLASH_INVALID_IMG -1003
0037 #define FLASH_IMG_NULL_DATA -1004
0038 #define FLASH_IMG_BAD_LEN -1005
0039
0040
0041 #define FLASH_REJECT_TMP_SIDE 0
0042 #define FLASH_COMMIT_TMP_SIDE 1
0043
0044
0045 #define FLASH_UPDATE_CANCEL 0
0046 #define FLASH_UPDATE_INIT 1
0047
0048
0049 #define VALIDATE_TMP_UPDATE 0
0050 #define VALIDATE_FLASH_AUTH 1
0051 #define VALIDATE_INVALID_IMG 2
0052 #define VALIDATE_CUR_UNKNOWN 3
0053
0054
0055
0056
0057 #define VALIDATE_TMP_COMMIT_DL 4
0058
0059
0060
0061
0062 #define VALIDATE_TMP_COMMIT 5
0063
0064
0065
0066 #define VALIDATE_TMP_UPDATE_DL 6
0067
0068
0069
0070
0071 #define VALIDATE_OUT_OF_WRNTY 7
0072
0073
0074 #define VALIDATE_BUF_SIZE 4096
0075
0076
0077 #define MAX_IMAGE_SIZE 0x40000000
0078
0079
0080 enum {
0081 IMAGE_INVALID,
0082 IMAGE_LOADING,
0083 IMAGE_READY,
0084 };
0085
0086
0087 struct image_data_t {
0088 int status;
0089 void *data;
0090 uint32_t size;
0091 };
0092
0093
0094 struct image_header_t {
0095 uint16_t magic;
0096 uint16_t version;
0097 uint32_t size;
0098 };
0099
0100 struct validate_flash_t {
0101 int status;
0102 void *buf;
0103 uint32_t buf_size;
0104 uint32_t result;
0105 };
0106
0107 struct manage_flash_t {
0108 int status;
0109 };
0110
0111 struct update_flash_t {
0112 int status;
0113 };
0114
0115 static struct image_header_t image_header;
0116 static struct image_data_t image_data;
0117 static struct validate_flash_t validate_flash_data;
0118 static struct manage_flash_t manage_flash_data;
0119
0120
0121 static struct update_flash_t update_flash_data = {
0122 .status = FLASH_NO_OP,
0123 };
0124
0125 static DEFINE_MUTEX(image_data_mutex);
0126
0127
0128
0129
0130 static inline void opal_flash_validate(void)
0131 {
0132 long ret;
0133 void *buf = validate_flash_data.buf;
0134 __be32 size = cpu_to_be32(validate_flash_data.buf_size);
0135 __be32 result;
0136
0137 ret = opal_validate_flash(__pa(buf), &size, &result);
0138
0139 validate_flash_data.status = ret;
0140 validate_flash_data.buf_size = be32_to_cpu(size);
0141 validate_flash_data.result = be32_to_cpu(result);
0142 }
0143
0144
0145
0146
0147
0148
0149
0150 static ssize_t validate_show(struct kobject *kobj,
0151 struct kobj_attribute *attr, char *buf)
0152 {
0153 struct validate_flash_t *args_buf = &validate_flash_data;
0154 int len;
0155
0156
0157 if (args_buf->status < VALIDATE_TMP_UPDATE) {
0158 len = sprintf(buf, "%d\n", args_buf->status);
0159 goto out;
0160 }
0161
0162
0163 len = sprintf(buf, "%d\n", args_buf->result);
0164
0165
0166 if ((args_buf->result != VALIDATE_TMP_UPDATE) &&
0167 (args_buf->result < VALIDATE_CUR_UNKNOWN))
0168 goto out;
0169
0170 if (args_buf->buf_size > (VALIDATE_BUF_SIZE - len)) {
0171 memcpy(buf + len, args_buf->buf, VALIDATE_BUF_SIZE - len);
0172 len = VALIDATE_BUF_SIZE;
0173 } else {
0174 memcpy(buf + len, args_buf->buf, args_buf->buf_size);
0175 len += args_buf->buf_size;
0176 }
0177 out:
0178
0179 args_buf->status = FLASH_NO_OP;
0180 return len;
0181 }
0182
0183
0184
0185
0186
0187
0188
0189
0190 static ssize_t validate_store(struct kobject *kobj,
0191 struct kobj_attribute *attr,
0192 const char *buf, size_t count)
0193 {
0194 struct validate_flash_t *args_buf = &validate_flash_data;
0195
0196 if (buf[0] != '1')
0197 return -EINVAL;
0198
0199 mutex_lock(&image_data_mutex);
0200
0201 if (image_data.status != IMAGE_READY ||
0202 image_data.size < VALIDATE_BUF_SIZE) {
0203 args_buf->result = VALIDATE_INVALID_IMG;
0204 args_buf->status = VALIDATE_IMG_INCOMPLETE;
0205 goto out;
0206 }
0207
0208
0209 memcpy(args_buf->buf, image_data.data, VALIDATE_BUF_SIZE);
0210
0211 args_buf->status = VALIDATE_IMG_READY;
0212 args_buf->buf_size = VALIDATE_BUF_SIZE;
0213
0214
0215 opal_flash_validate();
0216
0217 out:
0218 mutex_unlock(&image_data_mutex);
0219 return count;
0220 }
0221
0222
0223
0224
0225 static inline void opal_flash_manage(uint8_t op)
0226 {
0227 struct manage_flash_t *const args_buf = &manage_flash_data;
0228
0229 args_buf->status = opal_manage_flash(op);
0230 }
0231
0232
0233
0234
0235 static ssize_t manage_show(struct kobject *kobj,
0236 struct kobj_attribute *attr, char *buf)
0237 {
0238 struct manage_flash_t *const args_buf = &manage_flash_data;
0239 int rc;
0240
0241 rc = sprintf(buf, "%d\n", args_buf->status);
0242
0243 args_buf->status = FLASH_NO_OP;
0244 return rc;
0245 }
0246
0247
0248
0249
0250
0251
0252 static ssize_t manage_store(struct kobject *kobj,
0253 struct kobj_attribute *attr,
0254 const char *buf, size_t count)
0255 {
0256 uint8_t op;
0257 switch (buf[0]) {
0258 case '0':
0259 op = FLASH_REJECT_TMP_SIDE;
0260 break;
0261 case '1':
0262 op = FLASH_COMMIT_TMP_SIDE;
0263 break;
0264 default:
0265 return -EINVAL;
0266 }
0267
0268
0269 opal_flash_manage(op);
0270 return count;
0271 }
0272
0273
0274
0275
0276 static int opal_flash_update(int op)
0277 {
0278 struct opal_sg_list *list;
0279 unsigned long addr;
0280 int64_t rc = OPAL_PARAMETER;
0281
0282 if (op == FLASH_UPDATE_CANCEL) {
0283 pr_alert("FLASH: Image update cancelled\n");
0284 addr = '\0';
0285 goto flash;
0286 }
0287
0288 list = opal_vmalloc_to_sg_list(image_data.data, image_data.size);
0289 if (!list)
0290 goto invalid_img;
0291
0292
0293 addr = __pa(list);
0294
0295 flash:
0296 rc = opal_update_flash(addr);
0297
0298 invalid_img:
0299 return rc;
0300 }
0301
0302
0303 void opal_flash_update_print_message(void)
0304 {
0305 if (update_flash_data.status != FLASH_IMG_READY)
0306 return;
0307
0308 pr_alert("FLASH: Flashing new firmware\n");
0309 pr_alert("FLASH: Image is %u bytes\n", image_data.size);
0310 pr_alert("FLASH: Performing flash and reboot/shutdown\n");
0311 pr_alert("FLASH: This will take several minutes. Do not power off!\n");
0312
0313
0314 msleep(500);
0315 }
0316
0317
0318
0319
0320 static ssize_t update_show(struct kobject *kobj,
0321 struct kobj_attribute *attr, char *buf)
0322 {
0323 struct update_flash_t *const args_buf = &update_flash_data;
0324 return sprintf(buf, "%d\n", args_buf->status);
0325 }
0326
0327
0328
0329
0330
0331
0332 static ssize_t update_store(struct kobject *kobj,
0333 struct kobj_attribute *attr,
0334 const char *buf, size_t count)
0335 {
0336 struct update_flash_t *const args_buf = &update_flash_data;
0337 int rc = count;
0338
0339 mutex_lock(&image_data_mutex);
0340
0341 switch (buf[0]) {
0342 case '0':
0343 if (args_buf->status == FLASH_IMG_READY)
0344 opal_flash_update(FLASH_UPDATE_CANCEL);
0345 args_buf->status = FLASH_NO_OP;
0346 break;
0347 case '1':
0348
0349 if (image_data.status == IMAGE_READY)
0350 args_buf->status =
0351 opal_flash_update(FLASH_UPDATE_INIT);
0352 else
0353 args_buf->status = FLASH_INVALID_IMG;
0354 break;
0355 default:
0356 rc = -EINVAL;
0357 }
0358
0359 mutex_unlock(&image_data_mutex);
0360 return rc;
0361 }
0362
0363
0364
0365
0366 static void free_image_buf(void)
0367 {
0368 void *addr;
0369 int size;
0370
0371 addr = image_data.data;
0372 size = PAGE_ALIGN(image_data.size);
0373 while (size > 0) {
0374 ClearPageReserved(vmalloc_to_page(addr));
0375 addr += PAGE_SIZE;
0376 size -= PAGE_SIZE;
0377 }
0378 vfree(image_data.data);
0379 image_data.data = NULL;
0380 image_data.status = IMAGE_INVALID;
0381 }
0382
0383
0384
0385
0386 static int alloc_image_buf(char *buffer, size_t count)
0387 {
0388 void *addr;
0389 int size;
0390
0391 if (count < sizeof(image_header)) {
0392 pr_warn("FLASH: Invalid candidate image\n");
0393 return -EINVAL;
0394 }
0395
0396 memcpy(&image_header, (void *)buffer, sizeof(image_header));
0397 image_data.size = be32_to_cpu(image_header.size);
0398 pr_debug("FLASH: Candidate image size = %u\n", image_data.size);
0399
0400 if (image_data.size > MAX_IMAGE_SIZE) {
0401 pr_warn("FLASH: Too large image\n");
0402 return -EINVAL;
0403 }
0404 if (image_data.size < VALIDATE_BUF_SIZE) {
0405 pr_warn("FLASH: Image is shorter than expected\n");
0406 return -EINVAL;
0407 }
0408
0409 image_data.data = vzalloc(PAGE_ALIGN(image_data.size));
0410 if (!image_data.data) {
0411 pr_err("%s : Failed to allocate memory\n", __func__);
0412 return -ENOMEM;
0413 }
0414
0415
0416 addr = image_data.data;
0417 size = PAGE_ALIGN(image_data.size);
0418 while (size > 0) {
0419 SetPageReserved(vmalloc_to_page(addr));
0420 addr += PAGE_SIZE;
0421 size -= PAGE_SIZE;
0422 }
0423
0424 image_data.status = IMAGE_LOADING;
0425 return 0;
0426 }
0427
0428
0429
0430
0431
0432
0433
0434 static ssize_t image_data_write(struct file *filp, struct kobject *kobj,
0435 struct bin_attribute *bin_attr,
0436 char *buffer, loff_t pos, size_t count)
0437 {
0438 int rc;
0439
0440 mutex_lock(&image_data_mutex);
0441
0442
0443 if (pos == 0) {
0444
0445 if (image_data.data)
0446 free_image_buf();
0447
0448
0449 if (update_flash_data.status == FLASH_IMG_READY)
0450 opal_flash_update(FLASH_UPDATE_CANCEL);
0451
0452
0453 rc = alloc_image_buf(buffer, count);
0454 if (rc)
0455 goto out;
0456 }
0457
0458 if (image_data.status != IMAGE_LOADING) {
0459 rc = -ENOMEM;
0460 goto out;
0461 }
0462
0463 if ((pos + count) > image_data.size) {
0464 rc = -EINVAL;
0465 goto out;
0466 }
0467
0468 memcpy(image_data.data + pos, (void *)buffer, count);
0469 rc = count;
0470
0471
0472 if ((pos + count) == image_data.size) {
0473 pr_debug("FLASH: Candidate image loaded....\n");
0474 image_data.status = IMAGE_READY;
0475 }
0476
0477 out:
0478 mutex_unlock(&image_data_mutex);
0479 return rc;
0480 }
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 static const struct bin_attribute image_data_attr = {
0494 .attr = {.name = "image", .mode = 0200},
0495 .size = MAX_IMAGE_SIZE,
0496 .write = image_data_write,
0497 };
0498
0499 static struct kobj_attribute validate_attribute =
0500 __ATTR(validate_flash, 0600, validate_show, validate_store);
0501
0502 static struct kobj_attribute manage_attribute =
0503 __ATTR(manage_flash, 0600, manage_show, manage_store);
0504
0505 static struct kobj_attribute update_attribute =
0506 __ATTR(update_flash, 0600, update_show, update_store);
0507
0508 static struct attribute *image_op_attrs[] = {
0509 &validate_attribute.attr,
0510 &manage_attribute.attr,
0511 &update_attribute.attr,
0512 NULL
0513 };
0514
0515 static const struct attribute_group image_op_attr_group = {
0516 .attrs = image_op_attrs,
0517 };
0518
0519 void __init opal_flash_update_init(void)
0520 {
0521 int ret;
0522
0523
0524 if (!opal_check_token(OPAL_FLASH_VALIDATE))
0525 return;
0526
0527
0528 validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
0529 if (!validate_flash_data.buf) {
0530 pr_err("%s : Failed to allocate memory\n", __func__);
0531 return;
0532 }
0533
0534
0535 if (!opal_kobj) {
0536 pr_warn("FLASH: opal kobject is not available\n");
0537 goto nokobj;
0538 }
0539
0540
0541 ret = sysfs_create_group(opal_kobj, &image_op_attr_group);
0542 if (ret) {
0543 pr_warn("FLASH: Failed to create sysfs files\n");
0544 goto nokobj;
0545 }
0546
0547 ret = sysfs_create_bin_file(opal_kobj, &image_data_attr);
0548 if (ret) {
0549 pr_warn("FLASH: Failed to create sysfs files\n");
0550 goto nosysfs_file;
0551 }
0552
0553
0554 validate_flash_data.status = FLASH_NO_OP;
0555 manage_flash_data.status = FLASH_NO_OP;
0556 update_flash_data.status = FLASH_NO_OP;
0557 image_data.status = IMAGE_INVALID;
0558 return;
0559
0560 nosysfs_file:
0561 sysfs_remove_group(opal_kobj, &image_op_attr_group);
0562
0563 nokobj:
0564 kfree(validate_flash_data.buf);
0565 return;
0566 }