Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/firecracker
Path: blob/main/tests/host_tools/change_net_config_space.c
1956 views
1
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
// SPDX-License-Identifier: Apache-2.0
3
4
// This is used by the `test_net_config_space.py` integration test, which writes
5
// into the microVM configured network device config space a new MAC address.
6
7
#include <fcntl.h>
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <stdint.h>
11
#include <sys/mman.h>
12
#include <sys/types.h>
13
#include <sys/stat.h>
14
#include <unistd.h>
15
16
int show_usage() {
17
printf("Usage: ./change_net_config_space.bin [dev_addr_start] [mac_addr]\n");
18
printf("Example:\n");
19
printf("> ./change_net_config_space.bin 0xd00001000 0x060504030201\n");
20
return 0;
21
}
22
23
int main(int argc, char *argv[]) {
24
int fd, i, offset;
25
uint8_t *map_base;
26
volatile uint8_t *virt_addr;
27
28
uint64_t mapped_size, page_size, offset_in_page, target;
29
uint64_t width = 6;
30
31
uint64_t config_offset = 0x100;
32
uint64_t device_start_addr = 0x00000000;
33
uint64_t mac = 0;
34
35
if (argc != 3) {
36
return show_usage();
37
}
38
39
device_start_addr = strtoull(argv[1], NULL, 0);
40
mac = strtoull(argv[2], NULL, 0);
41
42
fd = open("/dev/mem", O_RDWR | O_SYNC);
43
if (fd < 0) {
44
perror("Failed to open '/dev/mem'.");
45
return 1;
46
}
47
48
target = device_start_addr + config_offset;
49
// Get the page size.
50
mapped_size = page_size = getpagesize();
51
// Get the target address physical frame page offset.
52
offset_in_page = (unsigned) target & (page_size - 1);
53
/* If the data length goes out of the current page,
54
* double the needed map size. */
55
if (offset_in_page + width > page_size) {
56
/* This access spans pages.
57
* Must map two pages to make it possible. */
58
mapped_size *= 2;
59
}
60
61
// Map the `/dev/mem` to virtual memory.
62
map_base = mmap(NULL,
63
mapped_size,
64
PROT_READ | PROT_WRITE,
65
MAP_SHARED,
66
fd,
67
target & ~(off_t)(page_size - 1));
68
if (map_base == MAP_FAILED) {
69
perror("Failed to mmap '/dev/mem'.");
70
return 2;
71
}
72
73
// Write in the network device config space a new MAC.
74
virt_addr = (volatile uint8_t*) (map_base + offset_in_page);
75
*virt_addr = (uint8_t) (mac >> 40);
76
printf("%02x", *virt_addr);
77
78
for (i = 1; i <= 5; i++) {
79
*(virt_addr + i) = (uint8_t) (mac >> (5 - i) * 8);
80
printf(":%02x", *(virt_addr + i));
81
}
82
83
// Deallocate resources.
84
munmap(map_base, mapped_size);
85
close(fd);
86
87
return 0;
88
}
89
90