thunder_pcie_common.c revision 294991
1/*-
2 * Copyright (c) 2015 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Semihalf under
6 * the sponsorship of the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30/* Common PCIe functions for Cavium Thunder SOC */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/arm64/cavium/thunder_pcie_common.c 294991 2016-01-28 15:34:13Z zbb $");
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/kernel.h>
38#include <sys/bus.h>
39#include <sys/rman.h>
40
41#include <machine/bus.h>
42#include <machine/cpu.h>
43#include <machine/intr.h>
44
45#include "thunder_pcie_common.h"
46
47uint32_t
48range_addr_is_pci(struct pcie_range *ranges, uint64_t addr, uint64_t size)
49{
50	struct pcie_range *r;
51	int tuple;
52
53	for (tuple = 0; tuple < RANGES_TUPLES_MAX; tuple++) {
54		r = &ranges[tuple];
55		if (addr >= r->pci_base &&
56		    addr < (r->pci_base + r->size) &&
57		    size < r->size) {
58			/* Address is within PCI range */
59			return (1);
60		}
61	}
62
63	/* Address is outside PCI range */
64	return (0);
65}
66
67uint32_t
68range_addr_is_phys(struct pcie_range *ranges, uint64_t addr, uint64_t size)
69{
70	struct pcie_range *r;
71	int tuple;
72
73	for (tuple = 0; tuple < RANGES_TUPLES_MAX; tuple++) {
74		r = &ranges[tuple];
75		if (addr >= r->phys_base &&
76		    addr < (r->phys_base + r->size) &&
77		    size < r->size) {
78			/* Address is within Physical range */
79			return (1);
80		}
81	}
82
83	/* Address is outside Physical range */
84	return (0);
85}
86
87uint64_t
88range_addr_pci_to_phys(struct pcie_range *ranges, uint64_t pci_addr)
89{
90	struct pcie_range *r;
91	uint64_t offset;
92	int tuple;
93
94	/* Find physical address corresponding to given bus address */
95	for (tuple = 0; tuple < RANGES_TUPLES_MAX; tuple++) {
96		r = &ranges[tuple];
97		if (pci_addr >= r->pci_base &&
98		    pci_addr < (r->pci_base + r->size)) {
99			/* Given pci addr is in this range.
100			 * Translate bus addr to phys addr.
101			 */
102			offset = pci_addr - r->pci_base;
103			return (r->phys_base + offset);
104		}
105	}
106	return (0);
107}
108
109