summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0001-Firmware-update-fix-for-mis-aligned-sectors.patch
blob: aebd776d4c4a9502bb1058bd3511b5d66d969523 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
From d58245421fec0ac212382164bd5cc0e881bc389f Mon Sep 17 00:00:00 2001
From: Snehalatha Venkatesh <snehalathax.v@intel.com>
Date: Fri, 27 May 2022 04:23:21 +0000
Subject: [PATCH] Firmware update fix for mis-aligned sectors

Firmware update breaks due to mis-aligned calculations bug in
erase and write sector boundaries, which was corrupting the
next sectors though it wasn't part of erase bit-map (in case of
increased u-boot image size, its region update is corrupting the
neighbouring other fw region). This fix validates the erase and
write boundaries properly now and allows the erase of needed sectors.

Tested: Tested firmware update on platform.

Signed-off-by: Vikram Bodireddy <vikram.bodireddy@intel.com>
Signed-off-by: Snehalatha Venkatesh <snehalathax.v@intel.com>
Signed-off-by: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
---
 pfr.hpp | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/pfr.hpp b/pfr.hpp
index 23a73b3..efe737a 100644
--- a/pfr.hpp
+++ b/pfr.hpp
@@ -412,6 +412,7 @@ bool pfr_write(mtd<deviceClassT>& dev, const std::string& filename,
     uint32_t wr_count = 1;
     uint32_t er_count = 1;
     uint32_t erase_end_addr = 0;
+    uint32_t write_end_addr = 0;
     for (uint32_t blk = 0; blk < pbc_hdr->bitmap_size; blk += wr_count)
     {
         if ((blk % 8) == 0)
@@ -504,28 +505,37 @@ bool pfr_write(mtd<deviceClassT>& dev, const std::string& filename,
             FWDEBUG("erase(" << std::hex << pfr_blk_size * blk << ", "
                              << pfr_blk_size * er_count + dev_offset << ")");
             dev.erase(pfr_blk_size * blk + dev_offset, pfr_blk_size * er_count);
-            erase_end_addr = (pfr_blk_size * (blk + er_count));
+            erase_end_addr = (pfr_blk_size * (blk + er_count)) - 1;
+            FWDEBUG("erase_end_addr: " << std::hex << erase_end_addr);
         }
 
         if (copy)
         {
             cbspan data(offset, offset + pfr_blk_size * wr_count);
-            // DUMP(PRINT_ERROR, data);
-            FWDEBUG("write(" << std::hex << pfr_blk_size * blk << ", "
-                             << pfr_blk_size * wr_count << "), offset = 0x"
-                             << (offset - map_base) + dev_offset);
+            write_end_addr = (pfr_blk_size * (blk + wr_count)) - 1;
+            FWDEBUG("write_end_addr: " << std::hex << write_end_addr);
+
             // Check if current write address wasn't part of previous 64K sector
             // erase. and erase it here.
-            if (((pfr_blk_size * (blk + wr_count)) >= erase_end_addr) ||
-                ((pfr_blk_size * blk) >= erase_end_addr))
+            if ((write_end_addr > erase_end_addr) ||
+                ((pfr_blk_size * blk) > erase_end_addr))
             {
                 // Currently 4K erases are not working hence making it always
                 // 64K erase.
                 // TODO: Fix 4K erase issue and fix the below logic to do
                 // incremental 4K erases.
-                dev.erase(erase_end_addr + dev_offset, pfr_blk_size * 16);
+                FWDEBUG("erase(" << std::hex
+                                 << (erase_end_addr + 1) + dev_offset << ", "
+                                 << pfr_blk_size * 16 << ")");
+
+                dev.erase((erase_end_addr + 1) + dev_offset, pfr_blk_size * 16);
                 erase_end_addr += pfr_blk_size * 16;
+                FWDEBUG("erase_end_addr: " << std::hex << erase_end_addr);
             }
+            // DUMP(PRINT_ERROR, data);
+            FWDEBUG("write(" << std::hex << pfr_blk_size * blk << ", "
+                             << pfr_blk_size * wr_count << "), offset = 0x"
+                             << (offset - map_base) + dev_offset);
             dev.write_raw(pfr_blk_size * blk + dev_offset, data);
 
             offset += pfr_blk_size * wr_count;
-- 
2.17.1