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>
9*0e00a84cSMasahiro Yamada #include <linux/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
sandbox_exit(void)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 */
__udelay(unsigned long usec)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
cleanup_before_linux(void)494b0730d2SSimon Glass int cleanup_before_linux(void)
504b0730d2SSimon Glass {
514b0730d2SSimon Glass return 0;
524b0730d2SSimon Glass }
534b0730d2SSimon Glass
cleanup_before_linux_select(int flags)5429748515SSimon Glass int cleanup_before_linux_select(int flags)
5529748515SSimon Glass {
5629748515SSimon Glass return 0;
5729748515SSimon Glass }
5829748515SSimon Glass
map_physmem(phys_addr_t paddr,unsigned long len,unsigned long flags)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
unmap_physmem(const void * vaddr,unsigned long flags)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
sandbox_set_enable_pci_map(int enable)899569c406SSimon Glass void sandbox_set_enable_pci_map(int enable)
909569c406SSimon Glass {
919569c406SSimon Glass enable_pci_map = enable;
929569c406SSimon Glass }
939569c406SSimon Glass
map_to_sysmem(const void * ptr)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
flush_dcache_range(unsigned long start,unsigned long stop)994b0730d2SSimon Glass void flush_dcache_range(unsigned long start, unsigned long stop)
1004b0730d2SSimon Glass {
1014b0730d2SSimon Glass }
102b45122fdSSimon Glass
invalidate_dcache_range(unsigned long start,unsigned long stop)1030d1414bdSBin Meng void invalidate_dcache_range(unsigned long start, unsigned long stop)
1040d1414bdSBin Meng {
1050d1414bdSBin Meng }
1060d1414bdSBin Meng
sandbox_read_fdt_from_file(void)107b45122fdSSimon Glass int sandbox_read_fdt_from_file(void)
108b45122fdSSimon Glass {
109b45122fdSSimon Glass struct sandbox_state *state = state_get_current();
110b45122fdSSimon Glass const char *fname = state->fdt_fname;
111b45122fdSSimon Glass void *blob;
112b45122fdSSimon Glass loff_t size;
113b45122fdSSimon Glass int err;
114b45122fdSSimon Glass int fd;
115b45122fdSSimon Glass
116b45122fdSSimon Glass blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
117b45122fdSSimon Glass if (!state->fdt_fname) {
118b45122fdSSimon Glass err = fdt_create_empty_tree(blob, 256);
119b45122fdSSimon Glass if (!err)
120b45122fdSSimon Glass goto done;
121b45122fdSSimon Glass printf("Unable to create empty FDT: %s\n", fdt_strerror(err));
122b45122fdSSimon Glass return -EINVAL;
123b45122fdSSimon Glass }
124b45122fdSSimon Glass
125b45122fdSSimon Glass err = os_get_filesize(fname, &size);
126b45122fdSSimon Glass if (err < 0) {
127b45122fdSSimon Glass printf("Failed to file FDT file '%s'\n", fname);
128b45122fdSSimon Glass return err;
129b45122fdSSimon Glass }
130b45122fdSSimon Glass fd = os_open(fname, OS_O_RDONLY);
131b45122fdSSimon Glass if (fd < 0) {
132b45122fdSSimon Glass printf("Failed to open FDT file '%s'\n", fname);
133b45122fdSSimon Glass return -EACCES;
134b45122fdSSimon Glass }
135b45122fdSSimon Glass if (os_read(fd, blob, size) != size) {
136b45122fdSSimon Glass os_close(fd);
137b45122fdSSimon Glass return -EIO;
138b45122fdSSimon Glass }
139b45122fdSSimon Glass os_close(fd);
140b45122fdSSimon Glass
141b45122fdSSimon Glass done:
142b45122fdSSimon Glass gd->fdt_blob = blob;
143b45122fdSSimon Glass
144b45122fdSSimon Glass return 0;
145b45122fdSSimon Glass }
146c87dc38dSSimon Glass
timer_get_boot_us(void)147c87dc38dSSimon Glass ulong timer_get_boot_us(void)
148c87dc38dSSimon Glass {
149c87dc38dSSimon Glass static uint64_t base_count;
150c87dc38dSSimon Glass uint64_t count = os_get_nsec();
151c87dc38dSSimon Glass
152c87dc38dSSimon Glass if (!base_count)
153c87dc38dSSimon Glass base_count = count;
154c87dc38dSSimon Glass
155c87dc38dSSimon Glass return (count - base_count) / 1000;
156c87dc38dSSimon Glass }
157