aboutsummaryrefslogtreecommitdiff
path: root/components/config/ramstore/config_ramstore.c
blob: 2e246454797cc8321e56bf66f5c5061eb90c5738 (plain)
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
/*
 * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "config_ramstore.h"
#include <config/interface/platform_config.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

/**
 * Variable length container for a configuration object.
 */
struct config_container
{
	size_t size;
	struct config_container *next;
};

static struct config_container *config_container_create(const void *data, size_t size)
{
	struct config_container *container = malloc(sizeof(struct config_container) + size);

	if (container) {

		container->size = size;
		container->next = NULL;

		memcpy((uint8_t*)container + sizeof(struct config_container), data, size);
	}

	return container;
}

static void config_container_destroy(struct config_container *container)
{
	free(container);
}

static const void *config_container_data(const struct config_container *container)
{
	return (const uint8_t*)container + sizeof(struct config_container);
}

/**
 * Singleton config_ramstore instance
 */
static struct config_ramstore
{
	struct config_container *device_region_list;
} ramstore = {0};


void config_ramstore_init(void)
{
	ramstore.device_region_list = NULL;
}

void config_ramstore_deinit(void)
{
	while (ramstore.device_region_list) {

		struct config_container *next = ramstore.device_region_list->next;
		free(ramstore.device_region_list);
		ramstore.device_region_list = next;
	}
}

int platform_config_device_add(const struct device_region *device_region)
{
	struct config_container *container;

	container = config_container_create(device_region, sizeof(struct device_region));
	if (!container) return -1;

	container->next = ramstore.device_region_list;
	ramstore.device_region_list = container;

	return 0;
}

struct device_region *platform_config_device_query(const char *dev_class,
                                                    int dev_instance)
{
	struct device_region *result = NULL;
	const struct config_container *container = ramstore.device_region_list;

	while (container) {

		const struct device_region *candidate;
		candidate = (const struct device_region*)config_container_data(container);

		if ((candidate->dev_instance == dev_instance) &&
			(strcmp(candidate->dev_class, dev_class) == 0)) {

			result = malloc(container->size);
			if (result) {

				memcpy(result, candidate, container->size);
			}

			break;
		}

		container = container->next;
	}

	return result;
}

void platform_config_device_query_free(struct device_region *device_region)
{
	free(device_region);
}

unsigned int platform_config_device_region_count(void)
{
	unsigned int count = 0;

	const struct config_container *container = ramstore.device_region_list;

	while (container) {

		++count;
		container = container->next;
	}

	return count;
}