xenguest_arm64.c 4.2 KB

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