blob: 60066f53f6e621ffc92bbce02d095ebf02ea7813 [file] [log] [blame]
Deepak Kodihallib6a446f2017-04-29 13:01:49 -05001#include "mboxd_pnor_partition_table.h"
Deepak Kodihalli017e45c2017-07-12 01:06:30 -05002#include "common.h"
Deepak Kodihallib6a446f2017-04-29 13:01:49 -05003#include "mbox.h"
Deepak Kodihalli017e45c2017-07-12 01:06:30 -05004#include "mboxd_flash.h"
Deepak Kodihallib6a446f2017-04-29 13:01:49 -05005#include "pnor_partition_table.hpp"
Ratan Gupta3214b512017-05-11 08:58:19 +05306#include <experimental/filesystem>
Deepak Kodihallib6a446f2017-04-29 13:01:49 -05007
8struct vpnor_partition_table
9{
10 openpower::virtual_pnor::partition::Table* table = nullptr;
11};
12
13void vpnor_create_partition_table(struct mbox_context *context)
14{
Ratan Gupta3214b512017-05-11 08:58:19 +053015 if (context && !context->vpnor)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050016 {
Ratan Gupta3214b512017-05-11 08:58:19 +053017 context->vpnor = new vpnor_partition_table;
18 context->vpnor->table =
Deepak Kodihallid1d79302017-07-11 23:01:39 -050019 new openpower::virtual_pnor::partition::Table(
20 1 << context->erase_size_shift,
21 context->flash_size);
Ratan Gupta3214b512017-05-11 08:58:19 +053022 }
23}
24
25void vpnor_create_partition_table_from_path(struct mbox_context *context,
26 const char *path)
27{
28 std::experimental::filesystem::path dir(path);
29
30 if (context && !context->vpnor)
31 {
32 context->vpnor = new vpnor_partition_table;
33 context->vpnor->table =
Deepak Kodihallid1d79302017-07-11 23:01:39 -050034 new openpower::virtual_pnor::partition::Table(
35 std::move(dir),
36 1 << context->erase_size_shift,
37 context->flash_size);
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050038 }
39}
40
41size_t vpnor_get_partition_table_size(const struct mbox_context *context)
42{
43 return context && context->vpnor ?
44 context->vpnor->table->size() : 0;
45}
46
47const struct pnor_partition_table* vpnor_get_partition_table(
48 const struct mbox_context *context)
49{
50 return context && context->vpnor ?
51 &(context->vpnor->table->getHostTable()) : nullptr;
52}
53
54const struct pnor_partition* vpnor_get_partition(
55 const struct mbox_context *context,
56 const size_t offset)
57{
58 return context && context->vpnor ?
59 &(context->vpnor->table->partition(offset)) : nullptr;
60}
61
Deepak Kodihalli017e45c2017-07-12 01:06:30 -050062void vpnor_copy_bootloader_partition(const struct mbox_context *context)
63{
64 // The hostboot bootloader has certain size/offset assumptions, so
65 // we need a special partition table here.
66 // It assumes the PNOR is 64M, the TOC size is 32K, the erase block is
67 // 4K, the page size is 4K.
68 // It also assumes the TOC is at the 'end of pnor - toc size - 1 page size'
69 // offset, and first looks for the TOC here, before proceeding to move up
70 // page by page looking for the TOC. So it is optimal to place the TOC at
71 // this offset.
72 constexpr size_t eraseSize = 0x1000;
73 constexpr size_t pageSize = 0x1000;
74 constexpr size_t pnorSize = 0x4000000;
75 constexpr size_t tocMaxSize = 0x8000;
76 constexpr size_t tocStart = pnorSize - tocMaxSize - pageSize;
77 constexpr auto blPartitionName = "HBB";
78
79 openpower::virtual_pnor::partition::Table blTable(eraseSize, pnorSize);
80 vpnor_partition_table vtbl{};
81 vtbl.table = &blTable;
82 struct mbox_context local{};
83 local.vpnor = &vtbl;
84 local.block_size_shift = log_2(eraseSize);
85 memcpy(&local.paths, &context->paths, sizeof(local.paths));
86
87 size_t tocOffset = 0;
Deepak Kodihalli7ee307c2017-07-12 03:41:08 -050088 uint32_t tocSize = blTable.size() * eraseSize;
Deepak Kodihalli017e45c2017-07-12 01:06:30 -050089 // Copy TOC
90 copy_flash(&local, tocOffset,
91 static_cast<uint8_t*>(context->mem) + tocStart,
Deepak Kodihalli7ee307c2017-07-12 03:41:08 -050092 tocSize);
Deepak Kodihalli017e45c2017-07-12 01:06:30 -050093 const pnor_partition& partition = blTable.partition(blPartitionName);
94 size_t hbbOffset = partition.data.base * eraseSize;
Deepak Kodihalli7ee307c2017-07-12 03:41:08 -050095 uint32_t hbbSize = partition.data.actual;
Deepak Kodihalli017e45c2017-07-12 01:06:30 -050096 // Copy HBB
97 copy_flash(&local, hbbOffset,
98 static_cast<uint8_t*>(context->mem) + hbbOffset, hbbSize);
99}
100
Deepak Kodihallib6a446f2017-04-29 13:01:49 -0500101void vpnor_destroy_partition_table(struct mbox_context *context)
102{
103 if(context && context->vpnor)
104 {
105 delete context->vpnor->table;
106 delete context->vpnor;
107 context->vpnor = nullptr;
108 }
109}