serial: serial_xen: Add Xen PV serial driver
[platform/kernel/u-boot.git] / board / xen / xenguest_arm64 / xenguest_arm64.c
1 // 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 #include <asm/xen/system.h>
21
22 #include <linux/compiler.h>
23
24 #include <xen/hvm.h>
25
26 DECLARE_GLOBAL_DATA_PTR;
27
28 int 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  */
39 void *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
47 static struct mm_region xen_mem_map[MAX_MEM_MAP_REGIONS];
48 struct mm_region *mem_map = xen_mem_map;
49
50 static 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
60 static int setup_mem_map(void)
61 {
62         int i = 0, ret, mem, reg = 0;
63         struct fdt_resource res;
64         const void *blob = gd->fdt_blob;
65         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++;
84
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
91         for (; i < MAX_MEM_MAP_REGIONS; i++) {
92                 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
117 void 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. */
126 int 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
137 int dram_init_banksize(void)
138 {
139         return fdtdec_setup_memory_banksize();
140 }
141
142 /*
143  * Board specific reset that is system reset.
144  */
145 void reset_cpu(ulong addr)
146 {
147 }
148
149 int ft_system_setup(void *blob, struct bd_info *bd)
150 {
151         return 0;
152 }
153
154 int ft_board_setup(void *blob, struct bd_info *bd)
155 {
156         return 0;
157 }
158
159 int board_early_init_f(void)
160 {
161         return 0;
162 }
163
164 int print_cpuinfo(void)
165 {
166         printf("Xen virtual CPU\n");
167         return 0;
168 }
169