OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 9:35 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Help me make interrupts working
PostPosted: Wed Mar 24, 2021 4:53 am 
Offline

Joined: Tue Jul 07, 2020 3:18 pm
Posts: 15
Trying to make interrupts working in my 64-bit higher half kernel.
github repo:
https://github.com/JustVic/kernel_interrupts


all interupts code in this three files:
trap.h, trap.c, trap.S
trap.h:
Code:
#ifndef _TRAP_H_
#define _TRAP_H_

#include "stdint.h"

struct IdtEntry{
    uint16_t low;
    uint16_t selector;
    uint8_t res0;
    uint8_t attr;
    uint16_t mid;
    uint32_t high;
    uint32_t res1;
} __attribute__((packed));


struct IdtPtr {
    uint16_t limit;
    uint64_t addr;
} __attribute__((packed));


struct TrapFrame {
    int64_t r15;
    int64_t r14;
    int64_t r13;
    int64_t r12;
    int64_t r11;
    int64_t r10;
    int64_t r9;
    int64_t r8;
    int64_t rbp;
    int64_t rdi;
    int64_t rsi;
    int64_t rdx;
    int64_t rcx;
    int64_t rbx;
    int64_t rax;
    int64_t trapno;
    int64_t errorcode;
    int64_t rip;
    int64_t cs;
    int64_t rflags;
    int64_t rsp;
    int64_t ss;
};


void vector0(void);
void vector1(void);
void vector2(void);
void vector3(void);
void vector4(void);
void vector5(void);
void vector6(void);
void vector7(void);
void vector8(void);
void vector10(void);
void vector11(void);
void vector12(void);
void vector13(void);
void vector14(void);
void vector16(void);
void vector17(void);
void vector18(void);
void vector19(void);
void vector32(void);
void vector39(void);
void init_idt(void);
void eoi(void);
void load_idt(struct IdtPtr *ptr);
unsigned char read_isr(void);

#endif


trap.c:

Code:
#include "trap.h"


struct IdtPtr idt_pointer;
struct IdtEntry vectors[256];

void init_idt_entry(struct IdtEntry *entry, uint64_t addr, uint8_t attribute)
{
    entry->low = (uint16_t)addr;
    entry->selector = 0x08;
    entry->attr = attribute;
    entry->mid = (uint16_t)(addr>>16);
    entry->high = (uint32_t)(addr>>32);
}


void init_idt(void)
{

    init_idt_entry(&vectors[0],(uint64_t)vector0,0x8e);
    init_idt_entry(&vectors[1],(uint64_t)vector1,0x8e);
    init_idt_entry(&vectors[2],(uint64_t)vector2,0x8e);
    init_idt_entry(&vectors[3],(uint64_t)vector3,0x8e);
    init_idt_entry(&vectors[4],(uint64_t)vector4,0x8e);
    init_idt_entry(&vectors[5],(uint64_t)vector5,0x8e);
    init_idt_entry(&vectors[6],(uint64_t)vector6,0x8e);
    init_idt_entry(&vectors[7],(uint64_t)vector7,0x8e);
    init_idt_entry(&vectors[8],(uint64_t)vector8,0x8e);
    init_idt_entry(&vectors[10],(uint64_t)vector10,0x8e);
    init_idt_entry(&vectors[11],(uint64_t)vector11,0x8e);
    init_idt_entry(&vectors[12],(uint64_t)vector12,0x8e);
    init_idt_entry(&vectors[13],(uint64_t)vector13,0x8e);
    init_idt_entry(&vectors[14],(uint64_t)vector14,0x8e);
    init_idt_entry(&vectors[16],(uint64_t)vector16,0x8e);
    init_idt_entry(&vectors[17],(uint64_t)vector17,0x8e);
    init_idt_entry(&vectors[18],(uint64_t)vector18,0x8e);
    init_idt_entry(&vectors[19],(uint64_t)vector19,0x8e);
    init_idt_entry(&vectors[32],(uint64_t)vector32,0x8e);
    init_idt_entry(&vectors[39],(uint64_t)vector39,0x8e);

    idt_pointer.limit = sizeof(vectors)-1;
    idt_pointer.addr = (uint64_t)vectors;
    load_idt(&idt_pointer);

}

void handler(struct TrapFrame *tf)
{
    unsigned char isr_value;

   printk("received interupt:");
   printk(" %d\n", tf->trapno);

    switch (tf->trapno) {
        case 32:
            eoi();
            break;
           
        case 39:
            isr_value = read_isr();
            if ((isr_value&(1<<7)) != 0) {
                eoi();
            }
            break;

        default:
            while (1) { }
    }
}


trap.S:
Code:
.text
.extern handler
.global vector0
.global vector1
.global vector2
.global vector3
.global vector4
.global vector5
.global vector6
.global vector7
.global vector8
.global vector10
.global vector11
.global vector12
.global vector13
.global vector14
.global vector16
.global vector17
.global vector18
.global vector19
.global vector32
.global vector39
.global eoi
.global read_isr
.global load_idt

Trap:
    push %rax
    push %rbx
    push %rcx
    push %rdx
    push %rsi
    push %rdi
    push %rbp
    push %r8
    push %r9
    push %r10
    push %r11
    push %r12
    push %r13
    push %r14
    push %r15

    mov %rsp,%rdi
    call handler

TrapReturn:
    pop %r15
   pop %r14
   pop %r13
    pop %r12
    pop %r11
    pop %r10
    pop %r9
   pop %r8
    pop %rbp
    pop %rdi
    pop %rsi
    pop %rdx
    pop %rcx
    pop %rbx
    pop %rax

    add $16,%rsp
    iretq

vector0:
    push $0
    push $0
    jmp Trap

vector1:
    push $0
    push $1
    jmp Trap

vector2:
    push $0
    push $2
    jmp Trap

vector3:
    push $0
    push $3
    jmp Trap

vector4:
    push $0
    push $4
    jmp Trap

vector5:
    push $0
    push $5
    jmp Trap

vector6:
    push $0
    push $6
    jmp Trap

vector7:
    push $0
    push $7
    jmp Trap

vector8:
    push $8
    jmp Trap

vector10:
    push $10
    jmp Trap

vector11:
    push $11
    jmp Trap

vector12:
    push $12
    jmp Trap

vector13:
    push $13
    jmp Trap

vector14:
    push $14
    jmp Trap

vector16:
    push $0
    push $16
    jmp Trap

vector17:
    push $17
    jmp Trap

vector18:
    push $0
    push $18
    jmp Trap

vector19:
    push $0
    push $19
    jmp Trap

vector32:
    push $0
    push $32
    jmp Trap

vector39:
    push $0
    push $39
    jmp Trap

eoi:
    mov $0x20,%al
    out %al, $0x20
    ret

read_isr:
    mov $11,%al
    out %al, $0x20
    in $0x20,%al
    ret

load_idt:
   lidt (%rdi)
    ret


and some init PIC code in boot64.S:
Code:
InitPIT:
    mov $(1<<2)|(3<<4), %al
    out %al, $0x43

    mov $11931,%ax
    out %al, $0x40
    mov %ah,%al
    out %al, $0x40
   ret

InitPIC:
    mov $0x11,%al
    out %al, $0x20
    out %al, $0xa0

    mov $32,%al
    out %al, $0x21
    mov $40,%al
    out %al, $0xa1

    mov $4,%al
    out %al, $0x21
    mov $2,%al
    out %al, $0xa1

    mov $1,%al
    out %al, $0x21
    out %al, $0xa1

    mov $0b11111110,%al
    out %al, $0x21
    mov $0b11111111,%al
    out %al, $0xa1

    ret


I don't understand what I did wrong and why interrupts not working. If someone could suggest how to make them work that would be great.


Top
 Profile  
 
 Post subject: Re: Help me make interrupts working
PostPosted: Wed Mar 24, 2021 6:30 am 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
What exactly is happening? A triple fault? No interrupts, period?

_________________
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg


Top
 Profile  
 
 Post subject: Re: Help me make interrupts working
PostPosted: Wed Mar 24, 2021 6:40 am 
Offline

Joined: Tue Jul 07, 2020 3:18 pm
Posts: 15
If I made a software interrupt by this line: asm volatile ("int $0x3");
qemu reboots. I am not exactly sure how to identify the triple fault.


Top
 Profile  
 
 Post subject: Re: Help me make interrupts working
PostPosted: Wed Mar 24, 2021 7:48 am 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
That means is triple faulted when QEMU restarts. This means your IDT is invalid. I will look at it and post what I find soon.

_________________
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg


Top
 Profile  
 
 Post subject: Re: Help me make interrupts working
PostPosted: Wed Mar 24, 2021 7:49 am 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
Have you set up a GDT?

_________________
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg


Top
 Profile  
 
 Post subject: Re: Help me make interrupts working
PostPosted: Wed Mar 24, 2021 7:56 am 
Offline

Joined: Tue Jul 07, 2020 3:18 pm
Posts: 15
Yes in boot32.S in the entry function _start:
...
lgdt (init_gdt64_ptr)
...

and in data section;

.section .data

.align 16
gdt64:
.quad 0x0000000000000000 // 0x00 NULL
.quad 0x0020980000000000 // 0x08 KCODE64
gdt64_end:

.align 16
init_gdt64_ptr:
.word gdt64_end - gdt64 - 1
.long gdt64


Top
 Profile  
 
 Post subject: Re: Help me make interrupts working
PostPosted: Wed Mar 24, 2021 1:59 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
JustVic wrote:
I am not exactly sure how to identify the triple fault.

Add "-d int" to your QEMU command line and read the output. (You may also want to add "-no-reboot" so it stops when it triple faults.)


Top
 Profile  
 
 Post subject: Re: Help me make interrupts working
PostPosted: Wed Mar 24, 2021 10:31 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1593
I don't see anything obviously wrong here. I second the suggestion to just use QEMU's debugging facilities to see what is going wrong. The only other suggestion I could make is to set your code segment to 0x00AF'9A00'0000'FFFF. Setting a segment limit ought not to matter, but maybe it does in this case?

_________________
Carpe diem!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 56 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group