xenguest_arm64.c 3.8 KB

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