forked from ClydeProjects/EagleTree
-
Notifications
You must be signed in to change notification settings - Fork 0
/
address.cpp
96 lines (87 loc) · 2.27 KB
/
address.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
#include <stdio.h>
#include "ssd.h"
using namespace ssd;
Address::Address():
package(0),
die(0),
plane(0),
block(0),
page(0),
valid(NONE)
{}
/* see "enum address_valid" in ssd.h for details on valid status */
Address::Address(uint package, uint die, uint plane, uint block, uint page, enum address_valid valid):
package(package),
die(die),
plane(plane),
block(block),
page(page),
valid(valid)
{
return;
}
Address::Address(uint address, enum address_valid valid):
valid(valid)
{
set_linear_address(address);
}
/* returns enum indicating to what level two addresses match
* limits comparison to the fields that are valid */
enum address_valid Address::compare(const Address &address) const
{
enum address_valid match = NONE;
if(package == address.package && valid >= PACKAGE && address.valid >= PACKAGE)
{
match = PACKAGE;
if(die == address.die && valid >= DIE && address.valid >= DIE)
{
match = DIE;
if(plane == address.plane && valid >= PLANE && address.valid >= PLANE)
{
match = PLANE;
if(block == address.block && valid >= BLOCK && address.valid >= BLOCK)
{
match = BLOCK;
if(page == address.page && valid >= PAGE && address.valid >= PAGE)
{
match = PAGE;
}
}
}
}
}
return match;
}
/* default stream is stdout */
void Address::print(FILE *stream) const
{
fprintf(stream, "(%d, %d, %d, %d, %d, %d)", package, die, plane, block, page, (int) valid);
}
void Address::set_linear_address(ulong address)
{
page = address % BLOCK_SIZE;
address /= BLOCK_SIZE;
block = address % PLANE_SIZE;
address /= PLANE_SIZE;
plane = address % DIE_SIZE;
address /= DIE_SIZE;
die = address % PACKAGE_SIZE;
address /= PACKAGE_SIZE;
package = address % SSD_SIZE;
address /= SSD_SIZE;
}
void Address::set_linear_address(ulong address, enum address_valid valid)
{
set_linear_address(address);
this->valid = valid;
}
unsigned long Address::get_linear_address() const
{
unsigned long address = 0;
if (valid == PAGE) address += page;
if (valid >= BLOCK) address += BLOCK_SIZE * block;
if (valid >= PLANE) address += BLOCK_SIZE * PLANE_SIZE * plane;
if (valid >= DIE) address += BLOCK_SIZE * PLANE_SIZE * DIE_SIZE * die;
if (valid >= PACKAGE) address += BLOCK_SIZE * PLANE_SIZE * DIE_SIZE * PACKAGE_SIZE * package;
return address;
}