summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4u/sys/iommu.h
blob: 947427280d2513ae3323994660957beb2aaa94a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1991-2000 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef _SYS_IOMMU_H
#define	_SYS_IOMMU_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#if defined(_KERNEL) && !defined(_ASM)
#include <sys/sunddi.h>
#include <sys/sysiosbus.h>
#include <sys/ddi_impldefs.h>
#endif /* defined(_KERNEL) && !defined(_ASM) */

#ifdef	__cplusplus
extern "C" {
#endif

#ifndef _ASM
/* constants for DVMA */
/*
 * It takes an 8byte TSB entry to map i an 8k page, so the conversion
 * from tsb size to dvma mapping is to multiply by 1000 or 0x400
 * left shift by 10 does this
 */
#define	IOMMU_TSB_TO_RNG	0xa
#define	IOMMU_TSB_SIZE_8M	0x2000
#define	IOMMU_TSB_SIZE_16M	0x4000
#define	IOMMU_TSB_SIZE_32M	0x8000
#define	IOMMU_TSB_SIZE_64M	0x10000
#define	IOMMU_TSB_SIZE_128M	0x20000
#define	IOMMU_TSB_SIZE_256M	0x40000
#define	IOMMU_TSB_SIZE_512M	0x80000
#define	IOMMU_TSB_SIZE_1G	0x100000

#define	IOMMU_PAGESIZE		0x2000		/* 8k page */
#define	IOMMU_PAGEMASK		0x1fff
#define	IOMMU_PAGEOFFSET	(IOMMU_PAGESIZE - 1)
#define	IOMMU_N_TTES		(IOMMU_DVMA_RANGE/IOMMU_PAGESIZE)
#define	IOMMU_TSB_TBL_SIZE	(IOMMU_N_TTES << 3)	/* 8B for each entry */
#define	IOMMU_PAGESHIFT		13

#define	OFF_IOMMU_CTRL_REG	0x2400
#define	IOMMU_CTRL_REG_SIZE	(NATURAL_REG_SIZE)
#define	OFF_TSB_BASE_ADDR	0x2408
#define	TSB_BASE_ADDR_SIZE	(NATURAL_REG_SIZE)
#define	OFF_IOMMU_FLUSH_REG	0x2410
#define	IOMMU_FLUSH_REG		(NATURAL_REG_SIZE)
#define	OFF_IOMMU_TLB_TAG	0x4580
#define	OFF_IOMMU_TLB_DATA	0x4600

#define	TSB_SIZE		3		/* 64M of DVMA */
#define	TSB_SIZE_SHIFT		16
#define	IOMMU_TLB_ENTRIES	16

#define	IOMMU_DISABLE		0		/* Turns off the IOMMU */
#define	IOMMU_ENABLE		1		/* Turns on the IOMMU */
#define	IOMMU_TLB_VALID		0x40000000ull
#define	IOMMU_DIAG_ENABLE	0x2ull

/*
 * Bit positions in the TLB entries
 */
#define	IOMMU_TLBTAG_WRITABLE	(1 << 21)
#define	IOMMU_TLBTAB_STREAM	(1 << 20)
#define	IOMMU_TLBTAG_SIZE	(1 << 19)
#define	IOMMU_TLBTAG_VA_MASK	0x7ffff	/* 19-bit vpn */
#define	IOMMU_TLBTAG_VA_SHIFT	13

#define	IOMMU_TLBDATA_VALID	(1 << 30)
#define	IOMMU_TLBDATA_LOCAL	(1 << 29)
#define	IOMMU_TLBDATA_CACHEABLE	(1 << 28)
#define	IOMMU_TLBDATA_PA_MASK	0xfffffff /* 28-bit ppn */
#define	IOMMU_TLBDATA_PA_SHIFT	13

/*
 * define IOPTEs
 */
#define	IOTTE_PFN_MSK	0x1ffffffe000ull
#define	IOTTE_CACHE	0x10ull
#define	IOTTE_WRITE	0x2ull
#define	IOTTE_STREAM	0x1000000000000000ull
#define	IOTTE_INTRA	0x800000000000000ull
#define	IOTTE_64K_PAGE	0x2000000000000000ull
#endif	/* _ASM */
#define	IOTTE_VALID	0x8000000000000000ull
#define	IOTTE_PFN_SHIFT 13

/*
 * IOMMU pages to bytes, and back (with and without rounding)
 */
#define	iommu_ptob(x)	((x) << IOMMU_PAGESHIFT)
#define	iommu_btop(x)	(((ioaddr_t)(x)) >> IOMMU_PAGESHIFT)
#define	iommu_btopr(x)	\
	((((ioaddr_t)(x) + IOMMU_PAGEOFFSET) >> IOMMU_PAGESHIFT))

#if defined(_KERNEL) && !defined(_ASM)

/* sbus nexus private dma mapping structure. */
struct dma_impl_priv {
	ddi_dma_impl_t mp;
	struct sbus_soft_state *softsp;
	volatile int sync_flag;
	uint64_t phys_sync_flag;
};

extern int iommu_init(struct sbus_soft_state *, caddr_t);
extern int iommu_resume_init(struct sbus_soft_state *);
extern int iommu_dma_mctl(dev_info_t *, dev_info_t *, ddi_dma_handle_t,
	enum ddi_dma_ctlops, off_t *, size_t *, caddr_t *, uint_t);
extern int iommu_dma_map(dev_info_t *, dev_info_t *, struct ddi_dma_req *,
	ddi_dma_handle_t *);
extern int iommu_dma_allochdl(dev_info_t *, dev_info_t *, ddi_dma_attr_t *,
	int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *);
extern int iommu_dma_freehdl(dev_info_t *, dev_info_t *, ddi_dma_handle_t);
extern int iommu_dma_bindhdl(dev_info_t *, dev_info_t *, ddi_dma_handle_t,
	struct ddi_dma_req *, ddi_dma_cookie_t *, uint_t *);
extern int iommu_dma_unbindhdl(dev_info_t *, dev_info_t *, ddi_dma_handle_t);
extern int iommu_dma_flush(dev_info_t *, dev_info_t *, ddi_dma_handle_t,
	off_t, size_t, uint_t);
extern int iommu_dma_win(dev_info_t *, dev_info_t *, ddi_dma_handle_t,
	uint_t, off_t *, size_t *, ddi_dma_cookie_t *, uint_t *);

extern void iommu_dvma_kaddr_load(ddi_dma_handle_t h, caddr_t a, uint_t len,
    uint_t index, ddi_dma_cookie_t *cp);

extern void iommu_dvma_unload(ddi_dma_handle_t h, uint_t objindex, uint_t view);

extern void iommu_dvma_sync(ddi_dma_handle_t h, uint_t objindex, uint_t view);

#endif /* _KERNEL && !_ASM */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_IOMMU_H */