blob: e3903bb9874239cb02cfd676cfeea58bf0e3095b [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>
Peng Fan8162f8f2020-08-06 12:42:50 +030020#include <asm/xen/system.h>
Andrii Anisov355d1e42020-08-06 12:42:47 +030021
22#include <linux/compiler.h>
23
Peng Fan8162f8f2020-08-06 12:42:50 +030024#include <xen/hvm.h>
25
Andrii Anisov355d1e42020-08-06 12:42:47 +030026DECLARE_GLOBAL_DATA_PTR;
27
28int board_init(void)
29{
30 return 0;
31}
32
33/*
34 * Use fdt provided by Xen: according to
35 * https://www.kernel.org/doc/Documentation/arm64/booting.txt
36 * x0 is the physical address of the device tree blob (dtb) in system RAM.
37 * This is stored in rom_pointer during low level init.
38 */
39void *board_fdt_blob_setup(void)
40{
41 if (fdt_magic(rom_pointer[0]) != FDT_MAGIC)
42 return NULL;
43 return (void *)rom_pointer[0];
44}
45
46#define MAX_MEM_MAP_REGIONS 5
47static struct mm_region xen_mem_map[MAX_MEM_MAP_REGIONS];
48struct mm_region *mem_map = xen_mem_map;
49
50static int get_next_memory_node(const void *blob, int mem)
51{
52 do {
53 mem = fdt_node_offset_by_prop_value(blob, mem,
54 "device_type", "memory", 7);
55 } while (!fdtdec_get_is_enabled(blob, mem));
56
57 return mem;
58}
59
60static int setup_mem_map(void)
61{
Peng Fan8162f8f2020-08-06 12:42:50 +030062 int i = 0, ret, mem, reg = 0;
Andrii Anisov355d1e42020-08-06 12:42:47 +030063 struct fdt_resource res;
64 const void *blob = gd->fdt_blob;
Peng Fan8162f8f2020-08-06 12:42:50 +030065 u64 gfn;
66
67 /*
68 * Add "magic" region which is used by Xen to provide some essentials
69 * for the guest: we need console.
70 */
71 ret = hvm_get_parameter_maintain_dcache(HVM_PARAM_CONSOLE_PFN, &gfn);
72 if (ret < 0) {
73 printf("%s: Can't get HVM_PARAM_CONSOLE_PFN, ret %d\n",
74 __func__, ret);
75 return -EINVAL;
76 }
77
78 xen_mem_map[i].virt = PFN_PHYS(gfn);
79 xen_mem_map[i].phys = PFN_PHYS(gfn);
80 xen_mem_map[i].size = PAGE_SIZE;
81 xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
82 PTE_BLOCK_INNER_SHARE);
83 i++;
Andrii Anisov355d1e42020-08-06 12:42:47 +030084
85 mem = get_next_memory_node(blob, -1);
86 if (mem < 0) {
87 printf("%s: Missing /memory node\n", __func__);
88 return -EINVAL;
89 }
90
Peng Fan8162f8f2020-08-06 12:42:50 +030091 for (; i < MAX_MEM_MAP_REGIONS; i++) {
Andrii Anisov355d1e42020-08-06 12:42:47 +030092 ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
93 if (ret == -FDT_ERR_NOTFOUND) {
94 reg = 0;
95 mem = get_next_memory_node(blob, mem);
96 if (mem == -FDT_ERR_NOTFOUND)
97 break;
98
99 ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
100 if (ret == -FDT_ERR_NOTFOUND)
101 break;
102 }
103 if (ret != 0) {
104 printf("No reg property for memory node\n");
105 return -EINVAL;
106 }
107
108 xen_mem_map[i].virt = (phys_addr_t)res.start;
109 xen_mem_map[i].phys = (phys_addr_t)res.start;
110 xen_mem_map[i].size = (phys_size_t)(res.end - res.start + 1);
111 xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
112 PTE_BLOCK_INNER_SHARE);
113 }
114 return 0;
115}
116
117void enable_caches(void)
118{
119 /* Re-setup the memory map as BSS gets cleared after relocation. */
120 setup_mem_map();
121 icache_enable();
122 dcache_enable();
123}
124
125/* Read memory settings from the Xen provided device tree. */
126int dram_init(void)
127{
128 int ret;
129
130 ret = fdtdec_setup_mem_size_base();
131 if (ret < 0)
132 return ret;
133 /* Setup memory map, so MMU page table size can be estimated. */
134 return setup_mem_map();
135}
136
137int dram_init_banksize(void)
138{
139 return fdtdec_setup_memory_banksize();
140}
141
142/*
143 * Board specific reset that is system reset.
144 */
145void reset_cpu(ulong addr)
146{
147}
148
149int ft_system_setup(void *blob, struct bd_info *bd)
150{
151 return 0;
152}
153
154int ft_board_setup(void *blob, struct bd_info *bd)
155{
156 return 0;
157}
158
159int board_early_init_f(void)
160{
161 return 0;
162}
163
164int print_cpuinfo(void)
165{
166 printf("Xen virtual CPU\n");
167 return 0;
168}
169