summaryrefslogtreecommitdiff
path: root/components/drivers/fdt/src/dtb_load.c
blob: ba47c383e9242527365c05b1c5072b61232a7d9d (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
/*
 * Copyright (c) 2006-2022, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include "libfdt.h"
#include <stdio.h>
#include <unistd.h>
#include "dtb_node.h"

extern int fdt_exec_status;

rt_bool_t dtb_node_check(void *fdt)
{
    return fdt_check_header(fdt) == 0 ? RT_TRUE : RT_FALSE;
}

void *dtb_node_load_from_fs(char *dtb_filename)
{
    void *fdt = NULL;
    size_t dtb_sz;
    int fd = -1;

    if (dtb_filename == NULL)
    {
        fdt_exec_status = FDT_RET_GET_EMPTY;
        goto end;
    }

    fd = open(dtb_filename, O_RDONLY, 0);

    if (fd == -1)
    {
        rt_kprintf("File `%s' not found.\n", dtb_filename);
        fdt_exec_status = FDT_RET_GET_EMPTY;
        goto end;
    }

    dtb_sz = lseek(fd, 0, SEEK_END);

    if (dtb_sz > 0)
    {
        if ((fdt = (struct fdt_header *)malloc(sizeof(uint8_t) * dtb_sz)) == NULL)
        {
            fdt_exec_status = FDT_RET_NO_MEMORY;
            goto end;
        }

        lseek(fd, 0, SEEK_SET);
        read(fd, fdt, sizeof(uint8_t) * dtb_sz);

        if (dtb_node_check(fdt) == RT_FALSE)
        {
            free(fdt);
        }
    }

end:
    if (fd != -1)
    {
        close(fd);
    }

    return fdt;
}

void *dtb_node_load_from_memory(void *dtb_ptr, rt_bool_t is_clone)
{
    void *fdt = NULL;

    if (dtb_ptr == NULL)
    {
        fdt_exec_status = FDT_RET_GET_EMPTY;
        goto end;
    }

    if (dtb_node_check(dtb_ptr) == RT_FALSE)
    {
        fdt_exec_status = FDT_RET_GET_EMPTY;
        fdt = NULL;
        goto end;
    }

    if (is_clone)
    {
        size_t dtb_sz = fdt_totalsize(dtb_ptr);
        if (dtb_sz > 0)
        {
            if ((fdt = malloc(dtb_sz)) != NULL)
            {
                memcpy(fdt, dtb_ptr, dtb_sz);
            }
            else
            {
                fdt_exec_status = FDT_RET_NO_MEMORY;
            }
        }
    }
    else
    {
        fdt = dtb_ptr;
    }

end:
    return fdt;
}