Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
17628bc6
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
17628bc6
编写于
15年前
作者:
E
Edgar E. Iglesias
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
xilinx: Add interrupt controller.
Signed-off-by:
N
Edgar E. Iglesias
<
edgar.iglesias@gmail.com
>
上级
1f07fd1f
无相关合并请求
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
167 addition
and
0 deletion
+167
-0
hw/xilinx_intc.c
hw/xilinx_intc.c
+167
-0
未找到文件。
hw/xilinx_intc.c
0 → 100644
浏览文件 @
17628bc6
/*
* QEMU Xilinx OPB Interrupt Controller.
*
* Copyright (c) 2009 Edgar E. Iglesias.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "sysbus.h"
#include "hw.h"
#define D(x)
#define R_ISR 0
#define R_IPR 1
#define R_IER 2
#define R_IAR 3
#define R_SIE 4
#define R_CIE 5
#define R_IVR 6
#define R_MER 7
#define R_MAX 8
struct
xlx_pic
{
SysBusDevice
busdev
;
qemu_irq
parent_irq
;
/* Configuration reg chosen at synthesis-time. QEMU populates
the bits at board-setup. */
uint32_t
c_kind_of_intr
;
/* Runtime control registers. */
uint32_t
regs
[
R_MAX
];
};
static
void
update_irq
(
struct
xlx_pic
*
p
)
{
uint32_t
i
;
/* Update the pending register. */
p
->
regs
[
R_IPR
]
=
p
->
regs
[
R_ISR
]
&
p
->
regs
[
R_IER
];
/* Update the vector register. */
for
(
i
=
0
;
i
<
32
;
i
++
)
{
if
(
p
->
regs
[
R_IPR
]
&
(
1
<<
i
))
break
;
}
if
(
i
==
32
)
i
=
~
0
;
p
->
regs
[
R_IVR
]
=
i
;
if
((
p
->
regs
[
R_MER
]
&
1
)
&&
p
->
regs
[
R_IPR
])
{
qemu_irq_raise
(
p
->
parent_irq
);
}
else
{
qemu_irq_lower
(
p
->
parent_irq
);
}
}
static
uint32_t
pic_readl
(
void
*
opaque
,
target_phys_addr_t
addr
)
{
struct
xlx_pic
*
p
=
opaque
;
uint32_t
r
=
0
;
addr
>>=
2
;
switch
(
addr
)
{
default:
if
(
addr
<
ARRAY_SIZE
(
p
->
regs
))
r
=
p
->
regs
[
addr
];
break
;
}
D
(
printf
(
"%s %x=%x
\n
"
,
__func__
,
addr
*
4
,
r
));
return
r
;
}
static
void
pic_writel
(
void
*
opaque
,
target_phys_addr_t
addr
,
uint32_t
value
)
{
struct
xlx_pic
*
p
=
opaque
;
addr
>>=
2
;
D
(
qemu_log
(
"%s addr=%x val=%x
\n
"
,
__func__
,
addr
*
4
,
value
));
switch
(
addr
)
{
case
R_IAR
:
p
->
regs
[
R_ISR
]
&=
~
value
;
/* ACK. */
break
;
case
R_SIE
:
p
->
regs
[
R_IER
]
|=
value
;
/* Atomic set ie. */
break
;
case
R_CIE
:
p
->
regs
[
R_IER
]
&=
~
value
;
/* Atomic clear ie. */
break
;
default:
if
(
addr
<
ARRAY_SIZE
(
p
->
regs
))
p
->
regs
[
addr
]
=
value
;
break
;
}
update_irq
(
p
);
}
static
CPUReadMemoryFunc
*
pic_read
[]
=
{
NULL
,
NULL
,
&
pic_readl
,
};
static
CPUWriteMemoryFunc
*
pic_write
[]
=
{
NULL
,
NULL
,
&
pic_writel
,
};
static
void
irq_handler
(
void
*
opaque
,
int
irq
,
int
level
)
{
struct
xlx_pic
*
p
=
opaque
;
if
(
!
(
p
->
regs
[
R_MER
]
&
2
))
{
qemu_irq_lower
(
p
->
parent_irq
);
return
;
}
/* Update source flops. Don't clear unless level triggered.
Edge triggered interrupts only go away when explicitely acked to
the interrupt controller. */
if
(
!
(
p
->
c_kind_of_intr
&
(
1
<<
irq
))
||
level
)
{
p
->
regs
[
R_ISR
]
&=
~
(
1
<<
irq
);
p
->
regs
[
R_ISR
]
|=
(
level
<<
irq
);
}
update_irq
(
p
);
}
static
void
xilinx_intc_init
(
SysBusDevice
*
dev
)
{
struct
xlx_pic
*
p
=
FROM_SYSBUS
(
typeof
(
*
p
),
dev
);
int
pic_regs
;
p
->
c_kind_of_intr
=
qdev_get_prop_int
(
&
dev
->
qdev
,
"kind-of-intr"
,
0
);
qdev_init_gpio_in
(
&
dev
->
qdev
,
irq_handler
,
32
);
sysbus_init_irq
(
dev
,
&
p
->
parent_irq
);
pic_regs
=
cpu_register_io_memory
(
0
,
pic_read
,
pic_write
,
p
);
sysbus_init_mmio
(
dev
,
R_MAX
*
4
,
pic_regs
);
}
static
void
xilinx_intc_register
(
void
)
{
sysbus_register_dev
(
"xilinx,intc"
,
sizeof
(
struct
xlx_pic
),
xilinx_intc_init
);
}
device_init
(
xilinx_intc_register
)
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
反馈
建议
客服
返回
顶部