xenguest_arm64.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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(void)
  36. {
  37. if (fdt_magic(rom_pointer[0]) != FDT_MAGIC)
  38. return NULL;
  39. return (void *)rom_pointer[0];
  40. }
  41. #define MAX_MEM_MAP_REGIONS 5
  42. static struct mm_region xen_mem_map[MAX_MEM_MAP_REGIONS];
  43. struct mm_region *mem_map = xen_mem_map;
  44. static int get_next_memory_node(const void *blob, int mem)
  45. {
  46. do {
  47. mem = fdt_node_offset_by_prop_value(blob, mem,
  48. "device_type", "memory", 7);
  49. } while (!fdtdec_get_is_enabled(blob, mem));
  50. return mem;
  51. }
  52. static int setup_mem_map(void)
  53. {
  54. int i = 0, ret, mem, reg = 0;
  55. struct fdt_resource res;
  56. const void *blob = gd->fdt_blob;
  57. u64 gfn;
  58. phys_addr_t gnttab_base;
  59. phys_size_t gnttab_sz;
  60. /*
  61. * Add "magic" region which is used by Xen to provide some essentials
  62. * for the guest: we need console and xenstore.
  63. */
  64. ret = hvm_get_parameter_maintain_dcache(HVM_PARAM_CONSOLE_PFN, &gfn);
  65. if (ret < 0) {
  66. printf("%s: Can't get HVM_PARAM_CONSOLE_PFN, ret %d\n",
  67. __func__, ret);
  68. return -EINVAL;
  69. }
  70. xen_mem_map[i].virt = PFN_PHYS(gfn);
  71. xen_mem_map[i].phys = PFN_PHYS(gfn);
  72. xen_mem_map[i].size = PAGE_SIZE;
  73. xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
  74. PTE_BLOCK_INNER_SHARE);
  75. i++;
  76. ret = hvm_get_parameter_maintain_dcache(HVM_PARAM_STORE_PFN, &gfn);
  77. if (ret < 0) {
  78. printf("%s: Can't get HVM_PARAM_STORE_PFN, ret %d\n",
  79. __func__, ret);
  80. return -EINVAL;
  81. }
  82. xen_mem_map[i].virt = PFN_PHYS(gfn);
  83. xen_mem_map[i].phys = PFN_PHYS(gfn);
  84. xen_mem_map[i].size = PAGE_SIZE;
  85. xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
  86. PTE_BLOCK_INNER_SHARE);
  87. i++;
  88. /* Get Xen's suggested physical page assignments for the grant table. */
  89. get_gnttab_base(&gnttab_base, &gnttab_sz);
  90. xen_mem_map[i].virt = gnttab_base;
  91. xen_mem_map[i].phys = gnttab_base;
  92. xen_mem_map[i].size = gnttab_sz;
  93. xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
  94. PTE_BLOCK_INNER_SHARE);
  95. i++;
  96. mem = get_next_memory_node(blob, -1);
  97. if (mem < 0) {
  98. printf("%s: Missing /memory node\n", __func__);
  99. return -EINVAL;
  100. }
  101. for (; i < MAX_MEM_MAP_REGIONS; i++) {
  102. ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
  103. if (ret == -FDT_ERR_NOTFOUND) {
  104. reg = 0;
  105. mem = get_next_memory_node(blob, mem);
  106. if (mem == -FDT_ERR_NOTFOUND)
  107. break;
  108. ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
  109. if (ret == -FDT_ERR_NOTFOUND)
  110. break;
  111. }
  112. if (ret != 0) {
  113. printf("No reg property for memory node\n");
  114. return -EINVAL;
  115. }
  116. xen_mem_map[i].virt = (phys_addr_t)res.start;
  117. xen_mem_map[i].phys = (phys_addr_t)res.start;
  118. xen_mem_map[i].size = (phys_size_t)(res.end - res.start + 1);
  119. xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
  120. PTE_BLOCK_INNER_SHARE);
  121. }
  122. return 0;
  123. }
  124. void enable_caches(void)
  125. {
  126. /* Re-setup the memory map as BSS gets cleared after relocation. */
  127. setup_mem_map();
  128. icache_enable();
  129. dcache_enable();
  130. }
  131. /* Read memory settings from the Xen provided device tree. */
  132. int dram_init(void)
  133. {
  134. int ret;
  135. ret = fdtdec_setup_mem_size_base();
  136. if (ret < 0)
  137. return ret;
  138. /* Setup memory map, so MMU page table size can be estimated. */
  139. return setup_mem_map();
  140. }
  141. int dram_init_banksize(void)
  142. {
  143. return fdtdec_setup_memory_banksize();
  144. }
  145. /*
  146. * Board specific reset that is system reset.
  147. */
  148. void reset_cpu(void)
  149. {
  150. }
  151. int ft_system_setup(void *blob, struct bd_info *bd)
  152. {
  153. return 0;
  154. }
  155. int ft_board_setup(void *blob, struct bd_info *bd)
  156. {
  157. return 0;
  158. }
  159. int print_cpuinfo(void)
  160. {
  161. printf("Xen virtual CPU\n");
  162. return 0;
  163. }
  164. void board_cleanup_before_linux(void)
  165. {
  166. xen_fini();
  167. }