summaryrefslogtreecommitdiff
path: root/lib/sbi/sbi_platform.c
blob: 1912512fee9bcfa1223c6a5b217927e0374db73e (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
/*
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2020 Western Digital Corporation or its affiliates.
 *
 * Authors:
 *   Atish Patra <atish.patra@wdc.com>
 */

#include <sbi/sbi_console.h>
#include <sbi/sbi_platform.h>
#include <sbi/sbi_string.h>

static inline char *sbi_platform_feature_id2string(unsigned long feature)
{
	char *fstr = NULL;

	if (!feature)
		return NULL;

	switch (feature) {
	case SBI_PLATFORM_HAS_TIMER_VALUE:
		fstr = "timer";
		break;
	case SBI_PLATFORM_HAS_HART_HOTPLUG:
		fstr = "hotplug";
		break;
	case SBI_PLATFORM_HAS_MFAULTS_DELEGATION:
		fstr = "mfdeleg";
		break;
	case SBI_PLATFORM_HAS_HART_SECONDARY_BOOT:
		fstr = "sec_boot";
		break;
	default:
		break;
	}

	return fstr;
}

/**
 * Get the platform features in string format
 *
 * @param plat pointer to struct sbi_platform
 * @param features_str pointer to a char array where the features string will be
 *		       updated
 * @param nfstr length of the features_str. The feature string will be truncated
 *		if nfstr is not long enough.
 * @return the features value currently set for the given platform
 */
int sbi_platform_get_features_str(const struct sbi_platform *plat,
						char *features_str, int nfstr)
{
	unsigned long features, feat = 1UL;
	char *temp;
	int offset = 0;

	if (!plat || !features_str || !nfstr)
		return SBI_EINVAL;

	features = sbi_platform_get_features(plat);

	do {
		if (features & feat) {
			temp = sbi_platform_feature_id2string(feat);
			if (temp) {
				sbi_snprintf(features_str + offset, nfstr,
					     "%s,", temp);
				offset = offset + sbi_strlen(temp) + 1;
			}
		}
		feat = feat << 1;
	} while (feat <= SBI_PLATFORM_HAS_LAST_FEATURE);

	features_str[offset - 1] = '\0';

	return 0;
}

/**
 * Get HART index for the given HART
 *
 * @param plat pointer to struct sbi_platform
 * @param hartid HART ID
 *
 * @return 0 <= value < hart_count for valid HART otherwise -1U
 */
u32 sbi_platform_hart_index(const struct sbi_platform *plat,
					  u32 hartid)
{
	u32 i;

	if (!plat)
		return -1U;
	if (plat->hart_index2id) {
		for (i = 0; i < plat->hart_count; i++) {
			if (plat->hart_index2id[i] == hartid)
				return i;
		}
		return -1U;
	}

	return hartid;
}