aboutsummaryrefslogtreecommitdiff
path: root/components/config/ramstore/config_ramstore.c
blob: 548ba4b02d6cd035a7438c48044c4c1a632fb667 (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
/*
 * 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);
}