LCOV - code coverage report
Current view: top level - core - flash-firmware-versions.c (source / functions) Hit Total Coverage
Test: skiboot.info Lines: 58 68 85.3 %
Date: 2024-01-02 21:04:04 Functions: 3 3 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  * Parse VERSION partition, add to device tree
       4                 :            :  *
       5                 :            :  * Copyright 2013-2018 IBM Corp.
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <skiboot.h>
       9                 :            : #include <device.h>
      10                 :            : #include <opal.h>
      11                 :            : #include <libstb/secureboot.h>
      12                 :            : #include <libstb/trustedboot.h>
      13                 :            : 
      14                 :            : /* ibm,firmware-versions support */
      15                 :            : static char *version_buf;
      16                 :            : static size_t version_buf_size = 0x2000;
      17                 :            : 
      18                 :         96 : static void __flash_dt_add_fw_version(struct dt_node *fw_version, char* data)
      19                 :            : {
      20                 :            :         static bool first = true;
      21                 :            :         char *prop;
      22                 :            :         int version_len, i;
      23                 :         96 :         int len = strlen(data);
      24                 :            :         const char *skiboot_version;
      25                 :         96 :         const char * version_str[] = {"open-power", "buildroot", "skiboot",
      26                 :            :                                       "hostboot-binaries", "hostboot", "linux",
      27                 :            :                                       "petitboot", "occ", "capp-ucode", "sbe",
      28                 :            :                                       "machine-xml", "hcode"};
      29                 :            : 
      30                 :         96 :         if (first) {
      31                 :         12 :                 first = false;
      32                 :            : 
      33                 :            :                 /* Increment past "key-" */
      34                 :         12 :                 if (memcmp(data, "open-power", strlen("open-power")) == 0)
      35                 :         10 :                         prop = data + strlen("open-power");
      36                 :            :                 else
      37                 :          2 :                         prop = strchr(data, '-');
      38                 :         12 :                 if (!prop) {
      39                 :          1 :                         prlog(PR_DEBUG,
      40                 :            :                               "FLASH: Invalid fw version format (%s)\n", data);
      41                 :         12 :                         return;
      42                 :            :                 }
      43                 :         11 :                 prop++;
      44                 :            : 
      45                 :         11 :                 dt_add_property_string(fw_version, "version", prop);
      46                 :         11 :                 return;
      47                 :            :         }
      48                 :            : 
      49                 :            :         /*
      50                 :            :          * PNOR version strings are not easily consumable. Split them into
      51                 :            :          * property, value.
      52                 :            :          *
      53                 :            :          * Example input from PNOR :
      54                 :            :          *   "open-power-firestone-v1.8"
      55                 :            :          *   "linux-4.4.6-openpower1-8420e0f"
      56                 :            :          *
      57                 :            :          * Desired output in device tree:
      58                 :            :          *   open-power = "firestone-v1.8";
      59                 :            :          *   linux = "4.4.6-openpower1-8420e0f";
      60                 :            :          */
      61                 :       1092 :         for(i = 0; i < ARRAY_SIZE(version_str); i++)
      62                 :            :         {
      63                 :       1008 :                 version_len = strlen(version_str[i]);
      64                 :       1008 :                 if (len < version_len)
      65                 :         39 :                         continue;
      66                 :            : 
      67                 :        969 :                 if (memcmp(data, version_str[i], version_len) != 0)
      68                 :        887 :                         continue;
      69                 :            : 
      70                 :            :                 /* Found a match, add property */
      71                 :         82 :                 if (dt_find_property(fw_version, version_str[i]))
      72                 :          6 :                         continue;
      73                 :            : 
      74                 :            :                 /* Increment past "key-" */
      75                 :         76 :                 prop = data + version_len + 1;
      76                 :         76 :                 dt_add_property_string(fw_version, version_str[i], prop);
      77                 :            : 
      78                 :            :                 /* Sanity check against what Skiboot thinks its version is. */
      79                 :         76 :                 if (strncmp(version_str[i], "skiboot",
      80                 :            :                                         strlen("skiboot")) == 0) {
      81                 :            :                         /*
      82                 :            :                          * If Skiboot was built with Buildroot its version may
      83                 :            :                          * include a 'skiboot-' prefix; ignore it.
      84                 :            :                          */
      85                 :            :                         if (strncmp(version, "skiboot-",
      86                 :            :                                                 strlen("skiboot-")) == 0)
      87                 :            :                                 skiboot_version = version + strlen("skiboot-");
      88                 :            :                         else
      89                 :          9 :                                 skiboot_version = version;
      90                 :          9 :                         if (strncmp(prop, skiboot_version,
      91                 :            :                                                 strlen(skiboot_version)) != 0)
      92                 :          9 :                                 prlog(PR_WARNING, "WARNING! Skiboot version does not match VERSION partition!\n");
      93                 :            :                 }
      94                 :            :         }
      95                 :            : }
      96                 :            : 
      97                 :         13 : void flash_dt_add_fw_version(void)
      98                 :            : {
      99                 :            :         uint8_t version_data[80];
     100                 :            :         int rc;
     101                 :         13 :         int numbytes = 0, i = 0;
     102                 :            :         struct dt_node *fw_version;
     103                 :            : 
     104                 :         13 :         if (version_buf == NULL)
     105                 :          0 :                 return;
     106                 :            : 
     107                 :         13 :         rc = wait_for_resource_loaded(RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE);
     108                 :         13 :         if (rc != OPAL_SUCCESS) {
     109                 :          0 :                 prlog(PR_WARNING, "FLASH: Failed to load VERSION data\n");
     110                 :          0 :                 free(version_buf);
     111                 :          0 :                 return;
     112                 :            :         }
     113                 :            : 
     114                 :         13 :         fw_version = dt_new(dt_root, "ibm,firmware-versions");
     115                 :         13 :         assert(fw_version);
     116                 :            : 
     117                 :         13 :         if (stb_is_container(version_buf, version_buf_size))
     118                 :          0 :                 numbytes += SECURE_BOOT_HEADERS_SIZE;
     119                 :       2520 :         for ( ; (numbytes < version_buf_size) && version_buf[numbytes]; numbytes++) {
     120                 :       2508 :                 if (version_buf[numbytes] == '\n') {
     121                 :         96 :                         version_data[i] = '\0';
     122                 :         96 :                         __flash_dt_add_fw_version(fw_version, version_data);
     123                 :         96 :                         memset(version_data, 0, sizeof(version_data));
     124                 :         96 :                         i = 0;
     125                 :         96 :                         continue;
     126                 :       2412 :                 } else if (version_buf[numbytes] == '\t') {
     127                 :         85 :                         continue; /* skip tabs */
     128                 :            :                 }
     129                 :            : 
     130                 :       2327 :                 version_data[i++] = version_buf[numbytes];
     131                 :       2327 :                 if (i == sizeof(version_data)) {
     132                 :          1 :                         prlog(PR_WARNING, "VERSION item >%lu chars, skipping\n",
     133                 :            :                               sizeof(version_data));
     134                 :          1 :                         break;
     135                 :            :                 }
     136                 :            :         }
     137                 :            : 
     138                 :         13 :         free(version_buf);
     139                 :            : }
     140                 :            : 
     141                 :         26 : void flash_fw_version_preload(void)
     142                 :            : {
     143                 :            :         int rc;
     144                 :            : 
     145                 :         26 :         if (proc_gen < proc_gen_p9)
     146                 :         13 :                 return;
     147                 :            : 
     148                 :         13 :         prlog(PR_INFO, "FLASH: Loading VERSION section\n");
     149                 :            : 
     150                 :         13 :         version_buf = malloc(version_buf_size);
     151                 :         13 :         if (!version_buf) {
     152                 :          0 :                 prlog(PR_WARNING, "FLASH: Failed to allocate memory\n");
     153                 :          0 :                 return;
     154                 :            :         }
     155                 :            : 
     156                 :         13 :         rc = start_preload_resource(RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE,
     157                 :            :                                     version_buf, &version_buf_size);
     158                 :         13 :         if (rc != OPAL_SUCCESS) {
     159                 :          0 :                 prlog(PR_WARNING,
     160                 :            :                       "FLASH: Failed to start loading VERSION data\n");
     161                 :          0 :                 free(version_buf);
     162                 :          0 :                 version_buf = NULL;
     163                 :            :         }
     164                 :            : }

Generated by: LCOV version 1.14