Xv6驱动(一):PLIC

PLIC文档

riscv/riscv-plic-spec: PLIC Specification (github.com)

PLIC内存布局

文档中规定的PLIC内存映射

其中base address是PLIC内存映射的基地址,由平台实现来指定 

Xv6 PLIC内存映射 

首先通过宏来定义了上面提到的base address,然后再计算基于base address的偏移量,得到其余PLIC寄存器的首地址

#define PLIC 0x0c000000L
#define PLIC_PRIORITY (PLIC + 0x0)
#define PLIC_PENDING (PLIC + 0x1000)
#define PLIC_SENABLE(hart) (PLIC + 0x2080 + (hart) * 0x100)
#define PLIC_SPRIORITY(hart) (PLIC + 0x201000 + (hart) * 0x2000)
#define PLIC_SCLAIM(hart) (PLIC + 0x201004 + (hart) * 0x2000)

Xv6外部中断

外部中断通常是指来自处理器外部设备的中断。

Xv6只支持两个外设:

  • uart0:中断号为10,映射到物理内存0x10000000
  • virtio disk:中断号为1,映射到物理内存0x10001000
// qemu puts UART registers here in physical memory.
#define UART0 0x10000000L
#define UART0_IRQ 10

// virtio mmio interface
#define VIRTIO0 0x10001000
#define VIRTIO0_IRQ 1

PLIC驱动

plicinit函数

同虚拟内存初始化,PLIC的初始化也是两阶段初始化。第一阶段的初始化由cpu0执行,也就是说该函数只执行一次。

该函数的任务是设置中断优先级。Xv6只支持两个外设:UARTvirtio mmio disk,该函数把这两个外设的中断优先级都设置为1。此外,RISC-V规定:如果两个相同优先级的中断同时触发,那么编号小的中断具有较高的优先级。

void plicinit(void)
{
	// set desired IRQ priorities non-zero (otherwise disabled).
	*(uint32 *)(PLIC + UART0_IRQ * 4) = 1;
	*(uint32 *)(PLIC + VIRTIO0_IRQ * 4) = 1;
}

plicinithart函数

该函数是PLIC的第二阶段初始化,每个核心初始化时都要执行这个函数。

该函数会使能S模式下的uart中断和virtio disk中断,并且设置S模式下中断阈值为0

这就说明了:

  1. 如果发生外部中断,那么每个核心都会收到外部中断的信号
  2. 只有一个核心会处理这次外部中断
void plicinithart(void)
{
	int hart = cpuid();

	// set enable bits for this hart's S-mode
	// for the uart and virtio disk.
	*(uint32 *)PLIC_SENABLE(hart) = (1 << UART0_IRQ) | (1 << VIRTIO0_IRQ);

	// set this hart's S-mode priority threshold to 0.
	*(uint32 *)PLIC_SPRIORITY(hart) = 0;
}

plic_claim函数

该函数由异常处理程序调用,用来返回异常号。如果同时有多个中断发生,PLIC硬件会根据之前的配置返回当前待定中断源中优先级最高的那个。其中只有一个核心会得到异常号,其他的核心的返回值是0

int plic_claim(void)
{
	int hart = cpuid();
	int irq = *(uint32 *)PLIC_SCLAIM(hart);
	return irq;
}

plic_complete函数 

中断请求寄存器和中断完成寄存器是同一个寄存器。中断处理程序处理完中断后,会调用该函数,同时将中断号写入该寄存器中。相当于操作系统告诉PLIC硬件:这个中断我已经处理完了,可以接受新的外部中断了

void plic_complete(int irq)
{
	int hart = cpuid();
	*(uint32 *)PLIC_SCLAIM(hart) = irq;
}

参考资料

The xv6 Kernel-27 PLIC_Platform Level Interrupt Controller_哔哩哔哩_bilibili

Lecture 9 - Interrupts 中文版_哔哩哔哩_bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值