Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gsplhtlxg
clone-Linux
提交
f9a22239
C
clone-Linux
项目概览
gsplhtlxg
/
clone-Linux
通知
2
Star
0
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
clone-Linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f9a22239
编写于
6月 01, 2005
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Automatic merge of
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
上级
eff910a9
88314ee7
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
92 addition
and
32 deletion
+92
-32
arch/sparc64/kernel/pci_iommu.c
arch/sparc64/kernel/pci_iommu.c
+68
-20
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/pci_psycho.c
+1
-1
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_sabre.c
+1
-1
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/pci_schizo.c
+1
-1
arch/sparc64/kernel/sbus.c
arch/sparc64/kernel/sbus.c
+14
-6
include/asm-sparc64/iommu.h
include/asm-sparc64/iommu.h
+2
-0
include/asm-sparc64/pbm.h
include/asm-sparc64/pbm.h
+5
-3
未找到文件。
arch/sparc64/kernel/pci_iommu.c
浏览文件 @
f9a22239
...
...
@@ -196,6 +196,34 @@ static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long
return
NULL
;
}
static
int
iommu_alloc_ctx
(
struct
pci_iommu
*
iommu
)
{
int
lowest
=
iommu
->
ctx_lowest_free
;
int
sz
=
IOMMU_NUM_CTXS
-
lowest
;
int
n
=
find_next_zero_bit
(
iommu
->
ctx_bitmap
,
sz
,
lowest
);
if
(
unlikely
(
n
==
sz
))
{
n
=
find_next_zero_bit
(
iommu
->
ctx_bitmap
,
lowest
,
1
);
if
(
unlikely
(
n
==
lowest
))
{
printk
(
KERN_WARNING
"IOMMU: Ran out of contexts.
\n
"
);
n
=
0
;
}
}
if
(
n
)
__set_bit
(
n
,
iommu
->
ctx_bitmap
);
return
n
;
}
static
inline
void
iommu_free_ctx
(
struct
pci_iommu
*
iommu
,
int
ctx
)
{
if
(
likely
(
ctx
))
{
__clear_bit
(
ctx
,
iommu
->
ctx_bitmap
);
if
(
ctx
<
iommu
->
ctx_lowest_free
)
iommu
->
ctx_lowest_free
=
ctx
;
}
}
/* Allocate and map kernel buffer of size SIZE using consistent mode
* DMA for PCI device PDEV. Return non-NULL cpu-side address if
* successful and set *DMA_ADDRP to the PCI side dma address.
...
...
@@ -236,7 +264,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
npages
=
size
>>
IO_PAGE_SHIFT
;
ctx
=
0
;
if
(
iommu
->
iommu_ctxflush
)
ctx
=
iommu
->
iommu_cur_ctx
++
;
ctx
=
iommu
_alloc_ctx
(
iommu
)
;
first_page
=
__pa
(
first_page
);
while
(
npages
--
)
{
iopte_val
(
*
iopte
)
=
(
IOPTE_CONSISTENT
(
ctx
)
|
...
...
@@ -317,6 +345,8 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_
}
}
iommu_free_ctx
(
iommu
,
ctx
);
spin_unlock_irqrestore
(
&
iommu
->
lock
,
flags
);
order
=
get_order
(
size
);
...
...
@@ -360,7 +390,7 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
base_paddr
=
__pa
(
oaddr
&
IO_PAGE_MASK
);
ctx
=
0
;
if
(
iommu
->
iommu_ctxflush
)
ctx
=
iommu
->
iommu_cur_ctx
++
;
ctx
=
iommu
_alloc_ctx
(
iommu
)
;
if
(
strbuf
->
strbuf_enabled
)
iopte_protection
=
IOPTE_STREAMING
(
ctx
);
else
...
...
@@ -380,39 +410,53 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
return
PCI_DMA_ERROR_CODE
;
}
static
void
pci_strbuf_flush
(
struct
pci_strbuf
*
strbuf
,
struct
pci_iommu
*
iommu
,
u32
vaddr
,
unsigned
long
ctx
,
unsigned
long
npages
)
static
void
pci_strbuf_flush
(
struct
pci_strbuf
*
strbuf
,
struct
pci_iommu
*
iommu
,
u32
vaddr
,
unsigned
long
ctx
,
unsigned
long
npages
,
int
direction
)
{
int
limit
;
PCI_STC_FLUSHFLAG_INIT
(
strbuf
);
if
(
strbuf
->
strbuf_ctxflush
&&
iommu
->
iommu_ctxflush
)
{
unsigned
long
matchreg
,
flushreg
;
u64
val
;
flushreg
=
strbuf
->
strbuf_ctxflush
;
matchreg
=
PCI_STC_CTXMATCH_ADDR
(
strbuf
,
ctx
);
limit
=
100000
;
pci_iommu_write
(
flushreg
,
ctx
);
for
(;;)
{
if
(((
long
)
pci_iommu_read
(
matchreg
))
>=
0L
)
break
;
limit
--
;
if
(
!
limit
)
break
;
udelay
(
1
);
val
=
pci_iommu_read
(
matchreg
);
val
&=
0xffff
;
if
(
!
val
)
goto
do_flush_sync
;
while
(
val
)
{
if
(
val
&
0x1
)
pci_iommu_write
(
flushreg
,
ctx
);
val
>>=
1
;
}
if
(
!
limit
)
val
=
pci_iommu_read
(
matchreg
);
if
(
unlikely
(
val
))
{
printk
(
KERN_WARNING
"pci_strbuf_flush: ctx flush "
"timeout vaddr[%08x] ctx[%lx]
\n
"
,
vaddr
,
ctx
);
"timeout matchreg[%lx] ctx[%lx]
\n
"
,
val
,
ctx
);
goto
do_page_flush
;
}
}
else
{
unsigned
long
i
;
do_page_flush:
for
(
i
=
0
;
i
<
npages
;
i
++
,
vaddr
+=
IO_PAGE_SIZE
)
pci_iommu_write
(
strbuf
->
strbuf_pflush
,
vaddr
);
}
do_flush_sync:
/* If the device could not have possibly put dirty data into
* the streaming cache, no flush-flag synchronization needs
* to be performed.
*/
if
(
direction
==
PCI_DMA_TODEVICE
)
return
;
PCI_STC_FLUSHFLAG_INIT
(
strbuf
);
pci_iommu_write
(
strbuf
->
strbuf_fsync
,
strbuf
->
strbuf_flushflag_pa
);
(
void
)
pci_iommu_read
(
iommu
->
write_complete_reg
);
...
...
@@ -466,7 +510,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
/* Step 1: Kick data out of streaming buffers if necessary. */
if
(
strbuf
->
strbuf_enabled
)
pci_strbuf_flush
(
strbuf
,
iommu
,
bus_addr
,
ctx
,
npages
);
pci_strbuf_flush
(
strbuf
,
iommu
,
bus_addr
,
ctx
,
npages
,
direction
);
/* Step 2: Clear out first TSB entry. */
iopte_make_dummy
(
iommu
,
base
);
...
...
@@ -474,6 +518,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
free_streaming_cluster
(
iommu
,
bus_addr
-
iommu
->
page_table_map_base
,
npages
,
ctx
);
iommu_free_ctx
(
iommu
,
ctx
);
spin_unlock_irqrestore
(
&
iommu
->
lock
,
flags
);
}
...
...
@@ -613,7 +659,7 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int
/* Step 4: Choose a context if necessary. */
ctx
=
0
;
if
(
iommu
->
iommu_ctxflush
)
ctx
=
iommu
->
iommu_cur_ctx
++
;
ctx
=
iommu
_alloc_ctx
(
iommu
)
;
/* Step 5: Create the mappings. */
if
(
strbuf
->
strbuf_enabled
)
...
...
@@ -678,7 +724,7 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
/* Step 1: Kick data out of streaming buffers if necessary. */
if
(
strbuf
->
strbuf_enabled
)
pci_strbuf_flush
(
strbuf
,
iommu
,
bus_addr
,
ctx
,
npages
);
pci_strbuf_flush
(
strbuf
,
iommu
,
bus_addr
,
ctx
,
npages
,
direction
);
/* Step 2: Clear out first TSB entry. */
iopte_make_dummy
(
iommu
,
base
);
...
...
@@ -686,6 +732,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
free_streaming_cluster
(
iommu
,
bus_addr
-
iommu
->
page_table_map_base
,
npages
,
ctx
);
iommu_free_ctx
(
iommu
,
ctx
);
spin_unlock_irqrestore
(
&
iommu
->
lock
,
flags
);
}
...
...
@@ -724,7 +772,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size
}
/* Step 2: Kick data out of streaming buffers. */
pci_strbuf_flush
(
strbuf
,
iommu
,
bus_addr
,
ctx
,
npages
);
pci_strbuf_flush
(
strbuf
,
iommu
,
bus_addr
,
ctx
,
npages
,
direction
);
spin_unlock_irqrestore
(
&
iommu
->
lock
,
flags
);
}
...
...
@@ -768,7 +816,7 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
i
--
;
npages
=
(
IO_PAGE_ALIGN
(
sglist
[
i
].
dma_address
+
sglist
[
i
].
dma_length
)
-
bus_addr
)
>>
IO_PAGE_SHIFT
;
pci_strbuf_flush
(
strbuf
,
iommu
,
bus_addr
,
ctx
,
npages
);
pci_strbuf_flush
(
strbuf
,
iommu
,
bus_addr
,
ctx
,
npages
,
direction
);
spin_unlock_irqrestore
(
&
iommu
->
lock
,
flags
);
}
...
...
arch/sparc64/kernel/pci_psycho.c
浏览文件 @
f9a22239
...
...
@@ -1212,7 +1212,7 @@ static void __init psycho_iommu_init(struct pci_controller_info *p)
/* Setup initial software IOMMU state. */
spin_lock_init
(
&
iommu
->
lock
);
iommu
->
iommu_cur_ctx
=
0
;
iommu
->
ctx_lowest_free
=
1
;
/* Register addresses. */
iommu
->
iommu_control
=
p
->
pbm_A
.
controller_regs
+
PSYCHO_IOMMU_CONTROL
;
...
...
arch/sparc64/kernel/pci_sabre.c
浏览文件 @
f9a22239
...
...
@@ -1265,7 +1265,7 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
/* Setup initial software IOMMU state. */
spin_lock_init
(
&
iommu
->
lock
);
iommu
->
iommu_cur_ctx
=
0
;
iommu
->
ctx_lowest_free
=
1
;
/* Register addresses. */
iommu
->
iommu_control
=
p
->
pbm_A
.
controller_regs
+
SABRE_IOMMU_CONTROL
;
...
...
arch/sparc64/kernel/pci_schizo.c
浏览文件 @
f9a22239
...
...
@@ -1753,7 +1753,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
/* Setup initial software IOMMU state. */
spin_lock_init
(
&
iommu
->
lock
);
iommu
->
iommu_cur_ctx
=
0
;
iommu
->
ctx_lowest_free
=
1
;
/* Register addresses, SCHIZO has iommu ctx flushing. */
iommu
->
iommu_control
=
pbm
->
pbm_regs
+
SCHIZO_IOMMU_CONTROL
;
...
...
arch/sparc64/kernel/sbus.c
浏览文件 @
f9a22239
...
...
@@ -117,17 +117,25 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages
#define STRBUF_TAG_VALID 0x02UL
static
void
sbus_strbuf_flush
(
struct
sbus_iommu
*
iommu
,
u32
base
,
unsigned
long
npages
)
static
void
sbus_strbuf_flush
(
struct
sbus_iommu
*
iommu
,
u32
base
,
unsigned
long
npages
,
int
direction
)
{
unsigned
long
n
;
int
limit
;
iommu
->
strbuf_flushflag
=
0UL
;
n
=
npages
;
while
(
n
--
)
upa_writeq
(
base
+
(
n
<<
IO_PAGE_SHIFT
),
iommu
->
strbuf_regs
+
STRBUF_PFLUSH
);
/* If the device could not have possibly put dirty data into
* the streaming cache, no flush-flag synchronization needs
* to be performed.
*/
if
(
direction
==
SBUS_DMA_TODEVICE
)
return
;
iommu
->
strbuf_flushflag
=
0UL
;
/* Whoopee cushion! */
upa_writeq
(
__pa
(
&
iommu
->
strbuf_flushflag
),
iommu
->
strbuf_regs
+
STRBUF_FSYNC
);
...
...
@@ -421,7 +429,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size,
spin_lock_irqsave
(
&
iommu
->
lock
,
flags
);
free_streaming_cluster
(
iommu
,
dma_base
,
size
>>
IO_PAGE_SHIFT
);
sbus_strbuf_flush
(
iommu
,
dma_base
,
size
>>
IO_PAGE_SHIFT
);
sbus_strbuf_flush
(
iommu
,
dma_base
,
size
>>
IO_PAGE_SHIFT
,
direction
);
spin_unlock_irqrestore
(
&
iommu
->
lock
,
flags
);
}
...
...
@@ -584,7 +592,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int
iommu
=
sdev
->
bus
->
iommu
;
spin_lock_irqsave
(
&
iommu
->
lock
,
flags
);
free_streaming_cluster
(
iommu
,
dvma_base
,
size
>>
IO_PAGE_SHIFT
);
sbus_strbuf_flush
(
iommu
,
dvma_base
,
size
>>
IO_PAGE_SHIFT
);
sbus_strbuf_flush
(
iommu
,
dvma_base
,
size
>>
IO_PAGE_SHIFT
,
direction
);
spin_unlock_irqrestore
(
&
iommu
->
lock
,
flags
);
}
...
...
@@ -596,7 +604,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t
size
=
(
IO_PAGE_ALIGN
(
base
+
size
)
-
(
base
&
IO_PAGE_MASK
));
spin_lock_irqsave
(
&
iommu
->
lock
,
flags
);
sbus_strbuf_flush
(
iommu
,
base
&
IO_PAGE_MASK
,
size
>>
IO_PAGE_SHIFT
);
sbus_strbuf_flush
(
iommu
,
base
&
IO_PAGE_MASK
,
size
>>
IO_PAGE_SHIFT
,
direction
);
spin_unlock_irqrestore
(
&
iommu
->
lock
,
flags
);
}
...
...
@@ -620,7 +628,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int
size
=
IO_PAGE_ALIGN
(
sg
[
i
].
dma_address
+
sg
[
i
].
dma_length
)
-
base
;
spin_lock_irqsave
(
&
iommu
->
lock
,
flags
);
sbus_strbuf_flush
(
iommu
,
base
,
size
>>
IO_PAGE_SHIFT
);
sbus_strbuf_flush
(
iommu
,
base
,
size
>>
IO_PAGE_SHIFT
,
direction
);
spin_unlock_irqrestore
(
&
iommu
->
lock
,
flags
);
}
...
...
include/asm-sparc64/iommu.h
浏览文件 @
f9a22239
...
...
@@ -16,4 +16,6 @@
#define IOPTE_CACHE 0x0000000000000010UL
/* Cached (in UPA E-cache) */
#define IOPTE_WRITE 0x0000000000000002UL
/* Writeable */
#define IOMMU_NUM_CTXS 4096
#endif
/* !(_SPARC_IOMMU_H) */
include/asm-sparc64/pbm.h
浏览文件 @
f9a22239
...
...
@@ -15,6 +15,7 @@
#include <asm/io.h>
#include <asm/page.h>
#include <asm/oplib.h>
#include <asm/iommu.h>
/* The abstraction used here is that there are PCI controllers,
* each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules
...
...
@@ -40,9 +41,6 @@ struct pci_iommu {
*/
spinlock_t
lock
;
/* Context allocator. */
unsigned
int
iommu_cur_ctx
;
/* IOMMU page table, a linear array of ioptes. */
iopte_t
*
page_table
;
/* The page table itself. */
int
page_table_sz_bits
;
/* log2 of ow many pages does it map? */
...
...
@@ -87,6 +85,10 @@ struct pci_iommu {
u16
flush
;
}
alloc_info
[
PBM_NCLUSTERS
];
/* CTX allocation. */
unsigned
long
ctx_lowest_free
;
unsigned
long
ctx_bitmap
[
IOMMU_NUM_CTXS
/
(
sizeof
(
unsigned
long
)
*
8
)];
/* Here a PCI controller driver describes the areas of
* PCI memory space where DMA to/from physical memory
* are addressed. Drivers interrogate the PCI layer
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录