123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * (C) 2013
- * David Feng <fenghua@phytium.com.cn>
- * Sharma Bhupesh <bhupesh.sharma@freescale.com>
- *
- * (C) 2020 EPAM Systems Inc
- */
- #include <common.h>
- #include <cpu_func.h>
- #include <dm.h>
- #include <errno.h>
- #include <malloc.h>
- #include <xen.h>
- #include <asm/global_data.h>
- #include <asm/io.h>
- #include <asm/armv8/mmu.h>
- #include <asm/xen.h>
- #include <asm/xen/hypercall.h>
- #include <asm/xen/system.h>
- #include <linux/compiler.h>
- #include <xen/gnttab.h>
- #include <xen/hvm.h>
- DECLARE_GLOBAL_DATA_PTR;
- int board_init(void)
- {
- return 0;
- }
- /*
- * Use fdt provided by Xen: according to
- * https://www.kernel.org/doc/Documentation/arm64/booting.txt
- * x0 is the physical address of the device tree blob (dtb) in system RAM.
- * This is stored in rom_pointer during low level init.
- */
- void *board_fdt_blob_setup(int *err)
- {
- *err = 0;
- if (fdt_magic(rom_pointer[0]) != FDT_MAGIC) {
- *err = -ENXIO;
- return NULL;
- }
- return (void *)rom_pointer[0];
- }
- #define MAX_MEM_MAP_REGIONS 5
- static struct mm_region xen_mem_map[MAX_MEM_MAP_REGIONS];
- struct mm_region *mem_map = xen_mem_map;
- static int get_next_memory_node(const void *blob, int mem)
- {
- do {
- mem = fdt_node_offset_by_prop_value(blob, mem,
- "device_type", "memory", 7);
- } while (!fdtdec_get_is_enabled(blob, mem));
- return mem;
- }
- static int setup_mem_map(void)
- {
- int i = 0, ret, mem, reg = 0;
- struct fdt_resource res;
- const void *blob = gd->fdt_blob;
- u64 gfn;
- phys_addr_t gnttab_base;
- phys_size_t gnttab_sz;
- /*
- * Add "magic" region which is used by Xen to provide some essentials
- * for the guest: we need console and xenstore.
- */
- ret = hvm_get_parameter_maintain_dcache(HVM_PARAM_CONSOLE_PFN, &gfn);
- if (ret < 0) {
- printf("%s: Can't get HVM_PARAM_CONSOLE_PFN, ret %d\n",
- __func__, ret);
- return -EINVAL;
- }
- xen_mem_map[i].virt = PFN_PHYS(gfn);
- xen_mem_map[i].phys = PFN_PHYS(gfn);
- xen_mem_map[i].size = PAGE_SIZE;
- xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
- PTE_BLOCK_INNER_SHARE);
- i++;
- ret = hvm_get_parameter_maintain_dcache(HVM_PARAM_STORE_PFN, &gfn);
- if (ret < 0) {
- printf("%s: Can't get HVM_PARAM_STORE_PFN, ret %d\n",
- __func__, ret);
- return -EINVAL;
- }
- xen_mem_map[i].virt = PFN_PHYS(gfn);
- xen_mem_map[i].phys = PFN_PHYS(gfn);
- xen_mem_map[i].size = PAGE_SIZE;
- xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
- PTE_BLOCK_INNER_SHARE);
- i++;
- /* Get Xen's suggested physical page assignments for the grant table. */
- get_gnttab_base(&gnttab_base, &gnttab_sz);
- xen_mem_map[i].virt = gnttab_base;
- xen_mem_map[i].phys = gnttab_base;
- xen_mem_map[i].size = gnttab_sz;
- xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
- PTE_BLOCK_INNER_SHARE);
- i++;
- mem = get_next_memory_node(blob, -1);
- if (mem < 0) {
- printf("%s: Missing /memory node\n", __func__);
- return -EINVAL;
- }
- for (; i < MAX_MEM_MAP_REGIONS; i++) {
- ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
- if (ret == -FDT_ERR_NOTFOUND) {
- reg = 0;
- mem = get_next_memory_node(blob, mem);
- if (mem == -FDT_ERR_NOTFOUND)
- break;
- ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
- if (ret == -FDT_ERR_NOTFOUND)
- break;
- }
- if (ret != 0) {
- printf("No reg property for memory node\n");
- return -EINVAL;
- }
- xen_mem_map[i].virt = (phys_addr_t)res.start;
- xen_mem_map[i].phys = (phys_addr_t)res.start;
- xen_mem_map[i].size = (phys_size_t)(res.end - res.start + 1);
- xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
- PTE_BLOCK_INNER_SHARE);
- }
- return 0;
- }
- void enable_caches(void)
- {
- /* Re-setup the memory map as BSS gets cleared after relocation. */
- setup_mem_map();
- icache_enable();
- dcache_enable();
- }
- /* Read memory settings from the Xen provided device tree. */
- int dram_init(void)
- {
- int ret;
- ret = fdtdec_setup_mem_size_base();
- if (ret < 0)
- return ret;
- /* Setup memory map, so MMU page table size can be estimated. */
- return setup_mem_map();
- }
- int dram_init_banksize(void)
- {
- return fdtdec_setup_memory_banksize();
- }
- /*
- * Board specific reset that is system reset.
- */
- void reset_cpu(void)
- {
- }
- int ft_system_setup(void *blob, struct bd_info *bd)
- {
- return 0;
- }
- int ft_board_setup(void *blob, struct bd_info *bd)
- {
- return 0;
- }
- int print_cpuinfo(void)
- {
- printf("Xen virtual CPU\n");
- return 0;
- }
- void board_cleanup_before_linux(void)
- {
- xen_fini();
- }
|