xenguest_arm64.c 4.3 KB

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