OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 10:40 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 54 posts ]  Go to page Previous  1, 2, 3, 4
Author Message
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 11:23 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1604
isaiah0311 wrote:
Here is how the IRQs are handled:
Code:
isr_handler:
.pic1
   mov ax, 0x20
   out 0x20, ax
   iretq
.pic2
   mov ax, 0x20
   out 0xa0, ax
   iretq

I know this won't read the keyboard input, but I didn't except it to cause a reboot. I figured it would just do nothing.
The ISRs are clobbering ax. You need to save ax and restore it, otherwise the main program will suddenly find itself with a changed AX. Also, the PIC2 handler needs to send EOI to PIC 1 as well. So at least this much is needed:
Code:
isr_handler:
.pic1:
  push rax
  mov ax,0x20
  out 0x20, ax
  pop rax
  iretq

.pic2:
  push rax
  mov ax,0x20
  out 0xa0, ax
  out 0x20, ax
  pop rax
  iretq
For the keyboard interrupt, you at least need to read out the keyboard controller, even if you just discard the byte. Otherwise the keyboard controller will just keep interrupting the CPU in an endless loop, and the CPU will never get to do anything.

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 11:57 pm 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
SKC wrote:
Read this.
And this.

So after reading these I came up with a little function to handle keyboard input. The C function it calls just prints "input read" to let me know it worked.
It works when I press a key the first time but then stops. It doesn't seem to be crashing because QEMU isn't rebooting like it used to. So I'm not sure why it stops working.
Code:
isr_handler:
.keyboard:
   push rax
   in ax, 0x21
   cld
   call read_input
   mov ax, 0x20
   out 0x20, ax
   pop rax
   iretq

nullplan wrote:
The ISRs are clobbering ax. You need to save ax and restore it, otherwise the main program will suddenly find itself with a changed AX. Also, the PIC2 handler needs to send EOI to PIC 1 as well.

Thank you, I fixed my ISR.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Sat Mar 13, 2021 12:25 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
isaiah0311 wrote:
Code:
   in ax, 0x21

What's this for?

isaiah0311 wrote:
Code:
   call read_input

If you call a function written in C, you need to save all of the registers C function calls are allowed to clobber. You might want to check the AMD64 psABI for the whole list.

isaiah0311 wrote:
Code:
   out 0x20, ax

That should be AL instead of AX.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Sat Mar 13, 2021 12:41 am 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
Octocontrabass wrote:
isaiah0311 wrote:
Code:
   in ax, 0x21

What's this for?

Reads the key code from the PIC and puts it into ax (now al).
Octocontrabass wrote:
If you call a function written in C, you need to save all of the registers C function calls are allowed to clobber. You might want to check the AMD64 psABI for the whole list.

Can I use my pushall and popall macros here or is it bad to preserve registers that aren't getting clobbered?


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Sat Mar 13, 2021 1:07 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
isaiah0311 wrote:
Reads the key code from the PIC and puts it into ax (now al).

The PIC doesn't know anything about key codes. Perhaps you're looking for the keyboard controller?

If you want to pass it as a uint8_t parameter to the C function, you need to use MOVZX to zero-extend AL into EDI. (The AMD64 psABI isn't clear about whether this is necessary, but Clang assumes you will do this.)

isaiah0311 wrote:
Can I use my pushall and popall macros here or is it bad to preserve registers that aren't getting clobbered?

It takes a bit more space on the stack, but otherwise it won't hurt.

Speaking of the stack, be careful to keep the stack properly 16-byte aligned when you call a C function. (If your pushall macro pushes 15 registers, the stack will be correctly aligned. Each value you push moves the stack by 8 bytes, and the interrupt itself pushes five values before running your handler code, for a total of (15+5)*8=160 bytes.)


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Sat Mar 13, 2021 8:58 am 
Offline
Member
Member

Joined: Tue Aug 11, 2020 12:14 pm
Posts: 151
Octocontrabass wrote:
Speaking of the stack, be careful to keep the stack properly 16-byte aligned when you call a C function. (If your pushall macro pushes 15 registers, the stack will be correctly aligned. Each value you push moves the stack by 8 bytes, and the interrupt itself pushes five values before running your handler code, for a total of (15+5)*8=160 bytes.)

We're going a bit off topic but I'd like to get some clarification on this particular point.

The only reference to 16-byte stack alignment I could find in the x86_64 ABI specifically mentioned 16-byte alignment for the initial %rsp value of a new process (section 3.4.1 of the ABI). It's not unreasonable to extrapolate that to mean that any function entry point should have a 16-byte stack alignment, so let's use that assumption.

Any compiled code (C, etc.) should do this automatically. But if I have assembly code in my kernel that calls a C function, I should actually align the stack as 8-byte aligned, but NOT 16-byte aligned, so that the 'call' instruction pushing the return address on the stack will result in the C function entry point getting a 16-byte aligned stack.

In other words, I should wrap all my asm->C calls with either a macro or a wrapper function that makes an extra adjustment to the stack (if necessary) and restores it after the call. (update: alternatively, I could use the logic the compiler uses, which is that I should know at all times how the stack is aligned, because I generated the instructions that manipulate it, so I may only need realignment in a few very specific places).

Do I have that right?


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Sat Mar 13, 2021 9:48 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
sj95126 wrote:
The only reference to 16-byte stack alignment I could find in the x86_64 ABI specifically mentioned 16-byte alignment for the initial %rsp value of a new process (section 3.4.1 of the ABI).
Quote:
The end of the input argument area shall be aligned on a 16 (32 or 64, if __m256 or __m512 is passed on stack) byte boundary.

Section 3.2.2 of the psABI. They say it a bit differently, but it means the stack needs to be aligned for all function calls.

sj95126 wrote:
But if I have assembly code in my kernel that calls a C function, I should actually align the stack as 8-byte aligned, but NOT 16-byte aligned, so that the 'call' instruction pushing the return address on the stack will result in the C function entry point getting a 16-byte aligned stack.

No, the stack must be 16-byte aligned before the CALL instruction.

sj95126 wrote:
In other words, I should wrap all my asm->C calls with either a macro or a wrapper function that makes an extra adjustment to the stack (if necessary) and restores it after the call. (update: alternatively, I could use the logic the compiler uses, which is that I should know at all times how the stack is aligned, because I generated the instructions that manipulate it, so I may only need realignment in a few very specific places).

Yep, that works.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Sat Mar 13, 2021 10:16 am 
Offline
Member
Member

Joined: Tue Aug 11, 2020 12:14 pm
Posts: 151
Octocontrabass wrote:
No, the stack must be 16-byte aligned before the CALL instruction.

Oh, good, that's actually easier. So I can use this:
Code:
#define CALL_ALIGN(x)           pushq   %r15 ; \
                                movq    %rsp, %r15 ; \
                                andw    $0xfff0, %sp ; \
                                call    x ; \
                                movq    %r15, %rsp ; \
                                popq    %r15


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Sat Mar 13, 2021 10:17 am 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
My IDT is fully functional and I am able to process keyboard input now. Thank you so much to everyone!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 54 posts ]  Go to page Previous  1, 2, 3, 4

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 96 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:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group