xref: /rk3399_rockchip-uboot/arch/sandbox/cpu/cpu.c (revision f4289cbd8a8d607399b507cb695b46cd771d6c1b)
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>
7*f4289cbdSSimon Glass #include <errno.h>
8*f4289cbdSSimon Glass #include <libfdt.h>
97a9219c1SSimon Glass #include <os.h>
10b45122fdSSimon Glass #include <asm/io.h>
115c2859cdSSimon Glass #include <asm/state.h>
126e206504SSimon Glass #include <dm/root.h>
134b0730d2SSimon Glass 
144b0730d2SSimon Glass DECLARE_GLOBAL_DATA_PTR;
154b0730d2SSimon Glass 
169569c406SSimon Glass /* Enable access to PCI memory with map_sysmem() */
179569c406SSimon Glass static bool enable_pci_map;
189569c406SSimon Glass 
199569c406SSimon Glass #ifdef CONFIG_PCI
209569c406SSimon Glass /* Last device that was mapped into memory, and length of mapping */
219569c406SSimon Glass static struct udevice *map_dev;
229569c406SSimon Glass unsigned long map_len;
239569c406SSimon Glass #endif
249569c406SSimon Glass 
255010d98fSSimon Glass void sandbox_exit(void)
264b0730d2SSimon Glass {
278939df09SSimon Glass 	/* Do this here while it still has an effect */
288939df09SSimon Glass 	os_fd_restore();
295c2859cdSSimon Glass 	if (state_uninit())
305c2859cdSSimon Glass 		os_exit(2);
315c2859cdSSimon Glass 
3261336833SSimon Glass 	if (dm_uninit())
3361336833SSimon Glass 		os_exit(2);
3461336833SSimon Glass 
357a9219c1SSimon Glass 	/* This is considered normal termination for now */
367a9219c1SSimon Glass 	os_exit(0);
3788bd0e9dSSimon Glass }
3888bd0e9dSSimon Glass 
394b0730d2SSimon Glass /* delay x useconds */
404b0730d2SSimon Glass void __udelay(unsigned long usec)
414b0730d2SSimon Glass {
429723563aSSimon Glass 	struct sandbox_state *state = state_get_current();
439723563aSSimon Glass 
449723563aSSimon Glass 	if (!state->skip_delays)
45d99a6874SMatthias Weisser 		os_usleep(usec);
464b0730d2SSimon Glass }
474b0730d2SSimon Glass 
484b0730d2SSimon Glass int cleanup_before_linux(void)
494b0730d2SSimon Glass {
504b0730d2SSimon Glass 	return 0;
514b0730d2SSimon Glass }
524b0730d2SSimon Glass 
5329748515SSimon Glass int cleanup_before_linux_select(int flags)
5429748515SSimon Glass {
5529748515SSimon Glass 	return 0;
5629748515SSimon Glass }
5729748515SSimon Glass 
584b0730d2SSimon Glass void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
594b0730d2SSimon Glass {
609569c406SSimon Glass #ifdef CONFIG_PCI
619569c406SSimon Glass 	unsigned long plen = len;
629569c406SSimon Glass 	void *ptr;
639569c406SSimon Glass 
649569c406SSimon Glass 	map_dev = NULL;
659569c406SSimon Glass 	if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) {
669569c406SSimon Glass 		if (plen != len) {
679569c406SSimon Glass 			printf("%s: Warning: partial map at %x, wanted %lx, got %lx\n",
689569c406SSimon Glass 			       __func__, paddr, len, plen);
699569c406SSimon Glass 		}
709569c406SSimon Glass 		map_len = len;
719569c406SSimon Glass 		return ptr;
729569c406SSimon Glass 	}
739569c406SSimon Glass #endif
749569c406SSimon Glass 
758ee666a7SSimon Glass 	return (void *)(gd->arch.ram_buf + paddr);
764b0730d2SSimon Glass }
774b0730d2SSimon Glass 
789569c406SSimon Glass void unmap_physmem(const void *vaddr, unsigned long flags)
799569c406SSimon Glass {
809569c406SSimon Glass #ifdef CONFIG_PCI
819569c406SSimon Glass 	if (map_dev) {
829569c406SSimon Glass 		pci_unmap_physmem(vaddr, map_len, map_dev);
839569c406SSimon Glass 		map_dev = NULL;
849569c406SSimon Glass 	}
859569c406SSimon Glass #endif
869569c406SSimon Glass }
879569c406SSimon Glass 
889569c406SSimon Glass void sandbox_set_enable_pci_map(int enable)
899569c406SSimon Glass {
909569c406SSimon Glass 	enable_pci_map = enable;
919569c406SSimon Glass }
929569c406SSimon Glass 
9366bd1cffSSimon Glass phys_addr_t map_to_sysmem(const void *ptr)
94781adb57SSimon Glass {
95781adb57SSimon Glass 	return (u8 *)ptr - gd->arch.ram_buf;
96781adb57SSimon Glass }
97781adb57SSimon Glass 
984b0730d2SSimon Glass void flush_dcache_range(unsigned long start, unsigned long stop)
994b0730d2SSimon Glass {
1004b0730d2SSimon Glass }
101b45122fdSSimon Glass 
102b45122fdSSimon Glass int sandbox_read_fdt_from_file(void)
103b45122fdSSimon Glass {
104b45122fdSSimon Glass 	struct sandbox_state *state = state_get_current();
105b45122fdSSimon Glass 	const char *fname = state->fdt_fname;
106b45122fdSSimon Glass 	void *blob;
107b45122fdSSimon Glass 	loff_t size;
108b45122fdSSimon Glass 	int err;
109b45122fdSSimon Glass 	int fd;
110b45122fdSSimon Glass 
111b45122fdSSimon Glass 	blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
112b45122fdSSimon Glass 	if (!state->fdt_fname) {
113b45122fdSSimon Glass 		err = fdt_create_empty_tree(blob, 256);
114b45122fdSSimon Glass 		if (!err)
115b45122fdSSimon Glass 			goto done;
116b45122fdSSimon Glass 		printf("Unable to create empty FDT: %s\n", fdt_strerror(err));
117b45122fdSSimon Glass 		return -EINVAL;
118b45122fdSSimon Glass 	}
119b45122fdSSimon Glass 
120b45122fdSSimon Glass 	err = os_get_filesize(fname, &size);
121b45122fdSSimon Glass 	if (err < 0) {
122b45122fdSSimon Glass 		printf("Failed to file FDT file '%s'\n", fname);
123b45122fdSSimon Glass 		return err;
124b45122fdSSimon Glass 	}
125b45122fdSSimon Glass 	fd = os_open(fname, OS_O_RDONLY);
126b45122fdSSimon Glass 	if (fd < 0) {
127b45122fdSSimon Glass 		printf("Failed to open FDT file '%s'\n", fname);
128b45122fdSSimon Glass 		return -EACCES;
129b45122fdSSimon Glass 	}
130b45122fdSSimon Glass 	if (os_read(fd, blob, size) != size) {
131b45122fdSSimon Glass 		os_close(fd);
132b45122fdSSimon Glass 		return -EIO;
133b45122fdSSimon Glass 	}
134b45122fdSSimon Glass 	os_close(fd);
135b45122fdSSimon Glass 
136b45122fdSSimon Glass done:
137b45122fdSSimon Glass 	gd->fdt_blob = blob;
138b45122fdSSimon Glass 
139b45122fdSSimon Glass 	return 0;
140b45122fdSSimon Glass }
141