mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 08:06:32 +00:00
改用int250作为系统调用
This commit is contained in:
@ -436,7 +436,6 @@ void apic_init()
|
||||
{
|
||||
RCBA_vaddr = 0;
|
||||
kwarn("Cannot get RCBA address. RCBA_phys=%#010lx", RCBA_phys);
|
||||
|
||||
}
|
||||
sti();
|
||||
}
|
||||
@ -448,50 +447,60 @@ void apic_init()
|
||||
*/
|
||||
void do_IRQ(struct pt_regs *rsp, ul number)
|
||||
{
|
||||
switch (number & 0x80) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC
|
||||
|
||||
if (number < 0x80) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC
|
||||
|
||||
// 外部中断控制器
|
||||
{
|
||||
case 0x00: // 外部中断控制器
|
||||
/* code */
|
||||
irq_desc_t *irq = &interrupt_desc[number - 32];
|
||||
|
||||
// 执行中断上半部处理程序
|
||||
if (irq->handler != NULL)
|
||||
irq->handler(number, irq->parameter, rsp);
|
||||
else
|
||||
kwarn("Intr vector [%d] does not have a handler!");
|
||||
|
||||
// 向中断控制器发送应答消息
|
||||
if (irq->controller != NULL && irq->controller->ack != NULL)
|
||||
irq->controller->ack(number);
|
||||
else
|
||||
{
|
||||
irq_desc_t *irq = &interrupt_desc[number - 32];
|
||||
|
||||
// 执行中断上半部处理程序
|
||||
if (irq->handler != NULL)
|
||||
irq->handler(number, irq->parameter, rsp);
|
||||
else
|
||||
kwarn("Intr vector [%d] does not have a handler!");
|
||||
|
||||
// 向中断控制器发送应答消息
|
||||
if (irq->controller != NULL && irq->controller->ack != NULL)
|
||||
irq->controller->ack(number);
|
||||
else
|
||||
{
|
||||
|
||||
// 向EOI寄存器写入0x00表示结束中断
|
||||
__asm__ __volatile__("movq $0x00, %%rdx \n\t"
|
||||
"movq $0x00, %%rax \n\t"
|
||||
"movq $0x80b, %%rcx \n\t"
|
||||
"wrmsr \n\t" ::
|
||||
: "memory");
|
||||
}
|
||||
// 向EOI寄存器写入0x00表示结束中断
|
||||
__asm__ __volatile__("movq $0x00, %%rdx \n\t"
|
||||
"movq $0x00, %%rax \n\t"
|
||||
"movq $0x80b, %%rcx \n\t"
|
||||
"wrmsr \n\t" ::
|
||||
: "memory");
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
}
|
||||
|
||||
else if (number >= 0x80 && number != 250)
|
||||
|
||||
{
|
||||
printk_color(RED, BLACK, "SMP IPI [ %d ]\n", number);
|
||||
apic_local_apic_edge_ack(number);
|
||||
default:
|
||||
}
|
||||
else if (number == 250) // 系统调用
|
||||
{
|
||||
kdebug("receive syscall");
|
||||
kdebug("rflags=%#010lx", rsp->rflags);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
kwarn("do IRQ receive: %d", number);
|
||||
break;
|
||||
}
|
||||
|
||||
// 检测是否有未处理的软中断
|
||||
if (softirq_status != 0)
|
||||
do_softirq();
|
||||
|
||||
// 检测当前进程是否可被调度
|
||||
struct process_control_block *current_proc = get_current_pcb();
|
||||
if (current_proc->flags & PROC_NEED_SCHED)
|
||||
if (current_pcb->flags & PROC_NEED_SCHED)
|
||||
{
|
||||
sched_cfs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,6 +50,7 @@ hardware_intr_controller HPET_intr_controller =
|
||||
|
||||
void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
|
||||
{
|
||||
printk("(HPET)");
|
||||
switch (param)
|
||||
{
|
||||
case 0: // 定时器0中断
|
||||
@ -73,7 +74,10 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
|
||||
}
|
||||
|
||||
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
|
||||
{
|
||||
current_pcb->flags |= PROC_NEED_SCHED;
|
||||
kdebug("need_sched. proc_jiffies=%ld", sched_cfs_ready_queue.cpu_exec_proc_jiffies);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -138,7 +142,7 @@ int HPET_init()
|
||||
// 由于这段内存与io/apic的映射在同一物理页内,因此不需要重复映射
|
||||
HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + hpet_table->address;
|
||||
}
|
||||
|
||||
|
||||
// 读取计时精度并计算频率
|
||||
uint64_t tmp;
|
||||
tmp = *(uint64_t *)(HPET_REG_BASE + GCAP_ID);
|
||||
@ -152,18 +156,22 @@ int HPET_init()
|
||||
// 使用I/O APIC 的IRQ2接收hpet定时器0的中断
|
||||
apic_make_rte_entry(&entry, 34, IO_APIC_FIXED, DEST_PHYSICAL, IDLE, POLARITY_HIGH, IRR_RESET, EDGE_TRIGGER, MASKED, 0);
|
||||
|
||||
*(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位
|
||||
io_mfence();
|
||||
|
||||
|
||||
*(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0;
|
||||
io_mfence();
|
||||
*(uint64_t *)(HPET_REG_BASE + TIM0_CONF) = 0x004c; // 设置定时器0为周期定时,边沿触发,投递到IO APIC的2号引脚(这里有点绕,写的是8259的引脚号,但是因为禁用了8259,因此会被路由到IO APIC的2号引脚)
|
||||
io_mfence();
|
||||
*(uint64_t *)(HPET_REG_BASE + TIM0_COMP) = HPET_freq; // 1s触发一次中断
|
||||
io_mfence();
|
||||
|
||||
rtc_get_cmos_time(&rtc_now);
|
||||
*(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0;
|
||||
|
||||
|
||||
|
||||
kinfo("HPET Initialized.");
|
||||
*(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位
|
||||
io_mfence();
|
||||
// 注册中断
|
||||
irq_register(34, &entry, &HPET_handler, 0, &HPET_intr_controller, "HPET0");
|
||||
kinfo("HPET Initialized.");
|
||||
}
|
@ -22,7 +22,7 @@ enum CMOSTimeSelector
|
||||
int rtc_get_cmos_time(struct rtc_time_t *t)
|
||||
{
|
||||
// 为防止中断请求打断该过程,需要先关中断
|
||||
//cli();
|
||||
cli();
|
||||
|
||||
uint8_t status_register_B = read_cmos(0x0B); // 读取状态寄存器B
|
||||
bool is_24h = ((status_register_B & 0x02) ? true : false); // 判断是否启用24小时模式
|
||||
@ -53,6 +53,6 @@ int rtc_get_cmos_time(struct rtc_time_t *t)
|
||||
|
||||
if ((!is_24h) && t->hour & 0x80) // 将十二小时制转为24小时
|
||||
t->hour = ((t->hour & 0x7f) + 12) % 24;
|
||||
//sti();
|
||||
sti();
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user