source: rtems/bsps/riscv/riscv/start/bspstart.c @ a7f5e42c

5
Last change on this file since a7f5e42c was a7f5e42c, checked in by Pragnesh Patel <pragnesh.patel@…>, on 10/22/19 at 10:20:05

riscv: add freedom E310 Arty A7 bsp

Added support for Sifive Freedom FE310 soc on Arty A7 FPGA board.
Update #3785.

Signed-off-by: Pragnesh Patel <pragnesh.patel@…>

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2018 embedded brains GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26#include <bsp/bootcard.h>
27#include <bsp/fatal.h>
28#include <bsp/fdt.h>
29#include <bsp/irq-generic.h>
30#include <bsp/riscv.h>
31
32#include <libfdt.h>
33#include <string.h>
34
35#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
36unsigned int riscv_core_freq;
37#endif
38
39void *riscv_fdt_get_address(const void *fdt, int node)
40{
41  int parent;
42  int ac;
43  int len;
44  const uint32_t *reg;
45  uint64_t addr;
46
47  parent = fdt_parent_offset(fdt, node);
48  if (parent < 0) {
49    return NULL;
50  }
51
52  ac = fdt_address_cells(fdt, parent);
53  if (ac != 1 && ac != 2) {
54    return NULL;
55  }
56
57  reg = fdt_getprop(fdt, node, "reg", &len);
58  if (reg == NULL || len < ac) {
59    return NULL;
60  }
61
62  addr = 0;
63
64  while (ac > 0) {
65    addr = (addr << 32) | fdt32_to_cpu(*reg);
66    ++reg;
67    --ac;
68  }
69
70#if __riscv_xlen < 64
71  if (addr > 0xffffffff) {
72    return NULL;
73  }
74#endif
75
76  return (void *)(uintptr_t) addr;
77}
78
79#ifdef RTEMS_SMP
80uint32_t riscv_hart_count;
81
82static uint32_t riscv_hart_phandles[CPU_MAXIMUM_PROCESSORS];
83#else
84static uint32_t riscv_hart_phandles[1];
85#endif
86
87static void riscv_find_harts(void)
88{
89  const void *fdt;
90  int node;
91  uint32_t max_hart_index;
92
93  fdt = bsp_fdt_get();
94  max_hart_index = 0;
95  node = -1;
96
97  while ((node = fdt_node_offset_by_compatible(fdt, node, "riscv")) >= 0) {
98    int subnode;
99    const uint32_t *val;
100    int len;
101    uint32_t phandle;
102    uint32_t hart_index;
103
104    val = fdt_getprop(fdt, node, "reg", &len);
105    if (val == NULL || len != 4) {
106      bsp_fatal(RISCV_FATAL_INVALID_HART_REG_IN_DEVICE_TREE);
107    }
108
109    hart_index = fdt32_to_cpu(val[0]);
110
111    if (hart_index >= RTEMS_ARRAY_SIZE(riscv_hart_phandles)) {
112      continue;
113    }
114
115    if (hart_index > max_hart_index) {
116      max_hart_index = hart_index;
117    }
118
119    phandle = 0;
120
121    fdt_for_each_subnode(subnode, fdt, node) {
122      int propoff;
123      bool interrupt_controller;
124      uint32_t potential_phandle;
125
126      interrupt_controller = false;
127      potential_phandle = 0;
128
129      fdt_for_each_property_offset(propoff, fdt, subnode) {
130        const char *name;
131
132        val = fdt_getprop_by_offset(fdt, propoff, &name, &len);
133        if (val != NULL) {
134          if (strcmp(name, "interrupt-controller") == 0) {
135            interrupt_controller = true;
136          } else if (len == 4 && strcmp(name, "phandle") == 0) {
137            potential_phandle = fdt32_to_cpu(val[0]);
138          }
139        }
140      }
141
142      if (interrupt_controller) {
143        phandle = potential_phandle;
144        break;
145      }
146    }
147
148    riscv_hart_phandles[hart_index] = phandle;
149  }
150
151#ifdef RTEMS_SMP
152  riscv_hart_count = max_hart_index + 1;
153#endif
154}
155
156uint32_t riscv_get_hart_index_by_phandle(uint32_t phandle)
157{
158  uint32_t hart_index;
159
160  for (hart_index = 0; hart_index < riscv_hart_count; ++hart_index) {
161    if (riscv_hart_phandles[hart_index] == phandle) {
162      return hart_index;
163    }
164  }
165
166  return UINT32_MAX;
167}
168
169#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
170static uint32_t get_core_frequency(void)
171{
172        uint32_t node;
173        const char *fdt=bsp_fdt_get();
174
175  char *tlclk;
176        uint32_t len;
177
178  do
179  {
180    node=fdt_node_offset_by_compatible(fdt, -1,"fixed-clock");
181    uint32_t *val=NULL;
182    if (node>0)
183    {
184      tlclk = fdt_getprop(fdt, node, "clock-output-names", &len);
185
186      if (strcmp(tlclk,"tlclk") == 0)
187      {
188        val = fdt_getprop(fdt, node, "clock-frequency", &len);
189                    if(val !=NULL)
190                    {
191                            riscv_core_freq=fdt32_to_cpu(*val);
192          break;
193                    }
194      }
195          }else
196    {
197      bsp_fatal(RISCV_FATAL_NO_TLCLOCK_FREQUENCY_IN_DEVICE_TREE);
198    }
199
200  } while (node > 0);
201
202        return riscv_core_freq;
203}
204
205inline uint32_t riscv_get_core_frequency(void)
206{
207        return riscv_core_freq;
208}
209#endif
210
211void bsp_start(void)
212{
213  riscv_find_harts();
214  bsp_interrupt_initialize();
215
216#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
217        riscv_core_freq=get_core_frequency();
218#endif
219
220}
Note: See TracBrowser for help on using the repository browser.