Skip to content

Commit 4388b39

Browse files
util/cbmem: add option to read CBMEM from file instead of RAM
Signed-off-by: Krystian Hebel <[email protected]> Change-Id: I273e1eed320b3d99a57ae5b361b79238f40cf825
1 parent 28df006 commit 4388b39

File tree

1 file changed

+99
-42
lines changed

1 file changed

+99
-42
lines changed

util/cbmem/cbmem.c

Lines changed: 99 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,20 @@ static int verbose = 0;
5858
#define debug(x...) if(verbose) printf(x)
5959

6060
/* File handle used to access /dev/mem */
61-
static int mem_fd;
61+
static int mem_fd = -1;
6262
static struct mapping lbtable_mapping;
6363

64+
/* File handle used to parse CBMEM from file instead of RAM */
65+
static int file_fd = -1;
66+
6467
/* TSC frequency from the LB_TAG_TSC_INFO record. 0 if not present. */
6568
static uint32_t tsc_freq_khz = 0;
6669

70+
static struct lb_cbmem_ref timestamps;
71+
static struct lb_cbmem_ref console;
72+
static struct lb_cbmem_ref tcpa_log;
73+
static struct lb_memory_range cbmem;
74+
6775
static void die(const char *msg)
6876
{
6977
if (msg)
@@ -101,40 +109,74 @@ static void *mapping_virt(const struct mapping *mapping)
101109
static void *map_memory_with_prot(struct mapping *mapping,
102110
unsigned long long phys, size_t sz, int prot)
103111
{
104-
void *v;
105-
unsigned long long page_size;
112+
if (file_fd < 0) {
113+
void *v;
114+
unsigned long long page_size;
106115

107-
page_size = system_page_size();
116+
page_size = system_page_size();
108117

109-
mapping->virt = NULL;
110-
mapping->offset = phys % page_size;
111-
mapping->virt_size = sz + mapping->offset;
112-
mapping->size = sz;
113-
mapping->phys = phys;
114-
115-
if (size_to_mib(mapping->virt_size) == 0) {
116-
debug("Mapping %zuB of physical memory at 0x%llx (requested 0x%llx).\n",
117-
mapping->virt_size, phys - mapping->offset, phys);
118-
} else {
119-
debug("Mapping %zuMB of physical memory at 0x%llx (requested 0x%llx).\n",
120-
size_to_mib(mapping->virt_size), phys - mapping->offset,
121-
phys);
122-
}
118+
mapping->virt = NULL;
119+
mapping->offset = phys % page_size;
120+
mapping->virt_size = sz + mapping->offset;
121+
mapping->size = sz;
122+
mapping->phys = phys;
123123

124-
v = mmap(NULL, mapping->virt_size, prot, MAP_SHARED, mem_fd,
125-
phys - mapping->offset);
124+
if (size_to_mib(mapping->virt_size) == 0) {
125+
debug("Mapping %zuB of physical memory at 0x%llx (requested 0x%llx).\n",
126+
mapping->virt_size, phys - mapping->offset, phys);
127+
} else {
128+
debug("Mapping %zuMB of physical memory at 0x%llx (requested 0x%llx).\n",
129+
size_to_mib(mapping->virt_size), phys - mapping->offset,
130+
phys);
131+
}
126132

127-
if (v == MAP_FAILED) {
128-
debug("Mapping failed %zuB of physical memory at 0x%llx.\n",
129-
mapping->virt_size, phys - mapping->offset);
130-
return NULL;
131-
}
133+
v = mmap(NULL, mapping->virt_size, prot, MAP_SHARED, mem_fd,
134+
phys - mapping->offset);
135+
136+
if (v == MAP_FAILED) {
137+
debug("Mapping failed %zuB of physical memory at 0x%llx.\n",
138+
mapping->virt_size, phys - mapping->offset);
139+
return NULL;
140+
}
141+
142+
mapping->virt = v;
143+
144+
if (mapping->offset != 0)
145+
debug(" ... padding virtual address with 0x%zx bytes.\n",
146+
mapping->offset);
147+
} else {
148+
ssize_t ret;
149+
mapping->virt = malloc(sz);
150+
mapping->offset = 0;
151+
mapping->virt_size = sz;
152+
mapping->size = sz;
153+
mapping->phys = phys;
154+
155+
debug("map_memory phys = %llx, size = %zuB, cbmem.start = %lx\n", phys, sz, cbmem.start);
156+
157+
if (mapping->virt == NULL) {
158+
debug("Couldn't allocate %zuB of memory.\n", sz);
159+
return NULL;
160+
}
132161

133-
mapping->virt = v;
162+
if (lseek(file_fd, mapping->phys - cbmem.start, SEEK_SET) < 0) {
163+
debug("Couldn't read file from offset %llx.\n",
164+
mapping->phys - cbmem.start);
165+
free(mapping->virt);
166+
return NULL;
167+
}
134168

135-
if (mapping->offset != 0)
136-
debug(" ... padding virtual address with 0x%zx bytes.\n",
137-
mapping->offset);
169+
ret = read(file_fd, mapping->virt, sz);
170+
if (ret < 0) {
171+
debug("Error reading file: %s\n", strerror(errno));
172+
free(mapping->virt);
173+
return NULL;
174+
}
175+
if ((size_t)ret != sz) {
176+
debug("Truncated read from offset %llx, requested %zuB, got %zuB.\n",
177+
mapping->phys - cbmem.start, sz, ret);
178+
}
179+
}
138180

139181
return mapping_virt(mapping);
140182
}
@@ -153,7 +195,11 @@ static int unmap_memory(struct mapping *mapping)
153195
if (mapping->virt == NULL)
154196
return -1;
155197

156-
munmap(mapping->virt, mapping->virt_size);
198+
if (file_fd < 0)
199+
munmap(mapping->virt, mapping->virt_size);
200+
else
201+
free(mapping->virt);
202+
157203
mapping->virt = NULL;
158204
mapping->offset = 0;
159205
mapping->virt_size = 0;
@@ -265,11 +311,6 @@ static int find_cbmem_entry(uint32_t id, uint64_t *addr, size_t *size)
265311
* none found.
266312
*/
267313

268-
static struct lb_cbmem_ref timestamps;
269-
static struct lb_cbmem_ref console;
270-
static struct lb_cbmem_ref tcpa_log;
271-
static struct lb_memory_range cbmem;
272-
273314
/* This is a work-around for a nasty problem introduced by initially having
274315
* pointer sized entries in the lb_cbmem_ref structures. This caused problems
275316
* on 64bit x86 systems because coreboot is 32bit on those systems.
@@ -1340,6 +1381,7 @@ static void print_usage(const char *name, int exit_code)
13401381
" -S | --stacked-timestamps: print stacked timestamps (e.g. for flame graph tools)\n"
13411382
" -a | --add-timestamp ID: append timestamp with ID\n"
13421383
" -L | --tcpa-log print TCPA log\n"
1384+
" -f | --file FILE: read CBMEM from FILE instead of memory\n"
13431385
" -V | --verbose: verbose (debugging) output\n"
13441386
" -v | --version: print the version\n"
13451387
" -h | --help: print this help\n"
@@ -1493,12 +1535,13 @@ int main(int argc, char** argv)
14931535
{"add-timestamp", required_argument, 0, 'a'},
14941536
{"hexdump", 0, 0, 'x'},
14951537
{"rawdump", required_argument, 0, 'r'},
1538+
{"file", required_argument, 0, 'f'},
14961539
{"verbose", 0, 0, 'V'},
14971540
{"version", 0, 0, 'v'},
14981541
{"help", 0, 0, 'h'},
14991542
{0, 0, 0, 0}
15001543
};
1501-
while ((opt = getopt_long(argc, argv, "c12B:CltTSa:LxVvh?r:",
1544+
while ((opt = getopt_long(argc, argv, "c12B:CltTSa:LxVvh?r:f:",
15021545
long_options, &option_index)) != EOF) {
15031546
switch (opt) {
15041547
case 'c':
@@ -1539,6 +1582,14 @@ int main(int argc, char** argv)
15391582
print_defaults = 0;
15401583
rawdump_id = strtoul(optarg, NULL, 16);
15411584
break;
1585+
case 'f':
1586+
file_fd = open(optarg, O_RDONLY, 0);
1587+
if (file_fd < 0) {
1588+
fprintf(stderr, "Failed to open file '%s': %s\n",
1589+
optarg, strerror(errno));
1590+
return 1;
1591+
}
1592+
break;
15421593
case 't':
15431594
timestamp_type = TIMESTAMPS_PRINT_NORMAL;
15441595
print_defaults = 0;
@@ -1580,11 +1631,13 @@ int main(int argc, char** argv)
15801631
print_usage(argv[0], 1);
15811632
}
15821633

1583-
mem_fd = open("/dev/mem", timestamp_id ? O_RDWR : O_RDONLY, 0);
1584-
if (mem_fd < 0) {
1585-
fprintf(stderr, "Failed to gain memory access: %s\n",
1586-
strerror(errno));
1587-
return 1;
1634+
if (file_fd < 0) {
1635+
mem_fd = open("/dev/mem", timestamp_id ? O_RDWR : O_RDONLY, 0);
1636+
if (mem_fd < 0) {
1637+
fprintf(stderr, "Failed to gain memory access: %s\n",
1638+
strerror(errno));
1639+
return 1;
1640+
}
15881641
}
15891642

15901643
#if defined(__arm__) || defined(__aarch64__)
@@ -1681,6 +1734,10 @@ int main(int argc, char** argv)
16811734

16821735
unmap_memory(&lbtable_mapping);
16831736

1684-
close(mem_fd);
1737+
if (file_fd >= 0)
1738+
close(file_fd);
1739+
if (mem_fd >= 0)
1740+
close(mem_fd);
1741+
16851742
return 0;
16861743
}

0 commit comments

Comments
 (0)