blob: 1d1e2290855c1bcb9302a13cf9c90f0ae93bb004 [file] [log] [blame]
Andrii Anisov355d1e42020-08-06 12:42:47 +03001// SPDX-License-Identifier: GPL-2.0
2/*
3 * (C) 2013
4 * David Feng <fenghua@phytium.com.cn>
5 * Sharma Bhupesh <bhupesh.sharma@freescale.com>
6 *
7 * (C) 2020 EPAM Systems Inc
8 */
9
10#include <common.h>
11#include <cpu_func.h>
12#include <dm.h>
13#include <errno.h>
14#include <malloc.h>
15
16#include <asm/io.h>
17#include <asm/armv8/mmu.h>
18#include <asm/xen.h>
19#include <asm/xen/hypercall.h>
20
21#include <linux/compiler.h>
22
23DECLARE_GLOBAL_DATA_PTR;
24
25int board_init(void)
26{
27 return 0;
28}
29
30/*
31 * Use fdt provided by Xen: according to
32 * https://www.kernel.org/doc/Documentation/arm64/booting.txt
33 * x0 is the physical address of the device tree blob (dtb) in system RAM.
34 * This is stored in rom_pointer during low level init.
35 */
36void *board_fdt_blob_setup(void)
37{
38 if (fdt_magic(rom_pointer[0]) != FDT_MAGIC)
39 return NULL;
40 return (void *)rom_pointer[0];
41}
42
43#define MAX_MEM_MAP_REGIONS 5
44static struct mm_region xen_mem_map[MAX_MEM_MAP_REGIONS];
45struct mm_region *mem_map = xen_mem_map;
46
47static int get_next_memory_node(const void *blob, int mem)
48{
49 do {
50 mem = fdt_node_offset_by_prop_value(blob, mem,
51 "device_type", "memory", 7);
52 } while (!fdtdec_get_is_enabled(blob, mem));
53
54 return mem;
55}
56
57static int setup_mem_map(void)
58{
59 int i, ret, mem, reg = 0;
60 struct fdt_resource res;
61 const void *blob = gd->fdt_blob;
62
63 mem = get_next_memory_node(blob, -1);
64 if (mem < 0) {
65 printf("%s: Missing /memory node\n", __func__);
66 return -EINVAL;
67 }
68
69 for (i = 0; i < MAX_MEM_MAP_REGIONS; i++) {
70 ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
71 if (ret == -FDT_ERR_NOTFOUND) {
72 reg = 0;
73 mem = get_next_memory_node(blob, mem);
74 if (mem == -FDT_ERR_NOTFOUND)
75 break;
76
77 ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
78 if (ret == -FDT_ERR_NOTFOUND)
79 break;
80 }
81 if (ret != 0) {
82 printf("No reg property for memory node\n");
83 return -EINVAL;
84 }
85
86 xen_mem_map[i].virt = (phys_addr_t)res.start;
87 xen_mem_map[i].phys = (phys_addr_t)res.start;
88 xen_mem_map[i].size = (phys_size_t)(res.end - res.start + 1);
89 xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
90 PTE_BLOCK_INNER_SHARE);
91 }
92 return 0;
93}
94
95void enable_caches(void)
96{
97 /* Re-setup the memory map as BSS gets cleared after relocation. */
98 setup_mem_map();
99 icache_enable();
100 dcache_enable();
101}
102
103/* Read memory settings from the Xen provided device tree. */
104int dram_init(void)
105{
106 int ret;
107
108 ret = fdtdec_setup_mem_size_base();
109 if (ret < 0)
110 return ret;
111 /* Setup memory map, so MMU page table size can be estimated. */
112 return setup_mem_map();
113}
114
115int dram_init_banksize(void)
116{
117 return fdtdec_setup_memory_banksize();
118}
119
120/*
121 * Board specific reset that is system reset.
122 */
123void reset_cpu(ulong addr)
124{
125}
126
127int ft_system_setup(void *blob, struct bd_info *bd)
128{
129 return 0;
130}
131
132int ft_board_setup(void *blob, struct bd_info *bd)
133{
134 return 0;
135}
136
137int board_early_init_f(void)
138{
139 return 0;
140}
141
142int print_cpuinfo(void)
143{
144 printf("Xen virtual CPU\n");
145 return 0;
146}
147
148__weak struct serial_device *default_serial_console(void)
149{
150 return NULL;
151}
152