xref: /aosp_15_r20/external/cpuinfo/src/linux/mockfile.c (revision 2b54f0db79fd8303838913b20ff3780cddaa909f)
1*2b54f0dbSXin Li #include <stdbool.h>
2*2b54f0dbSXin Li #include <stdint.h>
3*2b54f0dbSXin Li #include <stdlib.h>
4*2b54f0dbSXin Li #include <stddef.h>
5*2b54f0dbSXin Li #include <string.h>
6*2b54f0dbSXin Li #include <errno.h>
7*2b54f0dbSXin Li 
8*2b54f0dbSXin Li #include <sys/types.h>
9*2b54f0dbSXin Li #include <sys/stat.h>
10*2b54f0dbSXin Li #include <unistd.h>
11*2b54f0dbSXin Li #include <fcntl.h>
12*2b54f0dbSXin Li #include <sched.h>
13*2b54f0dbSXin Li 
14*2b54f0dbSXin Li #if !CPUINFO_MOCK
15*2b54f0dbSXin Li 	#error This file should be built only in mock mode
16*2b54f0dbSXin Li #endif
17*2b54f0dbSXin Li 
18*2b54f0dbSXin Li #include <cpuinfo-mock.h>
19*2b54f0dbSXin Li #include <arm/linux/api.h>
20*2b54f0dbSXin Li #include <arm/midr.h>
21*2b54f0dbSXin Li #include <cpuinfo/log.h>
22*2b54f0dbSXin Li 
23*2b54f0dbSXin Li 
24*2b54f0dbSXin Li static struct cpuinfo_mock_file* cpuinfo_mock_files = NULL;
25*2b54f0dbSXin Li static uint32_t cpuinfo_mock_file_count = 0;
26*2b54f0dbSXin Li 
27*2b54f0dbSXin Li 
cpuinfo_mock_filesystem(struct cpuinfo_mock_file * files)28*2b54f0dbSXin Li void CPUINFO_ABI cpuinfo_mock_filesystem(struct cpuinfo_mock_file* files) {
29*2b54f0dbSXin Li 	cpuinfo_log_info("filesystem mocking enabled");
30*2b54f0dbSXin Li 	uint32_t file_count = 0;
31*2b54f0dbSXin Li 	while (files[file_count].path != NULL) {
32*2b54f0dbSXin Li 		/* Indicate that file is not opened */
33*2b54f0dbSXin Li 		files[file_count].offset = SIZE_MAX;
34*2b54f0dbSXin Li 		file_count += 1;
35*2b54f0dbSXin Li 	}
36*2b54f0dbSXin Li 	cpuinfo_mock_files = files;
37*2b54f0dbSXin Li 	cpuinfo_mock_file_count = file_count;
38*2b54f0dbSXin Li }
39*2b54f0dbSXin Li 
cpuinfo_mock_open(const char * path,int oflag)40*2b54f0dbSXin Li int CPUINFO_ABI cpuinfo_mock_open(const char* path, int oflag) {
41*2b54f0dbSXin Li 	if (cpuinfo_mock_files == NULL) {
42*2b54f0dbSXin Li 		cpuinfo_log_warning("cpuinfo_mock_open called without mock filesystem; redictering to open");
43*2b54f0dbSXin Li 		return open(path, oflag);
44*2b54f0dbSXin Li 	}
45*2b54f0dbSXin Li 
46*2b54f0dbSXin Li 	for (uint32_t i = 0; i < cpuinfo_mock_file_count; i++) {
47*2b54f0dbSXin Li 		if (strcmp(cpuinfo_mock_files[i].path, path) == 0) {
48*2b54f0dbSXin Li 			if (oflag != O_RDONLY) {
49*2b54f0dbSXin Li 				errno = EACCES;
50*2b54f0dbSXin Li 				return -1;
51*2b54f0dbSXin Li 			}
52*2b54f0dbSXin Li 			if (cpuinfo_mock_files[i].offset != SIZE_MAX) {
53*2b54f0dbSXin Li 				errno = ENFILE;
54*2b54f0dbSXin Li 				return -1;
55*2b54f0dbSXin Li 			}
56*2b54f0dbSXin Li 			cpuinfo_mock_files[i].offset = 0;
57*2b54f0dbSXin Li 			return (int) i;
58*2b54f0dbSXin Li 		}
59*2b54f0dbSXin Li 	}
60*2b54f0dbSXin Li 	errno = ENOENT;
61*2b54f0dbSXin Li 	return -1;
62*2b54f0dbSXin Li }
63*2b54f0dbSXin Li 
cpuinfo_mock_close(int fd)64*2b54f0dbSXin Li int CPUINFO_ABI cpuinfo_mock_close(int fd) {
65*2b54f0dbSXin Li 	if (cpuinfo_mock_files == NULL) {
66*2b54f0dbSXin Li 		cpuinfo_log_warning("cpuinfo_mock_close called without mock filesystem; redictering to close");
67*2b54f0dbSXin Li 		return close(fd);
68*2b54f0dbSXin Li 	}
69*2b54f0dbSXin Li 
70*2b54f0dbSXin Li 	if ((unsigned int) fd >= cpuinfo_mock_file_count) {
71*2b54f0dbSXin Li 		errno = EBADF;
72*2b54f0dbSXin Li 		return -1;
73*2b54f0dbSXin Li 	}
74*2b54f0dbSXin Li 	if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
75*2b54f0dbSXin Li 		errno = EBADF;
76*2b54f0dbSXin Li 		return -1;
77*2b54f0dbSXin Li 	}
78*2b54f0dbSXin Li 	cpuinfo_mock_files[fd].offset = SIZE_MAX;
79*2b54f0dbSXin Li 	return 0;
80*2b54f0dbSXin Li }
81*2b54f0dbSXin Li 
cpuinfo_mock_read(int fd,void * buffer,size_t capacity)82*2b54f0dbSXin Li ssize_t CPUINFO_ABI cpuinfo_mock_read(int fd, void* buffer, size_t capacity) {
83*2b54f0dbSXin Li 	if (cpuinfo_mock_files == NULL) {
84*2b54f0dbSXin Li 		cpuinfo_log_warning("cpuinfo_mock_read called without mock filesystem; redictering to read");
85*2b54f0dbSXin Li 		return read(fd, buffer, capacity);
86*2b54f0dbSXin Li 	}
87*2b54f0dbSXin Li 
88*2b54f0dbSXin Li 	if ((unsigned int) fd >= cpuinfo_mock_file_count) {
89*2b54f0dbSXin Li 		errno = EBADF;
90*2b54f0dbSXin Li 		return -1;
91*2b54f0dbSXin Li 	}
92*2b54f0dbSXin Li 	if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
93*2b54f0dbSXin Li 		errno = EBADF;
94*2b54f0dbSXin Li 		return -1;
95*2b54f0dbSXin Li 	}
96*2b54f0dbSXin Li 
97*2b54f0dbSXin Li 	const size_t offset = cpuinfo_mock_files[fd].offset;
98*2b54f0dbSXin Li 	size_t count = cpuinfo_mock_files[fd].size - offset;
99*2b54f0dbSXin Li 	if (count > capacity) {
100*2b54f0dbSXin Li 		count = capacity;
101*2b54f0dbSXin Li 	}
102*2b54f0dbSXin Li 	memcpy(buffer, (void*) cpuinfo_mock_files[fd].content + offset, count);
103*2b54f0dbSXin Li 	cpuinfo_mock_files[fd].offset += count;
104*2b54f0dbSXin Li 	return (ssize_t) count;
105*2b54f0dbSXin Li }
106