xref: /openbmc/u-boot/lib/addr_map.c (revision 7b6e80538b919c814c94ce8887cec7b892f98a71)
178acc472SPeter Tyser /*
278acc472SPeter Tyser  * Copyright 2008 Freescale Semiconductor, Inc.
378acc472SPeter Tyser  *
478acc472SPeter Tyser  * This program is free software; you can redistribute it and/or
578acc472SPeter Tyser  * modify it under the terms of the GNU General Public License
678acc472SPeter Tyser  * Version 2 as published by the Free Software Foundation.
778acc472SPeter Tyser  *
878acc472SPeter Tyser  * This program is distributed in the hope that it will be useful,
978acc472SPeter Tyser  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1078acc472SPeter Tyser  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1178acc472SPeter Tyser  * GNU General Public License for more details.
1278acc472SPeter Tyser  *
1378acc472SPeter Tyser  * You should have received a copy of the GNU General Public License
1478acc472SPeter Tyser  * along with this program; if not, write to the Free Software
1578acc472SPeter Tyser  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
1678acc472SPeter Tyser  * MA 02111-1307 USA
1778acc472SPeter Tyser  */
1878acc472SPeter Tyser 
1978acc472SPeter Tyser #include <common.h>
2078acc472SPeter Tyser #include <addr_map.h>
2178acc472SPeter Tyser 
2278acc472SPeter Tyser static struct {
2378acc472SPeter Tyser 	phys_addr_t paddr;
2478acc472SPeter Tyser 	phys_size_t size;
2578acc472SPeter Tyser 	unsigned long vaddr;
2678acc472SPeter Tyser } address_map[CONFIG_SYS_NUM_ADDR_MAP];
2778acc472SPeter Tyser 
2878acc472SPeter Tyser phys_addr_t addrmap_virt_to_phys(void * vaddr)
2978acc472SPeter Tyser {
3078acc472SPeter Tyser 	int i;
3178acc472SPeter Tyser 
3278acc472SPeter Tyser 	for (i = 0; i < CONFIG_SYS_NUM_ADDR_MAP; i++) {
3378acc472SPeter Tyser 		u64 base, upper, addr;
3478acc472SPeter Tyser 
3578acc472SPeter Tyser 		if (address_map[i].size == 0)
3678acc472SPeter Tyser 			continue;
3778acc472SPeter Tyser 
3878acc472SPeter Tyser 		addr = (u64)((u32)vaddr);
3978acc472SPeter Tyser 		base = (u64)(address_map[i].vaddr);
4078acc472SPeter Tyser 		upper = (u64)(address_map[i].size) + base - 1;
4178acc472SPeter Tyser 
4278acc472SPeter Tyser 		if (addr >= base && addr <= upper) {
4378acc472SPeter Tyser 			return addr - address_map[i].vaddr + address_map[i].paddr;
4478acc472SPeter Tyser 		}
4578acc472SPeter Tyser 	}
4678acc472SPeter Tyser 
4778acc472SPeter Tyser 	return (phys_addr_t)(~0);
4878acc472SPeter Tyser }
4978acc472SPeter Tyser 
50*7b6e8053STimur Tabi void *addrmap_phys_to_virt(phys_addr_t paddr)
5178acc472SPeter Tyser {
5278acc472SPeter Tyser 	int i;
5378acc472SPeter Tyser 
5478acc472SPeter Tyser 	for (i = 0; i < CONFIG_SYS_NUM_ADDR_MAP; i++) {
55*7b6e8053STimur Tabi 		phys_addr_t base, upper;
5678acc472SPeter Tyser 
5778acc472SPeter Tyser 		if (address_map[i].size == 0)
5878acc472SPeter Tyser 			continue;
5978acc472SPeter Tyser 
60*7b6e8053STimur Tabi 		base = address_map[i].paddr;
61*7b6e8053STimur Tabi 		upper = address_map[i].size + base - 1;
6278acc472SPeter Tyser 
63*7b6e8053STimur Tabi 		if (paddr >= base && paddr <= upper) {
64*7b6e8053STimur Tabi 			phys_addr_t offset;
65*7b6e8053STimur Tabi 
66*7b6e8053STimur Tabi 			offset = address_map[i].paddr - address_map[i].vaddr;
67*7b6e8053STimur Tabi 
68*7b6e8053STimur Tabi 			return (void *)(unsigned long)(paddr - offset);
6978acc472SPeter Tyser 		}
7078acc472SPeter Tyser 	}
7178acc472SPeter Tyser 
72*7b6e8053STimur Tabi 	return (void *)(~0);
7378acc472SPeter Tyser }
7478acc472SPeter Tyser 
7578acc472SPeter Tyser void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr,
7678acc472SPeter Tyser 			phys_size_t size, int idx)
7778acc472SPeter Tyser {
7878acc472SPeter Tyser 	if (idx > CONFIG_SYS_NUM_ADDR_MAP)
7978acc472SPeter Tyser 		return;
8078acc472SPeter Tyser 
8178acc472SPeter Tyser 	address_map[idx].vaddr = vaddr;
8278acc472SPeter Tyser 	address_map[idx].paddr = paddr;
8378acc472SPeter Tyser 	address_map[idx].size  = size;
8478acc472SPeter Tyser }
85