xenguest_arm64.c 4.3 KB

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