14b0730d2SSimon Glass /* 24b0730d2SSimon Glass * Copyright (c) 2011 The Chromium OS Authors. 31a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 44b0730d2SSimon Glass */ 59569c406SSimon Glass #define DEBUG 64b0730d2SSimon Glass #include <common.h> 79d922450SSimon Glass #include <dm.h> 8f4289cbdSSimon Glass #include <errno.h> 9f4289cbdSSimon Glass #include <libfdt.h> 107a9219c1SSimon Glass #include <os.h> 11b45122fdSSimon Glass #include <asm/io.h> 125c2859cdSSimon Glass #include <asm/state.h> 136e206504SSimon Glass #include <dm/root.h> 144b0730d2SSimon Glass 154b0730d2SSimon Glass DECLARE_GLOBAL_DATA_PTR; 164b0730d2SSimon Glass 179569c406SSimon Glass /* Enable access to PCI memory with map_sysmem() */ 189569c406SSimon Glass static bool enable_pci_map; 199569c406SSimon Glass 209569c406SSimon Glass #ifdef CONFIG_PCI 219569c406SSimon Glass /* Last device that was mapped into memory, and length of mapping */ 229569c406SSimon Glass static struct udevice *map_dev; 239569c406SSimon Glass unsigned long map_len; 249569c406SSimon Glass #endif 259569c406SSimon Glass 265010d98fSSimon Glass void sandbox_exit(void) 274b0730d2SSimon Glass { 288939df09SSimon Glass /* Do this here while it still has an effect */ 298939df09SSimon Glass os_fd_restore(); 305c2859cdSSimon Glass if (state_uninit()) 315c2859cdSSimon Glass os_exit(2); 325c2859cdSSimon Glass 3361336833SSimon Glass if (dm_uninit()) 3461336833SSimon Glass os_exit(2); 3561336833SSimon Glass 367a9219c1SSimon Glass /* This is considered normal termination for now */ 377a9219c1SSimon Glass os_exit(0); 3888bd0e9dSSimon Glass } 3988bd0e9dSSimon Glass 404b0730d2SSimon Glass /* delay x useconds */ 414b0730d2SSimon Glass void __udelay(unsigned long usec) 424b0730d2SSimon Glass { 439723563aSSimon Glass struct sandbox_state *state = state_get_current(); 449723563aSSimon Glass 459723563aSSimon Glass if (!state->skip_delays) 46d99a6874SMatthias Weisser os_usleep(usec); 474b0730d2SSimon Glass } 484b0730d2SSimon Glass 494b0730d2SSimon Glass int cleanup_before_linux(void) 504b0730d2SSimon Glass { 514b0730d2SSimon Glass return 0; 524b0730d2SSimon Glass } 534b0730d2SSimon Glass 5429748515SSimon Glass int cleanup_before_linux_select(int flags) 5529748515SSimon Glass { 5629748515SSimon Glass return 0; 5729748515SSimon Glass } 5829748515SSimon Glass 594b0730d2SSimon Glass void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) 604b0730d2SSimon Glass { 61a7d9caecSSimon Glass #if defined(CONFIG_PCI) && !defined(CONFIG_SPL_BUILD) 629569c406SSimon Glass unsigned long plen = len; 639569c406SSimon Glass void *ptr; 649569c406SSimon Glass 659569c406SSimon Glass map_dev = NULL; 669569c406SSimon Glass if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) { 679569c406SSimon Glass if (plen != len) { 689569c406SSimon Glass printf("%s: Warning: partial map at %x, wanted %lx, got %lx\n", 699569c406SSimon Glass __func__, paddr, len, plen); 709569c406SSimon Glass } 719569c406SSimon Glass map_len = len; 729569c406SSimon Glass return ptr; 739569c406SSimon Glass } 749569c406SSimon Glass #endif 759569c406SSimon Glass 768ee666a7SSimon Glass return (void *)(gd->arch.ram_buf + paddr); 774b0730d2SSimon Glass } 784b0730d2SSimon Glass 799569c406SSimon Glass void unmap_physmem(const void *vaddr, unsigned long flags) 809569c406SSimon Glass { 819569c406SSimon Glass #ifdef CONFIG_PCI 829569c406SSimon Glass if (map_dev) { 839569c406SSimon Glass pci_unmap_physmem(vaddr, map_len, map_dev); 849569c406SSimon Glass map_dev = NULL; 859569c406SSimon Glass } 869569c406SSimon Glass #endif 879569c406SSimon Glass } 889569c406SSimon Glass 899569c406SSimon Glass void sandbox_set_enable_pci_map(int enable) 909569c406SSimon Glass { 919569c406SSimon Glass enable_pci_map = enable; 929569c406SSimon Glass } 939569c406SSimon Glass 9466bd1cffSSimon Glass phys_addr_t map_to_sysmem(const void *ptr) 95781adb57SSimon Glass { 96781adb57SSimon Glass return (u8 *)ptr - gd->arch.ram_buf; 97781adb57SSimon Glass } 98781adb57SSimon Glass 994b0730d2SSimon Glass void flush_dcache_range(unsigned long start, unsigned long stop) 1004b0730d2SSimon Glass { 1014b0730d2SSimon Glass } 102b45122fdSSimon Glass 103b45122fdSSimon Glass int sandbox_read_fdt_from_file(void) 104b45122fdSSimon Glass { 105b45122fdSSimon Glass struct sandbox_state *state = state_get_current(); 106b45122fdSSimon Glass const char *fname = state->fdt_fname; 107b45122fdSSimon Glass void *blob; 108b45122fdSSimon Glass loff_t size; 109b45122fdSSimon Glass int err; 110b45122fdSSimon Glass int fd; 111b45122fdSSimon Glass 112b45122fdSSimon Glass blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); 113b45122fdSSimon Glass if (!state->fdt_fname) { 114b45122fdSSimon Glass err = fdt_create_empty_tree(blob, 256); 115b45122fdSSimon Glass if (!err) 116b45122fdSSimon Glass goto done; 117b45122fdSSimon Glass printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); 118b45122fdSSimon Glass return -EINVAL; 119b45122fdSSimon Glass } 120b45122fdSSimon Glass 121b45122fdSSimon Glass err = os_get_filesize(fname, &size); 122b45122fdSSimon Glass if (err < 0) { 123b45122fdSSimon Glass printf("Failed to file FDT file '%s'\n", fname); 124b45122fdSSimon Glass return err; 125b45122fdSSimon Glass } 126b45122fdSSimon Glass fd = os_open(fname, OS_O_RDONLY); 127b45122fdSSimon Glass if (fd < 0) { 128b45122fdSSimon Glass printf("Failed to open FDT file '%s'\n", fname); 129b45122fdSSimon Glass return -EACCES; 130b45122fdSSimon Glass } 131b45122fdSSimon Glass if (os_read(fd, blob, size) != size) { 132b45122fdSSimon Glass os_close(fd); 133b45122fdSSimon Glass return -EIO; 134b45122fdSSimon Glass } 135b45122fdSSimon Glass os_close(fd); 136b45122fdSSimon Glass 137b45122fdSSimon Glass done: 138b45122fdSSimon Glass gd->fdt_blob = blob; 139b45122fdSSimon Glass 140b45122fdSSimon Glass return 0; 141b45122fdSSimon Glass } 142*c87dc38dSSimon Glass 143*c87dc38dSSimon Glass ulong timer_get_boot_us(void) 144*c87dc38dSSimon Glass { 145*c87dc38dSSimon Glass static uint64_t base_count; 146*c87dc38dSSimon Glass uint64_t count = os_get_nsec(); 147*c87dc38dSSimon Glass 148*c87dc38dSSimon Glass if (!base_count) 149*c87dc38dSSimon Glass base_count = count; 150*c87dc38dSSimon Glass 151*c87dc38dSSimon Glass return (count - base_count) / 1000; 152*c87dc38dSSimon Glass } 153