forked from MatiasBjorling/flashsim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ssd_ftl.cpp
154 lines (116 loc) · 3.87 KB
/
ssd_ftl.cpp
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* Copyright 2009, 2010 Brendan Tauras */
/* ssd_ftl.cpp is part of FlashSim. */
/* FlashSim is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version. */
/* FlashSim is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License
* along with FlashSim. If not, see <http://www.gnu.org/licenses/>. */
/****************************************************************************/
/* Ftl class
* Brendan Tauras 2009-11-04
*
* This class is a stub class for the user to use as a template for implementing
* his/her FTL scheme. A few functions to gather information from lower-level
* hardware are added to assist writing a FTL scheme. The Ftl class should
* rely on the Garbage_collector and Wear_leveler classes for modularity and
* simplicity. */
#include <new>
#include <assert.h>
#include <stdio.h>
#include <math.h>
#include "ssd.h"
using namespace ssd;
Ftl::Ftl(Controller &controller):
controller(controller),
garbage(*this),
wear(*this)
{
currentPage = 0;
uint numCells = SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE * BLOCK_SIZE;
map = new long[numCells];
for (int i=0;i<numCells;i++)
map[i] = -1;
return;
}
Ftl::~Ftl(void)
{
delete map;
return;
}
enum status Ftl::read(Event &event)
{
if (map[event.get_logical_address()] == -1)
{
fprintf(stderr, "Page not written! Logical Address: %i\n", event.get_logical_address());
return FAILURE;
}
// Lookup mapping
event.set_address(resolve_logical_address(map[event.get_logical_address()]));
page_state s = controller.get_state(event.get_address());
fprintf(stderr, "CP: %u LP: %u\n", map[event.get_logical_address()], event.get_logical_address());
if (s == VALID)
{
controller.issue(event);
}
else
{
fprintf(stderr, "Page warning: Not able to read page as it has not been written or is invalid.");
return FAILURE;
}
return SUCCESS;
}
enum status Ftl::write(Event &event)
{
Address address = resolve_logical_address(currentPage);
// Physical address of I/O.
event.set_address(address);
// Update mappings
map[event.get_logical_address()] = currentPage;
fprintf(stderr, "CP: %u LP: %u\n", map[event.get_logical_address()], event.get_logical_address());
currentPage++;
controller.issue(event);
return SUCCESS;
}
inline Address Ftl::resolve_logical_address(uint logicalAddress)
{
uint numCells = SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE * BLOCK_SIZE;
Address phyAddress;
phyAddress.package = floor(logicalAddress / (numCells / SSD_SIZE));
phyAddress.die = floor(logicalAddress / (numCells / SSD_SIZE / PACKAGE_SIZE));
phyAddress.plane = floor(logicalAddress / (numCells / SSD_SIZE / PACKAGE_SIZE / DIE_SIZE));
phyAddress.block = floor(logicalAddress / (numCells / SSD_SIZE / PACKAGE_SIZE / DIE_SIZE / PLANE_SIZE));
phyAddress.page = logicalAddress % BLOCK_SIZE;
phyAddress.valid = PAGE;
fprintf(stderr, "numCells: %i package: %i die: %i plane: %i block: %i page: %i\n", numCells, phyAddress.package, phyAddress.die, phyAddress.plane, phyAddress.block, phyAddress.page);
return phyAddress;
}
enum status Ftl::erase(Event &event)
{
return SUCCESS;
}
enum status Ftl::merge(Event &event)
{
return SUCCESS;
}
void Ftl::garbage_collect(Event &event)
{
(void) garbage.collect(event);
}
ssd::ulong Ftl::get_erases_remaining(const Address &address) const
{
return controller.get_erases_remaining(address);
}
void Ftl::get_least_worn(Address &address) const
{
controller.get_least_worn(address);
return;
}
enum page_state Ftl::get_state(const Address &address) const
{
return controller.get_state(address);
}