From aab5ced6ec820b19c167b4ad23cc299b6966e93b Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Thu, 16 Apr 2020 10:02:40 +0530 Subject: qcom: pd-mapper: Syncup with upstream github project Syncup with https://github.com/andersson/pd-mapper upstream project up to commit: ab5074fdd5e4 ("pd-mapper: Use remoteproc firmware to find jsons") Signed-off-by: Amit Pundir Change-Id: I4ad3c07977c1e41a657c6c0479ad6dee9c154374 --- qcom/pd-mapper/Makefile | 2 + qcom/pd-mapper/assoc.c | 158 ++++++++++++++++ qcom/pd-mapper/assoc.h | 54 ++++++ qcom/pd-mapper/json.c | 451 +++++++++++++++++++++++++++++++++++++++++++++ qcom/pd-mapper/json.h | 67 +++++++ qcom/pd-mapper/pd-mapper.c | 203 +++++++++++++++++++- 6 files changed, 931 insertions(+), 4 deletions(-) create mode 100644 qcom/pd-mapper/assoc.c create mode 100644 qcom/pd-mapper/assoc.h create mode 100644 qcom/pd-mapper/json.c create mode 100644 qcom/pd-mapper/json.h (limited to 'qcom/pd-mapper') diff --git a/qcom/pd-mapper/Makefile b/qcom/pd-mapper/Makefile index ca58003..908dbfd 100644 --- a/qcom/pd-mapper/Makefile +++ b/qcom/pd-mapper/Makefile @@ -8,6 +8,8 @@ bindir := $(prefix)/bin servicedir := $(prefix)/lib/systemd/system SRCS := pd-mapper.c \ + assoc.c \ + json.c \ servreg_loc.c OBJS := $(SRCS:.c=.o) diff --git a/qcom/pd-mapper/assoc.c b/qcom/pd-mapper/assoc.c new file mode 100644 index 0000000..692c882 --- /dev/null +++ b/qcom/pd-mapper/assoc.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013, Bjorn Andersson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "assoc.h" + +static unsigned long assoc_hash(const char *value) +{ + unsigned long hash = 0; + unsigned long g; + const char *v = value; + + while (*v) { + hash = (hash << 4) + *(v++); + g = hash & 0xF0000000L; + if (g) + hash ^= g >> 24; + hash &= ~g; + } + + return hash; +} + +void assoc_init(struct assoc *assoc, unsigned long size) +{ + assert(size > 0); + + assoc->size = size; + assoc->fill = 0; + assoc->keys = calloc(size, sizeof(const char *)); + assoc->values = malloc(size * sizeof(void *)); +} + +void *assoc_get(struct assoc *assoc, const char *key) +{ + unsigned long hash; + + hash = assoc_hash(key) % assoc->size; + while (assoc->keys[hash]) { + if (!strcmp(assoc->keys[hash], key)) + return assoc->values[hash]; + + hash = (hash + 1) % assoc->size; + } + + return NULL; +} + +static void _assoc_set(struct assoc *assoc, const char *key, void *value) +{ + struct assoc new_set; + unsigned long hash; + unsigned long i; + + assert(assoc->fill < assoc->size); + + /* Grow set at 80% utilization */ + if (5 * assoc->fill > 4 * assoc->size) { + assoc_init(&new_set, assoc->size * 5 / 4); + + for (i = 0; i < assoc->size; i++) + if (assoc->keys[i]) + assoc_set(&new_set, assoc->keys[i], + assoc->values[i]); + + free(assoc->keys); + free(assoc->values); + + assoc->keys = new_set.keys; + assoc->values = new_set.values; + assoc->fill = new_set.fill; + assoc->size = new_set.size; + } + + hash = assoc_hash(key) % assoc->size; + while (assoc->keys[hash]) { + if (!strcmp(assoc->keys[hash], key)) { + assoc->values[hash] = value; + return; + } + + hash = (hash + 1) % assoc->size; + } + + assoc->keys[hash] = key; + assoc->values[hash] = value; + assoc->fill++; +} + +void assoc_set(struct assoc *assoc, const char *key, void *value) +{ + _assoc_set(assoc, strdup(key), value); +} + +const char *assoc_next(struct assoc *assoc, void **value, unsigned long *iter) +{ + unsigned long it = *iter; + + while (!assoc->keys[it] && it < assoc->size) + it++; + + if (it == assoc->size) + return NULL; + + *iter = it + 1; + + if (it < assoc->size) { + if (value) + *value = assoc->values[it]; + return assoc->keys[it]; + } else { + return NULL; + } +} + +void assoc_destroy(struct assoc *assoc) +{ + unsigned long i; + + for (i = 0; i < assoc->size; i++) + free((void*)assoc->keys[i]); + + free(assoc->keys); + free(assoc->values); + assoc->size = 0; +} diff --git a/qcom/pd-mapper/assoc.h b/qcom/pd-mapper/assoc.h new file mode 100644 index 0000000..25d00fa --- /dev/null +++ b/qcom/pd-mapper/assoc.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013, Bjorn Andersson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ASSOC_H__ +#define __ASSOC_H__ + +struct assoc { + unsigned long size; + unsigned long fill; + + const char **keys; + void **values; +}; + +void assoc_init(struct assoc *assoc, unsigned long size); +void *assoc_get(struct assoc *assoc, const char *key); +void assoc_set(struct assoc *assoc, const char *key, void *value); +const char *assoc_next(struct assoc *assoc, void **value, unsigned long *iter); +void assoc_destroy(struct assoc *assoc); + +#define assoc_foreach(key, value, assoc, iter) \ + for ((iter) = 0, (key) = assoc_next((assoc), (value), &(iter)); \ + (key); \ + (key) = assoc_next((assoc), (value), &(iter))) + +#endif diff --git a/qcom/pd-mapper/json.c b/qcom/pd-mapper/json.c new file mode 100644 index 0000000..e08afa4 --- /dev/null +++ b/qcom/pd-mapper/json.c @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2018-2019, Linaro Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "json.h" + +static const char *input_buf; +static int input_pos; +static int input_len; + +static int json_parse_array(struct json_value *array); +static int json_parse_object(struct json_value *object); +static int json_parse_property(struct json_value *value); + +static int input(void) +{ + if (input_pos >= input_len) + return 0; + + return input_buf[input_pos++]; +} + +static void unput(void) +{ + input_pos--; +} + +static void json_skip_whitespace(void) +{ + int ch; + + while ((ch = input()) && isspace(ch)) + ; + unput(); +} + +static int json_parse_string(struct json_value *value) +{ + char buf[128]; + char *b = buf; + int ch; + + ch = input(); + if (ch != '"') { + unput(); + return 0; + } + + while ((ch = input()) && ch != '"' && b - buf < sizeof(buf) - 1) + *b++ = ch; + *b = '\0'; + + if (!ch) + return -1; + + value->type = JSON_TYPE_STRING; + value->u.string = strdup(buf); + + return 1; +} + +static int json_parse_number(struct json_value *value) +{ + char buf[20]; + char *b = buf; + int ch; + + while ((ch = input()) && isdigit(ch) && b - buf < sizeof(buf) - 1) + *b++ = ch; + *b = '\0'; + unput(); + + if (b == buf) + return 0; + + value->type = JSON_TYPE_NUMBER; + value->u.number = strtod(buf, NULL); + + return 1; +} + +static int json_parse_keyword(struct json_value *value) +{ + const char *match; + const char *m; + int ch; + + ch = input(); + switch (ch) { + case 't': + match = "true"; + value->type = JSON_TYPE_TRUE; + break; + case 'f': + match = "false"; + value->type = JSON_TYPE_FALSE; + break; + case 'n': + match = "null"; + value->type = JSON_TYPE_NULL; + break; + default: + unput(); + return 0; + } + + m = match; + while (*m && *m++ == ch) + ch = input(); + unput(); + + return *m == '\0' ? 1 : -1; +} + +static int json_parse_value(struct json_value *value) +{ + int ret; + + json_skip_whitespace(); + + ret = json_parse_object(value); + if (ret) + goto out; + + ret = json_parse_array(value); + if (ret) + goto out; + + ret = json_parse_string(value); + if (ret) + goto out; + + ret = json_parse_number(value); + if (ret) + goto out; + + ret = json_parse_keyword(value); + if (ret) + goto out; + + fprintf(stderr, "unable to match a value\n"); + return -1; + +out: + json_skip_whitespace(); + return ret; +} + +static int json_parse_array(struct json_value *array) +{ + struct json_value *value; + struct json_value *last = NULL; + int ret; + int ch; + + ch = input(); + if (ch != '[') { + unput(); + return 0; + } + + array->type = JSON_TYPE_ARRAY; + do { + value = calloc(1, sizeof(*value)); + if (!value) + return -1; + + ret = json_parse_value(value); + if (ret <= 0) { + free(value); + return -1; + } + + if (!array->u.value) + array->u.value = value; + if (last) + last->next = value; + last = value; + + ch = input(); + if (ch == ']') { + return 1; + } + + } while (ch == ','); + + fprintf(stderr, "expected ',' got '%c'\n", ch); + + return -1; +} + +static int json_parse_object(struct json_value *object) +{ + struct json_value *value; + struct json_value *last = NULL; + int ret; + int ch; + + ch = input(); + if (ch != '{') { + unput(); + return 0; + } + + object->type = JSON_TYPE_OBJECT; + + do { + value = calloc(1, sizeof(*value)); + if (!value) + return -1; + + ret = json_parse_property(value); + if (ret <= 0) { + free(value); + return -1; + } + + if (!object->u.value) + object->u.value = value; + if (last) + last->next = value; + last = value; + + ch = input(); + if (ch == '}') { + return 1; + } + } while (ch == ','); + + return -1; +} + +static int json_parse_property(struct json_value *value) +{ + struct json_value key; + int ret; + int ch; + + json_skip_whitespace(); + + ret = json_parse_string(&key); + if (ret <= 0) + return -1; + + value->key = key.u.string; + + json_skip_whitespace(); + + ch = input(); + if (ch != ':') + return -1; + + ret = json_parse_value(value); + if (ret <= 0) + return -1; + + return 1; +} + +struct json_value *json_parse(const char *json) +{ + struct json_value *root; + int ret; + + input_buf = json; + input_pos = 0; + input_len = strlen(input_buf); + + root = calloc(1, sizeof(*root)); + if (!root) + return NULL; + + ret = json_parse_value(root); + if (ret != 1) { + free(root); + return NULL; + } + + return root; +} + +struct json_value *json_parse_file(const char *file) +{ + struct json_value *root; + struct stat sb; + int ret; + int fd; + + fd = open(file, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "failed to open %s: %s\n", file, strerror(errno)); + return NULL; + } + + ret = fstat(fd, &sb); + if (ret < 0) + return NULL; + + input_pos = 0; + input_len = sb.st_size; + input_buf = malloc(sb.st_size); + + ret = read(fd, (char *)input_buf, input_len); + + close(fd); + + if (ret != input_len) { + fprintf(stderr, "failed to read %d bytes form %s\n", input_len, file); + return NULL; + } + + root = calloc(1, sizeof(*root)); + if (!root) + return NULL; + + ret = json_parse_value(root); + if (ret != 1) { + json_free(root); + return NULL; + } + + return root; +} + +struct json_value *json_get_child(struct json_value *object, const char *key) +{ + struct json_value *it; + + if(object->type != JSON_TYPE_OBJECT) + return NULL; + + for (it = object->u.value; it; it = it->next) { + if (!strcmp(it->key, key)) + return it; + } + + return NULL; +} + +int json_count_children(struct json_value *array) +{ + struct json_value *it; + int count = 0; + + if (!array || array->type != JSON_TYPE_ARRAY) + return -1; + + for (it = array->u.value; it; it = it->next) + count++; + + return count; +} + +int json_get_number(struct json_value *object, const char *key, double *number) +{ + struct json_value *it; + + if (!object || object->type != JSON_TYPE_OBJECT) + return -1; + + for (it = object->u.value; it; it = it->next) { + if (!strcmp(it->key, key)) { + if (it->type != JSON_TYPE_NUMBER) + return -1; + + *number = it->u.number; + return 0; + } + } + + return -1; +} + +const char *json_get_string(struct json_value *object, const char *key) +{ + struct json_value *it; + + if (!object || object->type != JSON_TYPE_OBJECT) + return NULL; + + for (it = object->u.value; it; it = it->next) { + if (!strcmp(it->key, key)) { + if (it->type != JSON_TYPE_STRING) + return NULL; + + return it->u.string; + } + } + + return NULL; +} + +void json_free(struct json_value *value) +{ + struct json_value *next; + struct json_value *it; + + free((char *)value->key); + + switch (value->type) { + case JSON_TYPE_OBJECT: + case JSON_TYPE_ARRAY: + it = value->u.value; + while (it) { + next = it->next; + json_free(it); + it = next; + } + break; + case JSON_TYPE_STRING: + free((char *)value->u.string); + break; + } + + free(value); +} diff --git a/qcom/pd-mapper/json.h b/qcom/pd-mapper/json.h new file mode 100644 index 0000000..91790a0 --- /dev/null +++ b/qcom/pd-mapper/json.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019, Linaro Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __JSON_H__ +#define __JSON_H__ + + +enum { + JSON_TYPE_UNKNOWN, + JSON_TYPE_TRUE, + JSON_TYPE_FALSE, + JSON_TYPE_NULL, + JSON_TYPE_NUMBER, + JSON_TYPE_STRING, + JSON_TYPE_ARRAY, + JSON_TYPE_OBJECT, +}; + +struct json_value { + const char *key; + + int type; + union { + double number; + const char *string; + struct json_value *value; + } u; + + struct json_value *next; +}; + +struct json_value *json_parse(const char *json); +struct json_value *json_parse_file(const char *file); +int json_count_children(struct json_value *array); +struct json_value *json_get_child(struct json_value *object, const char *key); +int json_get_number(struct json_value *object, const char *key, double *number); +const char *json_get_string(struct json_value *object, const char *key); +void json_free(struct json_value *value); + +#endif diff --git a/qcom/pd-mapper/pd-mapper.c b/qcom/pd-mapper/pd-mapper.c index 543dfb3..f26710d 100644 --- a/qcom/pd-mapper/pd-mapper.c +++ b/qcom/pd-mapper/pd-mapper.c @@ -28,13 +28,21 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include +#include #include +#include +#include +#include #include #include #include #include #include +#include "assoc.h" +#include "json.h" #include "servreg_loc.h" struct pd_map { @@ -43,10 +51,7 @@ struct pd_map { int instance; }; -static const struct pd_map pd_maps[] = { - { "kernel/elf_loader", "msm/modem/wlan_pd", 1 }, - {} -}; +static struct pd_map *pd_maps; static void handle_get_domain_list(int sock, const struct qrtr_packet *pkt) { @@ -113,6 +118,187 @@ respond: } } +static int pd_load_map(const char *file) +{ + static int num_pd_maps; + struct json_value *sr_service; + struct json_value *sr_domain; + struct json_value *root; + struct json_value *it; + const char *subdomain; + const char *provider; + const char *service; + const char *domain; + const char *soc; + struct pd_map *newp; + struct pd_map *map; + double number; + int count; + int ret; + + root = json_parse_file(file); + if (!root) + return -1; + + sr_domain = json_get_child(root, "sr_domain"); + soc = json_get_string(sr_domain, "soc"); + domain = json_get_string(sr_domain, "domain"); + subdomain = json_get_string(sr_domain, "subdomain"); + ret = json_get_number(sr_domain, "qmi_instance_id", &number); + if (ret) + return ret; + + if (!soc || !domain || !subdomain) { + fprintf(stderr, "failed to parse sr_domain\n"); + return -1; + } + + sr_service = json_get_child(root, "sr_service"); + count = json_count_children(sr_service); + if (count < 0) + return count; + + newp = realloc(pd_maps, (num_pd_maps + count + 1) * sizeof(*newp)); + if (!newp) + return -1; + pd_maps = newp; + + for (it = sr_service->u.value; it; it = it->next) { + provider = json_get_string(it, "provider"); + service = json_get_string(it, "service"); + + if (!provider || !service) { + fprintf(stderr, + "failed to parse provdider or service from %s\n", + file); + return -1; + } + + map = &pd_maps[num_pd_maps++]; + + map->service = malloc(strlen(provider) + strlen(service) + 2); + sprintf((char *)map->service, "%s/%s", provider, service); + + map->domain = malloc(strlen(soc) + strlen(domain) + strlen(subdomain) + 3); + sprintf((char *)map->domain, "%s/%s/%s", soc, domain, subdomain); + + map->instance = number; + } + + pd_maps[num_pd_maps].service = NULL; + + json_free(root); + + return 0; +} + +#define FIRMWARE_BASE "/lib/firmware/" + +static int pd_enumerate_jsons(struct assoc *json_set) +{ + char firmware_value[PATH_MAX]; + char json_path[PATH_MAX]; + char firmware_attr[32]; + struct dirent *fw_de; + char path[PATH_MAX]; + struct dirent *de; + int firmware_fd; + DIR *class_dir; + int class_fd; + DIR *fw_dir; + size_t len; + size_t n; + + class_fd = open("/sys/class/remoteproc", O_RDONLY | O_DIRECTORY); + if (class_fd < 0) { + warn("failed to open remoteproc class"); + return -1; + } + + class_dir = fdopendir(class_fd); + if (!class_dir) { + warn("failed to opendir"); + goto close_class; + } + + while ((de = readdir(class_dir)) != NULL) { + if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) + continue; + + if (strlen(de->d_name) + sizeof("/firmware") > sizeof(firmware_attr)) + continue; + + strcpy(firmware_attr, de->d_name); + strcat(firmware_attr, "/firmware"); + + firmware_fd = openat(class_fd, firmware_attr, O_RDONLY); + if (firmware_fd < 0) + continue; + + n = read(firmware_fd, firmware_value, sizeof(firmware_value)); + close(firmware_fd); + if (n < 0) { + continue; + } + + if (strlen(FIRMWARE_BASE) + strlen(firmware_value) + 1 > sizeof(path)) + continue; + + strcpy(path, FIRMWARE_BASE); + strcat(path, dirname(firmware_value)); + + fw_dir = opendir(path); + while ((fw_de = readdir(fw_dir)) != NULL) { + if (!strcmp(fw_de->d_name, ".") || !strcmp(fw_de->d_name, "..")) + continue; + + len = strlen(fw_de->d_name); + if (len < 5 || strcmp(&fw_de->d_name[len - 4], ".jsn")) + continue; + + if (strlen(FIRMWARE_BASE) + strlen(firmware_value) + 1 + + strlen(fw_de->d_name) + 1 > sizeof(path)) + continue; + + strcpy(json_path, path); + strcat(json_path, "/"); + strcat(json_path, fw_de->d_name); + + assoc_set(json_set, json_path, NULL); + } + + closedir(fw_dir); + } + + closedir(class_dir); +close_class: + close(class_fd); + + return 0; +} + +static int pd_load_maps(void) +{ + struct assoc json_set; + unsigned long it; + const char *jsn; + int ret = 0; + + assoc_init(&json_set, 20); + + pd_enumerate_jsons(&json_set); + + assoc_foreach(jsn, NULL, &json_set, it) { + ret = pd_load_map(jsn); + if (ret < 0) + break; + } + + assoc_destroy(&json_set); + + return ret; +} + int main(int argc __unused, char **argv __unused) { struct sockaddr_qrtr sq; @@ -123,6 +309,15 @@ int main(int argc __unused, char **argv __unused) int ret; int fd; + ret = pd_load_maps(); + if (ret) + exit(1); + + if (!pd_maps) { + fprintf(stderr, "no pd maps available\n"); + exit(1); + } + fd = qrtr_open(0); if (fd < 0) { fprintf(stderr, "failed to open qrtr socket\n"); -- cgit v1.2.3 From 4f619fba658deb64633165bdae0efea47db42952 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 14 Apr 2020 22:45:05 +0530 Subject: qcom: pd-mapper: Null terminate firmware_value string Null terminate firmware_value string to prevent strlen() read past the end of buffer. Otherwise pd-mapper will crash: console:/ # pd-mapper FORTIFY: strlen: detected read past end of buffer Aborted 134|console:/ # Signed-off-by: Amit Pundir Change-Id: Id0b9e1dda2bae12e3a36f1ce40376d1161878894 --- qcom/pd-mapper/pd-mapper.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'qcom/pd-mapper') diff --git a/qcom/pd-mapper/pd-mapper.c b/qcom/pd-mapper/pd-mapper.c index f26710d..c7db57f 100644 --- a/qcom/pd-mapper/pd-mapper.c +++ b/qcom/pd-mapper/pd-mapper.c @@ -241,6 +241,8 @@ static int pd_enumerate_jsons(struct assoc *json_set) continue; } + firmware_value[n] = '\0'; + if (strlen(FIRMWARE_BASE) + strlen(firmware_value) + 1 > sizeof(path)) continue; -- cgit v1.2.3 From b951ef2442aab86b76d3270b4657c4fbccc58af6 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 14 Apr 2020 22:48:17 +0530 Subject: qcom: pd-mapper: Use /vendor/firmware path for AOSP Signed-off-by: Amit Pundir Change-Id: I44f1d53cb16bc91e05be530c55e15a2657660be6 --- qcom/pd-mapper/pd-mapper.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'qcom/pd-mapper') diff --git a/qcom/pd-mapper/pd-mapper.c b/qcom/pd-mapper/pd-mapper.c index c7db57f..664b77d 100644 --- a/qcom/pd-mapper/pd-mapper.c +++ b/qcom/pd-mapper/pd-mapper.c @@ -192,7 +192,11 @@ static int pd_load_map(const char *file) return 0; } +#ifndef ANDROID #define FIRMWARE_BASE "/lib/firmware/" +#else +#define FIRMWARE_BASE "/vendor/firmware/" +#endif static int pd_enumerate_jsons(struct assoc *json_set) { -- cgit v1.2.3 From 4429e581cd6d90ab6a35d26df46e998b1d61d6f2 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 14 Apr 2020 22:15:09 +0530 Subject: qcom: pd-mapper: Update Android.bp srcs Signed-off-by: Amit Pundir Change-Id: I8b6f6907fd27e775fd399b109cd660372a6a6252 --- qcom/pd-mapper/Android.bp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'qcom/pd-mapper') diff --git a/qcom/pd-mapper/Android.bp b/qcom/pd-mapper/Android.bp index 84c065f..3bdbc32 100644 --- a/qcom/pd-mapper/Android.bp +++ b/qcom/pd-mapper/Android.bp @@ -3,6 +3,8 @@ cc_binary { vendor: true, srcs: [ "pd-mapper.c", + "assoc.c", + "json.c", "servreg_loc.c", ], shared_libs: ["libqrtr"], -- cgit v1.2.3