blob: 2de790be0724598ca8e6bec7cc93f85f5cedc3e9 [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"
Deepak Kodihalli64ec3e42017-07-17 06:15:16 -05006#include "config.h"
Ratan Gupta3214b512017-05-11 08:58:19 +05307#include <experimental/filesystem>
Deepak Kodihallib6a446f2017-04-29 13:01:49 -05008
9struct vpnor_partition_table
10{
11 openpower::virtual_pnor::partition::Table* table = nullptr;
12};
13
Deepak Kodihalli64ec3e42017-07-17 06:15:16 -050014void init_vpnor(struct mbox_context *context)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050015{
Ratan Gupta3214b512017-05-11 08:58:19 +053016 if (context && !context->vpnor)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050017 {
Deepak Kodihalli64ec3e42017-07-17 06:15:16 -050018 strcpy(context->paths.ro_loc, PARTITION_FILES_RO_LOC);
19 strcpy(context->paths.rw_loc, PARTITION_FILES_RW_LOC);
20 strcpy(context->paths.prsv_loc, PARTITION_FILES_PRSV_LOC);
21
Ratan Gupta3214b512017-05-11 08:58:19 +053022 context->vpnor = new vpnor_partition_table;
23 context->vpnor->table =
Deepak Kodihallid1d79302017-07-11 23:01:39 -050024 new openpower::virtual_pnor::partition::Table(
25 1 << context->erase_size_shift,
26 context->flash_size);
Ratan Gupta3214b512017-05-11 08:58:19 +053027 }
28}
29
30void vpnor_create_partition_table_from_path(struct mbox_context *context,
31 const char *path)
32{
33 std::experimental::filesystem::path dir(path);
34
35 if (context && !context->vpnor)
36 {
37 context->vpnor = new vpnor_partition_table;
38 context->vpnor->table =
Deepak Kodihallid1d79302017-07-11 23:01:39 -050039 new openpower::virtual_pnor::partition::Table(
40 std::move(dir),
41 1 << context->erase_size_shift,
42 context->flash_size);
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050043 }
44}
45
46size_t vpnor_get_partition_table_size(const struct mbox_context *context)
47{
48 return context && context->vpnor ?
49 context->vpnor->table->size() : 0;
50}
51
52const struct pnor_partition_table* vpnor_get_partition_table(
53 const struct mbox_context *context)
54{
55 return context && context->vpnor ?
56 &(context->vpnor->table->getHostTable()) : nullptr;
57}
58
59const struct pnor_partition* vpnor_get_partition(
60 const struct mbox_context *context,
61 const size_t offset)
62{
63 return context && context->vpnor ?
64 &(context->vpnor->table->partition(offset)) : nullptr;
65}
66
Deepak Kodihalli017e45c2017-07-12 01:06:30 -050067void vpnor_copy_bootloader_partition(const struct mbox_context *context)
68{
69 // The hostboot bootloader has certain size/offset assumptions, so
70 // we need a special partition table here.
71 // It assumes the PNOR is 64M, the TOC size is 32K, the erase block is
72 // 4K, the page size is 4K.
73 // It also assumes the TOC is at the 'end of pnor - toc size - 1 page size'
74 // offset, and first looks for the TOC here, before proceeding to move up
75 // page by page looking for the TOC. So it is optimal to place the TOC at
76 // this offset.
77 constexpr size_t eraseSize = 0x1000;
78 constexpr size_t pageSize = 0x1000;
79 constexpr size_t pnorSize = 0x4000000;
80 constexpr size_t tocMaxSize = 0x8000;
81 constexpr size_t tocStart = pnorSize - tocMaxSize - pageSize;
82 constexpr auto blPartitionName = "HBB";
83
84 openpower::virtual_pnor::partition::Table blTable(eraseSize, pnorSize);
85 vpnor_partition_table vtbl{};
86 vtbl.table = &blTable;
87 struct mbox_context local{};
88 local.vpnor = &vtbl;
89 local.block_size_shift = log_2(eraseSize);
90 memcpy(&local.paths, &context->paths, sizeof(local.paths));
91
92 size_t tocOffset = 0;
Deepak Kodihalli7ee307c2017-07-12 03:41:08 -050093 uint32_t tocSize = blTable.size() * eraseSize;
Deepak Kodihalli017e45c2017-07-12 01:06:30 -050094 // Copy TOC
95 copy_flash(&local, tocOffset,
96 static_cast<uint8_t*>(context->mem) + tocStart,
Deepak Kodihalli7ee307c2017-07-12 03:41:08 -050097 tocSize);
Deepak Kodihalli017e45c2017-07-12 01:06:30 -050098 const pnor_partition& partition = blTable.partition(blPartitionName);
99 size_t hbbOffset = partition.data.base * eraseSize;
Deepak Kodihalli7ee307c2017-07-12 03:41:08 -0500100 uint32_t hbbSize = partition.data.actual;
Deepak Kodihalli017e45c2017-07-12 01:06:30 -0500101 // Copy HBB
102 copy_flash(&local, hbbOffset,
103 static_cast<uint8_t*>(context->mem) + hbbOffset, hbbSize);
104}
105
Deepak Kodihalli64ec3e42017-07-17 06:15:16 -0500106void destroy_vpnor(struct mbox_context *context)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -0500107{
108 if(context && context->vpnor)
109 {
110 delete context->vpnor->table;
111 delete context->vpnor;
112 context->vpnor = nullptr;
113 }
114}