mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
e7fb789612
OF_HOSTFILE is used on sandbox configs only. Although it's pretty unique and not causing any confusions, we are better of having simpler config options for the DTB. So let's replace that with the existing OF_BOARD. U-Boot would then have only three config options for the DTB origin. - OF_SEPARATE, build separately from U-Boot - OF_BOARD, board specific way of providing the DTB - OF_EMBED embedded in the u-boot binary(should not be used in production Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Reviewed-by: Simon Glass <sjg@chromium.org>
200 lines
4.3 KiB
C
200 lines
4.3 KiB
C
// 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();
|
|
}
|