blob: 6e10bba76b71c83b86d15b1493ac7165e0c27dfe [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>
Oleksandr Andrushchenko10fa5362020-08-06 12:43:00 +030015#include <xen.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060016#include <asm/global_data.h>
Andrii Anisov355d1e42020-08-06 12:42:47 +030017
18#include <asm/io.h>
19#include <asm/armv8/mmu.h>
20#include <asm/xen.h>
21#include <asm/xen/hypercall.h>
Peng Fan8162f8f2020-08-06 12:42:50 +030022#include <asm/xen/system.h>
Andrii Anisov355d1e42020-08-06 12:42:47 +030023
24#include <linux/compiler.h>
25
Oleksandr Andrushchenko3cc1dcc2020-08-06 12:42:54 +030026#include <xen/gnttab.h>
Peng Fan8162f8f2020-08-06 12:42:50 +030027#include <xen/hvm.h>
28
Andrii Anisov355d1e42020-08-06 12:42:47 +030029DECLARE_GLOBAL_DATA_PTR;
30
31int board_init(void)
32{
33 return 0;
34}
35
36/*
37 * Use fdt provided by Xen: according to
38 * https://www.kernel.org/doc/Documentation/arm64/booting.txt
39 * x0 is the physical address of the device tree blob (dtb) in system RAM.
40 * This is stored in rom_pointer during low level init.
41 */
Ilias Apalodimasab5348a2021-10-26 09:12:33 +030042void *board_fdt_blob_setup(int *err)
Andrii Anisov355d1e42020-08-06 12:42:47 +030043{
Ilias Apalodimasab5348a2021-10-26 09:12:33 +030044 *err = 0;
45 if (fdt_magic(rom_pointer[0]) != FDT_MAGIC) {
46 *err = -ENXIO;
Andrii Anisov355d1e42020-08-06 12:42:47 +030047 return NULL;
Ilias Apalodimasab5348a2021-10-26 09:12:33 +030048 }
Andrii Anisov355d1e42020-08-06 12:42:47 +030049 return (void *)rom_pointer[0];
50}
51
52#define MAX_MEM_MAP_REGIONS 5
53static struct mm_region xen_mem_map[MAX_MEM_MAP_REGIONS];
54struct mm_region *mem_map = xen_mem_map;
55
56static int get_next_memory_node(const void *blob, int mem)
57{
58 do {
59 mem = fdt_node_offset_by_prop_value(blob, mem,
60 "device_type", "memory", 7);
61 } while (!fdtdec_get_is_enabled(blob, mem));
62
63 return mem;
64}
65
66static int setup_mem_map(void)
67{
Peng Fan8162f8f2020-08-06 12:42:50 +030068 int i = 0, ret, mem, reg = 0;
Andrii Anisov355d1e42020-08-06 12:42:47 +030069 struct fdt_resource res;
70 const void *blob = gd->fdt_blob;
Peng Fan8162f8f2020-08-06 12:42:50 +030071 u64 gfn;
Oleksandr Andrushchenko3cc1dcc2020-08-06 12:42:54 +030072 phys_addr_t gnttab_base;
73 phys_size_t gnttab_sz;
Peng Fan8162f8f2020-08-06 12:42:50 +030074
75 /*
76 * Add "magic" region which is used by Xen to provide some essentials
Oleksandr Andrushchenko4b728452020-08-06 12:42:53 +030077 * for the guest: we need console and xenstore.
Peng Fan8162f8f2020-08-06 12:42:50 +030078 */
79 ret = hvm_get_parameter_maintain_dcache(HVM_PARAM_CONSOLE_PFN, &gfn);
80 if (ret < 0) {
81 printf("%s: Can't get HVM_PARAM_CONSOLE_PFN, ret %d\n",
82 __func__, ret);
83 return -EINVAL;
84 }
85
86 xen_mem_map[i].virt = PFN_PHYS(gfn);
87 xen_mem_map[i].phys = PFN_PHYS(gfn);
88 xen_mem_map[i].size = PAGE_SIZE;
89 xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
90 PTE_BLOCK_INNER_SHARE);
91 i++;
Andrii Anisov355d1e42020-08-06 12:42:47 +030092
Oleksandr Andrushchenko4b728452020-08-06 12:42:53 +030093 ret = hvm_get_parameter_maintain_dcache(HVM_PARAM_STORE_PFN, &gfn);
94 if (ret < 0) {
95 printf("%s: Can't get HVM_PARAM_STORE_PFN, ret %d\n",
96 __func__, ret);
97 return -EINVAL;
98 }
99
100 xen_mem_map[i].virt = PFN_PHYS(gfn);
101 xen_mem_map[i].phys = PFN_PHYS(gfn);
102 xen_mem_map[i].size = PAGE_SIZE;
103 xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
104 PTE_BLOCK_INNER_SHARE);
105 i++;
106
Oleksandr Andrushchenko3cc1dcc2020-08-06 12:42:54 +0300107 /* Get Xen's suggested physical page assignments for the grant table. */
108 get_gnttab_base(&gnttab_base, &gnttab_sz);
109
110 xen_mem_map[i].virt = gnttab_base;
111 xen_mem_map[i].phys = gnttab_base;
112 xen_mem_map[i].size = gnttab_sz;
113 xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
114 PTE_BLOCK_INNER_SHARE);
115 i++;
116
Andrii Anisov355d1e42020-08-06 12:42:47 +0300117 mem = get_next_memory_node(blob, -1);
118 if (mem < 0) {
119 printf("%s: Missing /memory node\n", __func__);
120 return -EINVAL;
121 }
122
Peng Fan8162f8f2020-08-06 12:42:50 +0300123 for (; i < MAX_MEM_MAP_REGIONS; i++) {
Andrii Anisov355d1e42020-08-06 12:42:47 +0300124 ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
125 if (ret == -FDT_ERR_NOTFOUND) {
126 reg = 0;
127 mem = get_next_memory_node(blob, mem);
128 if (mem == -FDT_ERR_NOTFOUND)
129 break;
130
131 ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
132 if (ret == -FDT_ERR_NOTFOUND)
133 break;
134 }
135 if (ret != 0) {
136 printf("No reg property for memory node\n");
137 return -EINVAL;
138 }
139
140 xen_mem_map[i].virt = (phys_addr_t)res.start;
141 xen_mem_map[i].phys = (phys_addr_t)res.start;
142 xen_mem_map[i].size = (phys_size_t)(res.end - res.start + 1);
143 xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
144 PTE_BLOCK_INNER_SHARE);
145 }
146 return 0;
147}
148
149void enable_caches(void)
150{
151 /* Re-setup the memory map as BSS gets cleared after relocation. */
152 setup_mem_map();
153 icache_enable();
154 dcache_enable();
155}
156
157/* Read memory settings from the Xen provided device tree. */
158int dram_init(void)
159{
160 int ret;
161
162 ret = fdtdec_setup_mem_size_base();
163 if (ret < 0)
164 return ret;
165 /* Setup memory map, so MMU page table size can be estimated. */
166 return setup_mem_map();
167}
168
169int dram_init_banksize(void)
170{
171 return fdtdec_setup_memory_banksize();
172}
173
174/*
175 * Board specific reset that is system reset.
176 */
Harald Seiler6f14d5f2020-12-15 16:47:52 +0100177void reset_cpu(void)
Andrii Anisov355d1e42020-08-06 12:42:47 +0300178{
179}
180
181int ft_system_setup(void *blob, struct bd_info *bd)
182{
183 return 0;
184}
185
186int ft_board_setup(void *blob, struct bd_info *bd)
187{
188 return 0;
189}
190
Andrii Anisov355d1e42020-08-06 12:42:47 +0300191int print_cpuinfo(void)
192{
193 printf("Xen virtual CPU\n");
194 return 0;
195}
196
Oleksandr Andrushchenko10fa5362020-08-06 12:43:00 +0300197void board_cleanup_before_linux(void)
198{
199 xen_fini();
200}